X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fstructure%2Fevent_mgr.hxx;h=b8dda323fb7e7c15f4ae3156a69b1d52b99702dc;hb=5b92575ed31ab0577d5ece4da42a88cfb88b4ad7;hp=bcfd2d2500b1a32242771ee9b28f4348f0ba2589;hpb=d22640ef4e938b523bdc30cd83370977d30de856;p=simgear.git diff --git a/simgear/structure/event_mgr.hxx b/simgear/structure/event_mgr.hxx index bcfd2d25..b8dda323 100644 --- a/simgear/structure/event_mgr.hxx +++ b/simgear/structure/event_mgr.hxx @@ -1,209 +1,132 @@ -// eventmMgr.hxx -- periodic event scheduler -// -// Written by Curtis Olson, started December 1997. -// Modified by Bernie Bright, April 2002. -// -// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// $Id$ - -#ifndef SG_EVENT_MGR_HXX -#define SG_EVENT_MGR_HXX 1 - -#include - -#include -#include -#include - -#include -#include +#ifndef _SG_EVENT_MGR_HXX +#define _SG_EVENT_MGR_HXX -SG_USING_STD(vector); -SG_USING_STD(string); +#include +#include +#include "callback.hxx" -class SGEvent -{ +class SGEventMgr; +class SGTimer { public: + ~SGTimer(); + void run(); + + std::string name; + double interval; + SGCallback* callback; + bool repeat; + bool running; +}; - typedef int interval_type; - -private: - - string _name; - SGCallback* _callback; - SGSubsystem* _subsystem; - interval_type _repeat_value; - interval_type _initial_value; - int _ms_to_go; - - unsigned long _cum_time; // cumulative processor time of this event - unsigned long _min_time; // time of quickest execution - unsigned long _max_time; // time of slowest execution - unsigned long _count; // number of times executed - +class SGTimerQueue { public: + SGTimerQueue(int preSize=1); + ~SGTimerQueue(); - /** - * - */ - SGEvent(); + void update(double deltaSecs); - SGEvent( const char* desc, - SGCallback* cb, - interval_type repeat_value, - interval_type initial_value ); + double now() { return _now; } - SGEvent( const char* desc, - const SGSubsystem* subsystem, - interval_type repeat_value, - interval_type initial_value ); + void insert(SGTimer* timer, double time); + SGTimer* remove(SGTimer* timer); + SGTimer* remove(); - /** - * - */ - ~SGEvent(); + SGTimer* nextTimer() { return _numEntries ? _table[0].timer : 0; } + double nextTime() { return -_table[0].pri; } - /** - * - */ - inline void reset() - { - _ms_to_go = _repeat_value; + SGTimer* findByName(const std::string& name) const; +private: + // The "priority" is stored as a negative time. This allows the + // implementation to treat the "top" of the heap as the largest + // value and avoids developer mindbugs. ;) + struct HeapEntry { double pri; SGTimer* timer; }; + + int parent(int n) { return ((n+1)/2) - 1; } + int lchild(int n) { return ((n+1)*2) - 1; } + int rchild(int n) { return ((n+1)*2 + 1) - 1; } + double pri(int n) { return _table[n].pri; } + void swap(int a, int b) { + HeapEntry tmp = _table[a]; + _table[a] = _table[b]; + _table[b] = tmp; } + void siftDown(int n); + void siftUp(int n); + void growArray(); - /** - * Execute this event's callback. - */ - void run(); - - inline string name() const { return _name; } - inline interval_type repeat_value() const { return _repeat_value; } - inline int value() const { return _ms_to_go; } - - /** - * Display event statistics. - */ - void print_stats() const; + // gcc complains there is no function specification anywhere. + // void check(); - /** - * Update the elapsed time for this event. - * @param dt_ms elapsed time in milliseconds. - * @return true if elapsed time has expired. - */ - inline bool update( int dt_ms ) - { - return (_ms_to_go -= dt_ms) <= 0; - } + double _now; + HeapEntry *_table; + int _numEntries; + int _tableSize; }; - class SGEventMgr : public SGSubsystem { -private: - - typedef SGEvent::interval_type interval_type; - typedef vector< SGEvent > event_container_type; - - void add( const SGEvent& event ); - - // registered events. - event_container_type event_table; +public: + SGEventMgr() { _rtProp = 0; } + ~SGEventMgr() { _rtProp = 0; } + virtual void init() {} + virtual void update(double delta_time_sec); -public: - SGEventMgr(); - ~SGEventMgr(); + void setRealtimeProperty(SGPropertyNode* node) { _rtProp = node; } /** - * Initialize the scheduling subsystem. + * Add a single function callback event as a repeating task. + * ex: addTask("foo", &Function ... ) */ - void init(); - void reinit(); - void bind(); - void unbind(); - - /* - * Update the elapsed time for all events. - * @param dt elapsed time in seconds. - */ - void update( double dt ); + template + inline void addTask(const std::string& name, const FUNC& f, + double interval, double delay=0, bool sim=false) + { add(name, make_callback(f), interval, delay, true, sim); } /** - * register a free standing function to be executed some time in the future. - * @param desc A brief description of this callback for logging. - * @param cb The callback function to be executed. - * @param repeat_value repetition rate in milliseconds. - * @param initial_value initial delay value in milliseconds. A value of - * -1 means run immediately. + * Add a single function callback event as a one-shot event. + * ex: addEvent("foo", &Function ... ) */ - template< typename Fun > - inline void add( const char* name, - const Fun& f, - interval_type repeat_value, - interval_type initial_value = -1 ) - { - this->add( SGEvent( name, - make_callback(f), - repeat_value, - initial_value ) ); - } + template + inline void addEvent(const std::string& name, const FUNC& f, + double delay, bool sim=false) + { add(name, make_callback(f), 0, delay, false, sim); } /** - * register a subsystem of which the update function will be executed some - * time in the future. - * @param desc A brief description of this callback for logging. - * @param subsystem The subsystem of which the update function will be - * executed. - * @param repeat_value repetition rate in milliseconds. - * @param initial_value initial delay value in milliseconds. A value of - * -1 means run immediately. + * Add a object/method pair as a repeating task. + * ex: addTask("foo", &object, &ClassName::Method, ...) */ - inline void add( const char* name, - const SGSubsystem* subsystem, - interval_type repeat_value, - interval_type initial_value = -1 ) - { - this->add( SGEvent( name, - subsystem, - repeat_value, - initial_value ) ); - } - - template< class ObjPtr, typename MemFn > - inline void add( const char* name, - const ObjPtr& p, - MemFn pmf, - interval_type repeat_value, - interval_type initial_value = -1 ) - { - this->add( SGEvent( name, - make_callback(p,pmf), - repeat_value, - initial_value ) ); - } + template + inline void addTask(const std::string& name, + const OBJ& o, METHOD m, + double interval, double delay=0, bool sim=false) + { add(name, make_callback(o,m), interval, delay, true, sim); } /** - * Display statistics for all registered events. + * Add a object/method pair as a repeating task. + * ex: addEvent("foo", &object, &ClassName::Method, ...) */ - void print_stats() const; -}; + template + inline void addEvent(const std::string& name, + const OBJ& o, METHOD m, + double delay, bool sim=false) + { add(name, make_callback(o,m), 0, delay, false, sim); } -#endif //SG_EVENT_MGR_HXX + void removeTask(const std::string& name); +private: + friend class SGTimer; + + void add(const std::string& name, SGCallback* cb, + double interval, double delay, + bool repeat, bool simtime); + + SGPropertyNode_ptr _freezeProp; + SGPropertyNode_ptr _rtProp; + SGTimerQueue _rtQueue; + SGTimerQueue _simQueue; +}; + +#endif // _SG_EVENT_MGR_HXX