diff options
author | David Robillard <d@drobilla.net> | 2016-12-14 14:44:32 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2016-12-14 14:47:13 -0500 |
commit | bf71b4be9f36f9d7c619053d97ab6f98bb98dc21 (patch) | |
tree | ea1d8b78defdeec76026d24fbf507c75a97629d1 /src/server/events | |
parent | a2f86537a9fdaabe12b553a1cf066649a96b4891 (diff) | |
download | ingen-bf71b4be9f36f9d7c619053d97ab6f98bb98dc21.tar.gz ingen-bf71b4be9f36f9d7c619053d97ab6f98bb98dc21.tar.bz2 ingen-bf71b4be9f36f9d7c619053d97ab6f98bb98dc21.zip |
Fix real-time safety of control bindings
Diffstat (limited to 'src/server/events')
-rw-r--r-- | src/server/events/Delete.cpp | 11 | ||||
-rw-r--r-- | src/server/events/Delete.hpp | 4 | ||||
-rw-r--r-- | src/server/events/Delta.cpp | 54 | ||||
-rw-r--r-- | src/server/events/Delta.hpp | 32 |
4 files changed, 57 insertions, 44 deletions
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index d04f176c..b77f7c3e 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -56,6 +56,9 @@ Delete::~Delete() { delete _disconnect_event; delete _compiled_graph; + for (ControlBindings::Binding* b : _removed_bindings) { + delete b; + } } bool @@ -65,7 +68,7 @@ Delete::pre_process(PreProcessContext& ctx) return Event::pre_process_done(Status::NOT_DELETABLE, _path); } - _removed_bindings = _engine.control_bindings()->remove(_path); + _engine.control_bindings()->get_all(_path, _removed_bindings); Store::iterator iter = _engine.store()->find(_path); if (iter == _engine.store()->end()) { @@ -131,6 +134,10 @@ Delete::execute(RunContext& context) _disconnect_event->execute(context); } + if (!_removed_bindings.empty()) { + _engine.control_bindings()->remove(context, _removed_bindings); + } + GraphImpl* parent = _block ? _block->parent_graph() : NULL; if (_port) { parent = _port->parent_graph(); @@ -150,8 +157,6 @@ Delete::execute(RunContext& context) void Delete::post_process() { - _removed_bindings.reset(); - Broadcaster::Transfer t(*_engine.broadcaster()); if (respond() == Status::SUCCESS && (_block || _port)) { if (_block) { diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp index fd797804..1b34faf6 100644 --- a/src/server/events/Delete.hpp +++ b/src/server/events/Delete.hpp @@ -68,9 +68,9 @@ private: Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Graph CompiledGraph* _compiled_graph; ///< Graph's new process order DisconnectAll* _disconnect_event; + Store::Objects _removed_objects; - SPtr<ControlBindings::Bindings> _removed_bindings; - Store::Objects _removed_objects; + std::vector<ControlBindings::Binding*> _removed_bindings; }; } // namespace Events diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 66897c66..c623d51e 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -61,6 +61,7 @@ Delta::Delta(Engine& engine, , _object(NULL) , _graph(NULL) , _compiled_graph(NULL) + , _binding(NULL) , _state(NULL) , _context(context) , _type(type) @@ -223,8 +224,9 @@ Delta::pre_process(PreProcessContext& ctx) const Atom& value = r.second; if (key == uris.midi_binding && value == uris.patch_wildcard) { PortImpl* port = dynamic_cast<PortImpl*>(_object); - if (port) - _old_bindings = _engine.control_bindings()->remove(port); + if (port) { + _engine.control_bindings()->get_all(port->path(), _removed_bindings); + } } if (_object) { _removed.emplace(key, value); @@ -299,9 +301,10 @@ Delta::pre_process(PreProcessContext& ctx) } else if (key == uris.midi_binding) { if (port->is_a(PortType::CONTROL) || port->is_a(PortType::CV)) { if (value == uris.patch_wildcard) { - _engine.control_bindings()->learn(port); + _engine.control_bindings()->start_learn(port); } else if (value.type() == uris.atom_Object) { - op = SpecialType::CONTROL_BINDING; + op = SpecialType::CONTROL_BINDING; + _binding = new ControlBindings::Binding(); } else { _status = Status::BAD_VALUE_TYPE; } @@ -372,24 +375,23 @@ Delta::pre_process(PreProcessContext& ctx) if (!_create_event && key == uris.ingen_polyphonic) { GraphImpl* parent = dynamic_cast<GraphImpl*>(obj->parent()); - if (parent) { - if (value.type() == uris.forge.Bool) { - poly_changed = true; - op = SpecialType::POLYPHONIC; - obj->set_property(key, value, value.context()); - BlockImpl* block = dynamic_cast<BlockImpl*>(obj); - if (block) - block->set_polyphonic(value.get<int32_t>()); - if (value.get<int32_t>()) { - obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); - } else { - obj->prepare_poly(*_engine.buffer_factory(), 1); - } + if (!parent) { + _status = Status::BAD_OBJECT_TYPE; + } else if (value.type() != uris.forge.Bool) { + _status = Status::BAD_VALUE_TYPE; + } else { + poly_changed = true; + op = SpecialType::POLYPHONIC; + obj->set_property(key, value, value.context()); + BlockImpl* block = dynamic_cast<BlockImpl*>(obj); + if (block) { + block->set_polyphonic(value.get<int32_t>()); + } + if (value.get<int32_t>()) { + obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); } else { - _status = Status::BAD_VALUE_TYPE; + obj->prepare_poly(*_engine.buffer_factory(), 1); } - } else { - _status = Status::BAD_OBJECT_TYPE; } } } else if (is_client && key == uris.ingen_broadcast) { @@ -454,6 +456,10 @@ Delta::execute(RunContext& context) s->execute(context); } + if (!_removed_bindings.empty()) { + _engine.control_bindings()->remove(context, _removed_bindings); + } + NodeImpl* const object = dynamic_cast<NodeImpl*>(_object); BlockImpl* const block = dynamic_cast<BlockImpl*>(_object); PortImpl* const port = dynamic_cast<PortImpl*>(_object); @@ -501,7 +507,9 @@ Delta::execute(RunContext& context) break; case SpecialType::CONTROL_BINDING: if (port) { - _engine.control_bindings()->port_binding_changed(context, port, value); + if (!_engine.control_bindings()->set_port_binding(context, port, _binding, value)) { + _status = Status::BAD_VALUE; + } } else if (block) { if (uris.ingen_Internal == block->plugin_impl()->type()) { block->learn(); @@ -513,9 +521,9 @@ Delta::execute(RunContext& context) break; case SpecialType::NONE: if (port) { - if (key == uris.lv2_minimum) { + if (!strcmp(uris.lv2_minimum.c_str(), key.c_str())) { port->set_minimum(value); - } else if (key == uris.lv2_maximum) { + } else if (!strcmp(uris.lv2_maximum.c_str(), key.c_str())) { port->set_maximum(value); } } diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp index 98570210..ca9d0276 100644 --- a/src/server/events/Delta.hpp +++ b/src/server/events/Delta.hpp @@ -92,26 +92,26 @@ private: typedef std::vector<SetPortValue*> SetEvents; - Event* _create_event; - SetEvents _set_events; - std::vector<SpecialType> _types; - std::vector<SpecialType> _remove_types; - Raul::URI _subject; - Resource::Properties _properties; - Resource::Properties _remove; - ClientUpdate _update; - Ingen::Resource* _object; - GraphImpl* _graph; - CompiledGraph* _compiled_graph; - LilvState* _state; - Resource::Graph _context; - ControlBindings::Key _binding; - Type _type; + Event* _create_event; + SetEvents _set_events; + std::vector<SpecialType> _types; + std::vector<SpecialType> _remove_types; + Raul::URI _subject; + Resource::Properties _properties; + Resource::Properties _remove; + ClientUpdate _update; + Ingen::Resource* _object; + GraphImpl* _graph; + CompiledGraph* _compiled_graph; + ControlBindings::Binding* _binding; + LilvState* _state; + Resource::Graph _context; + Type _type; Resource::Properties _added; Resource::Properties _removed; - SPtr<ControlBindings::Bindings> _old_bindings; + std::vector<ControlBindings::Binding*> _removed_bindings; boost::optional<Resource> _preset; |