00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CS_CSEVENT_H__
00022 #define __CS_CSEVENT_H__
00023
00024 #include "csextern.h"
00025
00026 #include "csutil/hash.h"
00027 #include "csutil/strset.h"
00028 #include "csutil/scf_implementation.h"
00029 #include "csutil/weakref.h"
00030
00031 #include "iutil/event.h"
00032 #include "hashr.h"
00033 #include "csendian.h"
00034 #include "weakref.h"
00035 #include "cseventq.h"
00036 #include "strset.h"
00037 #include "eventnames.h"
00038
00039 class csEventQueue;
00040
00045 class csEventAttributeIterator;
00046 class csEvent;
00047
00054 class CS_CRYSTALSPACE_EXPORT csEvent : public scfImplementation1<csEvent, iEvent>
00055 {
00056 private:
00057 struct attribute
00058 {
00059 union
00060 {
00061 int64 intVal;
00062 double doubleVal;
00063 char* bufferVal;
00064 iBase* ibaseVal;
00065 void* rawPtr;
00066 };
00067 csEventAttributeType type;
00068 size_t dataSize;
00069 attribute (csEventAttributeType t) { type = t; }
00070 attribute (const attribute &o)
00071 {
00072 type = o.type;
00073 intVal = o.intVal;
00074 dataSize = o.dataSize;
00075 if ((o.type == csEventAttrEvent) || (o.type == csEventAttriBase))
00076 ibaseVal->IncRef();
00077 if (type == csEventAttrDatabuffer)
00078 {
00079 bufferVal = new char[dataSize];
00080 memcpy(bufferVal, o.bufferVal,dataSize);
00081 }
00082 }
00083 ~attribute ()
00084 {
00085 if (type == csEventAttrDatabuffer)
00086 delete[] bufferVal;
00087 else if ((type == csEventAttrEvent) || (type == csEventAttriBase))
00088 ibaseVal->DecRef();
00089 }
00090 };
00091 csHash<attribute*, csStringID> attributes;
00092 friend class csEventAttributeIterator;
00093
00094 size_t count;
00095
00096 bool CheckForLoops(iEvent *current, iEvent *e);
00097
00098 template <class T>
00099 bool InternalAddInt (const char* name, T value)
00100 {
00101 if (attributes.In (GetKeyID (name))) return false;
00102 attribute* object = new attribute (csEventAttrInt);
00103 object->intVal = (int64)value;
00104 attributes.Put (GetKeyID (name), object);
00105 count++;
00106 return true;
00107 }
00108
00109 template <class T>
00110 bool InternalAddUInt (const char* name, T value)
00111 {
00112 if (attributes.In (GetKeyID (name))) return false;
00113 attribute* object = new attribute (csEventAttrUInt);
00114 object->intVal = (int64)value;
00115 attributes.Put (GetKeyID (name), object);
00116 count++;
00117 return true;
00118 }
00119
00120 csEventError InternalReportMismatch (attribute* attr) const
00121 {
00122 switch (attr->type)
00123 {
00124 case csEventAttrInt:
00125 return csEventErrMismatchInt;
00126 case csEventAttrUInt:
00127 return csEventErrMismatchUInt;
00128 case csEventAttrFloat:
00129 return csEventErrMismatchFloat;
00130 case csEventAttrDatabuffer:
00131 return csEventErrMismatchBuffer;
00132 case csEventAttrEvent:
00133 return csEventErrMismatchEvent;
00134 case csEventAttriBase:
00135 return csEventErrMismatchIBase;
00136 default:
00137 break;
00138 }
00139 return csEventErrUhOhUnknown;
00140 }
00141
00142 template <class T>
00143 csEventError InternalRetrieveInt (const char* name, T& value) const
00144 {
00145 attribute* object = attributes.Get (GetKeyID (name), 0);
00146 if (!object) return csEventErrNotFound;
00147 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt))
00148 {
00149 value = (T)object->intVal;
00150 const T rangeMin = (T)(1 << (sizeof(T) * 8 - 1));
00151 const T rangeMax = ~rangeMin;
00152 if ((object->intVal < rangeMin) || (object->intVal > rangeMax))
00153 return csEventErrLossy;
00154 else
00155 return csEventErrNone;
00156 }
00157 else
00158 {
00159 return InternalReportMismatch (object);
00160 }
00161 }
00162
00163 template <class T>
00164 csEventError InternalRetrieveUint (const char* name, T& value) const
00165 {
00166 attribute* object = attributes.Get (GetKeyID (name), 0);
00167 if (!object) return csEventErrNotFound;
00168 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt))
00169 {
00170 value = (T)object->intVal;
00171 const T rangeMax = (T)~0;
00172 if ((uint64)object->intVal > rangeMax)
00173 return csEventErrLossy;
00174 else
00175 return csEventErrNone;
00176 }
00177 else
00178 {
00179 return InternalReportMismatch (object);
00180 }
00181 }
00182
00183 static char const* GetTypeName (csEventAttributeType t);
00184 static csStringID GetKeyID (const char* key);
00185 static const char* GetKeyName (csStringID id);
00186
00187 protected:
00188 virtual csRef<iEvent> CreateEvent();
00189
00190 public:
00192 csEvent ();
00193
00198 csEvent (csEvent const&);
00199
00203 csEvent (csTicks iTime, csEventID iName, bool iBroadcast);
00204
00206 virtual ~csEvent ();
00207
00209 const csEventID GetName();
00210
00212 #define CS_CSEVENT_ADDINT(type) \
00213 virtual bool Add (const char* name, type value) \
00214 { return InternalAddInt (name, value); }
00215 CS_CSEVENT_ADDINT(int8)
00216 CS_CSEVENT_ADDINT(int16)
00217 CS_CSEVENT_ADDINT(int32)
00218 CS_CSEVENT_ADDINT(int64)
00219 #undef CS_CSEVENT_ADDINT
00220 #define CS_CSEVENT_ADDUINT(type) \
00221 virtual bool Add (const char* name, type value) \
00222 { return InternalAddUInt (name, value); }
00223 CS_CSEVENT_ADDUINT(uint8)
00224 CS_CSEVENT_ADDUINT(uint16)
00225 CS_CSEVENT_ADDUINT(uint32)
00226 CS_CSEVENT_ADDUINT(uint64)
00227 #undef CS_CSEVENT_ADDUINT
00228 virtual bool Add (const char *name, float v);
00229 virtual bool Add (const char *name, double v);
00230 virtual bool Add (const char *name, const char *v);
00231 virtual bool Add (const char *name, const void *v, size_t size);
00232 virtual bool Add (const char *name, bool v);
00233 virtual bool Add (const char *name, iEvent* v);
00234 virtual bool Add (const char *name, iBase* v);
00235 virtual bool Add (const char *name, void *v);
00236
00238 #define CS_CSEVENT_FINDINT(T) \
00239 virtual csEventError Retrieve (const char* name, T& value) const \
00240 { return InternalRetrieveInt (name, value); }
00241 CS_CSEVENT_FINDINT(int8)
00242 CS_CSEVENT_FINDINT(int16)
00243 CS_CSEVENT_FINDINT(int32)
00244 #undef CS_CSEVENT_FINDINT
00245 virtual csEventError Retrieve (const char* name, int64& value) const
00246 {
00247 attribute* object = attributes.Get (GetKeyID (name), 0);
00248 if (!object) return csEventErrNotFound;
00249 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt))
00250 {
00251 value = object->intVal;
00252 return csEventErrNone;
00253 }
00254 else
00255 {
00256 return InternalReportMismatch (object);
00257 }
00258 }
00259
00260 #define CS_CSEVENT_FINDUINT(T) \
00261 virtual csEventError Retrieve (const char* name, T& value) const \
00262 { return InternalRetrieveUint (name, value); }
00263 CS_CSEVENT_FINDUINT(uint8)
00264 CS_CSEVENT_FINDUINT(uint16)
00265 CS_CSEVENT_FINDUINT(uint32)
00266 #undef CS_CSEVENT_FINDUINT
00267 virtual csEventError Retrieve (const char* name, uint64& value) const
00268 {
00269 attribute* object = attributes.Get (GetKeyID (name), 0);
00270 if (!object) return csEventErrNotFound;
00271 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt))
00272 {
00273 value = (uint64)object->intVal;
00274 return csEventErrNone;
00275 }
00276 else
00277 {
00278 return InternalReportMismatch (object);
00279 }
00280 }
00281
00282 virtual csEventError Retrieve (const char *name, float &v) const;
00283 virtual csEventError Retrieve (const char *name, double &v) const;
00284 virtual csEventError Retrieve (const char *name, const char *&v) const;
00285 virtual csEventError Retrieve (const char *name, const void *&v,
00286 size_t &size) const;
00287 virtual csEventError Retrieve (const char *name, bool &v) const;
00288 virtual csEventError Retrieve (const char *name, csRef<iEvent> &v) const;
00289 virtual csEventError Retrieve (const char *name, csRef<iBase> &v) const;
00290 virtual csEventError Retrieve (const char *name, void* &v) const;
00291
00292 virtual bool AttributeExists (const char* name);
00293 virtual csEventAttributeType GetAttributeType (const char* name);
00294
00295 virtual bool Remove (const char *name);
00296 virtual bool RemoveAll ();
00297
00298 virtual csRef<iEventAttributeIterator> GetAttributeIterator();
00299
00300 virtual bool Print (int level = 0);
00301
00302 };
00303
00311 class CS_CRYSTALSPACE_EXPORT csPoolEvent : public csEvent
00312 {
00313 typedef csEvent superclass;
00314 friend class csEventQueue;
00315 friend class csEvent;
00316
00317 private:
00318
00319
00320
00321 csWeakRef<csEventQueue> pool;
00322
00323
00324 csPoolEvent *next;
00325
00326
00327
00328 void Free () { csEvent::DecRef(); }
00329
00330 protected:
00331 virtual csRef<iEvent> CreateEvent();
00332
00333 public:
00335 csPoolEvent (csEventQueue *q);
00336
00338 virtual void DecRef ();
00339 };
00340
00344 class csEventAttributeIterator :
00345 public scfImplementation1<csEventAttributeIterator, iEventAttributeIterator>
00346 {
00347 csHash<csEvent::attribute*, csStringID>::GlobalIterator iterator;
00348 public:
00349
00350 csEventAttributeIterator (
00351 csHash<csEvent::attribute*, csStringID>::GlobalIterator& iter)
00352 : scfImplementationType (this), iterator(iter)
00353 {
00354 }
00355
00356 virtual ~csEventAttributeIterator()
00357 {
00358 }
00359
00360 virtual bool HasNext()
00361 {
00362 return iterator.HasNext();
00363 }
00364 virtual const char* Next();
00365 virtual void Reset()
00366 {
00367 iterator.Reset();
00368 }
00369 };
00370
00371 #endif // __CS_CSEVENT_H__