fix compilation breakages from the last commit
[ardour.git] / libs / pbd / controllable.cc
1 /*
2     Copyright (C) 2000-2007 Paul Davis 
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 */
19
20 #include "pbd/controllable.h"
21 #include "pbd/xml++.h"
22 #include "pbd/error.h"
23
24 #include "i18n.h"
25
26 using namespace PBD;
27 using namespace std;
28
29 sigc::signal<void,Controllable*> Controllable::Destroyed;
30 sigc::signal<bool,Controllable*> Controllable::StartLearning;
31 sigc::signal<void,Controllable*> Controllable::StopLearning;
32 sigc::signal<void,Controllable*,int,int> Controllable::CreateBinding;
33 sigc::signal<void,Controllable*> Controllable::DeleteBinding;
34
35 Glib::StaticRWLock Controllable::registry_lock = GLIBMM_STATIC_RW_LOCK_INIT;
36 Controllable::Controllables Controllable::registry;
37 Controllable::ControllablesByURI Controllable::registry_by_uri;
38
39 Controllable::Controllable (const string& name, const string& uri)
40         : _name (name)
41         , _uri (uri)
42         , _touching (false)
43 {
44         add ();
45 }
46
47 void
48 Controllable::add ()
49 {
50         Glib::RWLock::WriterLock lm (registry_lock);
51         registry.insert (this);
52
53         if (!_uri.empty()) {
54                 pair<string,Controllable*> newpair;
55                 newpair.first = _uri;
56                 newpair.second = this;
57                 registry_by_uri.insert (newpair);
58         }
59
60         this->GoingAway.connect (mem_fun (this, &Controllable::remove));
61 }
62
63 void
64 Controllable::remove ()
65 {
66         Glib::RWLock::WriterLock lm (registry_lock);
67
68         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
69                 if ((*i) == this) {
70                         registry.erase (i);
71                         break;
72                 }
73         }
74
75         if (!_uri.empty()) {
76                 ControllablesByURI::iterator i = registry_by_uri.find (_uri);
77                 if (i != registry_by_uri.end()) {
78                         registry_by_uri.erase (i);
79                 }
80         }
81
82
83 }
84
85 void
86 Controllable::set_uri (const string& new_uri)
87 {
88         Glib::RWLock::WriterLock lm (registry_lock);
89
90         if (!_uri.empty()) {
91                 ControllablesByURI::iterator i = registry_by_uri.find (_uri);
92                 if (i != registry_by_uri.end()) {
93                         registry_by_uri.erase (i);
94                 }
95         }
96
97         _uri = new_uri;
98
99         if (!_uri.empty()) {
100                 pair<string,Controllable*> newpair;
101                 newpair.first = _uri;
102                 newpair.second = this;
103                 registry_by_uri.insert (newpair);
104         }
105 }
106
107 Controllable*
108 Controllable::by_id (const ID& id)
109 {
110         Glib::RWLock::ReaderLock lm (registry_lock);
111
112         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
113                 if ((*i)->id() == id) {
114                         return (*i);
115                 }
116         }
117         return 0;
118 }
119
120 Controllable*
121 Controllable::by_uri (const string& uri)
122 {
123         Glib::RWLock::ReaderLock lm (registry_lock);
124         ControllablesByURI::iterator i;
125
126         if ((i = registry_by_uri.find (uri)) != registry_by_uri.end()) {
127                 return i->second;
128         }
129         return 0;
130 }
131
132 Controllable*
133 Controllable::by_name (const string& str)
134 {
135         Glib::RWLock::ReaderLock lm (registry_lock);
136
137         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
138                 if ((*i)->_name == str) {
139                         return (*i);
140                 }
141         }
142         return 0;
143 }
144
145 XMLNode&
146 Controllable::get_state ()
147 {
148         XMLNode* node = new XMLNode (X_("Controllable"));
149         char buf[64];
150
151         node->add_property (X_("name"), _name); // not reloaded from XML state, just there to look at
152         _id.print (buf, sizeof (buf));
153         node->add_property (X_("id"), buf);
154
155         if (!_uri.empty()) {
156                 node->add_property (X_("uri"), _uri);
157         }
158                 
159         return *node;
160 }
161
162 int
163 Controllable::set_state (const XMLNode& node, int /*version*/)
164 {
165         const XMLProperty* prop;
166
167         if ((prop = node.property (X_("id"))) != 0) {
168                 _id = prop->value();
169                 return 0;
170         } else {
171                 error << _("Controllable state node has no ID property") << endmsg;
172                 return -1;
173         }
174
175         if ((prop = node.property (X_("uri"))) != 0) {
176                 set_uri (prop->value());
177         }
178 }