From 98fe0e7056e6697396249531785d3899f94d79be Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 10 Jun 2006 01:52:02 +0000 Subject: More juggling git-svn-id: http://svn.drobilla.net/lad/grauph@15 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/Patch.cpp | 356 --------------------------------------------------- 1 file changed, 356 deletions(-) delete mode 100644 src/engine/Patch.cpp (limited to 'src/engine/Patch.cpp') diff --git a/src/engine/Patch.cpp b/src/engine/Patch.cpp deleted file mode 100644 index be938cae..00000000 --- a/src/engine/Patch.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include "Node.h" -#include "Patch.h" -#include "Plugin.h" -#include "Port.h" -#include "PortInfo.h" -#include "ClientBroadcaster.h" -#include "InternalNode.h" -#include "Connection.h" -#include "Om.h" -#include "OmApp.h" -#include "PortBase.h" -#include "ObjectStore.h" -#include "interface/ClientInterface.h" - -using std::cerr; using std::cout; using std::endl; - -namespace Om { - - -Patch::Patch(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size, size_t internal_poly) -: NodeBase(path, poly, parent, srate, buffer_size), - m_internal_poly(internal_poly), - m_process_order(NULL), - m_process(false) -{ - assert(internal_poly >= 1); - - m_plugin.type(Plugin::Patch); - m_plugin.lib_path(""); - m_plugin.plug_label("om_patch"); - m_plugin.name("Om patch"); - - //std::cerr << "Creating patch " << m_name << ", poly = " << poly - // << ", internal poly = " << internal_poly << std::endl; -} - - -Patch::~Patch() -{ - assert(!m_activated); - - for (List::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - delete (*i); - delete m_connections.remove(i); - } - - for (List::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { - assert(!(*i)->activated()); - delete (*i); - delete m_nodes.remove(i); - } - - delete m_process_order; -} - - -void -Patch::activate() -{ - NodeBase::activate(); - - for (List::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - (*i)->activate(); - - assert(m_activated); -} - - -void -Patch::deactivate() -{ - if (m_activated) { - - NodeBase::deactivate(); - - for (List::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { - if ((*i)->activated()) - (*i)->deactivate(); - assert(!(*i)->activated()); - } - } - assert(!m_activated); -} - - -void -Patch::process(bool b) -{ - if (!b) { - // Write output buffers to 0 - for (List::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { - assert((*i)->as_port() != NULL); - if ((*i)->as_port()->port_info()->is_output()) - (*i)->as_port()->clear_buffers(); - } - } - m_process = b; -} - - -/** Run the patch for the specified number of frames. - * - * Calls all Nodes in the order m_process_order specifies. - */ -inline void -Patch::run(size_t nframes) -{ - if (m_process_order == NULL || !m_process) - return; - - // Prepare all ports - for (List::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) - (*i)->as_port()->prepare_buffers(nframes); - - // Run all nodes - for (size_t i=0; i < m_process_order->size(); ++i) { - // Could be a gap due to a node removal event (see RemoveNodeEvent.cpp) - // If you're thinking this isn't very nice, you're right. - if (m_process_order->at(i) != NULL) - m_process_order->at(i)->run(nframes); - } -} - - -/** Returns the number of ports. - * - * Needs to override the NodeBase implementation since a Patch's ports are really - * just it's input and output nodes' ports. - */ -size_t -Patch::num_ports() const -{ - return m_bridge_nodes.size(); -} - - -#if 0 -void -Patch::send_creation_messages(ClientInterface* client) const -{ - cerr << "FIXME: creation\n"; - - om->client_broadcaster()->send_patch_to(client, this); - - for (List::const_iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) { - Node* node = (*j); - Port* port = node->as_port(); // NULL unless a bridge node - node->send_creation_messages(client); - - usleep(100); - - // If this is a bridge (input/output) node, send the patch control value as well - if (port != NULL && port->port_info()->is_control()) - om->client_broadcaster()->send_control_change_to(client, port->path(), - ((PortBase*)port)->buffer(0)->value_at(0)); - } - - for (List::const_iterator j = m_connections.begin(); j != m_connections.end(); ++j) { - om->client_broadcaster()->send_connection_to(client, *j); - } - - // Send port information - /*for (size_t i=0; i < m_ports.size(); ++i) { - Port* const port = m_ports.at(i); - - // Send metadata - const map& data = port->metadata(); - for (map::const_iterator i = data.begin(); i != data.end(); ++i) - om->client_broadcaster()->send_metadata_update_to(client, port->path(), (*i).first, (*i).second); - - if (port->port_info()->is_control()) - om->client_broadcaster()->send_control_change_to(client, port->path(), - ((PortBase*)port)->buffer(0)->value_at(0)); - }*/ -} -#endif - - -void -Patch::add_to_store() -{ - // Add self and ports - NodeBase::add_to_store(); - - // Add nodes - for (List::iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) - (*j)->add_to_store(); -} - - -void -Patch::remove_from_store() -{ - // Remove self and ports - NodeBase::remove_from_store(); - - // Remove nodes - for (List::iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) { - (*j)->remove_from_store(); - assert(om->object_store()->find((*j)->path()) == NULL); - } -} - - -// Patch specific stuff - - -void -Patch::add_node(ListNode* ln) -{ - assert(ln != NULL); - assert(ln->elem() != NULL); - assert(ln->elem()->parent_patch() == this); - assert(ln->elem()->poly() == m_internal_poly || ln->elem()->poly() == 1); - - m_nodes.push_back(ln); -} - - -ListNode* -Patch::remove_node(const string& name) -{ - for (List::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - if ((*i)->name() == name) - return m_nodes.remove(i); - - return NULL; -} - - -/** Remove a connection. Realtime safe. - */ -ListNode* -Patch::remove_connection(const Port* src_port, const Port* dst_port) -{ - bool found = false; - ListNode* connection = NULL; - for (List::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - if ((*i)->src_port() == src_port && (*i)->dst_port() == dst_port) { - connection = m_connections.remove(i); - found = true; - } - } - - if ( ! found) - cerr << "WARNING: [Patch::remove_connection] Connection not found !" << endl; - - return connection; -} - - -/** Remove a bridge_node. Realtime safe. - */ -ListNode* -Patch::remove_bridge_node(const InternalNode* node) -{ - bool found = false; - ListNode* bridge_node = NULL; - for (List::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { - if ((*i) == node) { - bridge_node = m_bridge_nodes.remove(i); - found = true; - } - } - - if ( ! found) - cerr << "WARNING: [Patch::remove_bridge_node] InternalNode not found !" << endl; - - return bridge_node; -} - - -/** Find the process order for this Patch. - * - * The process order is a flat list that the patch will execute in order - * when it's run() method is called. Return value is a newly allocated list - * which the caller is reponsible to delete. Note that this function does - * NOT actually set the process order, it is returned so it can be inserted - * at the beginning of an audio cycle (by various Events). - * - * This function is not realtime safe, due to the use of the List iterator - */ -Array* -Patch::build_process_order() const -{ - Node* node = NULL; - Array* const process_order = new Array(m_nodes.size()); - - for (List::const_iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - (*i)->traversed(false); - - // Traverse backwards starting at outputs - for (List::const_iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { - node = (*i); - assert(node->as_port() != NULL); - - // If the output node has been disconnected and has no connections left, don't traverse - // into it so it's not in the process order (and can be removed w/o flaming segfault death) - if (node->as_port()->port_info()->is_output() && node->providers()->size() > 0) - build_process_order_recursive(node, process_order); - } - - // Add any nodes that weren't hit by the traversal (disjoint nodes) - for (List::const_iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { - node = (*i); - if ( ! node->traversed()) { - process_order->push_back(*i); - node->traversed(true); - } - } - - assert(process_order->size() == m_nodes.size()); - - return process_order; -} - - -/** Rename this Patch. - * - * This is responsible for updating the ObjectStore so the Patch can be - * found at it's new path, as well as all it's children. - */ -void -Patch::set_path(const Path& new_path) -{ - const Path old_path = path(); - - // Update nodes - for (List::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - (*i)->set_path(new_path.base_path() + (*i)->name()); - - // Update self - NodeBase::set_path(new_path); -} - - -} // namespace Om -- cgit v1.2.1