From: <cn...@us...> - 2009-10-26 22:17:05
|
Revision: 585 http://hgengine.svn.sourceforge.net/hgengine/?rev=585&view=rev Author: cnlohr Date: 2009-10-26 22:16:58 +0000 (Mon, 26 Oct 2009) Log Message: ----------- Add Delegates to the Mesage Manager. They help clean up the syntax for receiving messages, as it makes it possible for you to just call the function you want called based on message, so you don't have to have if clauses for messages. Modified Paths: -------------- Mercury2/src/Camera.cpp Mercury2/src/Camera.h Mercury2/src/MercuryMessageManager.cpp Mercury2/src/MercuryMessageManager.h Mercury2/src/ModuleManager.h Modified: Mercury2/src/Camera.cpp =================================================================== --- Mercury2/src/Camera.cpp 2009-10-26 02:00:33 UTC (rev 584) +++ Mercury2/src/Camera.cpp 2009-10-26 22:16:58 UTC (rev 585) @@ -11,8 +11,8 @@ :TransformNode(), m_x(0), m_y(0) { m_lookAt = MercuryVector(0,0,-1); - REGISTER_FOR_MESSAGE( INPUTEVENT_MOUSE ); - REGISTER_FOR_MESSAGE( "SetCameraPosition" ); + REGISTER_MESSAGE_WITH_DELEGATE( INPUTEVENT_MOUSE, &CameraNode::HandleMouseInput ); + REGISTER_MESSAGE_WITH_DELEGATE( "SetCameraPosition", &CameraNode::SetCameraPosition ); POST_MESSAGE("QueryTerrainPoint", new VertexDataMessage(m_origionalPosition), 0.00001); } @@ -80,39 +80,28 @@ // EYE.Print(); } -void CameraNode::HandleMessage(const MString& message, const MessageData& data) +void CameraNode::HandleMouseInput(const MessageData& data) { - if (message == INPUTEVENT_MOUSE) - { - const MouseInput& m( dynamic_cast<const MouseInput&>( data ) ); - - m_y += m.dy/1200.0f; - m_x += m.dx/1200.0f; - - m_y = Clamp((-Q_PI/2.0f)+0.00001f, (Q_PI/2.0f)-0.00001f, m_y); + const MouseInput& m( dynamic_cast<const MouseInput&>( data ) ); + + m_y += m.dy/1200.0f; + m_x += m.dx/1200.0f; + + m_y = Clamp((-Q_PI/2.0f)+0.00001f, (Q_PI/2.0f)-0.00001f, m_y); - MQuaternion qLeftRight = MQuaternion::CreateFromAxisAngle(MercuryVector(0,1,0), m_x); - MercuryVector LocalX = MercuryVector( 1, 0, 0 ); - LocalX = LocalX.Rotate( qLeftRight ); - - MQuaternion qUpDown = MQuaternion::CreateFromAxisAngle(LocalX, m_y); - -// qLeftRight.Print(); - - SetRotation(qUpDown*qLeftRight); -// GetRotation().Print(); -// POST_MESSAGE("QueryTerrainPoint", new MessageData(), 0); + MQuaternion qLeftRight = MQuaternion::CreateFromAxisAngle(MercuryVector(0,1,0), m_x); + MercuryVector LocalX = MercuryVector( 1, 0, 0 ); + LocalX = LocalX.Rotate( qLeftRight ); + + MQuaternion qUpDown = MQuaternion::CreateFromAxisAngle(LocalX, m_y); + + SetRotation(qUpDown*qLeftRight); +} - } - else if (message == "SetCameraPosition") - { -// LOG.Write("SetCamPosition"); - const VertexDataMessage& m( dynamic_cast<const VertexDataMessage&>( data ) ); - SetPosition(m.Vertex); -// Update(0); -// ComputeMatrix(); -// m->Vertex.Print(); - } +void CameraNode::SetCameraPosition(const MessageData& data) +{ + const VertexDataMessage& m( dynamic_cast<const VertexDataMessage&>( data ) ); + SetPosition(m.Vertex); } void CameraNode::Update(float dTime) Modified: Mercury2/src/Camera.h =================================================================== --- Mercury2/src/Camera.h 2009-10-26 02:00:33 UTC (rev 584) +++ Mercury2/src/Camera.h 2009-10-26 22:16:58 UTC (rev 585) @@ -9,10 +9,11 @@ public: CameraNode(); virtual void ComputeMatrix(); - virtual void HandleMessage(const MString& message, const MessageData& data); + virtual void HandleMouseInput(const MessageData& data); virtual void Update(float dTime); virtual void PreRender(const MercuryMatrix& matrix); virtual void Render(const MercuryMatrix& matrix); + virtual void SetCameraPosition(const MessageData& data); GENRTTI(CameraNode); private: Modified: Mercury2/src/MercuryMessageManager.cpp =================================================================== --- Mercury2/src/MercuryMessageManager.cpp 2009-10-26 02:00:33 UTC (rev 584) +++ Mercury2/src/MercuryMessageManager.cpp 2009-10-26 22:16:58 UTC (rev 585) @@ -46,24 +46,17 @@ } } -void MercuryMessageManager::RegisterForMessage(const MString& message, MessageHandler* ptr) -{ - MSemaphoreLock lock(&m_recipientLock); - m_messageRecipients[message].push_back(ptr); -} - void MercuryMessageManager::UnRegisterForMessage(const MString& message, MessageHandler* ptr) { MSemaphoreLock lock(&m_recipientLock); - std::list< MessageHandler* >& subscriptions = m_messageRecipients[message]; - std::list< MessageHandler* >::iterator i = subscriptions.begin(); + std::list< MessagePair >& subscriptions = m_messageRecipients[message]; + std::list< MessagePair >::iterator i = subscriptions.begin(); for (;i != subscriptions.end(); ++i) { - if (*i == ptr) + if ((*i).h == ptr) { - printf("Deleted subscription\n"); subscriptions.erase( i ); return; } @@ -71,22 +64,39 @@ } +void MercuryMessageManager::RegisterForMessage(const MString& message, MessageHandler* ptr, Delegate d ) +{ + MSemaphoreLock lock(&m_recipientLock); + m_messageRecipients[message].push_back(MessagePair(ptr, d)); + +} + + void MercuryMessageManager::FireOffMessage( const MessageHolder & message ) { - std::list< MessageHandler* > recipients; + std::list< MessagePair > recipients; { //copy list first (quick lock) MSemaphoreLock lock(&m_recipientLock); - std::list< MessageHandler* > * r = m_messageRecipients.get( message.message ); + std::list< MessagePair > * r = m_messageRecipients.get( message.message ); if ( r ) recipients = *r; } if ( !recipients.empty() ) { - std::list< MessageHandler* >::iterator recipient = recipients.begin(); + std::list< MessagePair >::iterator recipient = recipients.begin(); for (; recipient != recipients.end(); ++recipient) { - (*recipient)->HandleMessage(message.message, *(message.data) ); + MessagePair & mp = *recipient; + //Okay, the following lines look horrible. Reason is we're using + //a horrible horrible c++ construct from the anals of pointerdom. + //The idea is we're using a delegate. If we have a delegate, use it. + //If you are receiving a delegate, you do not need the message name. + //Otherwise, send a standard message through the old interface. + if( mp.d ) + (mp.h->*(mp.d))( *(message.data) ); + else + mp.h->HandleMessage(message.message, *(message.data) ); } } } Modified: Mercury2/src/MercuryMessageManager.h =================================================================== --- Mercury2/src/MercuryMessageManager.h 2009-10-26 02:00:33 UTC (rev 584) +++ Mercury2/src/MercuryMessageManager.h 2009-10-26 22:16:58 UTC (rev 585) @@ -24,6 +24,8 @@ static bool Compare( void * left, void * right ); }; +typedef void (MessageHandler::*Delegate)(const MessageData&); + /* This message system uses absolute integer time values to fire off events. This ensures accuarate firing times while eliminating floating point error. Because we use absolute times in the queue we do not need to "count down" the @@ -36,7 +38,7 @@ void PostMessage(const MString& message, MessageData* data, float delay); void PumpMessages(const uint64_t& currTime); - void RegisterForMessage(const MString& message, MessageHandler* ptr); + void RegisterForMessage(const MString& message, MessageHandler* ptr, Delegate d = 0 ); void UnRegisterForMessage(const MString& message, MessageHandler* ptr); static MercuryMessageManager& GetInstance(); @@ -46,9 +48,16 @@ PriorityQueue m_messageQueue; uint64_t m_currTime; //microseconds + + struct MessagePair + { + MessagePair( MessageHandler * th, Delegate td ) : h(th), d(td) { } + MessageHandler * h; + Delegate d; + }; + + MHash< std::list< MessagePair > > m_messageRecipients; - MHash< std::list< MessageHandler* > > m_messageRecipients; - // MercuryMutex m_lock; MSemaphore m_queueLock; MSemaphore m_recipientLock; @@ -57,6 +66,7 @@ static InstanceCounter<MercuryMessageManager> MMcounter("MessageManager"); #define MESSAGEMAN MercuryMessageManager +#define REGISTER_MESSAGE_WITH_DELEGATE(x, d) MESSAGEMAN::GetInstance().RegisterForMessage(x, this, (Delegate)d) #define REGISTER_FOR_MESSAGE(x) MESSAGEMAN::GetInstance().RegisterForMessage(x, this) #define UNREGISTER_FOR_MESSAGE(x) MESSAGEMAN::GetInstance().UnRegisterForMessage(x, this) #define POST_MESSAGE(x,data,delay) MESSAGEMAN::GetInstance().PostMessage(x, data, delay) Modified: Mercury2/src/ModuleManager.h =================================================================== --- Mercury2/src/ModuleManager.h 2009-10-26 02:00:33 UTC (rev 584) +++ Mercury2/src/ModuleManager.h 2009-10-26 22:16:58 UTC (rev 585) @@ -29,6 +29,7 @@ void RegisterInstance( void * instance, const char * sClass ); void UnregisterInstance( void * instance ); + const char * GetInstanceType( void * inst ) { return m_pAllInstanceTypes[inst]; } #endif private: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |