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