/* 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 "PatchModel.hpp" #include "NodeModel.hpp" #include "ConnectionModel.hpp" #include "ClientStore.hpp" using namespace std; using namespace Raul; namespace Ingen { namespace Client { void PatchModel::add_child(SharedPtr c) { assert(c->parent().get() == this); SharedPtr pm = PtrCast(c); if (pm) { add_port(pm); return; } SharedPtr nm = PtrCast(c); if (nm) signal_new_node.emit(nm); } bool PatchModel::remove_child(SharedPtr o) { assert(o->path().is_child_of(_path)); assert(o->parent().get() == this); SharedPtr pm = PtrCast(o); if (pm) remove_port(pm); // Remove any connections which referred to this object, // since they can't possibly exist anymore for (Connections::iterator j = _connections->begin(); j != _connections->end() ; ) { Connections::iterator next = j; ++next; SharedPtr cm = PtrCast(*j); assert(cm); if (cm->src_port_path().parent() == o->path() || cm->src_port_path() == o->path() || cm->dst_port_path().parent() == o->path() || cm->dst_port_path() == o->path()) { signal_removed_connection.emit(cm); _connections->erase(j); // cuts our reference assert(!get_connection(cm->src_port_path(), cm->dst_port_path())); // no duplicates } j = next; } SharedPtr nm = PtrCast(o); if (nm) signal_removed_node.emit(nm); return true; } void PatchModel::clear() { _connections->clear(); NodeModel::clear(); assert(_connections->empty()); assert(_ports.empty()); } SharedPtr PatchModel::get_connection(const Path& src_port_path, const Path& dst_port_path) const { for (Connections::const_iterator i = _connections->begin(); i != _connections->end(); ++i) if ((*i)->src_port_path() == src_port_path && (*i)->dst_port_path() == dst_port_path) return PtrCast(*i); return SharedPtr(); } /** Add a connection to this patch. * * A reference to @a cm is taken, released on deletion or removal. * If @a cm only contains paths (not pointers to the actual ports), the ports * will be found and set. The ports referred to not existing as children of * this patch is a fatal error. */ void PatchModel::add_connection(SharedPtr cm) { // Store should have 'resolved' the connection already assert(cm); assert(cm->src_port()); assert(cm->dst_port()); assert(cm->src_port()->parent()); assert(cm->dst_port()->parent()); assert(cm->src_port_path() != cm->dst_port_path()); assert(cm->src_port()->parent().get() == this || cm->src_port()->parent()->parent().get() == this); assert(cm->dst_port()->parent().get() == this || cm->dst_port()->parent()->parent().get() == this); SharedPtr existing = get_connection(cm->src_port_path(), cm->dst_port_path()); if (existing) { assert(cm->src_port() == existing->src_port()); assert(cm->dst_port() == existing->dst_port()); } else { _connections->push_back(new Connections::Node(cm)); signal_new_connection.emit(cm); } } void PatchModel::remove_connection(const Path& src_port_path, const Path& dst_port_path) { for (Connections::iterator i = _connections->begin(); i != _connections->end(); ++i) { SharedPtr cm = PtrCast(*i); assert(cm); if (cm->src_port_path() == src_port_path && cm->dst_port_path() == dst_port_path) { signal_removed_connection.emit(cm); delete _connections->erase(i); // cuts our reference assert(!get_connection(src_port_path, dst_port_path)); // no duplicates return; } } cerr << "[PatchModel::remove_connection] WARNING: Failed to find connection " << src_port_path << " -> " << dst_port_path << endl; } bool PatchModel::enabled() const { const Raul::Atom& enabled = get_variable("ingen:enabled"); return (enabled.is_valid() && enabled.get_bool()); } void PatchModel::set_meta_property(const Raul::URI& key, const Atom& value) { NodeModel::set_meta_property(key, value); if (key.str() == "ingen:polyphony") _poly = value.get_int32(); } bool PatchModel::polyphonic() const { return (_parent) ? (_poly > 1) && _poly == PtrCast(_parent)->poly() && _poly > 1 : (_poly > 1); } } // namespace Client } // namespace Ingen