summaryrefslogtreecommitdiffstats
path: root/src/engine/ControlBindings.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-01-29 04:35:48 +0000
committerDavid Robillard <d@drobilla.net>2010-01-29 04:35:48 +0000
commit96613df7830699dbbfb5c2d9fe3ebdb0598e6aca (patch)
treebb7278466fc9ae92be6b53fb2f6399754d15f842 /src/engine/ControlBindings.cpp
parent1b964e850bbe3207fe9a65849520634955d141f0 (diff)
downloadingen-96613df7830699dbbfb5c2d9fe3ebdb0598e6aca.tar.gz
ingen-96613df7830699dbbfb5c2d9fe3ebdb0598e6aca.tar.bz2
ingen-96613df7830699dbbfb5c2d9fe3ebdb0598e6aca.zip
Remove references to deleted ports with control bindings (fix crash when applying binding to deleted port).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2393 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/ControlBindings.cpp')
-rw-r--r--src/engine/ControlBindings.cpp34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/engine/ControlBindings.cpp b/src/engine/ControlBindings.cpp
index b74a3124..2c2a1888 100644
--- a/src/engine/ControlBindings.cpp
+++ b/src/engine/ControlBindings.cpp
@@ -60,7 +60,7 @@ ControlBindings::set_port_value(ProcessContext& context, PortImpl* port, int8_t
void
ControlBindings::bind(ProcessContext& context, int8_t cc_num)
{
- _bindings.insert(make_pair(cc_num, _learn_port));
+ _bindings->insert(make_pair(cc_num, _learn_port));
const Events::SendBinding ev(context.engine(), context.start(), _learn_port,
MessageType(MessageType::MIDI_CC, cc_num));
@@ -70,6 +70,30 @@ ControlBindings::bind(ProcessContext& context, int8_t cc_num)
}
+SharedPtr<ControlBindings::Bindings>
+ControlBindings::remove(const Raul::Path& path)
+{
+ ThreadManager::assert_thread(THREAD_PRE_PROCESS);
+
+ SharedPtr<Bindings> old_bindings = _bindings;
+
+ SharedPtr<Bindings> copy(new Bindings(*_bindings.get()));
+
+ for (Bindings::iterator i = copy->begin(); i != copy->end();) {
+ Bindings::iterator next = i;
+ ++next;
+
+ if (i->second->path() == path || i->second->path().is_child_of(path))
+ copy->erase(i);
+
+ i = next;
+ }
+
+ _bindings = copy;
+ return old_bindings;
+}
+
+
void
ControlBindings::process(ProcessContext& context, EventBuffer* buffer)
{
@@ -79,6 +103,8 @@ ControlBindings::process(ProcessContext& context, EventBuffer* buffer)
uint16_t size = 0;
uint8_t* buf = NULL;
+ SharedPtr<Bindings> bindings = _bindings;
+
if (_learn_port) {
buffer->rewind();
while (buffer->get_event(&frames, &subframes, &type, &size, &buf)) {
@@ -91,14 +117,14 @@ ControlBindings::process(ProcessContext& context, EventBuffer* buffer)
}
}
- if (!_bindings.empty()) {
+ if (!bindings->empty()) {
buffer->rewind();
while (buffer->get_event(&frames, &subframes, &type, &size, &buf)) {
if (type == _map->midi_event && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) {
const int8_t controller = static_cast<const int8_t>(buf[1]);
const int8_t value = static_cast<const int8_t>(buf[2]);
- Bindings::const_iterator i = _bindings.find(controller);
- if (i != _bindings.end()) {
+ Bindings::const_iterator i = bindings->find(controller);
+ if (i != bindings->end()) {
set_port_value(context, i->second, value);
}
}