00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00108
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 csWeakRef<iCelPlLayer> pl;
00126 csRefArray<celMessageDispatcher> messageDispatchers;
00127 celSubscriptions messageSubscriptions;
00128 public:
00129 celMessageChannel () : scfImplementationType (this) { }
00130 virtual ~celMessageChannel () { RemoveMessageDispatchers (); }
00131
00132 virtual iMessageChannel* QueryMessageChannel ()
00133 {
00134 return static_cast<iMessageChannel*> (this);
00135 }
00137 virtual csRef<iMessageDispatcher> CreateMessageDispatcher (
00138 iMessageSender* sender, const char* msg_id,
00139 iMessageReceiverFilter* receiver_filter = 0);
00140 virtual void RemoveMessageDispatcher (iMessageDispatcher* msgdisp);
00141 virtual void Subscribe (iMessageReceiver* receiver, const char* mask);
00142 virtual void Unsubscribe (iMessageReceiver* receiver, const char* mask = 0);
00143 virtual bool SendMessage (const char* msgid,
00144 iMessageSender* sender, iCelParameterBlock* params,
00145 iCelDataArray* ret = 0);
00146 void RemoveMessageDispatchers ();
00147 void SetPL (iCelPlLayer* pl) { celMessageChannel::pl = pl; }
00148 };
00149
00150 #endif // __CEL_CELTOOL_STDMSGCHANNEL__
00151