summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-10-11 17:24:49 +0000
committerDavid Robillard <d@drobilla.net>2007-10-11 17:24:49 +0000
commit5791d19a0f56c65ef7b89da80f4bcc3e1cee0c93 (patch)
treede0a795658df184d29e4ed795c6b6b15c6e0454d
parent058174f81f325521957cc6927667dfcf0d7346b4 (diff)
downloadingen-5791d19a0f56c65ef7b89da80f4bcc3e1cee0c93.tar.gz
ingen-5791d19a0f56c65ef7b89da80f4bcc3e1cee0c93.tar.bz2
ingen-5791d19a0f56c65ef7b89da80f4bcc3e1cee0c93.zip
Fix awful plugin loading situation.
Don't double-lookup plugins on discovery/load. O(log(n)) plugin searching instead of 2*O(n). Don't keep discovered LADSPA plugins loaded (until a node is instantiated). git-svn-id: http://svn.drobilla.net/lad/ingen@876 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp10
-rw-r--r--src/libs/engine/ClientBroadcaster.hpp5
-rw-r--r--src/libs/engine/LADSPANode.cpp2
-rw-r--r--src/libs/engine/LADSPANode.hpp2
-rw-r--r--src/libs/engine/LV2Node.cpp12
-rw-r--r--src/libs/engine/LV2Node.hpp12
-rw-r--r--src/libs/engine/MidiNoteNode.cpp1
-rw-r--r--src/libs/engine/NodeBase.cpp2
-rw-r--r--src/libs/engine/NodeBase.hpp20
-rw-r--r--src/libs/engine/NodeFactory.cpp336
-rw-r--r--src/libs/engine/NodeFactory.hpp28
-rw-r--r--src/libs/engine/NodeImpl.hpp2
-rw-r--r--src/libs/engine/ObjectSender.cpp2
-rw-r--r--src/libs/engine/PluginImpl.cpp27
-rw-r--r--src/libs/engine/PluginImpl.hpp3
-rw-r--r--src/libs/engine/events/CreateNodeEvent.cpp6
-rw-r--r--src/libs/engine/events/RequestPluginsEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestPluginsEvent.hpp11
18 files changed, 209 insertions, 274 deletions
diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp
index df8e6c6f..67cf8dd9 100644
--- a/src/libs/engine/ClientBroadcaster.cpp
+++ b/src/libs/engine/ClientBroadcaster.cpp
@@ -100,12 +100,12 @@ ClientBroadcaster::send_error(const string& msg)
}
void
-ClientBroadcaster::send_plugins_to(ClientInterface* client, const list<PluginImpl*>& plugin_list)
+ClientBroadcaster::send_plugins_to(ClientInterface* client, const NodeFactory::Plugins& plugins)
{
client->transfer_begin();
- for (list<PluginImpl*>::const_iterator i = plugin_list.begin(); i != plugin_list.end(); ++i) {
- const PluginImpl* const plugin = *i;
+ for (NodeFactory::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) {
+ const PluginImpl* const plugin = i->second;
client->new_plugin(plugin->uri(), plugin->type_uri(), plugin->name());
}
@@ -114,10 +114,10 @@ ClientBroadcaster::send_plugins_to(ClientInterface* client, const list<PluginImp
void
-ClientBroadcaster::send_plugins(const list<PluginImpl*>& plugin_list)
+ClientBroadcaster::send_plugins(const NodeFactory::Plugins& plugins)
{
for (Clients::const_iterator c = _clients.begin(); c != _clients.end(); ++c)
- send_plugins_to((*c).second, plugin_list);
+ send_plugins_to((*c).second, plugins);
}
diff --git a/src/libs/engine/ClientBroadcaster.hpp b/src/libs/engine/ClientBroadcaster.hpp
index ecd19d34..73353588 100644
--- a/src/libs/engine/ClientBroadcaster.hpp
+++ b/src/libs/engine/ClientBroadcaster.hpp
@@ -26,6 +26,7 @@
#include <raul/SharedPtr.hpp>
#include "interface/ClientInterface.hpp"
#include "types.hpp"
+#include "NodeFactory.hpp"
using std::string;
@@ -62,7 +63,7 @@ public:
// Error that isn't the direct result of a request
void send_error(const string& msg);
- void send_plugins(const std::list<PluginImpl*>& plugin_list);
+ void send_plugins(const NodeFactory::Plugins& plugin_list);
void send_patch(const PatchImpl* p, bool recursive);
void send_node(const NodeImpl* node, bool recursive);
void send_port(const PortImpl* port);
@@ -81,7 +82,7 @@ public:
void send_program_add(const string& node_path, int bank, int program, const string& name);
void send_program_remove(const string& node_path, int bank, int program);
- void send_plugins_to(ClientInterface*, const std::list<PluginImpl*>& plugin_list);
+ void send_plugins_to(ClientInterface*, const NodeFactory::Plugins& plugin_list);
private:
typedef std::map<string, ClientInterface*> Clients;
diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp
index 5ae567db..ee5da968 100644
--- a/src/libs/engine/LADSPANode.cpp
+++ b/src/libs/engine/LADSPANode.cpp
@@ -36,7 +36,7 @@ namespace Ingen {
* Object is not usable until instantiate() is called with success.
* (It _will_ crash!)
*/
-LADSPANode::LADSPANode(const PluginImpl* plugin, const string& path, bool polyphonic, PatchImpl* parent, const LADSPA_Descriptor* descriptor, SampleRate srate, size_t buffer_size)
+LADSPANode::LADSPANode(PluginImpl* plugin, const string& path, bool polyphonic, PatchImpl* parent, const LADSPA_Descriptor* descriptor, SampleRate srate, size_t buffer_size)
: NodeBase(plugin, path, polyphonic, parent, srate, buffer_size),
_descriptor(descriptor),
_instances(NULL)
diff --git a/src/libs/engine/LADSPANode.hpp b/src/libs/engine/LADSPANode.hpp
index 8675a6fd..6d6cd442 100644
--- a/src/libs/engine/LADSPANode.hpp
+++ b/src/libs/engine/LADSPANode.hpp
@@ -34,7 +34,7 @@ namespace Ingen {
class LADSPANode : public NodeBase
{
public:
- LADSPANode(const PluginImpl* plugin,
+ LADSPANode(PluginImpl* plugin,
const string& name,
bool polyphonic,
PatchImpl* parent,
diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp
index e3b6c06b..bfcc619a 100644
--- a/src/libs/engine/LV2Node.cpp
+++ b/src/libs/engine/LV2Node.cpp
@@ -40,12 +40,12 @@ namespace Ingen {
* Object is not usable until instantiate() is called with success.
* (It _will_ crash!)
*/
-LV2Node::LV2Node(const PluginImpl* plugin,
- const string& name,
- bool polyphonic,
- PatchImpl* parent,
- SampleRate srate,
- size_t buffer_size)
+LV2Node::LV2Node(PluginImpl* plugin,
+ const string& name,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate,
+ size_t buffer_size)
: NodeBase(plugin, name, polyphonic, parent, srate, buffer_size)
, _lv2_plugin(plugin->slv2_plugin())
, _instances(NULL)
diff --git a/src/libs/engine/LV2Node.hpp b/src/libs/engine/LV2Node.hpp
index 7fd9bf6d..dbd79671 100644
--- a/src/libs/engine/LV2Node.hpp
+++ b/src/libs/engine/LV2Node.hpp
@@ -34,12 +34,12 @@ namespace Ingen {
class LV2Node : public NodeBase
{
public:
- LV2Node(const PluginImpl* plugin,
- const string& name,
- bool polyphonic,
- PatchImpl* parent,
- SampleRate srate,
- size_t buffer_size);
+ LV2Node(PluginImpl* plugin,
+ const string& name,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate,
+ size_t buffer_size);
virtual ~LV2Node();
diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp
index 7604bc61..7b3c1c9e 100644
--- a/src/libs/engine/MidiNoteNode.cpp
+++ b/src/libs/engine/MidiNoteNode.cpp
@@ -41,7 +41,6 @@ MidiNoteNode::MidiNoteNode(const string& path, bool polyphonic, PatchImpl* paren
: NodeBase(new PluginImpl(Plugin::Internal, "ingen:note_node"), path, polyphonic, parent, srate, buffer_size),
_voices(new Raul::Array<Voice>(_polyphony)),
_prepared_voices(NULL),
-
_sustain(false)
{
_ports = new Raul::Array<PortImpl*>(5);
diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp
index ca5d1fc0..78825e7a 100644
--- a/src/libs/engine/NodeBase.cpp
+++ b/src/libs/engine/NodeBase.cpp
@@ -33,7 +33,7 @@ using namespace std;
namespace Ingen {
-NodeBase::NodeBase(const PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size)
+NodeBase::NodeBase(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size)
: NodeImpl(parent, name, polyphonic),
_plugin(plugin),
_polyphony((polyphonic && parent) ? parent->internal_polyphony() : 1),
diff --git a/src/libs/engine/NodeBase.hpp b/src/libs/engine/NodeBase.hpp
index 5838614d..2671a5a0 100644
--- a/src/libs/engine/NodeBase.hpp
+++ b/src/libs/engine/NodeBase.hpp
@@ -48,12 +48,12 @@ namespace Shared {
class NodeBase : public NodeImpl
{
public:
- NodeBase(const PluginImpl* plugin,
- const string& name,
- bool poly,
- PatchImpl* parent,
- SampleRate rate,
- size_t buffer_size);
+ NodeBase(PluginImpl* plugin,
+ const string& name,
+ bool poly,
+ PatchImpl* parent,
+ SampleRate rate,
+ size_t buffer_size);
virtual ~NodeBase();
@@ -98,9 +98,9 @@ public:
Raul::List<NodeImpl*>* dependants() { return _dependants; }
void dependants(Raul::List<NodeImpl*>* l) { _dependants = l; }
- virtual const Plugin* plugin() const;
- virtual const PluginImpl* plugin_impl() const { return _plugin; }
- virtual void plugin(const PluginImpl* pi) { _plugin = pi; }
+ virtual const Plugin* plugin() const;
+ virtual PluginImpl* plugin_impl() const { return _plugin; }
+ virtual void plugin(PluginImpl* pi) { _plugin = pi; }
/** A node's parent is always a patch, so static cast should be safe */
inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; }
@@ -108,7 +108,7 @@ public:
protected:
virtual void signal_input_ready();
- const PluginImpl* _plugin;
+ PluginImpl* _plugin;
uint32_t _polyphony;
SampleRate _srate;
diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp
index c2b9536a..24d32929 100644
--- a/src/libs/engine/NodeFactory.cpp
+++ b/src/libs/engine/NodeFactory.cpp
@@ -53,86 +53,42 @@ NodeFactory::NodeFactory(Ingen::Shared::World* world)
: _world(world)
, _has_loaded(false)
{
- // Add builtin plugin types to _internal_plugins list
- // FIXME: ewwww, definitely a better way to do this!
-
- PatchImpl* parent = new PatchImpl(*world->local_engine, "dummy", 1, NULL, 1, 1, 1);
-
- NodeImpl* n = NULL;
- n = new MidiNoteNode("foo", 1, parent, 1, 1);
- _internal_plugins.push_back(new PluginImpl(n->plugin_impl()));
- delete n;
- n = new MidiTriggerNode("foo", 1, parent, 1, 1);
- _internal_plugins.push_back(new PluginImpl(n->plugin_impl()));
- delete n;
- n = new MidiControlNode("foo", 1, parent, 1, 1);
- _internal_plugins.push_back(new PluginImpl(n->plugin_impl()));
- delete n;
- n = new TransportNode("foo", 1, parent, 1, 1);
- _internal_plugins.push_back(new PluginImpl(n->plugin_impl()));
- delete n;
-
- delete parent;
}
NodeFactory::~NodeFactory()
{
- for (list<PluginImpl*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
- delete (*i);
- _plugins.clear();
-
- for (Libraries::iterator i = _libraries.begin(); i != _libraries.end(); ++i) {
- delete i->second;
- }
- _libraries.clear();
-}
-
-
-Glib::Module*
-NodeFactory::library(const string& path)
-{
- Glib::Module* plugin_library = NULL;
- Libraries::iterator library_i = _libraries.find(path);
- if (library_i != _libraries.end()) {
- plugin_library = library_i->second;
- assert(plugin_library);
- } else {
- plugin_library = new Glib::Module(path, Glib::MODULE_BIND_LOCAL);
- if (plugin_library && *plugin_library) {
- _libraries.insert(make_pair(path, plugin_library));
- return plugin_library;
- }
- }
+ for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
+ if (i->second->type() != Plugin::Internal)
+ delete i->second;
- return NULL;
+ _plugins.clear();
}
-const PluginImpl*
+PluginImpl*
NodeFactory::plugin(const string& uri)
{
- for (list<PluginImpl*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
- if ((*i)->uri() == uri)
- return (*i);
-
- return NULL;
+ Plugins::const_iterator i = _plugins.find(uri);
+ return ((i != _plugins.end()) ? i->second : NULL);
}
/** DEPRECATED: Find a plugin by type, lib, label.
*
- * Do not use.
+ * Slow. Evil. Do not use.
*/
-const PluginImpl*
+PluginImpl*
NodeFactory::plugin(const string& type, const string& lib, const string& label)
{
if (type == "" || lib == "" || label == "")
return NULL;
- for (list<PluginImpl*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
- if ((*i)->type_string() == type && (*i)->lib_name() == lib && (*i)->plug_label() == label)
- return (*i);
+ for (Plugins::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i)
+ if (i->second->type_string() == type
+ && i->second->lib_name() == lib
+ && i->second->plug_label() == label)
+ return i->second;
cerr << "ERROR: Failed to find " << type << " plugin " << lib << " / " << label << endl;
@@ -149,12 +105,14 @@ NodeFactory::load_plugins()
// this (expensive!) stuff to happen. Not the best solution - would be nice
// if clients could refresh plugins list for whatever reason :/
if (!_has_loaded) {
- _plugins.clear();
- _plugins = _internal_plugins;
+ _plugins.clear(); // FIXME: assert empty?
+
+ load_internal_plugins();
#ifdef HAVE_SLV2
load_lv2_plugins();
#endif
+
#ifdef HAVE_LADSPA
load_ladspa_plugins();
#endif
@@ -171,65 +129,32 @@ NodeFactory::load_plugins()
* Calls the load_*_plugin functions to actually do things, just a wrapper.
*/
NodeImpl*
-NodeFactory::load_plugin(const PluginImpl* a_plugin,
- const string& name,
- bool polyphonic,
- PatchImpl* parent)
+NodeFactory::load_plugin(PluginImpl* plugin,
+ const string& name,
+ bool polyphonic,
+ PatchImpl* parent)
{
assert(parent != NULL);
- assert(a_plugin);
+ assert(plugin);
NodeImpl* r = NULL;
- PluginImpl* plugin = NULL;
const SampleRate srate = parent->sample_rate();
const size_t buffer_size = parent->buffer_size();
- // FIXME FIXME FIXME: double lookup
-
- // Attempt to find the plugin in loaded DB
- if (a_plugin->type() != Plugin::Internal) {
-
- // DEPRECATED: Search by lib name / plug label
- if (a_plugin->uri().length() == 0) {
- assert(a_plugin->lib_name().length() > 0 && a_plugin->plug_label().length() > 0);
- //cerr << "Searching for: " << a_plugin->lib_name() << " : " << a_plugin->plug_label() << endl;
- for (list<PluginImpl*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- //cerr << (*i)->lib_name() << " : " << (*i)->plug_label() << endl;
- if (a_plugin->lib_name() == (*i)->lib_name() && a_plugin->plug_label() == (*i)->plug_label()) {
- plugin = *i;
- break;
- }
- }
- } else {
- // Search by URI
- for (list<PluginImpl*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- if (a_plugin->uri() == (*i)->uri()) {
- plugin = *i;
- break;
- }
- }
- }
-
- if (plugin == NULL) {
- cerr << "DID NOT FIND PLUGIN " << name << endl;
- return NULL;
- }
- }
-
- switch (a_plugin->type()) {
+ switch (plugin->type()) {
#ifdef HAVE_SLV2
case Plugin::LV2:
- r = load_lv2_plugin(plugin->uri(), name, polyphonic, parent, srate, buffer_size);
+ r = load_lv2_plugin(plugin, name, polyphonic, parent, srate, buffer_size);
break;
#endif
#ifdef HAVE_LADSPA
case Plugin::LADSPA:
- r = load_ladspa_plugin(plugin->uri(), name, polyphonic, parent, srate, buffer_size);
+ r = load_ladspa_plugin(plugin, name, polyphonic, parent, srate, buffer_size);
break;
#endif
case Plugin::Internal:
- r = load_internal_plugin(a_plugin->uri(), name, polyphonic, parent, srate, buffer_size);
+ r = load_internal_plugin(plugin, name, polyphonic, parent, srate, buffer_size);
break;
default:
cerr << "[NodeFactory] WARNING: Unknown plugin type." << endl;
@@ -239,25 +164,48 @@ NodeFactory::load_plugin(const PluginImpl* a_plugin,
}
+void
+NodeFactory::load_internal_plugins()
+{
+ // This is a touch gross...
+
+ PatchImpl* parent = new PatchImpl(*_world->local_engine, "dummy", 1, NULL, 1, 1, 1);
+
+ NodeImpl* n = NULL;
+ n = new MidiNoteNode("foo", 1, parent, 1, 1);
+ _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl()));
+ delete n;
+ n = new MidiTriggerNode("foo", 1, parent, 1, 1);
+ _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl()));
+ delete n;
+ n = new MidiControlNode("foo", 1, parent, 1, 1);
+ _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl()));
+ delete n;
+ n = new TransportNode("foo", 1, parent, 1, 1);
+ _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl()));
+ delete n;
+
+ delete parent;
+}
+
+
/** Loads an internal plugin.
*/
NodeImpl*
-NodeFactory::load_internal_plugin(const string& uri,
+NodeFactory::load_internal_plugin(PluginImpl* plugin,
const string& name,
bool polyphonic,
PatchImpl* parent,
SampleRate srate,
size_t buffer_size)
{
+ assert(plugin);
+ assert(plugin->type() == Plugin::Internal);
assert(parent != NULL);
- assert(uri.length() > 6);
- assert(uri.substr(0, 6) == "ingen:");
+ assert(plugin->uri().length() > 6);
+ assert(plugin->uri().substr(0, 6) == "ingen:");
- for (list<PluginImpl*>::iterator i = _internal_plugins.begin(); i != _internal_plugins.end(); ++i)
- if ((*i)->uri() == uri)
- return (*i)->instantiate(name, polyphonic, parent, srate, buffer_size);
-
- return NULL;
+ return plugin->instantiate(name, polyphonic, parent, srate, buffer_size);
}
@@ -276,37 +224,24 @@ NodeFactory::load_lv2_plugins()
SLV2Plugin lv2_plug = slv2_plugins_get_at(plugins, i);
- const char* uri = (const char*)slv2_plugin_get_uri(lv2_plug);
- assert(uri);
- //cerr << "\t" << uri << endl;
-
- PluginImpl* plug = NULL;
-
- bool found = false;
- for (list<PluginImpl*>::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- if (!strcmp((*i)->uri().c_str(), uri)) {
- plug = (*i);
- found = true;
- break;
- }
- }
-
- if (!found)
- plug = new PluginImpl(Plugin::LV2, uri);
-
- plug->slv2_plugin(lv2_plug);
- plug->module(NULL); // FIXME?
- plug->lib_path(slv2_uri_to_path(slv2_plugin_get_library_uri(lv2_plug)));
- char* name = slv2_plugin_get_name(lv2_plug);
- if (!name) {
+#ifndef NDEBUG
+ const string uri((const char*)slv2_plugin_get_uri(lv2_plug));
+ assert(_plugins.find(uri) == _plugins.end());
+#endif
+
+ PluginImpl* const plugin = new PluginImpl(Plugin::LV2, uri);
+
+ plugin->slv2_plugin(lv2_plug);
+ plugin->lib_path(slv2_uri_to_path(slv2_plugin_get_library_uri(lv2_plug)));
+ char* const name = slv2_plugin_get_name(lv2_plug);
+ if (name) {
+ plugin->name(name);
+ free(name);
+ _plugins.insert(make_pair(uri, plugin));
+ } else {
cerr << "ERROR: LV2 Plugin " << uri << " has no name. Ignoring." << endl;
continue;
}
- plug->name(name);
- free(name);
-
- if (!found)
- _plugins.push_back(plug);
}
slv2_plugins_free(_world->slv2_world, plugins);
@@ -317,36 +252,31 @@ NodeFactory::load_lv2_plugins()
* Returns 'poly' independant plugins as a NodeImpl*
*/
NodeImpl*
-NodeFactory::load_lv2_plugin(const string& plug_uri,
+NodeFactory::load_lv2_plugin(PluginImpl* plugin,
const string& node_name,
bool polyphonic,
PatchImpl* parent,
SampleRate srate,
size_t buffer_size)
{
- // Find (internal) Plugin
- PluginImpl* plugin = NULL;
- list<PluginImpl*>::iterator i;
- for (i = _plugins.begin(); i != _plugins.end(); ++i) {
- plugin = (*i);
- if ((*i)->uri() == plug_uri) break;
- }
-
+ assert(plugin);
+ assert(plugin->type() == Plugin::LV2);
+
NodeImpl* n = NULL;
- if (plugin) {
- n = new LV2Node(plugin, node_name, polyphonic, parent, srate, buffer_size);
-
- Glib::Mutex::Lock lock(_world->rdf_world->mutex());
-
- const bool success = ((LV2Node*)n)->instantiate();
-
- if (!success) {
- delete n;
- n = NULL;
- }
+ plugin->load(); // FIXME: unload
+
+ n = new LV2Node(plugin, node_name, polyphonic, parent, srate, buffer_size);
+
+ Glib::Mutex::Lock lock(_world->rdf_world->mutex());
+
+ const bool success = ((LV2Node*)n)->instantiate();
+
+ if (!success) {
+ delete n;
+ n = NULL;
}
-
+
return n;
}
@@ -369,12 +299,9 @@ NodeFactory::load_ladspa_plugins()
ladspa_path = env_ladspa_path;
}
- string dir;
- string full_lib_name;
-
// Yep, this should use an sstream alright..
while (ladspa_path != "") {
- dir = ladspa_path.substr(0, ladspa_path.find(':'));
+ const string dir = ladspa_path.substr(0, ladspa_path.find(':'));
if (ladspa_path.find(':') != string::npos)
ladspa_path = ladspa_path.substr(ladspa_path.find(':')+1);
else
@@ -395,26 +322,25 @@ NodeFactory::load_ladspa_plugins()
if (!strcmp(pfile->d_name, ".") || !strcmp(pfile->d_name, ".."))
continue;
- full_lib_name = dir +"/"+ pfile->d_name;
+ const string lib_path = dir +"/"+ pfile->d_name;
// Ignore stupid libtool files. Kludge alert.
- if (full_lib_name.substr(full_lib_name.length()-3) == ".la") {
+ if (lib_path.substr(lib_path.length()-3) == ".la") {
//cerr << "WARNING: Skipping stupid libtool file " << pfile->d_name << endl;
continue;
}
- Glib::Module* plugin_library = library(full_lib_name);
- if (!plugin_library) {
- cerr << "WARNING: Failed to load library " << full_lib_name << endl;
+ Glib::Module* plugin_library = new Glib::Module(lib_path, Glib::MODULE_BIND_LOCAL);
+ if (!plugin_library || !(*plugin_library)) {
+ cerr << "WARNING: Failed to load LADSPA library " << lib_path << endl;
continue;
}
bool found = plugin_library->get_symbol("ladspa_descriptor", (void*&)df);
if (!found || !df) {
cerr << "WARNING: Non-LADSPA library found in LADSPA path: " <<
- full_lib_name << endl;
+ lib_path << endl;
// Not a LADSPA plugin library
- _libraries.erase(full_lib_name);
delete plugin_library;
continue;
}
@@ -422,32 +348,29 @@ NodeFactory::load_ladspa_plugins()
for (unsigned long i=0; (descriptor = (LADSPA_Descriptor*)df(i)) != NULL; ++i) {
char id_str[11];
snprintf(id_str, 11, "%lu", descriptor->UniqueID);
- string uri = string("ladspa:").append(id_str);
- PluginImpl* plugin = new PluginImpl(Plugin::LADSPA, uri);
+ const string uri = string("ladspa:").append(id_str);
- assert(plugin_library != NULL);
- plugin->module(plugin_library);
- plugin->lib_path(dir + "/" + pfile->d_name);
- plugin->plug_label(descriptor->Label);
- plugin->name(descriptor->Name);
- plugin->type(Plugin::LADSPA);
- plugin->id(descriptor->UniqueID);
+ const Plugins::const_iterator i = _plugins.find(uri);
- bool found = false;
- for (list<PluginImpl*>::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- if ((*i)->uri() == plugin->uri()) {
- cerr << "Warning: Duplicate LADSPA plugin " << plugin->uri()
- << " found.\n Choosing " << (*i)->lib_path()
- << " over " << plugin->lib_path() << endl;
- found = true;
- break;
- }
+ if (i == _plugins.end()) {
+ PluginImpl* plugin = new PluginImpl(Plugin::LADSPA, uri);
+
+ assert(plugin_library != NULL);
+ plugin->module(NULL);
+ plugin->lib_path(lib_path);
+ plugin->plug_label(descriptor->Label);
+ plugin->name(descriptor->Name);
+ plugin->type(Plugin::LADSPA);
+ plugin->id(descriptor->UniqueID);
+
+ _plugins.insert(make_pair(uri, plugin));
+ } else {
+ cerr << "Warning: Duplicate LADSPA plugin " << uri << " found." << endl;
+ cerr << "\tUsing " << i->second->lib_path() << " over " << lib_path << endl;
}
- if (!found)
- _plugins.push_back(plugin);
- else
- delete plugin;
}
+
+ delete plugin_library;
}
closedir(pdir);
}
@@ -458,37 +381,28 @@ NodeFactory::load_ladspa_plugins()
* Returns 'poly' independant plugins as a NodeImpl*
*/
NodeImpl*
-NodeFactory::load_ladspa_plugin(const string& uri,
+NodeFactory::load_ladspa_plugin(PluginImpl* plugin,
const string& name,
bool polyphonic,
PatchImpl* parent,
SampleRate srate,
size_t buffer_size)
{
- assert(uri != "");
+ assert(plugin);
+ assert(plugin->type() == Plugin::LADSPA);
+ assert(plugin->id() != 0);
assert(name != "");
LADSPA_Descriptor_Function df = NULL;
- PluginImpl* plugin = NULL;
NodeImpl* n = NULL;
-
- // Attempt to find the lib
- list<PluginImpl*>::iterator i;
- for (i = _plugins.begin(); i != _plugins.end(); ++i) {
- plugin = (*i);
- if (plugin->uri() == uri) break;
- }
- assert(plugin->id() != 0);
-
- if (i == _plugins.end()) {
- cerr << "Did not find LADSPA plugin " << uri << " in database." << endl;
+ plugin->load(); // FIXME: unload
+ assert(plugin->module());
+ assert(*plugin->module());
+
+ if (!plugin->module()->get_symbol("ladspa_descriptor", (void*&)df)) {
+ cerr << "Looks like this isn't a LADSPA plugin." << endl;
return NULL;
- } else {
- if (!plugin->module()->get_symbol("ladspa_descriptor", (void*&)df)) {
- cerr << "Looks like this isn't a LADSPA plugin." << endl;
- return NULL;
- }
}
// Attempt to find the plugin in lib
diff --git a/src/libs/engine/NodeFactory.hpp b/src/libs/engine/NodeFactory.hpp
index a956a938..6eceb0ee 100644
--- a/src/libs/engine/NodeFactory.hpp
+++ b/src/libs/engine/NodeFactory.hpp
@@ -32,7 +32,7 @@
#endif
#include "types.hpp"
-using std::string; using std::list;
+using std::string;
namespace Ingen {
@@ -58,33 +58,31 @@ public:
~NodeFactory();
void load_plugins();
- NodeImpl* load_plugin(const PluginImpl* info, const string& name, bool polyphonic, PatchImpl* parent);
+ NodeImpl* load_plugin(PluginImpl* info, const string& name, bool polyphonic, PatchImpl* parent);
- const list<PluginImpl*>& plugins() { return _plugins; }
+ typedef std::map<std::string,PluginImpl*> Plugins;
+ const Plugins& plugins() const { return _plugins; }
- const PluginImpl* plugin(const string& uri);
- const PluginImpl* plugin(const string& type, const string& lib, const string& label); // DEPRECATED
+ PluginImpl* plugin(const string& uri);
+
+ /** DEPRECATED */
+ PluginImpl* plugin(const string& type, const string& lib, const string& label);
private:
#ifdef HAVE_LADSPA
void load_ladspa_plugins();
- NodeImpl* load_ladspa_plugin(const string& plugin_uri, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
+ NodeImpl* load_ladspa_plugin(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
#endif
#ifdef HAVE_SLV2
void load_lv2_plugins();
- NodeImpl* load_lv2_plugin(const string& plugin_uri, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
+ NodeImpl* load_lv2_plugin(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
#endif
- NodeImpl* load_internal_plugin(const string& plug_label, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
-
- Glib::Module* library(const string& path);
+ void load_internal_plugins();
+ NodeImpl* load_internal_plugin(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size);
- typedef std::map<std::string,Glib::Module*> Libraries;
-
- Libraries _libraries;
- list<PluginImpl*> _internal_plugins;
- list<PluginImpl*> _plugins; // FIXME: make a map
+ Plugins _plugins;
Ingen::Shared::World* _world;
bool _has_loaded;
diff --git a/src/libs/engine/NodeImpl.hpp b/src/libs/engine/NodeImpl.hpp
index 39692cc9..3c6c95f3 100644
--- a/src/libs/engine/NodeImpl.hpp
+++ b/src/libs/engine/NodeImpl.hpp
@@ -149,7 +149,7 @@ public:
/** Information about the Plugin this Node is an instance of.
* Not the best name - not all nodes come from plugins (ie Patch)
*/
- virtual const PluginImpl* plugin_impl() const = 0;
+ virtual PluginImpl* plugin_impl() const = 0;
/** Information about the Plugin this Node is an instance of.
* Not the best name - not all nodes come from plugins (ie Patch)
diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp
index 55dafaf4..4b2497e6 100644
--- a/src/libs/engine/ObjectSender.cpp
+++ b/src/libs/engine/ObjectSender.cpp
@@ -74,7 +74,7 @@ ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool r
void
ObjectSender::send_node(ClientInterface* client, const NodeImpl* node, bool recursive)
{
- const PluginImpl* const plugin = node->plugin_impl();
+ PluginImpl* const plugin = node->plugin_impl();
assert(node->path().length() > 0);
diff --git a/src/libs/engine/PluginImpl.cpp b/src/libs/engine/PluginImpl.cpp
index e8b090ef..dfff1031 100644
--- a/src/libs/engine/PluginImpl.cpp
+++ b/src/libs/engine/PluginImpl.cpp
@@ -15,14 +15,41 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <iostream>
#include "PluginImpl.hpp"
#include "MidiNoteNode.hpp"
#include "MidiTriggerNode.hpp"
#include "MidiControlNode.hpp"
#include "TransportNode.hpp"
+using namespace std;
+
namespace Ingen {
+
+void
+PluginImpl::load()
+{
+ if (!_module) {
+ cerr << "Loading " << _lib_path << endl;
+ _module = new Glib::Module(_lib_path, Glib::MODULE_BIND_LOCAL);
+ if (!(*_module))
+ delete _module;
+ }
+}
+
+
+void
+PluginImpl::unload()
+{
+ if (_module) {
+ cerr << "Unloading " << _lib_path << endl;
+ delete _module;
+ _module = NULL;
+ }
+}
+
+
NodeImpl*
PluginImpl::instantiate(const string& name, bool polyphonic, Ingen::PatchImpl* parent, SampleRate srate, size_t buffer_size)
{
diff --git a/src/libs/engine/PluginImpl.hpp b/src/libs/engine/PluginImpl.hpp
index 86d3cc5b..83814dc8 100644
--- a/src/libs/engine/PluginImpl.hpp
+++ b/src/libs/engine/PluginImpl.hpp
@@ -117,6 +117,9 @@ public:
void slv2_plugin(SLV2Plugin p) { _slv2_plugin = p; }
#endif
+ void load();
+ void unload();
+
NodeImpl* instantiate(const string& name, bool polyphonic, Ingen::PatchImpl* parent, SampleRate srate, size_t buffer_size);
private:
diff --git a/src/libs/engine/events/CreateNodeEvent.cpp b/src/libs/engine/events/CreateNodeEvent.cpp
index a0a8d08f..dea1024b 100644
--- a/src/libs/engine/events/CreateNodeEvent.cpp
+++ b/src/libs/engine/events/CreateNodeEvent.cpp
@@ -78,9 +78,9 @@ CreateNodeEvent::pre_process()
_patch = _engine.object_store()->find_patch(_path.parent());
- const PluginImpl* plugin = (_plugin_uri != "")
- ? _engine.node_factory()->plugin(_plugin_uri)
- : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label);
+ PluginImpl* const plugin = (_plugin_uri != "")
+ ? _engine.node_factory()->plugin(_plugin_uri)
+ : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label);
if (_patch && plugin) {
diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp
index 005048ea..8d7fc1ba 100644
--- a/src/libs/engine/events/RequestPluginsEvent.cpp
+++ b/src/libs/engine/events/RequestPluginsEvent.cpp
@@ -34,7 +34,7 @@ void
RequestPluginsEvent::pre_process()
{
// Take a copy to send in the post processing thread (to avoid problems
- // because std::list isn't thread safe)
+ // because std::map isn't thread safe)
_plugins = _engine.node_factory()->plugins();
QueuedEvent::pre_process();
diff --git a/src/libs/engine/events/RequestPluginsEvent.hpp b/src/libs/engine/events/RequestPluginsEvent.hpp
index ae6a77a9..f6b41d7a 100644
--- a/src/libs/engine/events/RequestPluginsEvent.hpp
+++ b/src/libs/engine/events/RequestPluginsEvent.hpp
@@ -18,19 +18,12 @@
#ifndef REQUESTPLUGINSEVENT_H
#define REQUESTPLUGINSEVENT_H
-#include <string>
-#include <list>
#include "QueuedEvent.hpp"
-using std::string;
+#include "NodeFactory.hpp"
namespace Ingen {
-class PluginImpl;
class Responder;
-namespace Shared {
- class ClientInterface;
-} using Shared::ClientInterface;
-
/** A request from a client to send notification of all objects (ie refresh).
*
@@ -45,7 +38,7 @@ public:
void post_process();
private:
- std::list<PluginImpl*> _plugins;
+ NodeFactory::Plugins _plugins;
};