00001 #ifndef _MERCURYMESSAGES_H
00002 #define _MERCURYMESSAGES_H
00003
00004 #include "global.h"
00005 #include <map>
00006 #include "MercuryCommands.h"
00007 #include "MercuryThreads.h"
00008 #include "MercuryCallback.h"
00009 #include "MercuryVector.h"
00010 #include "MHeap.h"
00011
00012 #include <queue>
00013
00015 void* AutoUpdateMessages( void * data );
00016
00018 class MercuryMessageManager
00019 {
00020 public:
00021 MercuryMessageManager();
00022
00024 void Subscribe( const MString &name, MercuryCallback cb );
00025
00027 void Unsubscribe( const MString &name, MercuryCallback cb );
00028
00030 void BroadcastMessage( const MString &name, const PStack& args);
00031
00033 void PostSystemMessage( const MString &name, const PStack& args, float fTimeInFuture = 0 );
00034
00036 void Update( float fDeltaTime );
00037
00038 inline void SetupThread() { m_thread.Create(AutoUpdateMessages, this); }
00039 private:
00040 struct PostData
00041 {
00042 PostData(float t = 0, const MString& n = "", const PStack& stack = PStack())
00043 :time(t), name(n), data(stack)
00044 {}
00045 float time;
00046 MString name;
00047 PStack data;
00048 bool operator<(const PostData& t) const
00049 {
00050 return time < t.time;
00051 }
00052 bool operator>(const PostData& t) const
00053 {
00054 return time > t.time;
00055 }
00056 };
00057 volatile std::map < MString, MVector< MercuryCallback > > m_mCallbacks;
00058 volatile MHeap< PostData > m_mPostCodes;
00059
00060
00061 float m_fTotalTime;
00062
00063 MercuryThread m_thread;
00064
00065
00066
00067 MercuryMutex m_mutexCallback;
00068 MercuryMutex m_mutexPost;
00069 };
00070
00072 extern MercuryMessageManager *MESSAGEMAN;
00073
00074
00076
00082 class MercuryMessageSubscription
00083 {
00084 public:
00085 MercuryMessageSubscription( );
00086 MercuryMessageSubscription( const MString &name, MercuryCallback cb );
00087 ~MercuryMessageSubscription();
00089 void Subscribe( const MString &name, MercuryCallback cb );
00091 void Unsubscribe( );
00092 private:
00093 MString m_sName;
00094 MercuryCallback m_pCallback;
00095 };
00096
00097 class MercuryMessageHandler;
00098
00100 struct MercuryMessageObjectData
00101 {
00102 int m_iNumber;
00103 MercuryMessageHandler* m_qHandler;
00104 };
00105
00107 struct MercuryMessageObjectSubscription
00108 {
00109 public:
00110 MercuryMessageObjectSubscription( const MString &sName, MercuryMessageObjectData data, MercuryCallbackFunction handler );
00111 ~MercuryMessageObjectSubscription();
00112 inline const MString& GetName() const { return m_sName; }
00113 bool TestOwner(const MString& name, void* handler) const { if ((name == m_sName) && (m_pData.m_qHandler == handler)) { return true; } return false; }
00114 private:
00115 MString m_sName;
00116 MercuryCallback m_pCallback;
00117 MercuryMessageObjectData m_pData;
00118 };
00119
00121 class MercuryMessageHandler : public MercuryCommandHandler
00122 {
00123 public:
00125 virtual void Message( int Message, PStack & data, const MString & name ) {};
00126
00128 static void ProcessMessage( const MString & name, void * mudata, PStack & data );
00129
00131 void RegisterMessage( int messageID, const MString & name );
00132
00133 void UnregisterMessage( int messageID, const MString & name );
00134
00135 CLASS_RTTI( MercuryMessageHandler, MercuryCommandHandler );
00136 private:
00137 MDeque< MAutoPtr<MercuryMessageObjectSubscription> > m_lCallbacks;
00138 };
00139
00140 #define REGISTER_STATEMENT_TO_MESSAGE( type, message, code ) \
00141 void stregister_##type( const MString &message, void * info, PStack & args ) \
00142 { \
00143 code \
00144 } \
00145 MercuryMessageSubscription sub##type( #message, MercuryCallback( stregister_##type, 0 ) );
00146
00147
00148 void HGEXPORT BroadcastPreExisting( const char * sMessageName, int iMPStack );
00149
00150 #endif
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178