From 138a87e915ad3aff184730415105f94c874174bf Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 20 Apr 2011 16:26:40 +0000 Subject: Rename Ingen::Engine to Ingen::Server (hopefully avoid odd name clases and fix #675). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3184 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/events/DisconnectAll.cpp | 189 ++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/server/events/DisconnectAll.cpp (limited to 'src/server/events/DisconnectAll.cpp') diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp new file mode 100644 index 00000000..dd694810 --- /dev/null +++ b/src/server/events/DisconnectAll.cpp @@ -0,0 +1,189 @@ +/* This file is part of Ingen. + * Copyright 2007-2011 David 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 "raul/Array.hpp" +#include "raul/Maid.hpp" +#include "raul/Path.hpp" + +#include "ClientBroadcaster.hpp" +#include "ConnectionImpl.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "InputPort.hpp" +#include "NodeImpl.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "PortImpl.hpp" +#include "Request.hpp" +#include "events/Disconnect.hpp" +#include "events/DisconnectAll.hpp" +#include "util.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { +namespace Server { +namespace Events { + +DisconnectAll::DisconnectAll(Engine& engine, SharedPtr request, SampleCount timestamp, const Path& parent_path, const Path& node_path) + : QueuedEvent(engine, request, timestamp) + , _parent_path(parent_path) + , _path(node_path) + , _parent(NULL) + , _node(NULL) + , _port(NULL) + , _compiled_patch(NULL) + , _deleting(false) +{ +} + +/** Internal version for use by other events. + */ +DisconnectAll::DisconnectAll(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) + : QueuedEvent(engine) + , _parent_path(parent->path()) + , _path(object->path()) + , _parent(parent) + , _node(dynamic_cast(object)) + , _port(dynamic_cast(object)) + , _compiled_patch(NULL) + , _deleting(true) +{ +} + +DisconnectAll::~DisconnectAll() +{ + for (Impls::iterator i = _impls.begin(); i != _impls.end(); ++i) + delete (*i); +} + +void +DisconnectAll::maybe_remove_connection(ConnectionImpl* c) +{ + if (c->pending_disconnection()) + return; + + OutputPort* src = dynamic_cast(c->src_port()); + InputPort* dst = dynamic_cast(c->dst_port()); + + if (_node) { + if (src->parent_node() == _node || dst->parent_node() == _node) { + _impls.push_back(new Disconnect::Impl(_engine, _parent, src, dst)); + } + } else { + assert(_port); + if (src == _port || dst == _port) { + _impls.push_back(new Disconnect::Impl(_engine, _parent, src, dst)); + } + } +} + +void +DisconnectAll::pre_process() +{ + if (!_deleting) { + _parent = _engine.engine_store()->find_patch(_parent_path); + + if (_parent == NULL) { + _error = PARENT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + GraphObjectImpl* object = _engine.engine_store()->find_object(_path); + + if (object == NULL) { + _error = OBJECT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { + _error = INVALID_PARENT_PATH; + QueuedEvent::pre_process(); + return; + } + + // Only one of these will succeed + _node = dynamic_cast(object); + _port = dynamic_cast(object); + + assert((_node || _port) && !(_node && _port)); + } + + for (Patch::Connections::const_iterator i = _parent->connections().begin(); + i != _parent->connections().end(); ++i) { + maybe_remove_connection((ConnectionImpl*)i->second.get()); + } + + if (!_deleting && _parent->enabled()) + _compiled_patch = _parent->compile(); + + QueuedEvent::pre_process(); +} + +void +DisconnectAll::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + for (Impls::iterator i = _impls.begin(); i != _impls.end(); ++i) { + (*i)->execute(context, + !_deleting || ((*i)->dst_port()->parent_node() != _node)); + } + } + + _engine.maid()->push(_parent->compiled_patch()); + _parent->compiled_patch(_compiled_patch); +} + +void +DisconnectAll::post_process() +{ + if (_error == NO_ERROR) { + if (_request) + _request->respond_ok(); + _engine.broadcaster()->disconnect_all(_parent_path, _path); + } else { + if (_request) { + boost::format fmt("Unable to disconnect %1% (%2%)"); + fmt % _path; + switch (_error) { + case INVALID_PARENT_PATH: + fmt % string("Invalid parent path: ").append(_parent_path.str()); + break; + case PARENT_NOT_FOUND: + fmt % string("Unable to find parent: ").append(_parent_path.str()); + break; + case OBJECT_NOT_FOUND: + fmt % string("Unable to find object"); + default: + break; + } + _request->respond_error(fmt.str()); + } + } +} + +} // namespace Server +} // namespace Ingen +} // namespace Events + -- cgit v1.2.1