summaryrefslogtreecommitdiffstats
path: root/src/server/events
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-12-14 14:44:32 -0500
committerDavid Robillard <d@drobilla.net>2016-12-14 14:47:13 -0500
commitbf71b4be9f36f9d7c619053d97ab6f98bb98dc21 (patch)
treeea1d8b78defdeec76026d24fbf507c75a97629d1 /src/server/events
parenta2f86537a9fdaabe12b553a1cf066649a96b4891 (diff)
downloadingen-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.cpp11
-rw-r--r--src/server/events/Delete.hpp4
-rw-r--r--src/server/events/Delta.cpp54
-rw-r--r--src/server/events/Delta.hpp32
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;