a more reliable/robust/less complex version of previous commit

This commit is contained in:
Paul Davis 2016-07-21 14:00:18 -04:00
parent 3bf7c4ef49
commit d53d0faf93
2 changed files with 25 additions and 13 deletions

View file

@ -328,8 +328,11 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) { for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
ptmp = i; ptmp = i;
++ptmp; ++ptmp;
if (((*i)->first)->get_controllable() == c) { if (((*i)->mc)->get_controllable() == c) {
(*i)->second.disconnect(); if ((*i)->own_mc) {
delete (*i)->mc;
}
(*i)->connection.disconnect();
delete *i; delete *i;
pending_controllables.erase (i); pending_controllables.erase (i);
} }
@ -338,6 +341,7 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
} }
MIDIControllable* mc = 0; MIDIControllable* mc = 0;
bool own_mc = false;
for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) { if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
@ -348,15 +352,14 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
if (!mc) { if (!mc) {
mc = new MIDIControllable (this, *_input_port->parser(), *c, false); mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
controllables.push_back (mc); own_mc = true;
} }
{ {
Glib::Threads::Mutex::Lock lm (pending_lock); Glib::Threads::Mutex::Lock lm (pending_lock);
MIDIPendingControllable* element = new MIDIPendingControllable; MIDIPendingControllable* element = new MIDIPendingControllable (mc, own_mc);
element->first = mc; c->LearningFinished.connect_same_thread (element->connection, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
c->LearningFinished.connect_same_thread (element->second, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
pending_controllables.push_back (element); pending_controllables.push_back (element);
} }
@ -376,8 +379,8 @@ GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
tmp = i; tmp = i;
++tmp; ++tmp;
if ( (*i)->first == mc) { if ( (*i)->mc == mc) {
(*i)->second.disconnect(); (*i)->connection.disconnect();
delete *i; delete *i;
pending_controllables.erase(i); pending_controllables.erase(i);
} }
@ -400,10 +403,10 @@ GenericMidiControlProtocol::stop_learning (Controllable* c)
*/ */
for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) { for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
if (((*i)->first)->get_controllable() == c) { if (((*i)->mc)->get_controllable() == c) {
(*i)->first->stop_learning (); (*i)->mc->stop_learning ();
dptr = (*i)->first; dptr = (*i)->mc;
(*i)->second.disconnect(); (*i)->connection.disconnect();
delete *i; delete *i;
pending_controllables.erase (i); pending_controllables.erase (i);

View file

@ -125,7 +125,16 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
typedef std::list<MIDIAction*> MIDIActions; typedef std::list<MIDIAction*> MIDIActions;
MIDIActions actions; MIDIActions actions;
typedef std::pair<MIDIControllable*,PBD::ScopedConnection> MIDIPendingControllable; struct MIDIPendingControllable {
MIDIControllable* mc;
bool own_mc;
PBD::ScopedConnection connection;
MIDIPendingControllable (MIDIControllable* c, bool omc)
: mc (c)
, own_mc (omc)
{}
};
typedef std::list<MIDIPendingControllable* > MIDIPendingControllables; typedef std::list<MIDIPendingControllable* > MIDIPendingControllables;
MIDIPendingControllables pending_controllables; MIDIPendingControllables pending_controllables;
Glib::Threads::Mutex controllables_lock; Glib::Threads::Mutex controllables_lock;