13
0

use boost::intrusive to manage FSM events (this is all RT code)

This commit is contained in:
Paul Davis 2019-09-20 09:33:24 -06:00
parent ea8ec74565
commit b075c67e51
2 changed files with 44 additions and 38 deletions

View File

@ -4,6 +4,11 @@
#include <list>
#include <queue>
#include <boost/intrusive/list.hpp>
#include <string>
#include <utility>
#include <iostream>
#include "pbd/demangle.h"
#include "pbd/stacktrace.h"
@ -30,7 +35,7 @@ struct TransportFSM
LocateDone
};
struct FSMEvent {
struct FSMEvent : public boost::intrusive::list_base_hook<> {
EventType type;
union {
bool abort; /* for stop */
@ -122,10 +127,10 @@ struct TransportFSM
void stop_playback ();
void start_saved_locate ();
void roll_after_locate ();
void start_locate (FSMEvent const *);
void interrupt_locate (FSMEvent const *);
void save_locate_and_start_declick (FSMEvent const *);
void start_declick (FSMEvent const *);
void start_locate (FSMEvent const &);
void interrupt_locate (FSMEvent const &);
void save_locate_and_start_declick (FSMEvent const &);
void start_declick (FSMEvent const &);
/* guards */
@ -140,7 +145,7 @@ struct TransportFSM
bool declick_in_progress() { return _motion_state == DeclickToLocate || _motion_state == DeclickToStop; }
void enqueue (FSMEvent* ev) {
queued_events.push (ev);
queued_events.push_back (*ev);
if (!processing) {
process_events ();
}
@ -152,18 +157,19 @@ struct TransportFSM
void transition (ButlerState bs);
void process_events ();
bool process_event (FSMEvent *);
bool process_event (FSMEvent&);
FSMEvent _last_locate;
FSMEvent _last_stop;
TransportAPI* api;
std::queue<FSMEvent*> queued_events;
std::list<FSMEvent*> deferred_events;
typedef boost::intrusive::list<FSMEvent> EventList;
EventList queued_events;
EventList deferred_events;
int processing;
void defer (FSMEvent* ev);
void bad_transition (FSMEvent const *);
void defer (FSMEvent& ev);
void bad_transition (FSMEvent const &);
};
} /* end namespace ARDOUR */

View File

@ -41,7 +41,7 @@ void*
TransportFSM::FSMEvent::operator new (size_t)
{
return pool->alloc();
}
}
void
TransportFSM::FSMEvent::operator delete (void *ptr, size_t /*size*/)
@ -71,13 +71,11 @@ TransportFSM::process_events ()
processing++;
while (!queued_events.empty()) {
FSMEvent* ev = queued_events.front();
queued_events.pop ();
MotionState oms = _motion_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) {
@ -88,9 +86,9 @@ TransportFSM::process_events ()
if (!deferred_events.empty() ){
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(); ) {
FSMEvent* deferred_ev = *e;
if (process_event (deferred_ev)) { /* event processed, remove from deferred */
for (EventList::iterator e = deferred_events.begin(); e != deferred_events.end(); ) {
FSMEvent* deferred_ev = &(*e);
if (process_event (*e)) { /* event processed, remove from deferred */
e = deferred_events.erase (e);
delete deferred_ev;
} else {
@ -101,6 +99,8 @@ TransportFSM::process_events ()
}
}
FSMEvent* ev = &queued_events.front();
queued_events.pop_front ();
delete ev;
}
@ -166,18 +166,18 @@ TransportFSM::current_state () const
}
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;
std::cerr << "bad transition, current state = " << current_state() << " event = " << enum_2_string (ev->type) << std::endl;
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;
}
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:
switch (_motion_state) {
@ -305,11 +305,11 @@ TransportFSM::start_playback ()
}
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");
_last_stop = *s;
_last_stop = s;
}
void
@ -320,20 +320,20 @@ TransportFSM::stop_playback ()
}
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");
_last_locate = *l;
_last_locate = l;
_last_stop = FSMEvent (StopTransport, false, false);
}
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");
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
@ -344,14 +344,14 @@ TransportFSM::start_saved_locate ()
}
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");
/* maintain original "with-roll" choice of initial locate, even though
* 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
@ -376,9 +376,9 @@ TransportFSM::roll_after_locate ()
}
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);
}