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:
parent
b3509479ba
commit
d15d3652b1
3 changed files with 107 additions and 68 deletions
|
@ -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, "" );
|
||||
}
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue