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

Generated for Crystal Space 2.0 by doxygen 1.7.6.1