1 #ifndef _ardour_transport_fsm_h_
2 #define _ardour_transport_fsm_h_
7 #include <boost/intrusive/list.hpp>
8 #include <boost/optional.hpp>
14 #include "pbd/demangle.h"
15 #include "pbd/stacktrace.h"
17 #include "ardour/debug.h"
18 #include "ardour/types.h"
27 /* All code related to this object is expected to be run synchronously
28 * and single-threaded from the process callback. It can be re-entrant
29 * if handling one transport state change queues another state change,
30 * but that is handled explicitly (see the @param processing member and
45 struct Event : public boost::intrusive::list_base_hook<> {
48 bool abort; /* for stop */
49 LocateTransportDisposition ltd; /* for locate */
52 bool clear_state; /* for stop */
53 bool with_flush; /* for locate */
65 , for_loop_end (false)
68 assert (t != StopTransport);
71 Event (EventType t, bool ab, bool cl)
76 assert (t == StopTransport);
78 Event (EventType t, samplepos_t pos, LocateTransportDisposition l, bool fl, bool lp, bool f4c)
89 void* operator new (size_t);
90 void operator delete (void *ptr, size_t /*size*/);
92 static void init_pool ();
99 TransportFSM (TransportAPI& tapi);
106 /* should we do anything here? this method is modelled on the
107 boost::msm design, but its not clear that we ever need to
108 do anything like this.
125 std::string current_state () const;
128 MotionState _motion_state;
129 ButlerState _butler_state;
133 /* transition actions */
135 void schedule_butler_for_transport_work () const;
136 void start_playback ();
137 void stop_playback (Event const &);
138 void start_locate_after_declick () const;
139 void locate_for_loop (Event const &);
140 void roll_after_locate () const;
141 void start_locate_while_stopped (Event const &) const;
142 void interrupt_locate (Event const &) const;
143 void start_declick_for_locate (Event const &);
147 bool should_roll_after_locate () const;
148 bool should_not_roll_after_locate () const { return !should_roll_after_locate (); }
151 bool locating () const { return _motion_state == WaitingForLocate; }
152 bool rolling () const { return _motion_state == Rolling; }
153 bool stopped () const { return _motion_state == Stopped; }
154 bool stopping () const { return _motion_state == DeclickToStop; }
155 bool waiting_for_butler() const { return _butler_state == WaitingForButler; }
156 bool declick_in_progress() const { return _motion_state == DeclickToLocate || _motion_state == DeclickToStop; }
158 void enqueue (Event* ev);
162 void transition (MotionState ms);
163 void transition (ButlerState bs);
165 void process_events ();
166 bool process_event (Event&, bool was_deferred, bool& deferred);
171 typedef boost::intrusive::list<Event> EventList;
172 EventList queued_events;
173 EventList deferred_events;
175 mutable boost::optional<bool> current_roll_after_locate_status;
177 void defer (Event& ev);
178 void bad_transition (Event const &);
179 void set_roll_after (bool) const;
180 bool compute_should_roll (LocateTransportDisposition) const;
183 } /* end namespace ARDOUR */