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