summaryrefslogtreecommitdiffstats
path: root/src/module
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-03-06 10:23:19 +0000
committerDavid Robillard <d@drobilla.net>2010-03-06 10:23:19 +0000
commit059f20c9666234f2be01498ee04f1e7ee795ba8f (patch)
treeef0d53073d53012aeaa7d084fccf477b166c0684 /src/module
parent085a451dfec54126be1b9346899c81d82e6eb58e (diff)
downloadingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.tar.gz
ingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.tar.bz2
ingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.zip
Save Ingen patches as working standard LV2 plugin bundles.
This allows you to create an Ingen patch in Ingen running as a Jack client, save it, then load that patch as an LV2 plugin in any LV2 compliant host. Eliminate (hopefully) all static data in the engine (for multiple instantiations in a single process). More API/ABI stable interface for Ingen::Shared::World. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2533 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/module')
-rw-r--r--src/module/World.cpp141
-rw-r--r--src/module/World.hpp68
-rw-r--r--src/module/ingen_module.cpp38
-rw-r--r--src/module/ingen_module.hpp6
4 files changed, 182 insertions, 71 deletions
diff --git a/src/module/World.cpp b/src/module/World.cpp
index 43d89d6c..727e2dc8 100644
--- a/src/module/World.cpp
+++ b/src/module/World.cpp
@@ -15,12 +15,19 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "ingen-config.h"
+#include <boost/utility.hpp>
#include <glibmm/module.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
+#ifdef HAVE_SLV2
+#include "slv2/slv2.h"
+#endif
#include "raul/log.hpp"
-#include "ingen-config.h"
+#include "redlandmm/World.hpp"
#include "shared/runtime_paths.hpp"
+#include "shared/LV2Features.hpp"
+#include "shared/LV2URIMap.hpp"
#include "World.hpp"
#define LOG(s) s << "[Module] "
@@ -85,6 +92,124 @@ load_module(const string& name)
}
}
+
+struct WorldImpl : public boost::noncopyable {
+ WorldImpl(Raul::Configuration* conf, int& a_argc, char**& a_argv)
+ : argc(a_argc)
+ , argv(a_argv)
+ , conf(conf)
+ , lv2_features(NULL)
+ , rdf_world(new Redland::World())
+ , uris(new Shared::LV2URIMap())
+#ifdef HAVE_SLV2
+ , slv2_world(slv2_world_new_using_rdf_world(rdf_world->c_obj()))
+#endif
+ {
+#ifdef HAVE_SLV2
+ lv2_features = new Ingen::Shared::LV2Features();
+ lv2_features->add_feature(LV2_URI_MAP_URI, uris);
+ slv2_world_load_all(slv2_world);
+#endif
+
+ // Set up RDF namespaces
+ rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/");
+ rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
+ rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#");
+ rdf_world->add_prefix("ingenui", "http://drobilla.net/ns/ingenuity#");
+ rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
+ rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#");
+ rdf_world->add_prefix("ctx", "http://lv2plug.in/ns/dev/contexts#");
+ rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#");
+ rdf_world->add_prefix("midi", "http://drobilla.net/ns/dev/midi#");
+ rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
+ rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
+ rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#");
+ rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
+ }
+
+ virtual ~WorldImpl()
+ {
+ modules.clear();
+ interface_factories.clear();
+ script_runners.clear();
+
+ #ifdef HAVE_SLV2
+ slv2_world_free(slv2_world);
+ slv2_world = NULL;
+ #endif
+
+ delete rdf_world;
+ rdf_world = NULL;
+
+ delete lv2_features;
+ lv2_features = NULL;
+
+ uris.reset();
+ }
+
+ typedef std::map< const std::string, SharedPtr<Module> > Modules;
+ Modules modules;
+
+ typedef std::map<const std::string, World::InterfaceFactory> InterfaceFactories;
+ InterfaceFactories interface_factories;
+
+ typedef bool (*ScriptRunner)(World* world, const char* filename);
+ typedef std::map<const std::string, ScriptRunner> ScriptRunners;
+ ScriptRunners script_runners;
+
+ int& argc;
+ char**& argv;
+ Raul::Configuration* conf;
+ LV2Features* lv2_features;
+ Redland::World* rdf_world;
+ SharedPtr<LV2URIMap> uris;
+ SharedPtr<EngineInterface> engine;
+ SharedPtr<Engine> local_engine;
+ SharedPtr<Serialisation::Serialiser> serialiser;
+ SharedPtr<Serialisation::Parser> parser;
+ SharedPtr<Store> store;
+#ifdef HAVE_SLV2
+ SLV2World slv2_world;
+#endif
+};
+
+
+World::World(Raul::Configuration* conf, int& argc, char**& argv)
+ : _impl(new WorldImpl(conf, argc, argv))
+{
+}
+
+
+World::~World()
+{
+ unload_all();
+ delete _impl;
+}
+
+void World::set_local_engine(SharedPtr<Engine> e) { _impl->local_engine = e; }
+void World::set_engine(SharedPtr<EngineInterface> e) { _impl->engine = e; }
+void World::set_serialiser(SharedPtr<Serialisation::Serialiser> s) { _impl->serialiser = s; }
+void World::set_parser(SharedPtr<Serialisation::Parser> p) { _impl->parser = p; }
+void World::set_store(SharedPtr<Store> s) { _impl->store = s; }
+void World::set_conf(Raul::Configuration* c) { _impl->conf = c; }
+
+int& World::argc() { return _impl->argc; }
+char**& World::argv() { return _impl->argv; }
+SharedPtr<Engine> World::local_engine() { return _impl->local_engine; }
+SharedPtr<EngineInterface> World::engine() { return _impl->engine; }
+SharedPtr<Serialisation::Serialiser> World::serialiser() { return _impl->serialiser; }
+SharedPtr<Serialisation::Parser> World::parser() { return _impl->parser; }
+SharedPtr<Store> World::store() { return _impl->store; }
+Raul::Configuration* World::conf() { return _impl->conf; }
+LV2Features* World::lv2_features() { return _impl->lv2_features; }
+
+#ifdef HAVE_SLV2
+SLV2World World::slv2_world() { return _impl->slv2_world; }
+#endif
+Redland::World* World::rdf_world() { return _impl->rdf_world; }
+SharedPtr<LV2URIMap> World::uris() { return _impl->uris; }
+
+
/** Load an Ingen module.
* @return true on success, false on failure
*/
@@ -97,7 +222,7 @@ World::load(const char* name)
Module* module = module_load();
module->library = lib;
module->load(this);
- modules.insert(make_pair(string(name), module));
+ _impl->modules.insert(make_pair(string(name), module));
return true;
} else {
LOG(error) << "Failed to load module `" << name << "'" << endl;
@@ -111,7 +236,7 @@ World::load(const char* name)
void
World::unload_all()
{
- modules.clear();
+ _impl->modules.clear();
}
@@ -121,8 +246,8 @@ SharedPtr<Ingen::Shared::EngineInterface>
World::interface(const std::string& url)
{
const string scheme = url.substr(0, url.find(":"));
- const InterfaceFactories::const_iterator i = interface_factories.find(scheme);
- if (i == interface_factories.end()) {
+ const WorldImpl::InterfaceFactories::const_iterator i = _impl->interface_factories.find(scheme);
+ if (i == _impl->interface_factories.end()) {
warn << "Unknown URI scheme `" << scheme << "'" << endl;
return SharedPtr<Ingen::Shared::EngineInterface>();
}
@@ -135,8 +260,8 @@ World::interface(const std::string& url)
bool
World::run(const std::string& mime_type, const std::string& filename)
{
- const ScriptRunners::const_iterator i = script_runners.find(mime_type);
- if (i == script_runners.end()) {
+ const WorldImpl::ScriptRunners::const_iterator i = _impl->script_runners.find(mime_type);
+ if (i == _impl->script_runners.end()) {
warn << "Unknown script MIME type `" << mime_type << "'" << endl;
return false;
}
@@ -147,7 +272,7 @@ World::run(const std::string& mime_type, const std::string& filename)
void
World::add_interface_factory(const std::string& scheme, InterfaceFactory factory)
{
- interface_factories.insert(make_pair(scheme, factory));
+ _impl->interface_factories.insert(make_pair(scheme, factory));
}
diff --git a/src/module/World.hpp b/src/module/World.hpp
index fcb48845..a84e2454 100644
--- a/src/module/World.hpp
+++ b/src/module/World.hpp
@@ -21,11 +21,17 @@
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
#include <glibmm/module.h>
+#include "ingen-config.h"
#include "raul/Configuration.hpp"
+#include "raul/SharedPtr.hpp"
#include "Module.hpp"
+#include "module/ingen_module.hpp"
+#ifdef HAVE_SLV2
typedef struct _SLV2World* SLV2World;
+#endif
namespace Redland { class World; }
@@ -41,6 +47,7 @@ class EngineInterface;
class Store;
class LV2Features;
class LV2URIMap;
+struct WorldImpl;
/** The "world" all Ingen modules may share.
@@ -52,46 +59,53 @@ class LV2URIMap;
* using World::load, e.g. loading the "ingen_serialisation" module will
* set World::serialiser and World::parser to valid objects.
*/
-struct World {
- World() : argc(0), argv(0), conf(0), rdf_world(0), slv2_world(0), lv2_features(0) {}
+class World : public boost::noncopyable {
+ friend Ingen::Shared::World* ::ingen_world_new(Raul::Configuration*, int&, char**&);
+ World(Raul::Configuration* conf, int& argc, char**& argv);
- bool load(const char* name);
- void unload_all();
+ friend void ::ingen_world_free(Ingen::Shared::World* world);
+ virtual ~World();
+
+ WorldImpl* _impl;
+
+public:
+ virtual bool load(const char* name);
+ virtual void unload_all();
typedef SharedPtr<Ingen::Shared::EngineInterface> (*InterfaceFactory)(
World* world, const std::string& engine_url);
- void add_interface_factory(const std::string& scheme, InterfaceFactory factory);
- SharedPtr<Ingen::Shared::EngineInterface> interface(const std::string& engine_url);
+ virtual void add_interface_factory(const std::string& scheme, InterfaceFactory factory);
+ virtual SharedPtr<Ingen::Shared::EngineInterface> interface(const std::string& engine_url);
- bool run(const std::string& mime_type, const std::string& filename);
+ virtual bool run(const std::string& mime_type, const std::string& filename);
- int argc;
- char** argv;
- Raul::Configuration* conf;
+ virtual void set_local_engine(SharedPtr<Engine> e);
+ virtual void set_engine(SharedPtr<EngineInterface> e);
+ virtual void set_serialiser(SharedPtr<Serialisation::Serialiser> s);
+ virtual void set_parser(SharedPtr<Serialisation::Parser> p);
+ virtual void set_store(SharedPtr<Store> s);
- Redland::World* rdf_world;
- SLV2World slv2_world;
- LV2Features* lv2_features;
+ virtual SharedPtr<Engine> local_engine();
+ virtual SharedPtr<EngineInterface> engine();
+ virtual SharedPtr<Serialisation::Serialiser> serialiser();
+ virtual SharedPtr<Serialisation::Parser> parser();
+ virtual SharedPtr<Store> store();
- boost::shared_ptr<LV2URIMap> uris;
+ virtual Redland::World* rdf_world();
+ virtual SharedPtr<LV2URIMap> uris();
- boost::shared_ptr<EngineInterface> engine;
- boost::shared_ptr<Engine> local_engine;
- boost::shared_ptr<Serialisation::Serialiser> serialiser;
- boost::shared_ptr<Serialisation::Parser> parser;
- boost::shared_ptr<Store> store;
+ virtual int& argc();
+ virtual char**& argv();
-private:
- typedef std::map< const std::string, boost::shared_ptr<Module> > Modules;
- Modules modules;
+ virtual Raul::Configuration* conf();
+ virtual void set_conf(Raul::Configuration* c);
- typedef std::map<const std::string, InterfaceFactory> InterfaceFactories;
- InterfaceFactories interface_factories;
+ virtual LV2Features* lv2_features();
- typedef bool (*ScriptRunner)(World* world, const char* filename);
- typedef std::map<const std::string, ScriptRunner> ScriptRunners;
- ScriptRunners script_runners;
+#ifdef HAVE_SLV2
+ virtual SLV2World slv2_world();
+#endif
};
diff --git a/src/module/ingen_module.cpp b/src/module/ingen_module.cpp
index 167fd0f2..140aec2e 100644
--- a/src/module/ingen_module.cpp
+++ b/src/module/ingen_module.cpp
@@ -28,46 +28,16 @@
extern "C" {
-static Ingen::Shared::World* world = NULL;
-
Ingen::Shared::World*
-ingen_get_world()
+ingen_world_new(Raul::Configuration* conf, int& argc, char**& argv)
{
- static Ingen::Shared::World* world = NULL;
-
- if (!world) {
- world = new Ingen::Shared::World();
- world->rdf_world = new Redland::World();
-#ifdef HAVE_SLV2
- world->slv2_world = slv2_world_new_using_rdf_world(world->rdf_world->world());
- world->lv2_features = new Ingen::Shared::LV2Features();
- world->uris = PtrCast<Ingen::Shared::LV2URIMap>(
- world->lv2_features->feature(LV2_URI_MAP_URI));
- slv2_world_load_all(world->slv2_world);
-#else
- world->uris = SharedPtr<Ingen::Shared::LV2URIMap>(
- new Ingen::Shared::LV2URIMap());
-#endif
- world->engine.reset();
- world->local_engine.reset();
- }
-
- return world;
+ return new Ingen::Shared::World(conf, argc, argv);
}
void
-ingen_destroy_world()
+ingen_world_free(Ingen::Shared::World* world)
{
- if (world) {
- world->unload_all();
-#ifdef HAVE_SLV2
- slv2_world_free(world->slv2_world);
- delete world->lv2_features;
-#endif
- delete world->rdf_world;
- delete world;
- world = NULL;
- }
+ delete world;
}
} // extern "C"
diff --git a/src/module/ingen_module.hpp b/src/module/ingen_module.hpp
index bb2c3adb..0fd921f7 100644
--- a/src/module/ingen_module.hpp
+++ b/src/module/ingen_module.hpp
@@ -18,12 +18,14 @@
#ifndef INGEN_MODULE_HPP
#define INGEN_MODULE_HPP
+namespace Raul { class Configuration; }
+
namespace Ingen { namespace Shared { class World; } }
extern "C" {
-Ingen::Shared::World* ingen_get_world();
-void ingen_destroy_world();
+Ingen::Shared::World* ingen_world_new(Raul::Configuration* conf, int& argc, char**& argv);
+void ingen_world_free(Ingen::Shared::World* world);
} // extern "C"