celtool/stdmsgchannel.h
00001 /* 00002 Crystal Space Entity Layer 00003 Copyright (C) 2008 by Jorrit Tyberghein 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library 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 GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #ifndef __CEL_CELTOOL_STDMSGCHANNEL__ 00021 #define __CEL_CELTOOL_STDMSGCHANNEL__ 00022 00023 #include "csutil/refarr.h" 00024 #include "csutil/weakref.h" 00025 #include "csutil/weakrefarr.h" 00026 #include "csutil/hash.h" 00027 #include "physicallayer/pl.h" 00028 #include "physicallayer/messaging.h" 00029 #include "celtool/celtoolextern.h" 00030 00031 class celMessageSubscription 00032 { 00033 public: 00034 csWeakRef<iMessageReceiver> receiver; 00035 csString mask; 00036 inline friend bool operator< (const celMessageSubscription& sub1, 00037 const celMessageSubscription& sub2) 00038 { 00039 return sub1.mask < sub2.mask; 00040 } 00041 }; 00042 00043 class celMessageDispatcher : public scfImplementation1<celMessageDispatcher, 00044 iMessageDispatcher> 00045 { 00046 private: 00047 csStringID msg_id; 00048 csString message; 00049 csWeakRef<iMessageSender> sender; 00050 csWeakRefArray<iMessageReceiver> receivers; 00051 csRef<iMessageReceiverFilter> receiver_filter; 00052 00053 public: 00054 celMessageDispatcher (csStringID msg_id, const char* message, 00055 iMessageSender* sender, iMessageReceiverFilter* receiver_filter) 00056 : scfImplementationType (this), 00057 msg_id (msg_id), 00058 message (message), 00059 sender (sender), 00060 receiver_filter (receiver_filter) { } 00061 virtual ~celMessageDispatcher () { } 00062 virtual bool SendMessage (iCelParameterBlock* params, iCelDataArray* ret) 00063 { 00064 size_t i = 0; 00065 bool handled = false; 00066 while (i < receivers.GetSize ()) 00067 { 00068 if (receivers[i]) 00069 { 00070 celData ret1; 00071 bool rc = receivers[i]->ReceiveMessage (msg_id, sender, ret1, params); 00072 if (rc) 00073 { 00074 handled = true; 00075 if (ret1.type != CEL_DATA_NONE && ret) ret->Push (ret1); 00076 } 00077 i++; 00078 } 00079 else 00080 { 00081 receivers.DeleteIndex (i); 00082 } 00083 } 00084 return handled; 00085 } 00086 00087 csStringID GetMessageID () const { return msg_id; } 00088 const csString& GetMessage () const { return message; } 00089 00090 void AddReceiver (iMessageReceiver* receiver); 00091 00092 void RemoveReceiver (iMessageReceiver* receiver) 00093 { 00094 size_t i = 0; 00095 while (i < receivers.GetSize ()) 00096 { 00097 if (receivers[i] == receiver) 00098 receivers.DeleteIndex (i); 00099 else 00100 i++; 00101 } 00102 } 00103 00104 iMessageSender* GetSender () const { return sender; } 00105 }; 00106 00107 // SafeCopyElementHandler has to be used here, as otherwise the weakref's in 00108 // the celMessageSubscription get memcopyed and thats not allowed. 00109 typedef csHash<celMessageSubscription,csPtrKey<iMessageReceiver>, 00110 CS::Memory::AllocatorMalloc, 00111 csArraySafeCopyElementHandler< 00112 CS::Container::HashElement<celMessageSubscription, 00113 csPtrKey<iMessageReceiver> > > > 00114 celSubscriptions; 00115 00121 class CEL_CELTOOL_EXPORT celMessageChannel : public scfImplementation1< 00122 celMessageChannel, iMessageChannel> 00123 { 00124 private: 00125 csArray<celMessageSubscription,csArraySafeCopyElementHandler<celMessageSubscription> > subscriptionQueue; 00126 csArray<celMessageSubscription,csArraySafeCopyElementHandler<celMessageSubscription> > unsubscriptionQueue; 00127 csWeakRef<iCelPlLayer> pl; 00128 csRefArray<celMessageDispatcher> messageDispatchers; 00129 celSubscriptions messageSubscriptions; 00130 int sending; 00131 public: 00132 celMessageChannel () : scfImplementationType (this) { sending = 0; } 00133 virtual ~celMessageChannel () { RemoveMessageDispatchers (); } 00134 00135 virtual iMessageChannel* QueryMessageChannel () 00136 { 00137 return static_cast<iMessageChannel*> (this); 00138 } 00140 virtual csRef<iMessageDispatcher> CreateMessageDispatcher ( 00141 iMessageSender* sender, const char* msg_id, 00142 iMessageReceiverFilter* receiver_filter = 0); 00143 virtual void RemoveMessageDispatcher (iMessageDispatcher* msgdisp); 00144 virtual void Subscribe (iMessageReceiver* receiver, const char* mask); 00145 virtual void Unsubscribe (iMessageReceiver* receiver, const char* mask = 0); 00146 virtual bool SendMessage (const char* msgid, 00147 iMessageSender* sender, iCelParameterBlock* params, 00148 iCelDataArray* ret = 0); 00149 void RemoveMessageDispatchers (); 00150 void SetPL (iCelPlLayer* pl) { celMessageChannel::pl = pl; } 00151 }; 00152 00153 #endif // __CEL_CELTOOL_STDMSGCHANNEL__ 00154
Generated for CEL: Crystal Entity Layer 1.4.1 by doxygen 1.7.1