1 #ifndef _library__movie__hpp__included__
2 #define _library__movie__hpp__included__
7 #include "portctrl-data.hpp"
10 * Movie being played back or recorded
16 * Construct new empty movie.
18 * throws std::bad_alloc: Not enough memory.
20 movie() throw(std::bad_alloc
);
28 * Is the movie in readonly mode?
30 * returns: True if in read-only mode, false if in read-write mode.
32 bool readonly_mode() throw();
35 * Switches movie to read-only or read-write mode. If switching to read-write mode, the movie is truncated.
37 * parameter enable: If true, switch to read-only mode, else to read-write mode.
38 * throws std::bad_alloc: Not enough memory.
40 void readonly_mode(bool enable
) throw(std::bad_alloc
);
43 * Returns the movie rerecord count (this is not the same thing as global rerecord count).
45 * returns: The movie rerecord count
46 * throws std::bad_alloc: Not enough memory.
48 std::string
rerecord_count() throw(std::bad_alloc
);
51 * Sets the movie rerecord count (this is not the same thing as global rerecord count).
53 * parameter count: The new rerecord count
54 * throws std::bad_alloc: Not enough memory.
56 void rerecord_count(const std::string
& count
) throw(std::bad_alloc
);
61 * returns: The project ID
62 * throws std::bad_alloc: Not enough memory.
64 std::string
project_id() throw(std::bad_alloc
);
67 * brief Set project ID
69 * parameter id: New project ID.
70 * throws std::bad_alloc: Not enough memory.
72 void project_id(const std::string
& id
) throw(std::bad_alloc
);
75 * Get number of frames in movie
77 * returns: The number of frames.
79 uint64_t get_frame_count() throw() { return movie_data
->count_frames(); }
82 * Get number of current frame in movie
84 * The first frame in movie is 1. 0 is "before first frame" value.
86 * returns: The number of frame
88 uint64_t get_current_frame() throw();
91 * Get number of lag frames so far
93 * returns: The number of lag frames.
95 uint64_t get_lag_frames() throw();
98 * This function advances to next frame in movie, discarding subframes not used. If the frame is lag frame, it is
99 * counted as lag frame and subframe entry for it is made (if in readwrite mode).
101 * throws std::bad_alloc: Not enough memory.
103 void next_frame() throw(std::bad_alloc
);
106 * Reads the data ready flag. On new frame, all data ready flags are unset. On reading control, its data ready
109 * parameter pid: Physical controller id.
110 * parameter index: Control ID.
111 * returns: The read value.
112 * throws std::logic_error: Invalid control index.
114 bool get_DRDY(unsigned port
, unsigned controller
, unsigned index
) throw(std::logic_error
);
117 * Set all data ready flags
119 void set_all_DRDY() throw();
122 * Poll a control by (port, controller, index) tuple.
124 * parameter pid: Physical controller ID.
125 * parameter index: The index of control in controller (0 to 11)
126 * returns: The read value
127 * throws std::bad_alloc: Not enough memory.
128 * throws std::logic_error: Invalid port, controller or index or before movie start.
130 short next_input(unsigned port
, unsigned controller
, unsigned index
) throw(std::bad_alloc
, std::logic_error
);
133 * Set current control values. These are read in readwrite mode.
135 * parameter controls: The new controls.
137 void set_controls(portctrl::frame controls
) throw();
140 * Get current control values in effect.
144 portctrl::frame
get_controls() throw();
147 * Loads a movie plus some other parameters. The playback pointer is positioned to start of movie and readonly
150 * parameter rerecs: Movie rerecord count.
151 * parameter project_id: Project ID of movie.
152 * parameter input: The input track.
153 * throws std::bad_alloc: Not enough memory.
154 * throws std::runtime_error: Bad movie data.
156 void load(const std::string
& rerecs
, const std::string
& project_id
, portctrl::frame_vector
& input
)
157 throw(std::bad_alloc
, std::runtime_error
);
160 * This method serializes the state of movie code.
162 * Parameter proj_id: The project ID is written here.
163 * Parameter curframe: Current frame is written here.
164 * Parameter lagframes: Lag counter is written here.
165 * Parameter pcounters: Poll counters are written here.
166 * throws std::bad_alloc: Not enough memory.
168 void save_state(std::string
& proj_id
, uint64_t& curframe
, uint64_t& lagframes
,
169 std::vector
<uint32_t>& pcounters
) throw(std::bad_alloc
);
172 * Given previous serialized state from this movie, restore the state.
174 * Parameter curframe: Current frame.
175 * Parameter lagframe: Lag counter.
176 * Parameter pcounters: Poll counters.
177 * Parameter ro: If true, restore in readonly mode.
178 * Parameter old_movie: Old movie to check for compatiblity against.
179 * Parameter old_projectid: Old project ID to check against.
181 * Throws std::bad_alloc: Not enough memory.
182 * Throws std::runtime_error: Movie check failure.
184 size_t restore_state(uint64_t curframe
, uint64_t lagframe
, const std::vector
<uint32_t>& pcounters
, bool ro
,
185 portctrl::frame_vector
* old_movie
, const std::string
& old_projectid
) throw(std::bad_alloc
,
188 * Reset the state of movie to initial state.
190 void reset_state() throw();
192 * Get how manyth poll in the frame next poll would be?
194 * returns: Poll number.
196 unsigned next_poll_number();
198 * Get how many subframes there are in specified frame.
200 * parameter frame: The frame number.
201 * returns: Number of subframes (0 if outside movie).
203 uint64_t frame_subframes(uint64_t frame
) throw();
205 * Read controls from specified subframe of specified frame.
207 * parameter frame: The frame number.
208 * parameter subframe: Subframe within frame (first is 0).
209 * returns: The controls for subframe. If subframe is too great, reads last present subframe. If frame is outside
210 * movie, reads all released.
212 portctrl::frame
read_subframe(uint64_t frame
, uint64_t subframe
) throw();
216 void fast_save(uint64_t& _frame
, uint64_t& _ptr
, uint64_t& _lagc
, std::vector
<uint32_t>& counters
);
220 void fast_load(uint64_t& _frame
, uint64_t& _ptr
, uint64_t& _lagc
, std::vector
<uint32_t>& counters
);
222 * Poll flag handling.
227 virtual ~poll_flag();
231 virtual int get_pflag() = 0;
235 virtual void set_pflag(int flag
) = 0;
238 * Set the poll flag handler.
240 void set_pflag_handler(poll_flag
* handler
);
244 void clear_caches() throw();
246 * Get sequence number (increments by 1 each time whole data is reloaded).
248 uint64_t get_seqno() throw() { return seqno
; }
250 * Get pollcounter vector.
252 portctrl::counters
& get_pollcounters() { return pollcounters
; }
254 * Get first subframe of this frame.
256 uint64_t get_current_frame_first_subframe() { return current_frame_first_subframe
; }
258 * Read specified triple at specified subframe of current frame. Only works in readonly mode.
260 int16_t read_subframe_at_index(uint32_t subframe
, unsigned port
, unsigned controller
, unsigned index
);
262 * Write specified triple at specified subframe of current frame (if possible). Only works in readonly mode.
264 void write_subframe_at_index(uint32_t subframe
, unsigned port
, unsigned controller
, unsigned index
,
267 * Call portctrl::frame_vector::compatible() with correct frame and pollcounters.
269 * Parameter with: The second vector.
270 * Returns: True if compatible, false if not.
272 bool compatible(portctrl::frame_vector
& with
)
274 return movie_data
->compatible(with
, current_frame
, pollcounters
.rawdata());
277 * Set external movie data.
279 * Parameter data: New movie data.
281 void set_movie_data(portctrl::frame_vector
* data
);
283 class fchange_listener
: public portctrl::frame_vector::fchange_listener
286 fchange_listener(movie
& m
);
288 void notify(portctrl::frame_vector
& src
, uint64_t old
);
292 movie(const movie
& mov
);
293 movie
& operator=(const movie
& m
);
296 //The poll flag handling.
297 poll_flag
* pflag_handler
;
298 //TRUE if readonly mode is active.
300 //TRUE if movie is latched to end.
302 //Movie (not global!) rerecord count.
303 std::string rerecords
;
305 std::string _project_id
;
306 //The actual controller data.
307 portctrl::frame_vector
* movie_data
;
308 //Current frame + 1 (0 before next_frame() has been called.
309 uint64_t current_frame
;
310 //First subframe in current frame (movie_data.size() if no subframes have been stored).
311 uint64_t current_frame_first_subframe
;
312 //How many times has each control been polled (bit 31 is data ready bit)?
313 portctrl::counters pollcounters
;
314 //Current state of buttons.
315 portctrl::frame current_controls
;
316 //Number of known lag frames.
319 uint64_t cached_frame
;
320 uint64_t cached_subframe
;
321 //Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
322 uint32_t count_changes(uint64_t first_subframe
) throw();