fully implement and deploy explicit x-thread signal connection syntax (testing comes...
[ardour.git] / libs / surfaces / mackie / route_signal.cc
1 /*
2         Copyright (C) 2006,2007 John Anderson
3
4         This program is free software; you can redistribute it and/or modify
5         it under the terms of the GNU General Public License as published by
6         the Free Software Foundation; either version 2 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12         GNU General Public License for more details.
13
14         You should have received a copy of the GNU General Public License
15         along with this program; if not, write to the Free Software
16         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 #include "route_signal.h"
19
20 #include "ardour/route.h"
21 #include "ardour/track.h"
22 #include "ardour/midi_ui.h"
23 #include "ardour/panner.h"
24
25 #include "mackie_control_protocol.h"
26
27 #include <stdexcept>
28
29 using namespace ARDOUR;
30 using namespace Mackie;
31 using namespace std;
32
33 #define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
34 #define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
35
36 void RouteSignal::connect()
37 {
38         if (_strip.has_solo()) {
39                 _route->solo_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_solo_changed, &_mcp, this), midi_ui_context());
40         }
41
42         if (_strip.has_mute()) {
43                 _route->mute_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_mute_changed, &_mcp, this), midi_ui_context());
44         }
45
46         if (_strip.has_gain()) {
47                 _route->gain_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_gain_changed, &_mcp, this, false), midi_ui_context());
48         }
49
50         _route->NameChanged.connect (connections, ui_bind (&MackieControlProtocol::notify_name_changed, &_mcp, this), midi_ui_context());
51         
52         if (_route->panner()) {
53                 _route->panner()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
54                 
55                 for ( unsigned int i = 0; i < _route->panner()->npanners(); ++i ) {
56                         _route->panner()->streampanner(i).Changed.connect (connections, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
57                 }
58         }
59         
60         boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
61         if (trk) {
62                 trk->rec_enable_control()->Changed .connect(connections, ui_bind (&MackieControlProtocol::notify_record_enable_changed, &_mcp, this), midi_ui_context());
63         }
64         
65         // TODO this works when a currently-banked route is made inactive, but not
66         // when a route is activated which should be currently banked.
67         _route->active_changed.connect (connections, ui_bind (&MackieControlProtocol::notify_active_changed, &_mcp, this), midi_ui_context());
68         
69         // TODO
70         // SelectedChanged
71         // RemoteControlIDChanged. Better handled at Session level.
72 }
73
74 void RouteSignal::disconnect()
75 {
76         connections.drop_connections ();
77 }
78
79 void RouteSignal::notify_all()
80 {
81 #ifdef DEBUG
82         cout << "RouteSignal::notify_all for " << _strip << endl;
83 #endif
84         if ( _strip.has_solo() )
85                 _mcp.notify_solo_changed( this );
86         
87         if ( _strip.has_mute() )
88                 _mcp.notify_mute_changed( this );
89         
90         if ( _strip.has_gain() )
91                 _mcp.notify_gain_changed( this );
92         
93         _mcp.notify_name_changed( this );
94         
95         if ( _strip.has_vpot() )
96                 _mcp.notify_panner_changed( this );
97         
98         if ( _strip.has_recenable() )
99                 _mcp.notify_record_enable_changed( this );
100 #ifdef DEBUG
101         cout << "RouteSignal::notify_all finish" << endl;
102 #endif
103 }