Nasal and event manager updates from Andy Ross.
This commit is contained in:
parent
1786692406
commit
34e2a9dc37
@ -356,6 +356,7 @@ AC_CONFIG_FILES([ \
|
||||
simgear/math/Makefile \
|
||||
simgear/metar/Makefile \
|
||||
simgear/misc/Makefile \
|
||||
simgear/nasal/Makefile \
|
||||
simgear/props/Makefile \
|
||||
simgear/route/Makefile \
|
||||
simgear/scene/Makefile \
|
||||
|
@ -24,6 +24,7 @@ SUBDIRS = \
|
||||
magvar \
|
||||
math \
|
||||
$(METAR_DIRS) \
|
||||
nasal \
|
||||
props \
|
||||
route \
|
||||
scene \
|
||||
|
@ -24,7 +24,8 @@ typedef enum {
|
||||
SG_CLIPPER = 0x00002000,
|
||||
SG_NETWORK = 0x00004000,
|
||||
SG_ATC = 0x00008000,
|
||||
SG_UNDEFD = 0x00010000, // For range checking
|
||||
SG_NASAL = 0x00010000,
|
||||
SG_UNDEFD = 0x00020000, // For range checking
|
||||
|
||||
SG_ALL = 0xFFFFFFFF
|
||||
} sgDebugClass;
|
||||
|
@ -1,258 +1,160 @@
|
||||
//
|
||||
// SGEventMgr.cxx -- Event Manager
|
||||
//
|
||||
// Written by Bernie Bright, started April 2002.
|
||||
//
|
||||
// Copyright (C) 2002 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "event_mgr.hxx"
|
||||
|
||||
SGEvent::SGEvent()
|
||||
: _name(""),
|
||||
_callback(0),
|
||||
_subsystem(0),
|
||||
_repeat_value(0),
|
||||
_initial_value(0),
|
||||
_ms_to_go(0),
|
||||
_cum_time(0),
|
||||
_min_time(100000),
|
||||
_max_time(0),
|
||||
_count(0)
|
||||
void SGEventMgr::add(SGCallback* cb,
|
||||
double interval, double delay,
|
||||
bool repeat, bool simtime)
|
||||
{
|
||||
SGTimer* t = new SGTimer;
|
||||
t->interval = interval;
|
||||
t->callback = cb;
|
||||
t->mgr = this;
|
||||
t->repeat = repeat;
|
||||
t->simtime = simtime;
|
||||
|
||||
SGTimerQueue* q = simtime ? &_simQueue : &_rtQueue;
|
||||
|
||||
q->insert(t, delay);
|
||||
}
|
||||
|
||||
SGEvent::SGEvent( const char* name,
|
||||
SGCallback* cb,
|
||||
interval_type repeat_value,
|
||||
interval_type initial_value )
|
||||
: _name(name),
|
||||
_callback(cb),
|
||||
_subsystem(NULL),
|
||||
_repeat_value(repeat_value),
|
||||
_initial_value(initial_value),
|
||||
_cum_time(0),
|
||||
_min_time(100000),
|
||||
_max_time(0),
|
||||
_count(0)
|
||||
void SGTimer::run()
|
||||
{
|
||||
if (_initial_value < 0)
|
||||
{
|
||||
this->run();
|
||||
_ms_to_go = _repeat_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ms_to_go = _initial_value;
|
||||
(*callback)();
|
||||
|
||||
if(repeat) {
|
||||
SGTimerQueue* q = simtime ? &mgr->_simQueue : &mgr->_rtQueue;
|
||||
q->insert(this, interval);
|
||||
} else {
|
||||
delete callback;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
SGEvent::SGEvent( const char* name,
|
||||
SGSubsystem* subsystem,
|
||||
interval_type repeat_value,
|
||||
interval_type initial_value )
|
||||
: _name(name),
|
||||
_callback(NULL),
|
||||
_subsystem(subsystem),
|
||||
_repeat_value(repeat_value),
|
||||
_initial_value(initial_value),
|
||||
_cum_time(0),
|
||||
_min_time(100000),
|
||||
_max_time(0),
|
||||
_count(0)
|
||||
void SGEventMgr::update(double delta_time_sec)
|
||||
{
|
||||
if (_initial_value < 0)
|
||||
{
|
||||
this->run();
|
||||
_ms_to_go = _repeat_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ms_to_go = _initial_value;
|
||||
_rtQueue.update(delta_time_sec);
|
||||
if(!_freezeProp || _freezeProp->getBoolValue() == false)
|
||||
_simQueue.update(delta_time_sec);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SGTimerQueue
|
||||
// This is the priority queue implementation:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SGTimerQueue::SGTimerQueue(int size)
|
||||
{
|
||||
_now = 0;
|
||||
_numEntries = 0;
|
||||
_tableSize = 1;
|
||||
while(size > _tableSize)
|
||||
_tableSize = ((_tableSize + 1)<<1) - 1;
|
||||
|
||||
_table = new HeapEntry[_tableSize];
|
||||
for(int i=0; i<_tableSize; i++) {
|
||||
_table[i].pri = 0;
|
||||
_table[i].timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SGEvent::~SGEvent()
|
||||
SGTimerQueue::~SGTimerQueue()
|
||||
{
|
||||
//delete callback_;
|
||||
delete[] _table;
|
||||
}
|
||||
|
||||
void
|
||||
SGEvent::run()
|
||||
void SGTimerQueue::update(double deltaSecs)
|
||||
{
|
||||
SGTimeStamp start_time;
|
||||
SGTimeStamp finish_time;
|
||||
|
||||
start_time.stamp();
|
||||
|
||||
// run the event
|
||||
if (_callback)
|
||||
{
|
||||
(*_callback)();
|
||||
} else if (_subsystem)
|
||||
{
|
||||
_subsystem->update(_repeat_value);
|
||||
}
|
||||
|
||||
finish_time.stamp();
|
||||
|
||||
++_count;
|
||||
|
||||
unsigned long duration = finish_time - start_time;
|
||||
|
||||
_cum_time += duration;
|
||||
|
||||
if ( duration < _min_time ) {
|
||||
_min_time = duration;
|
||||
}
|
||||
|
||||
if ( duration > _max_time ) {
|
||||
_max_time = duration;
|
||||
_now += deltaSecs;
|
||||
while(_numEntries && nextTime() <= _now) {
|
||||
SGTimer* t = remove();
|
||||
t->run();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SGEvent::print_stats() const
|
||||
void SGTimerQueue::insert(SGTimer* timer, double time)
|
||||
{
|
||||
SG_LOG( SG_EVENT, SG_INFO,
|
||||
" " << _name
|
||||
<< " int=" << _repeat_value / 1000.0
|
||||
<< " cum=" << _cum_time
|
||||
<< " min=" << _min_time
|
||||
<< " max=" << _max_time
|
||||
<< " count=" << _count
|
||||
<< " ave=" << _cum_time / (double)_count );
|
||||
if(time < 0) *(int*)0=0;
|
||||
|
||||
if(_numEntries >= _tableSize)
|
||||
growArray();
|
||||
|
||||
_numEntries++;
|
||||
_table[_numEntries-1].pri = -(_now + time);
|
||||
_table[_numEntries-1].timer = timer;
|
||||
|
||||
siftUp(_numEntries-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SGEventMgr::SGEventMgr()
|
||||
SGTimer* SGTimerQueue::remove(SGTimer* t)
|
||||
{
|
||||
int entry;
|
||||
for(entry=0; entry<_numEntries; entry++)
|
||||
if(_table[entry].timer == t)
|
||||
break;
|
||||
if(entry == _numEntries)
|
||||
return 0;
|
||||
|
||||
// Swap in the last item in the table, and sift down
|
||||
swap(entry, _numEntries-1);
|
||||
_numEntries--;
|
||||
siftDown(entry);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
SGEventMgr::~SGEventMgr()
|
||||
SGTimer* SGTimerQueue::remove()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::init()
|
||||
{
|
||||
SG_LOG( SG_EVENT, SG_INFO, "Initializing event manager" );
|
||||
|
||||
event_table.clear();
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::reinit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SGEventMgr::bind()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::unbind()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::update( double dt )
|
||||
{
|
||||
int dt_ms = int(dt * 1000);
|
||||
|
||||
if (dt_ms < 0)
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||
"SGEventMgr::update() called with negative delta T" );
|
||||
return;
|
||||
if(_numEntries == 0) {
|
||||
return 0;
|
||||
} else if(_numEntries == 1) {
|
||||
_numEntries = 0;
|
||||
return _table[0].timer;
|
||||
}
|
||||
|
||||
int min_value = 0;
|
||||
event_container_type::iterator first = event_table.begin();
|
||||
event_container_type::iterator last = event_table.end();
|
||||
event_container_type::iterator event = event_table.end();
|
||||
SGTimer *result = _table[0].timer;
|
||||
_table[0] = _table[_numEntries - 1];
|
||||
_numEntries--;
|
||||
siftDown(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Scan all events. Run one whose interval has expired.
|
||||
while (first != last)
|
||||
void SGTimerQueue::siftDown(int n)
|
||||
{
|
||||
// While we have a child bigger than us:
|
||||
while(((lchild(n) < (_numEntries-1))
|
||||
&& (_table[n].pri < _table[lchild(n)].pri))
|
||||
||
|
||||
((rchild(n) < (_numEntries-1))
|
||||
&& (_table[n].pri < _table[rchild(n)].pri)))
|
||||
{
|
||||
if (first->update( dt_ms ))
|
||||
{
|
||||
if (first->value() < min_value)
|
||||
{
|
||||
// Select event with largest negative value.
|
||||
// Its been waiting longest.
|
||||
min_value = first->value();
|
||||
event = first;
|
||||
}
|
||||
}
|
||||
++first;
|
||||
}
|
||||
|
||||
if (event != last)
|
||||
{
|
||||
event->run();
|
||||
|
||||
if (event->repeat_value() > 0)
|
||||
{
|
||||
event->reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting event " << event->name() );
|
||||
event_table.erase( event );
|
||||
// Swap us with the biggest child
|
||||
if(_table[lchild(n)].pri > _table[rchild(n)].pri) {
|
||||
swap(n, lchild(n));
|
||||
n = lchild(n);
|
||||
} else {
|
||||
swap(n, rchild(n));
|
||||
n = rchild(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::add( const SGEvent& event )
|
||||
void SGTimerQueue::siftUp(int n)
|
||||
{
|
||||
event_table.push_back( event );
|
||||
|
||||
SG_LOG( SG_EVENT, SG_INFO, "registered event " << event.name()
|
||||
<< " to run every " << event.repeat_value() << "ms" );
|
||||
}
|
||||
|
||||
void
|
||||
SGEventMgr::print_stats() const
|
||||
{
|
||||
SG_LOG( SG_EVENT, SG_INFO, "" );
|
||||
SG_LOG( SG_EVENT, SG_INFO, "Event Stats" );
|
||||
SG_LOG( SG_EVENT, SG_INFO, "-----------" );
|
||||
|
||||
event_container_type::const_iterator first = event_table.begin();
|
||||
event_container_type::const_iterator last = event_table.end();
|
||||
for (; first != last; ++first)
|
||||
{
|
||||
first->print_stats();
|
||||
while((n != 0) && (_table[n].pri > _table[parent(n)].pri)) {
|
||||
swap(n, parent(n));
|
||||
n = parent(n);
|
||||
}
|
||||
|
||||
SG_LOG( SG_EVENT, SG_INFO, "" );
|
||||
siftDown(n);
|
||||
}
|
||||
|
||||
void SGTimerQueue::growArray()
|
||||
{
|
||||
_tableSize = ((_tableSize+1)<<1) - 1;
|
||||
HeapEntry *newTable = new HeapEntry[_tableSize];
|
||||
for(int i=0; i<_numEntries; i++) {
|
||||
newTable[i].pri = _table[i].pri;
|
||||
newTable[i].timer = _table[i].timer;
|
||||
}
|
||||
delete[] _table;
|
||||
_table = newTable;
|
||||
}
|
||||
|
@ -1,209 +1,121 @@
|
||||
// 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
|
||||
|
||||
#ifndef SG_EVENT_MGR_HXX
|
||||
#define SG_EVENT_MGR_HXX 1
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <simgear/structure/callback.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "callback.hxx"
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
class SGEventMgr;
|
||||
|
||||
|
||||
class SGEvent
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
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
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SGEvent();
|
||||
|
||||
SGEvent( const char* desc,
|
||||
SGCallback* cb,
|
||||
interval_type repeat_value,
|
||||
interval_type initial_value );
|
||||
|
||||
SGEvent( const char* desc,
|
||||
SGSubsystem* subsystem,
|
||||
interval_type repeat_value,
|
||||
interval_type initial_value );
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
~SGEvent();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
inline void reset()
|
||||
{
|
||||
_ms_to_go = _repeat_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this event's callback.
|
||||
*/
|
||||
struct SGTimer {
|
||||
double interval;
|
||||
SGCallback* callback;
|
||||
SGEventMgr* mgr;
|
||||
bool repeat;
|
||||
bool simtime;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
class SGTimerQueue {
|
||||
public:
|
||||
SGTimerQueue(int preSize=1);
|
||||
~SGTimerQueue();
|
||||
|
||||
void update(double deltaSecs);
|
||||
|
||||
double now() { return _now; }
|
||||
|
||||
void insert(SGTimer* timer, double time);
|
||||
SGTimer* remove(SGTimer* timer);
|
||||
SGTimer* remove();
|
||||
|
||||
SGTimer* nextTimer() { return _numEntries ? _table[0].timer : 0; }
|
||||
double nextTime() { return -_table[0].pri; }
|
||||
|
||||
private:
|
||||
// The "priority" is stored as a negative time. This allows the
|
||||
// implemenetation 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; }
|
||||
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();
|
||||
void check();
|
||||
|
||||
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();
|
||||
~SGEventMgr();
|
||||
SGEventMgr() { _freezeProp = 0; }
|
||||
|
||||
virtual void init() {}
|
||||
virtual void update(double delta_time_sec);
|
||||
|
||||
void setFreezeProperty(SGPropertyNode* node) { _freezeProp = 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<typename FUNC>
|
||||
inline void addTask(const char* name, const FUNC& f,
|
||||
double interval, double delay=0, bool sim=false)
|
||||
{ add(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<typename FUNC>
|
||||
inline void addEvent(const char* name, const FUNC& f,
|
||||
double delay, bool sim=false)
|
||||
{ add(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,
|
||||
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<class OBJ, typename METHOD>
|
||||
inline void addTask(const char* name,
|
||||
const OBJ& o, METHOD m,
|
||||
double interval, double delay=0, bool sim=false)
|
||||
{ add(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<class OBJ, typename METHOD>
|
||||
inline void addEvent(const char* name,
|
||||
const OBJ& o, METHOD m,
|
||||
double delay, bool sim=false)
|
||||
{ add(make_callback(o,m), 0, delay, false, sim); }
|
||||
|
||||
private:
|
||||
friend class SGTimer;
|
||||
|
||||
void add(SGCallback* cb,
|
||||
double interval, double delay,
|
||||
bool repeat, bool simtime);
|
||||
|
||||
SGPropertyNode* _freezeProp;
|
||||
SGTimerQueue _rtQueue;
|
||||
SGTimerQueue _simQueue;
|
||||
};
|
||||
|
||||
|
||||
#endif //SG_EVENT_MGR_HXX
|
||||
#endif // _SG_EVENT_MGR_HXX
|
||||
|
Loading…
Reference in New Issue
Block a user