summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/interface/ClientInterface.h10
-rw-r--r--src/common/interface/EngineInterface.h48
-rw-r--r--src/common/util/CountedPtr.h53
-rw-r--r--src/common/util/Path.h19
-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
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp2
-rw-r--r--src/libs/engine/Makefile.am2
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp2
-rw-r--r--src/libs/engine/OSCResponder.cpp2
-rw-r--r--src/libs/engine/Patch.cpp2
-rw-r--r--src/libs/engine/QueuedEvent.h2
-rw-r--r--src/libs/engine/Responder.h2
-rw-r--r--src/libs/engine/events/MidiLearnEvent.h2
-rw-r--r--src/libs/engine/events/RenameEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestMetadataEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestPortValueEvent.cpp3
-rw-r--r--src/progs/Makefile.am2
-rw-r--r--src/progs/demolition/DemolitionClientInterface.cpp4
-rw-r--r--src/progs/demolition/DemolitionClientInterface.h10
-rw-r--r--src/progs/demolition/DemolitionModel.cpp2
-rw-r--r--src/progs/demolition/DemolitionModel.h2
-rw-r--r--src/progs/ingenuity/App.cpp5
-rw-r--r--src/progs/ingenuity/App.h8
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.cpp39
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.h3
-rw-r--r--src/progs/ingenuity/ConnectWindow.cpp8
-rw-r--r--src/progs/ingenuity/ControlGroups.cpp12
-rw-r--r--src/progs/ingenuity/ControlPanel.cpp19
-rw-r--r--src/progs/ingenuity/ControlPanel.h2
-rw-r--r--src/progs/ingenuity/ControllerFactory.cpp72
-rw-r--r--src/progs/ingenuity/ControllerFactory.h32
-rw-r--r--src/progs/ingenuity/DSSIModule.cpp4
-rw-r--r--src/progs/ingenuity/GtkObjectController.cpp2
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.cpp5
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.h8
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.cpp13
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.h4
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.cpp11
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.h6
-rw-r--r--src/progs/ingenuity/Loader.cpp4
-rw-r--r--src/progs/ingenuity/Loader.h24
-rw-r--r--src/progs/ingenuity/Makefile.am4
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.cpp10
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.h7
-rw-r--r--src/progs/ingenuity/NodeController.cpp59
-rw-r--r--src/progs/ingenuity/NodeController.h18
-rw-r--r--src/progs/ingenuity/NodePropertiesWindow.cpp1
-rw-r--r--src/progs/ingenuity/OmFlowCanvas.cpp27
-rw-r--r--src/progs/ingenuity/OmModule.cpp4
-rw-r--r--src/progs/ingenuity/OmModule.h1
-rw-r--r--src/progs/ingenuity/OmPatchPort.cpp2
-rw-r--r--src/progs/ingenuity/OmPort.cpp2
-rw-r--r--src/progs/ingenuity/PatchController.cpp281
-rw-r--r--src/progs/ingenuity/PatchController.h35
-rw-r--r--src/progs/ingenuity/PatchPropertiesWindow.cpp1
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.cpp29
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.h8
-rw-r--r--src/progs/ingenuity/PatchView.cpp29
-rw-r--r--src/progs/ingenuity/PatchView.h5
-rw-r--r--src/progs/ingenuity/PatchWindow.cpp154
-rw-r--r--src/progs/ingenuity/PatchWindow.h27
-rw-r--r--src/progs/ingenuity/PortController.cpp9
-rw-r--r--src/progs/ingenuity/PortController.h6
-rw-r--r--src/progs/ingenuity/RenameWindow.cpp2
-rw-r--r--src/progs/ingenuity/SubpatchModule.cpp41
-rw-r--r--src/progs/ingenuity/SubpatchModule.h8
-rw-r--r--src/progs/ingenuity/WindowFactory.cpp108
-rw-r--r--src/progs/ingenuity/WindowFactory.h42
-rw-r--r--src/progs/ingenuity/ingenuity.glade7
-rw-r--r--src/progs/patch_loader/patch_loader.cpp25
-rw-r--r--src/progs/server/Makefile.am2
-rw-r--r--src/progs/server/main.cpp2
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 != &copy);
@@ -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 != &copy) {
- 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);