From 664f3ca29832b7ec0432d1e46c6af901af68f574 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Jun 2009 00:59:51 +0000 Subject: Consistent imperative style event names. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2067 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/events.hpp | 6 +- src/engine/events/Connect.cpp | 204 ++++++++++++++++++++++++++++++++++ src/engine/events/Connect.hpp | 90 +++++++++++++++ src/engine/events/Connection.cpp | 204 ---------------------------------- src/engine/events/Connection.hpp | 90 --------------- src/engine/events/Disconnect.cpp | 212 ++++++++++++++++++++++++++++++++++++ src/engine/events/Disconnect.hpp | 88 +++++++++++++++ src/engine/events/DisconnectAll.cpp | 2 +- src/engine/events/Disconnection.cpp | 212 ------------------------------------ src/engine/events/Disconnection.hpp | 88 --------------- src/engine/events/Ping.hpp | 48 ++++++++ src/engine/events/PingQueued.hpp | 48 -------- src/engine/wscript | 4 +- 13 files changed, 648 insertions(+), 648 deletions(-) create mode 100644 src/engine/events/Connect.cpp create mode 100644 src/engine/events/Connect.hpp delete mode 100644 src/engine/events/Connection.cpp delete mode 100644 src/engine/events/Connection.hpp create mode 100644 src/engine/events/Disconnect.cpp create mode 100644 src/engine/events/Disconnect.hpp delete mode 100644 src/engine/events/Disconnection.cpp delete mode 100644 src/engine/events/Disconnection.hpp create mode 100644 src/engine/events/Ping.hpp delete mode 100644 src/engine/events/PingQueued.hpp (limited to 'src/engine') diff --git a/src/engine/events.hpp b/src/engine/events.hpp index 6c407428..0164bdb3 100644 --- a/src/engine/events.hpp +++ b/src/engine/events.hpp @@ -22,20 +22,20 @@ #include "events/AllNotesOff.hpp" #include "events/ClearPatch.hpp" -#include "events/Connection.hpp" +#include "events/Connect.hpp" #include "events/CreateNode.hpp" #include "events/CreatePatch.hpp" #include "events/CreatePort.hpp" #include "events/Deactivate.hpp" #include "events/Delete.hpp" +#include "events/Disconnect.hpp" #include "events/DisconnectAll.hpp" -#include "events/Disconnection.hpp" #include "events/Get.hpp" #include "events/LoadPlugins.hpp" #include "events/MidiLearn.hpp" #include "events/Move.hpp" #include "events/Note.hpp" -#include "events/PingQueued.hpp" +#include "events/Ping.hpp" #include "events/RegisterClient.hpp" #include "events/RequestAllObjects.hpp" #include "events/RequestMetadata.hpp" diff --git a/src/engine/events/Connect.cpp b/src/engine/events/Connect.cpp new file mode 100644 index 00000000..d6da9067 --- /dev/null +++ b/src/engine/events/Connect.cpp @@ -0,0 +1,204 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include +#include "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "ClientBroadcaster.hpp" +#include "Connect.hpp" +#include "ConnectionImpl.hpp" +#include "Engine.hpp" +#include "InputPort.hpp" +#include "EngineStore.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "PortImpl.hpp" +#include "Responder.hpp" +#include "types.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& src_port_path, const Path& dst_port_path) + : QueuedEvent(engine, responder, timestamp) + , _src_port_path(src_port_path) + , _dst_port_path(dst_port_path) + , _patch(NULL) + , _src_port(NULL) + , _dst_port(NULL) + , _compiled_patch(NULL) + , _patch_listnode(NULL) + , _port_listnode(NULL) + , _error(NO_ERROR) +{ +} + + +void +ConnectionEvent::pre_process() +{ + if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() + && _src_port_path.parent() != _dst_port_path.parent().parent() + && _src_port_path.parent().parent() != _dst_port_path.parent()) { + _error = PARENT_PATCH_DIFFERENT; + QueuedEvent::pre_process(); + return; + } + + _src_port = _engine.engine_store()->find_port(_src_port_path); + _dst_port = _engine.engine_store()->find_port(_dst_port_path); + + if (_src_port == NULL || _dst_port == NULL) { + _error = PORT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if ( ! (_src_port->type() == _dst_port->type() + || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) + && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { + _error = TYPE_MISMATCH; + QueuedEvent::pre_process(); + return; + } + + _dst_input_port = dynamic_cast(_dst_port); + _src_output_port = dynamic_cast(_src_port); + + if (!_dst_input_port || !_src_output_port) { + _error = DIRECTION_MISMATCH; + QueuedEvent::pre_process(); + return; + } + + NodeImpl* const src_node = _src_port->parent_node(); + NodeImpl* const dst_node = _dst_port->parent_node(); + + // Connection to a patch port from inside the patch + if (src_node->parent_patch() != dst_node->parent_patch()) { + + assert(src_node->parent() == dst_node || dst_node->parent() == src_node); + if (src_node->parent() == dst_node) + _patch = dynamic_cast(dst_node); + else + _patch = dynamic_cast(src_node); + + // Connection from a patch input to a patch output (pass through) + } else if (src_node == dst_node && dynamic_cast(src_node)) { + _patch = dynamic_cast(src_node); + + // Normal connection between nodes with the same parent + } else { + _patch = src_node->parent_patch(); + } + + assert(_patch); + + if (_patch->has_connection(_src_output_port, _dst_input_port)) { + _error = ALREADY_CONNECTED; + QueuedEvent::pre_process(); + return; + } + + if (src_node == NULL || dst_node == NULL) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + _connection = SharedPtr(new ConnectionImpl(_src_port, _dst_port)); + _patch_listnode = new PatchImpl::Connections::Node(_connection); + _port_listnode = new InputPort::Connections::Node(_connection); + + // Need to be careful about patch port connections here and adding a node's + // parent as a dependant/provider, or adding a patch as it's own provider... + if (src_node != dst_node && src_node->parent() == dst_node->parent()) { + dst_node->providers()->push_back(new Raul::List::Node(src_node)); + src_node->dependants()->push_back(new Raul::List::Node(dst_node)); + } + + _patch->add_connection(_patch_listnode); + + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + + QueuedEvent::pre_process(); +} + + +void +ConnectionEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + // This must be inserted here, since they're actually used by the audio thread + _dst_input_port->add_connection(_port_listnode); + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } +} + + +void +ConnectionEvent::post_process() +{ + std::ostringstream ss; + if (_error == NO_ERROR) { + _responder->respond_ok(); + _engine.broadcaster()->send_connection(_connection); + return; + } + + ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; + + switch (_error) { + case PARENT_PATCH_DIFFERENT: + ss << "Ports have mismatched parents"; break; + case PORT_NOT_FOUND: + ss << "Port not found"; break; + case TYPE_MISMATCH: + ss << "Type mismatch"; break; + case DIRECTION_MISMATCH: + ss << "Direction mismatch"; break; + case ALREADY_CONNECTED: + ss << "Already connected"; break; + case PARENTS_NOT_FOUND: + ss << "Parents not found"; break; + default: + ss << "Unknown error"; + } + ss << ")"; + _responder->respond_error(ss.str()); +} + + +} // namespace Ingen + diff --git a/src/engine/events/Connect.hpp b/src/engine/events/Connect.hpp new file mode 100644 index 00000000..b1f4bf6c --- /dev/null +++ b/src/engine/events/Connect.hpp @@ -0,0 +1,90 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CONNECTIONEVENT_H +#define CONNECTIONEVENT_H + +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "PatchImpl.hpp" +#include "InputPort.hpp" +#include "types.hpp" + +namespace Raul { + template class ListNode; + template class Array; +} + +namespace Ingen { + +class PatchImpl; +class NodeImpl; +class ConnectionImpl; +class MidiMessage; +class PortImpl; +class InputPort; +class OutputPort; +class CompiledPatch; + + +/** Make a Connection between two Ports. + * + * \ingroup engine + */ +class ConnectionEvent : public QueuedEvent +{ +public: + ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + + enum ErrorType { + NO_ERROR, + PARENT_PATCH_DIFFERENT, + PORT_NOT_FOUND, + TYPE_MISMATCH, + DIRECTION_MISMATCH, + ALREADY_CONNECTED, + PARENTS_NOT_FOUND + }; + + Raul::Path _src_port_path; + Raul::Path _dst_port_path; + + PatchImpl* _patch; + PortImpl* _src_port; + PortImpl* _dst_port; + OutputPort* _src_output_port; + InputPort* _dst_input_port; + + CompiledPatch* _compiled_patch; ///< New process order for Patch + + SharedPtr _connection; + PatchImpl::Connections::Node* _patch_listnode; + InputPort::Connections::Node* _port_listnode; + + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // CONNECTIONEVENT_H diff --git a/src/engine/events/Connection.cpp b/src/engine/events/Connection.cpp deleted file mode 100644 index 08ba49d5..00000000 --- a/src/engine/events/Connection.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 -#include -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "ClientBroadcaster.hpp" -#include "Connection.hpp" -#include "ConnectionImpl.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "types.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& src_port_path, const Path& dst_port_path) - : QueuedEvent(engine, responder, timestamp) - , _src_port_path(src_port_path) - , _dst_port_path(dst_port_path) - , _patch(NULL) - , _src_port(NULL) - , _dst_port(NULL) - , _compiled_patch(NULL) - , _patch_listnode(NULL) - , _port_listnode(NULL) - , _error(NO_ERROR) -{ -} - - -void -ConnectionEvent::pre_process() -{ - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if ( ! (_src_port->type() == _dst_port->type() - || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) - && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { - _error = TYPE_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast(_dst_port); - _src_output_port = dynamic_cast(_src_port); - - if (!_dst_input_port || !_src_output_port) { - _error = DIRECTION_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast(dst_node); - else - _patch = dynamic_cast(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast(src_node)) { - _patch = dynamic_cast(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - if (_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = ALREADY_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _connection = SharedPtr(new ConnectionImpl(_src_port, _dst_port)); - _patch_listnode = new PatchImpl::Connections::Node(_connection); - _port_listnode = new InputPort::Connections::Node(_connection); - - // Need to be careful about patch port connections here and adding a node's - // parent as a dependant/provider, or adding a patch as it's own provider... - if (src_node != dst_node && src_node->parent() == dst_node->parent()) { - dst_node->providers()->push_back(new Raul::List::Node(src_node)); - src_node->dependants()->push_back(new Raul::List::Node(dst_node)); - } - - _patch->add_connection(_patch_listnode); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -ConnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - // This must be inserted here, since they're actually used by the audio thread - _dst_input_port->add_connection(_port_listnode); - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -ConnectionEvent::post_process() -{ - std::ostringstream ss; - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_connection(_connection); - return; - } - - ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; - - switch (_error) { - case PARENT_PATCH_DIFFERENT: - ss << "Ports have mismatched parents"; break; - case PORT_NOT_FOUND: - ss << "Port not found"; break; - case TYPE_MISMATCH: - ss << "Type mismatch"; break; - case DIRECTION_MISMATCH: - ss << "Direction mismatch"; break; - case ALREADY_CONNECTED: - ss << "Already connected"; break; - case PARENTS_NOT_FOUND: - ss << "Parents not found"; break; - default: - ss << "Unknown error"; - } - ss << ")"; - _responder->respond_error(ss.str()); -} - - -} // namespace Ingen - diff --git a/src/engine/events/Connection.hpp b/src/engine/events/Connection.hpp deleted file mode 100644 index b1f4bf6c..00000000 --- a/src/engine/events/Connection.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CONNECTIONEVENT_H -#define CONNECTIONEVENT_H - -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "PatchImpl.hpp" -#include "InputPort.hpp" -#include "types.hpp" - -namespace Raul { - template class ListNode; - template class Array; -} - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class ConnectionEvent : public QueuedEvent -{ -public: - ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - DIRECTION_MISMATCH, - ALREADY_CONNECTED, - PARENTS_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - CompiledPatch* _compiled_patch; ///< New process order for Patch - - SharedPtr _connection; - PatchImpl::Connections::Node* _patch_listnode; - InputPort::Connections::Node* _port_listnode; - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // CONNECTIONEVENT_H diff --git a/src/engine/events/Disconnect.cpp b/src/engine/events/Disconnect.cpp new file mode 100644 index 00000000..e6d9b53d --- /dev/null +++ b/src/engine/events/Disconnect.cpp @@ -0,0 +1,212 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "events/Disconnect.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "ConnectionImpl.hpp" +#include "InputPort.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "ClientBroadcaster.hpp" +#include "PortImpl.hpp" +#include "EngineStore.hpp" + +using namespace std; + +namespace Ingen { + + +//// DisconnectionEvent //// + + +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path) + : QueuedEvent(engine, responder, timestamp) + , _src_port_path(src_port_path) + , _dst_port_path(dst_port_path) + , _patch(NULL) + , _src_port(NULL) + , _dst_port(NULL) + , _lookup(true) + , _patch_connection(NULL) + , _compiled_patch(NULL) + , _error(NO_ERROR) +{ +} + + +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) +: QueuedEvent(engine, responder, timestamp), + _src_port_path(src_port->path()), + _dst_port_path(dst_port->path()), + _patch(src_port->parent_node()->parent_patch()), + _src_port(src_port), + _dst_port(dst_port), + _lookup(false), + _compiled_patch(NULL), + _error(NO_ERROR) +{ + // FIXME: These break for patch ports.. is that ok? + /*assert(src_port->is_output()); + assert(dst_port->is_input()); + assert(src_port->type() == dst_port->type()); + assert(src_port->parent_node()->parent_patch() + == dst_port->parent_node()->parent_patch()); */ +} + + +void +DisconnectionEvent::pre_process() +{ + if (_lookup) { + if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() + && _src_port_path.parent() != _dst_port_path.parent().parent() + && _src_port_path.parent().parent() != _dst_port_path.parent()) { + _error = PARENT_PATCH_DIFFERENT; + QueuedEvent::pre_process(); + return; + } + + _src_port = _engine.engine_store()->find_port(_src_port_path); + _dst_port = _engine.engine_store()->find_port(_dst_port_path); + } + + if (_src_port == NULL || _dst_port == NULL) { + _error = PORT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + _dst_input_port = dynamic_cast(_dst_port); + _src_output_port = dynamic_cast(_src_port); + assert(_src_output_port); + assert(_dst_input_port); + + NodeImpl* const src_node = _src_port->parent_node(); + NodeImpl* const dst_node = _dst_port->parent_node(); + + // Connection to a patch port from inside the patch + if (src_node->parent_patch() != dst_node->parent_patch()) { + + assert(src_node->parent() == dst_node || dst_node->parent() == src_node); + if (src_node->parent() == dst_node) + _patch = dynamic_cast(dst_node); + else + _patch = dynamic_cast(src_node); + + // Connection from a patch input to a patch output (pass through) + } else if (src_node == dst_node && dynamic_cast(src_node)) { + _patch = dynamic_cast(src_node); + + // Normal connection between nodes with the same parent + } else { + _patch = src_node->parent_patch(); + } + + assert(_patch); + + if (!_patch->has_connection(_src_output_port, _dst_input_port)) { + _error = NOT_CONNECTED; + QueuedEvent::pre_process(); + return; + } + + if (src_node == NULL || dst_node == NULL) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + for (Raul::List::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) + if ((*i) == src_node) { + delete dst_node->providers()->erase(i); + break; + } + + for (Raul::List::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) + if ((*i) == dst_node) { + delete src_node->dependants()->erase(i); + break; + } + + _patch_connection = _patch->remove_connection(_src_port, _dst_port); + + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + + QueuedEvent::pre_process(); +} + + +void +DisconnectionEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + InputPort::Connections::Node* const port_connection + = _dst_input_port->remove_connection(_src_output_port); + + if (port_connection != NULL) { + assert(_patch_connection); + + if (port_connection->elem() != _patch_connection->elem()) { + cerr << "ERROR: Corrupt connections:" << endl; + cerr << "\t" << port_connection->elem() << ": " + << port_connection->elem()->src_port_path() + << " -> " << port_connection->elem()->dst_port_path() << endl + << "!=" << endl + << "\t" << _patch_connection->elem() << ": " + << _patch_connection->elem()->src_port_path() + << " -> " << _patch_connection->elem()->dst_port_path() << endl; + } + assert(port_connection->elem() == _patch_connection->elem()); + + // Destroy list node, which will drop reference to connection itself + _engine.maid()->push(port_connection); + _engine.maid()->push(_patch_connection); + + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } else { + _error = CONNECTION_NOT_FOUND; + } + } +} + + +void +DisconnectionEvent::post_process() +{ + if (_error == NO_ERROR) { + _responder->respond_ok(); + _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); + } else { + // FIXME: better error messages + string msg = "Unable to disconnect "; + msg.append(_src_port_path.str() + " -> " + _dst_port_path.str()); + cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; + _responder->respond_error(msg); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/Disconnect.hpp b/src/engine/events/Disconnect.hpp new file mode 100644 index 00000000..24766462 --- /dev/null +++ b/src/engine/events/Disconnect.hpp @@ -0,0 +1,88 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 DISCONNECTIONEVENT_H +#define DISCONNECTIONEVENT_H + +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "types.hpp" +#include "PatchImpl.hpp" + +namespace Raul { + template class ListNode; + template class Array; +} + +namespace Ingen { + +class NodeImpl; +class ConnectionImpl; +class MidiMessage; +class PortImpl; +class InputPort; +class OutputPort; +class CompiledPatch; + + +/** Make a Connection between two Ports. + * + * \ingroup engine + */ +class DisconnectionEvent : public QueuedEvent +{ +public: + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + + enum ErrorType { + NO_ERROR, + PARENT_PATCH_DIFFERENT, + PORT_NOT_FOUND, + TYPE_MISMATCH, + NOT_CONNECTED, + PARENTS_NOT_FOUND, + CONNECTION_NOT_FOUND + }; + + Raul::Path _src_port_path; + Raul::Path _dst_port_path; + + PatchImpl* _patch; + PortImpl* _src_port; + PortImpl* _dst_port; + OutputPort* _src_output_port; + InputPort* _dst_input_port; + + bool _lookup; + + PatchImpl::Connections::Node* _patch_connection; + CompiledPatch* _compiled_patch; ///< New process order for Patch + + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // DISCONNECTIONEVENT_H diff --git a/src/engine/events/DisconnectAll.cpp b/src/engine/events/DisconnectAll.cpp index 4fa643ea..2ab96394 100644 --- a/src/engine/events/DisconnectAll.cpp +++ b/src/engine/events/DisconnectAll.cpp @@ -23,7 +23,7 @@ #include "ClientBroadcaster.hpp" #include "ConnectionImpl.hpp" #include "events/DisconnectAll.hpp" -#include "events/Disconnection.hpp" +#include "events/Disconnect.hpp" #include "Engine.hpp" #include "InputPort.hpp" #include "NodeImpl.hpp" diff --git a/src/engine/events/Disconnection.cpp b/src/engine/events/Disconnection.cpp deleted file mode 100644 index fcbd643b..00000000 --- a/src/engine/events/Disconnection.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "events/Disconnection.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ConnectionImpl.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" - -using namespace std; - -namespace Ingen { - - -//// DisconnectionEvent //// - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path) - : QueuedEvent(engine, responder, timestamp) - , _src_port_path(src_port_path) - , _dst_port_path(dst_port_path) - , _patch(NULL) - , _src_port(NULL) - , _dst_port(NULL) - , _lookup(true) - , _patch_connection(NULL) - , _compiled_patch(NULL) - , _error(NO_ERROR) -{ -} - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port->path()), - _dst_port_path(dst_port->path()), - _patch(src_port->parent_node()->parent_patch()), - _src_port(src_port), - _dst_port(dst_port), - _lookup(false), - _compiled_patch(NULL), - _error(NO_ERROR) -{ - // FIXME: These break for patch ports.. is that ok? - /*assert(src_port->is_output()); - assert(dst_port->is_input()); - assert(src_port->type() == dst_port->type()); - assert(src_port->parent_node()->parent_patch() - == dst_port->parent_node()->parent_patch()); */ -} - - -void -DisconnectionEvent::pre_process() -{ - if (_lookup) { - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - } - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast(_dst_port); - _src_output_port = dynamic_cast(_src_port); - assert(_src_output_port); - assert(_dst_input_port); - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast(dst_node); - else - _patch = dynamic_cast(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast(src_node)) { - _patch = dynamic_cast(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - if (!_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = NOT_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - for (Raul::List::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) - if ((*i) == src_node) { - delete dst_node->providers()->erase(i); - break; - } - - for (Raul::List::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) - if ((*i) == dst_node) { - delete src_node->dependants()->erase(i); - break; - } - - _patch_connection = _patch->remove_connection(_src_port, _dst_port); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -DisconnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - InputPort::Connections::Node* const port_connection - = _dst_input_port->remove_connection(_src_output_port); - - if (port_connection != NULL) { - assert(_patch_connection); - - if (port_connection->elem() != _patch_connection->elem()) { - cerr << "ERROR: Corrupt connections:" << endl; - cerr << "\t" << port_connection->elem() << ": " - << port_connection->elem()->src_port_path() - << " -> " << port_connection->elem()->dst_port_path() << endl - << "!=" << endl - << "\t" << _patch_connection->elem() << ": " - << _patch_connection->elem()->src_port_path() - << " -> " << _patch_connection->elem()->dst_port_path() << endl; - } - assert(port_connection->elem() == _patch_connection->elem()); - - // Destroy list node, which will drop reference to connection itself - _engine.maid()->push(port_connection); - _engine.maid()->push(_patch_connection); - - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } else { - _error = CONNECTION_NOT_FOUND; - } - } -} - - -void -DisconnectionEvent::post_process() -{ - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); - } else { - // FIXME: better error messages - string msg = "Unable to disconnect "; - msg.append(_src_port_path.str() + " -> " + _dst_port_path.str()); - cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/Disconnection.hpp b/src/engine/events/Disconnection.hpp deleted file mode 100644 index 24766462..00000000 --- a/src/engine/events/Disconnection.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 DISCONNECTIONEVENT_H -#define DISCONNECTIONEVENT_H - -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "PatchImpl.hpp" - -namespace Raul { - template class ListNode; - template class Array; -} - -namespace Ingen { - -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class DisconnectionEvent : public QueuedEvent -{ -public: - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - NOT_CONNECTED, - PARENTS_NOT_FOUND, - CONNECTION_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - bool _lookup; - - PatchImpl::Connections::Node* _patch_connection; - CompiledPatch* _compiled_patch; ///< New process order for Patch - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // DISCONNECTIONEVENT_H diff --git a/src/engine/events/Ping.hpp b/src/engine/events/Ping.hpp new file mode 100644 index 00000000..108948a0 --- /dev/null +++ b/src/engine/events/Ping.hpp @@ -0,0 +1,48 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 PINGQUEUEDEVENT_H +#define PINGQUEUEDEVENT_H + +#include "QueuedEvent.hpp" +#include "types.hpp" +#include "Responder.hpp" + +namespace Ingen { + +class PortImpl; + + +/** A ping that travels through the pre-processed event queue before responding + * (useful for the order guarantee). + * + * \ingroup engine + */ +class PingQueuedEvent : public QueuedEvent +{ +public: + PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) + : QueuedEvent(engine, responder, timestamp) + {} + + void post_process() { _responder->respond_ok(); } +}; + + +} // namespace Ingen + +#endif // PINGQUEUEDEVENT_H diff --git a/src/engine/events/PingQueued.hpp b/src/engine/events/PingQueued.hpp deleted file mode 100644 index 108948a0..00000000 --- a/src/engine/events/PingQueued.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 PINGQUEUEDEVENT_H -#define PINGQUEUEDEVENT_H - -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "Responder.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A ping that travels through the pre-processed event queue before responding - * (useful for the order guarantee). - * - * \ingroup engine - */ -class PingQueuedEvent : public QueuedEvent -{ -public: - PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) - : QueuedEvent(engine, responder, timestamp) - {} - - void post_process() { _responder->respond_ok(); } -}; - - -} // namespace Ingen - -#endif // PINGQUEUEDEVENT_H diff --git a/src/engine/wscript b/src/engine/wscript index 298cbce8..e869534a 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -58,13 +58,13 @@ def build(bld): QueuedEventSource.cpp events/AllNotesOff.cpp events/ClearPatch.cpp - events/Connection.cpp + events/Connect.cpp events/CreateNode.cpp events/CreatePatch.cpp events/CreatePort.cpp events/Delete.cpp + events/Disconnect.cpp events/DisconnectAll.cpp - events/Disconnection.cpp events/Get.cpp events/LoadPlugins.cpp events/MidiLearn.cpp -- cgit v1.2.1