Line |
Branch |
Exec |
Source |
1 |
|
|
/************************************************************************ |
2 |
|
|
* |
3 |
|
|
* Copyright (C) 2017-2023 IRCAD France |
4 |
|
|
* Copyright (C) 2017-2020 IHU Strasbourg |
5 |
|
|
* |
6 |
|
|
* This file is part of Sight. |
7 |
|
|
* |
8 |
|
|
* Sight is free software: you can redistribute it and/or modify it under |
9 |
|
|
* the terms of the GNU Lesser General Public License as published by |
10 |
|
|
* the Free Software Foundation, either version 3 of the License, or |
11 |
|
|
* (at your option) any later version. |
12 |
|
|
* |
13 |
|
|
* Sight is distributed in the hope that it will be useful, |
14 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
|
|
* GNU Lesser General Public License for more details. |
17 |
|
|
* |
18 |
|
|
* You should have received a copy of the GNU Lesser General Public |
19 |
|
|
* License along with Sight. If not, see <https://www.gnu.org/licenses/>. |
20 |
|
|
* |
21 |
|
|
***********************************************************************/ |
22 |
|
|
|
23 |
|
|
#include "matrices_reader.hpp" |
24 |
|
|
|
25 |
|
|
#include <core/com/signal.hpp> |
26 |
|
|
#include <core/com/signal.hxx> |
27 |
|
|
#include <core/com/signals.hpp> |
28 |
|
|
#include <core/com/slot.hpp> |
29 |
|
|
#include <core/com/slot.hxx> |
30 |
|
|
#include <core/com/slots.hpp> |
31 |
|
|
#include <core/com/slots.hxx> |
32 |
|
|
#include <core/location/single_file.hpp> |
33 |
|
|
#include <core/location/single_folder.hpp> |
34 |
|
|
|
35 |
|
|
#include <service/macros.hpp> |
36 |
|
|
|
37 |
|
|
#include <ui/__/dialog/location.hpp> |
38 |
|
|
#include <ui/__/dialog/message.hpp> |
39 |
|
|
|
40 |
|
|
#include <boost/tokenizer.hpp> |
41 |
|
|
|
42 |
|
|
#include <cmath> |
43 |
|
|
#include <filesystem> |
44 |
|
|
#include <fstream> |
45 |
|
|
|
46 |
|
|
namespace sight::module::io::matrix |
47 |
|
|
{ |
48 |
|
|
|
49 |
|
|
static const core::com::slots::key_t START_READING = "start_reading"; |
50 |
|
|
static const core::com::slots::key_t STOP_READING = "stop_reading"; |
51 |
|
|
static const core::com::slots::key_t PAUSE = "pause"; |
52 |
|
|
static const core::com::slots::key_t TOGGLE_LOOP_MODE = "toggle_loop_mode"; |
53 |
|
|
|
54 |
|
|
static const core::com::slots::key_t READ_NEXT = "readNext"; |
55 |
|
|
static const core::com::slots::key_t READ_PREVIOUS = "readPrevious"; |
56 |
|
|
static const core::com::slots::key_t SET_STEP = "set_step"; |
57 |
|
|
|
58 |
|
|
//------------------------------------------------------------------------------ |
59 |
|
|
|
60 |
|
✗ |
matrices_reader::matrices_reader() noexcept |
61 |
|
|
{ |
62 |
|
✗ |
new_slot(START_READING, &matrices_reader::start_reading, this); |
63 |
|
✗ |
new_slot(STOP_READING, &matrices_reader::stop_reading, this); |
64 |
|
✗ |
new_slot(PAUSE, &matrices_reader::pause, this); |
65 |
|
✗ |
new_slot(TOGGLE_LOOP_MODE, &matrices_reader::toggle_loop_mode, this); |
66 |
|
|
|
67 |
|
✗ |
new_slot(READ_NEXT, &matrices_reader::read_next, this); |
68 |
|
✗ |
new_slot(READ_PREVIOUS, &matrices_reader::read_previous, this); |
69 |
|
✗ |
new_slot(SET_STEP, &matrices_reader::set_step, this); |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
//------------------------------------------------------------------------------ |
73 |
|
|
|
74 |
|
✗ |
matrices_reader::~matrices_reader() noexcept |
75 |
|
|
{ |
76 |
|
✗ |
if(nullptr != m_filestream) |
77 |
|
|
{ |
78 |
|
✗ |
m_filestream->close(); |
79 |
|
✗ |
delete m_filestream; |
80 |
|
|
} |
81 |
|
|
} |
82 |
|
|
|
83 |
|
|
//------------------------------------------------------------------------------ |
84 |
|
|
|
85 |
|
✗ |
sight::io::service::path_type_t matrices_reader::get_path_type() const |
86 |
|
|
{ |
87 |
|
✗ |
return sight::io::service::file; |
88 |
|
|
} |
89 |
|
|
|
90 |
|
|
//------------------------------------------------------------------------------ |
91 |
|
|
|
92 |
|
✗ |
void matrices_reader::configuring() |
93 |
|
|
{ |
94 |
|
✗ |
sight::io::service::reader::configuring(); |
95 |
|
|
|
96 |
|
✗ |
service::config_t config = this->get_config(); |
97 |
|
|
|
98 |
|
✗ |
m_fps = config.get<unsigned int>("fps", 30); |
99 |
|
✗ |
SIGHT_ASSERT("Fps setting is set to " << m_fps << " but should be > 0.", m_fps > 0); |
100 |
|
|
|
101 |
|
✗ |
m_use_timelapse = config.get<bool>("useTimelapse", m_use_timelapse); |
102 |
|
|
|
103 |
|
✗ |
m_create_new_ts = config.get<bool>("createTimestamp", m_create_new_ts); |
104 |
|
|
|
105 |
|
✗ |
m_one_shot = config.get<bool>("oneShot", m_one_shot); |
106 |
|
|
|
107 |
|
✗ |
m_step = config.get<std::uint64_t>("step", m_step); |
108 |
|
✗ |
SIGHT_ASSERT("Step value is set to " << m_step << " but should be > 0.", m_step > 0); |
109 |
|
✗ |
m_step_changed = m_step; |
110 |
|
|
|
111 |
|
✗ |
m_loop_matrix = config.get<bool>("loop", m_loop_matrix); |
112 |
|
|
} |
113 |
|
|
|
114 |
|
|
//------------------------------------------------------------------------------ |
115 |
|
|
|
116 |
|
✗ |
void matrices_reader::starting() |
117 |
|
|
{ |
118 |
|
✗ |
m_worker = core::thread::worker::make(); |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
//------------------------------------------------------------------------------ |
122 |
|
|
|
123 |
|
✗ |
void matrices_reader::open_location_dialog() |
124 |
|
|
{ |
125 |
|
✗ |
static auto default_directory = std::make_shared<core::location::single_folder>(); |
126 |
|
✗ |
sight::ui::dialog::location dialog_file; |
127 |
|
✗ |
dialog_file.set_title(m_window_title.empty() ? "Choose a csv file to read" : m_window_title); |
128 |
|
✗ |
dialog_file.set_default_location(default_directory); |
129 |
|
✗ |
dialog_file.set_option(ui::dialog::location::read); |
130 |
|
✗ |
dialog_file.set_type(ui::dialog::location::single_file); |
131 |
|
✗ |
dialog_file.add_filter(".csv file", "*.csv"); |
132 |
|
|
|
133 |
|
✗ |
auto result = std::dynamic_pointer_cast<core::location::single_file>(dialog_file.show()); |
134 |
|
✗ |
if(result) |
135 |
|
|
{ |
136 |
|
✗ |
default_directory->set_folder(result->get_file().parent_path()); |
137 |
|
✗ |
dialog_file.save_default_location(default_directory); |
138 |
|
✗ |
this->set_file(result->get_file()); |
139 |
|
|
|
140 |
|
✗ |
if(nullptr != m_filestream) |
141 |
|
|
{ |
142 |
|
✗ |
m_filestream->close(); |
143 |
|
|
} |
144 |
|
|
|
145 |
|
✗ |
m_filestream = new std::ifstream(this->get_file().string()); |
146 |
|
|
} |
147 |
|
|
else |
148 |
|
|
{ |
149 |
|
✗ |
this->clear_locations(); |
150 |
|
|
} |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
//------------------------------------------------------------------------------ |
154 |
|
|
|
155 |
|
✗ |
void matrices_reader::stopping() |
156 |
|
|
{ |
157 |
|
✗ |
this->stop_reading(); |
158 |
|
✗ |
m_worker->stop(); |
159 |
|
|
} |
160 |
|
|
|
161 |
|
|
//------------------------------------------------------------------------------ |
162 |
|
|
|
163 |
|
✗ |
void matrices_reader::updating() |
164 |
|
|
{ |
165 |
|
|
} |
166 |
|
|
|
167 |
|
|
//------------------------------------------------------------------------------ |
168 |
|
|
|
169 |
|
✗ |
void matrices_reader::read_previous() |
170 |
|
|
{ |
171 |
|
✗ |
if(m_one_shot) |
172 |
|
|
{ |
173 |
|
✗ |
if(m_ts_matrices_count - m_step >= m_step_changed) |
174 |
|
|
{ |
175 |
|
|
// Compute difference between a possible step change in set_step() slot and the current step value |
176 |
|
✗ |
const std::int64_t shift = static_cast<std::int64_t>(m_step_changed) - static_cast<std::int64_t>(m_step); |
177 |
|
✗ |
const std::int64_t shifted = static_cast<std::int64_t>(m_ts_matrices_count) - shift; |
178 |
|
|
|
179 |
|
|
// m_tsMatricesCount is pointing to previous matrix,so -1 = present matrix |
180 |
|
✗ |
m_ts_matrices_count = static_cast<std::size_t>(shifted) - (2 * m_step); |
181 |
|
✗ |
m_step = m_step_changed; |
182 |
|
|
|
183 |
|
✗ |
m_timer->stop(); |
184 |
|
✗ |
m_timer->start(); |
185 |
|
|
} |
186 |
|
|
else |
187 |
|
|
{ |
188 |
|
✗ |
sight::ui::dialog::message::show( |
189 |
|
|
"MatricesReader", |
190 |
|
|
"No previous Matrices." |
191 |
|
|
); |
192 |
|
|
} |
193 |
|
|
} |
194 |
|
|
} |
195 |
|
|
|
196 |
|
|
//------------------------------------------------------------------------------ |
197 |
|
|
|
198 |
|
✗ |
void matrices_reader::read_next() |
199 |
|
|
{ |
200 |
|
✗ |
if(m_one_shot) |
201 |
|
|
{ |
202 |
|
|
// Compute difference between a possible step change in set_step() slot and the current step value |
203 |
|
✗ |
const std::int64_t shift = static_cast<std::int64_t>(m_step_changed) - static_cast<std::int64_t>(m_step); |
204 |
|
✗ |
const std::int64_t shifted = static_cast<std::int64_t>(m_ts_matrices_count) + shift; |
205 |
|
|
|
206 |
|
✗ |
if(shifted < static_cast<std::int64_t>(m_ts_matrices.size())) |
207 |
|
|
{ |
208 |
|
|
// Update matrix position index |
209 |
|
✗ |
m_ts_matrices_count = static_cast<std::size_t>(shifted); |
210 |
|
✗ |
m_step = m_step_changed; |
211 |
|
|
|
212 |
|
✗ |
m_timer->stop(); |
213 |
|
✗ |
m_timer->start(); |
214 |
|
|
} |
215 |
|
|
else |
216 |
|
|
{ |
217 |
|
✗ |
sight::ui::dialog::message::show( |
218 |
|
|
"MatricesReader", |
219 |
|
|
"No more matrices to read." |
220 |
|
|
); |
221 |
|
|
} |
222 |
|
|
} |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
//------------------------------------------------------------------------------ |
226 |
|
|
|
227 |
|
✗ |
void matrices_reader::set_step(int _step, std::string _key) |
228 |
|
|
{ |
229 |
|
✗ |
if(_key == "step") |
230 |
|
|
{ |
231 |
|
✗ |
SIGHT_ASSERT("Needed step value (" << _step << ") should be > 0.", _step > 0); |
232 |
|
|
|
233 |
|
|
// Save the changed step value |
234 |
|
✗ |
m_step_changed = static_cast<std::uint64_t>(_step); |
235 |
|
|
} |
236 |
|
|
else |
237 |
|
|
{ |
238 |
|
✗ |
SIGHT_WARN("Only 'step' key is supported (current key value is : '" << _key << "')."); |
239 |
|
|
} |
240 |
|
|
} |
241 |
|
|
|
242 |
|
|
//------------------------------------------------------------------------------ |
243 |
|
|
|
244 |
|
✗ |
void matrices_reader::start_reading() |
245 |
|
|
{ |
246 |
|
✗ |
if(m_timer) |
247 |
|
|
{ |
248 |
|
✗ |
this->stop_reading(); |
249 |
|
|
} |
250 |
|
|
|
251 |
|
✗ |
if(!this->has_location_defined()) |
252 |
|
|
{ |
253 |
|
✗ |
this->open_location_dialog(); |
254 |
|
|
} |
255 |
|
|
|
256 |
|
✗ |
if(this->has_location_defined()) |
257 |
|
|
{ |
258 |
|
✗ |
if(nullptr == m_filestream) |
259 |
|
|
{ |
260 |
|
✗ |
std::string file = this->get_file().string(); |
261 |
|
|
|
262 |
|
✗ |
m_filestream = new std::ifstream(file); |
263 |
|
|
} |
264 |
|
|
|
265 |
|
✗ |
if(m_filestream->is_open()) |
266 |
|
|
{ |
267 |
|
✗ |
std::string line; |
268 |
|
✗ |
while(std::getline(*m_filestream, line)) |
269 |
|
|
{ |
270 |
|
|
// parse the cvs file with tokenizer |
271 |
|
✗ |
const boost::char_separator<char> sep(", ;"); |
272 |
|
✗ |
const boost::tokenizer<boost::char_separator<char> > tok {line, sep}; |
273 |
|
|
|
274 |
|
|
// nb of 4x4 matrices = nb of elements - 1 (timestamp) / 16. |
275 |
|
✗ |
const auto nb_of_elements = std::distance(tok.begin(), tok.end()); |
276 |
|
✗ |
if(nb_of_elements < 17) |
277 |
|
|
{ |
278 |
|
✗ |
SIGHT_WARN("Too few elements(" << nb_of_elements << ") to convert this csv line into matrices"); |
279 |
|
✗ |
continue; |
280 |
|
|
} |
281 |
|
|
|
282 |
|
✗ |
const auto nb_of_matrices = static_cast<unsigned int>((nb_of_elements - 1) / 16); |
283 |
|
|
|
284 |
|
✗ |
const auto matrix_tl = m_matrix_tl.lock(); |
285 |
|
✗ |
matrix_tl->init_pool_size(nb_of_matrices); |
286 |
|
|
|
287 |
|
✗ |
time_stamped_matrices current_ts_mat; |
288 |
|
|
|
289 |
|
✗ |
boost::tokenizer<boost::char_separator<char> >::iterator iter = tok.begin(); |
290 |
|
✗ |
current_ts_mat.timestamp = std::stod(iter.current_token()); |
291 |
|
|
|
292 |
|
✗ |
++iter; |
293 |
|
|
|
294 |
|
✗ |
for(unsigned int m = 0 ; m < nb_of_matrices ; ++m) |
295 |
|
|
{ |
296 |
|
✗ |
std::array<float, 16> mat {}; |
297 |
|
✗ |
for(float& i : mat) |
298 |
|
|
{ |
299 |
|
✗ |
i = std::stof(iter.current_token()); |
300 |
|
|
|
301 |
|
✗ |
if(iter != tok.end()) |
302 |
|
|
{ |
303 |
|
✗ |
++iter; |
304 |
|
|
} |
305 |
|
|
} |
306 |
|
|
|
307 |
|
✗ |
current_ts_mat.matrices.push_back(mat); |
308 |
|
|
} |
309 |
|
|
|
310 |
|
✗ |
m_ts_matrices.push_back(current_ts_mat); |
311 |
|
|
} |
312 |
|
|
|
313 |
|
✗ |
m_filestream->close(); |
314 |
|
|
} |
315 |
|
|
else |
316 |
|
|
{ |
317 |
|
✗ |
SIGHT_ERROR("The csv file '" + this->get_file().string() + "' can not be openned."); |
318 |
|
|
} |
319 |
|
|
|
320 |
|
✗ |
if(m_one_shot) |
321 |
|
|
{ |
322 |
|
✗ |
m_timer = m_worker->create_timer(); |
323 |
|
✗ |
m_timer->set_one_shot(true); |
324 |
|
✗ |
m_timer->set_function([this](auto&& ...){read_matrices();}); |
325 |
|
✗ |
m_timer->set_duration(std::chrono::milliseconds(0)); |
326 |
|
✗ |
m_timer->start(); |
327 |
|
|
} |
328 |
|
|
else |
329 |
|
|
{ |
330 |
|
✗ |
m_timer = m_worker->create_timer(); |
331 |
|
|
|
332 |
|
✗ |
core::thread::timer::time_duration_t duration; |
333 |
|
✗ |
if(m_use_timelapse) |
334 |
|
|
{ |
335 |
|
✗ |
m_timer->set_one_shot(true); |
336 |
|
✗ |
if(m_ts_matrices.size() >= 2) |
337 |
|
|
{ |
338 |
|
✗ |
duration = |
339 |
|
✗ |
std::chrono::milliseconds( |
340 |
|
✗ |
static_cast<std::uint64_t>(m_ts_matrices[1].timestamp |
341 |
|
✗ |
- m_ts_matrices[0].timestamp) |
342 |
|
|
); |
343 |
|
|
} |
344 |
|
|
else |
345 |
|
|
{ |
346 |
|
|
// Only one matrix to read, might as well just read it ASAP. |
347 |
|
✗ |
duration = std::chrono::milliseconds(0); |
348 |
|
|
} |
349 |
|
|
} |
350 |
|
|
else |
351 |
|
|
{ |
352 |
|
✗ |
duration = std::chrono::milliseconds(1000 / m_fps); |
353 |
|
|
} |
354 |
|
|
|
355 |
|
✗ |
m_timer->set_function([this](auto&& ...){read_matrices();}); |
356 |
|
✗ |
m_timer->set_duration(duration); |
357 |
|
✗ |
m_timer->start(); |
358 |
|
|
} |
359 |
|
|
|
360 |
|
✗ |
m_is_playing = true; |
361 |
|
|
} |
362 |
|
|
} |
363 |
|
|
|
364 |
|
|
//------------------------------------------------------------------------------ |
365 |
|
|
|
366 |
|
✗ |
void matrices_reader::stop_reading() |
367 |
|
|
{ |
368 |
|
✗ |
m_is_playing = false; |
369 |
|
|
|
370 |
|
✗ |
if(m_timer) |
371 |
|
|
{ |
372 |
|
✗ |
if(m_timer->is_running()) |
373 |
|
|
{ |
374 |
|
✗ |
m_timer->stop(); |
375 |
|
|
} |
376 |
|
|
|
377 |
|
✗ |
m_timer.reset(); |
378 |
|
|
} |
379 |
|
|
|
380 |
|
✗ |
if(nullptr != m_filestream) |
381 |
|
|
{ |
382 |
|
✗ |
m_filestream->close(); |
383 |
|
✗ |
delete m_filestream; |
384 |
|
✗ |
m_filestream = nullptr; |
385 |
|
|
} |
386 |
|
|
|
387 |
|
✗ |
if(!m_ts_matrices.empty()) |
388 |
|
|
{ |
389 |
|
✗ |
m_ts_matrices.clear(); |
390 |
|
|
} |
391 |
|
|
|
392 |
|
✗ |
m_ts_matrices_count = 0; |
393 |
|
|
|
394 |
|
|
//clear the timeline |
395 |
|
✗ |
const auto matrix_tl = m_matrix_tl.lock(); |
396 |
|
✗ |
matrix_tl->clear_timeline(); |
397 |
|
|
|
398 |
|
✗ |
auto sig = matrix_tl->signal<data::timeline::signals::cleared_t>(data::timeline::signals::CLEARED); |
399 |
|
✗ |
sig->async_emit(); |
400 |
|
|
} |
401 |
|
|
|
402 |
|
|
//------------------------------------------------------------------------------ |
403 |
|
|
|
404 |
|
✗ |
void matrices_reader::pause() |
405 |
|
|
{ |
406 |
|
✗ |
m_is_paused = !m_is_paused; |
407 |
|
✗ |
if(m_timer) |
408 |
|
|
{ |
409 |
|
✗ |
m_is_paused ? m_timer->stop() : m_timer->start(); |
410 |
|
|
} |
411 |
|
|
} |
412 |
|
|
|
413 |
|
|
//------------------------------------------------------------------------------ |
414 |
|
|
|
415 |
|
✗ |
void matrices_reader::read_matrices() |
416 |
|
|
{ |
417 |
|
✗ |
if(!m_is_paused && m_ts_matrices_count < m_ts_matrices.size()) |
418 |
|
|
{ |
419 |
|
✗ |
const auto t_start = core::clock::get_time_in_milli_sec(); |
420 |
|
✗ |
const auto matrix_tl = m_matrix_tl.lock(); |
421 |
|
|
|
422 |
|
✗ |
time_stamped_matrices current_matrices = m_ts_matrices[m_ts_matrices_count]; |
423 |
|
|
|
424 |
|
✗ |
core::clock::type timestamp = NAN; |
425 |
|
|
|
426 |
|
✗ |
if(m_create_new_ts) |
427 |
|
|
{ |
428 |
|
✗ |
timestamp = core::clock::get_time_in_milli_sec(); |
429 |
|
|
} |
430 |
|
|
else |
431 |
|
|
{ |
432 |
|
✗ |
timestamp = current_matrices.timestamp; |
433 |
|
|
} |
434 |
|
|
|
435 |
|
|
// Push matrix in timeline |
436 |
|
✗ |
SPTR(data::matrix_tl::buffer_t) matrix_buf; |
437 |
|
✗ |
matrix_buf = matrix_tl->create_buffer(timestamp); |
438 |
|
✗ |
matrix_tl->push_object(matrix_buf); |
439 |
|
|
|
440 |
|
✗ |
SIGHT_DEBUG("Reading matrix index " << m_ts_matrices_count << " with timestamp " << timestamp); |
441 |
|
✗ |
for(unsigned int i = 0 ; i < current_matrices.matrices.size() ; ++i) |
442 |
|
|
{ |
443 |
|
✗ |
matrix_buf->set_element(current_matrices.matrices[i], i); |
444 |
|
|
} |
445 |
|
|
|
446 |
|
✗ |
if(m_use_timelapse && (m_ts_matrices_count + m_step) < m_ts_matrices.size()) |
447 |
|
|
{ |
448 |
|
✗ |
const auto elapsed_time = core::clock::get_time_in_milli_sec() - t_start; |
449 |
|
✗ |
const std::size_t current_matrix = m_ts_matrices_count; |
450 |
|
✗ |
const double current_time = m_ts_matrices[current_matrix].timestamp + elapsed_time; |
451 |
|
✗ |
double next_duration = m_ts_matrices[m_ts_matrices_count + m_step].timestamp - current_time; |
452 |
|
|
|
453 |
|
|
// If the next matrix delay is already passed, drop the matrices and check the next one. |
454 |
|
✗ |
while(next_duration < elapsed_time && (m_ts_matrices_count + m_step) < m_ts_matrices.size()) |
455 |
|
|
{ |
456 |
|
✗ |
next_duration = m_ts_matrices[m_ts_matrices_count + m_step].timestamp - current_time; |
457 |
|
✗ |
m_ts_matrices_count += m_step; |
458 |
|
✗ |
SIGHT_DEBUG("Skipping a matrix"); |
459 |
|
|
} |
460 |
|
|
|
461 |
|
|
// If it is the last matrix array: stop the timer or loop |
462 |
|
✗ |
if((m_ts_matrices_count + m_step) == m_ts_matrices.size()) |
463 |
|
|
{ |
464 |
|
✗ |
m_timer->stop(); |
465 |
|
✗ |
if(m_loop_matrix) |
466 |
|
|
{ |
467 |
|
✗ |
matrix_tl->clear_timeline(); |
468 |
|
✗ |
m_ts_matrices_count = 0; |
469 |
|
✗ |
core::thread::timer::time_duration_t duration = std::chrono::milliseconds(1000 / m_fps); |
470 |
|
✗ |
m_timer->set_duration(duration); |
471 |
|
✗ |
m_timer->start(); |
472 |
|
|
} |
473 |
|
|
} |
474 |
|
|
else |
475 |
|
|
{ |
476 |
|
✗ |
next_duration = m_ts_matrices[m_ts_matrices_count + m_step].timestamp |
477 |
|
|
- current_time; |
478 |
|
✗ |
core::thread::timer::time_duration_t duration = |
479 |
|
✗ |
std::chrono::milliseconds(static_cast<std::int64_t>(next_duration)); |
480 |
|
✗ |
m_timer->stop(); |
481 |
|
✗ |
m_timer->set_duration(duration); |
482 |
|
✗ |
m_timer->start(); |
483 |
|
|
} |
484 |
|
|
} |
485 |
|
|
|
486 |
|
|
//Notify |
487 |
|
✗ |
data::timeline::signals::pushed_t::sptr sig; |
488 |
|
✗ |
sig = matrix_tl->signal<data::timeline::signals::pushed_t>( |
489 |
|
|
data::timeline::signals::PUSHED |
490 |
|
✗ |
); |
491 |
|
✗ |
sig->async_emit(timestamp); |
492 |
|
|
|
493 |
|
✗ |
m_ts_matrices_count += m_step; |
494 |
|
|
} |
495 |
|
✗ |
else if(!m_is_paused && m_loop_matrix) |
496 |
|
|
{ |
497 |
|
✗ |
const auto matrix_tl = m_matrix_tl.lock(); |
498 |
|
✗ |
matrix_tl->clear_timeline(); |
499 |
|
✗ |
m_ts_matrices_count = 0; |
500 |
|
|
} |
501 |
|
|
} |
502 |
|
|
|
503 |
|
|
// ----------------------------------------------------------------------------- |
504 |
|
|
|
505 |
|
✗ |
void matrices_reader::toggle_loop_mode() |
506 |
|
|
{ |
507 |
|
✗ |
m_loop_matrix = !m_loop_matrix; |
508 |
|
|
} |
509 |
|
|
|
510 |
|
|
//------------------------------------------------------------------------------ |
511 |
|
|
|
512 |
|
|
} // namespace sight::module::io::matrix |
513 |
|
|
|