1
0
Fork 0

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.
This commit is contained in:
curt 2002-04-25 20:31:14 +00:00
parent b3509479ba
commit d15d3652b1
3 changed files with 107 additions and 68 deletions

View file

@ -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 <config.h>
#endif
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
// #include <functional>
// #include <algorithm>
#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, "" );
}

View file

@ -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 )
const Fun& f,
interval_type repeat_value,
interval_type initial_value = -1 )
{
this->Register( FGEvent( name, new fgFunctionCallback(cb), 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)() const,
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>(obj,pmf), state, interval_ms ) );
}
template< class Obj >
void Register( const char* name,
Obj* obj, void (Obj::*pmf)(),
interval_type interval_ms,
EventState state = FG_EVENT_READY )
{
this->Register( FGEvent( name, new fgMethodCallback<Obj>(obj,pmf), state, interval_ms ) );
this->Register( FGEvent( name,
make_callback(p,pmf),
repeat_value,
initial_value ) );
}
/**

View file

@ -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;