From dd79e76e41446833088482588456afed37231bff Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 12 Aug 2015 04:46:29 +0000 Subject: Server-side presets. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5703 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/events/Delta.cpp | 54 ++++++++++++++++++++++++++++++++++++++++----- src/server/events/Delta.hpp | 5 +++++ src/server/events/Get.cpp | 38 +++++++++++++++++++++++++------ src/server/events/Get.hpp | 7 +++++- 4 files changed, 91 insertions(+), 13 deletions(-) (limited to 'src/server/events') diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 7d2f896d..dc6759b0 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -34,6 +34,7 @@ #include "PortImpl.hpp" #include "PortType.hpp" #include "SetPortValue.hpp" +#include "events/Get.hpp" // #define DUMP 1 // #include "ingen/URIMap.hpp" @@ -134,10 +135,45 @@ s_add_set_event(const char* port_symbol, bool Delta::pre_process() { + const Ingen::URIs& uris = _engine.world()->uris(); + const bool is_graph_object = Node::uri_is_path(_subject); const bool is_client = (_subject == "ingen:/clients/this"); + const bool is_file = (_subject.substr(0, 5) == "file:"); bool poly_changed = false; + if (_type == Type::PUT && is_file) { + // Ensure type is Preset, the only supported file put + const auto t = _properties.find(uris.rdf_type); + if (t == _properties.end() || t->second != uris.pset_Preset) { + return Event::pre_process_done(Status::BAD_REQUEST, _subject); + } + + // Get "prototype" for preset (node to save state for) + const auto p = _properties.find(uris.lv2_prototype); + if (p == _properties.end()) { + return Event::pre_process_done(Status::BAD_REQUEST, _subject); + } + + const Raul::URI prot(_engine.world()->forge().str(p->second, false)); + + Node* node = _engine.store()->get(Node::uri_to_path(Raul::URI(prot))); + if (!node) { + return Event::pre_process_done(Status::NOT_FOUND, prot); + } + + BlockImpl* block = dynamic_cast(node); + if (!block) { + return Event::pre_process_done(Status::BAD_OBJECT_TYPE, prot); + } + + if ((_preset = block->save_preset(_subject, _properties))) { + return Event::pre_process_done(Status::SUCCESS); + } else { + return Event::pre_process_done(Status::FAILURE); + } + } + // Take a writer lock while we modify the store std::unique_lock lock(_engine.store()->mutex()); @@ -149,8 +185,6 @@ Delta::pre_process() return Event::pre_process_done(Status::NOT_FOUND, _subject); } - const Ingen::URIs& uris = _engine.world()->uris(); - if (is_graph_object && !_object) { Raul::Path path(Node::uri_to_path(_subject)); bool is_graph = false, is_block = false, is_port = false, is_output = false; @@ -258,6 +292,8 @@ Delta::pre_process() if ((_state = block->load_preset(Raul::URI(str)))) { lilv_state_emit_port_values( _state, s_add_set_event, this); + } else { + _engine.log().warn(fmt("Failed to load preset <%1%>\n") % str); } } else { _status = Status::BAD_VALUE; @@ -341,7 +377,7 @@ Delta::pre_process() void Delta::execute(ProcessContext& context) { - if (_status != Status::SUCCESS) { + if (_status != Status::SUCCESS || _preset) { return; } @@ -406,7 +442,7 @@ Delta::execute(ProcessContext& context) if (port) { _engine.control_bindings()->port_binding_changed(context, port, value); } else if (block) { - if (block->plugin_impl()->type() == Plugin::Internal) { + if (uris.ingen_Internal == block->plugin_impl()->type()) { block->learn(); } } @@ -472,7 +508,15 @@ Delta::post_process() _engine.broadcaster()->clear_ignore_client(); break; case Type::PUT: - _engine.broadcaster()->put(_subject, _properties, _context); + if (_type == Type::PUT && _subject.substr(0, 5) == "file:") { + // Preset save + Get::Response response; + response.put(_preset->uri(), _preset->properties()); + response.send(_engine.broadcaster()); + } else { + // Graph object put + _engine.broadcaster()->put(_subject, _properties, _context); + } break; case Type::PATCH: _engine.broadcaster()->delta(_subject, _remove, _properties); diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp index 0b5934ac..7c303fc2 100644 --- a/src/server/events/Delta.hpp +++ b/src/server/events/Delta.hpp @@ -19,10 +19,13 @@ #include +#include + #include "lilv/lilv.h" #include "raul/URI.hpp" +#include "PluginImpl.hpp" #include "ControlBindings.hpp" #include "Event.hpp" @@ -128,6 +131,8 @@ private: SPtr _old_bindings; + boost::optional _preset; + std::unique_lock _poly_lock; ///< Long-term lock for poly changes }; diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index bba95485..185f275a 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -60,8 +60,10 @@ Get::Response::put_port(const PortImpl* port) void Get::Response::put_block(const BlockImpl* block) { - PluginImpl* const plugin = block->plugin_impl(); - if (plugin->type() == Plugin::Graph) { + const PluginImpl* const plugin = block->plugin_impl(); + const URIs& uris = plugin->uris(); + + if (uris.ingen_Graph == plugin->type()) { put_graph((const GraphImpl*)block); } else { put(block->uri(), block->properties()); @@ -82,7 +84,7 @@ Get::Response::put_graph(const GraphImpl* graph) graph->properties(Resource::Graph::EXTERNAL), Resource::Graph::EXTERNAL); - // Enqueue locks + // Enqueue blocks for (const auto& b : graph->blocks()) { put_block(&b); } @@ -100,6 +102,29 @@ Get::Response::put_graph(const GraphImpl* graph) } } +void +Get::Response::put_plugin(PluginImpl* plugin) +{ + put(plugin->uri(), plugin->properties()); + + for (const auto& p : plugin->presets()) { + put_preset(plugin->uris(), plugin->uri(), p.first, p.second); + } +} + +void +Get::Response::put_preset(const URIs& uris, + const Raul::URI& plugin, + const Raul::URI& preset, + const std::string& label) +{ + Resource::Properties props; + props.emplace(uris.rdf_type, uris.pset_Preset.urid); + props.emplace(uris.rdfs_label, uris.forge.alloc(label)); + props.emplace(uris.lv2_appliesTo, uris.forge.make_urid(plugin)); + put(preset, props); +} + /** Returns true if a is closer to the root than b. */ static inline bool put_higher_than(const Get::Response::Put& a, const Get::Response::Put& b) @@ -159,11 +184,10 @@ Get::pre_process() return Event::pre_process_done(Status::SUCCESS); } return Event::pre_process_done(Status::NOT_FOUND, _uri); + } else if ((_plugin = _engine.block_factory()->plugin(_uri))) { + _response.put_plugin(_plugin); + return Event::pre_process_done(Status::SUCCESS); } else { - if ((_plugin = _engine.block_factory()->plugin(_uri))) { - _response.put(_uri, _plugin->properties()); - return Event::pre_process_done(Status::SUCCESS); - } return Event::pre_process_done(Status::NOT_FOUND, _uri); } } diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp index 5a4bde23..f24e42e0 100644 --- a/src/server/events/Get.hpp +++ b/src/server/events/Get.hpp @@ -67,6 +67,11 @@ public: void put_port(const PortImpl* port); void put_block(const BlockImpl* block); void put_graph(const GraphImpl* graph); + void put_plugin(PluginImpl* plugin); + void put_preset(const URIs& uris, + const Raul::URI& plugin, + const Raul::URI& preset, + const std::string& label); void send(Interface* dest); @@ -88,7 +93,7 @@ public: private: const Raul::URI _uri; const Node* _object; - const PluginImpl* _plugin; + PluginImpl* _plugin; BlockFactory::Plugins _plugins; Response _response; }; -- cgit v1.2.1