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

  1. //========= Copyright (C) 1996-2013, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Helper for UI components - used for binding to both Scaleform ActionScript and
  4. // Panorama Javascript.
  5. //
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #ifndef UICOMPONENT_COMMON_H
  9. #define UICOMPONENT_COMMON_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #define USE_SCALEFORM_BINDINGS
  14. #if defined ( PANORAMA_ENABLE )
  15. #define USE_PANORAMA_BINDINGS
  16. #endif // PANORAMA_ENABLE
  17. // Scaleform events are simply KeyValue objects, so it's possible to test defining, declaring and broadcasting events
  18. // in isolation without including Scaleform headers using the define below.
  19. //#define TEST_SCALEFORM_EVENTS
  20. #ifndef CSGO_PORT
  21. // In Source1 the pointers_to_members pragma is used within Scaleform and VGUI headers to ensure member function pointers
  22. // are maximum size. This affects the panorama javascript bindings (see uijsregistration.h).
  23. // We also add the pragma here so that we always assume the larger size pointers in source 1 for consistency, regardless
  24. // of the order of includes.
  25. #define MEMBER_FUNCPTRS_MAXSIZE
  26. #pragma pointers_to_members( full_generality, virtual_inheritance )
  27. #endif
  28. #ifdef USE_SCALEFORM_BINDINGS
  29. #include "scaleformui/scaleformui.h"
  30. #endif
  31. #ifdef USE_PANORAMA_BINDINGS
  32. #include "panorama/uijsregistration.h"
  33. #include "panorama/iuiengine.h"
  34. #define DECLARE_PANORAMA_JSREGISTERFUNC void JSRegisterFunc();
  35. #else
  36. #define DECLARE_PANORAMA_JSREGISTERFUNC
  37. #endif
  38. #include "bannedwords.h"
  39. class IUiComponentGlobalInstanceBase
  40. {
  41. public:
  42. virtual void Tick() {}
  43. virtual void Shutdown() = 0;
  44. virtual void InstallScaleformBindings( int iSlot ) = 0;
  45. virtual void InstallPanoramaBindings() = 0;
  46. virtual void ShutdownComponentApiDef(int iSlot) = 0;
  47. };
  48. template < class T >
  49. class CUiComponentGlobalInstanceHelper : public IUiComponentGlobalInstanceBase
  50. {
  51. protected:
  52. static T* & InternalInstancePtr() { static T* s_pInstance = NULL; return s_pInstance; }
  53. public:
  54. static T* GetInstance()
  55. {
  56. if ( !InternalInstancePtr() )
  57. {
  58. InternalInstancePtr() = new T();
  59. }
  60. return InternalInstancePtr();
  61. }
  62. void Shutdown() OVERRIDE
  63. {
  64. T *pInstance = InternalInstancePtr();
  65. Assert( pInstance && (pInstance == this) );
  66. if ( pInstance && (pInstance == this) )
  67. {
  68. InternalInstancePtr() = NULL;
  69. delete pInstance;
  70. }
  71. }
  72. };
  73. #define UI_COMPONENT_DECLARE_GLOBAL_INSTANCE_ONLY( classname ) \
  74. protected: \
  75. friend class CUiComponentGlobalInstanceHelper< classname >; \
  76. void InstallScaleformBindings( int iSlot ) OVERRIDE; \
  77. void InstallPanoramaBindings( ) OVERRIDE; \
  78. void ShutdownComponentApiDef( int iSlot ) OVERRIDE; \
  79. classname(); \
  80. ~classname(); \
  81. private: \
  82. classname( const classname & other ); \
  83. classname & operator = ( const classname & other ); \
  84. DECLARE_PANORAMA_JSREGISTERFUNC
  85. #if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
  86. //-----------------------------------------------------------------------------
  87. // Purpose: Helpers for Scaleform events
  88. // The following macros and template functions allow Scaleform events to be declared
  89. // and broadcast using Panorama-style macros, so a single UI_COMPONENT_BROADCAST_EVENT
  90. // macro can broadcast both Panorama and Scaleform events.
  91. //-----------------------------------------------------------------------------
  92. namespace sfevents
  93. {
  94. template < typename T >
  95. void SetSFParam(KeyValues * pKv, const char* pName)
  96. {
  97. // Fallback for non-specialized types.
  98. pKv->SetInt(pName, 0);
  99. }
  100. template <> inline void SetSFParam< const char * >(KeyValues * pKv, const char* pName) { pKv->SetString(pName, ""); }
  101. template <> inline void SetSFParam< uint8 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
  102. template <> inline void SetSFParam< uint16 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
  103. template <> inline void SetSFParam< uint32 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
  104. template <> inline void SetSFParam< uint64 >(KeyValues * pKv, const char* pName) { pKv->SetUint64(pName, 0); }
  105. template <> inline void SetSFParam< int32 >(KeyValues * pKv, const char* pName) { pKv->SetInt(pName, 0); }
  106. template <> inline void SetSFParam< int64 >(KeyValues * pKv, const char* pName) { pKv->SetUint64(pName, 0); }
  107. template <> inline void SetSFParam< float >(KeyValues * pKv, const char* pName) { pKv->SetFloat(pName, 0.0f); }
  108. template <> inline void SetSFParam< bool >(KeyValues * pKv, const char* pName) { pKv->SetBool(pName, false); }
  109. template <> inline void SetSFParam< void* >(KeyValues * pKv, const char* pName) { pKv->SetPtr(pName, NULL); }
  110. inline void SetSFParamValues(KeyValues * pKv, ...)
  111. {
  112. va_list args;
  113. va_start(args, pKv);
  114. FOR_EACH_SUBKEY(pKv, pSubkey)
  115. {
  116. switch (pSubkey->GetDataType()) {
  117. case KeyValues::TYPE_STRING:
  118. pKv->SetString(pSubkey->GetName(), va_arg(args, const char*));
  119. break;
  120. case KeyValues::TYPE_INT:
  121. pKv->SetInt(pSubkey->GetName(), va_arg(args, int));
  122. break;
  123. case KeyValues::TYPE_FLOAT:
  124. pKv->SetFloat(pSubkey->GetName(), va_arg(args, double));
  125. break;
  126. case KeyValues::TYPE_UINT64:
  127. pKv->SetUint64(pSubkey->GetName(), va_arg(args, uint64));
  128. break;
  129. case KeyValues::TYPE_PTR:
  130. pKv->SetPtr(pSubkey->GetName(), va_arg(args, void*));
  131. break;
  132. default:
  133. Plat_FatalError("Invalid SF Event param type\n");
  134. break;
  135. }
  136. }
  137. }
  138. }
  139. #define SF_COMPONENT_EVENT_NAME( category, eventname ) "ScaleformComponent_" #category "_" #eventname
  140. #define SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ) g_ScaleformComponent_##category##_##eventname##_event
  141. #define SF_COMPONENT_DECLARE_EVENT0( category, eventname ) \
  142. class ScaleformComponent_##category##_##eventname##_event \
  143. { public: \
  144. ScaleformComponent_##category##_##eventname##_event() { m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); } \
  145. KeyValues* m_pKv; \
  146. }; \
  147. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  148. #define SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 ) \
  149. class ScaleformComponent_##category##_##eventname##_event \
  150. { public: \
  151. ScaleformComponent_##category##_##eventname##_event() { \
  152. m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
  153. sfevents::SetSFParam<param1>(m_pKv, param1_name); \
  154. } \
  155. KeyValues* m_pKv; \
  156. }; \
  157. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  158. #define SF_COMPONENT_DECLARE_EVENT2(category, eventname, param1_name, param1, param2_name, param2) \
  159. class ScaleformComponent_##category##_##eventname##_event \
  160. { public: \
  161. ScaleformComponent_##category##_##eventname##_event() { \
  162. m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
  163. sfevents::SetSFParam<param1>(m_pKv, param1_name); \
  164. sfevents::SetSFParam<param2>(m_pKv, param2_name); \
  165. } \
  166. KeyValues* m_pKv; \
  167. }; \
  168. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  169. #define SF_COMPONENT_DECLARE_EVENT3(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3) \
  170. class ScaleformComponent_##category##_##eventname##_event \
  171. { public: \
  172. ScaleformComponent_##category##_##eventname##_event() { \
  173. m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
  174. sfevents::SetSFParam<param1>(m_pKv, param1_name); \
  175. sfevents::SetSFParam<param2>(m_pKv, param2_name); \
  176. sfevents::SetSFParam<param3>(m_pKv, param3_name); \
  177. } \
  178. KeyValues* m_pKv; \
  179. }; \
  180. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  181. #define SF_COMPONENT_DECLARE_EVENT4(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4) \
  182. class ScaleformComponent_##category##_##eventname##_event \
  183. { public: \
  184. ScaleformComponent_##category##_##eventname##_event() { \
  185. m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
  186. sfevents::SetSFParam<param1>(m_pKv, param1_name); \
  187. sfevents::SetSFParam<param2>(m_pKv, param2_name); \
  188. sfevents::SetSFParam<param3>(m_pKv, param3_name); \
  189. sfevents::SetSFParam<param4>(m_pKv, param4_name); \
  190. } \
  191. KeyValues* m_pKv; \
  192. }; \
  193. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  194. #define SF_COMPONENT_DECLARE_EVENT5(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5) \
  195. class ScaleformComponent_##category##_##eventname##_event \
  196. { public: \
  197. ScaleformComponent_##category##_##eventname##_event() { \
  198. m_pKv = new KeyValues(SF_COMPONENT_EVENT_NAME(category, eventname)); \
  199. sfevents::SetSFParam<param1>(m_pKv, param1_name); \
  200. sfevents::SetSFParam<param2>(m_pKv, param2_name); \
  201. sfevents::SetSFParam<param3>(m_pKv, param3_name); \
  202. sfevents::SetSFParam<param4>(m_pKv, param4_name); \
  203. sfevents::SetSFParam<param5>(m_pKv, param5_name); \
  204. } \
  205. KeyValues* m_pKv; \
  206. }; \
  207. extern ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  208. #define SF_COMPONENT_DEFINE_EVENT(category, eventname) \
  209. ScaleformComponent_##category##_##eventname##_event SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname );
  210. #define SF_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
  211. { \
  212. KeyValues* pKv = SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ).m_pKv->MakeCopy(); \
  213. sfevents::SetSFParamValues(pKv, ##__VA_ARGS__); \
  214. if(g_pMatchFramework) g_pMatchFramework->GetEventsSubscription()->BroadcastEvent(pKv); \
  215. }
  216. #else // if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
  217. #define SF_COMPONENT_EVENT_NAME( category, eventname ) "ScaleformComponent_" #category "_" #eventname
  218. #define SF_COMPONENT_EVENT_OBJECT_NAME( category, eventname ) g_ScaleformComponent_##category##_##eventname##_event
  219. #define SF_COMPONENT_DECLARE_EVENT0( category, eventname )
  220. #define SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 )
  221. #define SF_COMPONENT_DECLARE_EVENT2(category, eventname, param1_name, param1, param2_name, param2)
  222. #define SF_COMPONENT_DECLARE_EVENT3(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3)
  223. #define SF_COMPONENT_DECLARE_EVENT4(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4)
  224. #define SF_COMPONENT_DECLARE_EVENT5(category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5)
  225. #define SF_COMPONENT_DEFINE_EVENT(category, eventname)
  226. #define SF_COMPONENT_BROADCAST_EVENT( category, eventname, ... )
  227. #endif // if defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)
  228. #ifdef USE_SCALEFORM_BINDINGS
  229. #define SF_COMPONENT_FUNCTION_NAME( fnname ) UiComponentFunction_##fnname
  230. // Should match SCALEFORM_CALLBACK_ARGS_DECL in uiscaleform.h
  231. #define SF_DEFAULT_PARAMS_DECL IUIMarshalHelper* pui, SFPARAMS obj
  232. #define SF_DEFAULT_PARAMS_PASS pui, obj
  233. #define SF_COMPONENT_FUNCTION( returntype, fnname ) \
  234. void SF_COMPONENT_FUNCTION_NAME(fnname)( SF_DEFAULT_PARAMS_DECL )
  235. #define SF_COMPONENT_FUNCTION_IMPL( classname, fnname ) \
  236. void classname::SF_COMPONENT_FUNCTION_NAME(fnname)( SF_DEFAULT_PARAMS_DECL )
  237. #define SF_COMPONENT_FUNCTION_DELEGATE( ptrcomponent, fnname ) \
  238. ( ptrcomponent )->SF_COMPONENT_FUNCTION_NAME( fnname )( SF_DEFAULT_PARAMS_PASS )
  239. #define SF_COMPONENT_API_DEF_BEGIN( componentclass ) \
  240. class componentclass##_Table : public IScaleformUIFunctionHandlerDefinitionTable \
  241. { \
  242. public: \
  243. virtual const ScaleformUIFunctionHandlerDefinition* GetTable( void ) const \
  244. { \
  245. static const ScaleformUIFunctionHandlerDefinition fnTable[] = {
  246. #define SF_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
  247. { #fnname, reinterpret_cast<ScaleformUIFunctionHandler>( &componentclass::SF_COMPONENT_FUNCTION_NAME( fnname ) ) },
  248. #define SF_COMPONENT_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass ) \
  249. { #fnname, reinterpret_cast<ScaleformUIFunctionHandler>( &componentclass::fnname ) }
  250. #define SF_COMPONENT_API_DEF_END( componentclass ) \
  251. { NULL, NULL } \
  252. }; \
  253. return fnTable; \
  254. } \
  255. }; \
  256. static componentclass##_Table g_##componentclass##_Table; \
  257. static SFVALUE g_##componentclass##_SFVALUE[SF_SLOT_IDS_COUNT];
  258. #define SF_COMPONENT_API_INSTALL( iSlot, componentclass, ptrInstance, componentname ) \
  259. do { \
  260. Assert( ( iSlot >= 0 ) && ( iSlot < SF_SLOT_IDS_COUNT ) ); \
  261. g_pScaleformUI->InstallGlobalObject( iSlot, "CScaleformComponent_" #componentname, \
  262. reinterpret_cast<ScaleformUIFunctionHandlerObject*>(static_cast<componentclass *>(ptrInstance)), \
  263. &g_##componentclass##_Table, \
  264. &g_##componentclass##_SFVALUE[iSlot] ); \
  265. } while( 0 )
  266. #define SF_COMPONENT_API_REMOVE( iSlot, componentclass ) \
  267. do { \
  268. Assert( ( iSlot >= 0 ) && ( iSlot < SF_SLOT_IDS_COUNT ) ); \
  269. g_pScaleformUI->RemoveGlobalObject( iSlot, g_##componentclass##_SFVALUE[iSlot] ); g_##componentclass##_SFVALUE[iSlot] = NULL; \
  270. } while( 0 )
  271. #define SF_INTEGRATION_XUID_PARAM( xuidVarName, iParam ) const char * xuidVarName = 0; { \
  272. if ( pui->Params_GetArgType( obj, iParam ) != IUIMarshalHelper::VT_String ) \
  273. { \
  274. AssertMsg( 0, __FUNCTION__ "ActionScript passed a non string param for xuid!\n" ); \
  275. return;\
  276. } \
  277. xuidVarName = ( pui->Params_GetArgAsString( obj, iParam ) ); \
  278. }
  279. #define SF_INTEGRATION_ITEMID_PARAM( itemidVarName, iParam ) itemid_t itemidVarName = 0; { \
  280. if ( pui->Params_GetArgType( obj, iParam ) != IUIMarshalHelper::VT_String ) \
  281. { \
  282. AssertMsg( 0, __FUNCTION__ " ActionScript passed a non string param for item id!\n" ); \
  283. return;\
  284. } \
  285. const char *pItemID = ( pui->Params_GetArgAsString( obj, iParam ) ); \
  286. if ( !pItemID ) \
  287. return; \
  288. itemidVarName = (uint64) Q_atoi64( pItemID ) ; \
  289. }
  290. #define SF_COMPONENT_NOTIFY_FLASH( category, eventname ) \
  291. if ( FlashAPIIsValid() ) \
  292. { \
  293. WITH_SLOT_LOCKED \
  294. { \
  295. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, SF_COMPONENT_EVENT_NAME( category, eventname ), NULL, 0 ); \
  296. } \
  297. }
  298. #define SF_COMPONENT_FORWARD_EVENT( szEvent ) \
  299. if ( StringHasPrefix( szEvent, "ScaleformComponent_" ) ) \
  300. { \
  301. if ( FlashAPIIsValid() ) \
  302. { \
  303. WITH_SLOT_LOCKED \
  304. { \
  305. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, szEvent, NULL, 0 ); \
  306. } \
  307. } \
  308. }
  309. #define SF_COMPONENT_HOST_DECL() \
  310. public: \
  311. CScaleformComponentHostSupport_ImageCacheHelper m_CScaleformComponentHostSupport_ImageCacheHelper; \
  312. void ScaleformComponentHost_EnsureAvatarCached( SF_DEFAULT_PARAMS_DECL ) \
  313. { \
  314. SF_INTEGRATION_XUID_PARAM( xuidUser, 0 ); \
  315. m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureAvatarCached( xuidUser ); \
  316. } \
  317. void ScaleformComponentHost_EnsureInventoryImageCached( SF_DEFAULT_PARAMS_DECL ) \
  318. { \
  319. SF_INTEGRATION_ITEMID_PARAM( itemID, 0 ); \
  320. m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureInventoryImageCached( itemID ); \
  321. } \
  322. void ScaleformComponentHost_EnsureItemDataImageCached( SF_DEFAULT_PARAMS_DECL ) \
  323. { \
  324. uint16 iDefIndex = ( uint16 ) pui->Params_GetArgAsNumber( obj, 0 ); \
  325. uint16 iPaintIndex = ( uint16 ) pui->Params_GetArgAsNumber( obj, 1 ); \
  326. m_CScaleformComponentHostSupport_ImageCacheHelper.EnsureItemDataImageCached( iDefIndex, iPaintIndex ); \
  327. } \
  328. void ScaleformComponentHost_GetScaleformComponentEventParamString( SF_DEFAULT_PARAMS_DECL ) \
  329. { \
  330. const char *pEventName = ( pui->Params_GetArgAsString( obj, 0 ) ); \
  331. const char *pParamName = ( pui->Params_GetArgAsString( obj, 1 ) ); \
  332. if ( !pEventName || !pParamName ) \
  333. return; \
  334. KeyValues *kvEventData = g_pMatchFramework->GetEventsSubscription()->GetEventData( pEventName ); \
  335. if ( !kvEventData ) \
  336. return; \
  337. pui->Params_SetResult( obj, kvEventData->GetString( pParamName, "" ) ); \
  338. } \
  339. #define SF_COMPONENT_HOST_IMAGE_CACHE_ENABLE( bEnable ) m_CScaleformComponentHostSupport_ImageCacheHelper.EnableCaching( bEnable )
  340. #define SF_COMPONENT_HOST_API_DEF() \
  341. { "EnsureAvatarCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureAvatarCached )}, \
  342. { "EnsureInventoryImageCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureInventoryImageCached )}, \
  343. { "EnsureItemDataImageCached", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_EnsureItemDataImageCached )}, \
  344. { "GetScaleformComponentEventParamString", reinterpret_cast<ScaleformUIFunctionHandler>( &T::ScaleformComponentHost_GetScaleformComponentEventParamString )} \
  345. // Registration of GC job handler for scaleform components
  346. #define SF_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn ) \
  347. class cjobclass : public GCSDK::CGCClientJob \
  348. { \
  349. public: \
  350. cjobclass( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) { } \
  351. virtual bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket ) \
  352. { \
  353. GCSDK::CProtoBufMsg<cmsgclass> msg( pNetPacket ); \
  354. ccomponentclass::GetInstance()->ccomponentfn( msg.Body() ); \
  355. return true; \
  356. } \
  357. }; \
  358. GC_REG_CLIENT_JOB( cjobclass, gcmsgid );
  359. inline char const * HelperSfGetStringParamSafe(SF_DEFAULT_PARAMS_DECL, int iParam, char const *szDefault = NULL)
  360. {
  361. if ((iParam >= 0)
  362. && (int(pui->Params_GetNumArgs(obj)) > iParam)
  363. && ( pui->Params_GetArgType( obj, iParam ) == IUIMarshalHelper::VT_String ) )
  364. return pui->Params_GetArgAsString(obj, iParam);
  365. else
  366. return szDefault;
  367. }
  368. #else // USE_SCALEFORM_BINDINGS
  369. #define SF_COMPONENT_FUNCTION_NAME( fnname )
  370. #define SF_DEFAULT_PARAMS_DECL
  371. #define SF_DEFAULT_PARAMS_PASS
  372. #define SF_COMPONENT_FUNCTION( returntype, fnname )
  373. #define SF_COMPONENT_FUNCTION_IMPL( classname, fnname )
  374. #define SF_COMPONENT_FUNCTION_DELEGATE( ptrcomponent, fnname )
  375. #define SF_COMPONENT_API_DEF_BEGIN( componentclass )
  376. #define SF_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass )
  377. #define SF_COMPONENT_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass )
  378. #define SF_COMPONENT_API_DEF_END( componentclass )
  379. #define SF_COMPONENT_API_INSTALL( iSlot, componentclass, ptrInstance )
  380. #define SF_COMPONENT_API_REMOVE( iSlot, componentclass )
  381. #define SF_INTEGRATION_XUID_PARAM( xuidVarName, iParam )
  382. #define SF_INTEGRATION_ITEMID_PARAM( itemidVarName, iParam )
  383. #define SF_COMPONENT_NOTIFY_FLASH( category, eventname )
  384. #define SF_COMPONENT_FORWARD_EVENT( szEvent )
  385. #define SF_COMPONENT_HOST_DECL()
  386. #define SF_COMPONENT_HOST_IMAGE_CACHE_ENABLE( bEnable )
  387. #define SF_COMPONENT_HOST_API_DEF()
  388. #define SF_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn )
  389. #endif // USE_SCALEFORM_BINDINGS
  390. #ifdef USE_PANORAMA_BINDINGS
  391. #define PANORAMA_COMPONENT_API_DEF_BEGIN( componentclass ) \
  392. void componentclass::JSRegisterFunc() \
  393. { \
  394. #define PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, argNames, description ) \
  395. panorama::RegisterJSMethod( #fnname, &componentclass::fnname, description, argNames );
  396. #define PANORAMA_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
  397. PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, "", "" )
  398. #define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, description ) \
  399. panorama::RegisterJSMethodRaw( #fnname, &componentclass::fnname, description );
  400. #define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF( returntype, fnname, componentclass ) \
  401. PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, "" )
  402. #define PANORAMA_COMPONENT_API_DEF_END( componentclass ) \
  403. }; \
  404. #define PANORAMA_COMPONENT_API_INSTALL( componentclass, ptrInstance, scriptVarName, description ) \
  405. do { \
  406. panorama::UIEngine()->StartRegisterJSScope( scriptVarName, description ); \
  407. CUtlDelegate< void() > del( ptrInstance, &componentclass::JSRegisterFunc ); \
  408. CUtlAbstractDelegate absDel = del.GetAbstractDelegate(); \
  409. panorama::UIEngine()->ExposeObjectTypeToJavaScript( #componentclass, absDel ); \
  410. panorama::UIEngine()->ExposeGlobalObjectToJavaScript(scriptVarName, ptrInstance, #componentclass, true); \
  411. panorama::UIEngine()->EndRegisterJSScope(); \
  412. } while (0)
  413. #define PANORAMA_COMPONENT_API_REMOVE( componentclass )
  414. #define PANORAMA_COMPONENT_EVENT_NAME( category, eventname ) PanoramaComponent_##category##_##eventname
  415. #define PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
  416. panorama::DispatchEvent(PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), NULL, ##__VA_ARGS__);
  417. #define PANORAMA_COMPONENT_BROADCAST_EVENT_WITH_PARAMS( category, eventname, ... ) \
  418. panorama::DispatchEvent(PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), NULL, ##__VA_ARGS__);
  419. #define PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname ) \
  420. DECLARE_PANORAMA_EVENT0(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ))
  421. #define PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 ) \
  422. DECLARE_PANORAMA_EVENT1(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1)
  423. #define PANORAMA_COMPONENT_DECLARE_EVENT2(category, eventname, param1, param2) \
  424. DECLARE_PANORAMA_EVENT2(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2)
  425. #define PANORAMA_COMPONENT_DECLARE_EVENT3(category, eventname, param1, param2, param3) \
  426. DECLARE_PANORAMA_EVENT3(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3)
  427. #define PANORAMA_COMPONENT_DECLARE_EVENT4(category, eventname, param1, param2, param3, param4) \
  428. DECLARE_PANORAMA_EVENT4(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3, param4)
  429. #define PANORAMA_COMPONENT_DECLARE_EVENT5(category, eventname, param1, param2, param3, param4, param5) \
  430. DECLARE_PANORAMA_EVENT5(PANORAMA_COMPONENT_EVENT_NAME( category, eventname ), param1, param2, param3, param4, param5)
  431. #define PANORAMA_COMPONENT_DEFINE_EVENT(category, eventname)\
  432. DEFINE_PANORAMA_EVENT(PANORAMA_COMPONENT_EVENT_NAME(category, eventname))
  433. #define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF( returntype, fnname, componentclass ) \
  434. RegisterJSMethodWithMarshallHelper( #fnname, &componentclass::SF_COMPONENT_FUNCTION_NAME( fnname ) );
  435. #define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass ) \
  436. RegisterJSMethodWithMarshallHelper( #fnname, &componentclass::fnname );
  437. // Helper class to allow the existing component functions to take a common object for param/return val handling
  438. // Allows existing SF component code which expects multiple return types or to sometimes not return a value to remain unchanged and be
  439. // called by new panorama js code if needed.
  440. class CPanoramaMarshallHelper : public IUIMarshalHelper
  441. {
  442. public:
  443. virtual SFVALUEARRAY Params_GetArgs( SFPARAMS params ) OVERRIDE;
  444. virtual unsigned int Params_GetNumArgs( SFPARAMS params ) OVERRIDE;
  445. virtual bool Params_ArgIs( SFPARAMS params, unsigned int index, _ValueType v ) OVERRIDE;
  446. virtual SFVALUE Params_GetArg( SFPARAMS params, int index = 0 ) OVERRIDE;
  447. virtual _ValueType Params_GetArgType( SFPARAMS params, int index = 0 ) OVERRIDE;
  448. virtual double Params_GetArgAsNumber( SFPARAMS params, int index = 0 ) OVERRIDE;
  449. virtual bool Params_GetArgAsBool( SFPARAMS params, int index = 0 ) OVERRIDE;
  450. virtual const char* Params_GetArgAsString( SFPARAMS params, int index = 0 ) OVERRIDE;
  451. virtual const wchar_t* Params_GetArgAsStringW( SFPARAMS params, int index = 0 ) OVERRIDE;
  452. virtual void Params_DebugSpew( SFPARAMS params ) OVERRIDE;
  453. virtual void Params_SetResult( SFPARAMS params, SFVALUE value ) OVERRIDE;
  454. virtual void Params_SetResult( SFPARAMS params, int value ) OVERRIDE;
  455. virtual void Params_SetResult( SFPARAMS params, float value ) OVERRIDE;
  456. virtual void Params_SetResult( SFPARAMS params, bool value ) OVERRIDE;
  457. virtual void Params_SetResult( SFPARAMS params, const char* value, bool bMakeNewValue = true ) OVERRIDE;
  458. virtual void Params_SetResult( SFPARAMS params, const wchar_t* value, bool bMakeNewValue = true ) OVERRIDE;
  459. virtual SFVALUE Params_CreateNewObject( SFPARAMS params ) OVERRIDE;
  460. virtual SFVALUE Params_CreateNewString( SFPARAMS params, const char* value ) OVERRIDE;
  461. virtual SFVALUE Params_CreateNewString( SFPARAMS params, const wchar_t* value ) OVERRIDE;
  462. virtual SFVALUE Params_CreateNewArray( SFPARAMS params, int size = -1 ) OVERRIDE;
  463. private:
  464. // Scratch storage for returning v8 string params. Grows to high water mark of param count.
  465. CUtlVector< CUtlString > m_vecStringStorage;
  466. };
  467. CPanoramaMarshallHelper *GetPanoramaMarshallHelper( void );
  468. template< typename ObjType >
  469. void JSMethodCallTupleWithMarshallHelper( const v8::FunctionCallbackInfo<v8::Value>& args )
  470. {
  471. v8::Isolate::Scope isolate_scope( args.GetIsolate() );
  472. v8::HandleScope handle_scope( args.GetIsolate() );
  473. ObjType *pPanel = panorama::GetThisPtrForJSCall<ObjType>( args.Holder() );
  474. if ( !pPanel )
  475. return;
  476. v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( args.Data() );
  477. panorama::HACKY_FUNC_PTR_CASTER< void ( ObjType::* )( IUIMarshalHelper* pui, SFPARAMS obj ) > caster;
  478. panorama::RestoreFuncPtr( caster, callbackArray, 0 );
  479. ( pPanel->*caster.funcPtr )( GetPanoramaMarshallHelper(), ( SFPARAMS ) &args );
  480. }
  481. template < typename ObjType >
  482. void RegisterJSMethodWithMarshallHelper( const char *pchMethodName, void ( ObjType::*mf )( IUIMarshalHelper* pui, SFPARAMS obj ), const char *pDesc = NULL )
  483. {
  484. v8::Isolate::Scope isolate_scope( panorama::GetV8Isolate() );
  485. v8::HandleScope handle_scope( panorama::GetV8Isolate() );
  486. v8::Handle<v8::Array> callbackArray = v8::Array::New( panorama::GetV8Isolate(), V8_CALLBACK_ARRAY_SIZE );
  487. panorama::GetPtrToCallbackArray( mf, callbackArray );
  488. v8::Handle<v8::ObjectTemplate> objTemplate = panorama::UIEngine()->GetCurrentV8ObjectTemplateToSetup();
  489. objTemplate->Set( v8::String::NewFromUtf8( panorama::GetV8Isolate(), pchMethodName ), v8::FunctionTemplate::New( panorama::GetV8Isolate(), &JSMethodCallTupleWithMarshallHelper<ObjType>, callbackArray ) );
  490. int nEntry = panorama::UIEngine()->NewRegisterJSEntry( pchMethodName, panorama::RegisterJSEntryInfo_t::k_EMethod, pDesc, panorama::k_ERegisterJSTypeVoid );
  491. panorama::RegisterJSType_t pParamTypes[ 1 ] = { panorama::k_ERegisterJSTypeRawV8Args };
  492. panorama::UIEngine()->SetRegisterJSEntryParams( nEntry, 1, pParamTypes, NULL );
  493. }
  494. #else // USE_PANORAMA_BINDINGS
  495. #define PANORAMA_COMPONENT_API_DEF_BEGIN( componentclass )
  496. #define PANORAMA_COMPONENT_FUNCTION_API_DEF( returntype, fnname, componentclass )
  497. #define PANORAMA_COMPONENT_FUNCTION_API_DEF_DOC( returntype, fnname, componentclass, argNames, description )
  498. #define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF( returntype, fnname, componentclass )
  499. #define PANORAMA_COMPONENT_FUNCTION_RAW_API_DEF_DOC( returntype, fnname, componentclass, description )
  500. #define PANORAMA_COMPONENT_API_DEF_END( componentclass )
  501. #define PANORAMA_COMPONENT_API_INSTALL( componentclass, ptrInstance, scriptVarName, description )
  502. #define PANORAMA_COMPONENT_API_REMOVE( componentclass )
  503. #define PANORAMA_COMPONENT_EVENT_NAME( category, eventname )
  504. #define PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ... )
  505. #define PANORAMA_COMPONENT_BROADCAST_EVENT_WITH_PARAMS( category, eventname, ... )
  506. #define PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname )
  507. #define PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 )
  508. #define PANORAMA_COMPONENT_DECLARE_EVENT2(category, eventname, param1, param2)
  509. #define PANORAMA_COMPONENT_DECLARE_EVENT3(category, eventname, param1, param2, param3)
  510. #define PANORAMA_COMPONENT_DECLARE_EVENT4(category, eventname, param1, param2, param3, param4)
  511. #define PANORAMA_COMPONENT_DECLARE_EVENT5(category, eventname, param1, param2, param3, param4, param5)
  512. #define PANORAMA_COMPONENT_DEFINE_EVENT(category, eventname)
  513. #define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF( returntype, fnname, componentclass )
  514. #define PANORAMA_COMPONENT_MARSHALL_HELPER_FUNCTION_API_DEF_NOPREFIX( returntype, fnname, componentclass )
  515. #endif // USE_PANORAMA_BINDINGS
  516. // 7ls - revisit shutdown code
  517. #define UI_COMPONENT_API_DEF_COMMON_DOC( componentclass, scriptVarName, description ) \
  518. void componentclass::InstallScaleformBindings(int iSlot) \
  519. { \
  520. SF_COMPONENT_API_INSTALL(iSlot, componentclass, this, scriptVarName); \
  521. } \
  522. void componentclass::InstallPanoramaBindings() \
  523. { \
  524. PANORAMA_COMPONENT_API_INSTALL(componentclass, this, #scriptVarName, description); \
  525. } \
  526. void componentclass::ShutdownComponentApiDef(int iSlot) \
  527. { \
  528. SF_COMPONENT_API_REMOVE(iSlot, componentclass); \
  529. PANORAMA_COMPONENT_API_REMOVE(componentclass); \
  530. }
  531. #define UI_COMPONENT_API_DEF_COMMON( componentclass, scriptVarName ) \
  532. UI_COMPONENT_API_DEF_COMMON_DOC( componentclass, scriptVarName, "" )
  533. #define UI_COMPONENT_BROADCAST_EVENT( category, eventname, ... ) \
  534. SF_COMPONENT_BROADCAST_EVENT( category, eventname, ##__VA_ARGS__ ) \
  535. PANORAMA_COMPONENT_BROADCAST_EVENT( category, eventname, ##__VA_ARGS__ )
  536. #define UI_COMPONENT_DECLARE_EVENT0( category, eventname ) \
  537. PANORAMA_COMPONENT_DECLARE_EVENT0( category, eventname ) \
  538. SF_COMPONENT_DECLARE_EVENT0( category, eventname )
  539. #define UI_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 ) \
  540. PANORAMA_COMPONENT_DECLARE_EVENT1( category, eventname, param1 ) \
  541. SF_COMPONENT_DECLARE_EVENT1( category, eventname, param1_name, param1 )
  542. #define UI_COMPONENT_DECLARE_EVENT2( category, eventname, param1_name, param1, param2_name, param2 ) \
  543. PANORAMA_COMPONENT_DECLARE_EVENT2( category, eventname, param1, param2 ) \
  544. SF_COMPONENT_DECLARE_EVENT2( category, eventname, param1_name, param1, param2_name, param2 )
  545. #define UI_COMPONENT_DECLARE_EVENT3( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3 ) \
  546. PANORAMA_COMPONENT_DECLARE_EVENT3( category, eventname, param1, param2, param3 ) \
  547. SF_COMPONENT_DECLARE_EVENT3( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3 )
  548. #define UI_COMPONENT_DECLARE_EVENT4( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4 ) \
  549. PANORAMA_COMPONENT_DECLARE_EVENT4( category, eventname, param1, param2, param3, param4 ) \
  550. SF_COMPONENT_DECLARE_EVENT4( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4 )
  551. #define UI_COMPONENT_DECLARE_EVENT5( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5 ) \
  552. PANORAMA_COMPONENT_DECLARE_EVENT5( category, eventname, param1, param2, param3, param4, param5 ) \
  553. SF_COMPONENT_DECLARE_EVENT5( category, eventname, param1_name, param1, param2_name, param2, param3_name, param3, param4_name, param4, param5_name, param5 )
  554. #define UI_COMPONENT_DEFINE_EVENT( category, eventname )\
  555. PANORAMA_COMPONENT_DEFINE_EVENT( category, eventname )\
  556. SF_COMPONENT_DEFINE_EVENT( category, eventname )
  557. // Only register Panorama cplusplus event handlers if not using Scaleform
  558. // (Otherwise handlers will be called twice)
  559. #if (defined (USE_PANORAMA_BINDINGS ) && !(defined (USE_SCALEFORM_BINDINGS) || defined (TEST_SCALEFORM_EVENTS)))
  560. #define UI_COMPONENT_REGISTER_EVENT_HANDLER(category, eventname, pObj, methodptr) \
  561. RegisterForUnhandledEvent( PANORAMA_COMPONENT_EVENT_NAME(category, eventname)(), pObj, methodptr );
  562. #else
  563. #define UI_COMPONENT_REGISTER_EVENT_HANDLER(category, eventname, pObj, methodptr)
  564. #endif
  565. #define UI_INTEGRATION_XUID_PARAM( xuidVarName, iParam ) XUID xuidVarName = 0; { \
  566. if ( pui->Params_GetArgType( obj, iParam ) != IScaleformUI::VT_String ) \
  567. { \
  568. AssertMsg1( 0, "%s UI code passed a non string param for xuid!\n", __FUNCTION__ ); \
  569. DevMsg( " error: Passed non-string param to %s for param %d.\n", __FUNCTION__, iParam ); \
  570. pui->Params_DebugSpew( obj ); \
  571. return;\
  572. } \
  573. const char *pFriendXuid = ( pui->Params_GetArgAsString( obj, iParam ) ); \
  574. if ( !pFriendXuid ) \
  575. { \
  576. /*AssertMsg( 0, __FUNCTION__ " passed an invalid xuid!\n" );*/ \
  577. } \
  578. CSteamID friendId( (uint64) Q_atoi64( pFriendXuid ) ); \
  579. if ( !friendId.IsValid() || !friendId.BIndividualAccount() ) \
  580. { \
  581. /*AssertMsg( 0, __FUNCTION__ " passed an invalid xuid!\n" );*/ \
  582. xuidVarName = 0; \
  583. } \
  584. else \
  585. { \
  586. xuidVarName = friendId.ConvertToUint64(); \
  587. } \
  588. }
  589. // Registration of GC job handler for ui component
  590. #define UI_COMPONENT_GC_REG_JOB( gcclientclass, cjobclass, cmsgclass, gcmsgid, ccomponentclass, ccomponentfn ) \
  591. class cjobclass : public GCSDK::CGCClientJob \
  592. { \
  593. public: \
  594. explicit cjobclass( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) { } \
  595. virtual bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket ) \
  596. { \
  597. GCSDK::CProtoBufMsg<cmsgclass> msg( pNetPacket ); \
  598. ccomponentclass::GetInstance()->ccomponentfn( msg.Body() ); \
  599. return true; \
  600. } \
  601. }; \
  602. GC_REG_CLIENT_JOB( cjobclass, gcmsgid );
  603. // Function decl/impl helpers for ui component code that will be called by scaleform and/or javascript
  604. #define UI_COMPONENT_FUNCTION_NAME( fnname ) UiComponentFunction_##fnname
  605. #define UI_DEFAULT_PARAMS_DECL IUIMarshalHelper* pui, SFPARAMS obj
  606. #define UI_DEFAULT_PARAMS_PASS pui, obj
  607. #define UI_COMPONENT_FUNCTION( returntype, fnname ) \
  608. void UI_COMPONENT_FUNCTION_NAME(fnname)( UI_DEFAULT_PARAMS_DECL )
  609. #define UI_COMPONENT_FUNCTION_IMPL( classname, fnname ) \
  610. void classname::UI_COMPONENT_FUNCTION_NAME(fnname)( UI_DEFAULT_PARAMS_DECL )
  611. inline char const * HelperUiGetStringParamSafe( UI_DEFAULT_PARAMS_DECL, int iParam, char const *szDefault = NULL )
  612. {
  613. if ( ( iParam >= 0 )
  614. && ( int( pui->Params_GetNumArgs( obj ) ) > iParam )
  615. && ( pui->Params_GetArgType( obj, iParam ) == IScaleformUI::VT_String ) )
  616. return pui->Params_GetArgAsString( obj, iParam );
  617. else
  618. return szDefault;
  619. }
  620. // Convert keyvalues to a json formatted string
  621. bool Helper_RecursiveKeyValuesToJSONString( const KeyValues* pKV, CUtlBuffer &outBuffer );
  622. #endif // UICOMPONENT_COMMON_H