use boost::intrusive to manage FSM events (this is all RT code)
This commit is contained in:
parent
ea8ec74565
commit
b075c67e51
|
@ -4,6 +4,11 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include <boost/intrusive/list.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "pbd/demangle.h"
|
#include "pbd/demangle.h"
|
||||||
#include "pbd/stacktrace.h"
|
#include "pbd/stacktrace.h"
|
||||||
|
|
||||||
|
@ -30,7 +35,7 @@ struct TransportFSM
|
||||||
LocateDone
|
LocateDone
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FSMEvent {
|
struct FSMEvent : public boost::intrusive::list_base_hook<> {
|
||||||
EventType type;
|
EventType type;
|
||||||
union {
|
union {
|
||||||
bool abort; /* for stop */
|
bool abort; /* for stop */
|
||||||
|
@ -122,10 +127,10 @@ struct TransportFSM
|
||||||
void stop_playback ();
|
void stop_playback ();
|
||||||
void start_saved_locate ();
|
void start_saved_locate ();
|
||||||
void roll_after_locate ();
|
void roll_after_locate ();
|
||||||
void start_locate (FSMEvent const *);
|
void start_locate (FSMEvent const &);
|
||||||
void interrupt_locate (FSMEvent const *);
|
void interrupt_locate (FSMEvent const &);
|
||||||
void save_locate_and_start_declick (FSMEvent const *);
|
void save_locate_and_start_declick (FSMEvent const &);
|
||||||
void start_declick (FSMEvent const *);
|
void start_declick (FSMEvent const &);
|
||||||
|
|
||||||
/* guards */
|
/* guards */
|
||||||
|
|
||||||
|
@ -140,7 +145,7 @@ struct TransportFSM
|
||||||
bool declick_in_progress() { return _motion_state == DeclickToLocate || _motion_state == DeclickToStop; }
|
bool declick_in_progress() { return _motion_state == DeclickToLocate || _motion_state == DeclickToStop; }
|
||||||
|
|
||||||
void enqueue (FSMEvent* ev) {
|
void enqueue (FSMEvent* ev) {
|
||||||
queued_events.push (ev);
|
queued_events.push_back (*ev);
|
||||||
if (!processing) {
|
if (!processing) {
|
||||||
process_events ();
|
process_events ();
|
||||||
}
|
}
|
||||||
|
@ -152,18 +157,19 @@ struct TransportFSM
|
||||||
void transition (ButlerState bs);
|
void transition (ButlerState bs);
|
||||||
|
|
||||||
void process_events ();
|
void process_events ();
|
||||||
bool process_event (FSMEvent *);
|
bool process_event (FSMEvent&);
|
||||||
|
|
||||||
FSMEvent _last_locate;
|
FSMEvent _last_locate;
|
||||||
FSMEvent _last_stop;
|
FSMEvent _last_stop;
|
||||||
|
|
||||||
TransportAPI* api;
|
TransportAPI* api;
|
||||||
std::queue<FSMEvent*> queued_events;
|
typedef boost::intrusive::list<FSMEvent> EventList;
|
||||||
std::list<FSMEvent*> deferred_events;
|
EventList queued_events;
|
||||||
|
EventList deferred_events;
|
||||||
int processing;
|
int processing;
|
||||||
|
|
||||||
void defer (FSMEvent* ev);
|
void defer (FSMEvent& ev);
|
||||||
void bad_transition (FSMEvent const *);
|
void bad_transition (FSMEvent const &);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* end namespace ARDOUR */
|
} /* end namespace ARDOUR */
|
||||||
|
|
|
@ -41,7 +41,7 @@ void*
|
||||||
TransportFSM::FSMEvent::operator new (size_t)
|
TransportFSM::FSMEvent::operator new (size_t)
|
||||||
{
|
{
|
||||||
return pool->alloc();
|
return pool->alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::FSMEvent::operator delete (void *ptr, size_t /*size*/)
|
TransportFSM::FSMEvent::operator delete (void *ptr, size_t /*size*/)
|
||||||
|
@ -71,13 +71,11 @@ TransportFSM::process_events ()
|
||||||
processing++;
|
processing++;
|
||||||
|
|
||||||
while (!queued_events.empty()) {
|
while (!queued_events.empty()) {
|
||||||
FSMEvent* ev = queued_events.front();
|
|
||||||
queued_events.pop ();
|
|
||||||
|
|
||||||
MotionState oms = _motion_state;
|
MotionState oms = _motion_state;
|
||||||
ButlerState obs = _butler_state;
|
ButlerState obs = _butler_state;
|
||||||
|
|
||||||
if (process_event (ev)) { /* event processed successfully */
|
if (process_event (queued_events.front())) { /* event processed successfully */
|
||||||
|
|
||||||
if (oms != _motion_state || obs != _butler_state) {
|
if (oms != _motion_state || obs != _butler_state) {
|
||||||
|
|
||||||
|
@ -88,9 +86,9 @@ TransportFSM::process_events ()
|
||||||
if (!deferred_events.empty() ){
|
if (!deferred_events.empty() ){
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("processing %1 deferred events\n", deferred_events.size()));
|
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("processing %1 deferred events\n", deferred_events.size()));
|
||||||
|
|
||||||
for (std::list<FSMEvent*>::iterator e = deferred_events.begin(); e != deferred_events.end(); ) {
|
for (EventList::iterator e = deferred_events.begin(); e != deferred_events.end(); ) {
|
||||||
FSMEvent* deferred_ev = *e;
|
FSMEvent* deferred_ev = &(*e);
|
||||||
if (process_event (deferred_ev)) { /* event processed, remove from deferred */
|
if (process_event (*e)) { /* event processed, remove from deferred */
|
||||||
e = deferred_events.erase (e);
|
e = deferred_events.erase (e);
|
||||||
delete deferred_ev;
|
delete deferred_ev;
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,6 +99,8 @@ TransportFSM::process_events ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSMEvent* ev = &queued_events.front();
|
||||||
|
queued_events.pop_front ();
|
||||||
delete ev;
|
delete ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,18 +166,18 @@ TransportFSM::current_state () const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::bad_transition (FSMEvent const * ev)
|
TransportFSM::bad_transition (FSMEvent const & ev)
|
||||||
{
|
{
|
||||||
error << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev->type) << endmsg;
|
error << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev.type) << endmsg;
|
||||||
std::cerr << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev->type) << std::endl;
|
std::cerr << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev.type) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TransportFSM::process_event (FSMEvent* ev)
|
TransportFSM::process_event (FSMEvent& ev)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("process %1\n", enum_2_string (ev->type)));
|
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("process %1\n", enum_2_string (ev.type)));
|
||||||
|
|
||||||
switch (ev->type) {
|
switch (ev.type) {
|
||||||
|
|
||||||
case StartTransport:
|
case StartTransport:
|
||||||
switch (_motion_state) {
|
switch (_motion_state) {
|
||||||
|
@ -305,11 +305,11 @@ TransportFSM::start_playback ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::start_declick (FSMEvent const * s)
|
TransportFSM::start_declick (FSMEvent const & s)
|
||||||
{
|
{
|
||||||
assert (s->type == StopTransport);
|
assert (s.type == StopTransport);
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_declick\n");
|
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_declick\n");
|
||||||
_last_stop = *s;
|
_last_stop = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -320,20 +320,20 @@ TransportFSM::stop_playback ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::save_locate_and_start_declick (FSMEvent const * l)
|
TransportFSM::save_locate_and_start_declick (FSMEvent const & l)
|
||||||
{
|
{
|
||||||
assert (l->type == Locate);
|
assert (l.type == Locate);
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::save_locate_and_stop\n");
|
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::save_locate_and_stop\n");
|
||||||
_last_locate = *l;
|
_last_locate = l;
|
||||||
_last_stop = FSMEvent (StopTransport, false, false);
|
_last_stop = FSMEvent (StopTransport, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::start_locate (FSMEvent const * l)
|
TransportFSM::start_locate (FSMEvent const & l)
|
||||||
{
|
{
|
||||||
assert (l->type == Locate);
|
assert (l.type == Locate);
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_locate\n");
|
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::start_locate\n");
|
||||||
api->locate (l->target, l->with_roll, l->with_flush, l->with_loop, l->force);
|
api->locate (l.target, l.with_roll, l.with_flush, l.with_loop, l.force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -344,14 +344,14 @@ TransportFSM::start_saved_locate ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::interrupt_locate (FSMEvent const * l)
|
TransportFSM::interrupt_locate (FSMEvent const & l)
|
||||||
{
|
{
|
||||||
assert (l->type == Locate);
|
assert (l.type == Locate);
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::interrupt\n");
|
DEBUG_TRACE (DEBUG::TFSMEvents, "tfsm::interrupt\n");
|
||||||
/* maintain original "with-roll" choice of initial locate, even though
|
/* maintain original "with-roll" choice of initial locate, even though
|
||||||
* we are interrupting the locate to start a new one.
|
* we are interrupting the locate to start a new one.
|
||||||
*/
|
*/
|
||||||
api->locate (l->target, _last_locate.with_roll, l->with_flush, l->with_loop, l->force);
|
api->locate (l.target, _last_locate.with_roll, l.with_flush, l.with_loop, l.force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -376,9 +376,9 @@ TransportFSM::roll_after_locate ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransportFSM::defer (FSMEvent* ev)
|
TransportFSM::defer (FSMEvent& ev)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("Defer %1 during %2\n", enum_2_string (ev->type), current_state()));
|
DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("Defer %1 during %2\n", enum_2_string (ev.type), current_state()));
|
||||||
deferred_events.push_back (ev);
|
deferred_events.push_back (ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user