have Actors automatically subscribe to a message for each command that ends in "MessageCommand"
This commit is contained in:
+42
-7
@@ -14,6 +14,7 @@
|
|||||||
#include "ActorCommands.h"
|
#include "ActorCommands.h"
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "LuaReference.h"
|
#include "LuaReference.h"
|
||||||
|
#include "MessageManager.h"
|
||||||
|
|
||||||
|
|
||||||
// lua start
|
// lua start
|
||||||
@@ -64,7 +65,7 @@ void Actor::Reset()
|
|||||||
m_bZWrite = false;
|
m_bZWrite = false;
|
||||||
m_CullMode = CULL_NONE;
|
m_CullMode = CULL_NONE;
|
||||||
|
|
||||||
m_mapNameToCommands.clear();
|
UnsubcribeAndClearCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor::Actor()
|
Actor::Actor()
|
||||||
@@ -74,6 +75,35 @@ Actor::Actor()
|
|||||||
m_bFirstUpdate = true;
|
m_bFirstUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool GetMessageNameFromCommandName( const CString &sCommandName, CString &sMessageNameOut )
|
||||||
|
{
|
||||||
|
if( sCommandName.Right(7) == "Message" )
|
||||||
|
{
|
||||||
|
sMessageNameOut = sCommandName.Left(sCommandName.size()-7);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::UnsubcribeAndClearCommands()
|
||||||
|
{
|
||||||
|
FOREACHM_CONST( CString, apActorCommands, m_mapNameToCommands, e )
|
||||||
|
{
|
||||||
|
CString sMessage;
|
||||||
|
if( GetMessageNameFromCommandName(e->first, sMessage) )
|
||||||
|
MESSAGEMAN->Unsubscribe( this, sMessage );
|
||||||
|
}
|
||||||
|
m_mapNameToCommands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor::~Actor()
|
||||||
|
{
|
||||||
|
UnsubcribeAndClearCommands();
|
||||||
|
}
|
||||||
|
|
||||||
void Actor::LoadFromNode( const CString& sDir, const XNode* pNode )
|
void Actor::LoadFromNode( const CString& sDir, const XNode* pNode )
|
||||||
{
|
{
|
||||||
// Load Name, if any.
|
// Load Name, if any.
|
||||||
@@ -95,20 +125,18 @@ void Actor::LoadFromNode( const CString& sDir, const XNode* pNode )
|
|||||||
FOREACH_CONST_Attr( pNode, a )
|
FOREACH_CONST_Attr( pNode, a )
|
||||||
{
|
{
|
||||||
CString sKeyName = a->m_sName; /* "OnCommand" */
|
CString sKeyName = a->m_sName; /* "OnCommand" */
|
||||||
sKeyName.MakeLower();
|
|
||||||
|
|
||||||
if( sKeyName.Right(7) != "command" )
|
if( sKeyName.Right(7).CompareNoCase("Command") != 0 )
|
||||||
continue; /* not a command */
|
continue; /* not a command */
|
||||||
|
|
||||||
CString sValue = a->m_sValue;
|
CString sValue = a->m_sValue;
|
||||||
THEME->EvaluateString( sValue );
|
THEME->EvaluateString( sValue );
|
||||||
Commands cmds = ParseCommands( sValue );
|
apActorCommands apac( new ActorCommands( sValue ) );
|
||||||
apActorCommands apac( new ActorCommands( cmds ) );
|
|
||||||
|
|
||||||
CString sCmdName;
|
CString sCmdName;
|
||||||
/* Special case: "Command=foo" -> "OnCommand=foo" */
|
/* Special case: "Command=foo" -> "OnCommand=foo" */
|
||||||
if( sKeyName.size() == 7 )
|
if( sKeyName.size() == 7 )
|
||||||
sCmdName="on";
|
sCmdName="On";
|
||||||
else
|
else
|
||||||
sCmdName = sKeyName.Left( sKeyName.size()-7 );
|
sCmdName = sKeyName.Left( sKeyName.size()-7 );
|
||||||
AddCommand( sCmdName, apac );
|
AddCommand( sCmdName, apac );
|
||||||
@@ -997,12 +1025,14 @@ void Actor::QueueCommand( const CString& sCommandName )
|
|||||||
void Actor::AddCommand( const CString &sCmdName, apActorCommands apac )
|
void Actor::AddCommand( const CString &sCmdName, apActorCommands apac )
|
||||||
{
|
{
|
||||||
m_mapNameToCommands[sCmdName] = apac;
|
m_mapNameToCommands[sCmdName] = apac;
|
||||||
|
CString sMessage;
|
||||||
|
if( GetMessageNameFromCommandName(sCmdName, sMessage) )
|
||||||
|
MESSAGEMAN->Subscribe( this, sMessage );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::PlayCommand( const CString &sCommandName )
|
void Actor::PlayCommand( const CString &sCommandName )
|
||||||
{
|
{
|
||||||
CString sKey = sCommandName;
|
CString sKey = sCommandName;
|
||||||
sKey.MakeLower();
|
|
||||||
map<CString, apActorCommands>::const_iterator it = m_mapNameToCommands.find( sKey );
|
map<CString, apActorCommands>::const_iterator it = m_mapNameToCommands.find( sKey );
|
||||||
|
|
||||||
if( it == m_mapNameToCommands.end() )
|
if( it == m_mapNameToCommands.end() )
|
||||||
@@ -1011,6 +1041,11 @@ void Actor::PlayCommand( const CString &sCommandName )
|
|||||||
RunCommands( *it->second );
|
RunCommands( *it->second );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Actor::HandleMessage( const CString& sMessage )
|
||||||
|
{
|
||||||
|
PlayCommand( sMessage + "Message" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford
|
* (c) 2001-2004 Chris Danford
|
||||||
|
|||||||
+10
-2
@@ -11,6 +11,7 @@ struct XNode;
|
|||||||
struct lua_State;
|
struct lua_State;
|
||||||
class LuaReference;
|
class LuaReference;
|
||||||
#include "LuaBinding.h"
|
#include "LuaBinding.h"
|
||||||
|
#include "MessageManager.h"
|
||||||
|
|
||||||
|
|
||||||
#define DRAW_ORDER_BEFORE_EVERYTHING -100
|
#define DRAW_ORDER_BEFORE_EVERYTHING -100
|
||||||
@@ -18,11 +19,12 @@ class LuaReference;
|
|||||||
#define DRAW_ORDER_AFTER_EVERYTHING 200
|
#define DRAW_ORDER_AFTER_EVERYTHING 200
|
||||||
|
|
||||||
|
|
||||||
class Actor
|
class Actor : public IMessageSubscriber
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Actor();
|
Actor();
|
||||||
virtual ~Actor() {}
|
virtual ~Actor();
|
||||||
|
void UnsubcribeAndClearCommands();
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
void LoadFromNode( const CString& sDir, const XNode* pNode );
|
void LoadFromNode( const CString& sDir, const XNode* pNode );
|
||||||
|
|
||||||
@@ -317,6 +319,12 @@ public:
|
|||||||
static float GetCommandsLengthSeconds( const LuaReference& cmds );
|
static float GetCommandsLengthSeconds( const LuaReference& cmds );
|
||||||
static float GetCommandsLengthSeconds( const apActorCommands& cmds ) { return GetCommandsLengthSeconds( *cmds ); } // convenience
|
static float GetCommandsLengthSeconds( const apActorCommands& cmds ) { return GetCommandsLengthSeconds( *cmds ); } // convenience
|
||||||
|
|
||||||
|
//
|
||||||
|
// Messages
|
||||||
|
//
|
||||||
|
virtual void HandleMessage( const CString& sMessage );
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Animation
|
// Animation
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -15,19 +15,19 @@ MessageManager::~MessageManager()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageManager::Subscribe( Actor* pActor, const CString& sMessage )
|
void MessageManager::Subscribe( IMessageSubscriber* pSubscriber, const CString& sMessage )
|
||||||
{
|
{
|
||||||
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
SubscribersSet::iterator iter = subs.find(pActor);
|
SubscribersSet::iterator iter = subs.find(pSubscriber);
|
||||||
ASSERT_M( iter == subs.end(), "already subscribed" );
|
ASSERT_M( iter == subs.end(), "already subscribed" );
|
||||||
#endif
|
#endif
|
||||||
subs.insert( pActor );
|
subs.insert( pSubscriber );
|
||||||
}
|
}
|
||||||
void MessageManager::Unsubscribe( Actor* pActor, const CString& sMessage )
|
void MessageManager::Unsubscribe( IMessageSubscriber* pSubscriber, const CString& sMessage )
|
||||||
{
|
{
|
||||||
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
||||||
SubscribersSet::iterator iter = subs.find(pActor);
|
SubscribersSet::iterator iter = subs.find(pSubscriber);
|
||||||
ASSERT( iter != subs.end() );
|
ASSERT( iter != subs.end() );
|
||||||
subs.erase( iter );
|
subs.erase( iter );
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,9 @@ void MessageManager::Unsubscribe( Actor* pActor, const CString& sMessage )
|
|||||||
void MessageManager::Broadcast( const CString& sMessage )
|
void MessageManager::Broadcast( const CString& sMessage )
|
||||||
{
|
{
|
||||||
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
SubscribersSet& subs = m_MessageToSubscribers[sMessage];
|
||||||
FOREACHS_CONST( Actor*, subs, p )
|
FOREACHS_CONST( IMessageSubscriber*, subs, p )
|
||||||
{
|
{
|
||||||
(*p)->PlayCommand( sMessage );
|
(*p)->HandleMessage( sMessage );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
class Actor;
|
|
||||||
|
|
||||||
|
class IMessageSubscriber
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void HandleMessage( const CString& sMessage ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class MessageManager
|
class MessageManager
|
||||||
{
|
{
|
||||||
@@ -14,12 +18,12 @@ public:
|
|||||||
MessageManager();
|
MessageManager();
|
||||||
~MessageManager();
|
~MessageManager();
|
||||||
|
|
||||||
void Subscribe( Actor* pActor, const CString& sMessage );
|
void Subscribe( IMessageSubscriber* pSubscriber, const CString& sMessage );
|
||||||
void Unsubscribe( Actor* pActor, const CString& sMessage );
|
void Unsubscribe( IMessageSubscriber* pSubscriber, const CString& sMessage );
|
||||||
void Broadcast( const CString& sMessage );
|
void Broadcast( const CString& sMessage );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef set<Actor*> SubscribersSet;
|
typedef set<IMessageSubscriber*> SubscribersSet;
|
||||||
map<CString,SubscribersSet> m_MessageToSubscribers;
|
map<CString,SubscribersSet> m_MessageToSubscribers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user