From d15d3652b1cb5bac635c5de802773b7bc60616ad Mon Sep 17 00:00:00 2001 From: curt Date: Thu, 25 Apr 2002 20:31:14 +0000 Subject: [PATCH] Bernie Bright: - Added initial_value argument, in milliseconds, that specifies when event is first run. The default value of -1 triggers the event immediately as per the existing behaviour. A repeat_value greater than zero runs the event no less than every 'repeat_value' milliseconds afterwards. A repeat_value of zero deletes the event. - Modified run queue behaviour such that only one event per frame is run. --- src/Time/FGEventMgr.cxx | 101 ++++++++++++++++++++++++++++++---------- src/Time/FGEventMgr.hxx | 70 +++++++++++----------------- src/Time/light.cxx | 4 +- 3 files changed, 107 insertions(+), 68 deletions(-) diff --git a/src/Time/FGEventMgr.cxx b/src/Time/FGEventMgr.cxx index d22c3b928..0dfb7f260 100644 --- a/src/Time/FGEventMgr.cxx +++ b/src/Time/FGEventMgr.cxx @@ -1,19 +1,40 @@ +// +// FGEventMgr.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 #endif #include #include -// #include -// #include #include "FGEventMgr.hxx" FGEventMgr::FGEvent::FGEvent() : name_(""), callback_(0), - status_(FG_EVENT_SUSP), - ms_(0), + repeat_value_(0), + initial_value_(0), ms_to_go_(0), cum_time(0), min_time(100000), @@ -24,20 +45,27 @@ FGEventMgr::FGEvent::FGEvent() FGEventMgr::FGEvent::FGEvent( const char* name, fgCallback* cb, - EventState status, - interval_type ms ) + interval_type repeat_value, + interval_type initial_value ) : name_(name), callback_(cb), - status_(status), - ms_(ms), - ms_to_go_(ms), + repeat_value_(repeat_value), + initial_value_(initial_value), + //ms_to_go_(repeat_value_), cum_time(0), min_time(100000), max_time(0), count(0) { - if (status == FG_EVENT_READY) + if (initial_value_ < 0) + { this->run(); + ms_to_go_ = repeat_value_; + } + else + { + ms_to_go_ = initial_value_; + } } @@ -55,7 +83,7 @@ FGEventMgr::FGEvent::run() start_time.stamp(); // run the event - callback_->call(0); + (*callback_)(); finish_time.stamp(); @@ -72,8 +100,6 @@ FGEventMgr::FGEvent::run() if ( duration > max_time ) { max_time = duration; } - - reset(); } void @@ -81,7 +107,7 @@ FGEventMgr::FGEvent::print_stats() const { SG_LOG( SG_EVENT, SG_INFO, " " << name_ - << " int=" << ms_ / 1000.0 + << " int=" << repeat_value_ / 1000.0 << " cum=" << cum_time << " min=" << min_time << " max=" << max_time @@ -118,14 +144,46 @@ FGEventMgr::unbind() void FGEventMgr::update( int dt ) { - // Scan all events. Execute any whose interval has expired. + if (dt < 0) + { + SG_LOG( SG_GENERAL, SG_ALERT, + "FGEventMgr::update() called with negative delta T" ); + return; + } + + int min_value = 0; event_container_type::iterator first = event_table.begin(); event_container_type::iterator last = event_table.end(); - for(; first != last; ++first) + event_container_type::iterator event = event_table.end(); + + // Scan all events. Run one whose interval has expired. + while (first != last) { if (first->update( dt )) { - first->run(); + 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 ); } } } @@ -136,7 +194,7 @@ FGEventMgr::Register( const FGEvent& event ) event_table.push_back( event ); SG_LOG( SG_EVENT, SG_INFO, "Registered event " << event.name() - << " to run every " << event.interval() << "ms" ); + << " to run every " << event.repeat_value() << "ms" ); } void @@ -146,17 +204,12 @@ FGEventMgr::print_stats() const SG_LOG( SG_EVENT, SG_INFO, "Event Stats" ); SG_LOG( SG_EVENT, SG_INFO, "-----------" ); -#if 1 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(); } -#else - // #@!$ MSVC can't handle const member functions. - std::for_each( event_table.begin(), event_table.end(), - std::mem_fun_ref( &FGEvent::print_stats ) ); -#endif + SG_LOG( SG_EVENT, SG_INFO, "" ); } diff --git a/src/Time/FGEventMgr.hxx b/src/Time/FGEventMgr.hxx index 085135f69..497711810 100644 --- a/src/Time/FGEventMgr.hxx +++ b/src/Time/FGEventMgr.hxx @@ -43,15 +43,6 @@ class FGEventMgr : public FGSubsystem { public: - /** - * - */ - enum EventState { - FG_EVENT_SUSP = 0, - FG_EVENT_READY = 1, - FG_EVENT_QUEUED = 2 - }; - typedef int interval_type; private: @@ -69,8 +60,8 @@ private: FGEvent( const char* desc, fgCallback* cb, - EventState status, - interval_type ms ); + interval_type repeat_value, + interval_type initial_value ); /** * @@ -82,8 +73,7 @@ private: */ void reset() { - status_ = FG_EVENT_READY; - ms_to_go_ = ms_; + ms_to_go_ = repeat_value_; } /** @@ -91,10 +81,9 @@ private: */ void run(); - bool is_ready() const { return status_ == FG_EVENT_READY; } - string name() const { return name_; } - interval_type interval() const { return ms_; } + interval_type repeat_value() const { return repeat_value_; } + int value() const { return ms_to_go_; } /** * Display event statistics. @@ -108,9 +97,6 @@ private: */ bool update( int dt_ms ) { - if (status_ != FG_EVENT_READY) - return false; - ms_to_go_ -= dt_ms; return ms_to_go_ <= 0; } @@ -118,8 +104,8 @@ private: private: string name_; fgCallback* callback_; - EventState status_; - interval_type ms_; + interval_type repeat_value_; + interval_type initial_value_; int ms_to_go_; unsigned long cum_time; // cumulative processor time of this event @@ -148,36 +134,36 @@ public: void update( int dt ); /** - * Register a function to be executed every 'interval' milliseconds. + * 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 state - * @param interval Callback repetition rate in milliseconds. + * @param repeat_value repetition rate in milliseconds. + * @param initial_value initial delay value in milliseconds. A value of + * -1 means run immediately. */ + template< typename Fun > void Register( const char* name, - void (*cb)(), - interval_type interval_ms, - EventState state = FG_EVENT_READY ) - { - this->Register( FGEvent( name, new fgFunctionCallback(cb), state, interval_ms ) ); - } - - template< class Obj > - void Register( const char* name, - Obj* obj, void (Obj::*pmf)() const, - interval_type interval_ms, - EventState state = FG_EVENT_READY ) + const Fun& f, + interval_type repeat_value, + interval_type initial_value = -1 ) { - this->Register( FGEvent( name, new fgMethodCallback(obj,pmf), state, interval_ms ) ); + this->Register( FGEvent( name, + make_callback(f), + repeat_value, + initial_value ) ); } - template< class Obj > + template< class ObjPtr, typename MemFn > void Register( const char* name, - Obj* obj, void (Obj::*pmf)(), - interval_type interval_ms, - EventState state = FG_EVENT_READY ) + const ObjPtr& p, + MemFn pmf, + interval_type repeat_value, + interval_type initial_value = -1 ) { - this->Register( FGEvent( name, new fgMethodCallback(obj,pmf), state, interval_ms ) ); + this->Register( FGEvent( name, + make_callback(p,pmf), + repeat_value, + initial_value ) ); } /** diff --git a/src/Time/light.cxx b/src/Time/light.cxx index a38526051..7cb0dd4f1 100644 --- a/src/Time/light.cxx +++ b/src/Time/light.cxx @@ -101,9 +101,9 @@ void fgLIGHT::Update( void ) { // if the 4th field is 0.0, this specifies a direction ... GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 }; // base sky color - GLfloat base_sky_color[4] = {0.60, 0.60, 0.90, 1.0}; + GLfloat base_sky_color[4] = { 0.60, 0.60, 0.90, 1.0 }; // base fog color - GLfloat base_fog_color[4] = {0.90, 0.90, 1.00, 1.0}; + GLfloat base_fog_color[4] = { 0.90, 0.90, 1.00, 1.0 }; double deg, ambient, diffuse, sky_brightness; f = current_aircraft.fdm_state; -- 2.39.5