summaryrefslogtreecommitdiffstats
path: root/src/libs/engine/events
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-05-14 23:31:15 +0000
committerDavid Robillard <d@drobilla.net>2008-05-14 23:31:15 +0000
commiteb10d32d8b59f2158ba64ba55e310ba0f5f24170 (patch)
treed67944c6ada3369ba988cee4bd86ca24ee9de703 /src/libs/engine/events
parent5fc6f5df54a2650c4a53f04ee38cfebec0a515e1 (diff)
downloadingen-eb10d32d8b59f2158ba64ba55e310ba0f5f24170.tar.gz
ingen-eb10d32d8b59f2158ba64ba55e310ba0f5f24170.tar.bz2
ingen-eb10d32d8b59f2158ba64ba55e310ba0f5f24170.zip
Fix clear patch command (ticket #18).
Potential destruction race/leak fixes. More thorough thread assertions on graph object methods. git-svn-id: http://svn.drobilla.net/lad/ingen@1207 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine/events')
-rw-r--r--src/libs/engine/events/ClearPatchEvent.cpp75
-rw-r--r--src/libs/engine/events/ClearPatchEvent.hpp16
-rw-r--r--src/libs/engine/events/DestroyEvent.cpp3
-rw-r--r--src/libs/engine/events/DestroyEvent.hpp3
4 files changed, 59 insertions, 38 deletions
diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp
index 211ca79e..0e725e65 100644
--- a/src/libs/engine/events/ClearPatchEvent.cpp
+++ b/src/libs/engine/events/ClearPatchEvent.cpp
@@ -27,15 +27,19 @@
#include "NodeImpl.hpp"
#include "ConnectionImpl.hpp"
#include "QueuedEventSource.hpp"
+#include "AudioDriver.hpp"
+#include "MidiDriver.hpp"
namespace Ingen {
ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path)
-: QueuedEvent(engine, responder, time, true, source),
- _patch_path(patch_path),
- _patch(NULL),
- _process(false)
+ : QueuedEvent(engine, responder, time, true, source)
+ , _patch_path(patch_path)
+ , _driver_port(NULL)
+ , _process(false)
+ , _ports_array(NULL)
+ , _compiled_patch(NULL)
{
}
@@ -43,18 +47,20 @@ ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder,
void
ClearPatchEvent::pre_process()
{
- cerr << "FIXME: CLEAR PATCH\n";
-#if 0
- _patch = _engine.object_store()->find_patch(_patch_path);
+ ObjectStore::Objects::iterator patch_iterator = _engine.object_store()->find(_patch_path);
- if (_patch != NULL) {
-
- _process = _patch->enabled();
-
- for (List<Node*>::const_iterator i = _patch->nodes().begin(); i != _patch->nodes().end(); ++i)
- (*i)->remove_from_store();
+ if (patch_iterator != _engine.object_store()->objects().end()) {
+ _patch = PtrCast<PatchImpl>(patch_iterator->second);
+ if (_patch) {
+ _process = _patch->enabled();
+ _removed_table = _engine.object_store()->remove_children(patch_iterator);
+ _patch->nodes().clear();
+ _patch->connections().clear();
+ _ports_array = _patch->build_ports_array();
+ if (_patch->enabled())
+ _compiled_patch = _patch->compile();
+ }
}
-#endif
QueuedEvent::pre_process();
}
@@ -65,17 +71,31 @@ ClearPatchEvent::execute(ProcessContext& context)
{
QueuedEvent::execute(context);
- if (_patch != NULL) {
+ if (_patch && _removed_table) {
_patch->disable();
- cerr << "FIXME: CLEAR PATCH\n";
- //for (List<Node*>::const_iterator i = _patch->nodes().begin(); i != _patch->nodes().end(); ++i)
- // (*i)->remove_from_patch();
-
if (_patch->compiled_patch() != NULL) {
_engine.maid()->push(_patch->compiled_patch());
_patch->compiled_patch(NULL);
}
+
+ _patch->clear_ports();
+ _patch->connections().clear();
+ _patch->compiled_patch(_compiled_patch);
+ Raul::Array<PortImpl*>* old_ports = _patch->external_ports();
+ _patch->external_ports(_ports_array);
+ _ports_array = old_ports;
+
+ // Remove driver ports, if necessary
+ if (_patch->parent() == NULL) {
+ for (ObjectStore::Objects::iterator i = _removed_table->begin(); i != _removed_table->end(); ++i) {
+ SharedPtr<PortImpl> port = PtrCast<PortImpl>(i->second);
+ if (port && port->type() == DataType::AUDIO)
+ _driver_port = _engine.audio_driver()->remove_port(port->path());
+ else if (port && port->type() == DataType::EVENT)
+ _driver_port = _engine.midi_driver()->remove_port(port->path());
+ }
+ }
}
}
@@ -84,18 +104,8 @@ void
ClearPatchEvent::post_process()
{
if (_patch != NULL) {
- // Delete all nodes
- for (List<NodeImpl*>::iterator i = _patch->nodes().begin(); i != _patch->nodes().end(); ++i) {
- (*i)->deactivate();
- delete *i;
- }
- _patch->nodes().clear();
-
- // Delete all connections
- for (PatchImpl::Connections::iterator i = _patch->connections().begin(); i != _patch->connections().end(); ++i)
- (*i).reset();
-
- _patch->connections().clear();
+ delete _ports_array;
+ delete _driver_port;
// Restore patch's run state
if (_process)
@@ -105,8 +115,9 @@ ClearPatchEvent::post_process()
// Make sure everything's sane
assert(_patch->nodes().size() == 0);
+ assert(_patch->num_ports() == 0);
assert(_patch->connections().size() == 0);
-
+
// Reply
_responder->respond_ok();
_engine.broadcaster()->send_patch_cleared(_patch_path);
diff --git a/src/libs/engine/events/ClearPatchEvent.hpp b/src/libs/engine/events/ClearPatchEvent.hpp
index afe66eed..0353dc01 100644
--- a/src/libs/engine/events/ClearPatchEvent.hpp
+++ b/src/libs/engine/events/ClearPatchEvent.hpp
@@ -20,13 +20,18 @@
#include <string>
#include <raul/Array.hpp>
+#include <raul/Table.hpp>
+#include <raul/Path.hpp>
#include "QueuedEvent.hpp"
+#include "ObjectStore.hpp"
+#include "PatchImpl.hpp"
using std::string;
namespace Ingen {
class PatchImpl;
+class DriverPort;
/** Delete all nodes from a patch.
@@ -43,9 +48,14 @@ public:
void post_process();
private:
- const string _patch_path;
- PatchImpl* _patch;
- bool _process;
+ const string _patch_path;
+ SharedPtr<PatchImpl> _patch;
+ DriverPort* _driver_port;
+ bool _process;
+ Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch
+ CompiledPatch* _compiled_patch; ///< Patch's new process order
+
+ SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table;
};
diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp
index d2b2d42b..4f2cba3f 100644
--- a/src/libs/engine/events/DestroyEvent.cpp
+++ b/src/libs/engine/events/DestroyEvent.cpp
@@ -199,8 +199,7 @@ DestroyEvent::post_process()
_responder->respond_error("Unable to destroy object");
}
- if (_driver_port)
- delete _driver_port;
+ delete _driver_port;
}
diff --git a/src/libs/engine/events/DestroyEvent.hpp b/src/libs/engine/events/DestroyEvent.hpp
index 4a82c5bb..134290b1 100644
--- a/src/libs/engine/events/DestroyEvent.hpp
+++ b/src/libs/engine/events/DestroyEvent.hpp
@@ -60,7 +60,6 @@ public:
private:
Path _path;
ObjectStore::Objects::iterator _store_iterator;
- SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table;
SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node
SharedPtr<PortImpl> _port; ///< Non-NULL iff a port
DriverPort* _driver_port;
@@ -70,6 +69,8 @@ private:
CompiledPatch* _compiled_patch; ///< Patch's new process order
DisconnectNodeEvent* _disconnect_node_event;
DisconnectPortEvent* _disconnect_port_event;
+
+ SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table;
};