diff options
author | David Robillard <d@drobilla.net> | 2010-03-06 10:23:19 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-03-06 10:23:19 +0000 |
commit | 059f20c9666234f2be01498ee04f1e7ee795ba8f (patch) | |
tree | ef0d53073d53012aeaa7d084fccf477b166c0684 /src/module | |
parent | 085a451dfec54126be1b9346899c81d82e6eb58e (diff) | |
download | ingen-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.cpp | 141 | ||||
-rw-r--r-- | src/module/World.hpp | 68 | ||||
-rw-r--r-- | src/module/ingen_module.cpp | 38 | ||||
-rw-r--r-- | src/module/ingen_module.hpp | 6 |
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" |