diff options
author | David Robillard <d@drobilla.net> | 2006-07-14 03:43:32 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-07-14 03:43:32 +0000 |
commit | 50a3102b9b533d7f8786d220f8df67421b9227c8 (patch) | |
tree | 669f84631ba1d9a1d312e3f76b226ca938c75c0f /libs/pbd | |
parent | edd841895b873b14c4aa814a80de5dc20ff30618 (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/SConscript | 8 | ||||
-rw-r--r-- | libs/pbd/controllable.cc | 26 | ||||
-rw-r--r-- | libs/pbd/id.cc | 63 | ||||
-rw-r--r-- | libs/pbd/pbd/controllable.h | 46 | ||||
-rw-r--r-- | libs/pbd/pbd/id.h | 47 | ||||
-rw-r--r-- | libs/pbd/pbd/stateful.h | 51 | ||||
-rw-r--r-- | libs/pbd/stateful.cc | 137 |
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; +} + |