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.
252 lines
9.4 KiB
252 lines
9.4 KiB
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
|
|
|
|
#ifndef UI_NUGGET_H
|
|
#define UI_NUGGET_H
|
|
|
|
#include "game_controls/igameuisystemmgr.h"
|
|
#include "matchmaking/imatchframework.h"
|
|
#include "fmtstr.h"
|
|
#include "utlstringmap.h"
|
|
|
|
class CUiNuggetBase;
|
|
class CUiNuggetReference;
|
|
class CUiNuggetFactoryRegistrarBase;
|
|
class CUiNuggetFactoryRegistrarBaseInstances;
|
|
class CUiNuggetFactoryRegistrarBaseSingleton;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Base class for implementing UI nuggets
|
|
//
|
|
|
|
class CUiNuggetBase : public IGameUIScreenController
|
|
{
|
|
public:
|
|
CUiNuggetBase();
|
|
virtual ~CUiNuggetBase();
|
|
|
|
// IGameUIScreenController
|
|
public:
|
|
// Connects a screen to the controller, returns number of
|
|
// remaining connected screens (or 1 for the first connection)
|
|
virtual int OnScreenConnected( IGameUISystem *pScreenView );
|
|
|
|
// Releases the screen from controller, returns number of
|
|
// remaining connected screens (returns 0 if no screens are
|
|
// connected - new object must be reacquired from factory
|
|
// in this case)
|
|
virtual int OnScreenDisconnected( IGameUISystem *pScreenView );
|
|
|
|
// Callback for screen events handling
|
|
virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *kvEvent );
|
|
|
|
// Broadcast an event to all connected screens (caller retains ownership of keyvalues)
|
|
virtual void BroadcastEventToScreens( KeyValues *kvEvent );
|
|
|
|
public:
|
|
// Add a reference to the nugget to be notified upon release
|
|
virtual void AddReferenceSink( CUiNuggetReference *pSink ) { m_arrReferences.AddToTail( pSink ); }
|
|
|
|
protected:
|
|
// Policy for whether the object should be deleted when no screen references remain
|
|
virtual bool ShouldDeleteOnLastScreenDisconnect() { return true; }
|
|
|
|
protected:
|
|
struct ConnectionInfo_t
|
|
{
|
|
IGameUISystem *m_pScreen;
|
|
int m_nRefCount;
|
|
|
|
explicit ConnectionInfo_t( IGameUISystem *pScreen = NULL ) : m_pScreen( pScreen ), m_nRefCount( 0 ) {}
|
|
bool operator == ( ConnectionInfo_t const &other ) const { return m_pScreen == other.m_pScreen; }
|
|
};
|
|
typedef CUtlVector< ConnectionInfo_t > ConnectedScreens;
|
|
ConnectedScreens m_arrConnectedScreens;
|
|
CUtlVector< int > m_arrEventsDisabledScreenHandles;
|
|
|
|
KeyValues *m_pUiNuggetData;
|
|
KeyValues::AutoDelete m_autodelete_m_pUiNuggetData;
|
|
|
|
private:
|
|
CUtlVector< int * > m_arrBroadcastEventIdxArray;
|
|
CUtlVector< CUiNuggetReference * > m_arrReferences;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Declaration of UI nuggets factories
|
|
//
|
|
|
|
class CUiNuggetFactoryRegistrarBase : public IGameUIScreenControllerFactory
|
|
{
|
|
public:
|
|
CUiNuggetFactoryRegistrarBase();
|
|
~CUiNuggetFactoryRegistrarBase();
|
|
|
|
virtual void Register();
|
|
|
|
virtual char const *GetName() = 0;
|
|
|
|
public:
|
|
static void RegisterAll();
|
|
|
|
private:
|
|
CUiNuggetFactoryRegistrarBase *m_pPrev, *m_pNext;
|
|
};
|
|
|
|
class CUiNuggetFactoryRegistrarBaseGlobalInstance : public CUiNuggetFactoryRegistrarBase
|
|
{
|
|
public:
|
|
// Returns an instance of a controller interface
|
|
virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) = 0;
|
|
|
|
// Access controller instances
|
|
virtual int GetControllerInstancesCount() { return 1; }
|
|
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) = 0;
|
|
};
|
|
|
|
class CUiNuggetFactoryRegistrarBaseSingleton : public CUiNuggetFactoryRegistrarBase
|
|
{
|
|
friend class CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker;
|
|
public:
|
|
CUiNuggetFactoryRegistrarBaseSingleton();
|
|
|
|
public:
|
|
// Returns an instance of a controller interface
|
|
virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
|
|
|
|
// Access controller instances
|
|
virtual int GetControllerInstancesCount() { return !!m_pSingleton; }
|
|
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_pSingleton; }
|
|
|
|
public:
|
|
// Creates an instance of a controller interface
|
|
virtual CUiNuggetBase * CreateNewController() = 0;
|
|
|
|
protected:
|
|
CUiNuggetBase *m_pSingleton;
|
|
};
|
|
|
|
class CUiNuggetFactoryRegistrarBaseInstances : public CUiNuggetFactoryRegistrarBase
|
|
{
|
|
friend class CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker;
|
|
public:
|
|
// Returns an instance of a controller interface
|
|
virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
|
|
|
|
// Access controller instances
|
|
virtual int GetControllerInstancesCount() { return m_arrInstances.Count(); }
|
|
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_arrInstances.IsValidIndex( iIndex ) ? m_arrInstances[iIndex] : NULL; }
|
|
|
|
public:
|
|
// Creates an instance of a controller interface
|
|
virtual CUiNuggetBase * CreateNewController() = 0;
|
|
|
|
protected:
|
|
// Nugget instances
|
|
CUtlVector< CUiNuggetBase * > m_arrInstances;
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Macros to be used to declare UI nuggets factories
|
|
//
|
|
|
|
// Global instance factory - a nugget instance always exists in a global variable
|
|
// and is always shared with all screens.
|
|
#define UI_NUGGET_FACTORY_GLOBAL_INSTANCE( nuggetclassname, instanceptr, scriptname ) \
|
|
namespace { \
|
|
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseGlobalInstance \
|
|
{ \
|
|
virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) { return static_cast< nuggetclassname * >( instanceptr ); } \
|
|
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return static_cast< nuggetclassname * >( instanceptr ); } \
|
|
virtual char const * GetName() { return scriptname; } \
|
|
} \
|
|
g_factory_##nuggetclassname##_globalinstance; \
|
|
};
|
|
|
|
// Singleton factory - create a new nugget instance and share it with all screens
|
|
// until all references to the nugget are released and nugget is destroyed.
|
|
// If nugget policy is not deleting the nugget upon last release, then a single nugget
|
|
// instance will be created once and shared with all screens.
|
|
#define UI_NUGGET_FACTORY_SINGLETON( nuggetclassname, scriptname ) \
|
|
namespace { \
|
|
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseSingleton \
|
|
{ \
|
|
virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
|
|
virtual char const * GetName() { return scriptname; } \
|
|
} \
|
|
g_factory_##nuggetclassname##_singleton; \
|
|
};
|
|
|
|
// Instances factory - create a new nugget instance per each request.
|
|
// Screens need to implement own methods of sharing data from a single nugget
|
|
// instance. Nugget instance must be marked for delete upon last release.
|
|
#define UI_NUGGET_FACTORY_INSTANCES( nuggetclassname, scriptname ) \
|
|
namespace { \
|
|
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseInstances \
|
|
{ \
|
|
virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
|
|
virtual char const * GetName() { return scriptname; } \
|
|
} \
|
|
g_factory_##nuggetclassname##_instances; \
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Macros to be used to declare nuggets functions
|
|
//
|
|
|
|
#define DECLARE_NUGGET_FN_MAP( classname, baseclass ) \
|
|
typedef classname NuggetEventMapClass; \
|
|
typedef baseclass NuggetEventMapBaseClass; \
|
|
class NuggetEventMap : \
|
|
public CUtlStringMap< KeyValues * (classname::*)( IGameUISystem *pScreenView, KeyValues *args ) > \
|
|
{} \
|
|
m_NuggetEventMap; \
|
|
class NuggetPreBroadcastMap : \
|
|
public CUtlStringMap< bool (classname::*)( KeyValues *args ) > \
|
|
{} \
|
|
m_NuggetPreBroadcastMap; \
|
|
virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *args ) { \
|
|
char const *szEvent = args->GetName(); \
|
|
UtlSymId_t sym = m_NuggetEventMap.Find( szEvent ); \
|
|
if ( sym != m_NuggetEventMap.InvalidIndex() ) { \
|
|
return (this->* (m_NuggetEventMap[sym]) )( pScreenView, args ); \
|
|
} \
|
|
return NuggetEventMapBaseClass::OnScreenEvent( pScreenView, args ); \
|
|
} \
|
|
virtual void BroadcastEventToScreens( KeyValues *args ) { \
|
|
char const *szEvent = args->GetName(); \
|
|
UtlSymId_t sym = m_NuggetPreBroadcastMap.Find( szEvent ); \
|
|
if ( sym != m_NuggetPreBroadcastMap.InvalidIndex() ) { \
|
|
if ( ! (this->* (m_NuggetPreBroadcastMap[sym]) )( args ) ) return; \
|
|
} \
|
|
return NuggetEventMapBaseClass::BroadcastEventToScreens( args ); \
|
|
}
|
|
|
|
#define NUGGET_FN( eventname ) \
|
|
class eventname##_EventRegistrar { \
|
|
public: typedef eventname##_EventRegistrar ThisClass; \
|
|
eventname##_EventRegistrar() { \
|
|
NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) ); \
|
|
pNugget->m_NuggetEventMap[ #eventname ] = &NuggetEventMapClass::Event_##eventname; \
|
|
COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetEventMap ) ); \
|
|
} } m_##eventname##_EventRegistrar; \
|
|
KeyValues * Event_##eventname( IGameUISystem *pScreenView, KeyValues *args )
|
|
|
|
|
|
#define NUGGET_BROADCAST_FN( eventname ) \
|
|
class eventname##_BroadcastRegistrar { \
|
|
public: typedef eventname##_BroadcastRegistrar ThisClass; \
|
|
eventname##_BroadcastRegistrar() { \
|
|
NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) ); \
|
|
pNugget->m_NuggetPreBroadcastMap[ #eventname ] = &NuggetEventMapClass::Broadcast_##eventname; \
|
|
COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetPreBroadcastMap ) ); \
|
|
} } m_##eventname##_BroadcastRegistrar; \
|
|
bool Broadcast_##eventname( KeyValues *args )
|
|
|
|
|
|
#endif // UI_NUGGET_H
|