2009-02-01 01:24:33 +01:00
|
|
|
/*
|
|
|
|
|
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"
|
|
|
|
|
|
2009-02-06 22:52:06 +01:00
|
|
|
#include <tr1/functional>
|
2009-02-01 01:24:33 +01:00
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace proc {
|
|
|
|
|
namespace play {
|
2009-02-06 22:52:06 +01:00
|
|
|
|
|
|
|
|
using std::tr1::function;
|
|
|
|
|
|
2009-02-01 01:24:33 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
|
* 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:
|
2009-02-06 22:52:06 +01:00
|
|
|
TickService (Tick callback)
|
2009-02-01 01:24:33 +01:00
|
|
|
: Thread("Tick generator (dummy)",
|
|
|
|
|
bind (&TickService::timerLoop, this, callback))
|
2009-02-08 04:10:37 +01:00
|
|
|
{
|
|
|
|
|
INFO (proc, "TickService started.");
|
|
|
|
|
}
|
2009-02-01 01:24:33 +01:00
|
|
|
|
|
|
|
|
~TickService ()
|
|
|
|
|
{
|
|
|
|
|
uint curr_tick = timespan_;
|
|
|
|
|
timespan_ = 0;
|
2009-02-08 04:10:37 +01:00
|
|
|
usleep (2*curr_tick); ////TODO actually should wait for timer thread termination
|
|
|
|
|
|
|
|
|
|
INFO (proc, "TickService shutdown.");
|
2009-02-01 01:24:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 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_);
|
2009-02-08 04:10:37 +01:00
|
|
|
}
|
|
|
|
|
TRACE (proc_dbg, "Tick Thread timer loop exiting...");
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-01 01:24:33 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace play
|
|
|
|
|
|
|
|
|
|
} // namespace proc
|
|
|
|
|
#endif // PROC_PLAY_TICKSERVICE_H
|
|
|
|
|
|