Planeshift
|
00001 /* 00002 * msgmanager.h 00003 * 00004 * Copyright (C) 2005 Atomic Blue ([email protected], http://www.atomicblue.org) 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation (version 2 of the License) 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 */ 00019 #ifndef __MSGMANAGER_H__ 00020 #define __MSGMANAGER_H__ 00021 //============================================================================= 00022 // Crystal Space Includes 00023 //============================================================================= 00024 #include <csutil/ref.h> 00025 00026 //============================================================================= 00027 // Project Includes 00028 //============================================================================= 00029 #include "net/subscriber.h" // Subscriber class 00030 #include "net/message.h" // For msgtype typedef 00031 #include "util/eventmanager.h" 00032 #include "globals.h" 00033 00034 //============================================================================= 00035 // Local Includes 00036 //============================================================================= 00037 00038 class Client; 00039 class gemObject; 00040 class gemActor; 00041 class MsgEntry; 00042 class GEMSupervisor; 00043 00048 00049 00050 #define NO_VALIDATION 0x00 00051 #define REQUIRE_ANY_CLIENT 0x01 00052 #define REQUIRE_READY_CLIENT 0x02 00053 #define REQUIRE_ALREADY_READY_CLIENT 0x04 00054 #define REQUIRE_ACTOR 0x08 00055 #define REQUIRE_ALIVE 0x10 00056 #define REQUIRE_TARGET 0x20 00057 #define REQUIRE_TARGETACTOR 0x40 00058 #define REQUIRE_TARGETNPC 0x80 00059 00060 00067 class MessageManagerBase : public iNetSubscriber 00068 { 00069 public: 00070 00071 virtual bool Verify(MsgEntry* pMsg, unsigned int flags, Client* &client); 00072 00074 Client* FindPlayerClient(const char* name); 00075 00082 csArray<csString> DecodeCommandArea(Client* client, csString target); 00083 00093 gemObject* FindObjectByString(const csString &str, gemActor* me) const; 00094 }; 00095 00103 template <class SubClass> 00104 class MessageManager : public MessageManagerBase 00105 { 00106 public: 00107 typedef void(SubClass::*FunctionPointer)(MsgEntry*, Client*); 00108 00110 virtual ~MessageManager() 00111 { 00112 UnsubscribeAll(); 00113 } 00114 00124 inline void Subscribe(FunctionPointer fpt, msgtype type, uint32_t flags = 0x01) 00125 { 00126 CS::Threading::RecursiveMutexScopedLock lock(mutex); 00127 if(!handlers.Contains(type)) 00128 { 00129 GetEventManager()->Subscribe(this, type, flags); 00130 } 00131 handlers.Put(type, fpt); 00132 } 00133 00140 inline bool Unsubscribe(msgtype type) 00141 { 00142 CS::Threading::RecursiveMutexScopedLock lock(mutex); 00143 if(handlers.Contains(type)) 00144 { 00145 handlers.DeleteAll(type); 00146 return GetEventManager()->Unsubscribe(this, type); 00147 } 00148 return false; 00149 } 00150 00158 inline bool Unsubscribe(FunctionPointer handler, msgtype type) 00159 { 00160 CS::Threading::RecursiveMutexScopedLock lock(mutex); 00161 if(handlers.Contains(type)) 00162 { 00163 handlers.Delete(type, handler); 00164 if(!handlers.Contains(type)) 00165 { 00166 return GetEventManager()->Unsubscribe(this, type); 00167 } 00168 else 00169 { 00170 return true; 00171 } 00172 } 00173 else 00174 { 00175 return false; 00176 } 00177 } 00178 00184 inline bool UnsubscribeAll() 00185 { 00186 CS::Threading::RecursiveMutexScopedLock lock(mutex); 00187 handlers.Empty(); 00188 if(psserver->GetEventManager()) 00189 return GetEventManager()->UnsubscribeAll(this); 00190 return false; 00191 } 00192 00200 void HandleMessage(MsgEntry* msg, Client* client) 00201 { 00202 csArray<FunctionPointer> msgHandlers; 00203 { 00204 CS::Threading::RecursiveMutexScopedLock lock(mutex); 00205 msgHandlers = handlers.GetAll(msg->GetType()); 00206 } 00207 SubClass* self = dynamic_cast<SubClass*>(this); 00208 if(!self) 00209 { 00210 // fatal error, we aren't a base of our subclass! 00211 return; 00212 } 00213 00214 for(size_t i = 0; i < msgHandlers.GetSize(); ++i) 00215 { 00216 (self->*msgHandlers[i])(msg, client); 00217 } 00218 } 00219 00220 private: 00221 CS::Threading::RecursiveMutex mutex; 00222 csHash<FunctionPointer, msgtype> handlers; 00223 00231 inline EventManager* GetEventManager() const 00232 { 00233 EventManager* eventManager = psserver->GetEventManager(); 00234 CS_ASSERT(eventManager); 00235 return eventManager; 00236 } 00237 }; 00238 00241 #endif