summaryrefslogtreecommitdiff
path: root/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/surfaces/generic_midi/generic_midi_control_protocol.cc')
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc84
1 files changed, 67 insertions, 17 deletions
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 83c5d9008d..4bbf3745c6 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -15,7 +15,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
#include <algorithm>
@@ -126,15 +125,51 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
return false;
}
- MIDIControllable* mc = new MIDIControllable (*_port, *c);
+ MIDIControllables::iterator tmp;
+ for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
+ tmp = i;
+ ++tmp;
+ if (&(*i)->get_controllable() == c) {
+ delete (*i);
+ controllables.erase (i);
+ }
+ i = tmp;
+ }
+
+ MIDIPendingControllables::iterator ptmp;
+ for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
+ ptmp = i;
+ ++ptmp;
+ if (&((*i).first)->get_controllable() == c) {
+ (*i).second.disconnect();
+ delete (*i).first;
+ pending_controllables.erase (i);
+ }
+ i = ptmp;
+ }
+
+
+ MIDIControllable* mc = 0;
+
+ for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
+ if ((*i)->get_controllable().id() == c->id()) {
+ mc = *i;
+ break;
+ }
+ }
+
+ if (!mc) {
+ mc = new MIDIControllable (*_port, *c);
+ }
{
Glib::Mutex::Lock lm (pending_lock);
- std::pair<MIDIControllables::iterator,bool> result;
- result = pending_controllables.insert (mc);
- if (result.second) {
- c->LearningFinished.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc));
- }
+
+ std::pair<MIDIControllable *, sigc::connection> element;
+ element.first = mc;
+ element.second = c->LearningFinished.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc));
+
+ pending_controllables.push_back (element);
}
mc->learn_about_external_control ();
@@ -147,10 +182,18 @@ GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
Glib::Mutex::Lock lm (pending_lock);
Glib::Mutex::Lock lm2 (controllables_lock);
- MIDIControllables::iterator i = find (pending_controllables.begin(), pending_controllables.end(), mc);
+ MIDIPendingControllables::iterator tmp;
+
+ for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
+ tmp = i;
+ ++tmp;
+
+ if ( (*i).first == mc) {
+ (*i).second.disconnect();
+ pending_controllables.erase(i);
+ }
- if (i != pending_controllables.end()) {
- pending_controllables.erase (i);
+ i = tmp;
}
controllables.insert (mc);
@@ -160,19 +203,27 @@ void
GenericMidiControlProtocol::stop_learning (Controllable* c)
{
Glib::Mutex::Lock lm (pending_lock);
+ Glib::Mutex::Lock lm2 (controllables_lock);
+ MIDIControllable* dptr = 0;
/* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
relevant MIDIControllable and remove it from the pending list.
*/
- for (MIDIControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
- if (&(*i)->get_controllable() == c) {
- (*i)->stop_learning ();
- delete (*i);
+ for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
+ if (&((*i).first)->get_controllable() == c) {
+ (*i).first->stop_learning ();
+ dptr = (*i).first;
+ (*i).second.disconnect();
+
pending_controllables.erase (i);
break;
}
}
+
+ if (dptr) {
+ delete dptr;
+ }
}
XMLNode&
@@ -244,7 +295,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
ID id = prop->value ();
- c = session->controllable_by_id (id);
+ c = Controllable::by_id (id);
if (c) {
MIDIControllable* mc = new MIDIControllable (*_port, *c);
@@ -253,8 +304,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
}
} else {
- warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"),
- id)
+ warning << string_compose (_("Generic MIDI control: controllable %1 not found (ignored)"), id)
<< endmsg;
}
}