From 2122a857662203936a04a39df7d0e1ad1db82853 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 6 Jan 2007 04:16:26 +0000 Subject: Work on Port destruction (still broken). git-svn-id: http://svn.drobilla.net/lad/ingen@233 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/GraphObject.cpp | 56 +++++++++ src/libs/engine/GraphObject.h | 10 +- src/libs/engine/InternalNode.h | 13 +- src/libs/engine/Makefile.am | 1 + src/libs/engine/Node.h | 9 -- src/libs/engine/NodeBase.cpp | 26 +--- src/libs/engine/NodeBase.h | 5 - src/libs/engine/Patch.cpp | 14 ++- src/libs/engine/Patch.h | 2 +- src/libs/engine/Port.h | 3 - src/libs/engine/events/AddNodeEvent.cpp | 4 +- src/libs/engine/events/ClearPatchEvent.cpp | 5 +- src/libs/engine/events/CreatePatchEvent.cpp | 2 - src/libs/engine/events/DestroyEvent.cpp | 157 +++++++++++++++++-------- src/libs/engine/events/DestroyEvent.h | 17 ++- src/libs/engine/events/DisconnectPortEvent.cpp | 8 +- src/progs/ingenuity/PatchPortModule.cpp | 2 +- src/progs/ingenuity/Port.cpp | 18 ++- src/progs/ingenuity/Port.h | 9 +- src/progs/ingenuity/ThreadedLoader.cpp | 9 +- 20 files changed, 233 insertions(+), 137 deletions(-) create mode 100644 src/libs/engine/GraphObject.cpp (limited to 'src') 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((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* 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 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); } - - 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* 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* 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* ln) } +/** Remove a node. + * Realtime Safe. Preprocessing thread. + */ ListNode* 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* -Patch::remove_port(const Port* port) +Patch::remove_port(const string& name) { bool found = false; ListNode* ret = NULL; for (List::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::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* Patch::build_process_order() const { - //cerr << "*********** BUILDING PROCESS ORDER FOR " << path() << endl; + cerr << "*********** Building process order for " << path() << endl; Array* const process_order = new Array(_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) { _input_ports.push_back(port); } ///< Preprocesser thread void add_output(ListNode* port) { _output_ports.push_back(port); } ///< Preprocessor thread - ListNode* remove_port(const Port* p); + ListNode* remove_port(const string& name); void add_connection(ListNode* c) { _connections.push_back(c); } ListNode* 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(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::const_iterator i = m_patch->nodes().begin(); i != m_patch->nodes().end(); ++i) - (*i)->remove_from_patch(); + cerr << "FIXME: CLEAR PATCH\n"; + //for (List::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, 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, Frame DestroyEvent::DestroyEvent(Engine& engine, SharedPtr 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(_object); + + if (!_node) + _port = dynamic_cast(_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* m_patch_listnode; - TreeNode* m_store_treenode; - Array* 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* _patch_node_listnode; + ListNode* _patch_port_listnode; + TreeNode* _store_treenode; + Array* _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 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::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 canvas, SharedPtrm_patch_port = boost::shared_ptr(new Port(ret, port, true)); + ret->m_patch_port = boost::shared_ptr(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 module, SharedPtr pm, bool flip) +Port::Port(boost::shared_ptr module, SharedPtr 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 module, SharedPtr pm, bool flip = false); + Port(boost::shared_ptr module, SharedPtr pm, bool flip = false, bool destroyable = false); virtual ~Port() {} - SharedPtr model() const { return m_port_model; } + SharedPtr model() const { return _port_model; } private: - SharedPtr m_port_model; + + void on_menu_destroy(); + + SharedPtr _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, -- cgit v1.2.1