summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-01-06 04:16:26 +0000
committerDavid Robillard <d@drobilla.net>2007-01-06 04:16:26 +0000
commit2122a857662203936a04a39df7d0e1ad1db82853 (patch)
treeb31070a9d01ab20da1a03bf8d029dc3ce6ab66bc /src
parent9c5f7e9dc2029f97d0baf622165701e7c124b25e (diff)
downloadingen-2122a857662203936a04a39df7d0e1ad1db82853.tar.gz
ingen-2122a857662203936a04a39df7d0e1ad1db82853.tar.bz2
ingen-2122a857662203936a04a39df7d0e1ad1db82853.zip
Work on Port destruction (still broken).
git-svn-id: http://svn.drobilla.net/lad/ingen@233 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/libs/engine/GraphObject.cpp56
-rw-r--r--src/libs/engine/GraphObject.h10
-rw-r--r--src/libs/engine/InternalNode.h13
-rw-r--r--src/libs/engine/Makefile.am1
-rw-r--r--src/libs/engine/Node.h9
-rw-r--r--src/libs/engine/NodeBase.cpp26
-rw-r--r--src/libs/engine/NodeBase.h5
-rw-r--r--src/libs/engine/Patch.cpp14
-rw-r--r--src/libs/engine/Patch.h2
-rw-r--r--src/libs/engine/Port.h3
-rw-r--r--src/libs/engine/events/AddNodeEvent.cpp4
-rw-r--r--src/libs/engine/events/ClearPatchEvent.cpp5
-rw-r--r--src/libs/engine/events/CreatePatchEvent.cpp2
-rw-r--r--src/libs/engine/events/DestroyEvent.cpp157
-rw-r--r--src/libs/engine/events/DestroyEvent.h17
-rw-r--r--src/libs/engine/events/DisconnectPortEvent.cpp8
-rw-r--r--src/progs/ingenuity/PatchPortModule.cpp2
-rw-r--r--src/progs/ingenuity/Port.cpp18
-rw-r--r--src/progs/ingenuity/Port.h9
-rw-r--r--src/progs/ingenuity/ThreadedLoader.cpp9
20 files changed, 233 insertions, 137 deletions
diff --git a/src/libs/engine/GraphObject.cpp b/src/libs/engine/GraphObject.cpp
new file mode 100644
index 00000000..03b4eae7
--- /dev/null
+++ b/src/libs/engine/GraphObject.cpp
@@ -0,0 +1,56 @@
+/* This file is part of Ingen. Copyright (C) 2007 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 "GraphObject.h"
+#include "Patch.h"
+#include "ObjectStore.h"
+
+namespace Ingen {
+
+
+Patch*
+GraphObject::parent_patch() const
+{
+ return dynamic_cast<Patch*>((Node*)_parent);
+}
+
+
+// FIXME: these functions are stupid/ugly
+
+void
+GraphObject::add_to_store(ObjectStore* store)
+{
+ store->add(this);
+ _store = store;
+}
+
+
+void
+GraphObject::remove_from_store()
+{
+ if (_store) {
+ TreeNode<GraphObject*>* node = _store->remove(path());
+ if (node != NULL) {
+ assert(_store->find(path()) == NULL);
+ delete node;
+ }
+ }
+
+ _store = NULL;
+}
+
+
+} // namespace Ingen
diff --git a/src/libs/engine/GraphObject.h b/src/libs/engine/GraphObject.h
index 8fe2a0a6..1f3caa7b 100644
--- a/src/libs/engine/GraphObject.h
+++ b/src/libs/engine/GraphObject.h
@@ -49,7 +49,7 @@ public:
typedef std::map<string, Atom> MetadataMap;
GraphObject(GraphObject* parent, const string& name)
- : _parent(parent), _name(name)
+ : _store(NULL), _parent(parent), _name(name)
{
assert(parent == NULL || _name.length() > 0);
assert(_name.find("/") == string::npos);
@@ -83,10 +83,13 @@ public:
/** Patch and Node override this to recursively add their children. */
- virtual void add_to_store(ObjectStore* store) = 0;
+ virtual void add_to_store(ObjectStore* store);
/** Patch and Node override this to recursively remove their children. */
- virtual void remove_from_store() = 0;
+ virtual void remove_from_store();
+
+ /** The Patch this object is a child of. */
+ virtual Patch* parent_patch() const;
/** Path is dynamically generated from parent to ease renaming */
inline const Path path() const {
@@ -99,6 +102,7 @@ public:
}
protected:
+ ObjectStore* _store;
GraphObject* _parent;
string _name;
diff --git a/src/libs/engine/InternalNode.h b/src/libs/engine/InternalNode.h
index 25a453b9..44810871 100644
--- a/src/libs/engine/InternalNode.h
+++ b/src/libs/engine/InternalNode.h
@@ -35,28 +35,17 @@ class InternalNode : public NodeBase
{
public:
InternalNode(const Plugin* plugin, const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size)
- : NodeBase(plugin, path, poly, parent, srate, buffer_size),
- _is_added(false)
+ : NodeBase(plugin, path, poly, parent, srate, buffer_size)
{
}
virtual ~InternalNode() {}
- virtual void deactivate() { if (_is_added) remove_from_patch(); NodeBase::deactivate(); }
-
virtual void process(SampleCount nframes, FrameTime start, FrameTime end)
{ NodeBase::process(nframes, start, end); }
- virtual void add_to_patch() { assert(!_is_added); _is_added = true; }
- virtual void remove_from_patch() { assert(_is_added); _is_added = false; }
-
- //virtual void send_creation_messages(ClientInterface* client) const
- //{ NodeBase::send_creation_messages(client); }
-
protected:
Plugin* plugin() const { return const_cast<Plugin*>(_plugin); }
-
- bool _is_added;
};
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index 3e4edf2c..eac42257 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -63,6 +63,7 @@ libingen_la_SOURCES = \
QueuedEngineInterface.h \
QueuedEngineInterface.cpp \
GraphObject.h \
+ GraphObject.cpp \
Maid.h \
Maid.cpp \
MaidObject.h \
diff --git a/src/libs/engine/Node.h b/src/libs/engine/Node.h
index 7a4600ee..db220c15 100644
--- a/src/libs/engine/Node.h
+++ b/src/libs/engine/Node.h
@@ -103,15 +103,6 @@ public:
*/
virtual const Plugin* plugin() const = 0;
- /** Add self to a Patch.
- *
- * This function must be realtime-safe! Any non-realtime actions that
- * need to be done before adding to a patch can be done in activate().
- */
- virtual void add_to_patch() = 0;
-
- virtual void remove_from_patch() = 0;
-
virtual void set_buffer_size(size_t size) = 0;
};
diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp
index 1462e3bf..7cc005ab 100644
--- a/src/libs/engine/NodeBase.cpp
+++ b/src/libs/engine/NodeBase.cpp
@@ -34,7 +34,6 @@ namespace Ingen {
NodeBase::NodeBase(const Plugin* plugin, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size)
: Node(parent, name),
- _store(NULL),
_plugin(plugin),
_poly(poly),
_srate(srate),
@@ -79,21 +78,12 @@ NodeBase::deactivate()
}
-/*
-void
-NodeBase::send_creation_messages(ClientInterface* client) const
-{
- cerr << "FIXME: send_creation\n";
- //_engine.broadcaster()->send_node_to(client, this);
-}
-*/
-
void
NodeBase::add_to_store(ObjectStore* store)
{
assert(!_store);
- store->add(this);
+ GraphObject::add_to_store(store);
for (size_t i=0; i < num_ports(); ++i)
store->add(_ports->at(i));
@@ -105,23 +95,19 @@ NodeBase::add_to_store(ObjectStore* store)
void
NodeBase::remove_from_store()
{
- // Remove self
- TreeNode<GraphObject*>* node = _store->remove(path());
- if (node != NULL) {
- assert(_store->find(path()) == NULL);
- delete node;
- }
-
// Remove ports
for (size_t i=0; i < num_ports(); ++i) {
- node = _store->remove(_ports->at(i)->path());
+ TreeNode<GraphObject*>* node = _store->remove(_ports->at(i)->path());
if (node != NULL) {
assert(_store->find(_ports->at(i)->path()) == NULL);
delete node;
}
}
+
+ // Remove self
+ GraphObject::remove_from_store();
- _store = NULL;
+ assert(_store == NULL);
}
diff --git a/src/libs/engine/NodeBase.h b/src/libs/engine/NodeBase.h
index d48dd1a1..31deb35e 100644
--- a/src/libs/engine/NodeBase.h
+++ b/src/libs/engine/NodeBase.h
@@ -58,9 +58,6 @@ public:
virtual void set_buffer_size(size_t size);
- virtual void add_to_patch() {}
- virtual void remove_from_patch() {}
-
void add_to_store(ObjectStore* store);
void remove_from_store();
@@ -89,8 +86,6 @@ public:
Patch* parent_patch() const { return (Patch*)_parent; }
protected:
- ObjectStore* _store;
-
const Plugin* _plugin;
size_t _poly;
diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp
index 967623e5..d1d3e84a 100644
--- a/src/libs/engine/Patch.cpp
+++ b/src/libs/engine/Patch.cpp
@@ -188,6 +188,9 @@ Patch::add_node(ListNode<Node*>* ln)
}
+/** Remove a node.
+ * Realtime Safe. Preprocessing thread.
+ */
ListNode<Node*>*
Patch::remove_node(const string& name)
{
@@ -263,15 +266,16 @@ Patch::create_port(const string& name, DataType type, size_t buffer_size, bool i
}
-/** Remove a port. Realtime safe.
+/** Remove a port.
+ * Realtime safe. Preprocessing thread.
*/
ListNode<Port*>*
-Patch::remove_port(const Port* port)
+Patch::remove_port(const string& name)
{
bool found = false;
ListNode<Port*>* ret = NULL;
for (List<Port*>::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) {
- if ((*i) == port) {
+ if ((*i)->name() == name) {
ret = _input_ports.remove(i);
found = true;
}
@@ -279,7 +283,7 @@ Patch::remove_port(const Port* port)
if (!found)
for (List<Port*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) {
- if ((*i) == port) {
+ if ((*i)->name() == name) {
ret = _output_ports.remove(i);
found = true;
}
@@ -305,7 +309,7 @@ Patch::remove_port(const Port* port)
Array<Node*>*
Patch::build_process_order() const
{
- //cerr << "*********** BUILDING PROCESS ORDER FOR " << path() << endl;
+ cerr << "*********** Building process order for " << path() << endl;
Array<Node*>* const process_order = new Array<Node*>(_nodes.size(), NULL);
diff --git a/src/libs/engine/Patch.h b/src/libs/engine/Patch.h
index b7fe5718..3a4f08d5 100644
--- a/src/libs/engine/Patch.h
+++ b/src/libs/engine/Patch.h
@@ -79,7 +79,7 @@ public:
Port* create_port(const string& name, DataType type, size_t buffer_size, bool is_output);
void add_input(ListNode<Port*>* port) { _input_ports.push_back(port); } ///< Preprocesser thread
void add_output(ListNode<Port*>* port) { _output_ports.push_back(port); } ///< Preprocessor thread
- ListNode<Port*>* remove_port(const Port* p);
+ ListNode<Port*>* remove_port(const string& name);
void add_connection(ListNode<Connection*>* c) { _connections.push_back(c); }
ListNode<Connection*>* remove_connection(const Port* src_port, const Port* dst_port);
diff --git a/src/libs/engine/Port.h b/src/libs/engine/Port.h
index 90dbdd00..9f645e3e 100644
--- a/src/libs/engine/Port.h
+++ b/src/libs/engine/Port.h
@@ -43,9 +43,6 @@ class Port : public GraphObject
public:
virtual ~Port() {}
- void add_to_store(ObjectStore* store) { assert(false); }
- void remove_from_store() { assert(false); }
-
/** A port's parent is always a node, so static cast should be safe */
Node* parent_node() const { return (Node*)_parent; }
diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp
index 74a08b00..92214009 100644
--- a/src/libs/engine/events/AddNodeEvent.cpp
+++ b/src/libs/engine/events/AddNodeEvent.cpp
@@ -96,6 +96,8 @@ AddNodeEvent::pre_process()
m_patch->add_node(new ListNode<Node*>(m_node));
m_node->add_to_store(_engine.object_store());
+ // FIXME: not really necessary to build process order since it's not connected,
+ // just append to the list
if (m_patch->enabled())
m_process_order = m_patch->build_process_order();
}
@@ -110,8 +112,6 @@ AddNodeEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
QueuedEvent::execute(nframes, start, end);
if (m_node != NULL) {
- m_node->add_to_patch();
-
if (m_patch->process_order() != NULL)
_engine.maid()->push(m_patch->process_order());
m_patch->process_order(m_process_order);
diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp
index 52366139..db2ea54b 100644
--- a/src/libs/engine/events/ClearPatchEvent.cpp
+++ b/src/libs/engine/events/ClearPatchEvent.cpp
@@ -64,8 +64,9 @@ ClearPatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
if (m_patch != NULL) {
m_patch->disable();
- for (List<Node*>::const_iterator i = m_patch->nodes().begin(); i != m_patch->nodes().end(); ++i)
- (*i)->remove_from_patch();
+ cerr << "FIXME: CLEAR PATCH\n";
+ //for (List<Node*>::const_iterator i = m_patch->nodes().begin(); i != m_patch->nodes().end(); ++i)
+ // (*i)->remove_from_patch();
if (m_patch->process_order() != NULL) {
_engine.maid()->push(m_patch->process_order());
diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp
index f5baf53e..9124f280 100644
--- a/src/libs/engine/events/CreatePatchEvent.cpp
+++ b/src/libs/engine/events/CreatePatchEvent.cpp
@@ -102,8 +102,6 @@ CreatePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
assert(m_parent != NULL);
assert(m_path != "/");
- m_patch->add_to_patch();
-
if (m_parent->process_order() != NULL)
_engine.maid()->push(m_parent->process_order());
m_parent->process_order(m_process_order);
diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp
index 10b870a2..9801f0fe 100644
--- a/src/libs/engine/events/DestroyEvent.cpp
+++ b/src/libs/engine/events/DestroyEvent.cpp
@@ -36,12 +36,16 @@ namespace Ingen {
DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool block)
: QueuedEvent(engine, responder, time, source, source),
- m_path(path),
- m_node(NULL),
- m_patch_listnode(NULL),
- m_store_treenode(NULL),
- m_process_order(NULL),
- m_disconnect_event(NULL)
+ _path(path),
+ _object(NULL),
+ _node(NULL),
+ _port(NULL),
+ _patch_node_listnode(NULL),
+ _patch_port_listnode(NULL),
+ _store_treenode(NULL),
+ _process_order(NULL),
+ _disconnect_node_event(NULL),
+ _disconnect_port_event(NULL)
{
assert(_source);
}
@@ -49,56 +53,92 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, Frame
DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, Node* node, bool block)
: QueuedEvent(engine, responder, block, source),
- m_path(node->path()),
- m_node(node),
- m_patch_listnode(NULL),
- m_store_treenode(NULL),
- m_process_order(NULL),
- m_disconnect_event(NULL)
+ _path(node->path()),
+ _object(node),
+ _node(node),
+ _port(NULL),
+ _patch_node_listnode(NULL),
+ _patch_port_listnode(NULL),
+ _store_treenode(NULL),
+ _process_order(NULL),
+ _disconnect_node_event(NULL),
+ _disconnect_port_event(NULL)
{
}
DestroyEvent::~DestroyEvent()
{
- delete m_disconnect_event;
+ delete _disconnect_node_event;
+ delete _disconnect_port_event;
}
void
DestroyEvent::pre_process()
{
- if (m_node == NULL)
- m_node = _engine.object_store()->find_node(m_path);
-
- if (m_node != NULL && m_path != "/") {
- assert(m_node->parent_patch() != NULL);
- m_patch_listnode = m_node->parent_patch()->remove_node(m_path.name());
- if (m_patch_listnode != NULL) {
- assert(m_patch_listnode->elem() == m_node);
+ if (_object == NULL) {
+ _object = _engine.object_store()->find(_path);
+
+ if (_object) {
+ _node = dynamic_cast<Node*>(_object);
+
+ if (!_node)
+ _port = dynamic_cast<Port*>(_object);
+ }
+ }
+
+ if (_node != NULL && _path != "/") {
+ assert(_node->parent_patch() != NULL);
+ _patch_node_listnode = _node->parent_patch()->remove_node(_path.name());
+ if (_patch_node_listnode != NULL) {
+ assert(_patch_node_listnode->elem() == _node);
- m_node->remove_from_store();
+ _node->remove_from_store();
- if (m_node->providers()->size() != 0 || m_node->dependants()->size() != 0) {
- m_disconnect_event = new DisconnectNodeEvent(_engine, m_node);
- m_disconnect_event->pre_process();
+ if (_node->providers()->size() != 0 || _node->dependants()->size() != 0) {
+ _disconnect_node_event = new DisconnectNodeEvent(_engine, _node);
+ _disconnect_node_event->pre_process();
}
- if (m_node->parent_patch()->enabled()) {
- m_process_order = m_node->parent_patch()->build_process_order();
+ if (_node->parent_patch()->enabled()) {
+ // FIXME: is this called multiple times?
+ _process_order = _node->parent_patch()->build_process_order();
// Remove node to be removed from the process order so it isn't executed by
// Patch::run and can safely be destroyed
- //for (size_t i=0; i < m_process_order->size(); ++i)
- // if (m_process_order->at(i) == m_node)
- // m_process_order->at(i) = NULL; // ew, gap
+ //for (size_t i=0; i < _process_order->size(); ++i)
+ // if (_process_order->at(i) == _node)
+ // _process_order->at(i) = NULL; // ew, gap
#ifdef DEBUG
// Be sure node is removed from process order, so it can be destroyed
- for (size_t i=0; i < m_process_order->size(); ++i)
- assert(m_process_order->at(i) != m_node);
+ for (size_t i=0; i < _process_order->size(); ++i)
+ assert(_process_order->at(i) != _node);
#endif
}
}
+ } else if (_port) {
+ assert(_port->parent_patch() != NULL);
+ _patch_port_listnode = _port->parent_patch()->remove_port(_path.name());
+ if (_patch_port_listnode != NULL) {
+ assert(_patch_port_listnode->elem() == _port);
+
+ _port->remove_from_store();
+
+ _disconnect_port_event = new DisconnectPortEvent(_engine, _port);
+ _disconnect_port_event->pre_process();
+
+ if (_port->parent_patch()->enabled()) {
+ // FIXME: is this called multiple times?
+ _process_order = _port->parent_patch()->build_process_order();
+ // Remove port to be removed from the process order so it isn't executed by
+ // Patch::run and can safely be destroyed
+ //for (size_t i=0; i < _process_order->size(); ++i)
+ // if (_process_order->at(i) == _port)
+ // _process_order->at(i) = NULL; // ew, gap
+ }
+ }
+
}
QueuedEvent::pre_process();
@@ -110,15 +150,25 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
{
QueuedEvent::execute(nframes, start, end);
- if (m_patch_listnode != NULL) {
- m_node->remove_from_patch();
+ if (_patch_node_listnode != NULL) {
+ assert(_node);
+
+ if (_disconnect_node_event != NULL)
+ _disconnect_node_event->execute(nframes, start, end);
- if (m_disconnect_event != NULL)
- m_disconnect_event->execute(nframes, start, end);
+ if (_node->parent_patch()->process_order() != NULL)
+ _engine.maid()->push(_node->parent_patch()->process_order());
+ _node->parent_patch()->process_order(_process_order);
+
+ } else if (_patch_port_listnode != NULL) {
+ assert(_port);
+
+ if (_disconnect_port_event != NULL)
+ _disconnect_port_event->execute(nframes, start, end);
- if (m_node->parent_patch()->process_order() != NULL)
- _engine.maid()->push(m_node->parent_patch()->process_order());
- m_node->parent_patch()->process_order(m_process_order);
+ if (_port->parent_patch()->process_order() != NULL)
+ _engine.maid()->push(_port->parent_patch()->process_order());
+ _port->parent_patch()->process_order(_process_order);
}
}
@@ -129,19 +179,28 @@ DestroyEvent::post_process()
if (_source)
_source->unblock();
- if (m_node == NULL) {
- if (m_path == "/")
+ if (_object == NULL) {
+ if (_path == "/")
_responder->respond_error("You can not destroy the root patch (/)");
else
- _responder->respond_error("Could not find node to destroy");
- } else if (m_patch_listnode != NULL) {
- m_node->deactivate();
+ _responder->respond_error("Could not find object to destroy");
+ } else if (_patch_node_listnode != NULL) {
+ assert(_node);
+ _node->deactivate();
+ _responder->respond_ok();
+ if (_disconnect_node_event != NULL)
+ _disconnect_node_event->post_process();
+ _engine.broadcaster()->send_destroyed(_path);
+ _engine.maid()->push(_patch_node_listnode);
+ _engine.maid()->push(_node);
+ } else if (_patch_port_listnode != NULL) {
+ assert(_port);
_responder->respond_ok();
- if (m_disconnect_event != NULL)
- m_disconnect_event->post_process();
- _engine.broadcaster()->send_destroyed(m_path);
- _engine.maid()->push(m_patch_listnode);
- _engine.maid()->push(m_node);
+ if (_disconnect_port_event != NULL)
+ _disconnect_port_event->post_process();
+ _engine.broadcaster()->send_destroyed(_path);
+ _engine.maid()->push(_patch_port_listnode);
+ _engine.maid()->push(_port);
} else {
_responder->respond_error("Unable to destroy object");
}
diff --git a/src/libs/engine/events/DestroyEvent.h b/src/libs/engine/events/DestroyEvent.h
index 23d0ba90..ad67bbca 100644
--- a/src/libs/engine/events/DestroyEvent.h
+++ b/src/libs/engine/events/DestroyEvent.h
@@ -32,6 +32,7 @@ namespace Ingen {
class GraphObject;
class Patch;
class Node;
+class Port;
class Plugin;
class DisconnectNodeEvent;
class DisconnectPortEvent;
@@ -53,12 +54,16 @@ public:
void post_process();
private:
- Path m_path;
- Node* m_node;
- ListNode<Node*>* m_patch_listnode;
- TreeNode<GraphObject*>* m_store_treenode;
- Array<Node*>* m_process_order; // Patch's new process order
- DisconnectNodeEvent* m_disconnect_event;
+ Path _path;
+ GraphObject* _object;
+ Node* _node; ///< Same as _object if it is a Node, otherwise NULL
+ Port* _port; ///< Same as _object if it is a Port, otherwise NULL
+ ListNode<Node*>* _patch_node_listnode;
+ ListNode<Port*>* _patch_port_listnode;
+ TreeNode<GraphObject*>* _store_treenode;
+ Array<Node*>* _process_order; ///< Patch's new process order
+ DisconnectNodeEvent* _disconnect_node_event;
+ DisconnectPortEvent* _disconnect_port_event;
};
diff --git a/src/libs/engine/events/DisconnectPortEvent.cpp b/src/libs/engine/events/DisconnectPortEvent.cpp
index 782b4cf4..cfd523e0 100644
--- a/src/libs/engine/events/DisconnectPortEvent.cpp
+++ b/src/libs/engine/events/DisconnectPortEvent.cpp
@@ -52,7 +52,7 @@ DisconnectPortEvent::DisconnectPortEvent(Engine& engine, SharedPtr<Responder> re
DisconnectPortEvent::DisconnectPortEvent(Engine& engine, Port* port)
: QueuedEvent(engine),
- m_port_path(""),
+ m_port_path(port->path()),
m_patch((port->parent_node() == NULL) ? NULL : port->parent_node()->parent_patch()),
m_port(port),
m_process_order(NULL),
@@ -132,11 +132,13 @@ void
DisconnectPortEvent::post_process()
{
if (m_succeeded) {
- _responder->respond_ok();
+ if (_responder)
+ _responder->respond_ok();
for (List<DisconnectionEvent*>::iterator i = m_disconnection_events.begin(); i != m_disconnection_events.end(); ++i)
(*i)->post_process();
} else {
- _responder->respond_error("Unable to disconnect port.");
+ if (_responder)
+ _responder->respond_error("Unable to disconnect port.");
}
}
diff --git a/src/progs/ingenuity/PatchPortModule.cpp b/src/progs/ingenuity/PatchPortModule.cpp
index e1fb37a8..e4c00130 100644
--- a/src/progs/ingenuity/PatchPortModule.cpp
+++ b/src/progs/ingenuity/PatchPortModule.cpp
@@ -68,7 +68,7 @@ PatchPortModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PortMod
new PatchPortModule(canvas, port));
assert(ret);
- ret->m_patch_port = boost::shared_ptr<Port>(new Port(ret, port, true));
+ ret->m_patch_port = boost::shared_ptr<Port>(new Port(ret, port, true, true));
ret->add_port(ret->m_patch_port);
ret->resize();
diff --git a/src/progs/ingenuity/Port.cpp b/src/progs/ingenuity/Port.cpp
index 5d12cffa..e8e795d0 100644
--- a/src/progs/ingenuity/Port.cpp
+++ b/src/progs/ingenuity/Port.cpp
@@ -21,6 +21,7 @@
#include "PortModel.h"
#include "ControlModel.h"
#include "Configuration.h"
+#include "ModelEngineInterface.h"
#include "App.h"
using std::cerr; using std::endl;
@@ -31,15 +32,26 @@ namespace Ingenuity {
/** @param flip Make an input port appear as an output port, and vice versa.
*/
-Port::Port(boost::shared_ptr<LibFlowCanvas::Module> module, SharedPtr<PortModel> pm, bool flip)
+Port::Port(boost::shared_ptr<LibFlowCanvas::Module> module, SharedPtr<PortModel> pm, bool flip, bool destroyable)
: LibFlowCanvas::Port(module,
pm->path().name(),
flip ? (!pm->is_input()) : pm->is_input(),
App::instance().configuration()->get_port_color(pm.get())),
- m_port_model(pm)
+ _port_model(pm)
{
assert(module);
- assert(m_port_model);
+ assert(_port_model);
+
+ if (destroyable)
+ m_menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy",
+ sigc::mem_fun(this, &Port::on_menu_destroy)));
+}
+
+
+void
+Port::on_menu_destroy()
+{
+ App::instance().engine()->destroy(_port_model->path());
}
diff --git a/src/progs/ingenuity/Port.h b/src/progs/ingenuity/Port.h
index a23cd2c9..0498b5a8 100644
--- a/src/progs/ingenuity/Port.h
+++ b/src/progs/ingenuity/Port.h
@@ -35,14 +35,17 @@ namespace Ingenuity {
class Port : public LibFlowCanvas::Port
{
public:
- Port(boost::shared_ptr<LibFlowCanvas::Module> module, SharedPtr<PortModel> pm, bool flip = false);
+ Port(boost::shared_ptr<LibFlowCanvas::Module> module, SharedPtr<PortModel> pm, bool flip = false, bool destroyable = false);
virtual ~Port() {}
- SharedPtr<PortModel> model() const { return m_port_model; }
+ SharedPtr<PortModel> model() const { return _port_model; }
private:
- SharedPtr<PortModel> m_port_model;
+
+ void on_menu_destroy();
+
+ SharedPtr<PortModel> _port_model;
};
diff --git a/src/progs/ingenuity/ThreadedLoader.cpp b/src/progs/ingenuity/ThreadedLoader.cpp
index 79cd8507..83b3d6b5 100644
--- a/src/progs/ingenuity/ThreadedLoader.cpp
+++ b/src/progs/ingenuity/ThreadedLoader.cpp
@@ -55,7 +55,7 @@ ThreadedLoader::_whipped()
_mutex.unlock();
}
-/** FIXME: most of these paramteres do nothing */
+/** FIXME: use poly parameter */
void
ThreadedLoader::load_patch(bool merge,
const string& data_base_uri,
@@ -67,13 +67,6 @@ ThreadedLoader::load_patch(bool merge,
{
_mutex.lock();
- /*_events.push_back(sigc::hide_return(sigc::bind(
- sigc::mem_fun(_loader, &Loader::load_patch),
- merge, data_base_uri, data_path,
- engine_data, engine_parent, engine_name, engine_poly)));*/
-
- cerr << "FIXME: load under root only\n";
-
_events.push_back(sigc::hide_return(sigc::bind(
sigc::mem_fun(_loader, &Loader::load),
data_base_uri,