WIP quick'n dirty Tick service implementation

This commit is contained in:
Fischlurch 2009-02-01 01:24:33 +01:00
parent 5ebd0dcf5a
commit e23417cfc0
3 changed files with 127 additions and 1 deletions

View file

@ -23,6 +23,7 @@
#include "proc/play/dummy-player-service.hpp"
#include "proc/play/dummy-image-generator.hpp"
#include "proc/play/tick-service.hpp"
#include "lib/singleton.hpp"
extern "C" {
@ -31,9 +32,11 @@ extern "C" {
#include <string>
#include <memory>
#include <tr1/functional>
#include <boost/scoped_ptr.hpp>
namespace proc {
namespace play{
@ -41,6 +44,7 @@ namespace proc {
using lumiera::Subsys;
using std::auto_ptr;
using boost::scoped_ptr;
using std::tr1::bind;
namespace { // hidden local details of the service implementation....
@ -292,7 +296,7 @@ namespace proc {
ProcessImpl::ProcessImpl()
: fps_(0), play_(false), imageGen_(0)
: fps_(0), play_(false), imageGen_(0), tick_(new TickService (bind (ProcessImpl::doFrame, this)))
{ }
@ -319,12 +323,16 @@ namespace proc {
{
REQUIRE (fps==0 || fps_==0 );
REQUIRE (fps==0 || !play_ );
REQUIRE (tick_)
fps_ = fps;
play_ = (fps != 0);
if (play_)
imageGen_.reset(new DummyImageGenerator(fps));
// callbacks with given frequency, starting now
tick_->activate(fps);
}
@ -333,6 +341,7 @@ namespace proc {
ProcessImpl::doPlay(bool yes)
{
REQUIRE (isActive());
tick_->activate (yes? fps_:0);
play_ = yes;
}

View file

@ -56,6 +56,7 @@ namespace proc {
class DummyImageGenerator;
class TickService;
/********************************************************************
@ -74,6 +75,7 @@ namespace proc {
bool play_;
boost::scoped_ptr<DummyImageGenerator> imageGen_;
boost::scoped_ptr<TickService> tick_;
public:

View file

@ -0,0 +1,115 @@
/*
TICK-SERVICE.hpp - issuing timed callbacks
Copyright (C) Lumiera.org
2009, Joel Holdsworth <joel@airwebreathe.org.uk>,
Hermann Vosseler <Ichthyostega@web.de>
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.
*/
/** @file tick-service.hpp
** A timer service invoking a given callback periodically.
** This is a rough preliminary implementation as of 1/2009. We use it to
** drive the frame "creation" of a player dummy (the render engine is not
** ready yet). The intention is to make this a real service later on, which
** might consolidate and sync various ongoing output processes to a common
** beat, which it implements by precision posix timers. Probably then this
** service will become part of the backend, or rely on a timing service.
**
** @see proc::play::DummyPlayerService
**
*/
#ifndef PROC_PLAY_TICKSERVICE_H
#define PROC_PLAY_TICKSERVICE_H
#include "backend/thread-wrapper.hpp"
#include <limits>
namespace proc {
namespace play {
/************************************************************
* Tick generating service for a periodic callback,
* with adjustable frequency. Quick'n dirty implementation!
*/
class TickService
: backend::Thread
{
typedef function<void(void)> Tick;
volatile uint timespan_;
/** poll interval for new settings in wait state */
static const uint POLL_TIMEOUT = 1000;
public:
TickService (Tick& callback)
: Thread("Tick generator (dummy)",
bind (&TickService::timerLoop, this, callback))
{ }
~TickService ()
{
uint curr_tick = timespan_;
timespan_ = 0;
usleep (curr_tick); ////TODO actually should wait for timer thread termination
}
/** set the periodic timer to run with a given frequency,
* starting \em now. Well, not actually now, but at the next
* opportunity. It should be \em now, but this implementation
* is sloppy! setting fps==0 halts (pauses) the timer.
*/
void activate (uint fps)
{
REQUIRE ( 0==fps
|| 1000000/fps < std::numeric_limits<uint>::max()
&& 1000000/fps > POLL_TIMEOUT);
if (fps)
timespan_ = 1000000/fps; // microseconds per tick
else
timespan_ = POLL_TIMEOUT;
}
private:
void timerLoop(Tick periodicFun)
{
timespan_ = POLL_TIMEOUT;
while (0 < timespan_)
{
if (timespan_ > POLL_TIMEOUT)
periodicFun();
usleep (timespan_);
} }
};
} // namespace play
} // namespace proc
#endif // PROC_PLAY_TICKSERVICE_H