csutil/csevent.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

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

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