From 2e5b94e064c6b53461b39f5aeeeabb110a98c814 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Wed, 23 Feb 2005 18:53:54 +0000 Subject: [PATCH] have Actors automatically subscribe to a message for each command that ends in "MessageCommand" --- stepmania/src/Actor.cpp | 49 +++++++++++++++++++++++++++----- stepmania/src/Actor.h | 12 ++++++-- stepmania/src/MessageManager.cpp | 14 ++++----- stepmania/src/MessageManager.h | 12 +++++--- 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/stepmania/src/Actor.cpp b/stepmania/src/Actor.cpp index c63eb6b848..f547550eb7 100644 --- a/stepmania/src/Actor.cpp +++ b/stepmania/src/Actor.cpp @@ -14,6 +14,7 @@ #include "ActorCommands.h" #include "ThemeManager.h" #include "LuaReference.h" +#include "MessageManager.h" // lua start @@ -64,7 +65,7 @@ void Actor::Reset() m_bZWrite = false; m_CullMode = CULL_NONE; - m_mapNameToCommands.clear(); + UnsubcribeAndClearCommands(); } Actor::Actor() @@ -74,6 +75,35 @@ Actor::Actor() 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 ) { // Load Name, if any. @@ -95,20 +125,18 @@ void Actor::LoadFromNode( const CString& sDir, const XNode* pNode ) FOREACH_CONST_Attr( pNode, a ) { CString sKeyName = a->m_sName; /* "OnCommand" */ - sKeyName.MakeLower(); - if( sKeyName.Right(7) != "command" ) + if( sKeyName.Right(7).CompareNoCase("Command") != 0 ) continue; /* not a command */ CString sValue = a->m_sValue; THEME->EvaluateString( sValue ); - Commands cmds = ParseCommands( sValue ); - apActorCommands apac( new ActorCommands( cmds ) ); + apActorCommands apac( new ActorCommands( sValue ) ); CString sCmdName; /* Special case: "Command=foo" -> "OnCommand=foo" */ if( sKeyName.size() == 7 ) - sCmdName="on"; + sCmdName="On"; else sCmdName = sKeyName.Left( sKeyName.size()-7 ); AddCommand( sCmdName, apac ); @@ -997,12 +1025,14 @@ void Actor::QueueCommand( const CString& sCommandName ) void Actor::AddCommand( const CString &sCmdName, apActorCommands apac ) { m_mapNameToCommands[sCmdName] = apac; + CString sMessage; + if( GetMessageNameFromCommandName(sCmdName, sMessage) ) + MESSAGEMAN->Subscribe( this, sMessage ); } void Actor::PlayCommand( const CString &sCommandName ) { CString sKey = sCommandName; - sKey.MakeLower(); map::const_iterator it = m_mapNameToCommands.find( sKey ); if( it == m_mapNameToCommands.end() ) @@ -1011,6 +1041,11 @@ void Actor::PlayCommand( const CString &sCommandName ) RunCommands( *it->second ); } +void Actor::HandleMessage( const CString& sMessage ) +{ + PlayCommand( sMessage + "Message" ); +} + /* * (c) 2001-2004 Chris Danford diff --git a/stepmania/src/Actor.h b/stepmania/src/Actor.h index b8c20e2282..379753495a 100644 --- a/stepmania/src/Actor.h +++ b/stepmania/src/Actor.h @@ -11,6 +11,7 @@ struct XNode; struct lua_State; class LuaReference; #include "LuaBinding.h" +#include "MessageManager.h" #define DRAW_ORDER_BEFORE_EVERYTHING -100 @@ -18,11 +19,12 @@ class LuaReference; #define DRAW_ORDER_AFTER_EVERYTHING 200 -class Actor +class Actor : public IMessageSubscriber { public: Actor(); - virtual ~Actor() {} + virtual ~Actor(); + void UnsubcribeAndClearCommands(); virtual void Reset(); void LoadFromNode( const CString& sDir, const XNode* pNode ); @@ -317,6 +319,12 @@ public: static float GetCommandsLengthSeconds( const LuaReference& cmds ); static float GetCommandsLengthSeconds( const apActorCommands& cmds ) { return GetCommandsLengthSeconds( *cmds ); } // convenience + // + // Messages + // + virtual void HandleMessage( const CString& sMessage ); + + // // Animation // diff --git a/stepmania/src/MessageManager.cpp b/stepmania/src/MessageManager.cpp index bbdf15089a..d9a392b4a8 100644 --- a/stepmania/src/MessageManager.cpp +++ b/stepmania/src/MessageManager.cpp @@ -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]; #if _DEBUG - SubscribersSet::iterator iter = subs.find(pActor); + SubscribersSet::iterator iter = subs.find(pSubscriber); ASSERT_M( iter == subs.end(), "already subscribed" ); #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::iterator iter = subs.find(pActor); + SubscribersSet::iterator iter = subs.find(pSubscriber); ASSERT( iter != subs.end() ); subs.erase( iter ); } @@ -35,9 +35,9 @@ void MessageManager::Unsubscribe( Actor* pActor, const CString& sMessage ) void MessageManager::Broadcast( const CString& sMessage ) { SubscribersSet& subs = m_MessageToSubscribers[sMessage]; - FOREACHS_CONST( Actor*, subs, p ) + FOREACHS_CONST( IMessageSubscriber*, subs, p ) { - (*p)->PlayCommand( sMessage ); + (*p)->HandleMessage( sMessage ); } } diff --git a/stepmania/src/MessageManager.h b/stepmania/src/MessageManager.h index aace0cd5e4..e6a8592c1e 100644 --- a/stepmania/src/MessageManager.h +++ b/stepmania/src/MessageManager.h @@ -5,8 +5,12 @@ #include #include -class Actor; +class IMessageSubscriber +{ +public: + virtual void HandleMessage( const CString& sMessage ) = 0; +}; class MessageManager { @@ -14,12 +18,12 @@ public: MessageManager(); ~MessageManager(); - void Subscribe( Actor* pActor, const CString& sMessage ); - void Unsubscribe( Actor* pActor, const CString& sMessage ); + void Subscribe( IMessageSubscriber* pSubscriber, const CString& sMessage ); + void Unsubscribe( IMessageSubscriber* pSubscriber, const CString& sMessage ); void Broadcast( const CString& sMessage ); private: - typedef set SubscribersSet; + typedef set SubscribersSet; map m_MessageToSubscribers; };