From b853b3dde1f7028dd275f78433a6ad9b5b9f61c7 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 8 Sep 2006 23:15:42 +0000 Subject: More cleanups git-svn-id: http://svn.drobilla.net/lad/ingen@122 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/interface/ClientInterface.h | 2 + src/common/interface/EngineInterface.h | 7 + src/libs/client/DirectSigClientInterface.h | 38 +-- src/libs/client/Makefile.am | 2 +- src/libs/client/ModelEngineInterface.h | 13 +- src/libs/client/OSCClientReceiver.cpp | 11 + src/libs/client/OSCClientReceiver.h | 1 + src/libs/client/OSCEngineSender.cpp | 114 +++++-- src/libs/client/OSCEngineSender.h | 10 +- src/libs/client/OSCModelEngineInterface.cpp | 366 ----------------------- src/libs/client/OSCModelEngineInterface.h | 85 +----- src/libs/client/SigClientInterface.h | 59 +--- src/libs/client/Store.cpp | 27 +- src/libs/client/Store.h | 12 +- src/libs/client/ThreadedSigClientInterface.h | 100 +++---- src/libs/engine/OSCClientSender.cpp | 9 + src/libs/engine/OSCClientSender.h | 2 + src/libs/engine/OSCResponder.cpp | 4 +- src/progs/demolition/DemolitionClientInterface.h | 2 + src/progs/ingenuity/App.cpp | 62 ++-- src/progs/ingenuity/App.h | 51 ++-- src/progs/ingenuity/ConnectWindow.cpp | 46 ++- src/progs/ingenuity/ConnectWindow.h | 35 ++- src/progs/ingenuity/Controller.cpp | 11 +- src/progs/ingenuity/Controller.h | 2 +- src/progs/ingenuity/LoadPluginWindow.cpp | 8 +- src/progs/ingenuity/PatchWindow.cpp | 2 +- src/progs/ingenuity/RenameWindow.cpp | 3 +- src/progs/ingenuity/main.cpp | 7 +- src/progs/patch_loader/patch_loader.cpp | 22 +- 30 files changed, 381 insertions(+), 732 deletions(-) delete mode 100644 src/libs/client/OSCModelEngineInterface.cpp diff --git a/src/common/interface/ClientInterface.h b/src/common/interface/ClientInterface.h index eac8e605..dcc709d6 100644 --- a/src/common/interface/ClientInterface.h +++ b/src/common/interface/ClientInterface.h @@ -35,6 +35,8 @@ public: virtual ~ClientInterface() {} + virtual void response(int32_t id, bool success, const string& msg) = 0; + virtual void bundle_begin() = 0; virtual void bundle_end() = 0; diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h index 864e1b6f..7dc996dc 100644 --- a/src/common/interface/EngineInterface.h +++ b/src/common/interface/EngineInterface.h @@ -63,6 +63,13 @@ public: const string& plugin_type, const string& plugin_uri, bool polyphonic) = 0; + + /** DEPRECATED */ + virtual void create_node(const string& path, + const string& plugin_type, + const string& library_name, + const string& plugin_label, + bool polyphonic) = 0; virtual void rename(const string& old_path, const string& new_name) = 0; diff --git a/src/libs/client/DirectSigClientInterface.h b/src/libs/client/DirectSigClientInterface.h index d57771cd..fe131188 100644 --- a/src/libs/client/DirectSigClientInterface.h +++ b/src/libs/client/DirectSigClientInterface.h @@ -50,61 +50,61 @@ private: // ClientInterface function implementations to drive SigClientInterface signals virtual void bundle_begin() - { emit_bundle_begin(); } + { bundle_begin_sig.emit(); } virtual void bundle_end() - { emit_bundle_end(); } + { bundle_end_sig.emit(); } virtual void error(const string& msg) - { emit_error(msg); } + { error_sig.emit(msg); } virtual void num_plugins(uint32_t num) - { emit_num_plugins(num); } + { num_plugins_sig.emit(num); } virtual void new_plugin(const string& type, const string& uri, const string& name) - { emit_new_plugin(type, uri, name); } + { new_plugin_sig.emit(type, uri, name); } virtual void new_patch(const string& path, uint32_t poly) - { emit_new_patch(path, poly); } + { new_patch_sig.emit(path, poly); } virtual void new_node(const string& plugin_type, const string& plugin_uri, const string& node_path, bool is_polyphonic, uint32_t num_ports) - { emit_new_node(plugin_type, plugin_uri, node_path, is_polyphonic, num_ports); } + { new_node_sig.emit(plugin_type, plugin_uri, node_path, is_polyphonic, num_ports); } virtual void new_port(const string& path, const string& data_type, bool is_output) - { emit_new_port(path, data_type, is_output); } + { new_port_sig.emit(path, data_type, is_output); } virtual void patch_enabled(const string& path) - { emit_patch_enabled(path); } + { patch_enabled_sig.emit(path); } virtual void patch_disabled(const string& path) - { emit_patch_disabled(path); } + { patch_disabled_sig.emit(path); } virtual void patch_cleared(const string& path) - { emit_patch_cleared(path); } + { patch_cleared_sig.emit(path); } virtual void object_renamed(const string& old_path, const string& new_path) - { emit_object_renamed(old_path, new_path); } + { object_renamed_sig.emit(old_path, new_path); } virtual void object_destroyed(const string& path) - { emit_object_destroyed(path); } + { object_destroyed_sig.emit(path); } virtual void connection(const string& src_port_path, const string& dst_port_path) - { emit_connection(src_port_path, dst_port_path); } + { connection_sig.emit(src_port_path, dst_port_path); } virtual void disconnection(const string& src_port_path, const string& dst_port_path) - { emit_disconnection(src_port_path, dst_port_path); } + { disconnection_sig.emit(src_port_path, dst_port_path); } virtual void metadata_update(const string& subject_path, const string& predicate, const string& value) - { emit_metadata_update(subject_path, predicate, value); } + { metadata_update_sig.emit(subject_path, predicate, value); } virtual void control_change(const string& port_path, float value) - { emit_control_change(port_path, value); } + { control_change_sig.emit(port_path, value); } virtual void program_add(const string& node_path, uint32_t bank, uint32_t program, const string& program_name) - { emit_program_add(node_path, bank, program, program_name); } + { program_add_sig.emit(node_path, bank, program, program_name); } virtual void program_remove(const string& node_path, uint32_t bank, uint32_t program) - { emit_program_remove(node_path, bank, program); } + { program_remove_sig.emit(node_path, bank, program); } }; diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index f8a9a1cf..effa2759 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -10,7 +10,6 @@ libomclient_la_SOURCES = \ OSCEngineSender.h \ OSCEngineSender.cpp \ OSCModelEngineInterface.h \ - OSCModelEngineInterface.cpp \ OSCClientReceiver.h \ OSCClientReceiver.cpp \ SigClientInterface.h \ @@ -18,6 +17,7 @@ libomclient_la_SOURCES = \ ThreadedSigClientInterface.h \ ThreadedSigClientInterface.cpp \ ModelEngineInterface.h \ + ModelEngineInterface.cpp \ ModelClientInterface.h \ ModelClientInterface.cpp \ PresetModel.h \ diff --git a/src/libs/client/ModelEngineInterface.h b/src/libs/client/ModelEngineInterface.h index 42b95d00..29d82d8d 100644 --- a/src/libs/client/ModelEngineInterface.h +++ b/src/libs/client/ModelEngineInterface.h @@ -22,12 +22,13 @@ #include "interface/EngineInterface.h" using std::string; -/** \defgroup IngenClient Client Library - */ +class Path; +/** \defgroup IngenClient Client Library */ namespace Ingen { namespace Client { +class ObjectModel; class NodeModel; class PresetModel; class PatchModel; @@ -42,11 +43,11 @@ class ModelEngineInterface : public virtual Shared::EngineInterface public: virtual ~ModelEngineInterface() {} - virtual void create_patch_from_model(const PatchModel* pm) = 0; - virtual void create_node_from_model(const NodeModel* nm) = 0; + virtual void create_patch_from_model(const PatchModel* pm); + virtual void create_node_from_model(const NodeModel* nm); - virtual void set_all_metadata(const NodeModel* nm) = 0; - virtual void set_preset(const string& patch_path, const PresetModel* pm) = 0; + virtual void set_all_metadata(const ObjectModel* nm); + virtual void set_preset(const Path& patch_path, const PresetModel* pm); protected: ModelEngineInterface() {} diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index 56d8ea14..1d52caa3 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -141,6 +141,7 @@ OSCClientReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv void OSCClientReceiver::setup_callbacks() { + lo_server_thread_add_method(_st, "/om/response", "iis", response_cb, this); lo_server_thread_add_method(_st, "/om/num_plugins", "i", num_plugins_cb, this); lo_server_thread_add_method(_st, "/om/plugin", "sss", plugin_cb, this); lo_server_thread_add_method(_st, "/om/new_patch", "si", new_patch_cb, this); @@ -358,6 +359,16 @@ OSCClientReceiver::m_control_change_cb(const char* path, const char* types, lo_a } +int +OSCClientReceiver::m_response_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) +{ + assert(!strcmp(types, "iis")); + response(argv[0]->i, argv[1]->i, &argv[2]->s); + + return 0; +} + + /** Number of plugins in engine, should precede /om/plugin messages in response * to a /om/send_plugins */ diff --git a/src/libs/client/OSCClientReceiver.h b/src/libs/client/OSCClientReceiver.h index 60fa9495..2d957a6a 100644 --- a/src/libs/client/OSCClientReceiver.h +++ b/src/libs/client/OSCClientReceiver.h @@ -93,6 +93,7 @@ private: //int32_t _num_received_ports; LO_HANDLER(error); + LO_HANDLER(response); LO_HANDLER(num_plugins); LO_HANDLER(plugin); LO_HANDLER(plugin_list_end); diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp index cc70dc8e..10d9ab2e 100644 --- a/src/libs/client/OSCEngineSender.cpp +++ b/src/libs/client/OSCEngineSender.cpp @@ -14,8 +14,10 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "OSCEngineSender.h" #include "interface/ClientKey.h" +using std::cout; using std::cerr; using std::endl; namespace Ingen { namespace Client { @@ -38,6 +40,62 @@ OSCEngineSender::~OSCEngineSender() } +/** Attempt to connect to the engine (by pinging it). + * + * This doesn't register a client (or otherwise affect the client/engine state). + * To check for success wait for the ping response with id @a ping_id (using the + * relevant OSCClientReceiver). + * + * Passing a client_port of 0 will automatically choose a free port. If the + * @a block parameter is true, this function will not return until a connection + * has successfully been made. + */ +void +OSCEngineSender::attach(int32_t ping_id, bool block) +{ + cerr << "FIXME: attach\n"; + //start_listen_thread(_client_port); + + /*if (engine_url == "") { + string local_url = m_osc_listener->listen_url().substr( + 0, m_osc_listener->listen_url().find_last_of(":")); + local_url.append(":16180"); + _engine_addr = lo_address_new_from_url(local_url.c_str()); + } else { + _engine_addr = lo_address_new_from_url(engine_url.c_str()); + } + */ + _engine_addr = lo_address_new_from_url(_engine_url.c_str()); + + if (_engine_addr == NULL) { + cerr << "Unable to connect, aborting." << endl; + exit(EXIT_FAILURE); + } + + cout << "[OSCEngineSender] Attempting to contact engine at " << _engine_url << " ..." << endl; + + _id = ping_id; + this->ping(); + + /*if (block) { + set_wait_response_id(request_id); + + while (1) { + if (m_response_semaphore.try_wait() != 0) { + cout << "."; + cout.flush(); + ping(request_id); + usleep(100000); + } else { + cout << " connected." << endl; + m_waiting_for_response = false; + break; + } + } + } + */ +} + /* *** EngineInterface implementation below here *** */ @@ -103,7 +161,7 @@ OSCEngineSender::quit() void OSCEngineSender::create_patch(const string& path, - uint32_t poly) + uint32_t poly) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/create_patch", "isi", @@ -115,8 +173,8 @@ OSCEngineSender::create_patch(const string& path, void OSCEngineSender::create_port(const string& path, - const string& data_type, - bool is_output) + const string& data_type, + bool is_output) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/create_port", "issi", @@ -129,9 +187,9 @@ OSCEngineSender::create_port(const string& path, void OSCEngineSender::create_node(const string& path, - const string& plugin_type, - const string& plugin_uri, - bool polyphonic) + const string& plugin_type, + const string& plugin_uri, + bool polyphonic) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/create_node", "isssi", @@ -143,9 +201,31 @@ OSCEngineSender::create_node(const string& path, } +/** Create a node using library name and plugin label (DEPRECATED). + * + * DO NOT USE THIS. + */ +void +OSCEngineSender::create_node(const string& path, + const string& plugin_type, + const string& library_name, + const string& plugin_label, + bool polyphonic) +{ + assert(_engine_addr); + lo_send(_engine_addr, "/om/synth/create_node", "issssi", + next_id(), + path.c_str(), + plugin_type.c_str(), + library_name.c_str(), + plugin_label.c_str(), + (polyphonic ? 1 : 0)); +} + + void OSCEngineSender::rename(const string& old_path, - const string& new_name) + const string& new_name) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/rename", "iss", @@ -197,7 +277,7 @@ OSCEngineSender::disable_patch(const string& patch_path) void OSCEngineSender::connect(const string& src_port_path, - const string& dst_port_path) + const string& dst_port_path) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/connect", "iss", @@ -209,7 +289,7 @@ OSCEngineSender::connect(const string& src_port_path, void OSCEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) + const string& dst_port_path) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/disconnect", "iss", @@ -231,7 +311,7 @@ OSCEngineSender::disconnect_all(const string& node_path) void OSCEngineSender::set_port_value(const string& port_path, - float val) + float val) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/set_port_value", "isf", @@ -243,8 +323,8 @@ OSCEngineSender::set_port_value(const string& port_path, void OSCEngineSender::set_port_value(const string& port_path, - uint32_t voice, - float val) + uint32_t voice, + float val) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/set_port_value", "isif", @@ -257,7 +337,7 @@ OSCEngineSender::set_port_value(const string& port_path, void OSCEngineSender::set_port_value_queued(const string& port_path, - float val) + float val) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/set_port_value_queued", "isf", @@ -269,8 +349,8 @@ OSCEngineSender::set_port_value_queued(const string& port_path, void OSCEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) + uint32_t bank, + uint32_t program) { assert(_engine_addr); lo_send(_engine_addr, @@ -293,8 +373,8 @@ OSCEngineSender::midi_learn(const string& node_path) void OSCEngineSender::set_metadata(const string& obj_path, - const string& predicate, - const string& value) + const string& predicate, + const string& value) { assert(_engine_addr); lo_send(_engine_addr, "/om/metadata/set", "isss", diff --git a/src/libs/client/OSCEngineSender.h b/src/libs/client/OSCEngineSender.h index 91e2d559..3335a91f 100644 --- a/src/libs/client/OSCEngineSender.h +++ b/src/libs/client/OSCEngineSender.h @@ -47,11 +47,13 @@ public: string engine_url() { return _engine_url; } inline size_t next_id() - { if (_id != -1) { _id = (_id == -2) ? 0 : _id+1; } return _id; } + { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } void enable_responses() { _id = 0; } void disable_responses() { _id = -1; } + void attach(int32_t ping_id, bool block); + /* *** EngineInterface implementation below here *** */ @@ -80,6 +82,12 @@ public: const string& plugin_type, const string& plugin_uri, bool polyphonic); + + void create_node(const string& path, + const string& plugin_type, + const string& library_name, + const string& plugin_label, + bool polyphonic); void rename(const string& old_path, const string& new_name); diff --git a/src/libs/client/OSCModelEngineInterface.cpp b/src/libs/client/OSCModelEngineInterface.cpp deleted file mode 100644 index 14f2fe3a..00000000 --- a/src/libs/client/OSCModelEngineInterface.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "OSCModelEngineInterface.h" -#include -#include -#include -#include -#include -#include -#include "OSCClientReceiver.h" -#include "PatchModel.h" -#include "ConnectionModel.h" -#include "PresetModel.h" -#include "ControlModel.h" -#include "NodeModel.h" -#include "PluginModel.h" - -using std::cerr; using std::cout; using std::endl; - -namespace Ingen { -namespace Client { - - -/** Construct a OSCModelEngineInterface with a user-provided ModelClientInterface object for notification - * of engine events. - */ -OSCModelEngineInterface::OSCModelEngineInterface(const string& engine_url) -: OSCEngineSender(engine_url), - m_request_id(0), - m_is_attached(false), - m_is_registered(false) - /*m_blocking(false), - m_waiting_for_response(false), - m_wait_response_id(0), - m_response_received(false), - m_wait_response_was_affirmative(false), - m_response_semaphore(0)*/ -{ -} - - -OSCModelEngineInterface::~OSCModelEngineInterface() -{ - detach(); -} - - -/** Attempt to connect to the engine and notify it of our existance. - * - * Passing a client_port of 0 will automatically choose a free port. If the - * @a block parameter is true, this function will not return until a connection - * has successfully been made. - */ -void -OSCModelEngineInterface::attach(bool block) -{ - cerr << "FIXME: listen thread\n"; - //start_listen_thread(_client_port); - - /*if (engine_url == "") { - string local_url = m_osc_listener->listen_url().substr( - 0, m_osc_listener->listen_url().find_last_of(":")); - local_url.append(":16180"); - _engine_addr = lo_address_new_from_url(local_url.c_str()); - } else { - _engine_addr = lo_address_new_from_url(engine_url.c_str()); - } - */ - _engine_addr = lo_address_new_from_url(_engine_url.c_str()); - - if (_engine_addr == NULL) { - cerr << "Unable to connect, aborting." << endl; - exit(EXIT_FAILURE); - } - - char* lo_url = lo_address_get_url(_engine_addr); - cout << "[OSCModelEngineInterface] Attempting to contact engine at " << lo_url << " ..." << endl; - - this->ping(); - - m_is_attached = true; // FIXME - - /*if (block) { - set_wait_response_id(request_id); - - while (1) { - if (m_response_semaphore.try_wait() != 0) { - cout << "."; - cout.flush(); - ping(request_id); - usleep(100000); - } else { - cout << " connected." << endl; - m_waiting_for_response = false; - break; - } - } - } - */ - - free(lo_url); -} - -void -OSCModelEngineInterface::detach() -{ - m_is_attached = false; -} - -#if 0 -void -OSCModelEngineInterface::start_listen_thread(int client_port) -{ - if (m_st != NULL) - return; - - if (client_port == 0) { - m_st = lo_server_thread_new(NULL, error_cb); - } else { - char port_str[8]; - snprintf(port_str, 8, "%d", client_port); - m_st = lo_server_thread_new(port_str, error_cb); - } - - if (m_st == NULL) { - cerr << "[OSCModelEngineInterface] Could not start OSC listener. Aborting." << endl; - exit(EXIT_FAILURE); - } else { - cout << "[OSCModelEngineInterface] Started OSC listener on port " << lo_server_thread_get_port(m_st) << endl; - } - - lo_server_thread_add_method(m_st, NULL, NULL, generic_cb, NULL); - - lo_server_thread_add_method(m_st, "/om/response/ok", "i", om_response_ok_cb, this); - lo_server_thread_add_method(m_st, "/om/response/error", "is", om_response_error_cb, this); - - - m_osc_listener = new OSCListener(m_st, m_client_hooks); - m_osc_listener->setup_callbacks(); - - // Display any uncaught messages to the console - lo_server_thread_add_method(m_st, NULL, NULL, unknown_cb, NULL); - - lo_server_thread_start(m_st); -} -#endif - -///// OSC Commands ///// - - - -/** Load a node. - */ -void -OSCModelEngineInterface::create_node_from_model(const NodeModel* nm) -{ - assert(_engine_addr); - - // Load by URI - if (nm->plugin()->uri().length() > 0) { - lo_send(_engine_addr, "/om/synth/create_node", "isssi", next_id(), - nm->path().c_str(), - nm->plugin()->type_string(), - nm->plugin()->uri().c_str(), - (nm->polyphonic() ? 1 : 0)); - // Load by libname, label - } else { - //assert(nm->plugin()->lib_name().length() > 0); - assert(nm->plugin()->plug_label().length() > 0); - lo_send(_engine_addr, "/om/synth/create_node", "issssi", next_id(), - nm->path().c_str(), - nm->plugin()->type_string(), - nm->plugin()->lib_name().c_str(), - nm->plugin()->plug_label().c_str(), - (nm->polyphonic() ? 1 : 0)); - } -} - - -/** Create a patch. - */ -void -OSCModelEngineInterface::create_patch_from_model(const PatchModel* pm) -{ - assert(_engine_addr); - lo_send(_engine_addr, "/om/synth/create_patch", "isi", next_id(), pm->path().c_str(), pm->poly()); -} - - -/** Notify LASH restoring is finished */ -/* -void -OSCModelEngineInterface::lash_restore_finished() -{ - assert(_engine_addr != NULL); - int id = m_request_id++; - lo_send(_engine_addr, "/om/lash/restore_finished", "i", id); -} -*/ -#if 0 -/** Set/add a piece of metadata. - */ -void -OSCModelEngineInterface::set_metadata(const string& obj_path, - const string& key, const string& value) -{ - assert(_engine_addr != NULL); - int id = m_request_id++; - - // Deal with the "special" DSSI metadata strings - if (key.substr(0, 16) == "dssi-configure--") { - string path = "/dssi" + obj_path + "/configure"; - string dssi_key = key.substr(16); - lo_send(_engine_addr, path.c_str(), "ss", dssi_key.c_str(), value.c_str()); - } else if (key == "dssi-program") { - string path = "/dssi" + obj_path + "/program"; - string dssi_bank_str = value.substr(0, value.find("/")); - int dssi_bank = atoi(dssi_bank_str.c_str()); - string dssi_program_str = value.substr(value.find("/")+1); - int dssi_program = atoi(dssi_program_str.c_str()); - lo_send(_engine_addr, path.c_str(), "ii", dssi_bank, dssi_program); - } - - // Normal metadata - lo_send(_engine_addr, "/om/metadata/set", "isss", id, - obj_path.c_str(), key.c_str(), value.c_str()); -} -#endif - -/** Set all pieces of metadata in a NodeModel. - */ -void -OSCModelEngineInterface::set_all_metadata(const NodeModel* nm) -{ - assert(_engine_addr != NULL); - - for (map::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) - set_metadata(nm->path(), (*i).first, (*i).second.c_str()); -} - - -/** Set a preset by setting all relevant controls for a patch. - */ -void -OSCModelEngineInterface::set_preset(const string& patch_path, const PresetModel* const pm) -{ - assert(patch_path.find("//") == string::npos); - for (list::const_iterator i = pm->controls().begin(); i != pm->controls().end(); ++i) { - set_port_value_queued((*i).port_path(), (*i).value()); - usleep(1000); - } -} - - -///// Requests ///// - - -#if 0 -/** Sets the response ID to be waited for on the next call to wait_for_response() - */ - -void -OSCModelEngineInterface::set_wait_response_id(int id) -{ - assert(!m_waiting_for_response); - m_wait_response_id = id; - m_response_received = false; - m_waiting_for_response = true; -} - - -/** Waits for the response set by set_wait_response() from the server. - * - * Returns whether or not the response was positive (ie a success message) - * or negative (ie an error) - */ -bool -OSCModelEngineInterface::wait_for_response() -{ - cerr << "[OSCModelEngineInterface] Waiting for response " << m_wait_response_id << ": "; - bool ret = true; - - assert(m_waiting_for_response); - assert(!m_response_received); - - while (!m_response_received) - m_response_semaphore.wait(); - - cerr << " received." << endl; - - m_waiting_for_response = false; - ret = m_wait_response_was_affirmative; - - return ret; -} -#endif - -///// Static OSC callbacks ////// - - -//// End static callbacks, member callbacks below //// - -/* -int -OSCModelEngineInterface::m_om_response_ok_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data) -{ - assert(argc == 1 && !strcmp(types, "i")); - - // FIXME - if (!m_is_attached) - m_is_attached = true; - - if (m_waiting_for_response) { - const int request_id = argv[0]->i; - - if (request_id == m_wait_response_id) { - m_response_received = true; - m_wait_response_was_affirmative = true; - m_response_semaphore.post(); - } - } - - return 0; -} - - -int -OSCModelEngineInterface::m_om_response_error_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data) -{ - assert(argc == 2 && !strcmp(types, "is")); - - const int request_id = argv[0]->i; - const char* msg = &argv[1]->s; - - if (m_waiting_for_response) { - if (request_id == m_wait_response_id) { - m_response_received = true; - m_wait_response_was_affirmative = false; - m_response_semaphore.post(); - } - } - - cerr << "ERROR: " << msg << endl; - //if (m_client_hooks != NULL) - // m_client_hooks->error(msg); - - return 0; -} -*/ - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/OSCModelEngineInterface.h b/src/libs/client/OSCModelEngineInterface.h index f600fb8f..1ca263fa 100644 --- a/src/libs/client/OSCModelEngineInterface.h +++ b/src/libs/client/OSCModelEngineInterface.h @@ -14,99 +14,28 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef OSCCONTROLLER_H -#define OSCCONTROLLER_H +#ifndef OSCMODELENGINEINTERFACE_H +#define OSCMODELENGINEINTERFACE_H #include -#include -#include "util/Semaphore.h" -#include "interface/EngineInterface.h" #include "OSCEngineSender.h" #include "ModelEngineInterface.h" -using std::string; -/** \defgroup IngenClient Client Library - */ +using std::string; +/** \defgroup IngenClient Client Library */ namespace Ingen { namespace Client { -class NodeModel; -class PresetModel; -class PatchModel; -class ModelClientInterface; - -/** Old model-based OSC engine command interface. - * - * This is an old class from before when the well-defined interfaces between - * engine and client were defined. I've wrapped it around OSCEngineSender - * so all the common functions are implemented there, and implemented the - * remaining functions using those, for compatibility. Hopefully something - * better gets figured out and this can go away completely, but for now this - * gets the existing clients working through EngineInterface in the easiest - * way possible. This class needs to die. - * - * \ingroup IngenClient - */ class OSCModelEngineInterface : public OSCEngineSender, public ModelEngineInterface { public: - //OSCModelEngineInterface(ModelClientInterface* const client_hooks, const string& engine_url); - OSCModelEngineInterface(const string& engine_url); - ~OSCModelEngineInterface(); - - void attach(bool block = true); - void detach(); - - bool is_attached() { return m_is_attached; } - - // FIXME: reimplement - void set_wait_response_id(int32_t id) {} - bool wait_for_response() { return false; } - int get_next_request_id() { return m_request_id++; } - - /* *** Model alternatives to EngineInterface functions below *** */ - - void create_patch_from_model(const PatchModel* pm); - void create_node_from_model(const NodeModel* nm); - - void set_all_metadata(const NodeModel* nm); - void set_preset(const string& patch_path, const PresetModel* const pm); - -protected: - void start_listen_thread(); - - int m_request_id; - - bool m_is_attached; - bool m_is_registered; - /* - bool m_blocking; - bool m_waiting_for_response; - int m_wait_response_id; - bool m_response_received; - bool m_wait_response_was_affirmative; - - Semaphore m_response_semaphore; - */ -private: - // Prevent copies - OSCModelEngineInterface(const OSCModelEngineInterface& copy); - OSCModelEngineInterface& operator=(const OSCModelEngineInterface& copy); + OSCModelEngineInterface(const string& engine_url) : OSCEngineSender(engine_url) {} }; -/* -inline int -OSCModelEngineInterface::om_response_ok_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* comm) { - return ((OSCModelEngineInterface*)comm)->m_om_response_ok_cb(path, types, argv, argc, data); -} -inline int -OSCModelEngineInterface::om_response_error_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* comm) { - return ((OSCModelEngineInterface*)comm)->m_om_response_error_cb(path, types, argv, argc, data); -} -*/ + } // namespace Client } // namespace Ingen -#endif // OSCCONTROLLER_H +#endif // OSCMODELENGINEINTERFACE_H diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h index 6e14de8c..de76f9c1 100644 --- a/src/libs/client/SigClientInterface.h +++ b/src/libs/client/SigClientInterface.h @@ -39,6 +39,7 @@ public: // See the corresponding emitting functions below for parameter meanings + sigc::signal response_sig; sigc::signal bundle_begin_sig; sigc::signal bundle_end_sig; sigc::signal error_sig; @@ -59,64 +60,6 @@ public: sigc::signal program_add_sig; sigc::signal program_remove_sig; - - inline void emit_bundle_begin() - { bundle_begin_sig.emit(); } - - inline void emit_bundle_end() - { bundle_end_sig.emit(); } - - inline void emit_error(const string& msg) - { error_sig.emit(msg); } - - inline void emit_num_plugins(uint32_t num) - { num_plugins_sig.emit(num); } - - inline void emit_new_plugin(const string& type, const string& uri, const string& name) - { new_plugin_sig.emit(type, uri, name); } - - inline void emit_new_patch(const string& path, uint32_t poly) - { new_patch_sig.emit(path, poly); } - - inline void emit_new_node(const string& plugin_type, const string& plugin_uri, const string& node_path, bool is_polyphonic, uint32_t num_ports) - { new_node_sig.emit(plugin_type, plugin_uri, node_path, is_polyphonic, num_ports); } - - inline void emit_new_port(const string& path, const string& data_type, bool is_output) - { new_port_sig.emit(path, data_type, is_output); } - - inline void emit_patch_enabled(const string& path) - { patch_enabled_sig.emit(path); } - - inline void emit_patch_disabled(const string& path) - { patch_disabled_sig.emit(path); } - - inline void emit_patch_cleared(const string& path) - { patch_cleared_sig.emit(path); } - - inline void emit_object_renamed(const string& old_path, const string& new_path) - { object_renamed_sig.emit(old_path, new_path); } - - inline void emit_object_destroyed(const string& path) - { object_destroyed_sig.emit(path); } - - inline void emit_connection(const string& src_port_path, const string& dst_port_path) - { connection_sig.emit(src_port_path, dst_port_path); } - - inline void emit_disconnection(const string& src_port_path, const string& dst_port_path) - { disconnection_sig.emit(src_port_path, dst_port_path); } - - inline void emit_metadata_update(const string& subject_path, const string& predicate, const string& value) - { metadata_update_sig.emit(subject_path, predicate, value); } - - inline void emit_control_change(const string& port_path, float value) - { control_change_sig.emit(port_path, value); } - - inline void emit_program_add(const string& node_path, uint32_t bank, uint32_t program, const string& program_name) - { program_add_sig.emit(node_path, bank, program, program_name); } - - inline void emit_program_remove(const string& node_path, uint32_t bank, uint32_t program) - { program_remove_sig.emit(node_path, bank, program); } - protected: SigClientInterface() {} }; diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index 219ea13f..7fd011b7 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -27,24 +27,21 @@ namespace Ingen { namespace Client { -/// Singleton instance -Store* Store::_instance = 0; - -Store::Store(SigClientInterface& emitter) +Store::Store(CountedPtr emitter) { //emitter.new_plugin_sig.connect(sigc::mem_fun(this, &Store::add_plugin)); - emitter.object_destroyed_sig.connect(sigc::mem_fun(this, &Store::destruction_event)); - emitter.new_plugin_sig.connect(sigc::mem_fun(this, &Store::new_plugin_event)); - emitter.new_patch_sig.connect(sigc::mem_fun(this, &Store::new_patch_event)); - emitter.new_node_sig.connect(sigc::mem_fun(this, &Store::new_node_event)); - emitter.new_port_sig.connect(sigc::mem_fun(this, &Store::new_port_event)); - emitter.patch_enabled_sig.connect(sigc::mem_fun(this, &Store::patch_enabled_event)); - emitter.patch_disabled_sig.connect(sigc::mem_fun(this, &Store::patch_disabled_event)); - emitter.connection_sig.connect(sigc::mem_fun(this, &Store::connection_event)); - emitter.disconnection_sig.connect(sigc::mem_fun(this, &Store::disconnection_event)); - emitter.metadata_update_sig.connect(sigc::mem_fun(this, &Store::metadata_update_event)); - emitter.control_change_sig.connect(sigc::mem_fun(this, &Store::control_change_event)); + emitter->object_destroyed_sig.connect(sigc::mem_fun(this, &Store::destruction_event)); + emitter->new_plugin_sig.connect(sigc::mem_fun(this, &Store::new_plugin_event)); + emitter->new_patch_sig.connect(sigc::mem_fun(this, &Store::new_patch_event)); + emitter->new_node_sig.connect(sigc::mem_fun(this, &Store::new_node_event)); + emitter->new_port_sig.connect(sigc::mem_fun(this, &Store::new_port_event)); + emitter->patch_enabled_sig.connect(sigc::mem_fun(this, &Store::patch_enabled_event)); + emitter->patch_disabled_sig.connect(sigc::mem_fun(this, &Store::patch_disabled_event)); + emitter->connection_sig.connect(sigc::mem_fun(this, &Store::connection_event)); + emitter->disconnection_sig.connect(sigc::mem_fun(this, &Store::disconnection_event)); + emitter->metadata_update_sig.connect(sigc::mem_fun(this, &Store::metadata_update_event)); + emitter->control_change_sig.connect(sigc::mem_fun(this, &Store::control_change_event)); } diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h index cb6c3206..8407c9fb 100644 --- a/src/libs/client/Store.h +++ b/src/libs/client/Store.h @@ -35,12 +35,14 @@ class PatchModel; class NodeModel; class PortModel; -/** Singeton which holds all "Ingen Objects" for easy/fast lookup +/** Automatically manages models of objects in the engine. * * \ingroup IngenClient */ class Store : public sigc::trackable { // FIXME: is trackable necessary? public: + Store(CountedPtr emitter); + CountedPtr plugin(const string& uri); CountedPtr object(const string& path); /*CountedPtr patch(const string& path); @@ -53,15 +55,7 @@ public: const map >& plugins() const { return m_plugins; } - static void instantiate(SigClientInterface& emitter) - { if (!_instance) _instance = new Store(emitter); } - - inline static Store& instance() { assert(_instance); return *_instance; } - private: - Store(SigClientInterface& emitter); - - static Store* _instance; void add_object(CountedPtr object); CountedPtr remove_object(const string& path); diff --git a/src/libs/client/ThreadedSigClientInterface.h b/src/libs/client/ThreadedSigClientInterface.h index 985b1f26..afc756c4 100644 --- a/src/libs/client/ThreadedSigClientInterface.h +++ b/src/libs/client/ThreadedSigClientInterface.h @@ -44,27 +44,23 @@ class ThreadedSigClientInterface : virtual public SigClientInterface public: ThreadedSigClientInterface(uint32_t queue_size) : _sigs(queue_size) - , error_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_error)) - //, new_plugin_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_plugin_model)) - //, new_patch_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_patch_model)) - //, new_node_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_node_model)) - //, new_port_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_port_model)) - //, connection_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_connection_model)) - , new_plugin_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_plugin)) - , new_patch_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_patch)) - , new_node_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_node)) - , new_port_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_new_port)) - , connection_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_connection)) - , patch_enabled_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_patch_enabled)) - , patch_disabled_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_patch_disabled)) - , patch_cleared_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_patch_cleared)) - , object_destroyed_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_object_destroyed)) - , object_renamed_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_object_renamed)) - , disconnection_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_disconnection)) - , metadata_update_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_metadata_update)) - , control_change_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_control_change)) - , program_add_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_program_add)) - , program_remove_slot(sigc::mem_fun((SigClientInterface*)this, &SigClientInterface::emit_program_remove)) + , response_slot(response_sig.make_slot()) + , error_slot(error_sig.make_slot()) + , new_plugin_slot(new_plugin_sig.make_slot()) + , new_patch_slot(new_patch_sig.make_slot()) + , new_node_slot(new_node_sig.make_slot()) + , new_port_slot(new_port_sig.make_slot()) + , connection_slot(connection_sig.make_slot()) + , patch_enabled_slot(patch_enabled_sig.make_slot()) + , patch_disabled_slot(patch_disabled_sig.make_slot()) + , patch_cleared_slot(patch_cleared_sig.make_slot()) + , object_destroyed_slot(object_destroyed_sig.make_slot()) + , object_renamed_slot(object_renamed_sig.make_slot()) + , disconnection_slot(disconnection_sig.make_slot()) + , metadata_update_slot(metadata_update_sig.make_slot()) + , control_change_slot(control_change_sig.make_slot()) + , program_add_slot(program_add_sig.make_slot()) + , program_remove_slot(program_remove_sig.make_slot()) {} @@ -74,24 +70,12 @@ public: void num_plugins(uint32_t num) { _num_plugins = num; } + void response(int32_t id, bool success, const string& msg) + { push_sig(sigc::bind(response_slot, id, success, msg)); } + void error(const string& msg) { push_sig(sigc::bind(error_slot, msg)); } - /* - void new_plugin_model(PluginModel* const pm) - { push_sig(sigc::bind(new_plugin_slot, pm)); } - - void new_patch_model(PatchModel* const pm) - { push_sig(sigc::bind(new_patch_slot, pm)); } - - void new_node_model(NodeModel* const nm) - { assert(nm); push_sig(sigc::bind(new_node_slot, nm)); } - - void new_port_model(PortModel* const pm) - { push_sig(sigc::bind(new_port_slot, pm)); } - void connection_model(ConnectionModel* const cm) - { push_sig(sigc::bind(connection_slot, cm)); } - */ void new_plugin(const string& type, const string& uri, const string& name) { push_sig(sigc::bind(new_plugin_slot, type, uri, name)); } @@ -146,30 +130,26 @@ private: Queue _sigs; uint32_t _num_plugins; - sigc::slot bundle_begin_slot; - sigc::slot bundle_end_slot; - sigc::slot num_plugins_slot; - sigc::slot error_slot; - /*sigc::slot new_plugin_slot; - sigc::slot new_patch_slot; - sigc::slot new_node_slot; - sigc::slot new_port_slot; - sigc::slot connection_slot; */ - sigc::slot new_plugin_slot; - sigc::slot new_patch_slot; - sigc::slot new_node_slot; - sigc::slot new_port_slot; - sigc::slot connection_slot; - sigc::slot patch_enabled_slot; - sigc::slot patch_disabled_slot; - sigc::slot patch_cleared_slot; - sigc::slot object_destroyed_slot; - sigc::slot object_renamed_slot; - sigc::slot disconnection_slot; - sigc::slot metadata_update_slot; - sigc::slot control_change_slot; - sigc::slot program_add_slot; - sigc::slot program_remove_slot; + sigc::slot bundle_begin_slot; + sigc::slot bundle_end_slot; + sigc::slot num_plugins_slot; + sigc::slot response_slot; + sigc::slot error_slot; + sigc::slot new_plugin_slot; + sigc::slot new_patch_slot; + sigc::slot new_node_slot; + sigc::slot new_port_slot; + sigc::slot connection_slot; + sigc::slot patch_enabled_slot; + sigc::slot patch_disabled_slot; + sigc::slot patch_cleared_slot; + sigc::slot object_destroyed_slot; + sigc::slot object_renamed_slot; + sigc::slot disconnection_slot; + sigc::slot metadata_update_slot; + sigc::slot control_change_slot; + sigc::slot program_add_slot; + sigc::slot program_remove_slot; }; diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index d6f56e74..65fb89fe 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -78,6 +78,15 @@ namespace Ingen { */ +void +OSCClientSender::response(int32_t id, bool success, const string& msg) +{ + if (lo_send(_address, "/om/response", "iis", id, success ? 1 : 0, msg.c_str()) < 0) { + cerr << "Unable to send response " << id << "! (" + << lo_address_errstr(_address) << ")" << endl; + } +} + /** \page client_osc_namespace * \n diff --git a/src/libs/engine/OSCClientSender.h b/src/libs/engine/OSCClientSender.h index 1826a36d..8427c51a 100644 --- a/src/libs/engine/OSCClientSender.h +++ b/src/libs/engine/OSCClientSender.h @@ -62,6 +62,8 @@ public: void bundle_begin() {} void bundle_end() {} + void response(int32_t id, bool success, const string& msg); + void num_plugins(uint32_t num); void error(const string& msg); diff --git a/src/libs/engine/OSCResponder.cpp b/src/libs/engine/OSCResponder.cpp index d67342d6..50619089 100644 --- a/src/libs/engine/OSCResponder.cpp +++ b/src/libs/engine/OSCResponder.cpp @@ -56,7 +56,7 @@ OSCResponder::respond_ok() _addr = lo_address_new_from_url(_url); //cerr << "OK " << _id << endl; - if (lo_send(_addr, "/om/response/ok", "i", _id) < 0) { + if (lo_send(_addr, "/om/response", "iis", _id, 1, "") < 0) { cerr << "Unable to send response " << _id << "! (" << lo_address_errstr(_addr) << ")" << endl; } @@ -69,7 +69,7 @@ OSCResponder::respond_error(const string& msg) _addr = lo_address_new_from_url(_url); //cerr << "ERR " << _id << endl; - if (lo_send(_addr, "/om/response/error", "is",_id, msg.c_str()) < 0) { + if (lo_send(_addr, "/om/response", "iis",_id, 0, msg.c_str()) < 0) { cerr << "Unable to send response " << _id << "! (" << lo_address_errstr(_addr) << endl; } diff --git a/src/progs/demolition/DemolitionClientInterface.h b/src/progs/demolition/DemolitionClientInterface.h index 1cd85ec2..303de621 100644 --- a/src/progs/demolition/DemolitionClientInterface.h +++ b/src/progs/demolition/DemolitionClientInterface.h @@ -45,6 +45,8 @@ public: void num_plugins(uint32_t num) {} + void response(int32_t id, bool success, const string& msg) {} + // OSC thread functions void error(const string& msg); diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index 26bf50cd..1a7d7760 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -61,24 +61,26 @@ class OmPort; App* App::_instance = 0; -App::App() -: m_configuration(new Configuration()), - m_about_dialog(NULL), - m_enable_signal(true) +App::App(CountedPtr listener) +: _listener(listener), + _store(new Store(listener)), + _configuration(new Configuration()), + _about_dialog(NULL), + _enable_signal(true) { Glib::RefPtr glade_xml = GladeFactory::new_glade_reference(); - glade_xml->get_widget_derived("connect_win", m_connect_window); - //glade_xml->get_widget_derived("new_patch_win", m_new_patch_window); - //glade_xml->get_widget_derived("load_patch_win", m_load_patch_window); - glade_xml->get_widget_derived("config_win", m_config_window); - glade_xml->get_widget_derived("patch_tree_win", m_patch_tree_window); -// glade_xml->get_widget_derived("main_patches_treeview", m_objects_treeview); - glade_xml->get_widget("about_win", m_about_dialog); + glade_xml->get_widget_derived("connect_win", _connect_window); + //glade_xml->get_widget_derived("new_patch_win", _new_patch_window); + //glade_xml->get_widget_derived("load_patch_win", _load_patch_window); + glade_xml->get_widget_derived("config_win", _config_window); + glade_xml->get_widget_derived("patch_tree_win", _patch_tree_window); +// glade_xml->get_widget_derived("main_patches_treeview", _objects_treeview); + glade_xml->get_widget("about_win", _about_dialog); - m_config_window->configuration(m_configuration); + _config_window->configuration(_configuration); - glade_xml->get_widget_derived("messages_win", m_messages_window); + glade_xml->get_widget_derived("messages_win", _messages_window); } @@ -86,13 +88,19 @@ App::~App() { } +void +App::instantiate(CountedPtr& listener) +{ + if (!_instance) + _instance = new App(listener); +} void App::error_message(const string& str) { - m_messages_window->post(str); - m_messages_window->show(); - m_messages_window->raise(); + _messages_window->post(str); + _messages_window->show(); + _messages_window->raise(); } @@ -100,7 +108,7 @@ App::error_message(const string& str) bool App::idle_callback() { - m_client_hooks->process_events(); + _client_hooks->process_events(); #ifdef HAVE_LASH //if (lash_controller->enabled()) @@ -119,7 +127,7 @@ App::idle_callback() App::event_load_session() { Gtk::FileChooserDialog* dialog - = new Gtk::FileChooserDialog(*m_main_window, "Load Session", Gtk::FILE_CHOOSER_ACTION_OPEN); + = new Gtk::FileChooserDialog(*_main_window, "Load Session", Gtk::FILE_CHOOSER_ACTION_OPEN); dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); @@ -140,7 +148,7 @@ App::event_load_session() void App::event_save_session_as() { - Gtk::FileChooserDialog dialog(*m_main_window, "Save Session", Gtk::FILE_CHOOSER_ACTION_SAVE); + Gtk::FileChooserDialog dialog(*_main_window, "Save Session", Gtk::FILE_CHOOSER_ACTION_SAVE); /* Gtk::VBox* box = dialog.get_vbox(); @@ -170,9 +178,9 @@ App::event_save_session_as() if (fin.is_open()) { // File exists string msg = "File already exists! Are you sure you want to overwrite "; msg += filename + "?"; - Gtk::MessageDialog confirm_dialog(*m_main_window, + Gtk::MessageDialog confir_dialog(*m_main_window, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confirm_dialog.run() == Gtk::RESPONSE_YES) + if (confir_dialog.run() == Gtk::RESPONSE_YES) confirm = true; else confirm = false; @@ -191,14 +199,14 @@ App::event_save_session_as() void App::add_patch_window(PatchWindow* pw) { - m_windows.push_back(pw); + _windows.push_back(pw); } void App::remove_patch_window(PatchWindow* pw) { - m_windows.erase(find(m_windows.begin(), m_windows.end(), pw)); + _windows.erase(find(_windows.begin(), _windows.end(), pw)); } @@ -208,7 +216,7 @@ int App::num_open_patch_windows() { int ret = 0; - for (list::iterator i = m_windows.begin(); i != m_windows.end(); ++i) + for (list::iterator i = _windows.begin(); i != _windows.end(); ++i) if ((*i)->is_visible()) ++ret; @@ -221,15 +229,15 @@ App::disconnect() { // FIXME: this is pretty gross.. figure out the death situation better - list windows = m_windows; // make a copy + list windows = _windows; // make a copy for (list::iterator i = windows.begin(); i != windows.end(); ++i) delete (*i); - Store::instance().clear(); + _store->clear(); // PatchWindow destructor removes them from the list - assert(m_windows.size() == 0); + assert(_windows.size() == 0); } diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 1e64abe8..2d56e445 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -25,10 +25,16 @@ #include #include #include +#include using std::string; using std::map; using std::list; using std::cerr; using std::endl; -namespace Ingen { namespace Client { class PatchModel; class PluginModel; } } +namespace Ingen { namespace Client { + class PatchModel; + class PluginModel; + class Store; + class SigClientInterface; +} } using namespace Ingen::Client; /** \defgroup Ingenuity GTK Client @@ -77,40 +83,47 @@ public: int num_open_patch_windows(); - ConnectWindow* connect_window() const { return m_connect_window; } - Gtk::Dialog* about_dialog() const { return m_about_dialog; } - ConfigWindow* configuration_dialog() const { return m_config_window; } - MessagesWindow* messages_dialog() const { return m_messages_window; } - PatchTreeWindow* patch_tree() const { return m_patch_tree_window; } - Configuration* configuration() const { return m_configuration; } + ConnectWindow* connect_window() const { return _connect_window; } + Gtk::Dialog* about_dialog() const { return _about_dialog; } + ConfigWindow* configuration_dialog() const { return _config_window; } + MessagesWindow* messages_dialog() const { return _messages_window; } + PatchTreeWindow* patch_tree() const { return _patch_tree_window; } + Configuration* configuration() const { return _configuration; } + Store* store() const { return _store; } + + const CountedPtr& client() const { return _listener; } + + static void instantiate(CountedPtr& listener); - static void instantiate() { if (!_instance) _instance = new App(); } - static inline App& instance() { assert(_instance); return *_instance; } + static inline App& instance() { assert(_instance); return *_instance; } protected: - App(); + App(CountedPtr listener); static App* _instance; //bool connect_callback(); //bool idle_callback(); - Configuration* m_configuration; + CountedPtr _listener; + Store* _store; + + Configuration* _configuration; - list m_windows; + list _windows; - ConnectWindow* m_connect_window; - MessagesWindow* m_messages_window; - PatchTreeWindow* m_patch_tree_window; - ConfigWindow* m_config_window; - Gtk::Dialog* m_about_dialog; - Gtk::Button* m_engine_error_close_button; + ConnectWindow* _connect_window; + MessagesWindow* _messages_window; + PatchTreeWindow* _patch_tree_window; + ConfigWindow* _config_window; + Gtk::Dialog* _about_dialog; + Gtk::Button* _engine_error_close_button; /** Used to avoid feedback loops with (eg) process checkbutton * FIXME: Maybe this should be globally implemented at the Controller level, * disable all command sending while handling events to avoid feedback * issues with widget event callbacks? This same pattern is duplicated * too much... */ - bool m_enable_signal; + bool _enable_signal; }; diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp index f608c79c..d4027e20 100644 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ b/src/progs/ingenuity/ConnectWindow.cpp @@ -18,14 +18,15 @@ #include #include #include +#include #include "interface/ClientKey.h" -#include "interface/ClientInterface.h" #include "ThreadedSigClientInterface.h" #include "Controller.h" #include "Store.h" #include "PatchController.h" #include "PatchModel.h" #include "App.h" +using Ingen::Client::ThreadedSigClientInterface; namespace Ingenuity { @@ -33,6 +34,8 @@ namespace Ingenuity { ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) : Gtk::Dialog(cobject) , _client(NULL) +, _ping_id(-1) +, _attached(false) { xml->get_widget("connect_icon", _icon); xml->get_widget("connect_progress_bar", _progress_bar); @@ -56,13 +59,15 @@ ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr client) +ConnectWindow::start() { - _client = client; + _client = App::instance().client(); + assert(_client); resize(100, 100); show(); } + void ConnectWindow::init() { @@ -79,6 +84,7 @@ ConnectWindow::init() _progress_label->set_text(string("Disconnected")); } + void ConnectWindow::connect() { @@ -111,6 +117,8 @@ ConnectWindow::connect() void ConnectWindow::disconnect() { + _attached = false; + _progress_bar->set_fraction(0.0); _connect_button->set_sensitive(false); _disconnect_button->set_sensitive(false); @@ -124,7 +132,7 @@ ConnectWindow::disconnect() void ConnectWindow::quit() { - if (Controller::instance().is_attached()) { + if (_attached) { Gtk::MessageDialog d(*this, "This will exit Ingenuity, but the engine will " "remain running (if it is remote).\n\nAre you sure you want to quit?", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); @@ -180,22 +188,34 @@ ConnectWindow::gtk_callback() /* Connecting to engine */ if (stage == 0) { + assert(!_attached); + assert(_client); + // FIXME //assert(!Controller::instance().is_attached()); _progress_label->set_text(string("Connecting to engine at ").append( Controller::instance().engine_url()).append("...")); present(); - Controller::instance().attach(); + + _client->response_sig.connect(sigc::mem_fun(this, &ConnectWindow::response_received)); + + _ping_id = rand(); + while (_ping_id == -1) + _ping_id = rand(); + + Controller::instance().attach(_ping_id); ++stage; + + } else if (stage == 1) { - if (Controller::instance().is_attached()) { + if (_attached) { Controller::instance().activate(); ++stage; } else { const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + (now.tv_usec - last.tv_usec) * 0.001f; if (ms_since_last > 1000) { - Controller::instance().attach(); + Controller::instance().attach(_ping_id); last = now; } } @@ -222,19 +242,19 @@ ConnectWindow::gtk_callback() ++stage; } else if (stage == 4) { // Wait for first plugins message - if (Store::instance().plugins().size() > 0) { + if (App::instance().store()->plugins().size() > 0) { _progress_label->set_text(string("Receiving plugins...")); ++stage; } } else if (stage == 5) { // FIXME - /*if (Store::instance().plugins().size() < _client->num_plugins()) { + /*if (App::instance().store().plugins().size() < _client->num_plugins()) { static char buf[32]; - snprintf(buf, 32, "%zu/%zu", Store::instance().plugins().size(), + snprintf(buf, 32, "%zu/%zu", App::instance().store().plugins().size(), ThreadedSigClientInterface::instance()->num_plugins()); _progress_bar->set_text(Glib::ustring(buf)); _progress_bar->set_fraction( - Store::instance().plugins().size() / (double)_client->num_plugins()); + App::instance().store().plugins().size() / (double)_client->num_plugins()); } else {*/ _progress_bar->set_text(""); ++stage; @@ -244,8 +264,8 @@ ConnectWindow::gtk_callback() Controller::instance().request_all_objects(); ++stage; } else if (stage == 7) { - if (Store::instance().num_objects() > 0) { - CountedPtr root = Store::instance().object("/"); + if (App::instance().store()->num_objects() > 0) { + CountedPtr root = App::instance().store()->object("/"); assert(root); PatchController* root_controller = new PatchController(root); root_controller->show_patch_window(); diff --git a/src/progs/ingenuity/ConnectWindow.h b/src/progs/ingenuity/ConnectWindow.h index b553c3da..fba6b9d8 100644 --- a/src/progs/ingenuity/ConnectWindow.h +++ b/src/progs/ingenuity/ConnectWindow.h @@ -21,7 +21,8 @@ #include #include #include "util/CountedPtr.h" -#include "interface/ClientInterface.h" +#include "ThreadedSigClientInterface.h" +using Ingen::Client::SigClientInterface; namespace Ingenuity { @@ -41,7 +42,9 @@ class ConnectWindow : public Gtk::Dialog public: ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - void start(CountedPtr client); + void start(); + void response_received(int32_t id, bool, string) { if ((id) == _ping_id) _attached = true; } + private: void server_toggled(); void launch_toggled(); @@ -54,18 +57,22 @@ private: bool gtk_callback(); - CountedPtr _client; - Gtk::Image* _icon; - Gtk::ProgressBar* _progress_bar; - Gtk::Label* _progress_label; - Gtk::Entry* _url_entry; - Gtk::RadioButton* _server_radio; - Gtk::SpinButton* _port_spinbutton; - Gtk::RadioButton* _launch_radio; - Gtk::RadioButton* _internal_radio; - Gtk::Button* _disconnect_button; - Gtk::Button* _connect_button; - Gtk::Button* _quit_button; + CountedPtr _client; + + int32_t _ping_id; + bool _attached; + + Gtk::Image* _icon; + Gtk::ProgressBar* _progress_bar; + Gtk::Label* _progress_label; + Gtk::Entry* _url_entry; + Gtk::RadioButton* _server_radio; + Gtk::SpinButton* _port_spinbutton; + Gtk::RadioButton* _launch_radio; + Gtk::RadioButton* _internal_radio; + Gtk::Button* _disconnect_button; + Gtk::Button* _connect_button; + Gtk::Button* _quit_button; }; diff --git a/src/progs/ingenuity/Controller.cpp b/src/progs/ingenuity/Controller.cpp index bb7e4c9b..a007ece8 100644 --- a/src/progs/ingenuity/Controller.cpp +++ b/src/progs/ingenuity/Controller.cpp @@ -40,10 +40,11 @@ Controller::Controller(const string& engine_url) Controller::~Controller() { - if (is_attached()) { + // FIXME + //if (is_attached()) { unregister_client(ClientKey()); // FIXME - detach(); - } + //detach(); + //} delete m_loader; delete m_patch_librarian; @@ -54,9 +55,9 @@ Controller::~Controller() * See documentation OSCModelEngineInterface::attach. */ void -Controller::attach() +Controller::attach(int32_t ping_id) { - OSCModelEngineInterface::attach(false); + OSCModelEngineInterface::attach(ping_id, false); } /* diff --git a/src/progs/ingenuity/Controller.h b/src/progs/ingenuity/Controller.h index a2c1ce0d..6a855758 100644 --- a/src/progs/ingenuity/Controller.h +++ b/src/progs/ingenuity/Controller.h @@ -54,7 +54,7 @@ class Controller : public OSCModelEngineInterface public: ~Controller(); - void attach(); + void attach(int32_t ping_id); //void register_client_and_wait(); diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 9d18cec4..99fd4704 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -134,7 +134,7 @@ void LoadPluginWindow::on_show() { if (!m_has_shown) { - set_plugin_list(Store::instance().plugins()); + set_plugin_list(App::instance().store()->plugins()); // Center on patch window int m_w, m_h; @@ -341,8 +341,8 @@ LoadPluginWindow::filter_changed() size_t num_visible = 0; - for (std::map >::const_iterator i = Store::instance().plugins().begin(); - i != Store::instance().plugins().end(); ++i) { + for (std::map >::const_iterator i = App::instance().store()->plugins().begin(); + i != App::instance().store()->plugins().end(); ++i) { const CountedPtr plugin = (*i).second; @@ -390,7 +390,7 @@ void LoadPluginWindow::clear_clicked() { m_search_entry->set_text(""); - set_plugin_list(Store::instance().plugins()); + set_plugin_list(App::instance().store()->plugins()); } bool diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index ba1ed9e7..69e8f7de 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -287,7 +287,7 @@ PatchWindow::breadcrumb_clicked(BreadCrumb* crumb) // FIXME: check to be sure PatchModel exists, then controller - maybe // even make a controller if there isn't one? PatchController* const pc = dynamic_cast( - Store::instance().object(crumb->path())->controller()); + App::instance().store()->object(crumb->path())->controller()); assert(pc != NULL); if (pc == m_patch) { diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp index 5521f951..52f5bc98 100644 --- a/src/progs/ingenuity/RenameWindow.cpp +++ b/src/progs/ingenuity/RenameWindow.cpp @@ -21,6 +21,7 @@ #include "ObjectModel.h" #include "GtkObjectController.h" #include "Store.h" +#include "App.h" using std::string; namespace Ingenuity { @@ -69,7 +70,7 @@ RenameWindow::name_changed() m_message_label->set_text("Name may not contain '/'"); m_ok_button->property_sensitive() = false; //} else if (m_object->parent()->patch_model()->get_node(name) != NULL) { - } else if (Store::instance().object(m_object->model()->parent()->base_path() + name)) { + } else if (App::instance().store()->object(m_object->model()->parent()->base_path() + name)) { m_message_label->set_text("An object already exists with that name."); m_ok_button->property_sensitive() = false; } else if (name.length() == 0) { diff --git a/src/progs/ingenuity/main.cpp b/src/progs/ingenuity/main.cpp index 0c504a11..034a1c85 100644 --- a/src/progs/ingenuity/main.cpp +++ b/src/progs/ingenuity/main.cpp @@ -68,11 +68,10 @@ main(int argc, char** argv) Gnome::Canvas::init(); Gtk::Main gtk_main(argc, argv); - OSCSigEmitter* emitter = new OSCSigEmitter(1024, 16181); + CountedPtr emitter(new OSCSigEmitter(1024, 16181)); /* Instantiate all singletons */ - App::instantiate(); - Store::instantiate(*(SigClientInterface*)emitter); + App::instantiate(emitter); Controller::instantiate(engine_url); @@ -90,7 +89,7 @@ main(int argc, char** argv) LashController* lash_controller = new LashController(lash_args); #endif - App::instance().connect_window()->start(CountedPtr(emitter)); + App::instance().connect_window()->start(); gtk_main.run(); return 0; diff --git a/src/progs/patch_loader/patch_loader.cpp b/src/progs/patch_loader/patch_loader.cpp index 1161e92e..105a379c 100644 --- a/src/progs/patch_loader/patch_loader.cpp +++ b/src/progs/patch_loader/patch_loader.cpp @@ -52,21 +52,21 @@ int main(int argc, char** argv) /* **** Mr. Spock.. Engage **** */ - OSCModelEngineInterface osc_controller(engine_url); - PatchLibrarian librarian(&osc_controller); + OSCModelEngineInterface engine(engine_url); + PatchLibrarian librarian(&engine); /* Connect to engine */ - osc_controller.attach(client_port); - osc_controller.activate(); - //osc_controller.register_client(NULL); // FIXME + engine.attach(-1, client_port); + engine.activate(); + //engine.register_client(NULL); // FIXME - //int id = osc_controller.get_next_request_id(); - //osc_controller.set_wait_response_id(id); - //osc_controller.load_plugins(id); - //osc_controller.wait_for_response(); + //int id = engine.get_next_request_id(); + //engine.set_wait_response_id(id); + //engine.load_plugins(id); + //engine.wait_for_response(); /* FIXME: Make this work like this: - * osc_controller.load_plugins(); - * osc_controller.wait_for_response(); + * engine.load_plugins(); + * engine.wait_for_response(); */ // Load patches -- cgit v1.2.1