diff options
Diffstat (limited to 'libs/surfaces/generic_midi/generic_midi_control_protocol.cc')
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.cc | 84 |
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; } } |