From 96613df7830699dbbfb5c2d9fe3ebdb0598e6aca Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 29 Jan 2010 04:35:48 +0000 Subject: 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 --- src/engine/ControlBindings.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/engine/ControlBindings.cpp') 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::remove(const Raul::Path& path) +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + + SharedPtr old_bindings = _bindings; + + SharedPtr 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; + 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(buf[1]); const int8_t value = static_cast(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); } } -- cgit v1.2.1