summaryrefslogtreecommitdiffstats
path: root/src/libs/client
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-09-11 11:10:35 +0000
committerDavid Robillard <d@drobilla.net>2006-09-11 11:10:35 +0000
commitb15864870d34a1188eda93ad215734275037278e (patch)
tree224a1669a29091ea4198425d4a002e448cde8b30 /src/libs/client
parent22bf43352ddfc48452d776f10ad4d12161255049 (diff)
downloadingen-b15864870d34a1188eda93ad215734275037278e.tar.gz
ingen-b15864870d34a1188eda93ad215734275037278e.tar.bz2
ingen-b15864870d34a1188eda93ad215734275037278e.zip
Switched homebrew CountedPtr to boost::shared_ptr.
Factories for patch windows, controller. Robustness updated in many places. Tons of cleanups, rewrites, bugfixes, etc. git-svn-id: http://svn.drobilla.net/lad/ingen@128 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/client')
-rw-r--r--src/libs/client/ConnectionModel.cpp6
-rw-r--r--src/libs/client/Makefile.am2
-rw-r--r--src/libs/client/ModelClientInterface.cpp22
-rw-r--r--src/libs/client/ModelClientInterface.h13
-rw-r--r--src/libs/client/NodeModel.cpp44
-rw-r--r--src/libs/client/NodeModel.h8
-rw-r--r--src/libs/client/ObjectModel.cpp36
-rw-r--r--src/libs/client/ObjectModel.h26
-rw-r--r--src/libs/client/PatchLibrarian.cpp80
-rw-r--r--src/libs/client/PatchLibrarian.h14
-rw-r--r--src/libs/client/PatchModel.cpp50
-rw-r--r--src/libs/client/PatchModel.h4
-rw-r--r--src/libs/client/PortModel.h2
-rw-r--r--src/libs/client/Store.cpp299
-rw-r--r--src/libs/client/Store.h42
15 files changed, 341 insertions, 307 deletions
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;
};