Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

741 lines
34 KiB

//========= Copyright (C) 1996-2013, Valve Corporation, All rights reserved. ============//
//
// Purpose: Helper for UI components - used for binding to both Scaleform ActionScript and
// Panorama Javascript.
//
// $NoKeywords: $
//=============================================================================//
#ifndef UICOMPONENT_COMMON_H
#define UICOMPONENT_COMMON_H
#ifdef _WIN32
#pragma once
#endif
#define USE_SCALEFORM_BINDINGS
#if defined ( PANORAMA_ENABLE )
#define USE_PANORAMA_BINDINGS
#endif // PANORAMA_ENABLE
// Scaleform events are simply KeyValue objects, so it's possible to test defining, declaring and broadcasting events
// in isolation without including Scaleform headers using the define below.
//#define TEST_SCALEFORM_EVENTS
#ifndef CSGO_PORT
// In Source1 the pointers_to_members pragma is used within Scaleform and VGUI headers to ensure member function pointers
// are maximum size. This affects the panorama javascript bindings (see uijsregistration.h).
// We also add the pragma here so that we always assume the larger size pointers in source 1 for consistency, regardless
// of the order of includes.
#define MEMBER_FUNCPTRS_MAXSIZE
#pragma pointers_to_members( full_generality, virtual_inheritance )
#endif
#ifdef USE_SCALEFORM_BINDINGS
#include "scaleformui/scaleformui.h"
#endif
#ifdef USE_PANORAMA_BINDINGS
#include "panorama/uijsregistration.h"
#include "panorama/iuiengine.h"
#define DECLARE_PANORAMA_JSREGISTERFUNC void JSRegisterFunc();
#else
#define DECLARE_PANORAMA_JSREGISTERFUNC
#endif
#include "bannedwords.h"
class IUiComponentGlobalInstanceBase
{
public:
virtual void Tick() {}
virtual void Shutdown() = 0;
virtual void InstallScaleformBindings( int iSlot ) = 0;
virtual void InstallPanoramaBindings() = 0;
virtual void ShutdownComponentApiDef(int iSlot) = 0;
};
template < class T >
class CUiComponentGlobalInstanceHelper : public IUiComponentGlobalInstanceBase
{
protected:
static T* & InternalInstancePtr() { static T* s_pInstance = NULL; return s_pInstance; }
public:
static T* GetInstance()
{
if ( !InternalInstancePtr() )
{
InternalInstancePtr() = new T();
}
return InternalInstancePtr();
}
void Shutdown() OVERRIDE
{
T *pInstance = InternalInstancePtr();
Assert( pInstance && (pInstance == this) );
if ( pInstance && (pInstance == this) )
{
InternalInstancePtr() = NULL;
delete pInstance;
}
}
};
#define UI_COMPONENT_DECLARE_GLOBAL_INSTANCE_ONLY( classname ) \
protected: \
friend class CUiComponentGlobalInstanceHelper< classname >; \
void InstallScaleformBindings( int iSlot ) OVERRIDE; \
void InstallPanoramaBindings( ) OVERRIDE; \
void ShutdownComponentApiDef( int iSlot ) OVERRIDE; \
classname(); \
~classname(); \
private: \
classname( const classname & other ); \
classname & operator = ( const classname & other ); \
DECLARE_PANORAMA_JSREGISTERFUNC
#if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
//-----------------------------------------------------------------------------
// Purpose: Helpers for Scaleform events
// The following macros and template functions allow Scaleform events to be declared
// and broadcast using Panorama-style macros, so a single UI_COMPONENT_BROADCAST_EVENT
// macro can broadcast both Panorama and Scaleform events.
//-----------------------------------------------------------------------------
namespace sfevents
{
template < typename T >
void SetSFParam(KeyValues * pKv, const char* pName)
{
// Fallback for non-specialized types.
pKv->SetInt(pName, 0);
}
template <> inline void SetSFParam< const char * >(KeyValues * pKv, const char* pName) { pKv->SetString(pName, ""); }
template <> inline void SetSFParam< uint8 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
template <> inline void SetSFParam< uint16 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
template <> inline void SetSFParam< uint32 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
template <> inline void SetSFParam< uint64 >(KeyValues * pKv, const char* pName) { pKv->SetUint64(pName, 0); }
template <> inline void SetSFParam< int32 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
template <> inline void SetSFParam< int64 >(KeyValues * pKv, const char* pName) { pKv->SetUint64(pName, 0); }
template <> inline void SetSFParam< float >(KeyValues * pKv, const char* pName) { pKv->SetFloat(pName, 0.0f); }
template <> inline void SetSFParam< bool >(KeyValues * pKv, const char* pName) { pKv->SetBool(pName, false); }
template <> inline void SetSFParam< void* >(KeyValues * pKv, const char* pName) { pKv->SetPtr(pName, NULL); }
inline void SetSFParamValues(KeyValues * pKv, ...)
{
va_list args;
va_start(args, pKv);
FOR_EACH_SUBKEY(pKv, pSubkey)
{
switch (pSubkey->GetDataType()) {
case KeyValues::TYPE_STRING:
pKv->SetString(pSubkey->GetName(), va_arg(args, const char*));
break;
case KeyValues::TYPE_INT:
pKv->SetInt(pSubkey->GetName(), va_arg(args, int));
break;
case KeyValues::TYPE_FLOAT:
pKv->SetFloat(pSubkey->GetName(), va_arg(args, double));
break;
case KeyValues::TYPE_UINT64:
pKv->SetUint64(pSubkey->GetName(), va_arg(args, uint64));
break;
case KeyValues::TYPE_PTR:
pKv->SetPtr(pSubkey->GetName(), va_arg(args, void*));
break;
default:
Plat_FatalError("Invalid SF Event param type\n");
break;
}
}
}
}
#define SF_COMPONENT_EVENT_NAME( category, eventname ) "ScaleformComponent_" #category "_" #eventname
#define SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ) g_ScaleformComponent_##category##_##eventname##_event
#define SF_COMPONENT_DECLARE_EVENT0( category, eventname ) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); } \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 ) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { \
m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
sfevents::SetSFParam<param1>(m_pKv, param1_name); \
} \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DECLARE_EVENT2(category, eventname, param1_name, param1, param2_name, param2) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { \
m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
sfevents::SetSFParam<param1>(m_pKv, param1_name); \
sfevents::SetSFParam<param2>(m_pKv, param2_name); \
} \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DECLARE_EVENT3(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { \
m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
sfevents::SetSFParam<param1>(m_pKv, param1_name); \
sfevents::SetSFParam<param2>(m_pKv, param2_name); \
sfevents::SetSFParam<param3>(m_pKv, param3_name); \
} \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DECLARE_EVENT4(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { \
m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
sfevents::SetSFParam<param1>(m_pKv, param1_name); \
sfevents::SetSFParam<param2>(m_pKv, param2_name); \
sfevents::SetSFParam<param3>(m_pKv, param3_name); \
sfevents::SetSFParam<param4>(m_pKv, param4_name); \
} \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DECLARE_EVENT5(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5) \
class ScaleformComponent_##category##_##eventname##_event \
{ public: \
ScaleformComponent_##category##_##eventname##_event() { \
m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
sfevents::SetSFParam<param1>(m_pKv, param1_name); \
sfevents::SetSFParam<param2>(m_pKv, param2_name); \
sfevents::SetSFParam<param3>(m_pKv, param3_name); \
sfevents::SetSFParam<param4>(m_pKv, param4_name); \
sfevents::SetSFParam<param5>(m_pKv, param5_name); \
} \
KeyValues* m_pKv; \
}; \
extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_DEFINE_EVENT(category, eventname) \
ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
#define SF_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
{ \
KeyValues* pKv = SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ).m_pKv->MakeCopy(); \
sfevents::SetSFParamValues(pKv, ##__VA_ARGS__); \
if(g_pMatchFramework) g_pMatchFramework->GetEventsSubscription()->BroadcastEvent(pKv); \
}
#else // if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
#define SF_COMPONENT_EVENT_NAME( category, eventname ) "ScaleformComponent_" #category "_" #eventname
#define SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ) g_ScaleformComponent_##category##_##eventname##_event
#define SF_COMPONENT_DECLARE_EVENT0( category, eventname )
#define SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 )
#define SF_COMPONENT_DECLARE_EVENT2(category, eventname, param1_name, param1, param2_name, param2)
#define SF_COMPONENT_DECLARE_EVENT3(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3)
#define SF_COMPONENT_DECLARE_EVENT4(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4)
#define SF_COMPONENT_DECLARE_EVENT5(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5)
#define SF_COMPONENT_DEFINE_EVENT(category, eventname)
#define SF_COMPONENT_BROADCAST_EVENT( category, eventname, ... )
#endif // if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
#ifdef USE_SCALEFORM_BINDINGS
#define SF_COMPONENT_FUNCTION_NAME( fnname ) UiComponentFunction_##fnname
// Should match SCALEFORM_CALLBACK_ARGS_DECL in uiscaleform.h
#define SF_DEFAULT_PARAMS_DECL IUIMarshalHelper* pui, SFPARAMS obj
#define SF_DEFAULT_PARAMS_PASS pui, obj
#define SF_COMPONENT_FUNCTION( returntype, fnname ) \
void SF_COMPONENT_FUNCTION_NAME(fnname)( SF_DEFAULT_PARAMS_DECL )
#define SF_COMPONENT_FUNCTION_IMPL( classname, fnname ) \
void classname::SF_COMPONENT_FUNCTION_NAME(fnname)( SF_DEFAULT_PARAMS_DECL )
#define SF_COMPONENT_FUNCTION_DELEGATE( ptrcomponent, fnname ) \
( ptrcomponent )->SF_COMPONENT_FUNCTION_NAME( fnname )( SF_DEFAULT_PARAMS_PASS )
#define SF_COMPONENT_API_DEF_BEGIN( componentclass ) \
class componentclass##_Table : public IScaleformUIFunctionHandlerDefinitionTable \
{ \
public: \
virtual const ScaleformUIFunctionHandlerDefinition* GetTable( void ) const \
{ \
static const ScaleformUIFunctionHandlerDefinition fnTable[] = {
#define SF_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
{ #fnname, reinterpret_cast<ScaleformUIFunctionHandler>( &componentclass::SF_COMPONENT_FUNCTION_NAME( fnname ) ) },
#define SF_COMPONENT_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass ) \
{ #fnname, reinterpret_cast<ScaleformUIFunctionHandler>( &componentclass::fnname ) }
#define SF_COMPONENT_API_DEF_END( componentclass ) \
{ NULL, NULL } \
}; \
return fnTable; \
} \
}; \
static componentclass##_Table g_##componentclass##_Table; \
static SFVALUE g_##componentclass##_SFVALUE[SF_SLOT_IDS_COUNT];
#define SF_COMPONENT_API_INSTALL( iSlot, componentclass, ptrInstance, componentname ) \
do { \
Assert( ( iSlot >= 0 ) && ( iSlot < SF_SLOT_IDS_COUNT ) ); \
g_pScaleformUI->InstallGlobalObject( iSlot, "CScaleformComponent_" #componentname, \
reinterpret_cast<ScaleformUIFunctionHandlerObject*>(static_cast<componentclass *>(ptrInstance)), \
&g_##componentclass##_Table, \
&g_##componentclass##_SFVALUE[iSlot] ); \
} while( 0 )
#define SF_COMPONENT_API_REMOVE( iSlot, componentclass ) \
do { \
Assert( ( iSlot >= 0 ) && ( iSlot < SF_SLOT_IDS_COUNT ) ); \
g_pScaleformUI->RemoveGlobalObject( iSlot, g_##componentclass##_SFVALUE[iSlot] ); g_##componentclass##_SFVALUE[iSlot] = NULL; \
} while( 0 )
#define SF_INTEGRATION_XUID_PARAM( xuidVarName, iParam ) const char * xuidVarName = 0; { \
if ( pui->Params_GetArgType( obj, iParam ) != IUIMarshalHelper::VT_String ) \
{ \
AssertMsg( 0, __FUNCTION__ "ActionScript passed a non string param for xuid!\n" ); \
return;\
} \
xuidVarName = ( pui->Params_GetArgAsString( obj, iParam ) ); \
}
#define SF_INTEGRATION_ITEMID_PARAM( itemidVarName, iParam ) itemid_t itemidVarName = 0; { \
if ( pui->Params_GetArgType( obj, iParam ) != IUIMarshalHelper::VT_String ) \
{ \
AssertMsg( 0, __FUNCTION__ " ActionScript passed a non string param for item id!\n" ); \
return;\
} \
const char *pItemID = ( pui->Params_GetArgAsString( obj, iParam ) ); \
if ( !pItemID ) \
return; \
itemidVarName = (uint64) Q_atoi64( pItemID ) ; \
}
#define SF_COMPONENT_NOTIFY_FLASH( category, eventname ) \
if ( FlashAPIIsValid() ) \
{ \
WITH_SLOT_LOCKED \
{ \
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, SF_COMPONENT_EVENT_NAME( category, eventname ), NULL, 0 ); \
} \
}
#define SF_COMPONENT_FORWARD_EVENT( szEvent ) \
if ( StringHasPrefix( szEvent, "ScaleformComponent_" ) ) \
{ \
if ( FlashAPIIsValid() ) \
{ \
WITH_SLOT_LOCKED \
{ \
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, szEvent, NULL, 0 ); \
} \
} \
}
#define SF_COMPONENT_HOST_DECL() \
public: \
CScaleformComponentHostSupport_ImageCacheHelper m_CScaleformComponentHostSupport_ImageCacheHelper; \
void ScaleformComponentHost_EnsureAvatarCached( SF_DEFAULT_PARAMS_DECL ) \
{ \
SF_INTEGRATION_XUID_PARAM( xuidUser, 0 ); \
m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureAvatarCached( xuidUser ); \
} \
void ScaleformComponentHost_EnsureInventoryImageCached( SF_DEFAULT_PARAMS_DECL ) \
{ \
SF_INTEGRATION_ITEMID_PARAM( itemID, 0 ); \
m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureInventoryImageCached( itemID ); \
} \
void ScaleformComponentHost_EnsureItemDataImageCached( SF_DEFAULT_PARAMS_DECL ) \
{ \
uint16 iDefIndex = ( uint16 ) pui->Params_GetArgAsNumber( obj, 0 ); \
uint16 iPaintIndex = ( uint16 ) pui->Params_GetArgAsNumber( obj, 1 ); \
m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureItemDataImageCached( iDefIndex, iPaintIndex ); \
} \
void ScaleformComponentHost_GetScaleformComponentEventParamString( SF_DEFAULT_PARAMS_DECL ) \
{ \
const char *pEventName = ( pui->Params_GetArgAsString( obj, 0 ) ); \
const char *pParamName = ( pui->Params_GetArgAsString( obj, 1 ) ); \
if ( !pEventName || !pParamName ) \
return; \
KeyValues *kvEventData = g_pMatchFramework->GetEventsSubscription()->GetEventData( pEventName ); \
if ( !kvEventData ) \
return; \
pui->Params_SetResult( obj, kvEventData->GetString( pParamName, "" ) ); \
} \
#define SF_COMPONENT_HOST_IMAGE_CACHE_ENABLE( bEnable ) m_CScaleformComponentHostSupport_ImageCacheHelper.EnableCaching( bEnable )
#define SF_COMPONENT_HOST_API_DEF() \
{ "EnsureAvatarCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureAvatarCached )}, \
{ "EnsureInventoryImageCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureInventoryImageCached )}, \
{ "EnsureItemDataImageCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureItemDataImageCached )}, \
{ "GetScaleformComponentEventParamString", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_GetScaleformComponentEventParamString )} \
// Registration of GC job handler for scaleform components
#define SF_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn ) \
class cjobclass : public GCSDK::CGCClientJob \
{ \
public: \
cjobclass( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) { } \
virtual bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket ) \
{ \
GCSDK::CProtoBufMsg<cmsgclass> msg( pNetPacket ); \
ccomponentclass::GetInstance()->ccomponentfn( msg.Body() ); \
return true; \
} \
}; \
GC_REG_CLIENT_JOB( cjobclass, gcmsgid );
inline char const * HelperSfGetStringParamSafe(SF_DEFAULT_PARAMS_DECL, int iParam, char const *szDefault = NULL)
{
if ((iParam >= 0)
&& (int(pui->Params_GetNumArgs(obj)) > iParam)
&& ( pui->Params_GetArgType( obj, iParam ) == IUIMarshalHelper::VT_String ) )
return pui->Params_GetArgAsString(obj, iParam);
else
return szDefault;
}
#else // USE_SCALEFORM_BINDINGS
#define SF_COMPONENT_FUNCTION_NAME( fnname )
#define SF_DEFAULT_PARAMS_DECL
#define SF_DEFAULT_PARAMS_PASS
#define SF_COMPONENT_FUNCTION( returntype, fnname )
#define SF_COMPONENT_FUNCTION_IMPL( classname, fnname )
#define SF_COMPONENT_FUNCTION_DELEGATE( ptrcomponent, fnname )
#define SF_COMPONENT_API_DEF_BEGIN( componentclass )
#define SF_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass )
#define SF_COMPONENT_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass )
#define SF_COMPONENT_API_DEF_END( componentclass )
#define SF_COMPONENT_API_INSTALL( iSlot, componentclass, ptrInstance )
#define SF_COMPONENT_API_REMOVE( iSlot, componentclass )
#define SF_INTEGRATION_XUID_PARAM( xuidVarName, iParam )
#define SF_INTEGRATION_ITEMID_PARAM( itemidVarName, iParam )
#define SF_COMPONENT_NOTIFY_FLASH( category, eventname )
#define SF_COMPONENT_FORWARD_EVENT( szEvent )
#define SF_COMPONENT_HOST_DECL()
#define SF_COMPONENT_HOST_IMAGE_CACHE_ENABLE( bEnable )
#define SF_COMPONENT_HOST_API_DEF()
#define SF_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn )
#endif // USE_SCALEFORM_BINDINGS
#ifdef USE_PANORAMA_BINDINGS
#define PANORAMA_COMPONENT_API_DEF_BEGIN( componentclass ) \
void componentclass::JSRegisterFunc() \
{ \
#define PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, argNames, description ) \
panorama::RegisterJSMethod( #fnname, &componentclass::fnname, description, argNames );
#define PANORAMA_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, "", "" )
#define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, description ) \
panorama::RegisterJSMethodRaw( #fnname, &componentclass::fnname, description );
#define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF( returntype, fnname, componentclass ) \
PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, "" )
#define PANORAMA_COMPONENT_API_DEF_END( componentclass ) \
}; \
#define PANORAMA_COMPONENT_API_INSTALL( componentclass, ptrInstance, scriptVarName, description ) \
do { \
panorama::UIEngine()->StartRegisterJSScope( scriptVarName, description ); \
CUtlDelegate< void() > del( ptrInstance, &componentclass::JSRegisterFunc ); \
CUtlAbstractDelegate absDel = del.GetAbstractDelegate(); \
panorama::UIEngine()->ExposeObjectTypeToJavaScript( #componentclass, absDel ); \
panorama::UIEngine()->ExposeGlobalObjectToJavaScript(scriptVarName, ptrInstance, #componentclass, true); \
panorama::UIEngine()->EndRegisterJSScope(); \
} while (0)
#define PANORAMA_COMPONENT_API_REMOVE( componentclass )
#define PANORAMA_COMPONENT_EVENT_NAME( category, eventname ) PanoramaComponent_##category##_##eventname
#define PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
panorama::DispatchEvent(PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), NULL, ##__VA_ARGS__);
#define PANORAMA_COMPONENT_BROADCAST_EVENT_WITH_PARAMS( category, eventname, ... ) \
panorama::DispatchEvent(PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), NULL, ##__VA_ARGS__);
#define PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname ) \
DECLARE_PANORAMA_EVENT0(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ))
#define PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 ) \
DECLARE_PANORAMA_EVENT1(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1)
#define PANORAMA_COMPONENT_DECLARE_EVENT2(category, eventname, param1, param2) \
DECLARE_PANORAMA_EVENT2(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2)
#define PANORAMA_COMPONENT_DECLARE_EVENT3(category, eventname, param1, param2, param3) \
DECLARE_PANORAMA_EVENT3(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3)
#define PANORAMA_COMPONENT_DECLARE_EVENT4(category, eventname, param1, param2, param3, param4) \
DECLARE_PANORAMA_EVENT4(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3, param4)
#define PANORAMA_COMPONENT_DECLARE_EVENT5(category, eventname, param1, param2, param3, param4, param5) \
DECLARE_PANORAMA_EVENT5(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3, param4, param5)
#define PANORAMA_COMPONENT_DEFINE_EVENT(category, eventname)\
DEFINE_PANORAMA_EVENT(PANORAMA_COMPONENT_EVENT_NAME(category, eventname))
#define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
RegisterJSMethodWithMarshallHelper( #fnname, &componentclass::SF_COMPONENT_FUNCTION_NAME( fnname ) );
#define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass ) \
RegisterJSMethodWithMarshallHelper( #fnname, &componentclass::fnname );
// Helper class to allow the existing component functions to take a common object for param/return val handling
// Allows existing SF component code which expects multiple return types or to sometimes not return a value to remain unchanged and be
// called by new panorama js code if needed.
class CPanoramaMarshallHelper : public IUIMarshalHelper
{
public:
virtual SFVALUEARRAY Params_GetArgs( SFPARAMS params ) OVERRIDE;
virtual unsigned int Params_GetNumArgs( SFPARAMS params ) OVERRIDE;
virtual bool Params_ArgIs( SFPARAMS params, unsigned int index, _ValueType v ) OVERRIDE;
virtual SFVALUE Params_GetArg( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual _ValueType Params_GetArgType( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual double Params_GetArgAsNumber( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual bool Params_GetArgAsBool( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual const char* Params_GetArgAsString( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual const wchar_t* Params_GetArgAsStringW( SFPARAMS params, int index = 0 ) OVERRIDE;
virtual void Params_DebugSpew( SFPARAMS params ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, SFVALUE value ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, int value ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, float value ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, bool value ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, const char* value, bool bMakeNewValue = true ) OVERRIDE;
virtual void Params_SetResult( SFPARAMS params, const wchar_t* value, bool bMakeNewValue = true ) OVERRIDE;
virtual SFVALUE Params_CreateNewObject( SFPARAMS params ) OVERRIDE;
virtual SFVALUE Params_CreateNewString( SFPARAMS params, const char* value ) OVERRIDE;
virtual SFVALUE Params_CreateNewString( SFPARAMS params, const wchar_t* value ) OVERRIDE;
virtual SFVALUE Params_CreateNewArray( SFPARAMS params, int size = -1 ) OVERRIDE;
private:
// Scratch storage for returning v8 string params. Grows to high water mark of param count.
CUtlVector< CUtlString > m_vecStringStorage;
};
CPanoramaMarshallHelper *GetPanoramaMarshallHelper( void );
template< typename ObjType >
void JSMethodCallTupleWithMarshallHelper( const v8::FunctionCallbackInfo<v8::Value>& args )
{
v8::Isolate::Scope isolate_scope( args.GetIsolate() );
v8::HandleScope handle_scope( args.GetIsolate() );
ObjType *pPanel = panorama::GetThisPtrForJSCall<ObjType>( args.Holder() );
if ( !pPanel )
return;
v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( args.Data() );
panorama::HACKY_FUNC_PTR_CASTER< void ( ObjType::* )( IUIMarshalHelper* pui, SFPARAMS obj ) > caster;
panorama::RestoreFuncPtr( caster, callbackArray, 0 );
( pPanel->*caster.funcPtr )( GetPanoramaMarshallHelper(), ( SFPARAMS ) &args );
}
template < typename ObjType >
void RegisterJSMethodWithMarshallHelper( const char *pchMethodName, void ( ObjType::*mf )( IUIMarshalHelper* pui, SFPARAMS obj ), const char *pDesc = NULL )
{
v8::Isolate::Scope isolate_scope( panorama::GetV8Isolate() );
v8::HandleScope handle_scope( panorama::GetV8Isolate() );
v8::Handle<v8::Array> callbackArray = v8::Array::New( panorama::GetV8Isolate(), V8_CALLBACK_ARRAY_SIZE );
panorama::GetPtrToCallbackArray( mf, callbackArray );
v8::Handle<v8::ObjectTemplate> objTemplate = panorama::UIEngine()->GetCurrentV8ObjectTemplateToSetup();
objTemplate->Set( v8::String::NewFromUtf8( panorama::GetV8Isolate(), pchMethodName ), v8::FunctionTemplate::New( panorama::GetV8Isolate(), &JSMethodCallTupleWithMarshallHelper<ObjType>, callbackArray ) );
int nEntry = panorama::UIEngine()->NewRegisterJSEntry( pchMethodName, panorama::RegisterJSEntryInfo_t::k_EMethod, pDesc, panorama::k_ERegisterJSTypeVoid );
panorama::RegisterJSType_t pParamTypes[ 1 ] = { panorama::k_ERegisterJSTypeRawV8Args };
panorama::UIEngine()->SetRegisterJSEntryParams( nEntry, 1, pParamTypes, NULL );
}
#else // USE_PANORAMA_BINDINGS
#define PANORAMA_COMPONENT_API_DEF_BEGIN( componentclass )
#define PANORAMA_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass )
#define PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, argNames, description )
#define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF( returntype, fnname, componentclass )
#define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, description )
#define PANORAMA_COMPONENT_API_DEF_END( componentclass )
#define PANORAMA_COMPONENT_API_INSTALL( componentclass, ptrInstance, scriptVarName, description )
#define PANORAMA_COMPONENT_API_REMOVE( componentclass )
#define PANORAMA_COMPONENT_EVENT_NAME( category, eventname )
#define PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ... )
#define PANORAMA_COMPONENT_BROADCAST_EVENT_WITH_PARAMS( category, eventname, ... )
#define PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname )
#define PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 )
#define PANORAMA_COMPONENT_DECLARE_EVENT2(category, eventname, param1, param2)
#define PANORAMA_COMPONENT_DECLARE_EVENT3(category, eventname, param1, param2, param3)
#define PANORAMA_COMPONENT_DECLARE_EVENT4(category, eventname, param1, param2, param3, param4)
#define PANORAMA_COMPONENT_DECLARE_EVENT5(category, eventname, param1, param2, param3, param4, param5)
#define PANORAMA_COMPONENT_DEFINE_EVENT(category, eventname)
#define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF( returntype, fnname, componentclass )
#define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass )
#endif // USE_PANORAMA_BINDINGS
// 7ls - revisit shutdown code
#define UI_COMPONENT_API_DEF_COMMON_DOC( componentclass, scriptVarName, description ) \
void componentclass::InstallScaleformBindings(int iSlot) \
{ \
SF_COMPONENT_API_INSTALL(iSlot, componentclass, this, scriptVarName); \
} \
void componentclass::InstallPanoramaBindings() \
{ \
PANORAMA_COMPONENT_API_INSTALL(componentclass, this, #scriptVarName, description); \
} \
void componentclass::ShutdownComponentApiDef(int iSlot) \
{ \
SF_COMPONENT_API_REMOVE(iSlot, componentclass); \
PANORAMA_COMPONENT_API_REMOVE(componentclass); \
}
#define UI_COMPONENT_API_DEF_COMMON( componentclass, scriptVarName ) \
UI_COMPONENT_API_DEF_COMMON_DOC( componentclass, scriptVarName, "" )
#define UI_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
SF_COMPONENT_BROADCAST_EVENT( category, eventname, ##__VA_ARGS__ ) \
PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ##__VA_ARGS__ )
#define UI_COMPONENT_DECLARE_EVENT0( category, eventname ) \
PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname ) \
SF_COMPONENT_DECLARE_EVENT0( category, eventname )
#define UI_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 ) \
PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 ) \
SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 )
#define UI_COMPONENT_DECLARE_EVENT2( category, eventname, param1_name, param1, param2_name, param2 ) \
PANORAMA_COMPONENT_DECLARE_EVENT2( category, eventname, param1, param2 ) \
SF_COMPONENT_DECLARE_EVENT2( category, eventname, param1_name, param1, param2_name, param2 )
#define UI_COMPONENT_DECLARE_EVENT3( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3 ) \
PANORAMA_COMPONENT_DECLARE_EVENT3( category, eventname, param1, param2, param3 ) \
SF_COMPONENT_DECLARE_EVENT3( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3 )
#define UI_COMPONENT_DECLARE_EVENT4( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4 ) \
PANORAMA_COMPONENT_DECLARE_EVENT4( category, eventname, param1, param2, param3, param4 ) \
SF_COMPONENT_DECLARE_EVENT4( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4 )
#define UI_COMPONENT_DECLARE_EVENT5( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5 ) \
PANORAMA_COMPONENT_DECLARE_EVENT5( category, eventname, param1, param2, param3, param4, param5 ) \
SF_COMPONENT_DECLARE_EVENT5( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5 )
#define UI_COMPONENT_DEFINE_EVENT( category, eventname )\
PANORAMA_COMPONENT_DEFINE_EVENT( category, eventname )\
SF_COMPONENT_DEFINE_EVENT( category, eventname )
// Only register Panorama cplusplus event handlers if not using Scaleform
// (Otherwise handlers will be called twice)
#if (defined (USE_PANORAMA_BINDINGS ) && !(defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)))
#define UI_COMPONENT_REGISTER_EVENT_HANDLER(category, eventname, pObj, methodptr) \
RegisterForUnhandledEvent( PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), pObj, methodptr );
#else
#define UI_COMPONENT_REGISTER_EVENT_HANDLER(category, eventname, pObj, methodptr)
#endif
#define UI_INTEGRATION_XUID_PARAM( xuidVarName, iParam ) XUID xuidVarName = 0; { \
if ( pui->Params_GetArgType( obj, iParam ) != IScaleformUI::VT_String ) \
{ \
AssertMsg1( 0, "%s UI code passed a non string param for xuid!\n", __FUNCTION__ ); \
DevMsg( " error: Passed non-string param to %s for param %d.\n", __FUNCTION__, iParam ); \
pui->Params_DebugSpew( obj ); \
return;\
} \
const char *pFriendXuid = ( pui->Params_GetArgAsString( obj, iParam ) ); \
if ( !pFriendXuid ) \
{ \
/*AssertMsg( 0, __FUNCTION__ " passed an invalid xuid!\n" );*/ \
} \
CSteamID friendId( (uint64) Q_atoi64( pFriendXuid ) ); \
if ( !friendId.IsValid() || !friendId.BIndividualAccount() ) \
{ \
/*AssertMsg( 0, __FUNCTION__ " passed an invalid xuid!\n" );*/ \
xuidVarName = 0; \
} \
else \
{ \
xuidVarName = friendId.ConvertToUint64(); \
} \
}
// Registration of GC job handler for ui component
#define UI_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn ) \
class cjobclass : public GCSDK::CGCClientJob \
{ \
public: \
explicit cjobclass( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) { } \
virtual bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket ) \
{ \
GCSDK::CProtoBufMsg<cmsgclass> msg( pNetPacket ); \
ccomponentclass::GetInstance()->ccomponentfn( msg.Body() ); \
return true; \
} \
}; \
GC_REG_CLIENT_JOB( cjobclass, gcmsgid );
// Function decl/impl helpers for ui component code that will be called by scaleform and/or javascript
#define UI_COMPONENT_FUNCTION_NAME( fnname ) UiComponentFunction_##fnname
#define UI_DEFAULT_PARAMS_DECL IUIMarshalHelper* pui, SFPARAMS obj
#define UI_DEFAULT_PARAMS_PASS pui, obj
#define UI_COMPONENT_FUNCTION( returntype, fnname ) \
void UI_COMPONENT_FUNCTION_NAME(fnname)( UI_DEFAULT_PARAMS_DECL )
#define UI_COMPONENT_FUNCTION_IMPL( classname, fnname ) \
void classname::UI_COMPONENT_FUNCTION_NAME(fnname)( UI_DEFAULT_PARAMS_DECL )
inline char const * HelperUiGetStringParamSafe( UI_DEFAULT_PARAMS_DECL, int iParam, char const *szDefault = NULL )
{
if ( ( iParam >= 0 )
&& ( int( pui->Params_GetNumArgs( obj ) ) > iParam )
&& ( pui->Params_GetArgType( obj, iParam ) == IScaleformUI::VT_String ) )
return pui->Params_GetArgAsString( obj, iParam );
else
return szDefault;
}
// Convert keyvalues to a json formatted string
bool Helper_RecursiveKeyValuesToJSONString( const KeyValues* pKV, CUtlBuffer &outBuffer );
#endif // UICOMPONENT_COMMON_H