ControlProtocols are single instance.
Activating an already active protocol leads to crashes due to
various rasons (e.g. port already registered), re-used singleton
event_loop_name and request-buffers, duplicate free of
AbstractUI request buffers during deactivate,..
The GUI should be notified about the tearing down of the control
surfaces *before* the protocols are actually destroyed.
On ProtocolStatusChange ControlSurfacesOptions::selection_changed() might try
to access protocol->has_editor() of a protocol that happens to be selected in
the preferences GUI. I this protocol already has been destroyed, a crash will
occur.
This allows to special-cases session-specific control-surface state.
e.g. midi-learn.
Only restore midi-learned, session-specific, bindings when loading a
session with generic-midi enabled.
Also dis/re-enable generic-midi resets midi-learned, but no other
session-independent settings.
This also handles the edge case:
1) load global config, generic-midi = ON, w/ bindings.
state is remembered as cpi->state
2) load session-condig, generic-midi = OFF, cpi->state is retained
3) user enables the surface, cpi->state from (1) is applied.
-> invalid bindings applied -> fail
Keep latest surface configuration, regardless if surface is active
or being deactivated. Current state after de-activation is retained.
Currently state loaded from a session overrides global state from
global preferences, if the surface is marked active in the session.
This is to allow midi-learn.
generic-midi and session-specific midi-learn will require additional
work.
- Control-protocols may transmit data during cleanup
(e.g. reset surface), and need the Audio-engine to do so.
- destroying the ControlProtocolManager w/o the Session calling
::drop_protocols(), lead to a double free.
The Editor continues to notify them, but via a direct call to ControlProtocolManager, not a signal.
The CP Manager calls the ControlProtocol static method to set up static data structures holding
selection info for all surfaces and then notifies each surface/protocol that selection has changed.
ControlProtocolManager::set_state() already takes the protocols_lock.
However effectively this is a NO-OP. During ::set_state no CPI should
be instantiated and ControlProtocolManager::teardown() returns early.
Currently this code isn't reached because we never call ControlProtocolManager::teardown() on inactive protocols. But at some point it might be appropriate to unload modules (.so/.dll/.dylib) even if the protocol was never instantiated
This new design will work even when threads that need to receive
messages from RT threads are created *after* the RT threads. The
existing design would fail because the RT thread(s) would never
be known the later created threads, and so signals emitted by the
RT thread and causing call_slot() in the receiver would end up
being enqueued using a lock-protected list. The new design ensures
that communication always uses a lock-free FIFO instead
Windows headers define SearchPath which means we have to undefine it
where necessary. This is a pain and can be tricksy, so I feel renaming
the class slightly is the easiest solution.
It's slightly possible that this causes trivial build failures on different
configurations, but otherwise shouldn't cause any problems (i.e. no actual
changes other than include/naming/namespace stuff). I deliberately avoided
removing libardour-config.h since this can mysteriously break things, though a
few of those do seem to be unnecessary.
This commit only targets includes of ardour/*.h. There is also a very large
number of unnecessary includes of stuff in gtk2_ardour; tackling that should
also give a big improvement in build time when things are modified.
git-svn-id: svn://localhost/ardour2/branches/3.0@12420 d708f5d6-7413-0410-9779-e7cbd77b26cf