have Actors automatically subscribe to a message for each command that ends in "MessageCommand"

This commit is contained in:
Chris Danford
2005-02-23 18:53:54 +00:00
parent ed044bd2f9
commit 2e5b94e064
4 changed files with 67 additions and 20 deletions
+42 -7
View File
@@ -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
View File
@@ -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
// //
+7 -7
View File
@@ -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 );
} }
} }
+8 -4
View File
@@ -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;
}; };