csutil/csevent.h
Go to the documentation of this file.00001 /* 00002 Crystal Space 3D engine: Event class interface 00003 Written by Andrew Zabolotny <bit@eltech.ru>, Jonathan Tarbox, 00004 Frank Richter, Adam D. Bradley <artdodge@cs.bu.edu> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public 00017 License along with this library; if not, write to the Free 00018 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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 // As per the XML pool, keep a reference to the pool container obejct 00319 // and this also allows our overridden DecRef() to place the event back 00320 // into the pool when users are done with it. 00321 csWeakRef<csEventQueue> pool; 00322 00323 // The next event in the pool, or null if the event is in use. 00324 csPoolEvent *next; 00325 00326 // The 'real' DecRef() call that deletes the event, should in theory only be 00327 // called from csEventQueue. 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__
Generated for Crystal Space 2.0 by doxygen 1.6.1