143 std::string filename;
144 std::vector<ossia::net::node_base*> roots;
145 std::chrono::steady_clock::time_point first_ts;
146 int64_t nots_index{};
149 boost::container::flat_map<int, ossia::net::parameter_base*> m_map;
150 boost::container::flat_map<int64_t, std::vector<ossia::value>> m_vec_ts;
151 std::vector<std::vector<ossia::value>> m_vec_no_ts;
154 bool first_is_timestamp =
false;
157 void setActive(
bool b)
166 void setLoops(
bool b) { loops = b; }
171 f.setFileName(filter_filename(this->filename, context));
172 if(f.fileName().isEmpty())
178 f.open(QIODevice::ReadOnly);
187 for(
auto in : this->roots)
189 if([[maybe_unused]]
auto p = in->get_parameter())
195 auto data = (
const char*)f.map(0, f.size());
199 r.parse_view({data, data + f.size()});
200 int columns = r.cols();
202 auto header = r.header();
204 boost::container::flat_map<std::string, ossia::net::parameter_base*> params;
206 for(
auto node : roots)
207 if(
auto p = node->get_parameter())
208 params[node->osc_address()] = p;
213 auto header_it = header.begin();
214 if(first_is_timestamp)
224 for(; header_it != header.end(); ++header_it)
226 auto addr = *header_it;
228 addr.read_raw_value(v);
229 if(
auto it = params.find(v); it != params.end())
231 m_map[i] = it->second;
239 if(first_is_timestamp)
242 r.parse_view({data, data + f.size()});
243 m_vec_ts.reserve(r.rows());
244 for(
const auto& row : r)
246 parse_row_with_timestamps(columns, row, v);
252 m_vec_no_ts.reserve(r.rows());
253 for(
const auto& row : r)
255 parse_row_no_timestamps(columns, row, v);
259 first_ts = std::chrono::steady_clock::now();
262 void parse_cell_impl(
263 const std::string& v, ossia::net::parameter_base& param, ossia::value& out)
267 std::optional<ossia::value> res;
268 if(v.starts_with(
'"') && v.ends_with(
'"'))
269 res = State::parseValue(std::string_view(v).substr(1, v.size() - 2));
271 res = State::parseValue(v);
275 out = std::move(*res);
276 if(
auto t = param.get_value_type(); out.get_type() != t)
278 ossia::convert(out, t);
285 parse_cell(
const auto& cell, std::string& v, std::vector<ossia::value>& vec,
int i)
287 if(
auto param = m_map[i])
291 parse_cell_impl(v, *param, vec[i]);
296 void parse_row_no_timestamps(
int columns,
auto& row, std::string& v)
298 auto& vec = this->m_vec_no_ts.emplace_back(columns);
301 for(
auto it = row.begin(); it != row.end(); ++it)
303 parse_cell(*it, v, vec, i);
308 void parse_row_with_timestamps(
int columns,
auto& row, std::string& v)
310 if(row.length() <= 1)
313 auto it = row.begin();
314 const auto& ts = *it;
318 auto tstamp = ossia::parse_strict<int64_t>(v);
322 auto& vec = this->m_vec_ts[*tstamp];
323 vec.resize(columns - 1);
326 for(++it; it != row.end(); ++it)
328 parse_cell(*it, v, vec, i);
335 if(first_is_timestamp)
340 using namespace std::chrono;
341 auto ts = duration_cast<milliseconds>(steady_clock::now() - first_ts).count();
343 ts %= m_vec_ts.rbegin()->first + 1;
348 if(m_vec_no_ts.empty())
351 using namespace std::chrono;
352 if(loops && nots_index >= std::ssize(m_vec_no_ts))
354 read_no_ts(nots_index++);
358 void read_no_ts(int64_t timestamp)
362 if(timestamp >= std::ssize(m_vec_no_ts))
364 auto it = m_vec_no_ts.begin() + timestamp;
365 if(it != m_vec_no_ts.end())
372 if(
auto p = m_map.find(i); p != m_map.end())
374 p->second->push_value(v);
382 void read_ts(int64_t timestamp)
384 auto it = m_vec_ts.lower_bound(timestamp);
385 if(it != m_vec_ts.end())
387 if(it != m_vec_ts.begin())
390 for(
auto& v : it->second)
394 if(
auto p = m_map.find(i); p != m_map.end())
396 p->second->push_value(v);
405 for(
auto& v : m_vec_ts.rbegin()->second)
409 if(
auto p = m_map.find(i); p != m_map.end())
411 p->second->push_value(v);
447 std::shared_ptr<recorder_thread> recorder;
448 std::shared_ptr<player_thread> player;
450 std::vector<ossia::net::node_base*> roots;
451 bool first_is_timestamp{};
456 swap(recorder->filename, path);
457 swap(recorder->roots, roots);
458 player->filename = recorder->filename;
459 player->roots = recorder->roots;
460 player->first_is_timestamp = first_is_timestamp;
461 recorder->first_is_timestamp = first_is_timestamp;