csutil/csevent.h
Go to the documentation of this file.00001 /* 00002 Crystal Space 3D engine: Event class interface 00003 Written by Andrew Zabolotny <[email protected]>, Jonathan Tarbox, 00004 Frank Richter, Adam D. Bradley <[email protected]> 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 }; 00066 csEventAttributeType type; 00067 size_t dataSize; 00068 attribute (csEventAttributeType t) { type = t; } 00069 attribute (const attribute &o) 00070 { 00071 type = o.type; 00072 intVal = o.intVal; 00073 dataSize = o.dataSize; 00074 if ((o.type == csEventAttrEvent) || (o.type == csEventAttriBase)) 00075 ibaseVal->IncRef(); 00076 if (type == csEventAttrDatabuffer) 00077 { 00078 bufferVal = new char[dataSize]; 00079 memcpy(bufferVal, o.bufferVal,dataSize); 00080 } 00081 } 00082 ~attribute () 00083 { 00084 if (type == csEventAttrDatabuffer) 00085 delete[] bufferVal; 00086 else if ((type == csEventAttrEvent) || (type == csEventAttriBase)) 00087 ibaseVal->DecRef(); 00088 } 00089 }; 00090 csHash<attribute*, csStringID> attributes; 00091 friend class csEventAttributeIterator; 00092 00093 size_t count; 00094 00095 bool CheckForLoops(iEvent *current, iEvent *e); 00096 00097 template <class T> 00098 bool InternalAddInt (const char* name, T value) 00099 { 00100 if (attributes.In (GetKeyID (name))) return false; 00101 attribute* object = new attribute (csEventAttrInt); 00102 object->intVal = (int64)value; 00103 attributes.Put (GetKeyID (name), object); 00104 count++; 00105 return true; 00106 } 00107 00108 template <class T> 00109 bool InternalAddUInt (const char* name, T value) 00110 { 00111 if (attributes.In (GetKeyID (name))) return false; 00112 attribute* object = new attribute (csEventAttrUInt); 00113 object->intVal = (int64)value; 00114 attributes.Put (GetKeyID (name), object); 00115 count++; 00116 return true; 00117 } 00118 00119 csEventError InternalReportMismatch (attribute* attr) const 00120 { 00121 switch (attr->type) 00122 { 00123 case csEventAttrInt: 00124 return csEventErrMismatchInt; 00125 case csEventAttrUInt: 00126 return csEventErrMismatchUInt; 00127 case csEventAttrFloat: 00128 return csEventErrMismatchFloat; 00129 case csEventAttrDatabuffer: 00130 return csEventErrMismatchBuffer; 00131 case csEventAttrEvent: 00132 return csEventErrMismatchEvent; 00133 case csEventAttriBase: 00134 return csEventErrMismatchIBase; 00135 default: 00136 break; 00137 } 00138 return csEventErrUhOhUnknown; 00139 } 00140 00141 template <class T> 00142 csEventError InternalRetrieveInt (const char* name, T& value) const 00143 { 00144 attribute* object = attributes.Get (GetKeyID (name), 0); 00145 if (!object) return csEventErrNotFound; 00146 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt)) 00147 { 00148 value = (T)object->intVal; 00149 const T rangeMin = (T)(1 << (sizeof(T) * 8 - 1)); 00150 const T rangeMax = ~rangeMin; 00151 if ((object->intVal < rangeMin) || (object->intVal > rangeMax)) 00152 return csEventErrLossy; 00153 else 00154 return csEventErrNone; 00155 } 00156 else 00157 { 00158 return InternalReportMismatch (object); 00159 } 00160 } 00161 00162 template <class T> 00163 csEventError InternalRetrieveUint (const char* name, T& value) const 00164 { 00165 attribute* object = attributes.Get (GetKeyID (name), 0); 00166 if (!object) return csEventErrNotFound; 00167 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt)) 00168 { 00169 value = (T)object->intVal; 00170 const T rangeMax = (T)~0; 00171 if ((uint64)object->intVal > rangeMax) 00172 return csEventErrLossy; 00173 else 00174 return csEventErrNone; 00175 } 00176 else 00177 { 00178 return InternalReportMismatch (object); 00179 } 00180 } 00181 00182 static char const* GetTypeName (csEventAttributeType t); 00183 static csStringID GetKeyID (const char* key); 00184 static const char* GetKeyName (csStringID id); 00185 00186 protected: 00187 virtual csRef<iEvent> CreateEvent(); 00188 00189 public: 00191 csEvent (); 00192 00197 csEvent (csEvent const&); 00198 00202 csEvent (csTicks iTime, csEventID iName, bool iBroadcast); 00203 00205 virtual ~csEvent (); 00206 00208 const csEventID GetName(); 00209 00211 #define CS_CSEVENT_ADDINT(type) \ 00212 virtual bool Add (const char* name, type value) \ 00213 { return InternalAddInt (name, value); } 00214 CS_CSEVENT_ADDINT(int8) 00215 CS_CSEVENT_ADDINT(int16) 00216 CS_CSEVENT_ADDINT(int32) 00217 CS_CSEVENT_ADDINT(int64) 00218 #undef CS_CSEVENT_ADDINT 00219 #define CS_CSEVENT_ADDUINT(type) \ 00220 virtual bool Add (const char* name, type value) \ 00221 { return InternalAddUInt (name, value); } 00222 CS_CSEVENT_ADDUINT(uint8) 00223 CS_CSEVENT_ADDUINT(uint16) 00224 CS_CSEVENT_ADDUINT(uint32) 00225 CS_CSEVENT_ADDUINT(uint64) 00226 #undef CS_CSEVENT_ADDUINT 00227 virtual bool Add (const char *name, float v); 00228 virtual bool Add (const char *name, double v); 00229 virtual bool Add (const char *name, const char *v); 00230 virtual bool Add (const char *name, const void *v, size_t size); 00231 virtual bool Add (const char *name, bool v); 00232 virtual bool Add (const char *name, iEvent* v); 00233 virtual bool Add (const char *name, iBase* v); 00234 00236 #define CS_CSEVENT_FINDINT(T) \ 00237 virtual csEventError Retrieve (const char* name, T& value) const \ 00238 { return InternalRetrieveInt (name, value); } 00239 CS_CSEVENT_FINDINT(int8) 00240 CS_CSEVENT_FINDINT(int16) 00241 CS_CSEVENT_FINDINT(int32) 00242 #undef CS_CSEVENT_FINDINT 00243 virtual csEventError Retrieve (const char* name, int64& value) const 00244 { 00245 attribute* object = attributes.Get (GetKeyID (name), 0); 00246 if (!object) return csEventErrNotFound; 00247 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt)) 00248 { 00249 value = object->intVal; 00250 return csEventErrNone; 00251 } 00252 else 00253 { 00254 return InternalReportMismatch (object); 00255 } 00256 } 00257 00258 #define CS_CSEVENT_FINDUINT(T) \ 00259 virtual csEventError Retrieve (const char* name, T& value) const \ 00260 { return InternalRetrieveUint (name, value); } 00261 CS_CSEVENT_FINDUINT(uint8) 00262 CS_CSEVENT_FINDUINT(uint16) 00263 CS_CSEVENT_FINDUINT(uint32) 00264 #undef CS_CSEVENT_FINDUINT 00265 virtual csEventError Retrieve (const char* name, uint64& value) const 00266 { 00267 attribute* object = attributes.Get (GetKeyID (name), 0); 00268 if (!object) return csEventErrNotFound; 00269 if ((object->type == csEventAttrInt) || (object->type == csEventAttrUInt)) 00270 { 00271 value = (uint64)object->intVal; 00272 return csEventErrNone; 00273 } 00274 else 00275 { 00276 return InternalReportMismatch (object); 00277 } 00278 } 00279 00280 virtual csEventError Retrieve (const char *name, float &v) const; 00281 virtual csEventError Retrieve (const char *name, double &v) const; 00282 virtual csEventError Retrieve (const char *name, const char *&v) const; 00283 virtual csEventError Retrieve (const char *name, const void *&v, 00284 size_t &size) const; 00285 virtual csEventError Retrieve (const char *name, bool &v) const; 00286 virtual csEventError Retrieve (const char *name, csRef<iEvent> &v) const; 00287 virtual csEventError Retrieve (const char *name, csRef<iBase> &v) const; 00288 00289 virtual bool AttributeExists (const char* name); 00290 virtual csEventAttributeType GetAttributeType (const char* name); 00291 00292 virtual bool Remove (const char *name); 00293 virtual bool RemoveAll (); 00294 00295 virtual csRef<iEventAttributeIterator> GetAttributeIterator(); 00296 00297 virtual bool Print (int level = 0); 00298 00299 }; 00300 00308 class CS_CRYSTALSPACE_EXPORT csPoolEvent : public csEvent 00309 { 00310 typedef csEvent superclass; 00311 friend class csEventQueue; 00312 friend class csEvent; 00313 00314 private: 00315 // As per the XML pool, keep a reference to the pool container obejct 00316 // and this also allows our overridden DecRef() to place the event back 00317 // into the pool when users are done with it. 00318 csWeakRef<csEventQueue> pool; 00319 00320 // The next event in the pool, or null if the event is in use. 00321 csPoolEvent *next; 00322 00323 // The 'real' DecRef() call that deletes the event, should in theory only be 00324 // called from csEventQueue. 00325 void Free () { csEvent::DecRef(); } 00326 00327 protected: 00328 virtual csRef<iEvent> CreateEvent(); 00329 00330 public: 00332 csPoolEvent (csEventQueue *q); 00333 00335 virtual void DecRef (); 00336 }; 00337 00341 class csEventAttributeIterator : 00342 public scfImplementation1<csEventAttributeIterator, iEventAttributeIterator> 00343 { 00344 csHash<csEvent::attribute*, csStringID>::GlobalIterator iterator; 00345 public: 00346 00347 csEventAttributeIterator ( 00348 csHash<csEvent::attribute*, csStringID>::GlobalIterator& iter) 00349 : scfImplementationType (this), iterator(iter) 00350 { 00351 } 00352 00353 virtual ~csEventAttributeIterator() 00354 { 00355 } 00356 00357 virtual bool HasNext() 00358 { 00359 return iterator.HasNext(); 00360 } 00361 virtual const char* Next(); 00362 virtual void Reset() 00363 { 00364 iterator.Reset(); 00365 } 00366 }; 00367 00368 #endif // __CS_CSEVENT_H__
Generated for Crystal Space by doxygen 1.4.7