| ## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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 (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__