summaryrefslogtreecommitdiff
path: root/libs/pbd
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-07-14 03:43:32 +0000
committerDavid Robillard <d@drobilla.net>2006-07-14 03:43:32 +0000
commit50a3102b9b533d7f8786d220f8df67421b9227c8 (patch)
tree669f84631ba1d9a1d312e3f76b226ca938c75c0f /libs/pbd
parentedd841895b873b14c4aa814a80de5dc20ff30618 (diff)
Merge big changes (mostly Controllable) from trunk
git-svn-id: svn://localhost/ardour2/branches/midi@682 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd')
-rw-r--r--libs/pbd/SConscript8
-rw-r--r--libs/pbd/controllable.cc26
-rw-r--r--libs/pbd/id.cc63
-rw-r--r--libs/pbd/pbd/controllable.h46
-rw-r--r--libs/pbd/pbd/id.h47
-rw-r--r--libs/pbd/pbd/stateful.h51
-rw-r--r--libs/pbd/stateful.cc137
7 files changed, 377 insertions, 1 deletions
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
index a9166d9505..36fb02885f 100644
--- a/libs/pbd/SConscript
+++ b/libs/pbd/SConscript
@@ -21,8 +21,10 @@ pbd_files = Split("""
basename.cc
base_ui.cc
convert.cc
+controllable.cc
dmalloc.cc
error.cc
+id.cc
mountpoint.cc
path.cc
pathscanner.cc
@@ -30,6 +32,7 @@ pool.cc
pthread_utils.cc
receiver.cc
stacktrace.cc
+stateful.cc
strsplit.cc
textreceiver.cc
transmitter.cc
@@ -46,7 +49,10 @@ if conf.CheckCHeader('execinfo.h'):
conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO")
pbd = conf.Finish()
-pbd.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], libraries['glib2'] ])
+pbd.Merge ([ libraries['sigc2'],
+ libraries['xml'],
+ libraries['glibmm2'],
+ libraries['glib2'] ])
pbd.VersionBuild(['version.cc','pbd/version.h'], 'SConscript')
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
new file mode 100644
index 0000000000..b1176c64a5
--- /dev/null
+++ b/libs/pbd/controllable.cc
@@ -0,0 +1,26 @@
+#include <pbd/controllable.h>
+#include <pbd/xml++.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+
+sigc::signal<void,Controllable*> Controllable::Created;
+sigc::signal<void,Controllable*> Controllable::GoingAway;
+sigc::signal<bool,Controllable*> Controllable::StartLearning;
+sigc::signal<void,Controllable*> Controllable::StopLearning;
+
+Controllable::Controllable ()
+{
+ Created (this);
+}
+
+XMLNode&
+Controllable::get_state ()
+{
+ XMLNode* node = new XMLNode (X_("Controllable"));
+ char buf[64];
+ _id.print (buf);
+ node->add_property (X_("id"), buf);
+ return *node;
+}
diff --git a/libs/pbd/id.cc b/libs/pbd/id.cc
new file mode 100644
index 0000000000..f9afa72c98
--- /dev/null
+++ b/libs/pbd/id.cc
@@ -0,0 +1,63 @@
+#include <ostream>
+#include <iostream>
+#include <stdio.h>
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+#include <pbd/id.h>
+
+using namespace std;
+using namespace PBD;
+
+Glib::Mutex* ID::counter_lock = 0;
+uint64_t ID::_counter = 0;
+
+void
+ID::init ()
+{
+ counter_lock = new Glib::Mutex;
+}
+
+ID::ID ()
+{
+ Glib::Mutex::Lock lm (*counter_lock);
+ id = _counter++;
+}
+
+ID::ID (string str)
+{
+ string_assign (str);
+}
+
+int
+ID::string_assign (string str)
+{
+ return sscanf (str.c_str(), "%" PRIu64, &id) != 0;
+}
+
+void
+ID::print (char* buf) const
+{
+ /* XXX sizeof buf is unknown. bad API design */
+ snprintf (buf, 16, "%" PRIu64, id);
+}
+
+ID&
+ID::operator= (string str)
+{
+ string_assign (str);
+ return *this;
+}
+
+ostream&
+operator<< (ostream& ostr, const ID& id)
+{
+ char buf[32];
+ id.print (buf);
+ ostr << buf;
+ return ostr;
+}
+
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
new file mode 100644
index 0000000000..c46e477b6e
--- /dev/null
+++ b/libs/pbd/pbd/controllable.h
@@ -0,0 +1,46 @@
+#ifndef __pbd_controllable_h__
+#define __pbd_controllable_h__
+
+#include <sigc++/trackable.h>
+#include <sigc++/signal.h>
+
+#include <pbd/stateful.h>
+#include <pbd/id.h>
+
+class XMLNode;
+
+namespace PBD {
+
+class Controllable : public virtual sigc::trackable, public Stateful {
+ public:
+ Controllable ();
+ virtual ~Controllable() { GoingAway (this); }
+
+ virtual void set_value (float) = 0;
+ virtual float get_value (void) const = 0;
+
+ virtual bool can_send_feedback() const { return true; }
+
+ sigc::signal<void> LearningFinished;
+
+ static sigc::signal<void,Controllable*> Created;
+ static sigc::signal<void,Controllable*> GoingAway;
+
+
+ static sigc::signal<bool,PBD::Controllable*> StartLearning;
+ static sigc::signal<void,PBD::Controllable*> StopLearning;
+
+ sigc::signal<void> Changed;
+
+ const PBD::ID& id() const { return _id; }
+
+ int set_state (const XMLNode&) { return 0; }
+ XMLNode& get_state ();
+
+ private:
+ PBD::ID _id;
+};
+
+}
+
+#endif /* __pbd_controllable_h__ */
diff --git a/libs/pbd/pbd/id.h b/libs/pbd/pbd/id.h
new file mode 100644
index 0000000000..9a3f10478d
--- /dev/null
+++ b/libs/pbd/pbd/id.h
@@ -0,0 +1,47 @@
+#ifndef __pbd_id_h__
+#define __pbd_id_h__
+
+#include <stdint.h>
+#include <string>
+
+#include <glibmm/thread.h>
+
+namespace PBD {
+
+class ID {
+ public:
+ ID ();
+ ID (std::string);
+
+ bool operator== (const ID& other) const {
+ return id == other.id;
+ }
+
+ bool operator!= (const ID& other) const {
+ return id != other.id;
+ }
+
+ ID& operator= (std::string);
+
+ bool operator< (const ID& other) const {
+ return id < other.id;
+ }
+
+ void print (char* buf) const;
+
+ static uint64_t counter() { return _counter; }
+ static void init_counter (uint64_t val) { _counter = val; }
+ static void init ();
+
+ private:
+ uint64_t id;
+ int string_assign (std::string);
+
+ static Glib::Mutex* counter_lock;
+ static uint64_t _counter;
+};
+
+}
+std::ostream& operator<< (std::ostream& ostr, const PBD::ID&);
+
+#endif /* __pbd_id_h__ */
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
new file mode 100644
index 0000000000..3038f16b4f
--- /dev/null
+++ b/libs/pbd/pbd/stateful.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: stateful.h 17 2005-09-24 19:13:41Z taybin $
+*/
+
+#ifndef __pbd_stateful_h__
+#define __pbd_stateful_h__
+
+#include <string>
+
+class XMLNode;
+
+class Stateful {
+ public:
+ Stateful();
+ virtual ~Stateful();
+
+ virtual XMLNode& get_state (void) = 0;
+
+ virtual int set_state (const XMLNode&) = 0;
+
+ /* Extra XML nodes */
+
+ void add_extra_xml (XMLNode&);
+ XMLNode *extra_xml (const std::string& str);
+
+ virtual void add_instant_xml (XMLNode&, const std::string& dir);
+ XMLNode *instant_xml (const std::string& str, const std::string& dir);
+
+ protected:
+ XMLNode *_extra_xml;
+ XMLNode *_instant_xml;
+};
+
+#endif /* __pbd_stateful_h__ */
+
diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc
new file mode 100644
index 0000000000..16aa528f59
--- /dev/null
+++ b/libs/pbd/stateful.cc
@@ -0,0 +1,137 @@
+/*
+ Copyright (C) 2000-2001 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: stateful.cc 629 2006-06-21 23:01:03Z paul $
+*/
+
+#include <unistd.h>
+
+#include <pbd/stateful.h>
+#include <pbd/xml++.h>
+#include <pbd/error.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+
+Stateful::Stateful ()
+{
+ _extra_xml = 0;
+ _instant_xml = 0;
+}
+
+Stateful::~Stateful ()
+{
+ // Do not delete _extra_xml. The use of add_child_nocopy()
+ // means it needs to live on indefinately.
+
+ if (_instant_xml) {
+ delete _instant_xml;
+ }
+}
+
+void
+Stateful::add_extra_xml (XMLNode& node)
+{
+ if (_extra_xml == 0) {
+ _extra_xml = new XMLNode ("extra");
+ }
+
+ _extra_xml->remove_nodes (node.name());
+ _extra_xml->add_child_nocopy (node);
+}
+
+XMLNode *
+Stateful::extra_xml (const string& str)
+{
+ if (_extra_xml == 0) {
+ return 0;
+ }
+
+ const XMLNodeList& nlist = _extra_xml->children();
+ XMLNodeConstIterator i;
+
+ for (i = nlist.begin(); i != nlist.end(); ++i) {
+ if ((*i)->name() == str) {
+ return (*i);
+ }
+ }
+
+ return 0;
+}
+
+void
+Stateful::add_instant_xml (XMLNode& node, const string& dir)
+{
+ if (_instant_xml == 0) {
+ _instant_xml = new XMLNode ("instant");
+ }
+
+ _instant_xml->remove_nodes_and_delete (node.name());
+ _instant_xml->add_child_copy (node);
+
+ XMLTree tree;
+ tree.set_filename(dir+"/instant.xml");
+
+ /* Important: the destructor for an XMLTree deletes
+ all of its nodes, starting at _root. We therefore
+ cannot simply hand it our persistent _instant_xml
+ node as its _root, because we will lose it whenever
+ the Tree goes out of scope.
+
+ So instead, copy the _instant_xml node (which does
+ a deep copy), and hand that to the tree.
+ */
+
+ XMLNode* copy = new XMLNode (*_instant_xml);
+ tree.set_root (copy);
+
+ if (!tree.write()) {
+ error << string_compose(_("Error: could not write %1"), dir+"/instant.xml") << endmsg;
+ }
+}
+
+XMLNode *
+Stateful::instant_xml (const string& str, const string& dir)
+{
+ if (_instant_xml == 0) {
+ string instant_file = dir + "/instant.xml";
+ if (access(instant_file.c_str(), F_OK) == 0) {
+ XMLTree tree;
+ if (tree.read(dir+"/instant.xml")) {
+ _instant_xml = new XMLNode(*(tree.root()));
+ } else {
+ warning << string_compose(_("Could not understand XML file %1"), instant_file) << endmsg;
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ const XMLNodeList& nlist = _instant_xml->children();
+ XMLNodeConstIterator i;
+
+ for (i = nlist.begin(); i != nlist.end(); ++i) {
+ if ((*i)->name() == str) {
+ return (*i);
+ }
+ }
+
+ return 0;
+}
+