From 92469df6ab3417c6d953f0b51766d42d71a230af Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 25 Jun 2012 12:33:13 +0000 Subject: [PATCH] add late/lazy binding between generic MIDI bindings and controllable elements in the session. this allows you to load a binding map that refers to elements that have not yet been created in the session, and when they are created, the binding will work git-svn-id: svn://localhost/ardour2/branches/3.0@12921 d708f5d6-7413-0410-9779-e7cbd77b26cf --- .../generic_midi_control_protocol.cc | 15 +++++--- .../generic_midi_control_protocol.h | 3 ++ .../surfaces/generic_midi/midicontrollable.cc | 38 ++++++++++++++++--- libs/surfaces/generic_midi/midicontrollable.h | 2 + 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index fab6431c08..6b8e321112 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -773,22 +773,27 @@ GenericMidiControlProtocol::reset_controllables () /* its entirely possible that the session doesn't have * the specified controllable (e.g. it has too few - * tracks). if we find this to be the case, drop any - * bindings that would be left without controllables. + * tracks). if we find this to be the case, we just leave + * the binding around, unbound, and it will do "late + * binding" (or "lazy binding") if/when any data arrives. */ boost::shared_ptr c = session->controllable_by_descriptor (desc); if (c) { existingBinding->set_controllable (c.get()); - } else { - controllables.erase (iter); - } + } } iter = next; } } +boost::shared_ptr +GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const +{ + return session->controllable_by_descriptor (desc); +} + MIDIFunction* GenericMidiControlProtocol::create_function (const XMLNode& node) { diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index 7248c83ba1..ee1144a667 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -32,6 +32,7 @@ namespace MIDI { namespace PBD { class Controllable; + class ControllableDescriptor; } namespace ARDOUR { @@ -57,6 +58,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { int set_feedback (bool yn); bool get_feedback () const; + boost::shared_ptr lookup_controllable (const PBD::ControllableDescriptor&) const; + XMLNode& get_state (); int set_state (const XMLNode&, int version); diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index 50662abdb7..d39886e0fc 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -184,11 +184,31 @@ MIDIControllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb) midi_sense_note (p, tb, false); } +int +MIDIControllable::lookup_controllable() +{ + if (!_descriptor) { + return -1; + } + + boost::shared_ptr c = _surface->lookup_controllable (*_descriptor); + + if (!c) { + return -1; + } + + controllable = c.get(); + + return 0; +} + void MIDIControllable::midi_sense_note (Parser &, EventTwoBytes *msg, bool /*is_on*/) { if (!controllable) { - return; + if (lookup_controllable()) { + return; + } } if (!controllable->is_toggle()) { @@ -206,7 +226,9 @@ void MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) { if (!controllable) { - return; + if (lookup_controllable ()) { + return; + } } if (controllable->touching()) { @@ -254,7 +276,9 @@ void MIDIControllable::midi_sense_program_change (Parser &, byte msg) { if (!controllable) { - return; + if (lookup_controllable ()) { + return; + } } if (!controllable->is_toggle()) { @@ -270,7 +294,9 @@ void MIDIControllable::midi_sense_pitchbend (Parser &, pitchbend_t pb) { if (!controllable) { - return; + if (lookup_controllable ()) { + return; + } } if (!controllable->is_toggle()) { @@ -299,7 +325,9 @@ MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/) bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]); - controllable->LearningFinished (); + if (controllable) { + controllable->LearningFinished (); + } } void diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h index bf377b6651..571f71edfe 100644 --- a/libs/surfaces/generic_midi/midicontrollable.h +++ b/libs/surfaces/generic_midi/midicontrollable.h @@ -116,6 +116,8 @@ class MIDIControllable : public PBD::Stateful uint32_t _rid; std::string _what; bool _bank_relative; + + int lookup_controllable(); void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t); void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on);