+
+ return info;
+ }
+
+ boost::property_tree::wptree delay_info() const
+ {
+ boost::property_tree::wptree info;
+
+ auto stage_info = stage_.delay_info();
+ auto mixer_info = mixer_.delay_info();
+ auto output_info = output_.delay_info();
+
+ // TODO: because of std::async deferred timed waiting does not work so for now we have to block
+ info.add_child(L"layers", stage_info.get());
+ info.add_child(L"mix-time", mixer_info.get());
+ info.add_child(L"output", output_info.get());
+
+ return info;
+ }
+
+ std::shared_ptr<void> add_tick_listener(std::function<void()> listener)
+ {
+ return lock(tick_listeners_mutex_, [&]
+ {
+ auto tick_listener_id = last_tick_listener_id++;
+ tick_listeners_.insert(std::make_pair(tick_listener_id, listener));
+
+ return std::shared_ptr<void>(nullptr, [=](void*)
+ {
+ lock(tick_listeners_mutex_, [&]
+ {
+ tick_listeners_.erase(tick_listener_id);
+ });
+ });
+ });