From 059f20c9666234f2be01498ee04f1e7ee795ba8f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 6 Mar 2010 10:23:19 +0000 Subject: 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 --- src/shared/Builder.cpp | 7 ++++--- src/shared/Builder.hpp | 8 +++++--- src/shared/LV2Features.cpp | 1 - src/shared/LV2Object.cpp | 8 ++------ src/shared/LV2Object.hpp | 5 +++-- src/shared/LV2URIMap.cpp | 22 +++++++++------------- src/shared/LV2URIMap.hpp | 5 ++--- src/shared/ResourceImpl.cpp | 8 +++----- src/shared/ResourceImpl.hpp | 11 ++++++++++- src/shared/runtime_paths.cpp | 33 +++++++++++++++++++++++---------- src/shared/runtime_paths.hpp | 2 ++ src/shared/wscript | 1 + 12 files changed, 64 insertions(+), 47 deletions(-) (limited to 'src/shared') diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp index 0cc4e980..72e90ad1 100644 --- a/src/shared/Builder.cpp +++ b/src/shared/Builder.cpp @@ -32,8 +32,9 @@ namespace Ingen { namespace Shared { -Builder::Builder(CommonInterface& interface) - : _interface(interface) +Builder::Builder(SharedPtr uris, CommonInterface& interface) + : _uris(uris) + , _interface(interface) { } @@ -41,7 +42,7 @@ Builder::Builder(CommonInterface& interface) void Builder::build(SharedPtr object) { - const LV2URIMap& uris = Shared::LV2URIMap::instance(); + const LV2URIMap& uris = *_uris.get(); SharedPtr patch = PtrCast(object); if (patch) { if (!object->path().is_root()) { diff --git a/src/shared/Builder.hpp b/src/shared/Builder.hpp index ec953d41..b77201dd 100644 --- a/src/shared/Builder.hpp +++ b/src/shared/Builder.hpp @@ -25,8 +25,9 @@ namespace Raul { class Path; } namespace Ingen { namespace Shared { -class GraphObject; class CommonInterface; +class GraphObject; +class LV2URIMap; /** Wrapper for CommonInterface to create existing objects/models. @@ -36,7 +37,7 @@ class CommonInterface; class Builder { public: - Builder(CommonInterface& interface); + Builder(SharedPtr uris, CommonInterface& interface); virtual ~Builder() {} void build(SharedPtr object); @@ -45,7 +46,8 @@ public: private: void build_object(SharedPtr object); - CommonInterface& _interface; + SharedPtr _uris; + CommonInterface& _interface; }; diff --git a/src/shared/LV2Features.cpp b/src/shared/LV2Features.cpp index 5088d6e0..21d6039e 100644 --- a/src/shared/LV2Features.cpp +++ b/src/shared/LV2Features.cpp @@ -28,7 +28,6 @@ namespace Shared { LV2Features::LV2Features() { - add_feature(LV2_URI_MAP_URI, SharedPtr(new LV2URIMap())); } diff --git a/src/shared/LV2Object.cpp b/src/shared/LV2Object.cpp index 252972ff..4388ede8 100644 --- a/src/shared/LV2Object.cpp +++ b/src/shared/LV2Object.cpp @@ -32,10 +32,8 @@ namespace LV2Object { bool -to_atom(const LV2_Object* object, Raul::Atom& atom) +to_atom(const Shared::LV2URIMap& uris, const LV2_Object* object, Raul::Atom& atom) { - const LV2URIMap& uris = Shared::LV2URIMap::instance(); - if (object->type == uris.object_class_string.id) { atom = Raul::Atom((char*)(object + 1)); return true; @@ -57,10 +55,8 @@ to_atom(const LV2_Object* object, Raul::Atom& atom) * object->size should be the capacity of the object (not including header) */ bool -from_atom(const Raul::Atom& atom, LV2_Object* object) +from_atom(const Shared::LV2URIMap& uris, const Raul::Atom& atom, LV2_Object* object) { - const LV2URIMap& uris = Shared::LV2URIMap::instance(); - char* str; switch (atom.type()) { case Raul::Atom::FLOAT: diff --git a/src/shared/LV2Object.hpp b/src/shared/LV2Object.hpp index 794422a0..bec2ff89 100644 --- a/src/shared/LV2Object.hpp +++ b/src/shared/LV2Object.hpp @@ -25,11 +25,12 @@ namespace Ingen { namespace Shared { class World; +class LV2URIMap; namespace LV2Object { - bool to_atom(const LV2_Object* object, Raul::Atom& atom); - bool from_atom(const Raul::Atom& atom, LV2_Object* object); + bool to_atom(const Shared::LV2URIMap& uris, const LV2_Object* object, Raul::Atom& atom); + bool from_atom(const Shared::LV2URIMap& uris, const Raul::Atom& atom, LV2_Object* object); } // namespace LV2Object diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp index d8114014..e069a644 100644 --- a/src/shared/LV2URIMap.cpp +++ b/src/shared/LV2URIMap.cpp @@ -19,11 +19,10 @@ #include #include #include +#include #include "raul/log.hpp" #include "object.lv2/object.h" #include "LV2URIMap.hpp" -#include "module/ingen_module.hpp" -#include "module/World.hpp" using namespace std; using namespace Raul; @@ -38,6 +37,12 @@ LV2URIMap::Quark::Quark(const char* c_str) { } +const char* +LV2URIMap::Quark::c_str() const +{ + return g_quark_to_string(id); +} + #define NS_CTX "http://lv2plug.in/ns/dev/contexts#" #define NS_INGEN "http://drobilla.net/ns/ingen#" #define NS_INGENUI "http://drobilla.net/ns/ingenuity#" @@ -114,23 +119,14 @@ LV2URIMap::LV2URIMap() } -const LV2URIMap& -LV2URIMap::instance() -{ - return *ingen_get_world()->uris; -} +struct null_deleter { void operator()(void const *) const {} }; uint32_t LV2URIMap::uri_to_id(const char* map, const char* uri) { - const uint32_t ret = static_cast(g_quark_from_string(uri)); - debug << "[LV2URIMap] "; - if (map) - debug << map << " : "; - debug << uri << " => " << ret << endl; - return ret; + return static_cast(g_quark_from_string(uri)); } diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp index 2c5bdef2..30203de7 100644 --- a/src/shared/LV2URIMap.hpp +++ b/src/shared/LV2URIMap.hpp @@ -38,9 +38,7 @@ public: return SharedPtr(&uri_map_feature, NullDeleter); } - uint32_t uri_to_id(const char* map, const char* uri); - - static const LV2URIMap& instance(); + virtual uint32_t uri_to_id(const char* map, const char* uri); private: static uint32_t uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data, @@ -53,6 +51,7 @@ private: public: struct Quark : public Raul::URI { Quark(const char* str); + const char* c_str() const; uint32_t id; }; diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index b542ff2d..db44f0f7 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -67,8 +67,7 @@ ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value) void ResourceImpl::remove_property(const Raul::URI& uri, const Raul::Atom& value) { - const LV2URIMap& uris = Shared::LV2URIMap::instance(); - if (value == uris.wildcard) { + if (value == _uris.wildcard) { _properties.erase(uri); } else { Properties::iterator i = _properties.find(uri); @@ -113,13 +112,13 @@ ResourceImpl::get_property(const Raul::URI& uri) const bool ResourceImpl::type( + const LV2URIMap& uris, const Properties& properties, bool& patch, bool& node, bool& port, bool& is_output, PortType& data_type) { typedef Resource::Properties::const_iterator iterator; - const LV2URIMap& uris = Shared::LV2URIMap::instance(); const std::pair types_range = properties.equal_range(uris.rdf_type); patch = node = port = is_output = false; @@ -198,10 +197,9 @@ ResourceImpl::add_properties(const Properties& p) void ResourceImpl::remove_properties(const Properties& p) { - const LV2URIMap& uris = Shared::LV2URIMap::instance(); typedef Resource::Properties::const_iterator iterator; for (iterator i = p.begin(); i != p.end(); ++i) { - if (i->second == uris.wildcard) { + if (i->second == _uris.wildcard) { _properties.erase(i->first); } else { for (Properties::iterator j = _properties.find(i->first); diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp index 8e827df8..7b77d669 100644 --- a/src/shared/ResourceImpl.hpp +++ b/src/shared/ResourceImpl.hpp @@ -21,16 +21,22 @@ #include #include #include "raul/URI.hpp" +#include "raul/SharedPtr.hpp" #include "interface/Resource.hpp" #include "interface/PortType.hpp" namespace Ingen { namespace Shared { +class LV2URIMap; + class ResourceImpl : virtual public Resource { public: - ResourceImpl(const Raul::URI& uri) : _uri(uri) {} + ResourceImpl(LV2URIMap& uris, const Raul::URI& uri) + : _uris(uris), _uri(uri) {} + + LV2URIMap& uris() const { return _uris; } virtual void set_uri(const Raul::URI& uri) { _uri = uri; } virtual const Raul::URI& uri() const { return _uri; } @@ -56,6 +62,7 @@ public: * output parameter set to true. Otherwise false is returned. */ static bool type( + const LV2URIMap& uris, const Properties& properties, bool& patch, bool& node, @@ -67,6 +74,8 @@ public: protected: Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value) const; + LV2URIMap& _uris; + private: Raul::URI _uri; mutable Properties _properties; diff --git a/src/shared/runtime_paths.cpp b/src/shared/runtime_paths.cpp index f823c4e2..832c3472 100644 --- a/src/shared/runtime_paths.cpp +++ b/src/shared/runtime_paths.cpp @@ -41,29 +41,44 @@ set_bundle_path_from_code(void* function) Dl_info dli; dladdr(function, &dli); +#ifdef BUNDLE char bin_loc[PATH_MAX]; realpath(dli.dli_fname, bin_loc); +#else + const char* bin_loc = dli.dli_fname; +#endif -#ifdef BUNDLE string bundle = bin_loc; bundle = bundle.substr(0, bundle.find_last_of(G_DIR_SEPARATOR)); bundle_path = bundle; -#endif } +void +set_bundle_path(const char* path) +{ + bundle_path = path; +} + + +/** Return the absolute path of a file in an Ingen LV2 bundle + */ +std::string +bundle_file_path(const std::string& name) +{ + return Glib::build_filename(bundle_path, name); +} + /** Return the absolute path of a 'resource' file. */ std::string data_file_path(const std::string& name) { - std::string ret; #ifdef BUNDLE - ret = Glib::build_filename(bundle_path, Glib::build_path(INGEN_DATA_DIR, name)); + return Glib::build_filename(bundle_path, Glib::build_path(INGEN_DATA_DIR, name)); #else - ret = Glib::build_filename(INGEN_DATA_DIR, name); + return Glib::build_filename(INGEN_DATA_DIR, name); #endif - return ret; } @@ -72,13 +87,11 @@ data_file_path(const std::string& name) std::string module_path(const std::string& name) { - std::string ret; #ifdef BUNDLE - ret = Glib::Module::build_path(Glib::build_path(bundle_path, INGEN_MODULE_DIR), name); + return Glib::Module::build_path(Glib::build_path(bundle_path, INGEN_MODULE_DIR), name); #else - ret = Glib::Module::build_path(INGEN_MODULE_DIR, name); + return Glib::Module::build_path(INGEN_MODULE_DIR, name); #endif - return ret; } diff --git a/src/shared/runtime_paths.hpp b/src/shared/runtime_paths.hpp index e93e2343..0e8e2b85 100644 --- a/src/shared/runtime_paths.hpp +++ b/src/shared/runtime_paths.hpp @@ -27,8 +27,10 @@ namespace Ingen { namespace Shared { +void set_bundle_path(const char* path); void set_bundle_path_from_code(void* function); +std::string bundle_file_path(const std::string& name); std::string data_file_path(const std::string& name); std::string module_path(const std::string& name); diff --git a/src/shared/wscript b/src/shared/wscript index 540d4e83..6626f55a 100644 --- a/src/shared/wscript +++ b/src/shared/wscript @@ -9,6 +9,7 @@ def build(bld): obj.source = ''' Builder.cpp ClashAvoider.cpp + Configuration.cpp LV2Features.cpp LV2Object.cpp LV2URIMap.cpp -- cgit v1.2.1