csutil/cseventq.h
Go to the documentation of this file.00001 /* 00002 Crystal Space 3D engine: Event Queue interface 00003 Copyright (C) 1998 by Andrew Zabolotny <bit@freya.etu.ru> 00004 Copyright (C) 2001 by Eric Sunshine <sunshine@sunshineco.com> 00005 Copyright (C) 2005 by Adam D. Bradley <artdodge@cs.bu.edu> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public 00018 License along with this library; if not, write to the Free 00019 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 #ifndef __CS_CSEVENTQ_H__ 00023 #define __CS_CSEVENTQ_H__ 00024 00025 #ifdef ADB_DEBUG /* debugging output... */ 00026 #include <iostream> 00027 #endif 00028 00033 #include "csextern.h" 00034 00035 #include "csutil/array.h" 00036 #include "csutil/hash.h" 00037 #include "csutil/ref.h" 00038 #include "csutil/refarr.h" 00039 #include "csutil/scf_implementation.h" 00040 #include "csutil/threading/mutex.h" 00041 #include "csutil/weakref.h" 00042 #include "csutil/eventhandlers.h" 00043 #include "iutil/eventh.h" 00044 #include "iutil/eventq.h" 00045 #include "cssubscription.h" 00046 00047 struct iObjectRegistry; 00048 00049 class csEventCord; 00050 class csEventOutlet; 00051 class csPoolEvent; 00052 00057 #define DEF_EVENT_QUEUE_LENGTH 256 00058 00059 template<> 00060 class csHashComputer<iEventHandler *> : public csHashComputerIntegral<iEventHandler *> {}; 00061 00067 class CS_CRYSTALSPACE_EXPORT csEventQueue : 00068 public scfImplementation1<csEventQueue, iEventQueue> 00069 { 00070 friend class csEventOutlet; 00071 friend class csPoolEvent; 00072 friend class csEventTree; 00073 friend class csEventQueueTest; 00074 00075 private: 00076 // Shared-object registry 00077 iObjectRegistry* Registry; 00078 // Event name registry 00079 csRef<iEventNameRegistry> NameRegistry; 00080 // Event handler registry 00081 csRef<iEventHandlerRegistry> HandlerRegistry; 00082 // The queue itself (technically, a ring buffer) 00083 volatile iEvent** EventQueue; 00084 // Queue head and tail pointers 00085 volatile size_t evqHead, evqTail; 00086 // The maximum queue length 00087 volatile size_t Length; 00088 // Event tree. All subscription PO graphs and delivery queues hang off 00089 // of this. 00090 csEventTree *EventTree; 00091 // Shortcut to per-event-name delivery queues. 00092 csHash<csEventTree *,csEventID> EventHash; 00093 // Array of allocated event outlets. 00094 csArray<csEventOutlet*> EventOutlets; 00095 // Array of allocated event cords. 00096 csHash<csEventCord *, csEventID> EventCords; 00097 // Pool of event objects 00098 csPoolEvent* EventPool; 00100 csRefArray<iEventHandler> handlers; 00101 00102 // Enlarge the queue size. 00103 void Resize (size_t iLength); 00104 // Send broadcast pseudo-events (bypassing event queue). 00105 void Notify (const csEventID &name); 00106 00107 /* 00108 * Start a loop. The purpose of this function is to protect 00109 * against modifications to the Listeners array while this array 00110 * is being processed. 00111 */ 00112 void StartLoop (); 00113 // End a loop. 00114 void EndLoop (); 00115 00116 public: 00117 00119 csEventQueue (iObjectRegistry*, size_t iLength = DEF_EVENT_QUEUE_LENGTH); 00121 virtual ~csEventQueue (); 00122 00124 virtual void Process (); 00126 virtual void Dispatch (iEvent&); 00127 00129 virtual csHandlerID RegisterListener (iEventHandler*); 00131 virtual csHandlerID RegisterListener (iEventHandler *handler, 00132 const csEventID &event) 00133 { 00134 csHandlerID id = RegisterListener(handler); 00135 if (id!=CS_HANDLER_INVALID) 00136 { 00137 if (Subscribe(handler, event)) 00138 return id; 00139 else 00140 RemoveListener(handler); /* fall through */ 00141 } 00142 return CS_HANDLER_INVALID; 00143 } 00145 virtual csHandlerID RegisterListener (iEventHandler *handler, 00146 const csEventID events[]) 00147 { 00148 csHandlerID id = RegisterListener(handler); 00149 if (id!=CS_HANDLER_INVALID) 00150 { 00151 if (Subscribe(handler, events)) 00152 return id; 00153 else 00154 RemoveListener(handler); /* fall through */ 00155 } 00156 return CS_HANDLER_INVALID; 00157 } 00163 virtual bool Subscribe (iEventHandler*, const csEventID &); 00170 virtual bool Subscribe (iEventHandler*, const csEventID[]); 00176 virtual void Unsubscribe (iEventHandler*, const csEventID &); 00181 virtual void Unsubscribe (iEventHandler*, const csEventID[]); 00188 virtual void RemoveListener (iEventHandler*); 00193 virtual void RemoveAllListeners (); 00194 00196 virtual csPtr<iEventOutlet> CreateEventOutlet (iEventPlug*); 00198 virtual iEventOutlet* GetEventOutlet (); 00200 virtual iEventCord* GetEventCord (const csEventID &); 00201 00203 uint32 CountPool (); 00204 protected: 00205 virtual iEvent *CreateRawEvent (); 00206 public: 00208 virtual csPtr<iEvent> CreateEvent (); 00209 virtual csPtr<iEvent> CreateEvent (const csEventID &name, bool broadcast); 00210 virtual csPtr<iEvent> CreateEvent (const csEventID &name); 00211 virtual csPtr<iEvent> CreateEvent (const char *name); 00212 virtual csPtr<iEvent> CreateBroadcastEvent (const csEventID &name); 00213 virtual csPtr<iEvent> CreateBroadcastEvent (const char *name); 00215 virtual void Post (iEvent*); 00217 virtual csPtr<iEvent> Get (); 00219 virtual void Clear (); 00221 virtual bool IsEmpty () { return evqHead == evqTail; } 00222 00223 csEventID Frame; 00224 CS_DEPRECATED_VAR(csEventID PreProcess); 00225 CS_DEPRECATED_VAR(csEventID ProcessEvent); 00226 CS_DEPRECATED_VAR(csEventID PostProcess); 00227 CS_DEPRECATED_VAR(csEventID FinalProcess); 00228 00229 #include "csutil/deprecated_warn_off.h" 00230 00243 struct iTypedFrameEventDispatcher : public iEventHandler 00244 { 00245 protected: 00246 csWeakRef<csEventQueue> parent; 00247 csEventID sendEvent; 00248 public: 00249 iTypedFrameEventDispatcher () 00250 { 00251 } 00252 virtual ~iTypedFrameEventDispatcher () 00253 { 00254 } 00255 CS_EVENTHANDLER_DEFAULT_INSTANCE_CONSTRAINTS 00256 virtual bool HandleEvent (iEvent&) 00257 { 00258 parent->Notify (sendEvent); 00259 return false; 00260 } 00261 }; 00262 00263 class PreProcessFrameEventDispatcher 00264 : public scfImplementation2<PreProcessFrameEventDispatcher, 00265 csEventQueue::iTypedFrameEventDispatcher, 00266 scfFakeInterface<iEventHandler> > 00267 { 00268 public: 00269 PreProcessFrameEventDispatcher (csEventQueue* parent) 00270 : scfImplementationType (this) 00271 { 00272 iTypedFrameEventDispatcher::parent = parent; 00273 sendEvent = parent->PreProcess; 00274 } 00275 CS_EVENTHANDLER_PHASE_LOGIC("crystalspace.deprecated.preprocess") 00276 }; 00277 00278 class ProcessFrameEventDispatcher 00279 : public scfImplementation2<ProcessFrameEventDispatcher, 00280 csEventQueue::iTypedFrameEventDispatcher, 00281 scfFakeInterface<iEventHandler> > 00282 { 00283 public: 00284 ProcessFrameEventDispatcher (csEventQueue* parent) 00285 : scfImplementationType (this) 00286 { 00287 iTypedFrameEventDispatcher::parent = parent; 00288 sendEvent = parent->ProcessEvent; 00289 } 00290 CS_EVENTHANDLER_PHASE_3D("crystalspace.deprecated.process") 00291 }; 00292 00293 class PostProcessFrameEventDispatcher 00294 : public scfImplementation2<PostProcessFrameEventDispatcher, 00295 csEventQueue::iTypedFrameEventDispatcher, 00296 scfFakeInterface<iEventHandler> > 00297 { 00298 public: 00299 PostProcessFrameEventDispatcher (csEventQueue* parent) 00300 : scfImplementationType (this) 00301 { 00302 iTypedFrameEventDispatcher::parent = parent; 00303 sendEvent = parent->PostProcess; 00304 } 00305 CS_EVENTHANDLER_PHASE_2D("crystalspace.deprecated.postprocess") 00306 }; 00307 00308 class FinalProcessFrameEventDispatcher 00309 : public scfImplementation2<FinalProcessFrameEventDispatcher, 00310 csEventQueue::iTypedFrameEventDispatcher, 00311 scfFakeInterface<iEventHandler> > 00312 { 00313 public: 00314 FinalProcessFrameEventDispatcher (csEventQueue* parent) 00315 : scfImplementationType (this) 00316 { 00317 iTypedFrameEventDispatcher::parent = parent; 00318 sendEvent = parent->FinalProcess; 00319 } 00320 CS_EVENTHANDLER_PHASE_FRAME("crystalspace.deprecated.finalprocess") 00321 }; 00322 }; 00323 00324 #endif // __CS_CSEVENTQ_H__
Generated for Crystal Space 1.4.0 by doxygen 1.5.8