diff options
86 files changed, 1109 insertions, 949 deletions
diff --git a/src/common/interface/ClientInterface.h b/src/common/interface/ClientInterface.h index 071b854e..3adc76f4 100644 --- a/src/common/interface/ClientInterface.h +++ b/src/common/interface/ClientInterface.h @@ -36,14 +36,14 @@ public: virtual ~ClientInterface() {} virtual void response(int32_t id, bool success, string msg) = 0; - + /** Bundles are a group of messages that are guaranteed to be in an * atomic unit with guaranteed order (eg a packet). For datagram * protocols (like UDP) there is likely an upper limit on bundle size. */ virtual void bundle_begin() = 0; virtual void bundle_end() = 0; - + /** Transfers are 'weak' bundles. These are used to break a large group * of similar/related messages into larger chunks (solely for communication * efficiency). A bunch of messages in a transfer will arrive as 1 or more @@ -51,11 +51,11 @@ public: */ virtual void transfer_begin() = 0; virtual void transfer_end() = 0; - + virtual void error(string msg) = 0; virtual void num_plugins(uint32_t num_plugins) = 0; - + virtual void new_plugin(string type, string uri, string name) = 0; @@ -101,7 +101,7 @@ public: uint32_t program, string program_name) = 0; - virtual void program_remove(string node_path, + virtual void program_remove(string node_path, uint32_t bank, uint32_t program) = 0; diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h index 04d143b1..46f6fa99 100644 --- a/src/common/interface/EngineInterface.h +++ b/src/common/interface/EngineInterface.h @@ -42,23 +42,23 @@ public: // Responses virtual void set_next_response_id(int32_t id) = 0; virtual void disable_responses() = 0; - + // Client registration virtual void register_client(ClientKey key, CountedPtr<ClientInterface> client) = 0; virtual void unregister_client(ClientKey key) = 0; - + // Engine commands virtual void load_plugins() = 0; virtual void activate() = 0; virtual void deactivate() = 0; virtual void quit() = 0; - + // Object commands virtual void create_patch(const string& path, uint32_t poly) = 0; - + virtual void create_port(const string& path, const string& data_type, bool direction) = 0; @@ -66,50 +66,50 @@ public: virtual void create_node(const string& path, const string& plugin_type, const string& plugin_uri, - bool polyphonic) = 0; + bool polyphonic) = 0; /** DEPRECATED */ virtual void create_node(const string& path, const string& plugin_type, const string& library_name, const string& plugin_label, - bool polyphonic) = 0; - + bool polyphonic) = 0; + virtual void rename(const string& old_path, const string& new_name) = 0; - + virtual void destroy(const string& path) = 0; - + virtual void clear_patch(const string& patch_path) = 0; - + virtual void enable_patch(const string& patch_path) = 0; - + virtual void disable_patch(const string& patch_path) = 0; - + virtual void connect(const string& src_port_path, const string& dst_port_path) = 0; - + virtual void disconnect(const string& src_port_path, const string& dst_port_path) = 0; - + virtual void disconnect_all(const string& node_path) = 0; - + virtual void set_port_value(const string& port_path, float val) = 0; - + virtual void set_port_value(const string& port_path, uint32_t voice, float val) = 0; - + virtual void set_port_value_queued(const string& port_path, float val) = 0; - + virtual void set_program(const string& node_path, uint32_t bank, uint32_t program) = 0; - + virtual void midi_learn(const string& node_path) = 0; - + virtual void set_metadata(const string& path, const string& predicate, const string& value) = 0; @@ -117,13 +117,13 @@ public: // Requests // virtual void ping() = 0; - + virtual void request_port_value(const string& port_path) = 0; - + virtual void request_plugins() = 0; - + virtual void request_all_objects() = 0; - + protected: EngineInterface() {} }; diff --git a/src/common/util/CountedPtr.h b/src/common/util/CountedPtr.h index c5eb2e50..e3f34ec2 100644 --- a/src/common/util/CountedPtr.h +++ b/src/common/util/CountedPtr.h @@ -21,6 +21,21 @@ #include <cassert> #include <cstddef> +// honestly, WTF? +#include <boost/shared_ptr.hpp> + +#define CountedPtr boost::shared_ptr +#define PtrCast boost::dynamic_pointer_cast +#if 0 +// FIXME +#ifndef NDEBUG +#define COUNTED_PTR_DEBUG +#include <iostream> +#include <list> +#include <algorithm> +static std::list<void*> counted_ptr_counters; +#endif + /** Simple reference counted pointer. * @@ -46,7 +61,7 @@ public: /** Allocate a new Counter (if p is non-NULL) */ CountedPtr(T* p) - : _counter(NULL) + : _counter(0) { if (p) _counter = new Counter(p); @@ -57,7 +72,7 @@ public: * in STL containers :/ */ CountedPtr() - : _counter(NULL) + : _counter(0) {} ~CountedPtr() @@ -67,7 +82,7 @@ public: /** Copy a CountedPtr with the same type. */ CountedPtr(const CountedPtr& copy) - : _counter(NULL) + : _counter(0) { assert(this != ©); @@ -81,7 +96,7 @@ public: */ template <class Y> CountedPtr(const CountedPtr<Y>& y) - : _counter(NULL) + : _counter(0) { assert(this != (CountedPtr*)&y); @@ -96,14 +111,14 @@ public: } } - assert(_counter == NULL || _counter == (Counter*)y._counter); + assert( ! _counter || _counter == (Counter*)y._counter); } /** Assign to the value of a CountedPtr of the same type. */ CountedPtr& operator=(const CountedPtr& copy) { if (this != ©) { - assert(_counter == NULL || _counter != copy._counter); + assert( ! _counter || _counter != copy._counter); release(); retain(copy._counter); } @@ -163,23 +178,42 @@ public: private: /** Stored on the heap and referred to by all existing CountedPtr's to * the object */ - struct Counter + class Counter { + public: Counter(T* p) : ptr(p) , count(1) { assert(p); +#ifdef COUNTED_PTR_DEBUG + assert(std::find(counted_ptr_counters.begin(), counted_ptr_counters.end(), (void*)p) + == counted_ptr_counters.end()); + counted_ptr_counters.push_back(p); + std::cerr << "Creating " << typeid(T).name() << " Counter " << this << std::endl; +#endif } + ~Counter() + { + // for debugging + assert(count == 0); + count = 0; + } + T* const ptr; volatile size_t count; + + private: + // Prevent copies (undefined) + Counter(const Counter& copy); + Counter& operator=(const Counter& copy); }; /** Increment the count */ void retain(Counter* c) { - assert(_counter == NULL || _counter == c); + assert( ! _counter || _counter == c); _counter = c; if (_counter) ++(c->count); @@ -193,12 +227,13 @@ private: delete _counter->ptr; delete _counter; } - _counter = NULL; + _counter = 0; } } Counter* _counter; }; +#endif #endif // COUNTED_PTR_H diff --git a/src/common/util/Path.h b/src/common/util/Path.h index c84607fb..6c6d54be 100644 --- a/src/common/util/Path.h +++ b/src/common/util/Path.h @@ -199,17 +199,28 @@ public: /** Parent path with a "/" appended. * - * Because of the "/" special case, append a child name to base_path() - * to construct a path. This return value followed by a valid name is - * guaranteed to be a valid path. + * This exists to avoid needing to be careful about the special case of "/". + * To create a child of a path, use parent.base() + child_name. + * Returned value is always a valid path, with the single exception that + * the last character is "/". */ - inline string base_path() const + inline string base() const { if ((*this) == "/") return *this; else return (*this) + "/"; } + + inline bool is_child_of(const Path& parent) const + { + return (length() > parent.length() && substr(0, parent.length()) == parent); + } + + inline bool is_parent_of(const Path& child) const + { + return child.is_child_of(*this); + } }; diff --git a/src/libs/client/ConnectionModel.cpp b/src/libs/client/ConnectionModel.cpp index 778678f7..421b620d 100644 --- a/src/libs/client/ConnectionModel.cpp +++ b/src/libs/client/ConnectionModel.cpp @@ -24,9 +24,7 @@ namespace Client { ConnectionModel::ConnectionModel(const Path& src_port, const Path& dst_port) : _src_port_path(src_port), - _dst_port_path(dst_port), - _src_port(NULL), - _dst_port(NULL) + _dst_port_path(dst_port) { // Be sure connection is within one patch //assert(_src_port_path.parent().parent() @@ -73,7 +71,7 @@ ConnectionModel::patch_path() const // Direct connection from patch input to patch output (pass through) // (parent patch is parent of ports) if (_src_port->parent() == _dst_port->parent()) { - CountedPtr<PatchModel> parent_patch = _src_port->parent(); + CountedPtr<PatchModel> parent_patch = PtrCast<PatchModel>(_src_port->parent()); if (parent_patch) return parent_patch->path(); } diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index f29529e5..23723f11 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = -I$(top_srcdir)/src/common -fno-exceptions +AM_CXXFLAGS = -I$(top_srcdir)/src/common if BUILD_CLIENT_LIB noinst_LTLIBRARIES = libomclient.la diff --git a/src/libs/client/ModelClientInterface.cpp b/src/libs/client/ModelClientInterface.cpp index 440f2a73..deb37187 100644 --- a/src/libs/client/ModelClientInterface.cpp +++ b/src/libs/client/ModelClientInterface.cpp @@ -26,31 +26,31 @@ namespace Client { void -ModelClientInterface::new_plugin_model(PluginModel* pi) +ModelClientInterface::new_plugin_model(CountedPtr<PluginModel> pi) { } void -ModelClientInterface::new_patch_model(PatchModel* pm) +ModelClientInterface::new_patch_model(CountedPtr<PatchModel> pm) { } void -ModelClientInterface::new_node_model(NodeModel* nm) +ModelClientInterface::new_node_model(CountedPtr<NodeModel> nm) { } void -ModelClientInterface::new_port_model(PortModel* port_info) +ModelClientInterface::new_port_model(CountedPtr<PortModel> port_info) { } void -ModelClientInterface::connection_model(ConnectionModel* cm) +ModelClientInterface::connection_model(CountedPtr<ConnectionModel> cm) { } @@ -67,7 +67,7 @@ ModelClientInterface::new_plugin(string type, string uri, string name) { - PluginModel* plugin = new PluginModel(type, uri); + CountedPtr<PluginModel> plugin(new PluginModel(type, uri)); plugin->name(name); new_plugin_model(plugin); } @@ -77,7 +77,7 @@ ModelClientInterface::new_plugin(string type, void ModelClientInterface::new_patch(string path, uint32_t poly) { - PatchModel* pm = new PatchModel(path, poly); + CountedPtr<PatchModel> pm(new PatchModel(path, poly)); //PluginModel* pi = new PluginModel(PluginModel::Patch); //pm->plugin(pi); new_patch_model(pm); @@ -94,9 +94,9 @@ ModelClientInterface::new_node(string plugin_type, { cerr << "FIXME: NEW NODE\n"; - PluginModel* plugin = new PluginModel(plugin_type, plugin_uri); + CountedPtr<PluginModel> plugin(new PluginModel(plugin_type, plugin_uri)); - NodeModel* nm = new NodeModel(plugin, node_path); + CountedPtr<NodeModel> nm(new NodeModel(plugin, node_path)); new_node_model(nm); } @@ -116,7 +116,7 @@ ModelClientInterface::new_port(string path, PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - PortModel* port_model = new PortModel(path, ptype, pdir); + CountedPtr<PortModel> port_model(new PortModel(path, ptype, pdir)); new_port_model(port_model); } @@ -126,7 +126,7 @@ void ModelClientInterface::connection(string src_port_path, string dst_port_path) { - connection_model(new ConnectionModel(src_port_path, dst_port_path)); + connection_model(CountedPtr<ConnectionModel>(new ConnectionModel(src_port_path, dst_port_path))); } diff --git a/src/libs/client/ModelClientInterface.h b/src/libs/client/ModelClientInterface.h index 84472137..9b467fa6 100644 --- a/src/libs/client/ModelClientInterface.h +++ b/src/libs/client/ModelClientInterface.h @@ -21,6 +21,7 @@ #include <memory> using std::string; using std::auto_ptr; #include "interface/ClientInterface.h" +#include "util/CountedPtr.h" namespace Ingen { namespace Client { @@ -49,13 +50,11 @@ public: virtual ~ModelClientInterface() {} - // FIXME: make these auto_ptr's - - virtual void new_plugin_model(PluginModel* pi); - virtual void new_patch_model(PatchModel* pm); - virtual void new_node_model(NodeModel* nm); - virtual void new_port_model(PortModel* port_info); - virtual void connection_model(ConnectionModel* cm); + virtual void new_plugin_model(CountedPtr<PluginModel> pi); + virtual void new_patch_model(CountedPtr<PatchModel> pm); + virtual void new_node_model(CountedPtr<NodeModel> nm); + virtual void new_port_model(CountedPtr<PortModel> port_info); + virtual void connection_model(CountedPtr<ConnectionModel> cm); // ClientInterface functions to drive the above: diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp index f544e812..05b7b43e 100644 --- a/src/libs/client/NodeModel.cpp +++ b/src/libs/client/NodeModel.cpp @@ -25,16 +25,17 @@ namespace Client { NodeModel::NodeModel(CountedPtr<PluginModel> plugin, const Path& path) : ObjectModel(path), m_polyphonic(false), + m_plugin_uri(plugin->uri()), m_plugin(plugin), m_x(0.0f), m_y(0.0f) { } -NodeModel::NodeModel(const Path& path) +NodeModel::NodeModel(const string& plugin_uri, const Path& path) : ObjectModel(path), m_polyphonic(false), - m_plugin(NULL), + m_plugin_uri(plugin_uri), m_x(0.0f), m_y(0.0f) { @@ -80,7 +81,7 @@ NodeModel::set_path(const Path& p) ObjectModel::set_path(p); for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) - (*i)->set_path(m_path + "/" + (*i)->name()); + (*i)->set_path(m_path + "/" + (*i)->path().name()); //if (m_parent && old_path.length() > 0) // parent_patch()->rename_node(old_path, p); @@ -88,18 +89,39 @@ NodeModel::set_path(const Path& p) void +NodeModel::add_child(CountedPtr<ObjectModel> c) +{ + assert(c->parent().get() == this); + + CountedPtr<PortModel> pm = PtrCast<PortModel>(c); + assert(pm); + add_port(pm); +} + + +void NodeModel::add_port(CountedPtr<PortModel> pm) { assert(pm); - assert(pm->name() != ""); - assert(pm->path().length() > m_path.length()); - assert(pm->path().substr(0, m_path.length()) == m_path); + assert(pm->path().is_child_of(m_path)); assert(pm->parent().get() == this); - assert(!get_port(pm->name())); - m_ports.push_back(pm); + PortModelList::iterator existing = m_ports.end(); + for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) { + if ((*i)->path() == pm->path()) { + existing = i; + break; + } + } - new_port_sig.emit(pm); + if (existing != m_ports.end()) { + cerr << "Warning: port clash, assimilating old port " << m_path << endl; + pm->assimilate(*existing); + *existing = pm; + } else { + m_ports.push_back(pm); + new_port_sig.emit(pm); + } } @@ -108,9 +130,9 @@ NodeModel::get_port(const string& port_name) { assert(port_name.find("/") == string::npos); for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) - if ((*i)->name() == port_name) + if ((*i)->path().name() == port_name) return (*i); - return NULL; + return CountedPtr<PortModel>(); } diff --git a/src/libs/client/NodeModel.h b/src/libs/client/NodeModel.h index 2a8b6973..f0bede51 100644 --- a/src/libs/client/NodeModel.h +++ b/src/libs/client/NodeModel.h @@ -44,9 +44,12 @@ class PluginModel; class NodeModel : public ObjectModel { public: + NodeModel(const string& plugin_uri, const Path& path); NodeModel(CountedPtr<PluginModel> plugin, const Path& path); virtual ~NodeModel(); + void add_child(CountedPtr<ObjectModel> c); + CountedPtr<PortModel> get_port(const string& port_name); void add_port(CountedPtr<PortModel> pm); void remove_port(const string& port_path); @@ -57,6 +60,8 @@ public: void add_program(int bank, int program, const string& name); void remove_program(int bank, int program); + string plugin_uri() { return m_plugin_uri; } + CountedPtr<PluginModel> plugin() const { return m_plugin; } //void plugin(CountedPtr<PluginModel> p) { m_plugin = p; } @@ -79,6 +84,7 @@ protected: bool m_polyphonic; PortModelList m_ports; ///< List of ports (instead of map to preserve order) + string m_plugin_uri; ///< Plugin URI (not redundant if PluginModel unknown CountedPtr<PluginModel> m_plugin; ///< The plugin this node is an instance of float m_x; ///< Just metadata, here as an optimization for GUI float m_y; ///< Just metadata, here as an optimization for GUI @@ -91,7 +97,7 @@ private: }; -typedef map<string, CountedPtr<NodeModel> > NodeModelMap; +typedef map<string, CountedPtr<NodeModel> > NodeModelMap; } // namespace Client diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp index 6309a774..b8688585 100644 --- a/src/libs/client/ObjectModel.cpp +++ b/src/libs/client/ObjectModel.cpp @@ -20,10 +20,8 @@ namespace Ingen { namespace Client { -ObjectModel::ObjectModel(const string& path) -: m_path(path), - m_parent(NULL), - m_controller(NULL) +ObjectModel::ObjectModel(const Path& path) +: m_path(path) { } @@ -37,30 +35,38 @@ ObjectModel::get_metadata(const string& key) const { map<string,string>::const_iterator i = m_metadata.find(key); if (i != m_metadata.end()) - return (*i).second; + return i->second; else return ""; } -/** The base path for children of this Object. - * - * (This is here to avoid needing special cases for the root patch everywhere). - */ -string -ObjectModel::base_path() const +void +ObjectModel::set_controller(CountedPtr<ObjectController> c) { - return (path() == "/") ? "/" : path() + "/"; + m_controller = c; } +/** Merge the data of @a model with self, as much as possible. + * + * This will merge the two models, but with any conflict take the version in + * this as correct. The paths of the two models must be equal. + */ void -ObjectModel::set_controller(ObjectController* c) +ObjectModel::assimilate(CountedPtr<ObjectModel> model) { - assert(m_controller == NULL); - m_controller = c; + assert(m_path == model->path()); + + for (map<string,string>::const_iterator i = model->metadata().begin(); + i != model->metadata().end(); ++i) { + map<string,string>::const_iterator i = m_metadata.find(i->first); + if (i == m_metadata.end()) + m_metadata[i->first] = i->second; + } } + } // namespace Client } // namespace Ingen diff --git a/src/libs/client/ObjectModel.h b/src/libs/client/ObjectModel.h index 9daccfd2..9ee4f8c4 100644 --- a/src/libs/client/ObjectModel.h +++ b/src/libs/client/ObjectModel.h @@ -26,6 +26,7 @@ #include <sigc++/sigc++.h> #include "util/Path.h" #include "util/CountedPtr.h" +#include "ObjectController.h" using std::string; using std::map; using std::find; using std::cout; using std::cerr; using std::endl; @@ -42,8 +43,8 @@ class ObjectController; class ObjectModel { public: - ObjectModel(const string& path); - ObjectModel() : m_path("/UNINITIALIZED"), m_parent(NULL) {} // FIXME: remove + ObjectModel(const Path& path); + ObjectModel() : m_path("/UNINITIALIZED") {} // FIXME: remove virtual ~ObjectModel() {} @@ -55,23 +56,24 @@ public: inline const Path& path() const { return m_path; } virtual void set_path(const Path& p) { m_path = p; } - CountedPtr<ObjectModel> parent() const { return m_parent; } + CountedPtr<ObjectModel> parent() const { return m_parent; } virtual void set_parent(CountedPtr<ObjectModel> p) { m_parent = p; } - ObjectController* controller() const { return m_controller; } - - void set_controller(ObjectController* c); + virtual void add_child(CountedPtr<ObjectModel> c) = 0; - // Convenience functions - string base_path() const; - const string name() const { return m_path.name(); } + CountedPtr<ObjectController> controller() const { return m_controller; } + void set_controller(CountedPtr<ObjectController> c); + + void assimilate(CountedPtr<ObjectModel> model); + // Signals sigc::signal<void, const string&, const string&> metadata_update_sig; + sigc::signal<void> destroyed_sig; protected: - Path m_path; - CountedPtr<ObjectModel> m_parent; - ObjectController* m_controller; // FIXME: remove + Path m_path; + CountedPtr<ObjectModel> m_parent; + CountedPtr<ObjectController> m_controller; map<string,string> m_metadata; diff --git a/src/libs/client/PatchLibrarian.cpp b/src/libs/client/PatchLibrarian.cpp index 86f3d407..07a98526 100644 --- a/src/libs/client/PatchLibrarian.cpp +++ b/src/libs/client/PatchLibrarian.cpp @@ -35,7 +35,6 @@ #include <cassert> #include <cstring> #include <string> -#include <unistd.h> // for usleep #include <cstdlib> // for atof #include <cmath> @@ -120,7 +119,7 @@ PatchLibrarian::translate_load_path(const string& path) * - The patch_model has no (Ingen) path */ void -PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool recursive) +PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& filename, bool recursive) { assert(filename != ""); assert(patch_model->path() != ""); @@ -132,7 +131,6 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool string dir = filename.substr(0, filename.find_last_of("/")); NodeModel* nm = NULL; - PatchModel* spm = NULL; // subpatch model xmlDocPtr xml_doc = NULL; xmlNodePtr xml_root_node = NULL; @@ -149,7 +147,7 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool string patch_name; if (patch_model->path() != "/") { - patch_name = patch_model->name(); + patch_name = patch_model->path().name(); } else { patch_name = filename; if (patch_name.find("/") != string::npos) @@ -186,15 +184,17 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool nm = i->second.get(); if (nm->plugin()->type() == PluginModel::Patch) { // Subpatch - spm = (PatchModel*)i->second.get(); + CountedPtr<PatchModel> spm = PtrCast<PatchModel>(i->second); + assert(spm); + xml_node = xmlNewChild(xml_root_node, NULL, (xmlChar*)"subpatch", NULL); - xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"name", (xmlChar*)spm->name().c_str()); + xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"name", (xmlChar*)spm->path().name().c_str()); string ref_filename; // No path if (spm->filename() == "") { - ref_filename = spm->name() + ".om"; + ref_filename = spm->path().name() + ".om"; spm->filename(dir +"/"+ ref_filename); // Absolute path } else if (spm->filename().substr(0, 1) == "/") { @@ -230,7 +230,7 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool } else { // Normal node xml_node = xmlNewChild(xml_root_node, NULL, (xmlChar*)"node", NULL); - xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"name", (xmlChar*)nm->name().c_str()); + xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"name", (xmlChar*)nm->path().name().c_str()); if (!nm->plugin()) break; @@ -321,7 +321,7 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool float val = pm->value(); xml_node = xmlNewChild(xml_preset_node, NULL, (xmlChar*)"control", NULL); xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"node-name", - (xmlChar*)nm->name().c_str()); + (xmlChar*)nm->path().name().c_str()); xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"port-name", (xmlChar*)pm->path().name().c_str()); snprintf(temp_buf, temp_buf_length, "%f", val); @@ -371,7 +371,7 @@ PatchLibrarian::save_patch(PatchModel* patch_model, const string& filename, bool * Returns the path of the newly created patch. */ string -PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) +PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing) { string filename = pm->filename(); @@ -426,7 +426,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if (load_name) { assert(key != NULL); if (pm->parent()) { - path = pm->parent()->base_path() + string((char*)key); + path = pm->parent()->path().base() + string((char*)key); } else { path = string("/") + string((char*)key); } @@ -464,7 +464,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if (wait) { //int id = _engine->get_next_request_id(); //_engine->set_wait_response_id(id); - _engine->create_patch_from_model(pm); + _engine->create_patch_from_model(pm.get()); //bool succeeded = _engine->wait_for_response(); // If creating the patch failed, bail out so we don't load all these nodes @@ -474,7 +474,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) return ""; }*/ // FIXME } else { - _engine->create_patch_from_model(pm); + _engine->create_patch_from_model(pm.get()); } } @@ -486,15 +486,14 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) _engine->set_metadata(pm->path(), "filename", pm->filename()); // Load nodes - NodeModel* nm = NULL; cur = xmlDocGetRootElement(doc)->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar*)"node"))) { - nm = parse_node(pm, doc, cur); - if (nm != NULL) { - _engine->create_node_from_model(nm); - _engine->set_all_metadata(nm); + CountedPtr<NodeModel> nm = parse_node(pm, doc, cur); + if (nm) { + _engine->create_node_from_model(nm.get()); + _engine->set_all_metadata(nm.get()); for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) { // FIXME: ew snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_min()); @@ -502,8 +501,6 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_max()); _engine->set_metadata((*j)->path(), "user-max", temp_buf); } - nm = NULL; - usleep(10000); } } cur = cur->next; @@ -526,7 +523,6 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) cm = parse_connection(pm, doc, cur); if (cm != NULL) { _engine->connect(cm->src_port_path(), cm->dst_port_path()); - usleep(1000); } } cur = cur->next; @@ -549,7 +545,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) xmlFreeDoc(doc); xmlCleanupParser(); - _engine->set_all_metadata(pm); + _engine->set_all_metadata(pm.get()); if (!existing) _engine->enable_patch(pm->path()); @@ -563,11 +559,11 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) /** Build a NodeModel given a pointer to a Node in a patch file. */ -NodeModel* -PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr node) +CountedPtr<NodeModel> +PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr node) { - PluginModel* plugin = new PluginModel(); - NodeModel* nm = new NodeModel(plugin, "/UNINITIALIZED"); // FIXME: ew + CountedPtr<PluginModel> plugin(new PluginModel()); + CountedPtr<NodeModel> nm(new NodeModel(plugin, "/UNINITIALIZED")); // FIXME: ew xmlChar* key; xmlNodePtr cur = node->xmlChildrenNode; @@ -576,7 +572,7 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - nm->set_path(parent->base_path() + Path::nameify((char*)key)); + nm->set_path(parent->path().base() + Path::nameify((char*)key)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { nm->polyphonic(!strcmp((char*)key, "true")); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { @@ -598,7 +594,7 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - path = nm->base_path() + Path::nameify((char*)key); + path = nm->path().base() + Path::nameify((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) { user_min = atof((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) { @@ -612,9 +608,9 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod } // FIXME: nasty assumptions - PortModel* pm = new PortModel(path, + CountedPtr<PortModel> pm(new PortModel(path, PortModel::CONTROL, PortModel::INPUT, PortModel::NONE, - 0.0, user_min, user_max); + 0.0, user_min, user_max)); pm->set_parent(nm); nm->add_port(pm); @@ -678,8 +674,7 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod if (nm->path() == "") { cerr << "[PatchLibrarian] Malformed patch file (node tag has empty children)" << endl; cerr << "[PatchLibrarian] Node ignored." << endl; - delete nm; - return NULL; + return CountedPtr<NodeModel>(); // Compatibility hacks for old patches } else if (plugin->type() == PluginModel::Internal) { @@ -716,9 +711,8 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod _load_path_translations[old_path + "/out"] = new_path; nm->set_path(new_path); - _engine->set_all_metadata(nm); - delete nm; - return NULL; + _engine->set_all_metadata(nm.get()); + return CountedPtr<NodeModel>(); } else { if (plugin->uri() == "") { if (plugin->plug_label() == "note_in") { @@ -740,12 +734,12 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod void -PatchLibrarian::load_subpatch(PatchModel* parent, xmlDocPtr doc, const xmlNodePtr subpatch) +PatchLibrarian::load_subpatch(const CountedPtr<PatchModel> parent, xmlDocPtr doc, const xmlNodePtr subpatch) { xmlChar *key; xmlNodePtr cur = subpatch->xmlChildrenNode; - PatchModel* pm = new PatchModel("/UNINITIALIZED", 1); // FIXME: ew + CountedPtr<PatchModel> pm(new PatchModel("/UNINITIALIZED", 1)); // FIXME: ew while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); @@ -754,7 +748,7 @@ PatchLibrarian::load_subpatch(PatchModel* parent, xmlDocPtr doc, const xmlNodePt if (parent == NULL) pm->set_path(string("/") + (const char*)key); else - pm->set_path(parent->base_path() + (const char*)key); + pm->set_path(parent->path().base() + (const char*)key); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { pm->poly(atoi((const char*)key)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"filename"))) { @@ -781,7 +775,7 @@ PatchLibrarian::load_subpatch(PatchModel* parent, xmlDocPtr doc, const xmlNodePt /** Build a ConnectionModel given a pointer to a connection in a patch file. */ ConnectionModel* -PatchLibrarian::parse_connection(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr node) +PatchLibrarian::parse_connection(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr node) { //cerr << "[PatchLibrarian] Parsing connection..." << endl; @@ -822,8 +816,8 @@ PatchLibrarian::parse_connection(const PatchModel* parent, xmlDocPtr doc, const dest_port = Path::nameify(dest_port); ConnectionModel* cm = new ConnectionModel( - translate_load_path(parent->base_path() + source_node +"/"+ source_port), - translate_load_path(parent->base_path() + dest_node +"/"+ dest_port)); + translate_load_path(parent->path().base() + source_node +"/"+ source_port), + translate_load_path(parent->path().base() + dest_node +"/"+ dest_port)); return cm; } @@ -832,12 +826,12 @@ PatchLibrarian::parse_connection(const PatchModel* parent, xmlDocPtr doc, const /** Build a PresetModel given a pointer to a preset in a patch file. */ PresetModel* -PatchLibrarian::parse_preset(const PatchModel* patch, xmlDocPtr doc, const xmlNodePtr node) +PatchLibrarian::parse_preset(const CountedPtr<const PatchModel> patch, xmlDocPtr doc, const xmlNodePtr node) { xmlNodePtr cur = node->xmlChildrenNode; xmlChar* key; - PresetModel* pm = new PresetModel(patch->base_path()); + PresetModel* pm = new PresetModel(patch->path().base()); while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); diff --git a/src/libs/client/PatchLibrarian.h b/src/libs/client/PatchLibrarian.h index cd4b4b7a..a900b22f 100644 --- a/src/libs/client/PatchLibrarian.h +++ b/src/libs/client/PatchLibrarian.h @@ -47,7 +47,7 @@ class PatchLibrarian public: // FIXME: return booleans and set an errstr that can be checked or something? - PatchLibrarian(CountedPtr<ModelEngineInterface> _engine) + PatchLibrarian(CountedPtr<ModelEngineInterface> engine) : _patch_search_path("."), _engine(_engine) { assert(_engine); @@ -58,8 +58,8 @@ public: string find_file(const string& filename, const string& additional_path = ""); - void save_patch(PatchModel* patch_model, const string& filename, bool recursive); - string load_patch(PatchModel* pm, bool wait = true, bool existing = false); + void save_patch(CountedPtr<PatchModel> patch_model, const string& filename, bool recursive); + string load_patch(CountedPtr<PatchModel> pm, bool wait = true, bool existing = false); private: string translate_load_path(const string& path); @@ -70,10 +70,10 @@ private: /// Translations of paths from the loading file to actual paths (for deprecated patches) std::map<string, string> _load_path_translations; - NodeModel* parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); - ConnectionModel* parse_connection(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); - PresetModel* parse_preset(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); - void load_subpatch(PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); + CountedPtr<NodeModel> parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr cur); + ConnectionModel* parse_connection(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr cur); + PresetModel* parse_preset(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr cur); + void load_subpatch(const CountedPtr<PatchModel> parent, xmlDocPtr doc, const xmlNodePtr cur); }; diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp index 5b1348b2..36e829f3 100644 --- a/src/libs/client/PatchModel.cpp +++ b/src/libs/client/PatchModel.cpp @@ -37,7 +37,7 @@ PatchModel::set_path(const Path& new_path) NodeModel::set_path(new_path); for (NodeModelMap::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - (*i).second->set_path(m_path +"/"+ (*i).second->name()); + (*i).second->set_path(m_path +"/"+ (*i).second->path().name()); #ifdef DEBUG // Be sure connection paths are updated and sane @@ -50,12 +50,31 @@ PatchModel::set_path(const Path& new_path) } +void +PatchModel::add_child(CountedPtr<ObjectModel> c) +{ + assert(c->parent().get() == this); + + CountedPtr<PortModel> pm = PtrCast<PortModel>(c); + if (pm) { + add_port(pm); + return; + } + + CountedPtr<NodeModel> nm = PtrCast<NodeModel>(c); + if (nm) { + add_node(nm); + return; + } +} + + CountedPtr<NodeModel> PatchModel::get_node(const string& name) { assert(name.find("/") == string::npos); NodeModelMap::iterator i = m_nodes.find(name); - return ((i != m_nodes.end()) ? (*i).second : CountedPtr<NodeModel>(NULL)); + return ((i != m_nodes.end()) ? (*i).second : CountedPtr<NodeModel>()); } @@ -63,13 +82,19 @@ void PatchModel::add_node(CountedPtr<NodeModel> nm) { assert(nm); - assert(nm->name().find("/") == string::npos); + assert(nm->path().is_child_of(m_path)); assert(nm->parent().get() == this); - assert(m_nodes.find(nm->name()) == m_nodes.end()); - - m_nodes[nm->name()] = nm; - - new_node_sig.emit(nm); + + NodeModelMap::iterator existing = m_nodes.find(nm->path().name()); + + if (existing != m_nodes.end()) { + cerr << "Warning: node clash, assimilating old node " << m_path << endl; + nm->assimilate((*existing).second); + (*existing).second = nm; + } else { + m_nodes[nm->path().name()] = nm; + new_node_sig.emit(nm); + } } @@ -123,15 +148,14 @@ PatchModel::rename_node(const Path& old_path, const Path& new_path) assert(new_path.parent() == path()); NodeModelMap::iterator i = m_nodes.find(old_path.name()); - NodeModel* nm = NULL; if (i != m_nodes.end()) { - nm = (*i).second.get(); + CountedPtr<NodeModel> nm = (*i).second; for (list<CountedPtr<ConnectionModel> >::iterator j = m_connections.begin(); j != m_connections.end(); ++j) { if ((*j)->src_port_path().parent() == old_path) - (*j)->src_port_path(new_path.base_path() + (*j)->src_port_path().name()); + (*j)->src_port_path(new_path.base() + (*j)->src_port_path().name()); if ((*j)->dst_port_path().parent() == old_path) - (*j)->dst_port_path(new_path.base_path() + (*j)->dst_port_path().name()); + (*j)->dst_port_path(new_path.base() + (*j)->dst_port_path().name()); } m_nodes.erase(i); assert(nm->path() == new_path); @@ -149,7 +173,7 @@ PatchModel::get_connection(const string& src_port_path, const string& dst_port_p for (list<CountedPtr<ConnectionModel> >::iterator i = m_connections.begin(); i != m_connections.end(); ++i) if ((*i)->src_port_path() == src_port_path && (*i)->dst_port_path() == dst_port_path) return (*i); - return NULL; + return CountedPtr<ConnectionModel>(); } diff --git a/src/libs/client/PatchModel.h b/src/libs/client/PatchModel.h index c15f7746..db444de2 100644 --- a/src/libs/client/PatchModel.h +++ b/src/libs/client/PatchModel.h @@ -40,7 +40,7 @@ class PatchModel : public NodeModel { public: PatchModel(const string& patch_path, uint poly) - : NodeModel(patch_path), + : NodeModel("ingen:patch", patch_path), m_enabled(false), m_poly(poly) {} @@ -50,6 +50,8 @@ public: virtual void set_path(const Path& path); + void add_child(CountedPtr<ObjectModel> c); + CountedPtr<NodeModel> get_node(const string& node_name); void add_node(CountedPtr<NodeModel> nm); void remove_node(const string& name); diff --git a/src/libs/client/PortModel.h b/src/libs/client/PortModel.h index 3aedc639..7b84c95a 100644 --- a/src/libs/client/PortModel.h +++ b/src/libs/client/PortModel.h @@ -70,6 +70,8 @@ public: { } + void add_child(CountedPtr<ObjectModel> c) { throw; } + inline float min_val() const { return m_min_val; } inline float user_min() const { return atof(get_metadata("min").c_str()); } // FIXME: haaack //inline void user_min(float f) { m_user_min = f; } diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index ef1b7283..36e815d8 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -55,22 +55,98 @@ Store::clear() void +Store::add_plugin_orphan(CountedPtr<NodeModel> node) +{ + cerr << "WARNING: Node " << node->path() << " received, but plugin " + << node->plugin_uri() << " unknown." << endl; + + map<string, list<CountedPtr<NodeModel> > >::iterator spawn + = m_plugin_orphans.find(node->plugin_uri()); + + if (spawn != m_plugin_orphans.end()) { + spawn->second.push_back(node); + } else { + list<CountedPtr<NodeModel> > l; + l.push_back(node); + m_plugin_orphans[node->plugin_uri()] = l; + } +} + + +void +Store::resolve_plugin_orphans(CountedPtr<PluginModel> plugin) +{ + map<string, list<CountedPtr<NodeModel> > >::iterator spawn + = m_plugin_orphans.find(plugin->uri()); + + if (spawn != m_plugin_orphans.end()) { + cerr << "XXXXXXXXXX PLUGIN-ORPHAN PLUGIN FOUND!! XXXXXXXXXXXXXXXXX" << endl; + } +} + + +void +Store::add_orphan(CountedPtr<ObjectModel> child) +{ + cerr << "WARNING: Orphan object " << child->path() << " received." << endl; + + map<Path, list<CountedPtr<ObjectModel> > >::iterator children + = m_orphans.find(child->path().parent()); + + if (children != m_orphans.end()) { + children->second.push_back(child); + } else { + list<CountedPtr<ObjectModel> > l; + l.push_back(child); + m_orphans[child->path().parent()] = l; + } +} + + +void +Store::resolve_orphans(CountedPtr<ObjectModel> parent) +{ + map<Path, list<CountedPtr<ObjectModel> > >::iterator children + = m_orphans.find(parent->path()); + + if (children != m_orphans.end()) { + cerr << "XXXXXXXXXXXXX ORPHAN PARENT FOUND!! XXXXXXXXXXXXXXXXX" << endl; + } +} + + +void Store::add_object(CountedPtr<ObjectModel> object) { assert(object->path() != ""); assert(m_objects.find(object->path()) == m_objects.end()); + if (object->path() != "/") { + CountedPtr<ObjectModel> parent = this->object(object->path().parent()); + if (parent) { + assert(object->path().is_child_of(parent->path())); + object->set_parent(parent); + parent->add_child(object); + assert(object->parent() == parent); + } else { + add_orphan(object); + } + } + m_objects[object->path()] = object; new_object_sig.emit(object); + + resolve_orphans(object); + //cout << "[Store] Added " << object->path() << endl; } CountedPtr<ObjectModel> -Store::remove_object(const string& path) +Store::remove_object(const Path& path) { - map<string, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); + map<Path, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); if (i != m_objects.end()) { assert((*i).second->path() == path); @@ -80,7 +156,7 @@ Store::remove_object(const string& path) return result; } else { cerr << "[Store] Unable to find object " << path << " to remove." << endl; - return NULL; + return CountedPtr<ObjectModel>(); } } @@ -91,84 +167,29 @@ Store::plugin(const string& uri) assert(uri.length() > 0); map<string, CountedPtr<PluginModel> >::iterator i = m_plugins.find(uri); if (i == m_plugins.end()) - return NULL; + return CountedPtr<PluginModel>(); else return (*i).second; } CountedPtr<ObjectModel> -Store::object(const string& path) +Store::object(const Path& path) { assert(path.length() > 0); - map<string, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); + map<Path, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); if (i == m_objects.end()) - return NULL; + return CountedPtr<ObjectModel>(); else return (*i).second; } -#if 0 -CountedPtr<PatchModel> -Store::patch(const string& path) -{ - assert(path.length() > 0); - map<string, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); - if (i == m_objects.end()) - return NULL; - else - return (CountedPtr<PatchModel>)(*i).second; // FIXME -} - - -CountedPtr<NodeModel> -Store::node(const string& path) -{ - assert(path.length() > 0); - map<string, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); - if (i == m_objects.end()) - return NULL; - else - return (*i).second; -} - - -CountedPtr<PortModel> -Store::port(const string& path) -{ - assert(path.length() > 0); - map<string, CountedPtr<ObjectModel> >::iterator i = m_objects.find(path); - if (i == m_objects.end()) { - return NULL; - } else { - // Normal port - /*PortModel* const pc = dynamic_cast<PortModel*>((*i).second); - if (pc) - return pc;*/ - return (*i).second; - - // Patch port (corresponding Node is in store) - // FIXME - // - /* - NodeModel* const nc = dynamic_cast<NodeModel*>((*i).second); - if (nc) - return nc->as_port(); // Patch port (maybe) - */ - } - - return NULL; -} -#endif - void Store::add_plugin(CountedPtr<PluginModel> pm) { - //if (m_plugins.find(pm->uri()) != m_plugins.end()) { - // cerr << "DUPE PLUGIN: " << pm->uri() << endl; - //} else { - m_plugins[pm->uri()] = pm; - //} + // FIXME: dupes? + + m_plugins[pm->uri()] = pm; } @@ -177,10 +198,9 @@ Store::add_plugin(CountedPtr<PluginModel> pm) void -Store::destruction_event(const string& path) +Store::destruction_event(const Path& path) { - // I'm assuming the compiler will optimize out all these const - // pointers into one... + // Hopefully the compiler will optimize all these const pointers into one... CountedPtr<ObjectModel> obj_ptr = remove_object(path); ObjectModel* const object = obj_ptr.get(); @@ -194,147 +214,94 @@ Store::destruction_event(const string& path) cerr << "Node\n"; PatchModel* const parent = dynamic_cast<PatchModel* const>(object->parent().get()); if (parent) - parent->remove_node(node->name()); + parent->remove_node(node->path().name()); } PortModel* const port = dynamic_cast<PortModel*>(object); if (port) { NodeModel* const parent = dynamic_cast<NodeModel* const>(object->parent().get()); assert(parent); - parent->remove_port(port->name()); + parent->remove_port(port->path().name()); } - // FIXME: emit signals + if (object) + object->destroyed_sig.emit(); } void Store::new_plugin_event(const string& type, const string& uri, const string& name) { - PluginModel* const p = new PluginModel(type, uri); + CountedPtr<PluginModel> p(new PluginModel(type, uri)); p->name(name); add_plugin(p); + resolve_plugin_orphans(p); } void -Store::new_patch_event(const string& path, uint32_t poly) +Store::new_patch_event(const Path& path, uint32_t poly) { - // FIXME: What to do with a conflict? - - if (m_objects.find(path) == m_objects.end()) { - CountedPtr<PatchModel> p(new PatchModel(path, poly)); - add_object(p); - - if (path != "/") { - CountedPtr<PatchModel> parent = object(p->path().parent()); - if (parent) { - assert(path.substr(0, parent->path().length()) == parent->path()); - p->set_parent(parent); - parent->add_node(p); - assert(p->parent() == parent); - } else { - cerr << "ERROR: new patch with no parent" << endl; - } - } - } + CountedPtr<PatchModel> p(new PatchModel(path, poly)); + add_object(p); } void -Store::new_node_event(const string& plugin_type, const string& plugin_uri, const string& node_path, bool is_polyphonic, uint32_t num_ports) +Store::new_node_event(const string& plugin_type, const string& plugin_uri, const Path& node_path, bool is_polyphonic, uint32_t num_ports) { - // FIXME: What to do with a conflict? - - if (m_objects.find(node_path) == m_objects.end()) { - - CountedPtr<PluginModel> plug = plugin(plugin_uri); - assert(plug); - + // FIXME: num_ports unused + + CountedPtr<PluginModel> plug = plugin(plugin_uri); + if (!plug) { + CountedPtr<NodeModel> n(new NodeModel(plugin_uri, node_path)); + n->polyphonic(is_polyphonic); + add_plugin_orphan(n); + } else { CountedPtr<NodeModel> n(new NodeModel(plug, node_path)); n->polyphonic(is_polyphonic); - // FIXME: num_ports unused add_object(n); - - //std::map<string, CountedPtr<ObjectModel> >::iterator pi = m_objects.find(n->path().parent()); - //if (pi != m_objects.end()) { - CountedPtr<PatchModel> parent = object(n->path().parent()); - if (parent) { - n->set_parent(parent); - assert(n->parent() == parent); - parent->add_node(n); - assert(n->parent() == parent); - } else { - cerr << "ERROR: new node with no parent" << endl; - } } } void -Store::new_port_event(const string& path, const string& type, bool is_output) +Store::new_port_event(const Path& path, const string& type, bool is_output) { // FIXME: this sucks - /* - if (m_objects.find(path) == m_objects.end()) { - PortModel::Type ptype = PortModel::CONTROL; - if (type == "AUDIO") ptype = PortModel::AUDIO; - else if (type == "CONTROL") ptype = PortModel::CONTROL; - else if (type== "MIDI") ptype = PortModel::MIDI; - else cerr << "[OSCListener] WARNING: Unknown port type received (" << type << ")" << endl; - - PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - - PortModel* const p = new PortModel(path, ptype, pdir); - - add_object(p); - } else - */ - if (m_objects.find(path) == m_objects.end()) { - - PortModel::Type ptype = PortModel::CONTROL; - if (type == "AUDIO") ptype = PortModel::AUDIO; - else if (type == "CONTROL") ptype = PortModel::CONTROL; - else if (type== "MIDI") ptype = PortModel::MIDI; - else cerr << "[Store] WARNING: Unknown port type received (" << type << ")" << endl; - - PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - - CountedPtr<PortModel> p(new PortModel(path, ptype, pdir)); - add_object(p); - - CountedPtr<NodeModel> parent = object(p->path().parent()); - if (parent) { - p->set_parent(parent); - assert(p->parent() == parent); - parent->add_port(p); - assert(p->parent() == parent); - } else { - cerr << "ERROR: new port with no parent" << endl; - } - } + + PortModel::Type ptype = PortModel::CONTROL; + if (type == "AUDIO") ptype = PortModel::AUDIO; + else if (type == "CONTROL") ptype = PortModel::CONTROL; + else if (type== "MIDI") ptype = PortModel::MIDI; + else cerr << "[Store] WARNING: Unknown port type received (" << type << ")" << endl; + + PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; + + CountedPtr<PortModel> p(new PortModel(path, ptype, pdir)); + add_object(p); } void -Store::patch_enabled_event(const string& path) +Store::patch_enabled_event(const Path& path) { - CountedPtr<PatchModel> patch = object(path); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object(path)); if (patch) patch->enable(); } void -Store::patch_disabled_event(const string& path) +Store::patch_disabled_event(const Path& path) { - CountedPtr<PatchModel> patch = object(path); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object(path)); if (patch) patch->disable(); } void -Store::metadata_update_event(const string& subject_path, const string& predicate, const string& value) +Store::metadata_update_event(const Path& subject_path, const string& predicate, const string& value) { CountedPtr<ObjectModel> subject = object(subject_path); if (subject) @@ -345,9 +312,9 @@ Store::metadata_update_event(const string& subject_path, const string& predicate void -Store::control_change_event(const string& port_path, float value) +Store::control_change_event(const Path& port_path, float value) { - CountedPtr<PortModel> port = object(port_path); + CountedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); if (port) port->value(value); else @@ -358,8 +325,8 @@ Store::control_change_event(const string& port_path, float value) void Store::connection_event(const Path& src_port_path, const Path& dst_port_path) { - CountedPtr<PortModel> src_port = object(src_port_path); - CountedPtr<PortModel> dst_port = object(dst_port_path); + CountedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); + CountedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); assert(src_port); assert(dst_port); @@ -367,9 +334,9 @@ Store::connection_event(const Path& src_port_path, const Path& dst_port_path) src_port->connected_to(dst_port); dst_port->connected_to(src_port); - CountedPtr<ConnectionModel> cm = new ConnectionModel(src_port, dst_port); + CountedPtr<ConnectionModel> cm(new ConnectionModel(src_port, dst_port)); - CountedPtr<PatchModel> patch = this->object(cm->patch_path()); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(this->object(cm->patch_path())); if (patch) patch->add_connection(cm); @@ -384,8 +351,8 @@ Store::disconnection_event(const Path& src_port_path, const Path& dst_port_path) // Find the ports and create a ConnectionModel just to get at the parent path // finding logic in ConnectionModel. So I'm lazy. - CountedPtr<PortModel> src_port = object(src_port_path); - CountedPtr<PortModel> dst_port = object(dst_port_path); + CountedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); + CountedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); assert(src_port); assert(dst_port); @@ -393,9 +360,9 @@ Store::disconnection_event(const Path& src_port_path, const Path& dst_port_path) src_port->disconnected_from(dst_port); dst_port->disconnected_from(src_port); - CountedPtr<ConnectionModel> cm = new ConnectionModel(src_port, dst_port); + CountedPtr<ConnectionModel> cm(new ConnectionModel(src_port, dst_port)); - CountedPtr<PatchModel> patch = this->object(cm->patch_path()); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(this->object(cm->patch_path())); if (patch) patch->remove_connection(src_port_path, dst_port_path); diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h index 44ca5c70..e70c5bc0 100644 --- a/src/libs/client/Store.h +++ b/src/libs/client/Store.h @@ -20,10 +20,11 @@ #include <cassert> #include <string> #include <map> +#include <list> #include "util/CountedPtr.h" #include <sigc++/sigc++.h> #include "util/Path.h" -using std::string; using std::map; +using std::string; using std::map; using std::list; namespace Ingen { namespace Client { @@ -44,10 +45,7 @@ public: Store(CountedPtr<SigClientInterface> emitter); CountedPtr<PluginModel> plugin(const string& uri); - CountedPtr<ObjectModel> object(const string& path); - /*CountedPtr<PatchModel> patch(const string& path); - CountedPtr<NodeModel> node(const string& path); - CountedPtr<PortModel> port(const string& path);*/ + CountedPtr<ObjectModel> object(const Path& path); void clear(); @@ -59,25 +57,39 @@ public: private: void add_object(CountedPtr<ObjectModel> object); - CountedPtr<ObjectModel> remove_object(const string& path); + CountedPtr<ObjectModel> remove_object(const Path& path); void add_plugin(CountedPtr<PluginModel> plugin); + void add_orphan(CountedPtr<ObjectModel> orphan); + void resolve_orphans(CountedPtr<ObjectModel> parent); + + void add_plugin_orphan(CountedPtr<NodeModel> orphan); + void resolve_plugin_orphans(CountedPtr<PluginModel> plugin); + // Slots for SigClientInterface signals - void destruction_event(const string& path); + void destruction_event(const Path& path); void new_plugin_event(const string& type, const string& uri, const string& name); - void new_patch_event(const string& path, uint32_t poly); - void new_node_event(const string& plugin_type, const string& plugin_uri, const string& node_path, bool is_polyphonic, uint32_t num_ports); - void new_port_event(const string& path, const string& data_type, bool is_output); - void patch_enabled_event(const string& path); - void patch_disabled_event(const string& path); - void metadata_update_event(const string& subject_path, const string& predicate, const string& value); - void control_change_event(const string& port_path, float value); + void new_patch_event(const Path& path, uint32_t poly); + void new_node_event(const string& plugin_type, const string& plugin_uri, const Path& node_path, bool is_polyphonic, uint32_t num_ports); + void new_port_event(const Path& path, const string& data_type, bool is_output); + void patch_enabled_event(const Path& path); + void patch_disabled_event(const Path& path); + void metadata_update_event(const Path& subject_path, const string& predicate, const string& value); + void control_change_event(const Path& port_path, float value); void connection_event(const Path& src_port_path, const Path& dst_port_path); void disconnection_event(const Path& src_port_path, const Path& dst_port_path); - map<string, CountedPtr<ObjectModel> > m_objects; ///< Keyed by Ingen path + map<Path, CountedPtr<ObjectModel> > m_objects; ///< Keyed by Ingen path map<string, CountedPtr<PluginModel> > m_plugins; ///< Keyed by URI + + /** Objects we've received, but depend on the existance of another unknown object. + * Keyed by the path of the depended-on object (for tolerance of orderless comms) */ + map<Path, list<CountedPtr<ObjectModel> > > m_orphans; + + /** Same idea, except with plugins instead of parents. + * It's unfortunate everything doesn't just have a URI and this was the same.. ahem.. */ + map<string, list<CountedPtr<NodeModel> > > m_plugin_orphans; }; diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index 181e5a2c..1b4a2bd2 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -112,7 +112,7 @@ ClientBroadcaster::client(const ClientKey& key) cerr << "[ClientBroadcaster] Failed to find client." << endl; - return NULL; + return CountedPtr<ClientInterface>(); } diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index daf6db6c..99679932 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = tests DIST_SUBDIRS = events -AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine/events -fno-exceptions +AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine/events MAINTAINERCLEANFILES = Makefile.in diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index ad985b7e..2eb68d70 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -52,7 +52,7 @@ OSCEngineReceiver::OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_siz QueuedEngineInterface(engine, queue_size, queue_size), // FIXME _port(port), _server(NULL), - _osc_responder(NULL) + _osc_responder(CountedPtr<OSCResponder>()) { _server = lo_server_new(port, error_cb); diff --git a/src/libs/engine/OSCResponder.cpp b/src/libs/engine/OSCResponder.cpp index a6d68721..a2931ca5 100644 --- a/src/libs/engine/OSCResponder.cpp +++ b/src/libs/engine/OSCResponder.cpp @@ -83,7 +83,7 @@ OSCResponder::client() if (_broadcaster) return _broadcaster->client(client_key()); else - return NULL; + return CountedPtr<ClientInterface>(); } } // namespace OM diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index bcbe4e68..747d60c7 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -361,7 +361,7 @@ Patch::set_path(const Path& new_path) // Update nodes for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->set_path(new_path.base_path() + (*i)->name()); + (*i)->set_path(new_path.base() + (*i)->name()); // Update self NodeBase::set_path(new_path); diff --git a/src/libs/engine/QueuedEvent.h b/src/libs/engine/QueuedEvent.h index 733ebd38..780e6a36 100644 --- a/src/libs/engine/QueuedEvent.h +++ b/src/libs/engine/QueuedEvent.h @@ -87,7 +87,7 @@ protected: // NULL event base (for internal events only!) QueuedEvent(Engine& engine) - : Event(engine, NULL, 0) + : Event(engine, CountedPtr<Ingen::Responder>(), 0) , _pre_processed(false), _blocking(false), _source(NULL) {} diff --git a/src/libs/engine/Responder.h b/src/libs/engine/Responder.h index 3976883d..63b6fc7f 100644 --- a/src/libs/engine/Responder.h +++ b/src/libs/engine/Responder.h @@ -52,7 +52,7 @@ public: virtual ~Responder() {} virtual ClientKey client_key() { return ClientKey(); } - virtual CountedPtr<ClientInterface> client() { return NULL; } + virtual CountedPtr<ClientInterface> client() { return CountedPtr<ClientInterface>(); } virtual void set_id(int32_t id) {} diff --git a/src/libs/engine/events/MidiLearnEvent.h b/src/libs/engine/events/MidiLearnEvent.h index 7a36706c..8c4ed6d2 100644 --- a/src/libs/engine/events/MidiLearnEvent.h +++ b/src/libs/engine/events/MidiLearnEvent.h @@ -38,7 +38,7 @@ class MidiLearnResponseEvent : public Event { public: MidiLearnResponseEvent(Engine& engine, const string& port_path, SampleCount timestamp) - : Event(engine, NULL, timestamp), + : Event(engine, CountedPtr<Responder>(), timestamp), m_port_path(port_path), m_value(0.0f) {} diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp index 82fe3737..75db4395 100644 --- a/src/libs/engine/events/RenameEvent.cpp +++ b/src/libs/engine/events/RenameEvent.cpp @@ -31,7 +31,7 @@ RenameEvent::RenameEvent(Engine& engine, CountedPtr<Responder> responder, Sample : QueuedEvent(engine, responder, timestamp), m_old_path(path), m_name(name), - m_new_path(m_old_path.parent().base_path() + name), + m_new_path(m_old_path.parent().base() + name), m_parent_patch(NULL), m_store_treenode(NULL), m_error(NO_ERROR) diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp index e2169f54..f6f1bdf9 100644 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ b/src/libs/engine/events/RequestMetadataEvent.cpp @@ -33,7 +33,7 @@ RequestMetadataEvent::RequestMetadataEvent(Engine& engine, CountedPtr<Responder> m_key(key), m_value(""), m_object(NULL), - m_client(CountedPtr<ClientInterface>(NULL)) + m_client(CountedPtr<ClientInterface>()) { } diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp index 80f55dcd..55f4731f 100644 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ b/src/libs/engine/events/RequestPortValueEvent.cpp @@ -32,8 +32,7 @@ RequestPortValueEvent::RequestPortValueEvent(Engine& engine, CountedPtr<Responde : QueuedEvent(engine, responder, timestamp), m_port_path(port_path), m_port(NULL), - m_value(0.0), - m_client(CountedPtr<ClientInterface>(NULL)) + m_value(0.0) { } diff --git a/src/progs/Makefile.am b/src/progs/Makefile.am index a1a8c911..01791a1b 100644 --- a/src/progs/Makefile.am +++ b/src/progs/Makefile.am @@ -5,7 +5,7 @@ DIST_SUBDIRS = python supercollider SUBDIRS = server if BUILD_CONSOLE_CLIENTS -SUBDIRS += patch_loader demolition +SUBDIRS += patch_loader #demolition endif if BUILD_GTK_CLIENT diff --git a/src/progs/demolition/DemolitionClientInterface.cpp b/src/progs/demolition/DemolitionClientInterface.cpp index a0704028..23f5733f 100644 --- a/src/progs/demolition/DemolitionClientInterface.cpp +++ b/src/progs/demolition/DemolitionClientInterface.cpp @@ -36,7 +36,7 @@ DemolitionClientInterface::error(string msg) void -DemolitionClientInterface::new_patch_model(PatchModel* pm) +DemolitionClientInterface::new_patch_model(CountedPtr<PatchModel> pm) { m_model->add_patch(pm); } @@ -68,7 +68,7 @@ DemolitionClientInterface::patch_disabled(string path) void -DemolitionClientInterface::new_node_model(NodeModel* nm) +DemolitionClientInterface::new_node_model(CountedPtr<NodeModel> nm) { m_model->add_node(nm); } diff --git a/src/progs/demolition/DemolitionClientInterface.h b/src/progs/demolition/DemolitionClientInterface.h index 83539afc..e1093411 100644 --- a/src/progs/demolition/DemolitionClientInterface.h +++ b/src/progs/demolition/DemolitionClientInterface.h @@ -56,19 +56,19 @@ public: void new_plugin(string type, string uri, string name) {} - void new_patch_model(PatchModel* const pm); - void new_port_model(PortModel* const port_model); + void new_patch_model(CountedPtr<PatchModel> pm); + void new_port_model(CountedPtr<PortModel> port_model); void object_destroyed(string path); void patch_enabled(string path); void patch_disabled(string path); void patch_cleared(string path) { throw; } - void new_node_model(NodeModel* const nm); + void new_node_model(CountedPtr<NodeModel> nm); void object_renamed(string old_path, string new_path); - void connection_model(ConnectionModel* const cm); + void connection_model(CountedPtr<ConnectionModel> cm); void disconnection(string src_port_path, string dst_port_path); void metadata_update(string path, string key, string value) {} void control_change(string port_path, float value); - void new_plugin_model(PluginModel* const pi); + void new_plugin_model(CountedPtr<PluginModel> pi); void program_add(string path, uint32_t bank, uint32_t program, string name) {}; void program_remove(string path, uint32_t bank, uint32_t program) {}; diff --git a/src/progs/demolition/DemolitionModel.cpp b/src/progs/demolition/DemolitionModel.cpp index b91b461a..8ac10195 100644 --- a/src/progs/demolition/DemolitionModel.cpp +++ b/src/progs/demolition/DemolitionModel.cpp @@ -189,7 +189,7 @@ DemolitionModel::remove_object(const Path& path) void -DemolitionModel::add_node(NodeModel* nm) +DemolitionModel::add_node(CountedPtr<NodeModel> nm) { PatchModel* parent = patch(nm->path().parent()); if (parent == NULL) { diff --git a/src/progs/demolition/DemolitionModel.h b/src/progs/demolition/DemolitionModel.h index 67eb1005..6ae8c0ec 100644 --- a/src/progs/demolition/DemolitionModel.h +++ b/src/progs/demolition/DemolitionModel.h @@ -39,7 +39,7 @@ public: NodeModel* node(const Path& path); void add_patch(PatchModel* pm) { m_patches.push_back(pm); } - void add_node(NodeModel* nm); + void add_node(CountedPtr<NodeModel> nm); void add_port(PortModel* pm); void remove_object(const Path& path); void add_connection(ConnectionModel* cm); diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index ecf94a92..ae452f27 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -22,7 +22,6 @@ #include <libgnomecanvasmm.h> #include <time.h> #include <sys/time.h> -#include "PatchView.h" #include "OmModule.h" #include "ControlPanel.h" #include "SubpatchModule.h" @@ -44,6 +43,7 @@ #include "ConnectWindow.h" #include "Store.h" #include "Loader.h" +#include "WindowFactory.h" #ifdef HAVE_LASH #include "LashController.h" #endif @@ -66,6 +66,7 @@ App::App() _loader(NULL), _configuration(new Configuration()), _about_dialog(NULL), + _window_factory(new WindowFactory()), _enable_signal(true) { Glib::RefPtr<Gnome::Glade::Xml> glade_xml = GladeFactory::new_glade_reference(); @@ -94,7 +95,7 @@ App::instantiate() void -App::attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client) +App::attach(const CountedPtr<ModelEngineInterface>& engine, const CountedPtr<SigClientInterface>& client) { assert( ! _engine); assert( ! _client); diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 06d52ca3..25e01ff2 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -61,6 +61,7 @@ class PatchTreeWindow; class ConnectWindow; class Configuration; class Loader; +class WindowFactory; /** Singleton master class most everything is contained within. @@ -85,7 +86,8 @@ public: int num_open_patch_windows(); - void attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client); + void attach(const CountedPtr<ModelEngineInterface>& engine, + const CountedPtr<SigClientInterface>& client); ConnectWindow* connect_window() const { return _connect_window; } Gtk::Dialog* about_dialog() const { return _about_dialog; } @@ -95,7 +97,8 @@ public: Configuration* configuration() const { return _configuration; } Store* store() const { return _store; } Loader* loader() const { return _loader; } - + WindowFactory* window_factory() const { return _window_factory; } + const CountedPtr<ModelEngineInterface>& engine() const { return _engine; } const CountedPtr<SigClientInterface>& client() const { return _client; } @@ -121,6 +124,7 @@ protected: PatchTreeWindow* _patch_tree_window; ConfigWindow* _config_window; Gtk::Dialog* _about_dialog; + WindowFactory* _window_factory; /** Used to avoid feedback loops with (eg) process checkbutton * FIXME: Maybe this should be globally implemented at the Controller level, diff --git a/src/progs/ingenuity/BreadCrumbBox.cpp b/src/progs/ingenuity/BreadCrumbBox.cpp index d2bf7f97..aea1cdf0 100644 --- a/src/progs/ingenuity/BreadCrumbBox.cpp +++ b/src/progs/ingenuity/BreadCrumbBox.cpp @@ -28,9 +28,10 @@ BreadCrumbBox::BreadCrumbBox() } -/** Destroys current breadcrumbs and rebuilds from scratch. - * - * (Needs to be called when a patch is cleared to eliminate children crumbs) +/** Sets up the crumbs to display a @a path. + * + * If @a path is already part of the shown path, it will be selected and the + * children preserved. */ void BreadCrumbBox::build(Path path) @@ -38,8 +39,8 @@ BreadCrumbBox::build(Path path) bool old_enable_signal = _enable_signal; _enable_signal = false; - // Moving to a parent path, just switch the active button - if (path.length() < _full_path.length() && _full_path.substr(0, path.length()) == path) { + // Moving to a path we already contain, just switch the active button + if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) { for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) (*i)->set_active( ((*i)->path() == path) ); @@ -102,5 +103,33 @@ BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) } } + +void +BreadCrumbBox::object_removed(const Path& path) +{ + for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == path) { + // Remove all crumbs after the removed one (inclusive) + for (std::list<BreadCrumb*>::iterator j = i; j != _breadcrumbs.end(); ) { + BreadCrumb* bc = *j; + j = _breadcrumbs.erase(j); + remove(*bc); + } + break; + } + } +} + + +void +BreadCrumbBox::object_renamed(const Path& old_path, const Path& new_path) +{ + for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == old_path) + (*i)->set_path(new_path); + } +} + + } // namespace Ingenuity diff --git a/src/progs/ingenuity/BreadCrumbBox.h b/src/progs/ingenuity/BreadCrumbBox.h index aedfade0..35215e43 100644 --- a/src/progs/ingenuity/BreadCrumbBox.h +++ b/src/progs/ingenuity/BreadCrumbBox.h @@ -44,6 +44,9 @@ public: private: void breadcrumb_clicked(BreadCrumb* crumb); + + void object_removed(const Path& path); + void object_renamed(const Path& old_path, const Path& new_path); Path _active_path; Path _full_path; diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp index 16b2adea..df95f3c3 100644 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ b/src/progs/ingenuity/ConnectWindow.cpp @@ -25,9 +25,11 @@ #include "OSCClientReceiver.h" #include "ThreadedSigClientInterface.h" #include "Store.h" +#include "ControllerFactory.h" #include "PatchController.h" #include "PatchModel.h" #include "App.h" +#include "WindowFactory.h" #ifdef MONOLITHIC_INGENUITY #include "engine/QueuedEngineInterface.h" #include "engine/Engine.h" @@ -349,10 +351,10 @@ ConnectWindow::gtk_callback() ++stage; } else if (stage == 7) { if (App::instance().store()->num_objects() > 0) { - CountedPtr<PatchModel> root = App::instance().store()->object("/"); + CountedPtr<PatchModel> root = PtrCast<PatchModel>(App::instance().store()->object("/")); assert(root); - PatchController* root_controller = new PatchController(root); - root_controller->show_patch_window(); + CountedPtr<PatchController> root_c = PtrCast<PatchController>(ControllerFactory::get_controller(root)); + App::instance().window_factory()->present(root_c); ++stage; } } else if (stage == 8) { diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp index 93a1cb5b..45218bdf 100644 --- a/src/progs/ingenuity/ControlGroups.cpp +++ b/src/progs/ingenuity/ControlGroups.cpp @@ -69,7 +69,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel : ControlGroup(panel, pm, separator), m_enabled(true), m_enable_signal(false), - m_name_label(pm->name(), 0.0, 0.0), + m_name_label(pm->path().name(), 0.0, 0.0), m_range_box(false, 0), m_range_label("<small>Range: </small>"), m_min_spinner(1.0, (pm->is_integer() ? 0 : 4)), // climb rate, digits @@ -90,7 +90,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel }*/ m_slider.property_draw_value() = false; - set_name(pm->name()); + set_name(pm->path().name()); m_name_label.property_use_markup() = true; m_range_label.property_use_markup() = true; @@ -305,10 +305,10 @@ IntegerControlGroup::IntegerControlGroup(ControlPanel* panel, CountedPtr<PortMod : ControlGroup(panel, pm, separator), m_enable_signal(false), m_alignment(0.5, 0.5, 0.0, 0.0), - m_name_label(pm->name()), + m_name_label(pm->path().name()), m_spinner(1.0, 0) { - set_name(pm->name()); + set_name(pm->path().name()); m_spinner.set_range(-99999, 99999); m_spinner.set_value(m_port_model->value()); @@ -379,9 +379,9 @@ ToggleControlGroup::ToggleControlGroup(ControlPanel* panel, CountedPtr<PortModel : ControlGroup(panel, pm, separator), m_enable_signal(false), m_alignment(0.5, 0.5, 0.0, 0.0), - m_name_label(pm->name()) + m_name_label(pm->path().name()) { - set_name(pm->name()); + set_name(pm->path().name()); set_value(m_port_model->value()); m_checkbutton.signal_toggled().connect( diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp index 57ac7824..90d17c8a 100644 --- a/src/progs/ingenuity/ControlPanel.cpp +++ b/src/progs/ingenuity/ControlPanel.cpp @@ -67,14 +67,7 @@ ControlPanel::init(NodeController* node, size_t poly) for (PortModelList::const_iterator i = node_model->ports().begin(); i != node_model->ports().end(); ++i) { - // FIXME: - if (*i) { - PortController* pc = (PortController*)((*i)->controller()); - assert(pc != NULL); - add_port(pc); - } else { - cerr << "WTF?\n"; - } + add_port(*i); } m_callback_enabled = true; @@ -95,13 +88,9 @@ ControlPanel::find_port(const Path& path) const /** Add a control to the panel for the given port. */ void -ControlPanel::add_port(PortController* port) +ControlPanel::add_port(CountedPtr<PortModel> pm) { - assert(port); - assert(port->model()); - //assert(port->control_panel() == NULL); - - const CountedPtr<PortModel> pm = port->port_model(); + assert(pm); // Already have port, don't add another if (find_port(pm->path()) != NULL) @@ -131,8 +120,6 @@ ControlPanel::add_port(PortController* port) // pm->disconnection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::disconnection), pm)) } - //port->set_control_panel(this); - Gtk::Requisition controls_size; m_control_box->size_request(controls_size); m_ideal_size.first = controls_size.width; diff --git a/src/progs/ingenuity/ControlPanel.h b/src/progs/ingenuity/ControlPanel.h index a0cc819d..025468d5 100644 --- a/src/progs/ingenuity/ControlPanel.h +++ b/src/progs/ingenuity/ControlPanel.h @@ -59,7 +59,7 @@ public: ControlGroup* find_port(const Path& path) const; - void add_port(PortController* port); + void add_port(CountedPtr<PortModel> port); void remove_port(const Path& path); //void rename_port(const Path& old_path, const Path& new_path); diff --git a/src/progs/ingenuity/ControllerFactory.cpp b/src/progs/ingenuity/ControllerFactory.cpp new file mode 100644 index 00000000..b95bef5b --- /dev/null +++ b/src/progs/ingenuity/ControllerFactory.cpp @@ -0,0 +1,72 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ControllerFactory.h" +#include "NodeModel.h" +#include "PatchModel.h" +#include "PortModel.h" +#include "NodeController.h" +#include "PatchController.h" +#include "PortController.h" +#include "DSSIController.h" + +namespace Ingenuity { + + +CountedPtr<GtkObjectController> +ControllerFactory::get_controller(CountedPtr<ObjectModel> model) +{ + CountedPtr<PatchModel> patch_m = PtrCast<PatchModel>(model); + if (patch_m && patch_m->controller()) { + assert(dynamic_cast<PatchController*>(patch_m->controller().get())); + return PtrCast<GtkObjectController>(patch_m->controller()); + } else if (patch_m) { + CountedPtr<PatchController> pc(new PatchController(patch_m)); + patch_m->set_controller(pc); + return pc; + } + + CountedPtr<NodeModel> node_m = PtrCast<NodeModel>(model); + if (node_m && node_m->controller()) { + assert(dynamic_cast<NodeController*>(node_m->controller().get())); + return PtrCast<GtkObjectController>(node_m->controller()); + } else if (node_m) { + if (node_m->plugin()->type() == PluginModel::DSSI) { + CountedPtr<NodeController> nc(new DSSIController(node_m)); + node_m->set_controller(nc); + return nc; + } else { + CountedPtr<NodeController> nc(new NodeController(node_m)); + node_m->set_controller(nc); + return nc; + } + } + + CountedPtr<PortModel> port_m = PtrCast<PortModel>(model); + if (port_m && port_m->controller()) { + assert(dynamic_cast<PortController*>(port_m->controller().get())); + return PtrCast<GtkObjectController>(port_m->controller()); + } else if (port_m) { + CountedPtr<PortController> pc(new PortController(port_m)); + port_m->set_controller(pc); + return pc; + } + + return CountedPtr<GtkObjectController>(); +} + + +} // namespace Ingenuity diff --git a/src/progs/ingenuity/ControllerFactory.h b/src/progs/ingenuity/ControllerFactory.h new file mode 100644 index 00000000..7f48c262 --- /dev/null +++ b/src/progs/ingenuity/ControllerFactory.h @@ -0,0 +1,32 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONTROLLER_FACTORY_H +#define CONTROLLER_FACTORY_H + +#include "util/CountedPtr.h" +#include "GtkObjectController.h" + +namespace Ingenuity { + +class ControllerFactory { +public: + static CountedPtr<GtkObjectController> get_controller(CountedPtr<ObjectModel> model); +}; + +} + +#endif // CONTROLLER_FACTORY_H diff --git a/src/progs/ingenuity/DSSIModule.cpp b/src/progs/ingenuity/DSSIModule.cpp index ebcd114c..3d91e69b 100644 --- a/src/progs/ingenuity/DSSIModule.cpp +++ b/src/progs/ingenuity/DSSIModule.cpp @@ -29,8 +29,8 @@ DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node) void DSSIModule::on_double_click(GdkEventButton* ev) { - DSSIController* const dc = static_cast<DSSIController*>(m_node); - if (!dc->attempt_to_show_gui()) + DSSIController* dc = dynamic_cast<DSSIController*>(m_node); + if (!dc || ! dc->attempt_to_show_gui()) show_control_window(); } diff --git a/src/progs/ingenuity/GtkObjectController.cpp b/src/progs/ingenuity/GtkObjectController.cpp index 798dc1f4..ccaa3ca5 100644 --- a/src/progs/ingenuity/GtkObjectController.cpp +++ b/src/progs/ingenuity/GtkObjectController.cpp @@ -28,8 +28,6 @@ GtkObjectController::GtkObjectController(CountedPtr<ObjectModel> model) GtkObjectController::~GtkObjectController() { - assert(m_model->controller() == this); - m_model->set_controller(NULL); } } // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp index a847e0fd..dcc08fff 100644 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ b/src/progs/ingenuity/LoadPatchWindow.cpp @@ -29,7 +29,6 @@ namespace Ingenuity { LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject), - m_patch_controller(NULL), m_replace(true) { xml->get_widget("load_patch_poly_from_current_radio", m_poly_from_current_radio); @@ -66,7 +65,7 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gno * This function MUST be called before using the window in any way! */ void -LoadPatchWindow::patch_controller(PatchController* pc) +LoadPatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; } @@ -111,7 +110,7 @@ LoadPatchWindow::ok_clicked() if (m_replace) App::instance().engine()->clear_patch(m_patch_controller->model()->path()); - PatchModel* pm = new PatchModel(m_patch_controller->model()->path(), poly); + CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path(), poly)); pm->filename(get_filename()); pm->set_metadata("filename", get_filename()); pm->set_parent(m_patch_controller->patch_model()->parent()); diff --git a/src/progs/ingenuity/LoadPatchWindow.h b/src/progs/ingenuity/LoadPatchWindow.h index 4f72c6c1..e22b1c1a 100644 --- a/src/progs/ingenuity/LoadPatchWindow.h +++ b/src/progs/ingenuity/LoadPatchWindow.h @@ -21,6 +21,8 @@ #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -42,7 +44,7 @@ class LoadPatchWindow : public Gtk::FileChooserDialog public: LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_replace() { m_replace = true; } void set_merge() { m_replace = false; } @@ -56,8 +58,8 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; - bool m_replace; + CountedPtr<PatchController> m_patch_controller; + bool m_replace; Gtk::RadioButton* m_poly_from_current_radio; Gtk::RadioButton* m_poly_from_file_radio; diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 4b4290c4..2b59efef 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -20,7 +20,6 @@ #include <algorithm> #include <cctype> #include "PatchController.h" -#include "PatchView.h" #include "NodeModel.h" #include "App.h" #include "PatchWindow.h" @@ -28,6 +27,8 @@ #include "PatchModel.h" #include "Store.h" #include "ModelEngineInterface.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" using std::cout; using std::cerr; using std::endl; @@ -35,7 +36,6 @@ namespace Ingenuity { LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::Window(cobject), - m_patch_controller(NULL), m_has_shown(false), m_plugin_name_offset(0), m_new_module_x(0), @@ -135,7 +135,7 @@ LoadPluginWindow::name_changed() * This function MUST be called before using the window in any way! */ void -LoadPluginWindow::patch_controller(PatchController* pc) +LoadPluginWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; @@ -190,9 +190,8 @@ LoadPluginWindow::set_plugin_list(const std::map<string, CountedPtr<PluginModel> { m_plugins_liststore->clear(); - CountedPtr<PluginModel> plugin = NULL; for (std::map<string, CountedPtr<PluginModel> >::const_iterator i = m.begin(); i != m.end(); ++i) { - plugin = (*i).second; + CountedPtr<PluginModel> plugin = (*i).second; Gtk::TreeModel::iterator iter = m_plugins_liststore->append(); Gtk::TreeModel::Row row = *iter; @@ -307,12 +306,12 @@ LoadPluginWindow::add_clicked() dialog.run(); } else { - const string path = m_patch_controller->model()->base_path() + name; + const string path = m_patch_controller->model()->path().base() + name; NodeModel* nm = new NodeModel(plugin, path); nm->polyphonic(polyphonic); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } nm->x(m_new_module_x); diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h index 9d875358..1654b777 100644 --- a/src/progs/ingenuity/LoadPluginWindow.h +++ b/src/progs/ingenuity/LoadPluginWindow.h @@ -87,7 +87,7 @@ class LoadPluginWindow : public Gtk::Window public: LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_plugin_list(const std::map<string, CountedPtr<PluginModel> >& m); void set_next_module_location(double x, double y) @@ -113,7 +113,7 @@ private: void plugin_selection_changed(); string generate_module_name(int offset = 0); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; bool m_has_shown; // plugin list only populated on show to speed patch window creation Glib::RefPtr<Gtk::ListStore> m_plugins_liststore; diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp index 832c917f..486c92b4 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp @@ -33,7 +33,6 @@ namespace Ingenuity { LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject), - m_patch_controller(NULL), m_new_module_x(0), m_new_module_y(0) { @@ -74,7 +73,7 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP * This function MUST be called before using the window in any way! */ void -LoadSubpatchWindow::patch_controller(PatchController* pc) +LoadSubpatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; @@ -130,7 +129,7 @@ LoadSubpatchWindow::enable_poly_spinner() void LoadSubpatchWindow::ok_clicked() { - assert(m_patch_controller != NULL); + assert(m_patch_controller); assert(m_patch_controller->model()); const string filename = get_filename(); @@ -148,13 +147,13 @@ LoadSubpatchWindow::ok_clicked() poly = m_patch_controller->patch_model()->poly(); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } - PatchModel* pm = new PatchModel(m_patch_controller->model()->base_path() + name, poly); + CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path().base() + name, poly)); pm->filename(filename); - pm->set_parent(m_patch_controller->model().get()); + pm->set_parent(m_patch_controller->model()); pm->x(m_new_module_x); pm->y(m_new_module_y); //if (name == "") diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h index c4696628..e33880e8 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.h +++ b/src/progs/ingenuity/LoadSubpatchWindow.h @@ -21,6 +21,8 @@ #include "PluginModel.h" #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -39,7 +41,7 @@ class LoadSubpatchWindow : public Gtk::FileChooserDialog public: LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } @@ -56,7 +58,7 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; double m_new_module_x; double m_new_module_y; diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp index fed49603..0ca6f966 100644 --- a/src/progs/ingenuity/Loader.cpp +++ b/src/progs/ingenuity/Loader.cpp @@ -211,14 +211,14 @@ Loader::m_thread_function(void *) void -Loader::load_patch(PatchModel* model, bool wait, bool merge) +Loader::load_patch(CountedPtr<PatchModel> model, bool wait, bool merge) { set_event(new LoadPatchEvent(m_patch_librarian, model, wait, merge)); } void -Loader::save_patch(PatchModel* model, const string& filename, bool recursive) +Loader::save_patch(CountedPtr<PatchModel> model, const string& filename, bool recursive) { cout << "[Loader] Saving patch " << filename << endl; set_event(new SavePatchEvent(m_patch_librarian, model, filename, recursive)); diff --git a/src/progs/ingenuity/Loader.h b/src/progs/ingenuity/Loader.h index 7ff6f189..58c301af 100644 --- a/src/progs/ingenuity/Loader.h +++ b/src/progs/ingenuity/Loader.h @@ -53,15 +53,15 @@ protected: class LoadPatchEvent : public LoaderEvent { public: - LoadPatchEvent(PatchLibrarian* pl, PatchModel* model, bool wait, bool merge) + LoadPatchEvent(PatchLibrarian* pl, CountedPtr<PatchModel> model, bool wait, bool merge) : m_patch_librarian(pl), m_patch_model(model), m_wait(wait), m_merge(merge) {} virtual ~LoadPatchEvent() {} void execute(); private: - PatchLibrarian* m_patch_librarian; - PatchModel* m_patch_model; - bool m_wait; - bool m_merge; + PatchLibrarian* m_patch_librarian; + CountedPtr<PatchModel> m_patch_model; + bool m_wait; + bool m_merge; }; @@ -72,15 +72,15 @@ private: class SavePatchEvent : public LoaderEvent { public: - SavePatchEvent(PatchLibrarian* pl, PatchModel* pm, const string& filename, bool recursive) + SavePatchEvent(PatchLibrarian* pl, CountedPtr<PatchModel> pm, const string& filename, bool recursive) : m_patch_librarian(pl), m_patch_model(pm), m_filename(filename), m_recursive(recursive) {} virtual ~SavePatchEvent() {} void execute(); private: - PatchLibrarian* m_patch_librarian; - PatchModel* m_patch_model; - string m_filename; - bool m_recursive; + PatchLibrarian* m_patch_librarian; + CountedPtr<PatchModel> m_patch_model; + string m_filename; + bool m_recursive; }; /* @@ -129,8 +129,8 @@ public: void launch(); void exit() { m_thread_exit_flag = true; } - void load_patch(PatchModel* model, bool wait, bool merge); - void save_patch(PatchModel* model, const string& filename, bool recursive); + void load_patch(CountedPtr<PatchModel> model, bool wait, bool merge); + void save_patch(CountedPtr<PatchModel> model, const string& filename, bool recursive); //void load_session(const string& filename); //void save_session(const string& filename); diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am index 7cc405c1..5c4f5eed 100644 --- a/src/progs/ingenuity/Makefile.am +++ b/src/progs/ingenuity/Makefile.am @@ -43,6 +43,8 @@ ingenuity_SOURCES = \ PortController.cpp \ DSSIController.h \ DSSIController.cpp \ + ControllerFactory.h \ + ControllerFactory.cpp \ LoadPluginWindow.h \ LoadPluginWindow.cpp \ LoadPatchWindow.h \ @@ -61,6 +63,8 @@ ingenuity_SOURCES = \ PatchView.cpp \ PatchWindow.h \ PatchWindow.cpp \ + WindowFactory.h \ + WindowFactory.cpp \ OmFlowCanvas.h \ OmFlowCanvas.cpp \ ../../common/types.h \ diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp index 0b94e3d2..7f434445 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ b/src/progs/ingenuity/NewSubpatchWindow.cpp @@ -18,10 +18,10 @@ #include "ModelEngineInterface.h" #include "NewSubpatchWindow.h" #include "PatchController.h" -#include "PatchView.h" -#include "OmFlowCanvas.h" #include "NodeModel.h" #include "PatchModel.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" namespace Ingenuity { @@ -50,7 +50,7 @@ NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr * This function MUST be called before using the window in any way! */ void -NewSubpatchWindow::patch_controller(PatchController* pc) +NewSubpatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; } @@ -83,11 +83,11 @@ void NewSubpatchWindow::ok_clicked() { PatchModel* pm = new PatchModel( - m_patch_controller->model()->base_path() + m_name_entry->get_text(), + m_patch_controller->model()->path().base() + m_name_entry->get_text(), m_poly_spinbutton->get_value_as_int()); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h index 46fa9e1c..32560dde 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.h +++ b/src/progs/ingenuity/NewSubpatchWindow.h @@ -14,13 +14,14 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef NEWSUBPATCHWINDOW_H #define NEWSUBPATCHWINDOW_H #include "PluginModel.h" #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -39,7 +40,7 @@ class NewSubpatchWindow : public Gtk::Window public: NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } @@ -49,7 +50,7 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; double m_new_module_x; double m_new_module_y; diff --git a/src/progs/ingenuity/NodeController.cpp b/src/progs/ingenuity/NodeController.cpp index 1c340516..677bc8b5 100644 --- a/src/progs/ingenuity/NodeController.cpp +++ b/src/progs/ingenuity/NodeController.cpp @@ -25,6 +25,7 @@ #include "GtkObjectController.h" #include "NodeControlWindow.h" #include "OmModule.h" +#include "ControllerFactory.h" #include "PatchController.h" #include "OmFlowCanvas.h" #include "RenameWindow.h" @@ -47,17 +48,13 @@ NodeController::NodeController(CountedPtr<NodeModel> model) m_properties_window(NULL), m_bridge_port(NULL) { - assert(!model->controller()); - model->set_controller(this); - // Create port controllers for (PortModelList::const_iterator i = node_model()->ports().begin(); i != node_model()->ports().end(); ++i) { assert(!(*i)->controller()); assert((*i)->parent()); assert((*i)->parent().get() == node_model().get()); - // FIXME: leak - PortController* const pc = new PortController(*i); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i)); assert((*i)->controller() == pc); // PortController() does this } @@ -92,6 +89,7 @@ NodeController::NodeController(CountedPtr<NodeModel> model) } model->new_port_sig.connect(sigc::mem_fun(this, &NodeController::add_port)); + model->destroyed_sig.connect(sigc::mem_fun(this, &NodeController::destroy)); } @@ -102,6 +100,13 @@ NodeController::~NodeController() void +NodeController::destroy() +{ + delete this; +} + + +void NodeController::create_module(OmFlowCanvas* canvas) { if (!m_module || m_module->canvas() != canvas) { @@ -144,7 +149,7 @@ NodeController::set_path(const Path& new_path) i != node_model()->ports().end(); ++i) { GtkObjectController* const pc = (GtkObjectController*)((*i)->controller()); assert(pc != NULL); - pc->set_path(m_model->path().base_path() + pc->model()->name()); + pc->set_path(m_model->path().base() + pc->model()->name()); } // Handle bridge port, if this node represents one @@ -160,7 +165,7 @@ NodeController::set_path(const Path& new_path) */ } - +#if 0 void NodeController::destroy() { @@ -178,7 +183,7 @@ NodeController::destroy() //if (m_module != NULL) // delete m_module; } - +#endif void NodeController::metadata_update(const string& key, const string& value) @@ -197,8 +202,8 @@ NodeController::metadata_update(const string& key, const string& value) } } - if (m_bridge_port != NULL) - m_bridge_port->metadata_update(key, value); + //if (m_bridge_port != NULL) + // m_bridge_port->metadata_update(key, value); GtkObjectController::metadata_update(key, value); } @@ -209,12 +214,11 @@ NodeController::add_port(CountedPtr<PortModel> pm) { assert(pm->parent().get() == node_model().get()); assert(pm->parent() == node_model()); - assert(node_model()->get_port(pm->name()) == pm); + assert(node_model()->get_port(pm->path().name()) == pm); //cout << "[NodeController] Adding port " << pm->path() << endl; - // FIXME: leak - PortController* pc = new PortController(pm); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(pm)); assert(pm->controller() == pc); if (m_module != NULL) { @@ -259,10 +263,10 @@ NodeController::show_rename_window() Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("rename_win"); xml->get_widget_derived("rename_win", win); - PatchController* parent = ((PatchController*)node_model()->parent()->controller()); - assert(parent != NULL); + CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller()); + assert(parent); - if (parent->window() != NULL) + if (parent->window()) win->set_transient_for(*parent->window()); win->set_object(this); @@ -298,7 +302,7 @@ NodeController::on_menu_clone() clone_name = clone_name + clone_postfix; - const string path = node_model()->parent_patch()->base_path() + clone_name; + const string path = node_model()->parent_patch()->base() + clone_name; NodeModel* nm = new NodeModel(node_model()->plugin(), path); nm->polyphonic(node_model()->polyphonic()); nm->x(node_model()->x() + 20); @@ -324,36 +328,33 @@ NodeController::on_menu_disconnect_all() void NodeController::show_properties_window() { - PatchController* parent = ((PatchController*)node_model()->parent()->controller()); - assert(parent != NULL); + CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller()); + assert(parent); - if (m_properties_window == NULL) { + if (m_properties_window) { Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("node_properties_win"); xml->get_widget_derived("node_properties_win", m_properties_window); } - assert(m_properties_window != NULL); - assert(parent != NULL); + assert(m_properties_window); + assert(parent); m_properties_window->set_node(node_model()); - if (parent->window() != NULL) + if (parent->window()) m_properties_window->set_transient_for(*parent->window()); m_properties_window->show(); } /** Create all (visual) ports and add them to module (and resize it). + * FIXME: this doesn't belong here */ void NodeController::create_all_ports() { - assert(m_module != NULL); + assert(m_module); - PortController* pc = NULL; for (PortModelList::const_iterator i = node_model()->ports().begin(); i != node_model()->ports().end(); ++i) { - pc = dynamic_cast<PortController*>((*i)->controller()); - // FIXME: leak - if (pc == NULL) - pc = new PortController(*i); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i)); pc->create_port(m_module); } diff --git a/src/progs/ingenuity/NodeController.h b/src/progs/ingenuity/NodeController.h index 84ac09cd..c0ee6ea9 100644 --- a/src/progs/ingenuity/NodeController.h +++ b/src/progs/ingenuity/NodeController.h @@ -20,14 +20,13 @@ #include <string> #include <gtkmm.h> #include "util/Path.h" +#include "util/CountedPtr.h" #include "GtkObjectController.h" #include "NodeModel.h" using std::string; using namespace Ingen::Client; -template <class T> class CountedPtr; - namespace Ingen { namespace Client { class MetadataModel; class PortModel; @@ -49,10 +48,7 @@ class OmFlowCanvas; class NodeController : public GtkObjectController { public: - NodeController(CountedPtr<NodeModel> model); virtual ~NodeController(); - - virtual void destroy(); virtual void metadata_update(const string& key, const string& value); @@ -68,10 +64,10 @@ public: OmModule* module() { return m_module; } - void bridge_port(PortController* port) { m_bridge_port = port; } - PortController* as_port() { return m_bridge_port; } + //void bridge_port(PortController* port) { m_bridge_port = port; } + //PortController* as_port() { return m_bridge_port; } - CountedPtr<NodeModel> node_model() { return m_model; } + CountedPtr<NodeModel> node_model() { return PtrCast<NodeModel>(m_model); } NodeControlWindow* control_window() { return m_control_window; } void control_window(NodeControlWindow* cw) { m_control_window = cw; } @@ -89,6 +85,12 @@ public: virtual void disable_controls_menuitem(); protected: + friend class ControllerFactory; + + NodeController(CountedPtr<NodeModel> model); + + virtual void destroy(); + virtual void add_port(CountedPtr<PortModel> pm); void create_all_ports(); diff --git a/src/progs/ingenuity/NodePropertiesWindow.cpp b/src/progs/ingenuity/NodePropertiesWindow.cpp index 2ee79527..a6bdfce1 100644 --- a/src/progs/ingenuity/NodePropertiesWindow.cpp +++ b/src/progs/ingenuity/NodePropertiesWindow.cpp @@ -26,7 +26,6 @@ using std::string; NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) : Gtk::Window(cobject) -, m_node_model(NULL) { glade_xml->get_widget("node_properties_path_label", m_node_path_label); glade_xml->get_widget("node_properties_polyphonic_checkbutton", m_node_polyphonic_toggle); diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp index a6e3617e..d530bca0 100644 --- a/src/progs/ingenuity/OmFlowCanvas.cpp +++ b/src/progs/ingenuity/OmFlowCanvas.cpp @@ -101,22 +101,21 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) if (src->model()->type() == PortModel::MIDI && dst->model()->type() == PortModel::CONTROL) { - // FIXME: leaks? - PluginModel* pm = new PluginModel(PluginModel::Internal, "", "midi_control_in", ""); - NodeModel* nm = new NodeModel(pm, m_patch_controller->model()->base_path() - + src->name() + "-" + dst->name()); + CountedPtr<PluginModel> pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); + CountedPtr<NodeModel> nm(new NodeModel(pm, m_patch_controller->model()->path().base() + + src->name() + "-" + dst->name())); nm->x(dst->module()->property_x() - dst->module()->width() - 20); nm->y(dst->module()->property_y()); - App::instance().engine()->create_node_from_model(nm); + App::instance().engine()->create_node_from_model(nm.get()); App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); App::instance().engine()->midi_learn(nm->path()); // Set control node range to port's user range - App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Min", + App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", atof(dst->model()->get_metadata("user-min").c_str())); - App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Max", + App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", atof(dst->model()->get_metadata("user-max").c_str())); } else { App::instance().engine()->connect(src->model()->path(), @@ -195,7 +194,7 @@ OmFlowCanvas::generate_port_name(const string& base) { void OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_output) { - const Path& path = m_patch_controller->path().base_path() + generate_port_name(name); + const Path& path = m_patch_controller->path().base() + generate_port_name(name); App::instance().engine()->create_port(path, type, is_output); char temp_buf[16]; @@ -224,7 +223,7 @@ void OmFlowCanvas::menu_add_audio_input() { string name = "audio_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "AUDIO", false); } @@ -232,7 +231,7 @@ void OmFlowCanvas::menu_add_audio_output() { string name = "audio_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "AUDIO", true); } @@ -240,7 +239,7 @@ void OmFlowCanvas::menu_add_control_input() { string name = "control_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "CONTROL", false); } @@ -248,7 +247,7 @@ void OmFlowCanvas::menu_add_control_output() { string name = "control_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "CONTROL", true); } @@ -256,7 +255,7 @@ void OmFlowCanvas::menu_add_midi_input() { string name = "midi_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "MIDI", false); } @@ -264,7 +263,7 @@ void OmFlowCanvas::menu_add_midi_output() { string name = "midi_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "MIDI", true); } */ diff --git a/src/progs/ingenuity/OmModule.cpp b/src/progs/ingenuity/OmModule.cpp index e34665a7..dd6f3da5 100644 --- a/src/progs/ingenuity/OmModule.cpp +++ b/src/progs/ingenuity/OmModule.cpp @@ -31,11 +31,11 @@ namespace Ingenuity { OmModule::OmModule(OmFlowCanvas* canvas, NodeController* node) -: LibFlowCanvas::Module(canvas, node->node_model()->name(), +: LibFlowCanvas::Module(canvas, node->node_model()->path().name(), node->node_model()->x(), node->node_model()->y()), m_node(node) { - assert(m_node != NULL); + assert(m_node); /*if (node_model()->polyphonic() && node_model()->parent() != NULL && node_model()->parent_patch()->poly() > 1) { diff --git a/src/progs/ingenuity/OmModule.h b/src/progs/ingenuity/OmModule.h index 2a31a84f..a3d56187 100644 --- a/src/progs/ingenuity/OmModule.h +++ b/src/progs/ingenuity/OmModule.h @@ -21,6 +21,7 @@ #include <string> #include <libgnomecanvasmm.h> #include <flowcanvas/Module.h> +#include "util/CountedPtr.h" #include "NodeController.h" using std::string; diff --git a/src/progs/ingenuity/OmPatchPort.cpp b/src/progs/ingenuity/OmPatchPort.cpp index b900a40c..0d3acf76 100644 --- a/src/progs/ingenuity/OmPatchPort.cpp +++ b/src/progs/ingenuity/OmPatchPort.cpp @@ -29,7 +29,7 @@ using namespace Ingen::Client; namespace Ingenuity { OmPatchPort::OmPatchPort(OmPortModule* module, CountedPtr<PortModel> pm) -: Port(module, pm->name(), !pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), +: Port(module, pm->path().name(), !pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), m_port_model(pm) { assert(module); diff --git a/src/progs/ingenuity/OmPort.cpp b/src/progs/ingenuity/OmPort.cpp index 69406b97..e2a32652 100644 --- a/src/progs/ingenuity/OmPort.cpp +++ b/src/progs/ingenuity/OmPort.cpp @@ -29,7 +29,7 @@ using namespace Ingen::Client; namespace Ingenuity { OmPort::OmPort(Module* module, CountedPtr<PortModel> pm) -: Port(module, pm->name(), pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), +: Port(module, pm->path().name(), pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), m_port_model(pm) { assert(module); diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp index 6ef90d32..8dee4cd2 100644 --- a/src/progs/ingenuity/PatchController.cpp +++ b/src/progs/ingenuity/PatchController.cpp @@ -44,6 +44,7 @@ #include "DSSIController.h" #include "PatchModel.h" #include "Store.h" +#include "ControllerFactory.h" using std::cerr; using std::cout; using std::endl; using namespace Ingen::Client; @@ -55,26 +56,12 @@ PatchController::PatchController(CountedPtr<PatchModel> model) : NodeController(model), m_properties_window(NULL), m_window(NULL), - m_patch_view(NULL), m_patch_model(model), m_module_x(0), m_module_y(0) { - assert(model->path().length() > 0); - assert(model->controller() == this); // NodeController() does this - assert(m_patch_model == model); - -/* FIXME if (model->path() != "/") { - PatchController* parent = Store::instance().patch(model->path().parent()); - if (parent != NULL) - parent->add_subpatch(this); - else - cerr << "[PatchController] " << path() << " ERROR: Parent not found." << endl; - }*/ - //model->new_port_sig.connect(sigc::mem_fun(this, &PatchController::add_port)); model->new_node_sig.connect(sigc::mem_fun(this, &PatchController::add_node)); - model->removed_node_sig.connect(sigc::mem_fun(this, &PatchController::remove_node)); model->new_connection_sig.connect(sigc::mem_fun(this, &PatchController::connection)); model->removed_connection_sig.connect(sigc::mem_fun(this, &PatchController::disconnection)); } @@ -82,27 +69,23 @@ PatchController::PatchController(CountedPtr<PatchModel> model) PatchController::~PatchController() { - if (m_patch_view != NULL) { + if (m_patch_view) { claim_patch_view(); - m_patch_view->hide(); - delete m_patch_view; - m_patch_view = NULL; } - if (m_control_window != NULL) { + if (m_control_window) { m_control_window->hide(); delete m_control_window; m_control_window = NULL; } - if (m_window != NULL) { - m_window->hide(); + if (m_window) { delete m_window; m_window = NULL; } } - +#if 0 void PatchController::clear() { @@ -113,8 +96,8 @@ PatchController::clear() size_t remaining = nodes.size(); while (remaining > 0) { - NodeController* const nc = (NodeController*)(*nodes.begin()).second->controller(); - assert(nc != NULL); + CountedPtr<NodeController> nc = (*nodes.begin()).second->controller(); + assert(nc); nc->destroy(); assert(nodes.size() == remaining - 1); --remaining; @@ -123,13 +106,14 @@ PatchController::clear() patch_model()->clear(); - if (m_patch_view != NULL) { - assert(m_patch_view->canvas() != NULL); + if (m_patch_view) { + assert(m_patch_view->canvas()); m_patch_view->canvas()->destroy(); } } +#endif - +#if 0 void PatchController::destroy() { @@ -139,9 +123,8 @@ PatchController::destroy() size_t remaining = nodes.size(); while (remaining > 0) { - NodeController* const nc = (NodeController*) - (*nodes.begin()).second->controller(); - assert(nc != NULL); + CountedPtr<NodeController> nc = (*nodes.begin()).second->controller(); + assert(nc); nc->destroy(); assert(nodes.size() == remaining - 1); --remaining; @@ -158,14 +141,22 @@ PatchController::destroy() //Store::instance().remove_object(this); // Delete self from parent (this will delete model) - /*if (patch_model()->parent() != NULL) { + /*if (patch_model()->parent()) { PatchController* const parent = (PatchController*)patch_model()->parent()->controller(); - assert(parent != NULL); + assert(parent); parent->remove_node(name()); } else { //delete m_model; }*/ } +#endif + + +void +PatchController::destroy() +{ + delete this; +} void @@ -189,25 +180,25 @@ PatchController::set_path(const Path& new_path) i != patch_model()->nodes().end(); ++i) { const NodeModel* const nm = (*i).second.get(); assert(nm ); - NodeController* const nc = ((NodeController*)nm->controller()); + CountedPtr<NodeController> nc = PtrCast<NodeController>(nm->controller()); assert(nc ); - nc->set_path(new_path.base_path() + nc->node_model()->name()); + nc->set_path(new_path.base() + nc->node_model()->path().name()); } #ifdef DEBUG // Be sure ports were renamed by their bridge nodes for (PortModelList::const_iterator i = node_model()->ports().begin(); i != node_model()->ports().end(); ++i) { - GtkObjectController* const pc = (GtkObjectController*)((*i)->controller()); - assert(pc ); + CountedPtr<GtkObjectController> pc = PtrCast<GtkObjectController>((*i)->controller()); + assert(pc); assert(pc->path().parent()== new_path); } #endif App::instance().patch_tree()->patch_renamed(old_path, new_path); - if (m_window) - m_window->patch_renamed(new_path); + /*if (m_window) + m_window->patch_renamed(new_path);*/ if (m_control_window) m_control_window->set_title(new_path + " Controls"); @@ -215,11 +206,10 @@ PatchController::set_path(const Path& new_path) if (m_module) m_module->name(new_path.name()); - PatchController* parent = dynamic_cast<PatchController*>( - patch_model()->parent()->controller()); + CountedPtr<PatchController> parent = PtrCast<PatchController>(patch_model()->parent()->controller()); - if (parent && parent->window()) - parent->window()->node_renamed(old_path, new_path); + //if (parent && parent->window()) + // parent->window()->node_renamed(old_path, new_path); //remove_from_store(); GtkObjectController::set_path(new_path); @@ -249,11 +239,12 @@ PatchController::create_module(OmFlowCanvas* canvas) //cerr << "Creating patch module " << m_model->path() << endl; - assert(canvas != NULL); + assert(canvas); assert(m_module == NULL); assert(!m_patch_view || canvas != m_patch_view->canvas()); - m_module = new SubpatchModule(canvas, this); + // FIXME: weirdo using model->controller() to get shared_ptr_from_this.. + m_module = new SubpatchModule(canvas, PtrCast<PatchController>(m_model->controller())); create_all_ports(); } @@ -261,23 +252,26 @@ PatchController::create_module(OmFlowCanvas* canvas) } -void -PatchController::create_view() +CountedPtr<PatchView> +PatchController::get_view() { - assert(m_patch_view == NULL); + if (m_patch_view) + return m_patch_view; Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget_derived("patch_view_vbox", m_patch_view); - assert(m_patch_view != NULL); + PatchView* pv = NULL; + xml->get_widget_derived("patch_view_vbox", pv); + assert(pv); + m_patch_view = CountedPtr<PatchView>(pv); m_patch_view->patch_controller(this); - assert(m_patch_view->canvas() != NULL); + assert(m_patch_view->canvas()); // Create modules for nodes for (NodeModelMap::const_iterator i = patch_model()->nodes().begin(); i != patch_model()->nodes().end(); ++i) { - NodeModel* const nm = (*i).second.get(); + const CountedPtr<NodeModel> nm = (*i).second; string val = nm->get_metadata("module-x"); if (val != "") @@ -294,9 +288,7 @@ PatchController::create_view() nm->y(y); } - NodeController* nc = ((NodeController*)nm->controller()); - if (!nc) - nc = create_controller_for_node(nm); + CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(nm)); assert(nc); assert(nm->controller() == nc); @@ -308,7 +300,7 @@ PatchController::create_view() // Create pseudo modules for ports (ports on this canvas, not on our module) for (PortModelList::const_iterator i = patch_model()->ports().begin(); i != patch_model()->ports().end(); ++i) { - PortController* const pc = dynamic_cast<PortController*>((*i)->controller()); + CountedPtr<PortController> pc = PtrCast<PortController>((*i)->controller()); assert(pc); pc->create_module(m_patch_view->canvas()); } @@ -323,6 +315,8 @@ PatchController::create_view() // Set run checkbox if (patch_model()->enabled()) m_patch_view->enable(); + + return m_patch_view; } @@ -345,7 +339,7 @@ PatchController::show_properties_window() void PatchController::connection(CountedPtr<ConnectionModel> cm) { - if (m_patch_view != NULL) { + if (m_patch_view) { // Deal with port "anonymous nodes" for this patch's own ports... const Path& src_parent_path = cm->src_port_path().parent(); @@ -365,97 +359,50 @@ PatchController::connection(CountedPtr<ConnectionModel> cm) } -NodeController* -PatchController::create_controller_for_node(CountedPtr<NodeModel> node) -{ - assert(!node->controller()); - NodeController* nc = NULL; - - CountedPtr<PatchModel> patch(node); - if (patch) { - assert(patch == node); - assert(patch->parent() == m_patch_model); - nc = new PatchController(patch); - } else { - assert(node->plugin()); - if (node->plugin()->type() == PluginModel::DSSI) - nc = new DSSIController(node); - else - nc = new NodeController(node); - } - - assert(node->controller() == nc); - return nc; -} - - /** Add a child node to this patch. * * This is for plugin nodes and patches, and is responsible for creating the - * GtkObjectController for @a object (and through that the View if necessary) + * GtkObjectController for @a node (and through that the View if necessary) */ void -PatchController::add_node(CountedPtr<NodeModel> object) +PatchController::add_node(CountedPtr<NodeModel> node) { - assert(object); - assert(object->parent() == m_patch_model); - assert(patch_model()->get_node(object->name())); - - /*if (patch_model()->get_node(nm->name()) != NULL) { - cerr << "Ignoring existing\n"; - // Node already exists, ignore - //delete nm; - } else {*/ - + assert(node); + assert(node->parent().get() == m_patch_model.get()); + assert(node->parent() == m_patch_model); + assert(patch_model()->get_node(node->path().name())); - CountedPtr<NodeModel> node(object); - if (node) { - assert(node->parent() == m_patch_model); + assert(node->parent() == m_patch_model); - NodeController* nc = create_controller_for_node(node); - assert(nc); - assert(node->controller() == nc); + CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(node)); + assert(nc); + assert(node->controller() == nc); - if (m_patch_view != NULL) { - double x, y; - m_patch_view->canvas()->get_new_module_location(x, y); - node->x(x); - node->y(y); - - // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) - float old_zoom = m_patch_view->canvas()->get_zoom(); - if (old_zoom != 1.0) - m_patch_view->canvas()->set_zoom(1.0); - - nc->create_module(m_patch_view->canvas()); - assert(nc->module()); - nc->module()->resize(); - - // Reset zoom - if (old_zoom != 1.0) { - m_patch_view->canvas()->set_zoom(old_zoom); - nc->module()->zoom(old_zoom); - } - } + if (m_patch_view) { + double x, y; + m_patch_view->canvas()->get_new_module_location(x, y); + node->x(x); + node->y(y); - } -} + // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) + float old_zoom = m_patch_view->canvas()->get_zoom(); + if (old_zoom != 1.0) + m_patch_view->canvas()->set_zoom(1.0); + nc->create_module(m_patch_view->canvas()); + assert(nc->module()); + nc->module()->resize(); -/** Removes a node from this patch. - */ -void -PatchController::remove_node(const string& name) -{ - assert(name.find("/") == string::npos); - assert(!m_patch_model->get_node(name)); + // Reset zoom + if (old_zoom != 1.0) { + m_patch_view->canvas()->set_zoom(old_zoom); + nc->module()->zoom(old_zoom); + } + } - // Update breadcrumbs if necessary - if (m_window) - m_window->node_removed(name); } - +#if 0 /** Add a port to this patch. * * Will add a port to the subpatch module and the control window, if they @@ -466,34 +413,33 @@ PatchController::add_port(CountedPtr<PortModel> pm) { assert(pm); assert(pm->parent() == m_patch_model); - assert(patch_model()->get_port(pm->name())); + assert(patch_model()->get_port(pm->path().name())); //cerr << "[PatchController] Adding port " << pm->path() << endl; - /*if (patch_model()->get_port(pm->name())) { + /*if (patch_model()->get_port(pm->path().name())) { cerr << "[PatchController] Ignoring duplicate port " << pm->path() << endl; return; }*/ //node_model()->add_port(pm); - // FIXME: leak - PortController* pc = new PortController(pm); + CountedPtr<PortController> pc = ControllerFactory::get_controller(pm); // Handle bridge ports/nodes (this is uglier than it should be) /*NodeController* nc = (NodeController*)Store::instance().node(pm->path())->controller(); - if (nc != NULL) + if (nc) nc->bridge_port(pc); */ // Create port on this patch's module (if there is one) - if (m_module != NULL) { + if (m_module) { pc->create_port(m_module); m_module->resize(); } // Create port's (pseudo) module on this patch's canvas (if there is one) - if (m_patch_view != NULL) { + if (m_patch_view) { // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) float old_zoom = m_patch_view->canvas()->get_zoom(); @@ -505,9 +451,9 @@ PatchController::add_port(CountedPtr<PortModel> pm) pc->module()->zoom(old_zoom); } - if (m_control_window != NULL) { - assert(m_control_window->control_panel() != NULL); - m_control_window->control_panel()->add_port(pc); + if (m_control_window) { + assert(m_control_window->control_panel()); + m_control_window->control_panel()->add_port(pm); m_control_window->resize(); } @@ -528,9 +474,9 @@ PatchController::remove_port(const Path& path, bool resize_module) //cerr << "[PatchController] Removing port " << path << endl; /* FIXME - if (m_control_panel != NULL) { + if (m_control_panel) { m_control_panel->remove_port(path); - if (m_control_window != NULL) { + if (m_control_window) { assert(m_control_window->control_panel() == m_control_panel); m_control_window->resize(); } @@ -546,7 +492,7 @@ PatchController::remove_port(const Path& path, bool resize_module) if (!has_control_inputs()) disable_controls_menuitem(); } - +#endif void PatchController::disconnection(const Path& src_port_path, const Path& dst_port_path) @@ -571,32 +517,13 @@ PatchController::disconnection(const Path& src_port_path, const Path& dst_port_p /* // Enable control slider in destination node control window PortController* p = (PortController)Store::instance().port(dst_port_path)->controller(); - assert(p != NULL); + assert(p); - if (p->control_panel() != NULL) + if (p->control_panel()) p->control_panel()->enable_port(p->path()); */ } -void -PatchController::show_patch_window() -{ - if (m_window == NULL) { - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - - xml->get_widget_derived("patch_win", m_window); - assert(m_window != NULL); - - if (m_patch_view == NULL) - create_view(); - - m_window->patch_controller(this); - } - - assert(m_window != NULL); - m_window->present(); -} - /** Become the parent of the patch view. * @@ -605,7 +532,7 @@ PatchController::show_patch_window() void PatchController::claim_patch_view() { - assert(m_patch_view != NULL); + assert(m_patch_view); m_patch_view->hide(); m_patch_view->reparent(m_patch_view_bin); @@ -625,24 +552,4 @@ PatchController::show_control_window() } -void -PatchController::enable_controls_menuitem() -{ - if (m_window != NULL) - m_window->menu_view_control_window()->property_sensitive() = true; - - NodeController::enable_controls_menuitem(); -} - - -void -PatchController::disable_controls_menuitem() -{ - if (m_window != NULL) - m_window->menu_view_control_window()->property_sensitive() = false; - - NodeController::disable_controls_menuitem(); -} - - } // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchController.h b/src/progs/ingenuity/PatchController.h index a5370826..2ee01738 100644 --- a/src/progs/ingenuity/PatchController.h +++ b/src/progs/ingenuity/PatchController.h @@ -19,9 +19,9 @@ #include <string> #include <gtkmm.h> +#include "util/CountedPtr.h" #include "NodeController.h" #include "PatchModel.h" -template <class T> class CountedPtr; namespace Ingen { namespace Client { class PatchModel; @@ -60,7 +60,6 @@ class NodeController; class PatchController : public NodeController { public: - PatchController(CountedPtr<PatchModel> model); virtual ~PatchController(); /* @@ -68,16 +67,14 @@ public: virtual void remove_from_store(); */ - virtual void destroy(); - virtual void metadata_update(const string& key, const string& value); - virtual void add_port(CountedPtr<PortModel> pm); - virtual void remove_port(const Path& path, bool resize_module); + //virtual void add_port(CountedPtr<PortModel> pm); + //virtual void remove_port(const Path& path, bool resize_module); void connection(CountedPtr<ConnectionModel> cm); void disconnection(const Path& src_port_path, const Path& dst_port_path); - void clear(); + //void clear(); void show_control_window(); void show_properties_window(); @@ -86,35 +83,31 @@ public: void claim_patch_view(); void create_module(OmFlowCanvas* canvas); - void create_view(); - PatchView* view() const { return m_patch_view; } + CountedPtr<PatchView> get_view(); PatchWindow* window() const { return m_window; } void window(PatchWindow* pw) { m_window = pw; } - inline string name() const { return m_model->name(); } - inline const Path& path() const { return m_model->path(); } - void set_path(const Path& new_path); //void enable(); //void disable(); - CountedPtr<PatchModel> patch_model() const { return m_patch_model; } + const CountedPtr<PatchModel> patch_model() const { return m_patch_model; } - void enable_controls_menuitem(); - void disable_controls_menuitem(); - private: - void add_node(CountedPtr<NodeModel> object); - void remove_node(const string& name); + friend class ControllerFactory; + PatchController(CountedPtr<PatchModel> model); - NodeController* create_controller_for_node(CountedPtr<NodeModel> node); + void destroy(); + void add_node(CountedPtr<NodeModel> object); + PatchPropertiesWindow* m_properties_window; - PatchWindow* m_window; ///< Patch Window currently showing m_patch_view - PatchView* m_patch_view; ///< View (canvas) of this patch + // FIXME: remove these + PatchWindow* m_window; ///< Patch Window currently showing m_patch_view + CountedPtr<PatchView> m_patch_view; ///< View (canvas) of this patch CountedPtr<PatchModel> m_patch_model; diff --git a/src/progs/ingenuity/PatchPropertiesWindow.cpp b/src/progs/ingenuity/PatchPropertiesWindow.cpp index ec440c15..2271cc21 100644 --- a/src/progs/ingenuity/PatchPropertiesWindow.cpp +++ b/src/progs/ingenuity/PatchPropertiesWindow.cpp @@ -24,7 +24,6 @@ using std::string; PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) : Gtk::Window(cobject) -, m_patch_model(NULL) { glade_xml->get_widget("properties_author_entry", m_author_entry); glade_xml->get_widget("properties_description_textview", m_textview); diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp index 0f8c947a..090aba18 100644 --- a/src/progs/ingenuity/PatchTreeWindow.cpp +++ b/src/progs/ingenuity/PatchTreeWindow.cpp @@ -23,6 +23,7 @@ #include "Store.h" #include "SubpatchModule.h" #include "PatchModel.h" +#include "WindowFactory.h" #include "util/Path.h" namespace Ingenuity { @@ -74,14 +75,14 @@ PatchTreeWindow::init(Store& store) void PatchTreeWindow::new_object(CountedPtr<ObjectModel> object) { - CountedPtr<PatchModel> patch = object; - if (patch && dynamic_cast<PatchController*>(patch->controller())) - add_patch(dynamic_cast<PatchController*>(patch->controller())); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object); + if (patch) + add_patch(PtrCast<PatchController>(patch->controller())); } void -PatchTreeWindow::add_patch(PatchController* pc) +PatchTreeWindow::add_patch(CountedPtr<PatchController> pc) { const CountedPtr<PatchModel> pm = pc->patch_model(); @@ -89,7 +90,7 @@ PatchTreeWindow::add_patch(PatchController* pc) Gtk::TreeModel::iterator iter = m_patch_treestore->append(); Gtk::TreeModel::Row row = *iter; if (pm->path() == "/") { - CountedPtr<OSCEngineSender> osc_sender = App::instance().engine(); + CountedPtr<OSCEngineSender> osc_sender = PtrCast<OSCEngineSender>(App::instance().engine()); string root_name = osc_sender ? osc_sender->engine_url() : "Internal"; // Hack off trailing '/' if it's there (ugly) //if (root_name.substr(root_name.length()-1,1) == "/") @@ -130,10 +131,8 @@ PatchTreeWindow::remove_patch(const Path& path) Gtk::TreeModel::iterator PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) { - PatchController* pc = NULL; - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - pc = (*c)[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = (*c)[m_patch_tree_columns.patch_controller_col]; if (pc->model()->path() == path) { return c; } else if ((*c)->children().size() > 0) { @@ -152,7 +151,7 @@ PatchTreeWindow::event_patch_selected() Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; } } */ @@ -166,8 +165,8 @@ PatchTreeWindow::show_patch_menu(GdkEventButton* ev) Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; - if (pc != NULL) + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; + if (pc) pc->show_menu(ev); } } @@ -178,9 +177,9 @@ PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::Tr { Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path); Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; - pc->show_patch_window(); + App::instance().window_factory()->present(pc); } @@ -191,10 +190,10 @@ PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path); Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; Glib::ustring patch_path = pc->model()->path(); - assert(pc != NULL); + assert(pc); if ( ! pc->patch_model()->enabled()) { if (m_enable_signal) diff --git a/src/progs/ingenuity/PatchTreeWindow.h b/src/progs/ingenuity/PatchTreeWindow.h index a43703a7..d23c4e54 100644 --- a/src/progs/ingenuity/PatchTreeWindow.h +++ b/src/progs/ingenuity/PatchTreeWindow.h @@ -50,7 +50,7 @@ public: void patch_disabled(const Path& path); void patch_renamed(const Path& old_path, const Path& new_path); - void add_patch(PatchController* pc); + void add_patch(CountedPtr<PatchController> pc); void remove_patch(const Path& path); void show_patch_menu(GdkEventButton* ev); @@ -68,9 +68,9 @@ protected: PatchTreeModelColumns() { add(name_col); add(enabled_col); add(patch_controller_col); } - Gtk::TreeModelColumn<Glib::ustring> name_col; - Gtk::TreeModelColumn<bool> enabled_col; - Gtk::TreeModelColumn<PatchController*> patch_controller_col; + Gtk::TreeModelColumn<Glib::ustring> name_col; + Gtk::TreeModelColumn<bool> enabled_col; + Gtk::TreeModelColumn<CountedPtr<PatchController> > patch_controller_col; }; bool m_enable_signal; diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp index bce44369..90c0083e 100644 --- a/src/progs/ingenuity/PatchView.cpp +++ b/src/progs/ingenuity/PatchView.cpp @@ -52,36 +52,34 @@ PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::X xml->get_widget("patch_view_zoom_full_but", _zoom_full_but); xml->get_widget("patch_view_zoom_normal_but", _zoom_normal_but); xml->get_widget("patch_view_scrolledwindow", _canvas_scrolledwindow); - - _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); } -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ void PatchView::patch_controller(PatchController* pc) { - //m_patch = new PatchController(pm, controller); _patch = pc; - _canvas = new OmFlowCanvas(pc, 1600*2, 1200*2); _canvas_scrolledwindow->add(*_canvas); - //_canvas->show(); - //_canvas_scrolledwindow->show(); _poly_spin->set_value(pc->patch_model()->poly()); - + _destroy_but->set_sensitive(pc->path() != "/"); //_description_window->patch_model(pc->model()); + pc->patch_model()->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); pc->patch_model()->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); + + _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); + + _clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked)); + + _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun( + static_cast<FlowCanvas*>(_canvas), &FlowCanvas::set_zoom), 1.0)); - _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::set_zoom), 1.0)); - _zoom_full_but->signal_clicked().connect(sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::zoom_full)); + _zoom_full_but->signal_clicked().connect( + sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::zoom_full)); } @@ -108,6 +106,11 @@ PatchView::process_toggled() } } +void +PatchView::clear_clicked() +{ + App::instance().engine()->clear_patch(_patch->path()); +} void PatchView::enable() diff --git a/src/progs/ingenuity/PatchView.h b/src/progs/ingenuity/PatchView.h index 3c507b94..59e16aad 100644 --- a/src/progs/ingenuity/PatchView.h +++ b/src/progs/ingenuity/PatchView.h @@ -63,7 +63,7 @@ public: PatchController* patch_controller() const { return _patch; } Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } void show_control_window(); - void process_toggled(); + void enable(); void disable(); @@ -71,6 +71,9 @@ public: void zoom_full(); private: + void process_toggled(); + void clear_clicked(); + PatchController* _patch; OmFlowCanvas* _canvas; diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index 2dfcded0..c395c265 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -20,7 +20,6 @@ #include <fstream> #include "App.h" #include "ModelEngineInterface.h" -#include "PatchView.h" #include "OmFlowCanvas.h" #include "PatchController.h" #include "LoadPluginWindow.h" @@ -37,13 +36,15 @@ #include "Store.h" #include "ConnectWindow.h" #include "Loader.h" +#include "ControllerFactory.h" +#include "WindowFactory.h" +#include "PatchView.h" namespace Ingenuity { PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::Window(cobject), - m_patch(NULL), m_load_plugin_window(NULL), m_new_subpatch_window(NULL), m_enable_signal(true), @@ -75,6 +76,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad xml->get_widget("patch_view_patch_tree_window_menuitem", m_menu_view_patch_tree_window); xml->get_widget("patch_help_about_menuitem", m_menu_help_about); + // FIXME: these shouldn't be loaded here xml->get_widget_derived("load_plugin_win", m_load_plugin_window); xml->get_widget_derived("new_subpatch_win", m_new_subpatch_window); xml->get_widget_derived("load_patch_win", m_load_patch_window); @@ -96,8 +98,6 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad sigc::mem_fun(this, &PatchWindow::event_save)); m_menu_save_as->signal_activate().connect( sigc::mem_fun(this, &PatchWindow::event_save_as)); - m_menu_close->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_close)); m_menu_quit->signal_activate().connect( sigc::mem_fun(this, &PatchWindow::event_quit)); m_menu_configuration->signal_activate().connect( @@ -125,7 +125,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad sigc::mem_fun<void>(App::instance().about_dialog(), &Gtk::Dialog::present)); m_breadcrumb_box = new BreadCrumbBox(); - m_breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::patch)); + m_breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::set_patch_from_path)); App::instance().add_patch_window(this); } @@ -133,38 +133,32 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad PatchWindow::~PatchWindow() { + // Prevents deletion + m_patch->claim_patch_view(); + App::instance().remove_patch_window(this); hide(); delete m_new_subpatch_window; delete m_load_subpatch_window; + delete m_breadcrumb_box; } -/** Set the patch controller from a Path (for BreadCrumbs) +/** Set the patch controller from a Path (for use by eg. BreadCrumbBox) */ void -PatchWindow::patch(const Path& path) +PatchWindow::set_patch_from_path(const Path& path) { - CountedPtr<PatchModel> model = App::instance().store()->object(path); + CountedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path)); if (!model) return; // can't really do anything useful.. - PatchController* pc = dynamic_cast<PatchController*>(model->controller()); - - if (!pc) { - pc = new PatchController(model); - model->set_controller(pc); - } - + CountedPtr<PatchController> pc = PtrCast<PatchController>(ControllerFactory::get_controller(model)); assert(pc); - if (pc->window() != NULL && pc->window()->is_visible()) { - pc->show_patch_window(); - } else { - patch_controller(pc); - } + App::instance().window_factory()->present(pc, this); } @@ -173,20 +167,15 @@ PatchWindow::patch(const Path& path) * This function MUST be called before using the window in any way! */ void -PatchWindow::patch_controller(PatchController* pc) +PatchWindow::set_patch(CountedPtr<PatchController> pc) { if (!pc || pc == m_patch) return; m_enable_signal = false; - assert(pc); - assert(m_patch != pc); - assert(m_patch == NULL || - pc->model()->path() != m_patch->model()->path()); - - PatchController* old_pc = m_patch; - if (old_pc != NULL) { + if (m_patch) { + CountedPtr<PatchController> old_pc = m_patch; assert(old_pc->window() == NULL || old_pc->window() == this); old_pc->claim_patch_view(); old_pc->window(NULL); @@ -194,12 +183,8 @@ PatchWindow::patch_controller(PatchController* pc) m_patch = pc; - if (pc->view() == NULL) - pc->create_view(); - assert(pc->view()); - - PatchView* const patch_view = pc->view(); - assert(patch_view != NULL); + CountedPtr<PatchView> patch_view = pc->get_view(); + assert(patch_view); patch_view->reparent(*m_viewport); if (m_breadcrumb_box->get_parent()) @@ -217,10 +202,10 @@ PatchWindow::patch_controller(PatchController* pc) assert(m_load_patch_window != NULL); assert(m_load_subpatch_window != NULL); - m_load_patch_window->patch_controller(m_patch); - m_load_plugin_window->patch_controller(m_patch); - m_new_subpatch_window->patch_controller(m_patch); - m_load_subpatch_window->patch_controller(m_patch); + m_load_patch_window->set_patch(m_patch); + m_load_plugin_window->set_patch(m_patch); + m_new_subpatch_window->set_patch(m_patch); + m_load_subpatch_window->set_patch(m_patch); m_menu_view_control_window->property_sensitive() = pc->has_control_inputs(); @@ -239,7 +224,6 @@ PatchWindow::patch_controller(PatchController* pc) else m_menu_destroy_patch->set_sensitive(true); - assert(old_pc == NULL || old_pc->window() != this); assert(m_patch == pc); assert(m_patch->window() == this); @@ -247,7 +231,6 @@ PatchWindow::patch_controller(PatchController* pc) } - void PatchWindow::event_show_engine() { @@ -272,58 +255,6 @@ PatchWindow::event_show_properties() } -/** Notification a node has been removed from the PatchView this window - * currently contains. - * - * This is used to update the breadcrumbs in case the Node is a patch which has - * a button present in the breadcrumbs that needs to be removed. - */ -void -PatchWindow::node_removed(const string& name) -{ - throw; // FIXME -/* - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == m_patch->model()->base_path() + name) { - for (list<BreadCrumb*>::iterator j = i; j != m_breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = m_breadcrumbs.erase(j); - m_breadcrumb_box->remove(*bc); - } - break; - } - }*/ -} - - -/** Same as @a node_removed, but for renaming. - */ -void -PatchWindow::node_renamed(const string& old_path, const string& new_path) -{ - throw; // FIXME - /* - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == old_path) - (*i)->set_path(new_path); - }*/ -} - - -/** Notification the patch this window is currently showing was renamed. - */ -void -PatchWindow::patch_renamed(const string& new_path) -{ - throw; // FIXME - /* - set_title(new_path); - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == m_patch->path()) - (*i)->set_path(new_path); - }*/ -} - /* void PatchWindow::event_open() @@ -344,7 +275,7 @@ PatchWindow::event_import() void PatchWindow::event_save() { - PatchModel* const model = m_patch->patch_model().get(); + CountedPtr<PatchModel> model(m_patch->patch_model().get()); if (model->filename() == "") event_save_as(); @@ -404,7 +335,7 @@ PatchWindow::event_save_as() fin.close(); if (confirm) { - App::instance().loader()->save_patch(m_patch->patch_model().get(), filename, recursive); + App::instance().loader()->save_patch(m_patch->patch_model(), filename, recursive); m_patch->patch_model()->filename(filename); } } @@ -433,20 +364,12 @@ PatchWindow::on_hide() bool -PatchWindow::on_delete_event(GdkEventAny* ev) -{ - event_close(); - return true; // destroy window -} - - -bool PatchWindow::on_key_press_event(GdkEventKey* event) { if (event->keyval == GDK_Delete) { - if (m_patch != NULL && m_patch->view() != NULL) { - assert(m_patch->view()->canvas() != NULL); - m_patch->view()->canvas()->destroy_selected(); + if (m_patch && m_patch->get_view()) { + assert(m_patch->get_view()->canvas()); + m_patch->get_view()->canvas()->destroy_selected(); } return true; } else { @@ -456,27 +379,6 @@ PatchWindow::on_key_press_event(GdkEventKey* event) void -PatchWindow::event_close() -{ - if (App::instance().num_open_patch_windows() > 1) { - hide(); - } else { - Gtk::MessageDialog d(*this, "This is the last remaining open patch " - "window. Closing this window will exit Ingenuity (the engine will " - "remain running).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - App::instance().quit(); - else - d.hide(); - } -} - - -void PatchWindow::event_quit() { Gtk::MessageDialog d(*this, "Would you like to quit just Ingenuity\nor kill the engine as well?", diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h index 07a3e92e..d538db78 100644 --- a/src/progs/ingenuity/PatchWindow.h +++ b/src/progs/ingenuity/PatchWindow.h @@ -23,9 +23,11 @@ #include <libglademm/xml.h> #include <libglademm.h> #include "util/Path.h" - +#include "util/CountedPtr.h" +#include "PatchController.h" using std::string; using std::list; + namespace Ingen { namespace Client { class PatchModel; class NodeModel; @@ -40,7 +42,6 @@ namespace Ingenuity { class PatchController; class OmFlowCanvas; -class PatchView; class LoadPluginWindow; class LoadPatchWindow; class NewSubpatchWindow; @@ -63,18 +64,13 @@ public: PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); ~PatchWindow(); - void patch(const Path& path); - void patch_controller(PatchController* pc); + void set_patch_from_path(const Path& path); + void set_patch(CountedPtr<PatchController> pc); - PatchController* patch_controller() const { return m_patch; } - LoadPluginWindow* load_plugin_window() const { return m_load_plugin_window; } - LoadSubpatchWindow* load_subpatch_window() const { return m_load_subpatch_window; } - NewSubpatchWindow* new_subpatch_window() const { return m_new_subpatch_window; } - - // Breadcrumb management - void node_removed(const string& name); - void node_renamed(const string& old_path, const string& new_path); - void patch_renamed(const string& new_path); + CountedPtr<PatchController> patch_controller() const { return m_patch; } + LoadPluginWindow* load_plugin_window() const { return m_load_plugin_window; } + LoadSubpatchWindow* load_subpatch_window() const { return m_load_subpatch_window; } + NewSubpatchWindow* new_subpatch_window() const { return m_new_subpatch_window; } Gtk::MenuItem* menu_view_control_window() { return m_menu_view_control_window; } @@ -83,14 +79,12 @@ public: protected: void on_show(); void on_hide(); - bool on_delete_event(GdkEventAny* ev); bool on_key_press_event(GdkEventKey* event); private: void event_import(); void event_save(); void event_save_as(); - void event_close(); void event_quit(); void event_destroy(); void event_clear(); @@ -99,7 +93,8 @@ private: void event_show_controls(); void event_show_engine(); - PatchController* m_patch; + CountedPtr<PatchController> m_patch; + LoadPluginWindow* m_load_plugin_window; LoadPatchWindow* m_load_patch_window; NewSubpatchWindow* m_new_subpatch_window; diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp index 6a23169f..167cb594 100644 --- a/src/progs/ingenuity/PortController.cpp +++ b/src/progs/ingenuity/PortController.cpp @@ -34,9 +34,6 @@ PortController::PortController(CountedPtr<PortModel> model) { assert(model); assert(model->parent()); - assert(model->controller() == NULL); - - model->set_controller(this); } @@ -44,8 +41,8 @@ void PortController::destroy() { assert(m_model->parent()); - NodeController* parent = (NodeController*)m_model->parent()->controller(); - assert(parent != NULL); + CountedPtr<NodeController> parent = PtrCast<NodeController>(m_model->parent()->controller()); + assert(parent); parent->remove_port(path(), false); } @@ -73,7 +70,7 @@ PortController::create_module(OmFlowCanvas* canvas) m_module = new OmPortModule(canvas, this, x, y); - if (CountedPtr<PatchModel>(port_model()->parent())) { + if (PtrCast<PatchModel>(port_model()->parent())) { if (m_patch_port) delete m_patch_port; diff --git a/src/progs/ingenuity/PortController.h b/src/progs/ingenuity/PortController.h index 1a58491b..e28cd21d 100644 --- a/src/progs/ingenuity/PortController.h +++ b/src/progs/ingenuity/PortController.h @@ -47,7 +47,6 @@ class OmFlowCanvas; class PortController : public GtkObjectController { public: - PortController(CountedPtr<PortModel> model); virtual ~PortController() {} virtual void destroy(); @@ -63,9 +62,12 @@ public: void set_path(const Path& new_path); - CountedPtr<PortModel> port_model() const { return m_model; } + CountedPtr<PortModel> port_model() const { return PtrCast<PortModel>(m_model); } private: + friend class ControllerFactory; + PortController(CountedPtr<PortModel> model); + OmPatchPort* m_patch_port; ///< Port on m_module OmPortModule* m_module; ///< Port pseudo-module (for patch ports only) OmPort* m_port; ///< Port on some other canvas module diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp index dfe4b07b..7a458e31 100644 --- a/src/progs/ingenuity/RenameWindow.cpp +++ b/src/progs/ingenuity/RenameWindow.cpp @@ -70,7 +70,7 @@ RenameWindow::name_changed() m_message_label->set_text("Name may not contain '/'"); m_ok_button->property_sensitive() = false; //} else if (m_object->parent()->patch_model()->get_node(name) != NULL) { - } else if (App::instance().store()->object(m_object->model()->parent()->base_path() + name)) { + } else if (App::instance().store()->object(m_object->model()->parent()->path().base() + name)) { m_message_label->set_text("An object already exists with that name."); m_ok_button->property_sensitive() = false; } else if (name.length() == 0) { diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp index d0492618..598cc9db 100644 --- a/src/progs/ingenuity/SubpatchModule.cpp +++ b/src/progs/ingenuity/SubpatchModule.cpp @@ -26,51 +26,46 @@ #include "OmFlowCanvas.h" #include "PatchController.h" #include "OmPort.h" +#include "WindowFactory.h" using std::cerr; using std::cout; using std::endl; namespace Ingenuity { -SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, PatchController* patch) -: OmModule(canvas, patch), +SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> patch) +: OmModule(canvas, patch.get()), m_patch(patch) { - assert(canvas != NULL); - assert(patch != NULL); + assert(canvas); + assert(patch); } void SubpatchModule::on_double_click(GdkEventButton* event) { - assert(m_patch != NULL); - - // If window is visible - if (m_patch->window() != NULL - && m_patch->window()->is_visible()) { - m_patch->show_patch_window(); // just raise it - // No window visible - } else { - if (event->state & GDK_SHIFT_MASK) - m_patch->show_patch_window(); // open a new window - else - browse_to_patch(); - } + assert(m_patch); + + CountedPtr<PatchController> parent = PtrCast<PatchController>(m_patch->model()->parent()->controller()); + + PatchWindow* const preferred + = (event->state & GDK_SHIFT_MASK) ? NULL : parent->window(); + + App::instance().window_factory()->present(m_patch, preferred); } -/** Browse to this patch in current (parent's) window. */ +/** Browse to this patch in current (parent's) window + * (unless an existing window is displaying it) + */ void SubpatchModule::browse_to_patch() { assert(m_patch->model()->parent()); - PatchController* pc = (PatchController*)m_patch->model()->parent()->controller(); - assert(pc != NULL); - assert(pc->window() != NULL); + CountedPtr<PatchController> pc = PtrCast<PatchController>(m_patch->model()->parent()->controller()); - assert(pc->window() != NULL); - pc->window()->patch_controller(m_patch); + App::instance().window_factory()->present(m_patch, pc->window()); } diff --git a/src/progs/ingenuity/SubpatchModule.h b/src/progs/ingenuity/SubpatchModule.h index c530311e..a8e6e971 100644 --- a/src/progs/ingenuity/SubpatchModule.h +++ b/src/progs/ingenuity/SubpatchModule.h @@ -21,6 +21,7 @@ #include <string> #include <libgnomecanvasmm.h> #include "OmModule.h" +#include "util/CountedPtr.h" #include "PatchController.h" using std::string; using std::list; @@ -36,7 +37,6 @@ namespace Ingenuity { class OmFlowCanvas; class NodeControlWindow; -class PatchController; /** A module to represent a subpatch @@ -46,7 +46,7 @@ class PatchController; class SubpatchModule : public OmModule { public: - SubpatchModule(OmFlowCanvas* canvas, PatchController* controller); + SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> controller); virtual ~SubpatchModule() {} void on_double_click(GdkEventButton* ev); @@ -55,10 +55,10 @@ public: void browse_to_patch(); void menu_remove(); - PatchController* patch() { return m_patch; } + CountedPtr<PatchController> patch() { return m_patch; } protected: - PatchController* m_patch; + CountedPtr<PatchController> m_patch; }; diff --git a/src/progs/ingenuity/WindowFactory.cpp b/src/progs/ingenuity/WindowFactory.cpp new file mode 100644 index 00000000..6a913663 --- /dev/null +++ b/src/progs/ingenuity/WindowFactory.cpp @@ -0,0 +1,108 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "WindowFactory.h" +#include "PatchWindow.h" +#include "GladeFactory.h" +#include "App.h" + +namespace Ingenuity { + + +/** Present a PatchWindow for a Patch. + * + * If @a preferred is not NULL, it will be set to display @a patch if the patch + * does not already have a visible window, otherwise that window will be presented and + * @a preferred left unmodified. + */ +void +WindowFactory::present(CountedPtr<PatchController> patch, PatchWindow* preferred) +{ + std::map<Path, PatchWindow*>::iterator w = _windows.find(patch->model()->path()); + + if (w != _windows.end()) { + (*w).second->present(); + } else if (preferred) { + w = _windows.find(preferred->patch_controller()->model()->path()); + assert((*w).second == preferred); + + preferred->set_patch(patch); + _windows.erase(w); + _windows[patch->model()->path()] = preferred; + preferred->present(); + + } else { + PatchWindow* win = create_new(patch); + win->present(); + } +} + + +PatchWindow* +WindowFactory::create_new(CountedPtr<PatchController> patch) +{ + // FIXME: can't just load "patch_win" and children because PatchWindow + // loads things it really shouldn't. + //Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("patch_win"); + Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); + + PatchWindow* win = NULL; + xml->get_widget_derived("patch_win", win); + assert(win); + + win->set_patch(patch); + _windows[patch->model()->path()] = win; + + win->signal_delete_event().connect(sigc::bind<0>( + sigc::mem_fun(this, &WindowFactory::remove), win)); + + cerr << "Created window - count: " << _windows.size() << endl; + + return win; +} + + +bool +WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored) +{ + if (_windows.size() <= 1) { + Gtk::MessageDialog d(*win, "This is the last remaining open patch " + "window. Closing this window will exit Ingenuity (the engine will " + "remain running).\n\nAre you sure you want to quit?", + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); + int ret = d.run(); + if (ret == Gtk::RESPONSE_CLOSE) + App::instance().quit(); + else + return false; + } + + std::map<Path, PatchWindow*>::iterator w + = _windows.find(win->patch_controller()->model()->path()); + + assert((*w).second == win); + _windows.erase(w); + + delete win; + + cerr << "Removed window " << win << "- count: " << _windows.size() << endl; + + return true; +} + +} // namespace Ingenuity diff --git a/src/progs/ingenuity/WindowFactory.h b/src/progs/ingenuity/WindowFactory.h new file mode 100644 index 00000000..add2d97b --- /dev/null +++ b/src/progs/ingenuity/WindowFactory.h @@ -0,0 +1,42 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WINDOW_FACTORY_H +#define WINDOW_FACTORY_H + +#include <map> +#include "util/CountedPtr.h" +#include "PatchController.h" + +namespace Ingenuity { + +class PatchWindow; + + +class WindowFactory { +public: + void present(CountedPtr<PatchController> patch, PatchWindow* preferred = NULL); + +private: + PatchWindow* create_new(CountedPtr<PatchController> patch); + bool remove(PatchWindow* win, GdkEventAny* ignored); + + std::map<Path, PatchWindow*> _windows; +}; + +} + +#endif // WINDOW_FACTORY_H diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade index 84540c7c..2221a805 100644 --- a/src/progs/ingenuity/ingenuity.glade +++ b/src/progs/ingenuity/ingenuity.glade @@ -1770,7 +1770,7 @@ <property name="spacing">0</property> <child> - <widget class="GtkToolbar" id="toolbar4"> + <widget class="GtkToolbar" id="patch_view_crumb_toolbar"> <property name="visible">True</property> <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> @@ -1822,7 +1822,7 @@ </child> <child> - <widget class="GtkToolbar" id="toolbar2"> + <widget class="GtkToolbar" id="patch_view_toolbar"> <property name="visible">True</property> <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> <property name="toolbar_style">GTK_TOOLBAR_ICONS</property> @@ -1942,7 +1942,8 @@ <child> <widget class="GtkToolButton" id="patch_view_clear_but"> <property name="visible">True</property> - <property name="tooltip" translatable="yes">Destroy all children nodes (twice to clear ports as well)</property> + <property name="tooltip" translatable="yes">Destroy all children nodes +(Click twice to clear ports as well)</property> <property name="label" translatable="yes"></property> <property name="use_underline">True</property> <property name="stock_id">gtk-clear</property> diff --git a/src/progs/patch_loader/patch_loader.cpp b/src/progs/patch_loader/patch_loader.cpp index 105a379c..f7464840 100644 --- a/src/progs/patch_loader/patch_loader.cpp +++ b/src/progs/patch_loader/patch_loader.cpp @@ -52,29 +52,28 @@ int main(int argc, char** argv) /* **** Mr. Spock.. Engage **** */ - OSCModelEngineInterface engine(engine_url); - PatchLibrarian librarian(&engine); + CountedPtr<OSCModelEngineInterface> engine(new OSCModelEngineInterface(engine_url)); + PatchLibrarian librarian(engine); /* Connect to engine */ - engine.attach(-1, client_port); - engine.activate(); - //engine.register_client(NULL); // FIXME + engine->attach(-1, client_port); + engine->activate(); + //engine->register_client(NULL); // FIXME - //int id = engine.get_next_request_id(); - //engine.set_wait_response_id(id); - //engine.load_plugins(id); - //engine.wait_for_response(); + //int id = engine->get_next_request_id(); + //engine->set_wait_response_id(id); + //engine->load_plugins(id); + //engine->wait_for_response(); /* FIXME: Make this work like this: - * engine.load_plugins(); - * engine.wait_for_response(); + * engine->load_plugins(); + * engine->wait_for_response(); */ // Load patches for (uint i=0; i < args_info.inputs_num; ++i) { - PatchModel* pm = new PatchModel("", 0); + CountedPtr<PatchModel> pm(new PatchModel("", 0)); pm->filename(args_info.inputs[i]); librarian.load_patch(pm, true); - delete pm; } return 0; diff --git a/src/progs/server/Makefile.am b/src/progs/server/Makefile.am index fc5b770b..e2a38742 100644 --- a/src/progs/server/Makefile.am +++ b/src/progs/server/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events -fno-exceptions +AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events MAINTAINERCLEANFILES = Makefile.in diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp index cd79a7b4..c33014a5 100644 --- a/src/progs/server/main.cpp +++ b/src/progs/server/main.cpp @@ -137,7 +137,7 @@ main(int argc, char** argv) set_denormal_flags(); - engine = new Engine(); + engine = CountedPtr<Engine>(new Engine()); OSCEngineReceiver* receiver = new OSCEngineReceiver( engine, pre_processor_queue_size, args_info.port_arg); |