From 5d1f579900182f283a1c21ad4e59daf7f035e219 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 9 Nov 2008 01:32:38 +0000 Subject: Move patch to /patch via HTTP to give a place for RESTful access to other things. Implement HTTP access to plugins. Work towards client being able to use HTTP to connect. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1712 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/HTTPClientReceiver.cpp | 45 ++++++++++++++++--- src/client/HTTPEngineSender.cpp | 44 ++++++++---------- src/client/PluginModel.hpp | 17 ------- src/common/interface/Plugin.hpp | 29 +++++++++--- src/engine/HTTPEngineReceiver.cpp | 95 ++++++++++++++++++++++++++------------- src/engine/HTTPEngineReceiver.hpp | 4 ++ src/engine/NodeFactory.cpp | 3 +- src/engine/OSCClientSender.cpp | 2 +- src/engine/OSCEngineReceiver.cpp | 2 +- src/engine/PluginImpl.hpp | 19 -------- src/gui/LoadPluginWindow.cpp | 2 +- src/ingen/cmdline.c | 44 +++--------------- src/ingen/cmdline.ggo | 2 +- src/ingen/cmdline.h | 10 ++--- src/serialisation/Parser.cpp | 57 +++++++++++++++-------- src/serialisation/Parser.hpp | 1 - src/serialisation/Serialiser.cpp | 6 +-- src/serialisation/Serialiser.hpp | 3 +- 18 files changed, 205 insertions(+), 180 deletions(-) (limited to 'src') diff --git a/src/client/HTTPClientReceiver.cpp b/src/client/HTTPClientReceiver.cpp index 4773b7ce..5d4a8660 100644 --- a/src/client/HTTPClientReceiver.cpp +++ b/src/client/HTTPClientReceiver.cpp @@ -53,11 +53,35 @@ void HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr) { HTTPClientReceiver* me = (HTTPClientReceiver*)ptr; - cout << "RECEIVED ASYNC MESSAGE: " << msg->response_body->data << endl; - me->_target->response_ok(0); - me->_target->enable(); - me->_parser->parse_string(me->_world, me->_target.get(), Glib::ustring(msg->response_body->data), - Glib::ustring("/"), Glib::ustring("")); + //cout << "RECEIVED ASYNC MESSAGE: " << msg->response_body->data << endl; + const string path = soup_message_get_uri(msg)->path; + if (path == "/") { + cout << "RECEIVED ROOT" << endl; + me->_target->response_ok(0); + me->_target->enable(); + } else if (path == "/plugins") { + cout << "RECIEVED PLUGINS" << endl; + if (msg->response_body->data == NULL) { + cout << "NO RESPONSE?!" << endl; + } else { + me->_target->response_ok(0); + me->_target->enable(); + me->_parser->parse_string(me->_world, me->_target.get(), + Glib::ustring(msg->response_body->data), + Glib::ustring("."), Glib::ustring("")); + } + } else if (path == "/patch") { + cout << "RECEIVED OBJECTS" << endl; + if (msg->response_body->data == NULL) { + cout << "NO RESPONSE?!" << endl; + } else { + me->_target->response_ok(0); + me->_target->enable(); + me->_parser->parse_string(me->_world, me->_target.get(), + Glib::ustring(msg->response_body->data), + Glib::ustring("/patch/"), Glib::ustring("")); + } + } } @@ -75,8 +99,17 @@ HTTPClientReceiver::start(bool dump) _parser = SharedPtr(new_parser()); } } + _session = soup_session_async_new(); - SoupMessage* msg = soup_message_new("GET", _url.c_str()); + SoupMessage* msg; + + msg = soup_message_new("GET", _url.c_str()); + soup_session_queue_message (_session, msg, message_callback, this); + + msg = soup_message_new("GET", (_url + "/plugins").c_str()); + soup_session_queue_message (_session, msg, message_callback, this); + + msg = soup_message_new("GET", (_url + "/patch").c_str()); soup_session_queue_message (_session, msg, message_callback, this); } diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp index 733e0ac7..312c10ba 100644 --- a/src/client/HTTPEngineSender.cpp +++ b/src/client/HTTPEngineSender.cpp @@ -63,14 +63,12 @@ HTTPEngineSender::attach(int32_t ping_id, bool block) void HTTPEngineSender::register_client(ClientInterface* client) { - } void HTTPEngineSender::unregister_client(const string& uri) { - } @@ -78,28 +76,24 @@ HTTPEngineSender::unregister_client(const string& uri) void HTTPEngineSender::load_plugins() { - } void HTTPEngineSender::activate() { - } void HTTPEngineSender::deactivate() { - } void HTTPEngineSender::quit() { - } @@ -108,23 +102,23 @@ HTTPEngineSender::quit() void HTTPEngineSender::new_patch(const string& path, - uint32_t poly) + uint32_t poly) { } void HTTPEngineSender::new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output) + uint32_t index, + const string& data_type, + bool is_output) { } void HTTPEngineSender::new_node(const string& path, - const string& plugin_uri) + const string& plugin_uri) { } @@ -135,16 +129,16 @@ HTTPEngineSender::new_node(const string& path, */ void HTTPEngineSender::new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label) + const string& plugin_type, + const string& library_name, + const string& plugin_label) { } void HTTPEngineSender::rename(const string& old_path, - const string& new_name) + const string& new_name) { } @@ -163,44 +157,44 @@ HTTPEngineSender::clear_patch(const string& patch_path) void HTTPEngineSender::connect(const string& src_port_path, - const string& dst_port_path) + const string& dst_port_path) { } void HTTPEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) + const string& dst_port_path) { } void HTTPEngineSender::disconnect_all(const string& parent_patch_path, - const string& node_path) + const string& node_path) { } void HTTPEngineSender::set_port_value(const string& port_path, - const Raul::Atom& value) + const Raul::Atom& value) { } void HTTPEngineSender::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) + uint32_t voice, + const Raul::Atom& value) { } void HTTPEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) + uint32_t bank, + uint32_t program) { } @@ -213,8 +207,8 @@ HTTPEngineSender::midi_learn(const string& node_path) void HTTPEngineSender::set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value) + const string& predicate, + const Raul::Atom& value) { } diff --git a/src/client/PluginModel.hpp b/src/client/PluginModel.hpp index f27bb232..3d25cb5e 100644 --- a/src/client/PluginModel.hpp +++ b/src/client/PluginModel.hpp @@ -66,23 +66,6 @@ public: const string& uri() const { return _uri; } const string& name() const { return _name; } - /** DEPRECATED */ - Type type_from_string(const string& type_string) { - if (type_string == "LV2") return LV2; - else if (type_string == "LADSPA") return LADSPA; - else if (type_string == "Internal") return Internal; - else if (type_string == "Patch") return Patch; - else return Internal; // ? - } - - Type type_from_uri(const string& type_uri) { - if (type_uri.substr(0, 6) != "ingen:") { - return Plugin::Internal; // ? - } else { - return type_from_string(type_uri.substr(6)); - } - } - string default_node_symbol(); string human_name(); string port_human_name(uint32_t index); diff --git a/src/common/interface/Plugin.hpp b/src/common/interface/Plugin.hpp index 716c240e..db67bf08 100644 --- a/src/common/interface/Plugin.hpp +++ b/src/common/interface/Plugin.hpp @@ -29,15 +29,30 @@ class Plugin public: enum Type { LV2, LADSPA, Internal, Patch }; - virtual Type type() const = 0; - virtual const std::string& uri() const = 0; + virtual Type type() const = 0; + virtual const std::string& uri() const = 0; inline const char* type_uri() const { - if (type() == LV2) return "ingen:LV2"; - else if (type() == LADSPA) return "ingen:LADSPA"; - else if (type() == Internal) return "ingen:Internal"; - else if (type() == Patch) return "ingen:Patch"; - else return ""; + switch (type()) { + case LV2: return "lv2:Plugin"; + case LADSPA: return "ingen:LADSPAPlugin"; + case Internal: return "ingen:Internal"; + case Patch: return "ingen:Patch"; + default: return ""; + } + } + + static inline Type type_from_uri(const std::string& uri) { + if (uri == "lv2:Plugin") + return LV2; + else if (uri == "ingen:LADSPAPlugin") + return LADSPA; + else if (uri == "ingen:Internal") + return Internal; + else if (uri == "ingen:Patch") + return Patch; + else + return Internal; } }; diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp index 4c5c3b36..8a035175 100644 --- a/src/engine/HTTPEngineReceiver.cpp +++ b/src/engine/HTTPEngineReceiver.cpp @@ -48,7 +48,7 @@ HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) soup_server_add_handler(_server, NULL, message_callback, this, NULL); cout << "Started HTTP server on port " << soup_server_get_port(_server) << endl; - Thread::set_name("HTTP receiver"); + Thread::set_name("HTTP Receiver"); if (!engine.world()->serialisation_module) engine.world()->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); @@ -64,12 +64,17 @@ HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) } else { cerr << "WARNING: Failed to load ingen_serialisation module, HTTP disabled." << endl; } + + Thread::set_name("HTTP Receiver"); } HTTPEngineReceiver::~HTTPEngineReceiver() { deactivate(); + stop(); + _receive_thread->stop(); + delete _receive_thread; if (_server != NULL) { soup_server_quit(_server); @@ -97,7 +102,7 @@ HTTPEngineReceiver::deactivate() void -HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path, +HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path_str, GHashTable *query, SoupClientContext* client, void* data) { HTTPEngineReceiver* me = (HTTPEngineReceiver*)data; @@ -108,10 +113,51 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const return; } + string path = path_str; + if (path[path.length()-1] == '/') { + path = path.substr(0, path.length()-1); + } + + SharedPtr serialiser = me->_engine.world()->serialiser; + + const string base_uri = ""; + const char* mime_type = "text/plain"; + + if (path == "/" || path == "") { + const string r = string("@prefix rdfs: .\n") + .append("\n<> rdfs:seeAlso ;") + .append("\n rdfs:seeAlso ."); + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length()); + return; + + } else if (path.substr(0, 8) == "/plugins") { + // FIXME: kludge + me->load_plugins(); + me->_receive_thread->whip(); + + serialiser->start_to_string("/", base_uri); + for (NodeFactory::Plugins::const_iterator p = me->_engine.node_factory()->plugins().begin(); + p != me->_engine.node_factory()->plugins().end(); ++p) + serialiser->serialise_plugin(*(Shared::Plugin*)p->second); + const string r = serialiser->finish(); + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length()); + return; + } else if (path.substr(0, 6) == "/patch") { + path = '/' + path.substr(6); + } else { + cout << "UNKNOWN PATH: " << path << endl; + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC, + "Unknown path\n\n", 14); + return; + } + if (!Path::is_valid(path)) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); const string& err = (boost::format("Bad path: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_COPY, err.c_str(), err.length()); return; } @@ -122,9 +168,9 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Find object Store::const_iterator start = store->find(path); if (start == store->end()) { - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); const string& err = (boost::format("No such object: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_COPY, err.c_str(), err.length()); return; } @@ -132,35 +178,22 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Get serialiser SharedPtr serialiser = me->_engine.world()->serialiser; if (!serialiser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, + soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC, "No serialiser available\n", 24); return; } -#if 0 - SoupMessageHeaders* in_head = msg->request_headers; + /*SoupMessageHeaders* in_head = msg->request_headers; const char* str = soup_message_headers_get(in_head, "Accept"); - cout << "Accept: " << str << endl; -#endif + cout << "Accept: " << str << endl;*/ // Serialise object const string response = serialiser->to_string(start->second, - "http://example.org", GraphObject::Variables()); - -#if 0 - FILE* xhtml_file = fopen("/home/dave/ingen_ui.xhtml", "r"); - string response; - while (!feof(xhtml_file)) { - int c = fgetc(xhtml_file); - if (c != EOF) - response += (char)c; - } - fclose(xhtml_file); -#endif - - soup_message_set_status (msg, SOUP_STATUS_OK); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + "http://localhost:16180/patch", GraphObject::Variables()); + + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, response.c_str(), response.length()); } else if (msg->method == SOUP_METHOD_PUT) { @@ -169,26 +202,26 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Be sure object doesn't exist Store::const_iterator start = store->find(path); if (start != store->end()) { - soup_message_set_status (msg, SOUP_STATUS_CONFLICT); + soup_message_set_status(msg, SOUP_STATUS_CONFLICT); return; } // Get parser SharedPtr parser = me->_engine.world()->parser; if (!parser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } //cout << "POST: " << msg->request_body->data << endl; // Load object - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } else if (msg->method == SOUP_METHOD_POST) { //cout << "PUT: " << msg->request_body->data << endl; - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } else { - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } } diff --git a/src/engine/HTTPEngineReceiver.hpp b/src/engine/HTTPEngineReceiver.hpp index 18f0a972..07b730b0 100644 --- a/src/engine/HTTPEngineReceiver.hpp +++ b/src/engine/HTTPEngineReceiver.hpp @@ -40,6 +40,10 @@ private: struct ReceiveThread : public Raul::Thread { ReceiveThread(HTTPEngineReceiver& receiver) : _receiver(receiver) {} virtual void _run(); + virtual void whip() { + while (_receiver.unprepared_events()) + _receiver.whip(); + } private: HTTPEngineReceiver& _receiver; }; diff --git a/src/engine/NodeFactory.cpp b/src/engine/NodeFactory.cpp index 45da0a03..91f44a83 100644 --- a/src/engine/NodeFactory.cpp +++ b/src/engine/NodeFactory.cpp @@ -87,8 +87,7 @@ NodeFactory::plugin(const string& type, const string& lib, const string& label) #ifdef HAVE_LADSPA for (Plugins::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) { LADSPAPlugin* lp = dynamic_cast(i->second); - if (lp && lp->type_string() == type - && lp->library_name() == lib + if (lp && lp->library_name() == lib && lp->label() == label) return lp; } diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 95b6ec65..162f02cd 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -294,7 +294,7 @@ OSCClientSender::port_activity(const std::string& port_path) /** \page client_osc_namespace *

\b /ingen/plugin - Notification of the existance of a plugin * \arg \b uri (string) - URI of plugin (e.g. http://example.org/filtermatic) - * \arg \b type (string) - Type of plugin (e.g. "ingen:LV2Plugin") + * \arg \b type (string) - Type of plugin (e.g. "lv2:Plugin", "ingen:LADSPAPlugin") * \arg \b symbol (string) - Valid symbol for plugin (default symbol for nodes) (e.g. "adsr") * \arg \b name (string) - Descriptive human-readable name of plugin (e.g. "ADSR Envelope") */ diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index e0299556..ba3e65c1 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -120,7 +120,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); - Thread::set_name("OSC Pre-Processor"); + Thread::set_name("OSC Receiver"); } diff --git a/src/engine/PluginImpl.hpp b/src/engine/PluginImpl.hpp index 8262bf74..53275313 100644 --- a/src/engine/PluginImpl.hpp +++ b/src/engine/PluginImpl.hpp @@ -67,25 +67,6 @@ public: void load(); void unload(); - const char* type_string() const { - if (_type == LADSPA) return "LADSPA"; - else if (_type == LV2) return "LV2"; - else if (_type == Internal) return "Internal"; - else if (_type == Patch) return "Patch"; - else return ""; - } - - const string type_uri() const { - return string("ingen:").append(type_string()); - } - - void set_type(const string& type_string) { - if (type_string == "LADSPA") _type = LADSPA; - else if (type_string == "LV2") _type = LV2; - else if (type_string == "Internal") _type = Internal; - else if (type_string == "Patch") _type = Patch; - } - Plugin::Type type() const { return _type; } void type(Plugin::Type t) { _type = t; } const string& uri() const { return _uri; } diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index c6815075..5036427e 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -217,7 +217,7 @@ LoadPluginWindow::set_plugins(SharedPtr m) row[_plugins_columns._col_name] = plugin->name(); if (!strcmp(plugin->type_uri(), "ingen:Internal")) row[_plugins_columns._col_type] = "Internal"; - else if (!strcmp(plugin->type_uri(), "ingen:LV2")) + else if (!strcmp(plugin->type_uri(), "lv2:Plugin")) row[_plugins_columns._col_type] = "LV2"; else if (!strcmp(plugin->type_uri(), "ingen:LADSPA")) row[_plugins_columns._col_type] = "LADSPA"; diff --git a/src/ingen/cmdline.c b/src/ingen/cmdline.c index e8a6ab63..c9e65f5f 100644 --- a/src/ingen/cmdline.c +++ b/src/ingen/cmdline.c @@ -1,7 +1,7 @@ /* - File autogenerated by gengetopt version 2.22.1 + File autogenerated by gengetopt generated with the following command: - gengetopt -u + gengetopt -g The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -23,7 +23,7 @@ const char *gengetopt_args_info_purpose = "A modular realtime audio processing system"; -const char *gengetopt_args_info_usage = "Usage: ingen [OPTIONS]... [FILES]..."; +const char *gengetopt_args_info_usage = "Usage: ingen [OPTIONS]..."; const char *gengetopt_args_info_description = "Ingen can be run in various configurations. The engine can\nrun as a stand-alone server controlled by OSC, or internal to\nanother process (e.g. the GUI). The GUI can communicate with the engine\nvia either method, and many GUIs (or other things) may connect to an\nengine via OSC.\n\nExamples:\n\n ingen -e - Run an engine, listen for OSC \n ingen -g - Run a GUI, connect via OSC \n ingen -eg - Run an engine and a GUI in one process\n\nThe -l (load) option can be used in all cases:\n \n ingen -el patch.ingen.ttl - Run an engine and load a patch\n ingen -gl patch.ingen.ttl - Run a GUI and load a patch\n ingen -egl patch.ingen.ttl - Run an engine and a GUI and load a patch\n\nOptions:\n"; @@ -31,7 +31,7 @@ const char *gengetopt_args_info_help[] = { " -h, --help Print help and exit", " -V, --version Print version and exit", " -C, --client-port=INT Client OSC port", - " -c, --connect=STRING Connect to existing engine at OSC URI \n (default=`osc.udp://localhost:16180')", + " -c, --connect=STRING Connect to existing engine at URI \n (default=`osc.udp://localhost:16180')", " -e, --engine Run (JACK) engine (default=off)", " -E, --engine-port=INT Engine OSC port (default=`16180')", " -g, --gui Launch the GTK graphical interface (default=off)", @@ -158,9 +158,6 @@ cmdline_parser_init (struct gengetopt_args_info *args_info) clear_given (args_info); clear_args (args_info); init_args_info (args_info); - - args_info->inputs = NULL; - args_info->inputs_num = 0; } void @@ -199,7 +196,7 @@ free_string_field (char **s) static void cmdline_parser_release (struct gengetopt_args_info *args_info) { - unsigned int i; + free_string_field (&(args_info->client_port_orig)); free_string_field (&(args_info->connect_arg)); free_string_field (&(args_info->connect_orig)); @@ -215,11 +212,6 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->run_orig)); - for (i = 0; i < args_info->inputs_num; ++i) - free (args_info->inputs [i]); - - if (args_info->inputs_num) - free (args_info->inputs); clear_given (args_info); } @@ -562,7 +554,7 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf goto failure; break; - case 'c': /* Connect to existing engine at OSC URI. */ + case 'c': /* Connect to existing engine at URI. */ if (update_arg( (void *)&(args_info->connect_arg), @@ -686,30 +678,6 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf if ( error ) return (EXIT_FAILURE); - if (optind < argc) - { - int i = 0 ; - int found_prog_name = 0; - /* whether program name, i.e., argv[0], is in the remaining args - (this may happen with some implementations of getopt, - but surely not with the one included by gengetopt) */ - - i = optind; - while (i < argc) - if (argv[i++] == argv[0]) { - found_prog_name = 1; - break; - } - i = 0; - - args_info->inputs_num = argc - optind - found_prog_name; - args_info->inputs = - (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; - while (optind < argc) - if (argv[optind++] != argv[0]) - args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; - } - return 0; failure: diff --git a/src/ingen/cmdline.ggo b/src/ingen/cmdline.ggo index f639cd98..11a56455 100644 --- a/src/ingen/cmdline.ggo +++ b/src/ingen/cmdline.ggo @@ -25,7 +25,7 @@ Options: " option "client-port" C "Client OSC port" int no -option "connect" c "Connect to existing engine at OSC URI" string no default="osc.udp://localhost:16180" +option "connect" c "Connect to existing engine at URI" string no default="osc.udp://localhost:16180" option "engine" e "Run (JACK) engine" flag off option "engine-port" E "Engine OSC port" int no default="16180" option "gui" g "Launch the GTK graphical interface" flag off diff --git a/src/ingen/cmdline.h b/src/ingen/cmdline.h index ee916423..8777d391 100644 --- a/src/ingen/cmdline.h +++ b/src/ingen/cmdline.h @@ -1,6 +1,6 @@ /** @file cmdline.h * @brief The header file for the command line option parser - * generated by GNU Gengetopt version 2.22.1 + * generated by GNU Gengetopt * http://www.gnu.org/software/gengetopt. * DO NOT modify this file, since it can be overwritten * @author GNU Gengetopt by Lorenzo Bettini */ @@ -37,9 +37,9 @@ struct gengetopt_args_info int client_port_arg; /**< @brief Client OSC port. */ char * client_port_orig; /**< @brief Client OSC port original value given at command line. */ const char *client_port_help; /**< @brief Client OSC port help description. */ - char * connect_arg; /**< @brief Connect to existing engine at OSC URI (default='osc.udp://localhost:16180'). */ - char * connect_orig; /**< @brief Connect to existing engine at OSC URI original value given at command line. */ - const char *connect_help; /**< @brief Connect to existing engine at OSC URI help description. */ + char * connect_arg; /**< @brief Connect to existing engine at URI (default='osc.udp://localhost:16180'). */ + char * connect_orig; /**< @brief Connect to existing engine at URI original value given at command line. */ + const char *connect_help; /**< @brief Connect to existing engine at URI help description. */ int engine_flag; /**< @brief Run (JACK) engine (default=off). */ const char *engine_help; /**< @brief Run (JACK) engine help description. */ int engine_port_arg; /**< @brief Engine OSC port (default='16180'). */ @@ -76,8 +76,6 @@ struct gengetopt_args_info unsigned int path_given ; /**< @brief Whether path was given. */ unsigned int run_given ; /**< @brief Whether run was given. */ - char **inputs ; /**< @brief unamed options (options without names) */ - unsigned inputs_num ; /**< @brief unamed options number */ } ; /** @brief The additional parameters to pass to parser functions */ diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 3945c379..b9f52652 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -42,12 +42,15 @@ namespace Serialisation { Glib::ustring Parser::uri_relative_to_base(Glib::ustring base, const Glib::ustring uri) { + //cout << "BASE: " << base << endl; base = base.substr(0, base.find_last_of("/")+1); + //cout << uri << " RELATIVE TO " << base << endl; Glib::ustring ret; - if (uri.length() > base.length() && uri.substr(0, base.length()) == base) + if (uri.length() >= base.length() && uri.substr(0, base.length()) == base) ret = uri.substr(base.length()); else ret = uri; + //cout << " => " << ret << endl; return ret; } @@ -126,13 +129,18 @@ Parser::parse( else query_str = Glib::ustring("SELECT DISTINCT ?subject ?class WHERE { ?subject a ?class . }"); + cout << "QUERY: " << query_str << endl; + Redland::Query query(*world->rdf_world, query_str); Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); const Redland::Node patch_class(*world->rdf_world, res, NS_INGEN "Patch"); const Redland::Node node_class(*world->rdf_world, res, NS_INGEN "Node"); + const Redland::Node internal_class(*world->rdf_world, res, NS_INGEN "Internal"); + const Redland::Node ladspa_class(*world->rdf_world, res, NS_INGEN "LADSPAPlugin"); const Redland::Node in_port_class(*world->rdf_world, res, NS_LV2 "InputPort"); const Redland::Node out_port_class(*world->rdf_world, res, NS_LV2 "OutputPort"); + const Redland::Node lv2_class(*world->rdf_world, res, NS_LV2 "Plugin"); string subject_str = ((object_uri && object_uri.get() != "") ? object_uri.get() : base_uri); if (subject_str[0] == '/') @@ -143,39 +151,43 @@ Parser::parse( const Redland::Node subject_uri(*world->rdf_world, res, subject_str); bool ret = false; + std::string path_str; for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { const Redland::Node& subject = (object_uri ? subject_uri : (*i)["subject"]); const Redland::Node& rdf_class = (*i)["class"]; + //cout << "SUBJECT: " << subject.to_c_string() << endl; if (!object_uri) { - std::string path_str = uri_relative_to_base(base_uri, subject.to_c_string()); + path_str = uri_relative_to_base(base_uri, subject.to_c_string()); + //cout << "BASE: " << base_uri.c_str() << endl; + //cout << "PATH: " << path_str.c_str() << endl; if (path_str[0] != '/') path_str = string("/").append(path_str); - if (Path(path_str).parent() != "/") + if (!Path::is_valid(path_str)) { + //cerr << "INVALID PATH: " << path_str << endl; + } else if (Path(path_str).parent() != "/") { continue; + } } - if (rdf_class == patch_class || rdf_class == node_class || - rdf_class == in_port_class || rdf_class == out_port_class) { - Raul::Path path("/"); - if (base_uri != subject.to_c_string()) { - string path_str = (string)uri_relative_to_base(base_uri, subject.to_c_string()); - if (path_str[0] != '/') - path_str = string("/").append(path_str); - if (Path::is_valid(path_str)) { - path = path_str; - } else { - cerr << "[Parser] ERROR: Invalid path '" << path << "'" << endl; - continue; - } - } + const bool is_plugin = (rdf_class == ladspa_class) + || (rdf_class == lv2_class) + || (rdf_class == internal_class); + + const bool is_object = (rdf_class == patch_class) + || (rdf_class == node_class) + || (rdf_class == in_port_class) + || (rdf_class == out_port_class); + + if (is_object) { + Raul::Path path(path_str == "" ? "/" : path_str); if (path.parent() != "/") continue; if (rdf_class == patch_class) { ret = parse_patch(world, target, model, base_uri, engine_base, - subject.to_c_string(), data); + path_str, data); if (ret) target->set_variable(path, "ingen:document", Atom(base_uri.c_str())); } else if (rdf_class == node_class) { @@ -184,11 +196,18 @@ Parser::parse( } else if (rdf_class == in_port_class || rdf_class == out_port_class) { ret = parse_port(world, target, model, base_uri, Glib::ustring("<") + subject.to_c_string() + ">", path, data); - } + } else if (rdf_class == ladspa_class || rdf_class == lv2_class || rdf_class == internal_class) if (ret == false) { cerr << "Failed to parse object " << object_uri << endl; return ret; } + } else if (is_plugin) { + if (path_str.length() > 0) { + const string uri = path_str.substr(1); + cout << "PLUGIN: " << uri << endl; + } else { + cout << "ERROR: Plugin with no URI parsed, ignoring" << endl; + } } } diff --git a/src/serialisation/Parser.hpp b/src/serialisation/Parser.hpp index 9d1314fe..d20e4345 100644 --- a/src/serialisation/Parser.hpp +++ b/src/serialisation/Parser.hpp @@ -116,7 +116,6 @@ private: const Glib::ustring& base_uri, const Glib::ustring& subject, const Raul::Path& parent); - }; diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index cb9e36e4..9e8623a3 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -372,16 +372,16 @@ Serialiser::serialise_patch(SharedPtr patch) void -Serialiser::serialise_plugin(SharedPtr plugin) +Serialiser::serialise_plugin(const Shared::Plugin& plugin) { assert(_model); - const Redland::Node plugin_id = Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin->uri()); + const Redland::Node plugin_id = Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin.uri()); _model->add_statement( plugin_id, "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin->type_uri())); + Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin.type_uri())); } diff --git a/src/serialisation/Serialiser.hpp b/src/serialisation/Serialiser.hpp index 58cad912..4d33d771 100644 --- a/src/serialisation/Serialiser.hpp +++ b/src/serialisation/Serialiser.hpp @@ -66,6 +66,7 @@ public: void start_to_string(const Raul::Path& root, const std::string& base_uri); void serialise(SharedPtr object) throw (std::logic_error); + void serialise_plugin(const Shared::Plugin& p); void serialise_connection(SharedPtr parent, SharedPtr c) throw (std::logic_error); @@ -78,8 +79,6 @@ private: void setup_prefixes(); - void serialise_plugin(SharedPtr p); - void serialise_patch(SharedPtr p); void serialise_node(SharedPtr n, const Redland::Node& id); void serialise_port(const Shared::Port* p, const Redland::Node& id); -- cgit v1.2.1