CrystalSpace

Public API Reference

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