diff options
Diffstat (limited to 'src/client/NodeModel.cpp')
-rw-r--r-- | src/client/NodeModel.cpp | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp new file mode 100644 index 00000000..ac0c8e68 --- /dev/null +++ b/src/client/NodeModel.cpp @@ -0,0 +1,224 @@ +/* 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 |