From 8223f1b24afe7d38454c6d12eb2f6bb2e5b1335d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 15 May 2012 17:46:56 +0000 Subject: Fix crash when loading patches from the command line. Remove unnecessary fields from CreateNode event. Clean up CreateNode event and fix bugs. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4418 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/PatchImpl.cpp | 12 ++--- src/server/events/CreateNode.cpp | 102 +++++++++++++++++++------------------- src/server/events/CreateNode.hpp | 4 -- src/server/events/CreatePatch.cpp | 7 +-- src/server/events/CreatePort.hpp | 1 - src/server/events/Get.cpp | 18 +++---- 6 files changed, 70 insertions(+), 74 deletions(-) (limited to 'src/server') diff --git a/src/server/PatchImpl.cpp b/src/server/PatchImpl.cpp index 89a7a699..fefc797e 100644 --- a/src/server/PatchImpl.cpp +++ b/src/server/PatchImpl.cpp @@ -157,19 +157,19 @@ PatchImpl::process(ProcessContext& context) NodeImpl::pre_process(context); - // Run all nodes if (_compiled_patch && _compiled_patch->size() > 0) { + // Run all nodes if (context.slaves().size() > 0) { process_parallel(context); } else { process_single(context); } - } - // Queue any cross-context edges - for (CompiledPatch::QueuedEdges::iterator i = _compiled_patch->queued_edges.begin(); - i != _compiled_patch->queued_edges.end(); ++i) { - (*i)->queue(context); + // Queue any cross-context edges + for (CompiledPatch::QueuedEdges::iterator i = _compiled_patch->queued_edges.begin(); + i != _compiled_patch->queued_edges.end(); ++i) { + (*i)->queue(context); + } } NodeImpl::post_process(context); diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp index 87ecd657..4c2d1382 100644 --- a/src/server/events/CreateNode.cpp +++ b/src/server/events/CreateNode.cpp @@ -22,7 +22,6 @@ #include "Broadcaster.hpp" #include "CreateNode.hpp" -#include "Driver.hpp" #include "Engine.hpp" #include "EngineStore.hpp" #include "NodeFactory.hpp" @@ -47,63 +46,73 @@ CreateNode::CreateNode(Engine& engine, , _plugin_uri(plugin_uri) , _properties(properties) , _patch(NULL) - , _plugin(NULL) , _node(NULL) , _compiled_patch(NULL) - , _node_already_exists(false) - , _polyphonic(false) -{ - const Resource::Properties::const_iterator p = properties.find( - engine.world()->uris().ingen_polyphonic); - if (p != properties.end() && p->second.type() == engine.world()->forge().Bool - && p->second.get_bool()) - _polyphonic = true; -} +{} void CreateNode::pre_process() { - if (_engine.engine_store()->find_object(_path) != NULL) { - _node_already_exists = true; + Ingen::Shared::URIs& uris = _engine.world()->uris(); + + if (_engine.engine_store()->find_object(_path)) { + _status = EXISTS; Event::pre_process(); return; } - _patch = _engine.engine_store()->find_patch(_path.parent()); - _plugin = _engine.node_factory()->plugin(_plugin_uri.str()); + if (!(_patch = _engine.engine_store()->find_patch(_path.parent()))) { + _status = PARENT_NOT_FOUND; + Event::pre_process(); + return; + } - if (_patch && _plugin) { + PluginImpl* plugin = _engine.node_factory()->plugin(_plugin_uri.str()); + if (!plugin) { + _status = PLUGIN_NOT_FOUND; + Event::pre_process(); + return; + } - _node = _plugin->instantiate(*_engine.buffer_factory(), _path.symbol(), _polyphonic, _patch, _engine); + const Resource::Properties::const_iterator p = _properties.find( + _engine.world()->uris().ingen_polyphonic); + const bool polyphonic = ( + p != _properties.end() && + p->second.type() == _engine.world()->forge().Bool && + p->second.get_bool()); + + if (!(_node = plugin->instantiate(*_engine.buffer_factory(), + _path.symbol(), + polyphonic, + _patch, + _engine))) { + _status = CREATION_FAILED; + Event::pre_process(); + return; + } - if (_node != NULL) { - _node->properties().insert(_properties.begin(), _properties.end()); - _node->activate(*_engine.buffer_factory()); + _node->properties().insert(_properties.begin(), _properties.end()); + _node->activate(*_engine.buffer_factory()); - // This can be done here because the audio thread doesn't touch the - // node tree - just the process order array - _patch->add_node(new PatchImpl::Nodes::Node(_node)); - _engine.engine_store()->add(_node); + // Add node to the store and the patch's pre-processor only node list + _patch->add_node(new PatchImpl::Nodes::Node(_node)); + _engine.engine_store()->add(_node); - // FIXME: not really necessary to build process order since it's not connected, - // just append to the list - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } + /* Compile patch with new node added for insertion in audio thread + TODO: Since the node is not connected at this point, a full compilation + could be avoided and the node simply appended. */ + if (_patch->enabled()) { + _compiled_patch = _patch->compile(); + assert(_compiled_patch); } - if (_node) { - Ingen::Shared::URIs& uris = _engine.world()->uris(); - _update.push_back(make_pair(_node->path(), _node->properties())); - for (uint32_t i = 0; i < _node->num_ports(); ++i) { - const PortImpl* port = _node->port_impl(i); - Resource::Properties pprops = port->properties(); - pprops.erase(uris.ingen_value); - pprops.insert(std::make_pair(uris.ingen_value, port->value())); - _update.push_back(std::make_pair(port->path(), pprops)); - } - } else { - _status = FAILURE; + _update.push_back(make_pair(_node->path(), _node->properties())); + for (uint32_t i = 0; i < _node->num_ports(); ++i) { + const PortImpl* port = _node->port_impl(i); + Resource::Properties pprops = port->properties(); + pprops.erase(uris.ingen_value); + pprops.insert(std::make_pair(uris.ingen_value, port->value())); + _update.push_back(std::make_pair(port->path(), pprops)); } Event::pre_process(); @@ -123,14 +132,8 @@ CreateNode::execute(ProcessContext& context) void CreateNode::post_process() { - if (_node_already_exists) { - respond(EXISTS); - } else if (!_patch) { - respond(PARENT_NOT_FOUND); - } else if (!_plugin) { - respond(PLUGIN_NOT_FOUND); - } else if (!_node) { - respond(FAILURE); + if (_status) { + respond(_status); } else { respond(SUCCESS); for (Update::const_iterator i = _update.begin(); i != _update.end(); ++i) { @@ -142,4 +145,3 @@ CreateNode::post_process() } // namespace Events } // namespace Server } // namespace Ingen - diff --git a/src/server/events/CreateNode.hpp b/src/server/events/CreateNode.hpp index b3b84abf..95d504de 100644 --- a/src/server/events/CreateNode.hpp +++ b/src/server/events/CreateNode.hpp @@ -28,7 +28,6 @@ namespace Ingen { namespace Server { class PatchImpl; -class PluginImpl; class NodeImpl; class CompiledPatch; @@ -62,11 +61,8 @@ private: Resource::Properties _properties; Update _update; PatchImpl* _patch; - PluginImpl* _plugin; NodeImpl* _node; CompiledPatch* _compiled_patch; ///< Patch's new process order - bool _node_already_exists; - bool _polyphonic; }; } // namespace Events diff --git a/src/server/events/CreatePatch.cpp b/src/server/events/CreatePatch.cpp index 8bb381a2..92d7a5e3 100644 --- a/src/server/events/CreatePatch.cpp +++ b/src/server/events/CreatePatch.cpp @@ -85,11 +85,12 @@ CreatePatch::pre_process() _patch->add_property(uris.rdf_type, Resource::Property(uris.ingen_Node, Resource::EXTERNAL)); - if (_parent != NULL) { + if (_parent) { _parent->add_node(new PatchImpl::Nodes::Node(_patch)); - - if (_parent->enabled()) + if (_parent->enabled()) { + _patch->enable(); _compiled_patch = _parent->compile(); + } } _patch->activate(*_engine.buffer_factory()); diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp index 25f8ba9b..3b40136e 100644 --- a/src/server/events/CreatePort.hpp +++ b/src/server/events/CreatePort.hpp @@ -55,7 +55,6 @@ public: private: Raul::Path _path; - Raul::URI _type; PortType _port_type; LV2_URID _buffer_type; PatchImpl* _patch; diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index ac8db196..9558c6aa 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -79,17 +79,15 @@ Get::post_process() respond(NOT_FOUND); } else if (!_request_client) { respond(CLIENT_NOT_FOUND); + } else { + respond(SUCCESS); + if (_object) { + ObjectSender::send_object(_request_client, _object, true); + } else if (_plugin) { + _request_client->put(_uri, _plugin->properties()); + } + _lock.release(); } - - respond(SUCCESS); - - if (_object) { - ObjectSender::send_object(_request_client, _object, true); - } else if (_plugin) { - _request_client->put(_uri, _plugin->properties()); - } - - _lock.release(); } } // namespace Events -- cgit v1.2.1