diff options
Diffstat (limited to 'src/libs/client')
32 files changed, 0 insertions, 5544 deletions
diff --git a/src/libs/client/ClientStore.cpp b/src/libs/client/ClientStore.cpp deleted file mode 100644 index 18582046..00000000 --- a/src/libs/client/ClientStore.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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/PathTable.hpp> -#include "ClientStore.hpp" -#include "ObjectModel.hpp" -#include "PatchModel.hpp" -#include "NodeModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" -#include "PatchModel.hpp" -#include "SigClientInterface.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -ClientStore::ClientStore(SharedPtr<EngineInterface> engine, SharedPtr<SigClientInterface> emitter) - : _engine(engine) - , _emitter(emitter) - , _plugins(new Plugins()) -{ - _handle_orphans = (engine && emitter); - - if (!emitter) - return; - - emitter->signal_object_destroyed.connect(sigc::mem_fun(this, &ClientStore::destroy)); - emitter->signal_object_renamed.connect(sigc::mem_fun(this, &ClientStore::rename)); - emitter->signal_new_plugin.connect(sigc::mem_fun(this, &ClientStore::new_plugin)); - emitter->signal_new_patch.connect(sigc::mem_fun(this, &ClientStore::new_patch)); - emitter->signal_new_node.connect(sigc::mem_fun(this, &ClientStore::new_node)); - emitter->signal_new_port.connect(sigc::mem_fun(this, &ClientStore::new_port)); - emitter->signal_patch_cleared.connect(sigc::mem_fun(this, &ClientStore::patch_cleared)); - emitter->signal_connection.connect(sigc::mem_fun(this, &ClientStore::connect)); - emitter->signal_disconnection.connect(sigc::mem_fun(this, &ClientStore::disconnect)); - emitter->signal_variable_change.connect(sigc::mem_fun(this, &ClientStore::set_variable)); - emitter->signal_property_change.connect(sigc::mem_fun(this, &ClientStore::set_property)); - emitter->signal_port_value.connect(sigc::mem_fun(this, &ClientStore::set_port_value)); - emitter->signal_voice_value.connect(sigc::mem_fun(this, &ClientStore::set_voice_value)); - emitter->signal_port_activity.connect(sigc::mem_fun(this, &ClientStore::port_activity)); -} - - -void -ClientStore::clear() -{ - Store::clear(); - _plugins->clear(); -} - - -void -ClientStore::add_plugin_orphan(SharedPtr<NodeModel> node) -{ - if (!_handle_orphans) - return; - - Raul::Table<string, list<SharedPtr<NodeModel> > >::iterator spawn - = _plugin_orphans.find(node->plugin_uri()); - - if (spawn != _plugin_orphans.end()) { - spawn->second.push_back(node); - } else { - cerr << "WARNING: Orphans of plugin " << node->plugin_uri() << " received" << endl; - _engine->request_plugin(node->plugin_uri()); - list<SharedPtr<NodeModel> > l; - l.push_back(node); - _plugin_orphans[node->plugin_uri()] = l; - } -} - - -void -ClientStore::resolve_plugin_orphans(SharedPtr<PluginModel> plugin) -{ - if (!_handle_orphans) - return; - Raul::Table<string, list<SharedPtr<NodeModel> > >::iterator n - = _plugin_orphans.find(plugin->uri()); - - if (n != _plugin_orphans.end()) { - - list<SharedPtr<NodeModel> > spawn = n->second; // take a copy - cerr << "Missing dependant " << plugin->uri() << " received" << endl; - - _plugin_orphans.erase(plugin->uri()); // prevent infinite recursion - - for (list<SharedPtr<NodeModel> >::iterator i = spawn.begin(); - i != spawn.end(); ++i) { - (*i)->_plugin = plugin; - //add_object(*i); - } - } -} - - -void -ClientStore::add_connection_orphan(std::pair<Path, Path> orphan) -{ - // Do this anyway, it's needed to get the connections for copy&paste - //if (!_handle_orphans) - //return; - - if (_handle_orphans) - cerr << "WARNING: Orphan connection " << orphan.first - << " -> " << orphan.second << " received." << endl; - - _connection_orphans.push_back(orphan); -} - - -void -ClientStore::resolve_connection_orphans(SharedPtr<PortModel> port) -{ - if (!_handle_orphans) - return; - assert(port->parent()); - - for (list< pair<Path, Path> >::iterator c = _connection_orphans.begin(); - c != _connection_orphans.end(); ) { - - list< pair<Path, Path> >::iterator next = c; - ++next; - - if (c->first == port->path() || c->second == port->path()) { - cerr << "Missing dependant (" << c->first << " -> " << c->second << ") received" << endl; - bool success = attempt_connection(c->first, c->second); - if (success) - _connection_orphans.erase(c); - } - - c = next; - } -} - - -void -ClientStore::add_orphan(SharedPtr<ObjectModel> child) -{ - if (!_handle_orphans) - return; - cerr << "WARNING: Orphan object " << child->path() << " received." << endl; - - Raul::PathTable<list<SharedPtr<ObjectModel> > >::iterator children - = _orphans.find(child->path().parent()); - - _engine->request_object(child->path().parent()); - - if (children != _orphans.end()) { - children->second.push_back(child); - } else { - list<SharedPtr<ObjectModel> > l; - l.push_back(child); - _orphans.insert(make_pair(child->path().parent(), l)); - } -} - - -void -ClientStore::add_variable_orphan(const Path& subject_path, const string& predicate, const Atom& value) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<std::pair<string, Atom> > >::iterator orphans - = _variable_orphans.find(subject_path); - - _engine->request_object(subject_path); - - if (orphans != _variable_orphans.end()) { - orphans->second.push_back(std::pair<string, Atom>(predicate, value)); - } else { - list<std::pair<string, Atom> > l; - l.push_back(std::pair<string, Atom>(predicate, value)); - _variable_orphans[subject_path] = l; - } -} - - -void -ClientStore::resolve_variable_orphans(SharedPtr<ObjectModel> subject) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<std::pair<string, Atom> > >::iterator v - = _variable_orphans.find(subject->path()); - - if (v != _variable_orphans.end()) { - - list<std::pair<string, Atom> > values = v->second; // take a copy - - _variable_orphans.erase(subject->path()); - cerr << "Missing dependant " << subject->path() << " received" << endl; - - for (list<std::pair<string, Atom> >::iterator i = values.begin(); - i != values.end(); ++i) { - subject->set_variable(i->first, i->second); - } - } -} - - -void -ClientStore::resolve_orphans(SharedPtr<ObjectModel> parent) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<SharedPtr<ObjectModel> > >::iterator c - = _orphans.find(parent->path()); - - if (c != _orphans.end()) { - - list<SharedPtr<ObjectModel> > children = c->second; // take a copy - - _orphans.erase(parent->path()); // prevent infinite recursion - - for (list<SharedPtr<ObjectModel> >::iterator i = children.begin(); - i != children.end(); ++i) { - add_object(*i); - } - } -} - - -void -ClientStore::add_object(SharedPtr<ObjectModel> object) -{ - // If we already have "this" object, merge the existing one into the new - // one (with precedence to the new values). - iterator existing = find(object->path()); - if (existing != end()) { - PtrCast<ObjectModel>(existing->second)->set(object); - } else { - - if (object->path() != "/") { - SharedPtr<ObjectModel> parent = this->object(object->path().parent()); - if (parent) { - assert(object->path().is_child_of(parent->path())); - object->set_parent(parent); - parent->add_child(object); - assert(parent && (object->parent() == parent)); - - (*this)[object->path()] = object; - signal_new_object.emit(object); - - resolve_variable_orphans(parent); - resolve_orphans(parent); - - SharedPtr<PortModel> port = PtrCast<PortModel>(object); - if (port) - resolve_connection_orphans(port); - - } else { - add_orphan(object); - } - } else { - (*this)[object->path()] = object; - signal_new_object.emit(object); - } - - } - - /*cout << "[Store] Added " << object->path() << " {" << endl; - for (iterator i = begin(); i != end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ -} - - -SharedPtr<ObjectModel> -ClientStore::remove_object(const Path& path) -{ - iterator i = find(path); - - if (i != end()) { - assert((*i).second->path() == path); - SharedPtr<ObjectModel> result = PtrCast<ObjectModel>((*i).second); - assert(result); - //erase(i); - iterator descendants_end = find_descendants_end(i); - SharedPtr<Store::Objects> removed = yank(i, descendants_end); - - /*cout << "[Store] Removing " << i->first << " {" << endl; - for (iterator i = removed.begin(); i != removed.end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ - - if (result) - result->signal_destroyed.emit(); - - if (result->path() != "/") { - assert(result->parent()); - - SharedPtr<ObjectModel> parent = this->object(result->path().parent()); - if (parent) { - parent->remove_child(result); - } - } - - assert(!object(path)); - - return result; - - } else { - return SharedPtr<ObjectModel>(); - } -} - - -SharedPtr<PluginModel> -ClientStore::plugin(const string& uri) -{ - assert(uri.length() > 0); - Plugins::iterator i = _plugins->find(uri); - if (i == _plugins->end()) - return SharedPtr<PluginModel>(); - else - return (*i).second; -} - - -SharedPtr<ObjectModel> -ClientStore::object(const Path& path) -{ - assert(path.length() > 0); - iterator i = find(path); - if (i == end()) { - return SharedPtr<ObjectModel>(); - } else { - SharedPtr<ObjectModel> model = PtrCast<ObjectModel>(i->second); - assert(model); - assert(model->path() == "/" || model->parent()); - return model; - } -} - -void -ClientStore::add_plugin(SharedPtr<PluginModel> pm) -{ - // FIXME: dupes? merge, like with objects? - - (*_plugins)[pm->uri()] = pm; - signal_new_plugin(pm); - //cerr << "Plugin: " << pm->uri() << ", # plugins: " << _plugins->size() << endl; -} - - -/* ****** Signal Handlers ******** */ - - -void -ClientStore::destroy(const std::string& path) -{ - SharedPtr<ObjectModel> removed = remove_object(path); - removed.reset(); - //cerr << "[ClientStore] removed object " << path << ", count: " << removed.use_count(); -} - -void -ClientStore::rename(const Path& old_path, const Path& new_path) -{ - iterator parent = find(old_path); - if (parent == end()) { - cerr << "[Store] Failed to find object " << old_path << " to rename." << endl; - return; - } - - iterator descendants_end = find_descendants_end(parent); - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = yank(parent, descendants_end); - - assert(removed->size() > 0); - - for (Table<Path, SharedPtr<Shared::GraphObject> >::iterator i = removed->begin(); i != removed->end(); ++i) { - const Path& child_old_path = i->first; - assert(Path::descendant_comparator(old_path, child_old_path)); - - Path child_new_path; - if (child_old_path == old_path) - child_new_path = new_path; - else - child_new_path = new_path.base() + child_old_path.substr(old_path.length()+1); - - cerr << "[Store] Renamed " << child_old_path << " -> " << child_new_path << endl; - PtrCast<ObjectModel>(i->second)->set_path(child_new_path); - i->first = child_new_path; - } - - cram(*removed.get()); - - //cerr << "[Store] Table:" << endl; - //for (size_t i=0; i < removed.size(); ++i) { - // cerr << removed[i].first << "\t\t: " << removed[i].second << endl; - //} - /*for (iterator i = begin(); i != end(); ++i) { - cerr << i->first << "\t\t: " << i->second << endl; - }*/ -} - -void -ClientStore::new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) -{ - SharedPtr<PluginModel> p(new PluginModel(uri, type_uri, symbol, name)); - add_plugin(p); - resolve_plugin_orphans(p); -} - - -void -ClientStore::new_patch(const string& path, uint32_t poly) -{ - SharedPtr<PatchModel> p(new PatchModel(path, poly)); - add_object(p); -} - - -void -ClientStore::new_node(const string& path, const string& plugin_uri) -{ - SharedPtr<PluginModel> plug = plugin(plugin_uri); - if (!plug) { - SharedPtr<NodeModel> n(new NodeModel(plugin_uri, path)); - add_plugin_orphan(n); - add_object(n); - } else { - SharedPtr<NodeModel> n(new NodeModel(plug, path)); - add_object(n); - } -} - - -void -ClientStore::new_port(const string& path, uint32_t index, const string& type, bool is_output) -{ - PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - - SharedPtr<PortModel> p(new PortModel(path, index, type, pdir)); - add_object(p); - if (p->parent()) - resolve_connection_orphans(p); -} - - -void -ClientStore::patch_cleared(const Path& path) -{ - iterator i = find(path); - if (i != end()) { - assert((*i).second->path() == path); - SharedPtr<PatchModel> patch = PtrCast<PatchModel>(i->second); - - iterator first_descendant = i; - ++first_descendant; - iterator descendants_end = find_descendants_end(i); - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = yank(first_descendant, descendants_end); - - for (iterator i = removed->begin(); i != removed->end(); ++i) { - SharedPtr<ObjectModel> model = PtrCast<ObjectModel>(i->second); - assert(model); - model->signal_destroyed.emit(); - if (model->parent() == patch) - patch->remove_child(model); - } - - } else { - cerr << "[Store] Unable to find patch " << path << " to clear." << endl; - } -} - - -void -ClientStore::set_variable(const string& subject_path, const string& predicate, const Atom& value) -{ - SharedPtr<ObjectModel> subject = object(subject_path); - - if (!value.is_valid()) { - cerr << "ERROR: variable '" << predicate << "' has no type" << endl; - } else if (subject) { - subject->set_variable(predicate, value); - } else { - add_variable_orphan(subject_path, predicate, value); - cerr << "WARNING: variable for unknown object " << subject_path << endl; - } -} - - -void -ClientStore::set_property(const string& subject_path, const string& predicate, const Atom& value) -{ - SharedPtr<ObjectModel> subject = object(subject_path); - - if (!value.is_valid()) { - cerr << "ERROR: property '" << predicate << "' has no type" << endl; - } else if (subject) { - subject->set_property(predicate, value); - } else { - cerr << "WARNING: property for unknown object " << subject_path - << " lost. Client must refresh!" << endl; - } -} - - -void -ClientStore::set_port_value(const string& port_path, const Raul::Atom& value) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->value(value); - else - cerr << "ERROR: control change for nonexistant port " << port_path << endl; -} - - -void -ClientStore::set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->value(voice, value); - else - cerr << "ERROR: poly control change for nonexistant port " << port_path << endl; -} - - -void -ClientStore::port_activity(const Path& port_path) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->signal_activity.emit(); - else - cerr << "ERROR: activity for nonexistant port " << port_path << endl; -} - - -SharedPtr<PatchModel> -ClientStore::connection_patch(const Path& src_port_path, const Path& dst_port_path) -{ - SharedPtr<PatchModel> patch; - - if (src_port_path.parent() == dst_port_path.parent()) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent())); - - if (!patch && src_port_path.parent() == dst_port_path.parent().parent()) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent())); - - if (!patch && src_port_path.parent().parent() == dst_port_path.parent()) - patch = PtrCast<PatchModel>(this->object(dst_port_path.parent())); - - if (!patch) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent().parent())); - - if (!patch) - cerr << "ERROR: Unable to find connection patch " << src_port_path - << " -> " << dst_port_path << endl; - - return patch; -} - - -bool -ClientStore::attempt_connection(const Path& src_port_path, const Path& dst_port_path, bool add_orphan) -{ - SharedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); - SharedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); - - if (src_port && dst_port) { - assert(src_port->parent()); - assert(dst_port->parent()); - - SharedPtr<PatchModel> patch = connection_patch(src_port_path, dst_port_path); - assert(patch); - - SharedPtr<ConnectionModel> cm(new ConnectionModel(src_port, dst_port)); - - src_port->connected_to(dst_port); - dst_port->connected_to(src_port); - - patch->add_connection(cm); - return true; - } else if (add_orphan) { - add_connection_orphan(make_pair(src_port_path, dst_port_path)); - } - - return false; -} - - -void -ClientStore::connect(const string& src_port_path, const string& dst_port_path) -{ - attempt_connection(src_port_path, dst_port_path, true); -} - - -void -ClientStore::disconnect(const string& src_port_path, const string& dst_port_path) -{ - // Find the ports and create a ConnectionModel just to get at the parent path - // finding logic in ConnectionModel. So I'm lazy. - - SharedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); - SharedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); - - if (src_port) - src_port->disconnected_from(dst_port); - else - cerr << "WARNING: Disconnection from nonexistant src port " << src_port_path << endl; - - if (dst_port) - dst_port->disconnected_from(dst_port); - else - cerr << "WARNING: Disconnection from nonexistant dst port " << dst_port_path << endl; - - SharedPtr<PatchModel> patch = connection_patch(src_port_path, dst_port_path); - - if (patch) - patch->remove_connection(src_port_path, dst_port_path); - else - cerr << "ERROR: disconnection in nonexistant patch: " - << src_port_path << " -> " << dst_port_path << endl; -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/ClientStore.hpp b/src/libs/client/ClientStore.hpp deleted file mode 100644 index f08fcd9b..00000000 --- a/src/libs/client/ClientStore.hpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CLIENT_STORE_HPP -#define CLIENT_STORE_HPP - -#include <cassert> -#include <string> -#include <list> -#include <raul/SharedPtr.hpp> -#include <sigc++/sigc++.h> -#include <raul/Path.hpp> -#include <raul/Atom.hpp> -#include <raul/PathTable.hpp> -#include <raul/TableImpl.hpp> -#include "interface/EngineInterface.hpp" -#include "shared/Store.hpp" -using std::string; using std::list; -using Ingen::Shared::EngineInterface; -using Raul::Path; -using Raul::Atom; - -namespace Ingen { - -namespace Shared { class GraphObject; } - -namespace Client { - -class SigClientInterface; -class ObjectModel; -class PluginModel; -class PatchModel; -class NodeModel; -class PortModel; -class ConnectionModel; - - -/** Automatically manages models of objects in the engine. - * - * \ingroup IngenClient - */ -class ClientStore : public Shared::Store, public Shared::CommonInterface, public sigc::trackable { -public: - ClientStore(SharedPtr<EngineInterface> engine=SharedPtr<EngineInterface>(), - SharedPtr<SigClientInterface> emitter=SharedPtr<SigClientInterface>()); - - SharedPtr<PluginModel> plugin(const string& uri); - SharedPtr<ObjectModel> object(const Path& path); - - void clear(); - - typedef Raul::Table<string, SharedPtr<PluginModel> > Plugins; - SharedPtr<const Plugins> plugins() const { return _plugins; } - SharedPtr<Plugins> plugins() { return _plugins; } - void set_plugins(SharedPtr<Plugins> p) { _plugins = p; } - - // CommonInterface - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name); - void new_patch(const string& path, uint32_t poly); - void new_node(const string& path, const string& plugin_uri); - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output); - void set_variable(const string& subject_path, const string& predicate, const Atom& value); - void set_property(const string& subject_path, const string& predicate, const Atom& value); - void set_port_value(const string& port_path, const Raul::Atom& value); - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value); - void connect(const string& src_port_path, const string& dst_port_path); - void disconnect(const string& src_port_path, const string& dst_port_path); - void destroy(const string& path); - - typedef list< std::pair<Path, Path> > ConnectionRecords; - const ConnectionRecords& connection_records() { return _connection_orphans; } - - sigc::signal<void, SharedPtr<ObjectModel> > signal_new_object; - sigc::signal<void, SharedPtr<PluginModel> > signal_new_plugin; - -private: - - void add(Shared::GraphObject* o) { throw; } - - void add_object(SharedPtr<ObjectModel> object); - SharedPtr<ObjectModel> remove_object(const Path& path); - - void add_plugin(SharedPtr<PluginModel> plugin); - - SharedPtr<PatchModel> connection_patch(const Path& src_port_path, const Path& dst_port_path); - - // It would be nice to integrate these somehow.. - - void add_orphan(SharedPtr<ObjectModel> orphan); - void resolve_orphans(SharedPtr<ObjectModel> parent); - - void add_connection_orphan(std::pair<Path, Path> orphan); - void resolve_connection_orphans(SharedPtr<PortModel> port); - - void add_plugin_orphan(SharedPtr<NodeModel> orphan); - void resolve_plugin_orphans(SharedPtr<PluginModel> plugin); - - void add_variable_orphan(const Path& subject, const string& predicate, const Atom& value); - void resolve_variable_orphans(SharedPtr<ObjectModel> subject); - - void bundle_begin() {} - void bundle_end() {} - - // Slots for SigClientInterface signals - void rename(const Path& old_path, const Path& new_path); - void patch_cleared(const Path& path); - void port_activity(const Path& port_path); - - bool attempt_connection(const Path& src_port_path, const Path& dst_port_path, bool add_orphan=false); - - bool _handle_orphans; - - SharedPtr<EngineInterface> _engine; - SharedPtr<SigClientInterface> _emitter; - - SharedPtr<Plugins> _plugins; ///< Map, keyed by plugin URI - - /** Objects we've received, but depend on the existance of another unknown object. - * Keyed by the path of the depended-on object (for tolerance of orderless comms) */ - Raul::PathTable<list<SharedPtr<ObjectModel> > > _orphans; - - /** Same idea, except with plugins instead of parents. - * It's unfortunate everything doesn't just have a URI and this was the same.. ahem.. */ - Raul::Table<string, list<SharedPtr<NodeModel> > > _plugin_orphans; - - /** Not orphans OF variable like the above, but orphans which are variable */ - Raul::PathTable<list<std::pair<string, Atom> > > _variable_orphans; - - /** Ditto */ - ConnectionRecords _connection_orphans; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // CLIENT_STORE_HPP diff --git a/src/libs/client/ConnectionModel.hpp b/src/libs/client/ConnectionModel.hpp deleted file mode 100644 index 91c448df..00000000 --- a/src/libs/client/ConnectionModel.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONNECTIONMODEL_H -#define CONNECTIONMODEL_H - -#include <cassert> -#include <string> -#include <list> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/Connection.hpp" -#include "PortModel.hpp" - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Class to represent a port->port connection in the engine. - * - * This can either have pointers to the connection ports' models, or just - * paths as strings. The engine passes just strings (by necessity), but - * clients can set the pointers then they don't have to worry about port - * renaming, as the connections will always return the port's path, even - * if it changes. - * - * \ingroup IngenClient - */ -class ConnectionModel : public Shared::Connection -{ -public: - SharedPtr<PortModel> src_port() const { return _src_port; } - SharedPtr<PortModel> dst_port() const { return _dst_port; } - - const Path src_port_path() const { return _src_port->path(); } - const Path dst_port_path() const { return _dst_port->path(); } - -private: - friend class ClientStore; - - ConnectionModel(SharedPtr<PortModel> src, SharedPtr<PortModel> dst) - : _src_port(src) - , _dst_port(dst) - { - assert(_src_port); - assert(_dst_port); - assert(_src_port->parent()); - assert(_dst_port->parent()); - assert(_src_port->path() != _dst_port->path()); - } - - const SharedPtr<PortModel> _src_port; - const SharedPtr<PortModel> _dst_port; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // CONNECTIONMODEL_H diff --git a/src/libs/client/DeprecatedLoader.cpp b/src/libs/client/DeprecatedLoader.cpp deleted file mode 100644 index a07893f7..00000000 --- a/src/libs/client/DeprecatedLoader.cpp +++ /dev/null @@ -1,711 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <fstream> -#include <vector> -#include <algorithm> -#include <utility> // for pair, make_pair -#include <cassert> -#include <cstring> -#include <string> -#include <cstdlib> // for atof -#include <cmath> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <raul/Path.hpp> -#include "interface/EngineInterface.hpp" -#include "PatchModel.hpp" -#include "NodeModel.hpp" -#include "ConnectionModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" -#include "DeprecatedLoader.hpp" - -#define NS_INGEN "http://drobilla.net/ns/ingen#" - -using namespace std; - -namespace Ingen { -namespace Client { - - -/** A single port's control setting (in a preset). - * - * \ingroup IngenClient - */ -class ControlModel -{ -public: - ControlModel(const Path& port_path, float value) - : _port_path(port_path) - , _value(value) - { - assert(_port_path.find("//") == string::npos); - } - - const Path& port_path() const { return _port_path; } - void port_path(const string& p) { _port_path = p; } - float value() const { return _value; } - void value(float v) { _value = v; } - -private: - Path _port_path; - float _value; -}; - - -/** Model of a preset (a collection of control settings). - * - * \ingroup IngenClient - */ -class PresetModel -{ -public: - PresetModel(const string& base_path) : _base_path(base_path) {} - - /** Add a control value to this preset. An empty string for a node_name - * means the port is on the patch itself (not a node in the patch). */ - void add_control(const string& node_name, string port_name, float value) { - if (port_name == "note_number") // FIXME: filthy kludge - port_name = "note"; - - if (node_name != "") - _controls.push_back(ControlModel(_base_path + node_name +"/"+ port_name, value)); - else - _controls.push_back(ControlModel(_base_path + port_name, value)); - } - - const string& name() const { return _name; } - void name(const string& n) { _name = n; } - - const list<ControlModel>& controls() const { return _controls; } - -private: - string _name; - string _base_path; - list<ControlModel> _controls; -}; - - -string -DeprecatedLoader::nameify_if_invalid(const string& name) -{ - if (Path::is_valid_name(name)) { - return name; - } else { - const string new_name = Path::nameify(name); - assert(Path::is_valid_name(new_name)); - if (new_name != name) - cerr << "WARNING: Illegal name '" << name << "' converted to '" - << new_name << "'" << endl; - return new_name; - } -} - - -string -DeprecatedLoader::translate_load_path(const string& path) -{ - std::map<string,string>::iterator t = _load_path_translations.find(path); - - if (t != _load_path_translations.end()) { - assert(Path::is_valid((*t).second)); - return (*t).second; - // Filthy, filthy kludges - // (FIXME: apply these less heavy handedly, only when it's an internal module) - } else if (path.find("midi") != string::npos) { - assert(Path::is_valid(path)); - if (path.substr(path.find_last_of("/")) == "/MIDI_In") - return path.substr(0, path.find_last_of("/")) + "/input"; - else if (path.substr(path.find_last_of("/")) == "/Note_Number") - return path.substr(0, path.find_last_of("/")) + "/note"; - else if (path.substr(path.find_last_of("/")) == "/Gate") - return path.substr(0, path.find_last_of("/")) + "/gate"; - else if (path.substr(path.find_last_of("/")) == "/Trigger") - return path.substr(0, path.find_last_of("/")) + "/trigger"; - else if (path.substr(path.find_last_of("/")) == "/Velocity") - return path.substr(0, path.find_last_of("/")) + "/velocity"; - else - return path; - } else { - return path; - } -} - - -/** Add a piece of data to a Variables, translating from deprecated unqualified keys - * - * Adds a namespace prefix for known keys, and ignores the rest. - */ -void -DeprecatedLoader::add_variable(GraphObject::Variables& data, string old_key, string value) -{ - string key = ""; - if (old_key == "module-x") - key = "ingenuity:canvas-x"; - else if (old_key == "module-y") - key = "ingenuity:canvas-y"; - - if (key != "") { - // FIXME: should this overwrite existing values? - if (data.find(key) == data.end()) { - // Hack to make module-x and module-y set as floats - char* c_val = strdup(value.c_str()); - char* endptr = NULL; - - // FIXME: locale kludges - char* locale = strdup(setlocale(LC_NUMERIC, NULL)); - - float fval = strtof(c_val, &endptr); - - setlocale(LC_NUMERIC, locale); - free(locale); - - if (endptr != c_val && *endptr == '\0') - data[key] = Atom(fval); - else - data[key] = Atom(value); - - free(c_val); - } - } -} - - -/** Load a patch in to the engine (and client) from a patch file. - * - * The name and poly from the passed PatchModel are used. If the name is - * the empty string, the name will be loaded from the file. If the poly - * is 0, it will be loaded from file. Otherwise the given values will - * be used. - * - * @param filename Local name of file to load patch from - * - * @param parent_path Patch to load this patch as a child of (empty string to load - * to the root patch) - * - * @param name Name of this patch (loaded/generated if the empty string) - * @param poly Polyphony of this patch (loaded/generated if 0) - * - * @param initial_data will be set last, so values passed there will override - * any values loaded from the patch file. - * - * @param existing If true, the patch will be loaded into a currently - * existing patch (ie a merging will take place). Errors will result - * if Nodes of conflicting names exist. - * - * Returns the path of the newly created patch. - */ -string -DeprecatedLoader::load_patch(const Glib::ustring& filename, - boost::optional<Path> parent_path, - string name, - GraphObject::Variables initial_data, - bool existing) -{ - cerr << "[DeprecatedLoader] Loading patch " << filename << " under " - << parent_path << " / " << name << endl; - - Path path = parent_path ? (parent_path.get().base() + name) - : "/" + name; - - const bool load_name = (name == ""); - - size_t poly = 0; - - /* Use parameter overridden polyphony, if given */ - GraphObject::Variables::iterator poly_param = initial_data.find("ingen:polyphony"); - if (poly_param != initial_data.end() && poly_param->second.type() == Atom::INT) - poly = poly_param->second.get_int32(); - - if (initial_data.find("filename") == initial_data.end()) - initial_data["filename"] = Atom(filename.c_str()); // FIXME: URL? - - xmlDocPtr doc = xmlParseFile(filename.c_str()); - - if (!doc) { - cerr << "Unable to parse patch file." << endl; - return ""; - } - - xmlNodePtr cur = xmlDocGetRootElement(doc); - - if (!cur) { - cerr << "Empty document." << endl; - xmlFreeDoc(doc); - return ""; - } - - if (xmlStrcmp(cur->name, (const xmlChar*) "patch")) { - cerr << "File is not an Ingen patch file (root node != <patch>)" << endl; - xmlFreeDoc(doc); - return ""; - } - - xmlChar* key = NULL; - cur = cur->xmlChildrenNode; - - // Load Patch attributes - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - if (load_name && key) { - if (parent_path) - path = Path(parent_path.get()).base() + nameify_if_invalid((char*)key); - else - path = Path("/"); - } - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { - if (poly == 0) { - poly = atoi((char*)key); - } - } else if (xmlStrcmp(cur->name, (const xmlChar*)"connection") - && xmlStrcmp(cur->name, (const xmlChar*)"node") - && xmlStrcmp(cur->name, (const xmlChar*)"subpatch") - && xmlStrcmp(cur->name, (const xmlChar*)"filename") - && xmlStrcmp(cur->name, (const xmlChar*)"preset")) { - // Don't know what this tag is, add it as variable without overwriting - // (so caller can set arbitrary parameters which will be preserved) - if (key) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - cur = cur->next; - } - - if (poly == 0) - poly = 1; - - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!! LOADING " << path << endl; - - // Create it, if we're not merging - if (!existing && path != "/") { - _engine->new_patch(path, poly); - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - } - - // Load nodes - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"node"))) - load_node(path, doc, cur); - - cur = cur->next; - } - - // Load subpatches - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"subpatch"))) { - load_subpatch(filename.substr(0, filename.find_last_of("/")), path, doc, cur); - } - cur = cur->next; - } - - // Load connections - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"connection"))) { - load_connection(path, doc, cur); - } - cur = cur->next; - } - - // Load presets (control values) - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - // I don't think Om ever wrote any preset other than "default"... - if ((!xmlStrcmp(cur->name, (const xmlChar*)"preset"))) { - SharedPtr<PresetModel> pm = load_preset(path, doc, cur); - assert(pm != NULL); - if (pm->name() == "default") { - list<ControlModel>::const_iterator i = pm->controls().begin(); - for ( ; i != pm->controls().end(); ++i) { - const float value = i->value(); - _engine->set_port_value(translate_load_path(i->port_path()), Atom(value)); - } - } else { - cerr << "WARNING: Unknown preset: \"" << pm->name() << endl; - } - } - cur = cur->next; - } - - xmlFreeDoc(doc); - xmlCleanupParser(); - - // Done above.. late enough? - //for (Variables::const_iterator i = data.begin(); i != data.end(); ++i) - // _engine->set_variable(subject, i->first, i->second); - - if (!existing) - _engine->set_property(path, "ingen:enabled", (bool)true); - - _load_path_translations.clear(); - - return path; -} - - -/** Build a NodeModel given a pointer to a Node in a patch file. - */ -bool -DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlChar* key; - xmlNodePtr cur = node->xmlChildrenNode; - - string path = ""; - bool polyphonic = false; - - string plugin_uri; - - string plugin_type; // deprecated - string library_name; // deprecated - string plugin_label; // deprecated - - GraphObject::Variables initial_data; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - path = parent.base() + nameify_if_invalid((char*)key); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { - polyphonic = !strcmp((char*)key, "true"); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { - plugin_type = (const char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"library-name"))) { - library_name = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"plugin-label"))) { - plugin_label = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"plugin-uri"))) { - plugin_uri = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"port"))) { - cerr << "FIXME: load port\n"; -#if 0 - xmlNodePtr child = cur->xmlChildrenNode; - - string port_name; - float user_min = 0.0; - float user_max = 0.0; - - while (child != NULL) { - key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - - if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - port_name = nameify_if_invalid((char*)key); - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) { - user_min = atof((char*)key); - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) { - user_max = atof((char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - child = child->next; - } - - assert(path.length() > 0); - assert(Path::is_valid(path)); - - // FIXME: /nasty/ assumptions - SharedPtr<PortModel> pm(new PortModel(Path(path).base() + port_name, - PortModel::CONTROL, PortModel::INPUT, PortModel::NONE, - 0.0, user_min, user_max)); - //pm->set_parent(nm); - nm->add_port(pm); -#endif - - } else { // Don't know what this tag is, add it as variable - if (key) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - xmlFree(key); - key = NULL; - - cur = cur->next; - } - - if (path == "") { - cerr << "[DeprecatedLoader] Malformed patch file (node tag has empty children)" << endl; - cerr << "[DeprecatedLoader] Node ignored." << endl; - return false; - } - - // Compatibility hacks for old patches that represent patch ports as nodes - if (plugin_uri == "") { - bool is_port = false; - - if (plugin_type == "Internal") { - // FIXME: indices - if (plugin_label == "audio_input") { - _engine->new_port(path, 0, "ingen:AudioPort", false); - is_port = true; - } else if (plugin_label == "audio_output") { - _engine->new_port(path, 0, "ingen:AudioPort", true); - is_port = true; - } else if (plugin_label == "control_input") { - _engine->new_port(path, 0, "ingen:ControlPort", false); - is_port = true; - } else if (plugin_label == "control_output" ) { - _engine->new_port(path, 0, "ingen:ControlPort", true); - is_port = true; - } else if (plugin_label == "midi_input") { - _engine->new_port(path, 0, "ingen:MIDIPort", false); - is_port = true; - } else if (plugin_label == "midi_output" ) { - _engine->new_port(path, 0, "ingen:MIDIPort", true); - is_port = true; - } else { - cerr << "WARNING: Unknown internal plugin label \"" << plugin_label << "\"" << endl; - } - } - - if (is_port) { - const string old_path = path; - const string new_path = (Path::is_valid(old_path) ? old_path : Path::pathify(old_path)); - - if (!Path::is_valid(old_path)) - cerr << "WARNING: Translating invalid port path \"" << old_path << "\" => \"" - << new_path << "\"" << endl; - - // Set up translations (for connections etc) to alias both the old - // module path and the old module/port path to the new port path - _load_path_translations[old_path] = new_path; - _load_path_translations[old_path + "/in"] = new_path; - _load_path_translations[old_path + "/out"] = new_path; - - path = new_path; - - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - - return SharedPtr<NodeModel>(); - - } else { - if (plugin_label == "note_in") { - plugin_uri = NS_INGEN "note_node"; - } else if (plugin_label == "control_input") { - plugin_uri = NS_INGEN "control_node"; - } else if (plugin_label == "transport") { - plugin_uri = NS_INGEN "transport_node"; - } else if (plugin_label == "trigger_in") { - plugin_uri = NS_INGEN "trigger_node"; - } else { - cerr << "WARNING: Unknown deprecated node (label " << plugin_label - << ")." << endl; - } - - if (plugin_uri != "") - _engine->new_node(path, plugin_uri); - else - _engine->new_node_deprecated(path, plugin_type, library_name, plugin_label); - - _engine->set_property(path, "ingen:polyphonic", polyphonic); - - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - - return true; - } - - // Not deprecated - } else { - _engine->new_node(path, plugin_uri); - _engine->set_property(path, "ingen:polyphonic", polyphonic); - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - return true; - } - - // (shouldn't get here) -} - - -bool -DeprecatedLoader::load_subpatch(const string& base_filename, const Path& parent, xmlDocPtr doc, const xmlNodePtr subpatch) -{ - xmlChar *key; - xmlNodePtr cur = subpatch->xmlChildrenNode; - - string name = ""; - string filename = ""; - size_t poly = 0; - - GraphObject::Variables initial_data; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - name = (const char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { - initial_data.insert(make_pair("ingen::polyphony", (int)poly)); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"filename"))) { - filename = base_filename + "/" + (const char*)key; - } else { // Don't know what this tag is, add it as variable - if (key != NULL && strlen((const char*)key) > 0) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - xmlFree(key); - key = NULL; - - cur = cur->next; - } - - cout << "Loading subpatch " << filename << " under " << parent << endl; - // load_patch sets the passed variable last, so values stored in the parent - // will override values stored in the child patch file - /*string path = */load_patch(filename, parent, name, initial_data, false); - - return false; -} - - -/** Build a ConnectionModel given a pointer to a connection in a patch file. - */ -bool -DeprecatedLoader::load_connection(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlChar *key; - xmlNodePtr cur = node->xmlChildrenNode; - - string source_node, source_port, dest_node, dest_port; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"source-node"))) { - source_node = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"source-port"))) { - source_port = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"destination-node"))) { - dest_node = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"destination-port"))) { - dest_port = (char*)key; - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - cur = cur->next; - } - - if (source_node == "" || source_port == "" || dest_node == "" || dest_port == "") { - cerr << "ERROR: Malformed patch file (connection tag has empty children)" << endl; - cerr << "ERROR: Connection ignored." << endl; - return false; - } - - // Compatibility fixes for old (fundamentally broken) patches - source_node = nameify_if_invalid(source_node); - source_port = nameify_if_invalid(source_port); - dest_node = nameify_if_invalid(dest_node); - dest_port = nameify_if_invalid(dest_port); - - _engine->connect( - translate_load_path(parent.base() + source_node +"/"+ source_port), - translate_load_path(parent.base() + dest_node +"/"+ dest_port)); - - return true; -} - - -/** Build a PresetModel given a pointer to a preset in a patch file. - */ -SharedPtr<PresetModel> -DeprecatedLoader::load_preset(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlNodePtr cur = node->xmlChildrenNode; - xmlChar* key; - - SharedPtr<PresetModel> pm(new PresetModel(parent.base())); - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - assert(key != NULL); - pm->name((char*)key); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"control"))) { - xmlNodePtr child = cur->xmlChildrenNode; - - string node_name = "", port_name = ""; - float val = 0.0; - - while (child != NULL) { - key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - - if ((!xmlStrcmp(child->name, (const xmlChar*)"node-name"))) { - node_name = (char*)key; - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"port-name"))) { - port_name = (char*)key; - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"value"))) { - val = atof((char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - child = child->next; - } - - // Compatibility fixes for old patch files - if (node_name != "") - node_name = nameify_if_invalid(node_name); - port_name = nameify_if_invalid(port_name); - - if (port_name == "") { - string msg = "Unable to parse control in patch file ( node = "; - msg.append(node_name).append(", port = ").append(port_name).append(")"); - cerr << "ERROR: " << msg << endl; - //m_client_hooks->error(msg); - } else { - // FIXME: temporary compatibility, remove any slashes from port name - // remove this soon once patches have migrated - string::size_type slash_index; - while ((slash_index = port_name.find("/")) != string::npos) - port_name[slash_index] = '-'; - - pm->add_control(node_name, port_name, val); - } - } - xmlFree(key); - key = NULL; - cur = cur->next; - } - if (pm->name() == "") { - cerr << "Preset in patch file has no name." << endl; - //m_client_hooks->error("Preset in patch file has no name."); - pm->name("Unnamed"); - } - - return pm; -} - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/DeprecatedLoader.hpp b/src/libs/client/DeprecatedLoader.hpp deleted file mode 100644 index c1af52c2..00000000 --- a/src/libs/client/DeprecatedLoader.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PATCHLIBRARIAN_H -#define PATCHLIBRARIAN_H - -#include <map> -#include <utility> -#include <string> -#include <cassert> -#include <boost/optional.hpp> -#include <glibmm/ustring.h> -#include <libxml/tree.h> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include "interface/EngineInterface.hpp" -#include "interface/GraphObject.hpp" -#include "ObjectModel.hpp" - -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::GraphObject; - -namespace Ingen { -namespace Client { - -class PatchModel; -class NodeModel; -class ConnectionModel; -class PresetModel; // defined in DeprecatedLoader.cpp - - -/** Loads deprecated (XML) patch files (from the Om days). - * - * \ingroup IngenClient - */ -class DeprecatedLoader -{ -public: - DeprecatedLoader(SharedPtr<EngineInterface> engine) - : /*_patch_search_path(".")*/ _engine(engine) - { - assert(_engine); - } - - /*void path(const string& path) { _patch_search_path = path; } - const string& path() { return _patch_search_path; }*/ - - string find_file(const string& filename, const string& additional_path = ""); - - string load_patch(const Glib::ustring& filename, - boost::optional<Path> parent_path, - string name, - GraphObject::Variables initial_data, - bool existing = false); - -private: - void add_variable(GraphObject::Variables& data, string key, string value); - - string nameify_if_invalid(const string& name); - string translate_load_path(const string& path); - - //string _patch_search_path; - SharedPtr<EngineInterface> _engine; - - /// Translations of paths from the loading file to actual paths (for deprecated patches) - std::map<string, string> _load_path_translations; - - bool load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - bool load_connection(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - bool load_subpatch(const string& base_filename, const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - - SharedPtr<PresetModel> load_preset(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PATCHLIBRARIAN_H diff --git a/src/libs/client/HTTPClientReceiver.cpp b/src/libs/client/HTTPClientReceiver.cpp deleted file mode 100644 index ece55ab2..00000000 --- a/src/libs/client/HTTPClientReceiver.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 <list> -#include <cassert> -#include <cstring> -#include <iostream> -#include <sstream> -#include <raul/AtomLiblo.hpp> -#include "module/Module.hpp" -#include "HTTPClientReceiver.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -HTTPClientReceiver::HTTPClientReceiver( - Shared::World* world, - const std::string& url, - SharedPtr<Shared::ClientInterface> target) - : _target(target) - , _world(world) - , _url(url) - , _session(NULL) -{ - start(false); -} - - -HTTPClientReceiver::~HTTPClientReceiver() -{ - stop(); -} - - -void -HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr) -{ - HTTPClientReceiver* me = (HTTPClientReceiver*)ptr; - cout << "RECEIVED ASYNC MESSAGE: " << msg->response_body->data << endl; - me->_target->response_ok(0); - me->_target->enable(); - me->_parser->parse_string(me->_world, me->_target.get(), Glib::ustring(msg->response_body->data), - Glib::ustring("/"), Glib::ustring("")); -} - - -void -HTTPClientReceiver::start(bool dump) -{ - Glib::Mutex::Lock lock(_world->rdf_world->mutex()); - if (!_parser) { - if (!_world->serialisation_module) - _world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (_world->serialisation_module) { - Parser* (*new_parser)() = NULL; - if (_world->serialisation_module->get_symbol("new_parser", (void*&)new_parser)) - _parser = SharedPtr<Parser>(new_parser()); - } - } - _session = soup_session_async_new(); - SoupMessage* msg = soup_message_new("GET", _url.c_str()); - soup_session_queue_message (_session, msg, message_callback, this); -} - - -void -HTTPClientReceiver::stop() -{ - if (_session != NULL) { - //unregister_client(); - soup_session_abort(_session); - _session = NULL; - } -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/HTTPClientReceiver.hpp b/src/libs/client/HTTPClientReceiver.hpp deleted file mode 100644 index bab55578..00000000 --- a/src/libs/client/HTTPClientReceiver.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 HTTPCLIENTRECEIVER_H -#define HTTPCLIENTRECEIVER_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <libsoup/soup.h> -#include "interface/ClientInterface.hpp" -#include "serialisation/Parser.hpp" -#include "redlandmm/World.hpp" -#include "raul/Deletable.hpp" - -namespace Ingen { -namespace Client { - - -class HTTPClientReceiver : public boost::noncopyable, public Raul::Deletable -{ -public: - HTTPClientReceiver(Shared::World* world, - const std::string& url, - SharedPtr<Shared::ClientInterface> target); - - ~HTTPClientReceiver(); - - std::string uri() const { return _url; } - - void start(bool dump); - void stop(); - -private: - static void message_callback(SoupSession* session, SoupMessage* msg, void* ptr); - - SharedPtr<Shared::ClientInterface> _target; - - Shared::World* _world; - const std::string _url; - SoupSession* _session; - SharedPtr<Parser> _parser; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // HTTPCLIENTRECEIVER_H diff --git a/src/libs/client/HTTPEngineSender.cpp b/src/libs/client/HTTPEngineSender.cpp deleted file mode 100644 index 733e0ac7..00000000 --- a/src/libs/client/HTTPEngineSender.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <libsoup/soup.h> -#include "HTTPEngineSender.hpp" - -using namespace std; - -namespace Ingen { -namespace Client { - - -HTTPEngineSender::HTTPEngineSender(const string& engine_url) - : _engine_url(engine_url) - , _id(0) - , _enabled(true) -{ - _session = soup_session_sync_new(); -} - - -HTTPEngineSender::~HTTPEngineSender() -{ - soup_session_abort(_session); -} - - -void -HTTPEngineSender::attach(int32_t ping_id, bool block) -{ - /*SoupMessage *msg; - msg = soup_message_new ("GET", _engine_url.c_str()); - int status = soup_session_send_message (_session, msg); - cout << "STATUS: " << status << endl; - cout << "RESPONSE: " << msg->response_body->data << endl;*/ -} - - -/* *** EngineInterface implementation below here *** */ - - -/** Register with the engine via HTTP. - * - * Note that this does not actually use 'key', since the engine creates - * it's own key for HTTP clients (namely the incoming URL), for NAT - * traversal. It is a parameter to remain compatible with EngineInterface. - */ -void -HTTPEngineSender::register_client(ClientInterface* client) -{ - -} - - -void -HTTPEngineSender::unregister_client(const string& uri) -{ - -} - - -// Engine commands -void -HTTPEngineSender::load_plugins() -{ - -} - - -void -HTTPEngineSender::activate() -{ - -} - - -void -HTTPEngineSender::deactivate() -{ - -} - - -void -HTTPEngineSender::quit() -{ - -} - - - -// Object commands - -void -HTTPEngineSender::new_patch(const string& path, - uint32_t poly) -{ -} - - -void -HTTPEngineSender::new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output) -{ -} - - -void -HTTPEngineSender::new_node(const string& path, - const string& plugin_uri) -{ -} - - -/** Create a node using library name and plugin label (DEPRECATED). - * - * DO NOT USE THIS. - */ -void -HTTPEngineSender::new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label) -{ -} - - -void -HTTPEngineSender::rename(const string& old_path, - const string& new_name) -{ -} - - -void -HTTPEngineSender::destroy(const string& path) -{ -} - - -void -HTTPEngineSender::clear_patch(const string& patch_path) -{ -} - - -void -HTTPEngineSender::connect(const string& src_port_path, - const string& dst_port_path) -{ -} - - -void -HTTPEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) -{ -} - - -void -HTTPEngineSender::disconnect_all(const string& parent_patch_path, - const string& node_path) -{ -} - - -void -HTTPEngineSender::set_port_value(const string& port_path, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ -} - - -void -HTTPEngineSender::midi_learn(const string& node_path) -{ -} - - -void -HTTPEngineSender::set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ -} - - - -// Requests // - -void -HTTPEngineSender::ping() -{ -} - - -void -HTTPEngineSender::request_plugin(const string& uri) -{ -} - - -void -HTTPEngineSender::request_object(const string& path) -{ -} - - -void -HTTPEngineSender::request_port_value(const string& port_path) -{ -} - - -void -HTTPEngineSender::request_variable(const string& object_path, const string& key) -{ -} - - -void -HTTPEngineSender::request_property(const string& object_path, const string& key) -{ -} - - -void -HTTPEngineSender::request_plugins() -{ -} - - -void -HTTPEngineSender::request_all_objects() -{ -} - - - -} // namespace Client -} // namespace Ingen - - diff --git a/src/libs/client/HTTPEngineSender.hpp b/src/libs/client/HTTPEngineSender.hpp deleted file mode 100644 index 411ddfd5..00000000 --- a/src/libs/client/HTTPEngineSender.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 HTTPENGINESENDER_H -#define HTTPENGINESENDER_H - -#include <inttypes.h> -#include <string> -#include <libsoup/soup.h> -#include "interface/EngineInterface.hpp" -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::ClientInterface; - -namespace Ingen { -namespace Client { - - -/* HTTP (via libsoup) interface to the engine. - * - * Clients can use this opaquely as an EngineInterface to control the engine - * over HTTP (whether over a network or not). - * - * \ingroup IngenClient - */ -class HTTPEngineSender : public EngineInterface { -public: - HTTPEngineSender(const string& engine_url); - ~HTTPEngineSender(); - - string uri() const { return _engine_url; } - - inline int32_t next_id() - { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } - - void set_next_response_id(int32_t id) { _id = id; } - void disable_responses() { _id = -1; } - - void attach(int32_t ping_id, bool block); - - - /* *** EngineInterface implementation below here *** */ - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { transfer_begin(); } - void bundle_end() { transfer_end(); } - - void transfer_begin(); - void transfer_end(); - - // Client registration - void register_client(ClientInterface* client); - void unregister_client(const string& uri); - - // Engine commands - void load_plugins(); - void activate(); - void deactivate(); - void quit(); - - // Object commands - - void new_patch(const string& path, - uint32_t poly); - - void new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output); - - void new_node(const string& path, - const string& plugin_uri); - - void new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label); - - void rename(const string& old_path, - const string& new_name); - - void destroy(const string& path); - - void clear_patch(const string& patch_path); - - void connect(const string& src_port_path, - const string& dst_port_path); - - void disconnect(const string& src_port_path, - const string& dst_port_path); - - void disconnect_all(const string& parent_patch_path, - const string& node_path); - - void set_port_value(const string& port_path, - const Raul::Atom& value); - - void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - void midi_learn(const string& node_path); - - void set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - void set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - void ping(); - void request_plugin(const string& uri); - void request_object(const string& path); - void request_port_value(const string& port_path); - void request_variable(const string& path, const string& key); - void request_property(const string& path, const string& key); - void request_plugins(); - void request_all_objects(); - -protected: - SoupSession* _session; - const string _engine_url; - int _client_port; - int32_t _id; - bool _enabled; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // HTTPENGINESENDER_H - diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am deleted file mode 100644 index 4af7c243..00000000 --- a/src/libs/client/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -if BUILD_CLIENT_LIB - - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_client.la - -libingen_client_la_CXXFLAGS = \ - -DPKGDATADIR=\"$(pkgdatadir)\" \ - @INGEN_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @LIBLO_CFLAGS@ \ - @LSIGCPP_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @LXML2_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @SLV2_CFLAGS@ \ - @SOUP_CFLAGS@ - -libingen_client_la_LIBADD = \ - ../shared/libingen_shared.la \ - @GLIBMM_LIBS@ \ - @LIBLO_LIBS@ \ - @LSIGCPP_LIBS@ \ - @LXML2_LIBS@ \ - @RAUL_LIBS@ \ - @REDLANDMM_LIBS@ \ - @SLV2_LIBS@ \ - @SOUP_LIBS@ - -libingen_client_la_SOURCES = \ - ClientStore.cpp \ - ClientStore.hpp \ - ConnectionModel.hpp \ - DeprecatedLoader.cpp \ - DeprecatedLoader.hpp \ - NodeModel.cpp \ - NodeModel.hpp \ - OSCClientReceiver.cpp \ - OSCClientReceiver.hpp \ - OSCEngineSender.cpp \ - OSCEngineSender.hpp \ - ObjectModel.cpp \ - ObjectModel.hpp \ - PatchModel.cpp \ - PatchModel.hpp \ - PluginModel.cpp \ - PluginModel.hpp \ - PluginUI.cpp \ - PluginUI.hpp \ - PortModel.cpp \ - PortModel.hpp \ - SigClientInterface.hpp \ - ThreadedSigClientInterface.cpp \ - ThreadedSigClientInterface.hpp \ - client.cpp \ - client.hpp - -if WITH_SOUP -libingen_client_la_SOURCES += \ - HTTPClientReceiver.cpp \ - HTTPClientReceiver.hpp \ - HTTPEngineSender.cpp \ - HTTPEngineSender.hpp -endif - -endif # BUILD_CLIENT_LIB - diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp deleted file mode 100644 index ac0c8e68..00000000 --- a/src/libs/client/NodeModel.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONFIG_H_PATH - -#include <cassert> -#include <cmath> -#include "interface/Port.hpp" -#include "NodeModel.hpp" -#include "PatchModel.hpp" - -namespace Ingen { -namespace Client { - - -NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path) - : ObjectModel(path) - , _plugin_uri(plugin->uri()) - , _plugin(plugin) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - -NodeModel::NodeModel(const string& plugin_uri, const Path& path) - : ObjectModel(path) - , _plugin_uri(plugin_uri) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - - -NodeModel::NodeModel(const NodeModel& copy) - : ObjectModel(copy) - , _plugin_uri(copy._plugin_uri) - , _num_values(copy._num_values) - , _min_values((float*)malloc(sizeof(float) * _num_values)) - , _max_values((float*)malloc(sizeof(float) * _num_values)) -{ - memcpy(_min_values, copy._min_values, sizeof(float) * _num_values); - memcpy(_max_values, copy._max_values, sizeof(float) * _num_values); -} - - -NodeModel::~NodeModel() -{ - clear(); -} - - -void -NodeModel::remove_port(SharedPtr<PortModel> port) -{ - // FIXME: slow - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i) == port) { - _ports.erase(i); - break; - } - } - signal_removed_port.emit(port); -} - - -void -NodeModel::remove_port(const Path& port_path) -{ - // FIXME: slow - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i)->path() == port_path) { - _ports.erase(i); - break; - } - } -} - - -void -NodeModel::clear() -{ - _ports.clear(); - assert(_ports.empty()); - delete[] _min_values; - delete[] _max_values; - _min_values = 0; - _max_values = 0; -} - - -void -NodeModel::add_child(SharedPtr<ObjectModel> c) -{ - assert(c->parent().get() == this); - - //ObjectModel::add_child(c); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - assert(pm); - add_port(pm); -} - - -bool -NodeModel::remove_child(SharedPtr<ObjectModel> c) -{ - assert(c->path().is_child_of(_path)); - assert(c->parent().get() == this); - - //bool ret = ObjectModel::remove_child(c); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - assert(pm); - remove_port(pm); - - //return ret; - return true; -} - - -void -NodeModel::add_port(SharedPtr<PortModel> pm) -{ - assert(pm); - assert(pm->path().is_child_of(_path)); - assert(pm->parent().get() == this); - - Ports::iterator existing = find(_ports.begin(), _ports.end(), pm); - - // Store should have handled this by merging the two - assert(existing == _ports.end()); - - _ports.push_back(pm); - signal_new_port.emit(pm); -} - - -SharedPtr<PortModel> -NodeModel::get_port(const string& port_name) const -{ - assert(port_name.find("/") == string::npos); - for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->path().name() == port_name) - return (*i); - return SharedPtr<PortModel>(); -} - - -Shared::Port* -NodeModel::port(uint32_t index) const -{ - assert(index < num_ports()); - return dynamic_cast<Shared::Port*>(_ports[index].get()); -} - - -void -NodeModel::port_value_range(SharedPtr<PortModel> port, float& min, float& max) -{ - assert(port->parent().get() == this); - -#ifdef HAVE_SLV2 - // Plugin value first - if (_plugin && _plugin->type() == PluginModel::LV2) { - - if (!_min_values) { - - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - - _num_values = slv2_plugin_get_num_ports(_plugin->slv2_plugin()); - _min_values = new float[_num_values]; - _max_values = new float[_num_values]; - slv2_plugin_get_port_ranges_float(_plugin->slv2_plugin(), - _min_values, _max_values, 0); - } - - if (!std::isnan(_min_values[port->index()])) - min = _min_values[port->index()]; - if (!std::isnan(_max_values[port->index()])) - max = _max_values[port->index()]; - } -#endif - - // Possibly overriden - const Atom& min_atom = port->get_variable("ingen:minimum"); - const Atom& max_atom = port->get_variable("ingen:maximum"); - if (min_atom.type() == Atom::FLOAT) - min = min_atom.get_float(); - if (max_atom.type() == Atom::FLOAT) - max = max_atom.get_float(); -} - - -void -NodeModel::set(SharedPtr<ObjectModel> model) -{ - SharedPtr<NodeModel> node = PtrCast<NodeModel>(model); - if (node) { - _plugin_uri = node->_plugin_uri; - _plugin = node->_plugin; - } - - ObjectModel::set(model); -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/NodeModel.hpp b/src/libs/client/NodeModel.hpp deleted file mode 100644 index 03afc17c..00000000 --- a/src/libs/client/NodeModel.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 NODEMODEL_H -#define NODEMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <sigc++/sigc++.h> -#include <raul/Table.hpp> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/Node.hpp" -#include "interface/Port.hpp" -#include "ObjectModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" - -using std::string; -using Raul::Table; - -namespace Ingen { -namespace Client { - -class PluginModel; -class ClientStore; - - -/** Node model class, used by the client to store engine's state. - * - * \ingroup IngenClient - */ -class NodeModel : public ObjectModel, virtual public Ingen::Shared::Node -{ -public: - NodeModel(const NodeModel& copy); - virtual ~NodeModel(); - - typedef vector<SharedPtr<PortModel> > Ports; - - SharedPtr<PortModel> get_port(const string& port_name) const; - - Shared::Port* port(uint32_t index) const; - - const string& plugin_uri() const { return _plugin_uri; } - const Shared::Plugin* plugin() const { return _plugin.get(); } - uint32_t num_ports() const { return _ports.size(); } - const Ports& ports() const { return _ports; } - - void port_value_range(SharedPtr<PortModel> port, float& min, float& max); - - // Signals - sigc::signal<void, SharedPtr<PortModel> > signal_new_port; - sigc::signal<void, SharedPtr<PortModel> > signal_removed_port; - -protected: - friend class ClientStore; - - NodeModel(const string& plugin_uri, const Path& path); - NodeModel(SharedPtr<PluginModel> plugin, const Path& path); - - NodeModel(const Path& path); - void add_child(SharedPtr<ObjectModel> c); - bool remove_child(SharedPtr<ObjectModel> c); - void add_port(SharedPtr<PortModel> pm); - void remove_port(SharedPtr<PortModel> pm); - void remove_port(const Path& port_path); - void add_program(int bank, int program, const string& name); - void remove_program(int bank, int program); - void set(SharedPtr<ObjectModel> model); - - virtual void clear(); - - Ports _ports; ///< Vector of ports (not a Table to preserve order) - string _plugin_uri; ///< Plugin URI (if PluginModel is unknown) - SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of - uint32_t _num_values; ///< Size of _min_values and _max_values - float* _min_values; ///< Port min values (cached for LV2) - float* _max_values; ///< Port max values (cached for LV2) -}; - - -} // namespace Client -} // namespace Ingen - -#endif // NODEMODEL_H diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp deleted file mode 100644 index 8ebd9d8e..00000000 --- a/src/libs/client/OSCClientReceiver.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "OSCClientReceiver.hpp" -#include <raul/AtomLiblo.hpp> -#include <list> -#include <cassert> -#include <cstring> -#include <iostream> -#include <sstream> - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -OSCClientReceiver::OSCClientReceiver(int listen_port, SharedPtr<Shared::ClientInterface> target) - : _target(target) - , _listen_port(listen_port) - , _st(NULL) -{ - start(false); // true = dump, false = shutup -} - - -OSCClientReceiver::~OSCClientReceiver() -{ - stop(); -} - - -void -OSCClientReceiver::start(bool dump_osc) -{ - if (_st != NULL) - return; - - // Attempt preferred port - if (_listen_port != 0) { - char port_str[8]; - snprintf(port_str, 8, "%d", _listen_port); - _st = lo_server_thread_new(port_str, lo_error_cb); - } - - // Find a free port - if (!_st) { - _st = lo_server_thread_new(NULL, lo_error_cb); - _listen_port = lo_server_thread_get_port(_st); - } - - if (_st == NULL) { - cerr << "[OSCClientReceiver] Could not start OSC listener. Aborting." << endl; - exit(EXIT_FAILURE); - } else { - cout << "[OSCClientReceiver] Started OSC listener on port " << lo_server_thread_get_port(_st) << endl; - } - - // Print all incoming messages - if (dump_osc) - lo_server_thread_add_method(_st, NULL, NULL, generic_cb, NULL); - - setup_callbacks(); - - // Display any uncaught messages to the console - //lo_server_thread_add_method(_st, NULL, NULL, unknown_cb, NULL); - - lo_server_thread_start(_st); -} - - -void -OSCClientReceiver::stop() -{ - if (_st != NULL) { - //unregister_client(); - lo_server_thread_free(_st); - _st = NULL; - } -} - - -int -OSCClientReceiver::generic_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) -{ - printf("[OSCMsg] %s (%s)\t", path, types); - - for (int i=0; i < argc; ++i) { - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\t"); - } - printf("\n"); - - /*for (int i=0; i < argc; ++i) { - printf(" '%c' ", types[i]); - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\n"); - } - printf("\n");*/ - - return 1; // not handled -} - - -void -OSCClientReceiver::lo_error_cb(int num, const char* msg, const char* path) -{ - cerr << "Got error from server: " << msg << endl; -} - - - -int -OSCClientReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) -{ - std::string msg = "Received unknown OSC message: "; - msg += path; - - cerr << msg << endl; - - return 0; -} - - -void -OSCClientReceiver::setup_callbacks() -{ - lo_server_thread_add_method(_st, "/ingen/ok", "i", response_ok_cb, this); - lo_server_thread_add_method(_st, "/ingen/error", "is", response_error_cb, this); - lo_server_thread_add_method(_st, "/ingen/plugin", "ssss", plugin_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_patch", "si", new_patch_cb, this); - lo_server_thread_add_method(_st, "/ingen/destroyed", "s", destroyed_cb, this); - lo_server_thread_add_method(_st, "/ingen/patch_cleared", "s", patch_cleared_cb, this); - lo_server_thread_add_method(_st, "/ingen/object_renamed", "ss", object_renamed_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_connection", "ss", connection_cb, this); - lo_server_thread_add_method(_st, "/ingen/disconnection", "ss", disconnection_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_node", "ss", new_node_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_port", "sisi", new_port_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_variable", NULL, set_variable_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_property", NULL, set_property_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_port_value", "sf", set_port_value_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_voice_value", "sif", set_voice_value_cb, this); - lo_server_thread_add_method(_st, "/ingen/port_activity", "s", port_activity_cb, this); - lo_server_thread_add_method(_st, "/ingen/program_add", "siis", program_add_cb, this); - lo_server_thread_add_method(_st, "/ingen/program_remove", "sii", program_remove_cb, this); -} - - -/** Catches errors that aren't a direct result of a client request. - */ -int -OSCClientReceiver::_error_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->error((char*)argv[0]); - return 0; -} - - -int -OSCClientReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->new_patch(&argv[0]->s, argv[1]->i); // path, poly - return 0; -} - - -int -OSCClientReceiver::_destroyed_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->destroy((const char*)&argv[0]->s); - return 0; -} - - -int -OSCClientReceiver::_patch_cleared_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->patch_cleared((const char*)&argv[0]->s); - return 0; -} - - -int -OSCClientReceiver::_object_renamed_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->object_renamed((const char*)&argv[0]->s, (const char*)&argv[1]->s); - return 0; -} - - -int -OSCClientReceiver::_connection_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const src_port_path = &argv[0]->s; - const char* const dst_port_path = &argv[1]->s; - - _target->connect(src_port_path, dst_port_path); - - return 0; -} - - -int -OSCClientReceiver::_disconnection_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[0]->s; - const char* dst_port_path = &argv[1]->s; - - _target->disconnect(src_port_path, dst_port_path); - - return 0; -} - - -/** Notification of a new node creation. - */ -int -OSCClientReceiver::_new_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* uri = &argv[0]->s; - const char* node_path = &argv[1]->s; - - _target->new_node(uri, node_path); - - return 0; -} - - -/** Notification of a new port creation. - */ -int -OSCClientReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[0]->s; - const uint32_t index = argv[1]->i; - const char* type = &argv[2]->s; - const bool is_output = (argv[3]->i == 1); - - _target->new_port(port_path, index, type, is_output); - - return 0; -} - - -/** Notification of a new or updated variable. - */ -int -OSCClientReceiver::_set_variable_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 3 || types[0] != 's' || types[1] != 's') - return 1; - - const char* obj_path = &argv[0]->s; - const char* key = &argv[1]->s; - - Atom value = AtomLiblo::lo_arg_to_atom(types[2], argv[2]); - - _target->set_variable(obj_path, key, value); - - return 0; -} - - -/** Notification of a new or updated property. - */ -int -OSCClientReceiver::_set_property_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 3 || types[0] != 's' || types[1] != 's') - return 1; - - const char* obj_path = &argv[0]->s; - const char* key = &argv[1]->s; - - Atom value = AtomLiblo::lo_arg_to_atom(types[2], argv[2]); - - _target->set_property(obj_path, key, value); - - return 0; -} - - -int -OSCClientReceiver::_set_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - const float value = argv[1]->f; - - _target->set_port_value(port_path, value); - - return 0; -} - - -int -OSCClientReceiver::_set_voice_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - const int voice = argv[1]->i; - const float value = argv[2]->f; - - _target->set_voice_value(port_path, voice, value); - - return 0; -} - - -int -OSCClientReceiver::_port_activity_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - - _target->port_activity(port_path); - - return 0; -} - - -int -OSCClientReceiver::_response_ok_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(!strcmp(types, "i")); - _target->response_ok(argv[0]->i); - - return 0; -} - - -int -OSCClientReceiver::_response_error_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(!strcmp(types, "is")); - _target->response_error(argv[0]->i, &argv[1]->s); - - return 0; -} - - -/** A plugin info response from the server, in response to an /ingen/send_plugins - */ -int -OSCClientReceiver::_plugin_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(argc == 4 && !strcmp(types, "ssss")); - _target->new_plugin(&argv[0]->s, &argv[1]->s, &argv[2]->s, &argv[3]->s); // uri, type, symbol, name - - return 0; -} - - -int -OSCClientReceiver::_program_add_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[0]->s; - int32_t bank = argv[1]->i; - int32_t program = argv[2]->i; - const char* name = &argv[3]->s; - - _target->program_add(node_path, bank, program, name); - - return 0; -} - - -int -OSCClientReceiver::_program_remove_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[0]->s; - int32_t bank = argv[1]->i; - int32_t program = argv[2]->i; - - _target->program_remove(node_path, bank, program); - - return 0; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/OSCClientReceiver.hpp b/src/libs/client/OSCClientReceiver.hpp deleted file mode 100644 index ea5871b3..00000000 --- a/src/libs/client/OSCClientReceiver.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OSCCLIENTRECEIVER_H -#define OSCCLIENTRECEIVER_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <lo/lo.h> -#include "interface/ClientInterface.hpp" -#include "raul/Deletable.hpp" - -namespace Ingen { -namespace Client { - -/** Arguments to a liblo handler */ -#define LO_HANDLER_ARGS const char* path, const char* types, lo_arg** argv, int argc, lo_message msg - -/** Define a static handler to be passed to lo_add_method, which is a trivial - * wrapper around a non-static method that does the real work. */ -#define LO_HANDLER(name) \ -int _##name##_cb (LO_HANDLER_ARGS);\ -inline static int name##_cb(LO_HANDLER_ARGS, void* osc_listener)\ -{ return ((OSCClientReceiver*)osc_listener)->_##name##_cb(path, types, argv, argc, msg); } - - -/** Callbacks for "notification band" OSC messages. - * - * Receives all notification of engine state, but not replies on the "control - * band". See OSC namespace documentation for details. - * - * Right now this class and Comm share the same lo_server_thread and the barrier - * between them is a bit odd, but eventually this class will be able to listen - * on a completely different port (ie have it's own lo_server_thread) to allow - * things like listening to the notification band over TCP while sending commands - * on the control band over UDP. - * - * \ingroup IngenClient - */ -class OSCClientReceiver : public boost::noncopyable, public Raul::Deletable -{ -public: - OSCClientReceiver(int listen_port, SharedPtr<Shared::ClientInterface> target); - ~OSCClientReceiver(); - - std::string uri() const { return lo_server_thread_get_url(_st); } - - void start(bool dump_osc); - void stop(); - - int listen_port() { return _listen_port; } - std::string listen_url() { return lo_server_thread_get_url(_st); } - -private: - void setup_callbacks(); - - static void lo_error_cb(int num, const char* msg, const char* path); - - static int generic_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data); - static int unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* osc_receiver); - - SharedPtr<Shared::ClientInterface> _target; - - int _listen_port; - lo_server_thread _st; - - LO_HANDLER(error); - LO_HANDLER(response_ok); - LO_HANDLER(response_error); - LO_HANDLER(plugin); - LO_HANDLER(plugin_list_end); - LO_HANDLER(new_patch); - LO_HANDLER(destroyed); - LO_HANDLER(patch_cleared); - LO_HANDLER(object_renamed); - LO_HANDLER(connection); - LO_HANDLER(disconnection); - LO_HANDLER(new_node); - LO_HANDLER(new_port); - LO_HANDLER(set_variable); - LO_HANDLER(set_property); - LO_HANDLER(set_port_value); - LO_HANDLER(set_voice_value); - LO_HANDLER(port_activity); - LO_HANDLER(program_add); - LO_HANDLER(program_remove); -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OSCCLIENTRECEIVER_H diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp deleted file mode 100644 index c21d16ce..00000000 --- a/src/libs/client/OSCEngineSender.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <raul/AtomLiblo.hpp> -#include "OSCEngineSender.hpp" - -using namespace std; -using Raul::Atom; - -namespace Ingen { -namespace Client { - - -/** Note the sending port is implicitly set by liblo, lo_send by default sends - * from the most recently created server, so create the OSC listener before - * this to have it all happen on the same port. Yeah, this is a big magic :/ - */ -OSCEngineSender::OSCEngineSender(const string& engine_url) - : _engine_url(engine_url) - , _id(0) -{ - _address = lo_address_new_from_url(engine_url.c_str()); -} - - -OSCEngineSender::~OSCEngineSender() -{ - lo_address_free(_address); -} - - -/** Attempt to connect to the engine (by pinging it). - * - * This doesn't register a client (or otherwise affect the client/engine state). - * To check for success wait for the ping response with id @a ping_id (using the - * relevant OSCClientReceiver). - * - * Passing a client_port of 0 will automatically choose a free port. If the - * @a block parameter is true, this function will not return until a connection - * has successfully been made. - */ -void -OSCEngineSender::attach(int32_t ping_id, bool block) -{ - if (!_address) - _address = lo_address_new_from_url(_engine_url.c_str()); - - if (_address == NULL) { - cerr << "Aborting: Unable to connect to " << _engine_url << endl; - exit(EXIT_FAILURE); - } - - cout << "[OSCEngineSender] Attempting to contact engine at " << _engine_url << " ..." << endl; - - _id = ping_id; - this->ping(); -} - -/* *** EngineInterface implementation below here *** */ - - -/** Register with the engine via OSC. - * - * Note that this does not actually use 'key', since the engine creates - * it's own key for OSC clients (namely the incoming URL), for NAT - * traversal. It is a parameter to remain compatible with EngineInterface. - */ -void -OSCEngineSender::register_client(ClientInterface* client) -{ - // FIXME: use parameters.. er, somehow. - send("/ingen/register_client", "i", next_id(), LO_ARGS_END, LO_ARGS_END); -} - - -void -OSCEngineSender::unregister_client(const string& uri) -{ - send("/ingen/unregister_client", "i", next_id(), LO_ARGS_END); -} - - -// Engine commands -void -OSCEngineSender::load_plugins() -{ - send("/ingen/load_plugins", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::activate() -{ - send("/ingen/activate", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::deactivate() -{ - send("/ingen/deactivate", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::quit() -{ - send("/ingen/quit", "i", next_id(), LO_ARGS_END); -} - - - -// Object commands - -void -OSCEngineSender::new_patch(const string& path, - uint32_t poly) -{ - send("/ingen/new_patch", "isi", - next_id(), - path.c_str(), - poly, - LO_ARGS_END); -} - - -void -OSCEngineSender::new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output) -{ - // FIXME: use index - send("/ingen/new_port", "issi", - next_id(), - path.c_str(), - data_type.c_str(), - (is_output ? 1 : 0), - LO_ARGS_END); -} - - -void -OSCEngineSender::new_node(const string& path, - const string& plugin_uri) -{ - - send("/ingen/new_node", "iss", - next_id(), - path.c_str(), - plugin_uri.c_str(), - LO_ARGS_END); -} - - -/** Create a node using library name and plugin label (DEPRECATED). - * - * DO NOT USE THIS. - */ -void -OSCEngineSender::new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label) -{ - send("/ingen/new_node", "issss", - next_id(), - path.c_str(), - plugin_type.c_str(), - library_name.c_str(), - plugin_label.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::rename(const string& old_path, - const string& new_name) -{ - send("/ingen/rename", "iss", - next_id(), - old_path.c_str(), - new_name.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::destroy(const string& path) -{ - send("/ingen/destroy", "is", - next_id(), - path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::clear_patch(const string& patch_path) -{ - send("/ingen/clear_patch", "is", - next_id(), - patch_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::connect(const string& src_port_path, - const string& dst_port_path) -{ - send("/ingen/connect", "iss", - next_id(), - src_port_path.c_str(), - dst_port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) -{ - send("/ingen/disconnect", "iss", - next_id(), - src_port_path.c_str(), - dst_port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::disconnect_all(const string& parent_patch_path, - const string& node_path) -{ - send("/ingen/disconnect_all", "iss", - next_id(), - parent_patch_path.c_str(), - node_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::set_port_value(const string& port_path, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, port_path.c_str()); - if (value.type() == Atom::BLOB) - lo_message_add_string(m, value.get_blob_type()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -void -OSCEngineSender::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, port_path.c_str()); - lo_message_add_int32(m, voice); - if (value.type() == Atom::BLOB) - lo_message_add_string(m, value.get_blob_type()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -void -OSCEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ - send((string("/dssi") + node_path + "/program").c_str(), - "ii", - bank, - program, - LO_ARGS_END); -} - - -void -OSCEngineSender::midi_learn(const string& node_path) -{ - send("/ingen/midi_learn", "is", - next_id(), - node_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, obj_path.c_str()); - lo_message_add_string(m, predicate.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_variable", m); -} - - -void -OSCEngineSender::set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, obj_path.c_str()); - lo_message_add_string(m, predicate.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_property", m); -} - - - -// Requests // - -void -OSCEngineSender::ping() -{ - send("/ingen/ping", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::request_plugin(const string& uri) -{ - send("/ingen/request_plugin", "is", - next_id(), - uri.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_object(const string& path) -{ - send("/ingen/request_object", "is", - next_id(), - path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_port_value(const string& port_path) -{ - send("/ingen/request_port_value", "is", - next_id(), - port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_variable(const string& object_path, const string& key) -{ - send("/ingen/request_variable", "iss", - next_id(), - object_path.c_str(), - key.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_property(const string& object_path, const string& key) -{ - send("/ingen/request_property", "iss", - next_id(), - object_path.c_str(), - key.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_plugins() -{ - send("/ingen/request_plugins", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::request_all_objects() -{ - send("/ingen/request_all_objects", "i", next_id(), LO_ARGS_END); -} - - - -} // namespace Client -} // namespace Ingen - - diff --git a/src/libs/client/OSCEngineSender.hpp b/src/libs/client/OSCEngineSender.hpp deleted file mode 100644 index ef4a2fa3..00000000 --- a/src/libs/client/OSCEngineSender.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OSCENGINESENDER_H -#define OSCENGINESENDER_H - -#include <inttypes.h> -#include <string> -#include <lo/lo.h> -#include "interface/EngineInterface.hpp" -#include "shared/OSCSender.hpp" -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::ClientInterface; - -namespace Ingen { -namespace Client { - - -/* OSC (via liblo) interface to the engine. - * - * Clients can use this opaquely as an EngineInterface* to control the engine - * over OSC (whether over a network or not, etc). - * - * \ingroup IngenClient - */ -class OSCEngineSender : public EngineInterface, public Shared::OSCSender { -public: - OSCEngineSender(const string& engine_url); - - ~OSCEngineSender(); - - std::string uri() const { return _engine_url; } - - inline int32_t next_id() - { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } - - void set_next_response_id(int32_t id) { _id = id; } - void disable_responses() { _id = -1; } - - void attach(int32_t ping_id, bool block); - - - /* *** EngineInterface implementation below here *** */ - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { OSCSender::bundle_begin(); } - void bundle_end() { OSCSender::bundle_end(); } - void transfer_begin() { OSCSender::transfer_begin(); } - void transfer_end() { OSCSender::transfer_end(); } - - // Client registration - void register_client(ClientInterface* client); - void unregister_client(const string& uri); - - // Engine commands - void load_plugins(); - void activate(); - void deactivate(); - void quit(); - - // Object commands - - void new_patch(const string& path, - uint32_t poly); - - void new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output); - - void new_node(const string& path, - const string& plugin_uri); - - void new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label); - - void rename(const string& old_path, - const string& new_name); - - void destroy(const string& path); - - void clear_patch(const string& patch_path); - - void connect(const string& src_port_path, - const string& dst_port_path); - - void disconnect(const string& src_port_path, - const string& dst_port_path); - - void disconnect_all(const string& parent_patch_path, - const string& node_path); - - void set_port_value(const string& port_path, - const Raul::Atom& value); - - void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - void midi_learn(const string& node_path); - - void set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - void set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - void ping(); - void request_plugin(const string& uri); - void request_object(const string& path); - void request_port_value(const string& port_path); - void request_variable(const string& path, const string& key); - void request_property(const string& path, const string& key); - void request_plugins(); - void request_all_objects(); - -protected: - const string _engine_url; - int _client_port; - int32_t _id; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OSCENGINESENDER_H - diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp deleted file mode 100644 index ede5f822..00000000 --- a/src/libs/client/ObjectModel.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <raul/TableImpl.hpp> -#include "interface/GraphObject.hpp" -#include "ObjectModel.hpp" - -using namespace std; - -namespace Ingen { -namespace Client { - - -ObjectModel::ObjectModel(const Path& path) - : _path(path) -{ -} - - -ObjectModel::~ObjectModel() -{ -} - - -/** Get a variable for this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -const Atom& -ObjectModel::get_variable(const string& key) const -{ - static const Atom null_atom; - - Variables::const_iterator i = _variables.find(key); - if (i != _variables.end()) - return i->second; - else - return null_atom; -} - - -/** Get a variable for this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -Atom& -ObjectModel::get_variable( string& key) -{ - static Atom null_atom; - - Variables::iterator i = _variables.find(key); - if (i != _variables.end()) - return i->second; - else - return null_atom; -} - - -/** Get a property of this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -const Atom& -ObjectModel::get_property(const string& key) const -{ - static const Atom null_atom; - - Properties::const_iterator i = _properties.find(key); - if (i != _properties.end()) - return i->second; - else - return null_atom; -} - - -/** Get a property of this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -Atom& -ObjectModel::get_property(const string& key) -{ - static Atom null_atom; - - Properties::iterator i = _properties.find(key); - if (i != _properties.end()) - return i->second; - else - return null_atom; -} - - -bool -ObjectModel::polyphonic() const -{ - Properties::const_iterator i = _properties.find("ingen:polyphonic"); - return (i != _properties.end() && i->second.type() == Atom::BOOL && i->second.get_bool()); -} - - -/** Merge the data of @a model with self, as much as possible. - * - * This will merge the two models, but with any conflict take the value in - * @a model as correct. The paths of the two models MUST be equal. - */ -void -ObjectModel::set(SharedPtr<ObjectModel> o) -{ - assert(_path == o->path()); - if (o->_parent) - _parent = o->_parent; - - for (Variables::const_iterator v = o->variables().begin(); v != o->variables().end(); ++v) { - Variables::const_iterator mine = _variables.find(v->first); - if (mine != _variables.end()) - cerr << "WARNING: " << _path << "Client/Server variable mismatch: " << v->first << endl; - _variables[v->first] = v->second; - signal_variable.emit(v->first, v->second); - } - - for (Properties::const_iterator v = o->properties().begin(); v != o->properties().end(); ++v) { - Properties::const_iterator mine = _properties.find(v->first); - if (mine != _properties.end()) - cerr << "WARNING: " << _path << "Client/Server property mismatch: " << v->first << endl; - _properties[v->first] = v->second; - signal_variable.emit(v->first, v->second); - } -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/ObjectModel.hpp b/src/libs/client/ObjectModel.hpp deleted file mode 100644 index 11cc87a4..00000000 --- a/src/libs/client/ObjectModel.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OBJECTMODEL_H -#define OBJECTMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <algorithm> -#include <cassert> -#include <boost/utility.hpp> -#include <sigc++/sigc++.h> -#include <raul/Atom.hpp> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include <raul/PathTable.hpp> -#include "interface/GraphObject.hpp" - -using Raul::PathTable; -using std::string; -using Raul::Atom; -using Raul::Path; -using Raul::Symbol; - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Base class for all GraphObject models (NodeModel, PatchModel, PortModel). - * - * There are no non-const public methods intentionally, models are not allowed - * to be manipulated directly by anything (but the Store) because of the - * asynchronous nature of engine control. To change something, use the - * controller (which the model probably shouldn't have a reference to but oh - * well, it reduces Collection Hell) and wait for the result (as a signal - * from this Model). - * - * \ingroup IngenClient - */ -class ObjectModel : virtual public Ingen::Shared::GraphObject -{ -public: - virtual ~ObjectModel(); - - const Atom& get_variable(const string& key) const; - Atom& get_variable( string& key); - const Atom& get_property(const string& key) const; - Atom& get_property(const string& key); - - virtual void set_variable(const string& key, const Atom& value) - { _variables[key] = value; signal_variable.emit(key, value); } - - virtual void set_property(const string& key, const Atom& value) - { _properties[key] = value; signal_property.emit(key, value); } - - const Variables& variables() const { return _variables; } - const Properties& properties() const { return _properties; } - Variables& variables() { return _variables; } - Properties& properties() { return _properties; } - const Path path() const { return _path; } - const Symbol symbol() const { return _path.name(); } - SharedPtr<ObjectModel> parent() const { return _parent; } - bool polyphonic() const; - - GraphObject* graph_parent() const { return _parent.get(); } - - // Signals - sigc::signal<void, SharedPtr<ObjectModel> > signal_new_child; - sigc::signal<void, SharedPtr<ObjectModel> > signal_removed_child; - sigc::signal<void, const string&, const Atom&> signal_variable; - sigc::signal<void, const string&, const Atom&> signal_property; - sigc::signal<void> signal_destroyed; - sigc::signal<void> signal_renamed; - -protected: - friend class ClientStore; - - ObjectModel(const Path& path); - - virtual void set_path(const Path& p) { _path = p; signal_renamed.emit(); } - virtual void set_parent(SharedPtr<ObjectModel> p) { assert(p); _parent = p; } - virtual void add_child(SharedPtr<ObjectModel> c) {} - virtual bool remove_child(SharedPtr<ObjectModel> c) { return true; } - - virtual void set(SharedPtr<ObjectModel> model); - - Path _path; - SharedPtr<ObjectModel> _parent; - - Variables _variables; - Properties _properties; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OBJECTMODEL_H diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp deleted file mode 100644 index af20c9f8..00000000 --- a/src/libs/client/PatchModel.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "PatchModel.hpp" -#include "NodeModel.hpp" -#include "ConnectionModel.hpp" -#include "ClientStore.hpp" -#include <cassert> -#include <iostream> - -using std::cerr; using std::cout; using std::endl; - -namespace Ingen { -namespace Client { - - -void -PatchModel::add_child(SharedPtr<ObjectModel> c) -{ - assert(c->parent().get() == this); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - if (pm) { - add_port(pm); - return; - } - - SharedPtr<NodeModel> nm = PtrCast<NodeModel>(c); - if (nm) - signal_new_node.emit(nm); -} - - -bool -PatchModel::remove_child(SharedPtr<ObjectModel> o) -{ - assert(o->path().is_child_of(_path)); - assert(o->parent().get() == this); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(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<ConnectionModel> cm = PtrCast<ConnectionModel>(*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<NodeModel> nm = PtrCast<NodeModel>(o); - if (nm) - signal_removed_node.emit(nm); - - return true; -} - - -void -PatchModel::clear() -{ - _connections->clear(); - - NodeModel::clear(); - - assert(_connections->empty()); - assert(_ports.empty()); -} - - -SharedPtr<ConnectionModel> -PatchModel::get_connection(const string& src_port_path, const string& 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<ConnectionModel>(*i); - - return SharedPtr<ConnectionModel>(); -} - - -/** 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<ConnectionModel> 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<ConnectionModel> 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 string& src_port_path, const string& dst_port_path) -{ - for (Connections::iterator i = _connections->begin(); i != _connections->end(); ++i) { - SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(*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 -{ - Properties::const_iterator i = _properties.find("ingen:enabled"); - return (i != _properties.end() && i->second.type() == Atom::BOOL && i->second.get_bool()); -} - - -void -PatchModel::set_property(const string& key, const Atom& value) -{ - ObjectModel::set_property(key, value); - if (key == "ingen:polyphony") - _poly = value.get_int32(); -} - - -bool -PatchModel::polyphonic() const -{ - return (_parent) - ? (_poly > 1) && _poly == PtrCast<PatchModel>(_parent)->poly() && _poly > 1 - : (_poly > 1); -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PatchModel.hpp b/src/libs/client/PatchModel.hpp deleted file mode 100644 index 70c8df0e..00000000 --- a/src/libs/client/PatchModel.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PATCHMODEL_H -#define PATCHMODEL_H - -#include <cassert> -#include <list> -#include <string> -#include <sigc++/sigc++.h> -#include <raul/SharedPtr.hpp> -#include "interface/Patch.hpp" -#include "NodeModel.hpp" - -#include "ConnectionModel.hpp" - -using std::list; using std::string; - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Client's model of a patch. - * - * \ingroup IngenClient - */ -class PatchModel : public NodeModel, public Ingen::Shared::Patch -{ -public: - /* WARNING: Copy constructor creates a shallow copy WRT connections */ - - const Connections& connections() const { return *_connections.get(); } - - SharedPtr<ConnectionModel> get_connection(const string& src_port_path, - const string& dst_port_path) const; - - uint32_t poly() const { return _poly; } - uint32_t internal_polyphony() const { return _poly; } - bool enabled() const; - bool polyphonic() const; - - /** "editable" = arranging,connecting,adding,deleting,etc - * not editable (control mode) you can just change controllers (performing) - */ - bool get_editable() const { return _editable; } - void set_editable(bool e) { if (_editable != e) { - _editable = e; - signal_editable.emit(e); - } } - - virtual void set_property(const string& key, const Atom& value); - - // Signals - sigc::signal<void, SharedPtr<NodeModel> > signal_new_node; - sigc::signal<void, SharedPtr<NodeModel> > signal_removed_node; - sigc::signal<void, SharedPtr<ConnectionModel> > signal_new_connection; - sigc::signal<void, SharedPtr<ConnectionModel> > signal_removed_connection; - sigc::signal<void, bool> signal_editable; - -private: - friend class ClientStore; - - PatchModel(const Path& patch_path, size_t internal_poly) - : NodeModel("ingen:Patch", patch_path) - , _connections(new Connections()) - , _poly(internal_poly) - , _editable(true) - { - } - - void clear(); - void add_child(SharedPtr<ObjectModel> c); - bool remove_child(SharedPtr<ObjectModel> c); - - void add_connection(SharedPtr<ConnectionModel> cm); - void remove_connection(const string& src_port_path, const string& dst_port_path); - - SharedPtr<Connections> _connections; - uint32_t _poly; - bool _editable; -}; - -typedef Table<string, SharedPtr<PatchModel> > PatchModelMap; - - -} // namespace Client -} // namespace Ingen - -#endif // PATCHMODEL_H diff --git a/src/libs/client/PluginModel.cpp b/src/libs/client/PluginModel.cpp deleted file mode 100644 index ff7e5b5c..00000000 --- a/src/libs/client/PluginModel.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <sstream> -#include <raul/Path.hpp> -#include "PluginModel.hpp" -#include "PatchModel.hpp" -#include "PluginUI.hpp" - -using namespace std; -using Ingen::Shared::EngineInterface; - -namespace Ingen { -namespace Client { - -#ifdef HAVE_SLV2 -SLV2World PluginModel::_slv2_world = NULL; -SLV2Plugins PluginModel::_slv2_plugins = NULL; -#endif - -Redland::World* PluginModel::_rdf_world = NULL; - - -string -PluginModel::default_node_symbol() -{ - return Raul::Path::nameify(_symbol); -} - - -string -PluginModel::human_name() -{ -#ifdef HAVE_SLV2 - if (_slv2_plugin) { - SLV2Value name = slv2_plugin_get_name(_slv2_plugin); - string ret = slv2_value_as_string(name); - slv2_value_free(name); - return ret; - } -#endif - return default_node_symbol(); -} - - -string -PluginModel::port_human_name(uint32_t index) -{ -#ifdef HAVE_SLV2 - if (_slv2_plugin) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - SLV2Port port = slv2_plugin_get_port_by_index(_slv2_plugin, index); - SLV2Value name = slv2_port_get_name(_slv2_plugin, port); - string ret = slv2_value_as_string(name); - slv2_value_free(name); - return ret; - } -#endif - return ""; -} - - -#ifdef HAVE_SLV2 -bool -PluginModel::has_ui() const -{ - Glib::Mutex::Lock lock(_rdf_world->mutex()); - - SLV2Value gtk_gui_uri = slv2_value_new_uri(_slv2_world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); - - SLV2UIs uis = slv2_plugin_get_uis(_slv2_plugin); - - if (slv2_values_size(uis) > 0) - for (unsigned i=0; i < slv2_uis_size(uis); ++i) - if (slv2_ui_is_a(slv2_uis_get_at(uis, i), gtk_gui_uri)) - return true; - - return false; -} - - -SharedPtr<PluginUI> -PluginModel::ui(Ingen::Shared::World* world, SharedPtr<NodeModel> node) const -{ - if (_type != LV2) - return SharedPtr<PluginUI>(); - - SharedPtr<PluginUI> ret = PluginUI::create(world, node, _slv2_plugin); - return ret; -} - - -const string& -PluginModel::icon_path() const -{ - if (_icon_path == "" && _type == LV2) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - _icon_path = get_lv2_icon_path(_slv2_plugin); - } - - return _icon_path; -} - - -/** RDF world mutex must be held by the caller */ -string -PluginModel::get_lv2_icon_path(SLV2Plugin plugin) -{ - string result; - SLV2Value svg_icon_pred = slv2_value_new_uri(_slv2_world, - "http://ll-plugins.nongnu.org/lv2/namespace#svgIcon"); - - SLV2Values paths = slv2_plugin_get_value(plugin, svg_icon_pred); - - if (slv2_values_size(paths) > 0) { - SLV2Value value = slv2_values_get_at(paths, 0); - if (slv2_value_is_uri(value)) - result = slv2_uri_to_path(slv2_value_as_string(value)); - slv2_values_free(paths); - } - - slv2_value_free(svg_icon_pred); - return result; -} -#endif - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PluginModel.hpp b/src/libs/client/PluginModel.hpp deleted file mode 100644 index e2137e19..00000000 --- a/src/libs/client/PluginModel.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PLUGINMODEL_H -#define PLUGINMODEL_H - -#include CONFIG_H_PATH -#include <string> -#include <iostream> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include <redlandmm/World.hpp> -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif -#include "interface/EngineInterface.hpp" -#include "interface/Plugin.hpp" -#include "module/World.hpp" - -using std::string; - -namespace Ingen { -namespace Client { - -class PatchModel; -class NodeModel; -class PluginUI; - - -/** Model for a plugin available for loading. - * - * \ingroup IngenClient - */ -class PluginModel : public Ingen::Shared::Plugin -{ -public: - PluginModel(const string& uri, const string& type_uri, const string& symbol, const string& name) - : _type(type_from_uri(type_uri)) - , _uri(uri) - , _symbol(symbol) - , _name(name) - { -#ifdef HAVE_SLV2 - Glib::Mutex::Lock lock(_rdf_world->mutex()); - SLV2Value plugin_uri = slv2_value_new_uri(_slv2_world, uri.c_str()); - _slv2_plugin = slv2_plugins_get_by_uri(_slv2_plugins, plugin_uri); - slv2_value_free(plugin_uri); -#endif - } - - Type type() const { return _type; } - const string& uri() const { return _uri; } - const string& name() const { return _name; } - - /** DEPRECATED */ - Type type_from_string(const string& type_string) { - if (type_string == "LV2") return LV2; - else if (type_string == "LADSPA") return LADSPA; - else if (type_string == "Internal") return Internal; - else if (type_string == "Patch") return Patch; - else return Internal; // ? - } - - Type type_from_uri(const string& type_uri) { - if (type_uri.substr(0, 6) != "ingen:") { - return Plugin::Internal; // ? - } else { - return type_from_string(type_uri.substr(6)); - } - } - - string default_node_symbol(); - string human_name(); - string port_human_name(uint32_t index); - -#ifdef HAVE_SLV2 - static SLV2World slv2_world() { return _slv2_world; } - SLV2Plugin slv2_plugin() { return _slv2_plugin; } - - SLV2Port slv2_port(uint32_t index) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - return slv2_plugin_get_port_by_index(_slv2_plugin, index); - } - - static void set_slv2_world(SLV2World world) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - _slv2_world = world; - _slv2_plugins = slv2_world_get_all_plugins(_slv2_world); - } - - bool has_ui() const; - - SharedPtr<PluginUI> ui(Ingen::Shared::World* world, - SharedPtr<NodeModel> node) const; - - const string& icon_path() const; - static string get_lv2_icon_path(SLV2Plugin plugin); -#endif - - static void set_rdf_world(Redland::World& world) { - _rdf_world = &world; - } - - static Redland::World* rdf_world() { return _rdf_world; } - -private: - const Type _type; - const string _uri; - const string _symbol; - const string _name; - -#ifdef HAVE_SLV2 - static SLV2World _slv2_world; - static SLV2Plugins _slv2_plugins; - - SLV2Plugin _slv2_plugin; - mutable string _icon_path; -#endif - - static Redland::World* _rdf_world; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PLUGINMODEL_H - diff --git a/src/libs/client/PluginUI.cpp b/src/libs/client/PluginUI.cpp deleted file mode 100644 index 9c562135..00000000 --- a/src/libs/client/PluginUI.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "lv2ext/lv2_event_helpers.h" -#include "shared/LV2URIMap.hpp" -#include "PluginUI.hpp" -#include "NodeModel.hpp" -#include "PortModel.hpp" - -using namespace std; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::LV2URIMap; -using Ingen::Shared::LV2Features; - -namespace Ingen { -namespace Client { - -static void -lv2_ui_write(LV2UI_Controller controller, - uint32_t port_index, - uint32_t buffer_size, - uint32_t format, - const void* buffer) -{ - /* - cerr << "lv2_ui_write (format " << format << "):" << endl; - fprintf(stderr, "RAW:\n"); - for (uint32_t i=0; i < buffer_size; ++i) { - unsigned char byte = ((unsigned char*)buffer)[i]; - if (byte >= 32 && byte <= 126) - fprintf(stderr, "%c ", ((unsigned char*)buffer)[i]); - else - fprintf(stderr, "%2X ", ((unsigned char*)buffer)[i]); - } - fprintf(stderr, "\n"); - */ - - PluginUI* ui = (PluginUI*)controller; - - SharedPtr<PortModel> port = ui->node()->ports()[port_index]; - - const LV2Features::Feature* f = ui->world()->lv2_features->feature(LV2_URI_MAP_URI); - LV2URIMap* map = (LV2URIMap*)f->controller; - assert(map); - - // float (special case, always 0) - if (format == 0) { - assert(buffer_size == 4); - if (*(float*)buffer == port->value().get_float()) - return; // do nothing (handle stupid plugin UIs that feed back) - - ui->world()->engine->set_port_value(port->path(), Atom(*(float*)buffer)); - - // FIXME: slow, need to cache ID - } else if (format == map->uri_to_id(NULL, "http://lv2plug.in/ns/extensions/ui#Events")) { - uint32_t midi_event_type = map->uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent"); - LV2_Event_Buffer* buf = (LV2_Event_Buffer*)buffer; - LV2_Event_Iterator iter; - uint8_t* data; - lv2_event_begin(&iter, buf); - while (lv2_event_is_valid(&iter)) { - LV2_Event* const ev = lv2_event_get(&iter, &data); - if (ev->type == midi_event_type) { - // FIXME: bundle multiple events by writing an entire buffer here - ui->world()->engine->set_port_value(port->path(), - Atom("lv2_midi:MidiEvent", ev->size, data)); - } else { - cerr << "WARNING: Unable to send event type " << ev->type << - " over OSC, ignoring event" << endl; - } - - lv2_event_increment(&iter); - } - } else { - cerr << "WARNING: Unknown value format " << format - << ", either plugin " << ui->node()->plugin()->uri() << " is broken" - << " or this is an Ingen bug" << endl; - } -} - - -PluginUI::PluginUI(Ingen::Shared::World* world, - SharedPtr<NodeModel> node) - : _world(world) - , _node(node) - , _instance(NULL) -{ -} - - -PluginUI::~PluginUI() -{ - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - slv2_ui_instance_free(_instance); -} - - -SharedPtr<PluginUI> -PluginUI::create(Ingen::Shared::World* world, - SharedPtr<NodeModel> node, - SLV2Plugin plugin) -{ - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - SharedPtr<PluginUI> ret; - - SLV2Value gtk_gui_uri = slv2_value_new_uri(world->slv2_world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); - - SLV2UIs uis = slv2_plugin_get_uis(plugin); - SLV2UI ui = NULL; - - if (slv2_values_size(uis) > 0) { - for (unsigned i=0; i < slv2_uis_size(uis); ++i) { - SLV2UI this_ui = slv2_uis_get_at(uis, i); - if (slv2_ui_is_a(this_ui, gtk_gui_uri)) { - ui = this_ui; - break; - } - } - } - - if (ui) { - cout << "Found GTK Plugin UI: " << slv2_ui_get_uri(ui) << endl; - ret = SharedPtr<PluginUI>(new PluginUI(world, node)); - SLV2UIInstance inst = slv2_ui_instantiate( - plugin, ui, lv2_ui_write, ret.get(), world->lv2_features->lv2_features()); - - if (inst) { - ret->set_instance(inst); - } else { - cerr << "ERROR: Failed to instantiate Plugin UI" << endl; - ret = SharedPtr<PluginUI>(); - } - } - - slv2_value_free(gtk_gui_uri); - return ret; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PluginUI.hpp b/src/libs/client/PluginUI.hpp deleted file mode 100644 index d20dd16a..00000000 --- a/src/libs/client/PluginUI.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PLUGINUI_H -#define PLUGINUI_H - -#include <slv2/slv2.h> -#include <raul/SharedPtr.hpp> -#include "module/World.hpp" - -namespace Ingen { -namespace Shared { class EngineInterface; } -namespace Client { - -class NodeModel; - - -/** Model for a plugin available for loading. - * - * \ingroup IngenClient - */ -class PluginUI { -public: - ~PluginUI(); - - static SharedPtr<PluginUI> create(Ingen::Shared::World* world, - SharedPtr<NodeModel> node, - SLV2Plugin plugin); - - Ingen::Shared::World* world() const { return _world; } - SharedPtr<NodeModel> node() const { return _node; } - SLV2UIInstance instance() const { return _instance; } - -private: - PluginUI(Ingen::Shared::World* world, - SharedPtr<NodeModel> node); - - void set_instance(SLV2UIInstance instance) { _instance = instance; } - - Ingen::Shared::World* _world; - SharedPtr<NodeModel> _node; - SLV2UIInstance _instance; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PLUGINUI_H - - diff --git a/src/libs/client/PortModel.cpp b/src/libs/client/PortModel.cpp deleted file mode 100644 index c18378db..00000000 --- a/src/libs/client/PortModel.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "PortModel.hpp" -#include "NodeModel.hpp" - -namespace Ingen { -namespace Client { - - -bool -PortModel::is_logarithmic() const -{ - const Atom& hint = get_variable("ingen:logarithmic"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -bool -PortModel::is_integer() const -{ - const Atom& hint = get_variable("ingen:integer"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -bool -PortModel::is_toggle() const -{ - const Atom& hint = get_variable("ingen:toggled"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -void -PortModel::set(SharedPtr<ObjectModel> model) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(model); - if (port) { - _index = port->_index; - _type = port->_type; - _direction = port->_direction; - _current_val = port->_current_val; - _connections = port->_connections; - signal_value_changed.emit(_current_val); - } - - ObjectModel::set(model); -} - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PortModel.hpp b/src/libs/client/PortModel.hpp deleted file mode 100644 index a7f52679..00000000 --- a/src/libs/client/PortModel.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PORTMODEL_H -#define PORTMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <vector> -#include <sigc++/sigc++.h> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include "interface/Port.hpp" -#include "ObjectModel.hpp" - -using std::string; using std::vector; - -namespace Ingen { -namespace Client { - - -/** Model of a port. - * - * \ingroup IngenClient - */ -class PortModel : public ObjectModel, public Ingen::Shared::Port -{ -public: - enum Direction { INPUT, OUTPUT }; - - inline uint32_t index() const { return _index; } - inline DataType type() const { return _type; } - inline const Atom& value() const { return _current_val; } - inline bool connected() const { return (_connections > 0); } - inline bool is_input() const { return (_direction == INPUT); } - inline bool is_output() const { return (_direction == OUTPUT); } - - bool is_logarithmic() const; - bool is_integer() const; - bool is_toggle() const; - - inline bool operator==(const PortModel& pm) const { return (_path == pm._path); } - - inline void value(const Atom& val) { - if (val != _current_val) { - _current_val = val; - signal_value_changed.emit(val); - } - } - - inline void value(uint32_t voice, const Atom& val) { - // FIXME: implement properly - signal_voice_changed.emit(voice, val); - } - - // Signals - sigc::signal<void, const Atom&> signal_value_changed; ///< Value ports - sigc::signal<void, uint32_t, const Atom&> signal_voice_changed; ///< Polyphonic value ports - sigc::signal<void> signal_activity; ///< Message ports - sigc::signal<void, SharedPtr<PortModel> > signal_connection; - sigc::signal<void, SharedPtr<PortModel> > signal_disconnection; - -private: - friend class ClientStore; - - PortModel(const Path& path, uint32_t index, DataType type, Direction dir) - : ObjectModel(path) - , _index(index) - , _type(type) - , _direction(dir) - , _current_val(0.0f) - , _connections(0) - { - if (_type == DataType::UNKNOWN) - std::cerr << "[PortModel] Warning: Unknown port type" << std::endl; - } - - void add_child(SharedPtr<ObjectModel> c) { throw; } - bool remove_child(SharedPtr<ObjectModel> c) { throw; } - - void connected_to(SharedPtr<PortModel> p) { ++_connections; signal_connection.emit(p); } - void disconnected_from(SharedPtr<PortModel> p) { --_connections; signal_disconnection.emit(p); } - - void set(SharedPtr<ObjectModel> model); - - uint32_t _index; - DataType _type; - Direction _direction; - Atom _current_val; - size_t _connections; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PORTMODEL_H diff --git a/src/libs/client/SigClientInterface.hpp b/src/libs/client/SigClientInterface.hpp deleted file mode 100644 index 7ab32c12..00000000 --- a/src/libs/client/SigClientInterface.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SIGCLIENTINTERFACE_H -#define SIGCLIENTINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <sigc++/sigc++.h> -#include "interface/ClientInterface.hpp" -using std::string; - -namespace Ingen { -namespace Client { - - -/** A LibSigC++ signal emitting interface for clients to use. - * - * This simply emits an sigc signal for every event (eg OSC message) coming from - * the engine. Use Store (which extends this) if you want a nice client-side - * model of the engine. - * - * The signals here match the calls to ClientInterface exactly. See the - * documentation for ClientInterface for meanings of signal parameters. - */ -class SigClientInterface : public Ingen::Shared::ClientInterface, public sigc::trackable -{ -public: - SigClientInterface() : _enabled(true) {} - - bool enabled() const { return _enabled; } - - std::string uri() const { return "(internal)"; } - - // Signal parameters match up directly with ClientInterface calls - - sigc::signal<void, int32_t> signal_response_ok; - sigc::signal<void, int32_t, string> signal_response_error; - sigc::signal<void> signal_bundle_begin; - sigc::signal<void> signal_bundle_end; - sigc::signal<void, string> signal_error; - sigc::signal<void, string, string, string, string> signal_new_plugin; - sigc::signal<void, string, uint32_t> signal_new_patch; - sigc::signal<void, string, string> signal_new_node; - sigc::signal<void, string, uint32_t, string, bool> signal_new_port; - sigc::signal<void, string> signal_patch_cleared; - sigc::signal<void, string, string> signal_object_renamed; - sigc::signal<void, string> signal_object_destroyed; - sigc::signal<void, string, string> signal_connection; - sigc::signal<void, string, string> signal_disconnection; - sigc::signal<void, string, string, Raul::Atom> signal_variable_change; - sigc::signal<void, string, string, Raul::Atom> signal_property_change; - sigc::signal<void, string, Raul::Atom> signal_port_value; - sigc::signal<void, string, uint32_t, Raul::Atom> signal_voice_value; - sigc::signal<void, string> signal_port_activity; - sigc::signal<void, string, uint32_t, uint32_t, string> signal_program_add; - sigc::signal<void, string, uint32_t, uint32_t> signal_program_remove; - - /** Fire pending signals. Only does anything on derived classes (that may queue) */ - virtual bool emit_signals() { return false; } - -protected: - - bool _enabled; - - // ClientInterface hooks that fire the above signals - - void enable() { _enabled = true; } - void disable() { _enabled = false ; } - - void bundle_begin() - { if (_enabled) signal_bundle_begin.emit(); } - - void bundle_end() - { if (_enabled) signal_bundle_end.emit(); } - - void transfer_begin() {} - void transfer_end() {} - - void response_ok(int32_t id) - { if (_enabled) signal_response_ok.emit(id); } - - void response_error(int32_t id, const string& msg) - { if (_enabled) signal_response_error.emit(id, msg); } - - void error(const string& msg) - { if (_enabled) signal_error.emit(msg); } - - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) - { if (_enabled) signal_new_plugin.emit(uri, type_uri, symbol, name); } - - void new_patch(const string& path, uint32_t poly) - { if (_enabled) signal_new_patch.emit(path, poly); } - - void new_node(const string& path, const string& plugin_uri) - { if (_enabled) signal_new_node.emit(path, plugin_uri); } - - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output) - { if (_enabled) signal_new_port.emit(path, index, data_type, is_output); } - - void connect(const string& src_port_path, const string& dst_port_path) - { if (_enabled) signal_connection.emit(src_port_path, dst_port_path); } - - void destroy(const string& path) - { if (_enabled) signal_object_destroyed.emit(path); } - - void patch_cleared(const string& path) - { if (_enabled) signal_patch_cleared.emit(path); } - - void object_renamed(const string& old_path, const string& new_path) - { if (_enabled) signal_object_renamed.emit(old_path, new_path); } - - void disconnect(const string& src_port_path, const string& dst_port_path) - { if (_enabled) signal_disconnection.emit(src_port_path, dst_port_path); } - - void set_variable(const string& path, const string& key, const Raul::Atom& value) - { if (_enabled) signal_variable_change.emit(path, key, value); } - - void set_property(const string& path, const string& key, const Raul::Atom& value) - { if (_enabled) signal_property_change.emit(path, key, value); } - - void set_port_value(const string& port_path, const Raul::Atom& value) - { if (_enabled) signal_port_value.emit(port_path, value); } - - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) - { if (_enabled) signal_voice_value.emit(port_path, voice, value); } - - void port_activity(const string& port_path) - { if (_enabled) signal_port_activity.emit(port_path); } - - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) - { if (_enabled) signal_program_add.emit(path, bank, program, name); } - - void program_remove(const string& path, uint32_t bank, uint32_t program) - { if (_enabled) signal_program_remove.emit(path, bank, program); } -}; - - -} // namespace Client -} // namespace Ingen - -#endif diff --git a/src/libs/client/ThreadedSigClientInterface.cpp b/src/libs/client/ThreadedSigClientInterface.cpp deleted file mode 100644 index ef95133b..00000000 --- a/src/libs/client/ThreadedSigClientInterface.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "ThreadedSigClientInterface.hpp" -#include <iostream> - -using namespace std; - -namespace Ingen { -namespace Client { - - -/** Push an event (from the engine, ie 'new patch') on to the queue. - */ -void -ThreadedSigClientInterface::push_sig(Closure ev) -{ - _attached = true; - if (!_enabled) - return; - - bool success = false; - while (!success) { - success = _sigs.push(ev); - if (!success) { - cerr << "WARNING: Client event queue full. Waiting..." << endl; - _mutex.lock(); - _cond.wait(_mutex); - _mutex.unlock(); - cerr << "Queue drained, continuing" << endl; - } - } -} - - -/** Process all queued events that came from the OSC thread. - * - * This function should be called from the Gtk thread to emit signals and cause - * the connected methods to execute. - */ -bool -ThreadedSigClientInterface::emit_signals() -{ - // Process a limited number of events, to prevent locking the GTK - // thread indefinitely while processing continually arriving events - - size_t num_processed = 0; - while (!_sigs.empty() && num_processed++ < (_sigs.capacity() * 3 / 4)) { - Closure& ev = _sigs.front(); - ev(); - ev.disconnect(); - _sigs.pop(); - } - - _mutex.lock(); - _cond.broadcast(); - _mutex.unlock(); - - return true; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/ThreadedSigClientInterface.hpp b/src/libs/client/ThreadedSigClientInterface.hpp deleted file mode 100644 index 3014c139..00000000 --- a/src/libs/client/ThreadedSigClientInterface.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 THREADEDSIGCLIENTINTERFACE_H -#define THREADEDSIGCLIENTINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <sigc++/sigc++.h> -#include <glibmm/thread.h> -#include "interface/ClientInterface.hpp" -#include "SigClientInterface.hpp" -#include <raul/Atom.hpp> -#include <raul/SRSWQueue.hpp> - -using std::string; - -/** Returns nothing and takes no parameters (because they have all been bound) */ -typedef sigc::slot<void> Closure; - -namespace Ingen { -namespace Shared { class EngineInterface; } -namespace Client { - - -/** A LibSigC++ signal emitting interface for clients to use. - * - * This emits signals (possibly) in a different thread than the ClientInterface - * functions are called. It must be explicitly driven with the emit_signals() - * function, which fires all enqueued signals up until the present. You can - * use this in a GTK idle callback for receiving thread safe engine signals. - */ -class ThreadedSigClientInterface : public SigClientInterface -{ -public: - ThreadedSigClientInterface(uint32_t queue_size) - : _sigs(queue_size) - , response_ok_slot(signal_response_ok.make_slot()) - , response_error_slot(signal_response_error.make_slot()) - , error_slot(signal_error.make_slot()) - , new_plugin_slot(signal_new_plugin.make_slot()) - , new_patch_slot(signal_new_patch.make_slot()) - , new_node_slot(signal_new_node.make_slot()) - , new_port_slot(signal_new_port.make_slot()) - , connection_slot(signal_connection.make_slot()) - , patch_cleared_slot(signal_patch_cleared.make_slot()) - , object_destroyed_slot(signal_object_destroyed.make_slot()) - , object_renamed_slot(signal_object_renamed.make_slot()) - , disconnection_slot(signal_disconnection.make_slot()) - , variable_change_slot(signal_variable_change.make_slot()) - , property_change_slot(signal_property_change.make_slot()) - , port_value_slot(signal_port_value.make_slot()) - , port_activity_slot(signal_port_activity.make_slot()) - , program_add_slot(signal_program_add.make_slot()) - , program_remove_slot(signal_program_remove.make_slot()) - { - } - - virtual std::string uri() const { return "(internal)"; } - - virtual void subscribe(Shared::EngineInterface* engine) { throw; } - - bool enabled() const { return _attached; } - - void bundle_begin() - { push_sig(bundle_begin_slot); } - - void bundle_end() - { push_sig(bundle_end_slot); } - - void transfer_begin() {} - void transfer_end() {} - - void response_ok(int32_t id) - { push_sig(sigc::bind(response_ok_slot, id)); } - - void response_error(int32_t id, const string& msg) - { push_sig(sigc::bind(response_error_slot, id, msg)); } - - void error(const string& msg) - { push_sig(sigc::bind(error_slot, msg)); } - - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) - { push_sig(sigc::bind(new_plugin_slot, uri, type_uri, symbol, name)); } - - void new_patch(const string& path, uint32_t poly) - { push_sig(sigc::bind(new_patch_slot, path, poly)); } - - void new_node(const string& path, const string& plugin_uri) - { push_sig(sigc::bind(new_node_slot, path, plugin_uri)); } - - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output) - { push_sig(sigc::bind(new_port_slot, path, index, data_type, is_output)); } - - void connect(const string& src_port_path, const string& dst_port_path) - { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); } - - void destroy(const string& path) - { push_sig(sigc::bind(object_destroyed_slot, path)); } - - void patch_cleared(const string& path) - { push_sig(sigc::bind(patch_cleared_slot, path)); } - - void object_renamed(const string& old_path, const string& new_path) - { push_sig(sigc::bind(object_renamed_slot, old_path, new_path)); } - - void disconnect(const string& src_port_path, const string& dst_port_path) - { push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); } - - void set_variable(const string& path, const string& key, const Raul::Atom& value) - { push_sig(sigc::bind(variable_change_slot, path, key, value)); } - - void set_property(const string& path, const string& key, const Raul::Atom& value) - { push_sig(sigc::bind(property_change_slot, path, key, value)); } - - void set_port_value(const string& port_path, const Raul::Atom& value) - { push_sig(sigc::bind(port_value_slot, port_path, value)); } - - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) - { push_sig(sigc::bind(voice_value_slot, port_path, voice, value)); } - - void port_activity(const string& port_path) - { push_sig(sigc::bind(port_activity_slot, port_path)); } - - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) - { push_sig(sigc::bind(program_add_slot, path, bank, program, name)); } - - void program_remove(const string& path, uint32_t bank, uint32_t program) - { push_sig(sigc::bind(program_remove_slot, path, bank, program)); } - - /** Process all queued events - Called from GTK thread to emit signals. */ - bool emit_signals(); - -private: - void push_sig(Closure ev); - - Glib::Mutex _mutex; - Glib::Cond _cond; - - Raul::SRSWQueue<Closure> _sigs; - bool _attached; - - sigc::slot<void> bundle_begin_slot; - sigc::slot<void> bundle_end_slot; - sigc::slot<void, int32_t> response_ok_slot; - sigc::slot<void, int32_t, string> response_error_slot; - sigc::slot<void, string> error_slot; - sigc::slot<void, string, string, string, string> new_plugin_slot; - sigc::slot<void, string, uint32_t> new_patch_slot; - sigc::slot<void, string, string> new_node_slot; - sigc::slot<void, string, uint32_t, string, bool> new_port_slot; - sigc::slot<void, string, string> connection_slot; - sigc::slot<void, string> patch_cleared_slot; - sigc::slot<void, string> object_destroyed_slot; - sigc::slot<void, string, string> object_renamed_slot; - sigc::slot<void, string, string> disconnection_slot; - sigc::slot<void, string, string, Raul::Atom> variable_change_slot; - sigc::slot<void, string, string, Raul::Atom> property_change_slot; - sigc::slot<void, string, Raul::Atom> port_value_slot; - sigc::slot<void, string, uint32_t, Raul::Atom> voice_value_slot; - sigc::slot<void, string> port_activity_slot; - sigc::slot<void, string, uint32_t, uint32_t, string> program_add_slot; - sigc::slot<void, string, uint32_t, uint32_t> program_remove_slot; -}; - - -} // namespace Client -} // namespace Ingen - -#endif diff --git a/src/libs/client/client.cpp b/src/libs/client/client.cpp deleted file mode 100644 index f3d62471..00000000 --- a/src/libs/client/client.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONFIG_H_PATH - -#include <iostream> -#include "client.hpp" -#include "OSCEngineSender.hpp" -#ifdef WITH_SOUP -#include "HTTPEngineSender.hpp" -#endif - -using namespace std; - -namespace Ingen { -namespace Client { - - -SharedPtr<Ingen::Shared::EngineInterface> -new_remote_interface(const std::string& url) -{ - const string scheme = url.substr(0, url.find(":")); - cout << "SCHEME: " << scheme << endl; - if (scheme == "osc.udp" || scheme == "osc.tcp") { - OSCEngineSender* oes = new OSCEngineSender(url); - oes->attach(rand(), true); - return SharedPtr<Shared::EngineInterface>(oes); -#ifdef WITH_SOUP - } else if (scheme == "http") { - HTTPEngineSender* hes = new HTTPEngineSender(url); - hes->attach(rand(), true); - return SharedPtr<Shared::EngineInterface>(hes); -#endif - } else { - cerr << "WARNING: Unknown URI scheme '" << scheme << "'" << endl; - return SharedPtr<Shared::EngineInterface>(); - } -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/client.hpp b/src/libs/client/client.hpp deleted file mode 100644 index 82166da5..00000000 --- a/src/libs/client/client.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 INGEN_CLIENT_H -#define INGEN_CLIENT_H - -#include <raul/SharedPtr.hpp> - -namespace Ingen { - -class Engine; - -namespace Shared { class EngineInterface; } - -namespace Client { - -extern "C" { - - SharedPtr<Shared::EngineInterface> new_remote_interface(const std::string& url); - SharedPtr<Shared::EngineInterface> new_queued_interface(SharedPtr<Ingen::Engine> engine); - -} - - -} // namespace Client -} // namespace Ingen - -#endif // INGEN_CLIENT_H - diff --git a/src/libs/client/wscript b/src/libs/client/wscript deleted file mode 100644 index 6b4408a7..00000000 --- a/src/libs/client/wscript +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - ClientStore.cpp - NodeModel.cpp - ObjectModel.cpp - PatchModel.cpp - PluginModel.cpp - PluginUI.cpp - PortModel.cpp - ThreadedSigClientInterface.cpp - client.cpp - ''' - - if bld.env()['HAVE_SOUP']: - obj.source += ''' - HTTPClientReceiver.cpp - HTTPEngineSender.cpp - ''' - - if bld.env()['HAVE_XML2']: - obj.source += ' DeprecatedLoader.cpp ' - - if bld.env()['HAVE_LIBLO']: - obj.source += ' OSCClientReceiver.cpp OSCEngineSender.cpp ' - - obj.includes = ['..', '../../common', '../..'] - obj.name = 'libingen_client' - obj.target = 'ingen_client' - obj.uselib = 'GLIBMM SLV2 RAUL REDLANDMM SOUP XML2 SIGCPP' - obj.vnum = '0.0.0' - |