Ardour  8.12
transport_fsm.h
Go to the documentation of this file.
1 #ifndef _ardour_transport_fsm_h_
2 #define _ardour_transport_fsm_h_
3 
4 #include <list>
5 #include <queue>
6 
7 #include <boost/intrusive/list.hpp>
8 #include <boost/optional.hpp>
9 
10 #include <string>
11 #include <utility>
12 #include <iostream>
13 
14 #include "pbd/demangle.h"
15 
16 #include "ardour/debug.h"
17 #include "ardour/types.h"
18 
19 namespace ARDOUR
20 {
21 
22 class TransportAPI;
23 
25 {
26  /* All code related to this object is expected to be run synchronously
27  * and single-threaded from the process callback. It can be re-entrant
28  * if handling one transport state change queues another state change,
29  * but that is handled explicitly (see the @p processing member and
30  * its usage).
31  */
32 
33  public:
34  enum EventType {
43  };
44 
45  struct Event : public boost::intrusive::list_base_hook<> {
47  /* for stop and speed */
50  /* for locate */
54  bool force;
55  /* for SetSpeed */
56  double speed;
57 
59  : type (t)
60  , abort_capture (false)
61  , clear_state (false)
62  , ltd (MustStop)
63  , target (0)
64  , for_loop_end (false)
65  , force (false)
66  {
67  assert (t != StopTransport);
68  assert (t != Locate);
69  }
70  Event (EventType t, bool ab, bool cl)
71  : type (t)
72  , abort_capture (ab)
73  , clear_state (cl)
74  , ltd (MustStop)
75  , target (0)
76  , for_loop_end (false)
77  , force (false)
78  {
79  assert (t == StopTransport);
80  }
81  Event (EventType t, samplepos_t pos, LocateTransportDisposition l, bool lp, bool f4c)
82  : type (t)
83  , abort_capture (false)
84  , clear_state (false)
85  , ltd (l)
86  , target (pos)
87  , for_loop_end (lp)
88  , force (f4c)
89  {
90  assert (t == Locate);
91  }
92  /* here we drop the event type as the first argument in order
93  disambiguate from the StopTransport case above (compiler can
94  cast double-to-bool and complains. C++11 would allow "=
95  delete" as an alternate fix, but this is fine.
96  */
97  Event (double sp)
98  : type (SetSpeed)
99  , speed (sp)
100  {
101  }
102 
103  void* operator new (size_t);
104  void operator delete (void *ptr, size_t /*size*/);
105 
106  static void init_pool ();
107 
108  private:
109  static PBD::Pool* pool;
110 
111  };
112 
114 
115  void hard_stop ();
116 
117  void start () {
118  init ();
119  }
120 
121  void stop () {
122  /* should we do anything here? this method is modelled on the
123  boost::msm design, but its not clear that we ever need to
124  do anything like this.
125  */
126  }
127 
128  enum MotionState {
134  };
135 
136  enum ButlerState {
139  };
140 
145  };
146 
147  std::string current_state () const;
148 
149  double transport_speed() const { return _transport_speed; }
150 
151  double default_speed() const { return _default_speed; }
152  void set_default_speed(double spd) const { _default_speed = spd; }
153 
154  private:
159 
160  void init();
161 
162  /* transition actions */
163 
165  void start_playback ();
166  void stop_playback (Event const &);
168  void locate_for_loop (Event const &);
169  void roll_after_locate () const;
170  void start_locate_while_stopped (Event const &) const;
171  void interrupt_locate (Event const &) const;
173  bool set_speed (Event const &);
174 
175  /* guards */
176 
179 
180  public:
181  bool locating () const { return _motion_state == WaitingForLocate; }
182  bool rolling () const { return _motion_state == Rolling; }
183  bool stopped () const { return _motion_state == Stopped; }
184  bool stopping () const { return _motion_state == DeclickToStop; }
188  bool forwards() const { return _direction_state == Forwards; }
189  bool backwards() const { return _direction_state == Backwards; }
190  bool reversing() const { return _direction_state == Reversing; }
191  bool will_roll_forwards() const;
192 
193  void enqueue (Event* ev);
194 
195  private:
196 
200 
201  void process_events ();
202  bool process_event (Event&, bool was_deferred, bool& deferred);
203 
205 
207  typedef boost::intrusive::list<Event> EventList;
211  mutable boost::optional<bool> current_roll_after_locate_status;
213  mutable double _default_speed;
215 
216  void defer (Event& ev);
217  void bad_transition (Event const &);
218  void set_roll_after (bool) const;
222 };
223 
224 } /* end namespace ARDOUR */
225 
226 #endif
Definition: pool.h:41
Temporal::samplepos_t samplepos_t
LocateTransportDisposition ltd
Definition: transport_fsm.h:51
static PBD::Pool * pool
Event(EventType t, samplepos_t pos, LocateTransportDisposition l, bool lp, bool f4c)
Definition: transport_fsm.h:81
Event(EventType t, bool ab, bool cl)
Definition: transport_fsm.h:70
double transport_speed() const
void transition(ButlerState)
bool process_event(Event &, bool was_deferred, bool &deferred)
ButlerState _butler_state
bool should_not_roll_after_locate() const
void interrupt_locate(Event const &) const
void enqueue(Event *ev)
void start_locate_after_declick()
void start_declick_for_locate(Event const &)
bool stopped() const
void start_locate_while_stopped(Event const &) const
int compute_transport_speed() const
void set_default_speed(double spd) const
double default_speed() const
bool locating() const
void schedule_butler_for_transport_work() const
bool should_roll_after_locate() const
void roll_after_locate() const
bool compute_should_roll(LocateTransportDisposition) const
bool stopping() const
boost::intrusive::list< Event > EventList
void set_roll_after(bool) const
DirectionState _direction_state
bool waiting_for_butler() const
void transition(DirectionState)
bool reversing() const
double most_recently_requested_speed
void stop_playback(Event const &)
void locate_for_loop(Event const &)
bool will_roll_forwards() const
TransportAPI * api
void bad_transition(Event const &)
std::string current_state() const
bool set_speed(Event const &)
MotionState _motion_state
bool forwards() const
bool backwards() const
TransportFSM(TransportAPI &tapi)
void defer(Event &ev)
void transition(MotionState)
bool declicking_for_locate() const
bool rolling() const
boost::optional< bool > current_roll_after_locate_status
bool declick_in_progress() const