Merged changes from trunk 1699:1751 into 2.1-staging
[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
28 sigc::signal<void,Controllable*> Controllable::Destroyed;
29 sigc::signal<bool,Controllable*> Controllable::StartLearning;
30 sigc::signal<void,Controllable*> Controllable::StopLearning;
31
32 Glib::Mutex* Controllable::registry_lock = 0;
33 Controllable::Controllables Controllable::registry;
34
35 Controllable::Controllable (std::string name)
36         : _name (name)
37 {
38         if (registry_lock == 0) {
39                 registry_lock = new Glib::Mutex;
40         }
41
42         add ();
43 }
44
45 void
46 Controllable::add ()
47 {
48         Glib::Mutex::Lock lm (*registry_lock);
49         registry.insert (this);
50         this->GoingAway.connect (mem_fun (this, &Controllable::remove));
51 }
52
53 void
54 Controllable::remove ()
55 {
56         Glib::Mutex::Lock lm (*registry_lock);
57         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
58                 if ((*i) == this) {
59                         registry.erase (i);
60                         break;
61                 }
62         }
63 }
64
65 Controllable*
66 Controllable::by_id (const ID& id)
67 {
68         Glib::Mutex::Lock lm (*registry_lock);
69
70         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
71                 if ((*i)->id() == id) {
72                         return (*i);
73                 }
74         }
75         return 0;
76 }
77
78
79 Controllable*
80 Controllable::by_name (const std::string& str)
81 {
82         Glib::Mutex::Lock lm (*registry_lock);
83
84         for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
85                 if ((*i)->_name == str) {
86                         return (*i);
87                 }
88         }
89         return 0;
90 }
91
92 XMLNode&
93 Controllable::get_state ()
94 {
95         XMLNode* node = new XMLNode (X_("controllable"));
96         char buf[64];
97
98         node->add_property (X_("name"), _name); // not reloaded from XML state, just there to look at
99         _id.print (buf, sizeof (buf));
100         node->add_property (X_("id"), buf);
101         return *node;
102 }
103
104 int
105 Controllable::set_state (const XMLNode& node)
106 {
107         const XMLProperty* prop = node.property (X_("id"));
108
109         if (prop) {
110                 _id = prop->value();
111                 return 0;
112         } else {
113                 error << _("Controllable state node has no ID property") << endmsg;
114                 return -1;
115         }
116 }