diff options
103 files changed, 936 insertions, 955 deletions
diff --git a/configure.ac b/configure.ac index 901e42e4..a819f3fd 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,8 @@ if test "$build_lash" = "yes"; then else AC_MSG_WARN([LASH not found, session support will not be built.]) fi +AC_MSG_WARN([NOTE: LASH support is not available at this time]) + AM_CONDITIONAL(WITH_LASH, [test "$build_lash" = "yes"]) # Use debugging flag? @@ -94,46 +96,40 @@ CFLAGS="$CFLAGS -pipe -fmessage-length=999" ########################################################################## -## ENGINE +## ENGINE (Universal engine options) ########################################################################## -# Check for building engine -build_engine="yes" -AC_ARG_ENABLE([engine], - AS_HELP_STRING(--enable-engine, Build engine (yes)), - [ if test x$enable_engine = xno ; then build_engine=no ; fi ]) - -# Check for building engine as an in-process jack client +# Build support for running as an in-process jack client build_in_process_engine="no" AC_ARG_ENABLE([in-process-engine], AS_HELP_STRING(--enable-in-process-engine, Build engine as an in-process Jack client (no)), [ if test x$enable_in_process_engine = xyes ; then build_in_process_engine=yes ; fi ]) -# Jack MIDI option +# Jack MIDI support build_jack_midi="no" AC_ARG_ENABLE(jack-midi, [AS_HELP_STRING(--enable-jack-midi, [Enable Jack MIDI support (no)])], [ if test x$enable_jack_midi = xyes ; then build_jack_midi=yes ; fi ]) -# ALSA option +# ALSA support build_alsa_midi="yes" AC_ARG_ENABLE(alsa-midi, [AS_HELP_STRING(--enable-alsa-midi, [Enable Alsa MIDI driver (yes)])], [ if test x$enable_alsa_midi = xno ; then build_alsa_midi=no ; fi ]) -# LV2 option +# LV2 support build_lv2="yes" AC_ARG_ENABLE(lv2, - [AS_HELP_STRING(--enable-lv2, [Enable LV2 plugin support through libslv2 (yes)])], + [AS_HELP_STRING(--enable-lv2, [Enable LV2 plugin support through libslv2 (yes) - Requires: libslv2])], [ if test x$enable_lv2 = xno ; then build_lv2=no ; fi ]) -# DSSI option +# DSSI support build_dssi="yes" AC_ARG_ENABLE(dssi, - [AS_HELP_STRING(--enable-dssi, [Enable DSSI plugin support (yes, requires Alsa)])], + [AS_HELP_STRING(--enable-dssi, [Enable DSSI plugin support (yes) - Requires: alsa])], [ if test x$enable_dssi = xno ; then build_dssi=no ; fi ]) -# LADSPA option +# LADSPA support build_ladspa="yes" AC_ARG_ENABLE(ladspa, [AS_HELP_STRING(--enable-ladspa, [Enable LADSPA plugin support (yes)])], @@ -141,11 +137,52 @@ AC_ARG_ENABLE(ladspa, if test "$build_in_process_engine" = "yes"; then - AC_DEFINE(BUILD_IN_PROCESS_ENGINE, 1, [Whether to build engine as Jack in-process client]) + AC_DEFINE(BUILD_IN_PROCESS_ENGINE, 1, [Whether to support running as a Jack in-process client]) fi -if test "$build_engine" = "yes" -o "$build_in_process_engine" = "yes"; then + +########################################################################## +## COMPONENTS (options for which components to build) +########################################################################## + +# Build unit tests? +build_unit_tests="no" +AC_ARG_ENABLE(unit-tests, + [AS_HELP_STRING(--enable-unit-tests, [Build unit tests (no) - Developers only])], + [build_unit_tests="$enableval"]) + +# Stand-alone engine (OSC controlled) +build_server="yes" +AC_ARG_ENABLE([server], + AS_HELP_STRING(--enable-server, Build OSC controlled stand-alone engine (yes)), + [ if test x$enable_server = xno ; then build_server=no ; fi ]) + +# Command-line clients +build_console_clients="yes" +AC_ARG_ENABLE([console-clients], + AS_HELP_STRING(--enable-console-clients, [Build command-line clients (yes) - Requires: libxml2, libsigc++]), + [ if test x$enable_console_clients = xno ; then build_console_clients=no ; fi ]) + +# Gtk client (Ingenuity) +build_gtk_client="yes" +AC_ARG_ENABLE([gtk-client], + AS_HELP_STRING(--enable-gtk-client, [Build GTK client, Ingenuity (true)]), + [ if test x$enable_gtk_client = xno ; then build_gtk_client=no ; fi ]) + +# Ingenuity with internal engine +monolithic_ingenuity="$build_gtk_client" +AC_ARG_ENABLE([monolithic-gtk-client], + AS_HELP_STRING(--enable-monolithic-gtk-client [Build Ingenuity with internal engine (true, if building Ingenuity)]), + [ if test x$enable_monolithic_gtk_client = xno ; then monolithic_gtk_client=no ; fi ]) + + + +########################################################################## +## SERVER +########################################################################## + +if test "$build_server" = "yes" -o "$monolothic_ingenuity"; then # Check for standard lib stuff AC_CHECK_FUNCS([posix_memalign, fesetround]) AC_CHECK_HEADERS([float.h stddef.h fenv.h]) @@ -223,16 +260,10 @@ if test "$build_engine" = "yes" -o "$build_in_process_engine" = "yes"; then fi fi - # Build unit tests? - build_unit_tests="no" - AC_ARG_ENABLE(unit-tests, - [AS_HELP_STRING(--enable-unit-tests, [Build unit tests (no)])], - [build_unit_tests="$enableval"]) - else - AC_MSG_WARN([Engine will NOT be built! (Nothing you're building produces sound)]) + AC_MSG_WARN([Engine will NOT be built! (Nothing you're building produces any sound itself)]) fi -AM_CONDITIONAL(BUILD_ENGINE, [test "$build_engine" = "yes"]) +AM_CONDITIONAL(BUILD_SERVER, [test "$build_server" = "yes"]) AM_CONDITIONAL(BUILD_IN_PROCESS_ENGINE, [test "$build_in_process_engine" = "yes"]) AM_CONDITIONAL(BUILD_UNIT_TESTS, [test "$build_unit_tests" = "yes"]) AM_CONDITIONAL(WITH_JACK_MIDI, [test "$build_jack_midi" = "yes"]) @@ -247,13 +278,8 @@ AM_CONDITIONAL(WITH_DSSI, [test "$build_dssi" = "yes"]) ## Console Clients ########################################################################## -build_console_clients="yes" -AC_ARG_ENABLE([console-clients], - AS_HELP_STRING(--enable-console-clients, Build console clients (true, requires libxml2)), - [ if test x$enable_console_clients = xno ; then build_console_clients=no ; fi ]) - if test "$build_console_clients" = "yes"; then - + # Check for libxml2 PKG_CHECK_MODULES(LXML2, libxml-2.0 >= 2.6.0) AC_SUBST(LXML2_LIBS) @@ -271,58 +297,45 @@ AM_CONDITIONAL(BUILD_CONSOLE_CLIENTS, [test "$build_console_clients" = "yes"]) ########################################################################## -## GTK Client +## GTK Client (Ingenuity) ########################################################################## -# Check for building gtk client -build_gtk_client="yes" -AC_ARG_ENABLE([gtk-client], - AS_HELP_STRING(--enable-gtk-client, Build GTK client. (true, requires console clients)), - [ if test x$enable_gtk_client = xno ; then build_gtk_client=no ; fi ]) - -if test "$build_console_clients" = "no"; then - AC_MSG_WARN([GTK client will NOT be built! (requires console clients)]) - build_gtk_client=no -fi if test "$build_gtk_client" = "yes"; then - # Checks for header files. + # Check misc. system stuff AC_CHECK_HEADERS([string.h sys/time.h unistd.h]) - - # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_TIME - - # Checks for library functions. AC_FUNC_ERROR_AT_LINE AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_STAT AC_CHECK_FUNCS([gettimeofday mkdir strcasecmp strchr strdup strtol]) - # Check for GTKMM PKG_CHECK_MODULES(GTKMM, gtkmm-2.4) AC_SUBST(GTKMM_CFLAGS) AC_SUBST(GTKMM_LIBS) - # Check for gnomecanvasmm PKG_CHECK_MODULES(GNOMECANVASMM, libgnomecanvasmm-2.6) AC_SUBST(GNOMECANVASMM_CFLAGS) AC_SUBST(GNOMECANVASMM_LIBS) - # Check for libglademm PKG_CHECK_MODULES(LIBGLADEMM, libglademm-2.4) AC_SUBST(LIBGLADEMM_CFLAGS) AC_SUBST(LIBGLADEMM_LIBS) - # Check for FlowCanvas PKG_CHECK_MODULES(FLOWCANVAS, flowcanvas >= 0.1.0) AC_SUBST(FLOWCANVAS_CFLAGS) AC_SUBST(FLOWCANVAS_LIBS) + + if test "$monolithic_ingenuity" = "yes"; then + AC_DEFINE(MONOLITHIC_INGENUITY, 1, [Whether to build an internal engine into Ingenuity]) + fi else AC_MSG_WARN([GTK client will NOT be built!]) fi AM_CONDITIONAL(BUILD_GTK_CLIENT, [test "$build_gtk_client" = "yes"]) +AM_CONDITIONAL(MONOLITHIC_INGENUITY, [test "$monolithic_ingenuity" = "yes"]) # Build client lib if anything above that depends on it is to be built AM_CONDITIONAL(BUILD_CLIENT_LIB, [test "$build_console_clients" = "yes" -o "$build_gtk_client" = "yes"]) @@ -367,6 +380,7 @@ AC_MSG_NOTICE([]) AC_MSG_NOTICE([Building console clients: $build_console_clients]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Building Ingenuity (GTK): $build_gtk_client]) +AC_MSG_NOTICE([ Monolithic: $monolithic_ingenuity]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Building with flags: $CXXFLAGS]) diff --git a/src/common/interface/ClientInterface.h b/src/common/interface/ClientInterface.h index dcc709d6..071b854e 100644 --- a/src/common/interface/ClientInterface.h +++ b/src/common/interface/ClientInterface.h @@ -35,63 +35,75 @@ public: virtual ~ClientInterface() {} - virtual void response(int32_t id, bool success, const string& msg) = 0; + virtual void response(int32_t id, bool success, string msg) = 0; + /** Bundles are a group of messages that are guaranteed to be in an + * atomic unit with guaranteed order (eg a packet). For datagram + * protocols (like UDP) there is likely an upper limit on bundle size. + */ virtual void bundle_begin() = 0; virtual void bundle_end() = 0; - virtual void error(const string& msg) = 0; + /** Transfers are 'weak' bundles. These are used to break a large group + * of similar/related messages into larger chunks (solely for communication + * efficiency). A bunch of messages in a transfer will arrive as 1 or more + * bundles (so a transfer can exceep the maximum bundle (packet) size). + */ + virtual void transfer_begin() = 0; + virtual void transfer_end() = 0; + + virtual void error(string msg) = 0; virtual void num_plugins(uint32_t num_plugins) = 0; - virtual void new_plugin(const string& type, - const string& uri, - const string& name) = 0; + virtual void new_plugin(string type, + string uri, + string name) = 0; - virtual void new_patch(const string& path, uint32_t poly) = 0; + virtual void new_patch(string path, uint32_t poly) = 0; - virtual void new_node(const string& plugin_type, - const string& plugin_uri, - const string& node_path, - bool is_polyphonic, - uint32_t num_ports) = 0; + virtual void new_node(string plugin_type, + string plugin_uri, + string node_path, + bool is_polyphonic, + uint32_t num_ports) = 0; - virtual void new_port(const string& path, - const string& data_type, - bool is_output) = 0; + virtual void new_port(string path, + string data_type, + bool is_output) = 0; - virtual void patch_enabled(const string& path) = 0; + virtual void patch_enabled(string path) = 0; - virtual void patch_disabled(const string& path) = 0; + virtual void patch_disabled(string path) = 0; - virtual void patch_cleared(const string& path) = 0; + virtual void patch_cleared(string path) = 0; - virtual void object_renamed(const string& old_path, - const string& new_path) = 0; + virtual void object_renamed(string old_path, + string new_path) = 0; - virtual void object_destroyed(const string& path) = 0; + virtual void object_destroyed(string path) = 0; - virtual void connection(const string& src_port_path, - const string& dst_port_path) = 0; + virtual void connection(string src_port_path, + string dst_port_path) = 0; - virtual void disconnection(const string& src_port_path, - const string& dst_port_path) = 0; + virtual void disconnection(string src_port_path, + string dst_port_path) = 0; - virtual void metadata_update(const string& subject_path, - const string& predicate, - const string& value) = 0; + virtual void metadata_update(string subject_path, + string predicate, + string value) = 0; - virtual void control_change(const string& port_path, - float value) = 0; + virtual void control_change(string port_path, + float value) = 0; - virtual void program_add(const string& node_path, - uint32_t bank, - uint32_t program, - const string& program_name) = 0; + virtual void program_add(string node_path, + uint32_t bank, + uint32_t program, + string program_name) = 0; - virtual void program_remove(const string& node_path, - uint32_t bank, - uint32_t program) = 0; + virtual void program_remove(string node_path, + uint32_t bank, + uint32_t program) = 0; protected: ClientInterface() {} diff --git a/src/common/interface/ClientKey.h b/src/common/interface/ClientKey.h index d53a4870..ba37ba59 100644 --- a/src/common/interface/ClientKey.h +++ b/src/common/interface/ClientKey.h @@ -42,9 +42,10 @@ public: * full incoming URL. */ enum Type { - NIL, ///< A NULL key (represents no client) - OSC_URL, ///< An OSC URL (remote host/client) - OSC_PORT ///< A local OSC port + NIL, ///< A NULL key (represents no client) + OSC_URL, ///< An OSC URL (remote host/client) + OSC_PORT, ///< A local OSC port + DIRECT ///< A direct in-process function call client }; ClientKey() @@ -53,7 +54,7 @@ public: {} ClientKey(Type type, const std::string& uri) - : _type(OSC_URL) + : _type(type) , _uri(uri) {} diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h index 7dc996dc..04d143b1 100644 --- a/src/common/interface/EngineInterface.h +++ b/src/common/interface/EngineInterface.h @@ -39,6 +39,10 @@ class EngineInterface public: virtual ~EngineInterface() {} + // Responses + virtual void set_next_response_id(int32_t id) = 0; + virtual void disable_responses() = 0; + // Client registration virtual void register_client(ClientKey key, CountedPtr<ClientInterface> client) = 0; virtual void unregister_client(ClientKey key) = 0; diff --git a/src/common/util/CountedPtr.h b/src/common/util/CountedPtr.h index 16eb0eee..c5eb2e50 100644 --- a/src/common/util/CountedPtr.h +++ b/src/common/util/CountedPtr.h @@ -87,13 +87,9 @@ public: // Fail if this is not a valid cast if (y) { -#ifdef WITH_RTTI T* const casted_y = dynamic_cast<T* const>(y._counter->ptr); -#else - T* const casted_y = static_cast<T* const>(y._counter->ptr); -#endif + if (casted_y) { - assert(casted_y == y._counter->ptr); //release(); // FIXME: leak? retain((Counter*)y._counter); assert(_counter == (Counter*)y._counter); diff --git a/src/common/util/Queue.h b/src/common/util/Queue.h index 10c7f0f5..a4c34222 100644 --- a/src/common/util/Queue.h +++ b/src/common/util/Queue.h @@ -66,6 +66,7 @@ Queue<T>::Queue(size_t size) m_size(size+1), m_objects((T*)calloc(m_size, sizeof(T))) { + assert(size > 1); } @@ -147,6 +148,7 @@ inline T& Queue<T>::pop() { assert(!is_empty()); + assert(m_size > 0); T& r = m_objects[m_front]; m_front = (m_front + 1) % (m_size); diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index effa2759..f29529e5 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = -I$(top_srcdir)/src/common -fno-exceptions -fno-rtti +AM_CXXFLAGS = -I$(top_srcdir)/src/common -fno-exceptions if BUILD_CLIENT_LIB noinst_LTLIBRARIES = libomclient.la diff --git a/src/libs/client/ModelClientInterface.cpp b/src/libs/client/ModelClientInterface.cpp index f2fcd10e..440f2a73 100644 --- a/src/libs/client/ModelClientInterface.cpp +++ b/src/libs/client/ModelClientInterface.cpp @@ -63,9 +63,9 @@ ModelClientInterface::connection_model(ConnectionModel* cm) void -ModelClientInterface::new_plugin(const string& type, - const string& uri, - const string& name) +ModelClientInterface::new_plugin(string type, + string uri, + string name) { PluginModel* plugin = new PluginModel(type, uri); plugin->name(name); @@ -75,7 +75,7 @@ ModelClientInterface::new_plugin(const string& type, void -ModelClientInterface::new_patch(const string& path, uint32_t poly) +ModelClientInterface::new_patch(string path, uint32_t poly) { PatchModel* pm = new PatchModel(path, poly); //PluginModel* pi = new PluginModel(PluginModel::Patch); @@ -86,9 +86,9 @@ ModelClientInterface::new_patch(const string& path, uint32_t poly) void -ModelClientInterface::new_node(const string& plugin_type, - const string& plugin_uri, - const string& node_path, +ModelClientInterface::new_node(string plugin_type, + string plugin_uri, + string node_path, bool is_polyphonic, uint32_t num_ports) { @@ -104,8 +104,8 @@ ModelClientInterface::new_node(const string& plugin_type, void -ModelClientInterface::new_port(const string& path, - const string& type, +ModelClientInterface::new_port(string path, + string type, bool is_output) { PortModel::Type ptype = PortModel::CONTROL; @@ -123,8 +123,8 @@ ModelClientInterface::new_port(const string& path, void -ModelClientInterface::connection(const string& src_port_path, - const string& dst_port_path) +ModelClientInterface::connection(string src_port_path, + string dst_port_path) { connection_model(new ConnectionModel(src_port_path, dst_port_path)); } diff --git a/src/libs/client/ModelClientInterface.h b/src/libs/client/ModelClientInterface.h index d4362a38..84472137 100644 --- a/src/libs/client/ModelClientInterface.h +++ b/src/libs/client/ModelClientInterface.h @@ -59,24 +59,24 @@ public: // ClientInterface functions to drive the above: - virtual void new_plugin(const string& type, - const string& uri, - const string& name); + virtual void new_plugin(string type, + string uri, + string name); - virtual void new_patch(const string& path, uint32_t poly); + virtual void new_patch(string path, uint32_t poly); - virtual void new_node(const string& plugin_type, - const string& plugin_uri, - const string& node_path, - bool is_polyphonic, - uint32_t num_ports); + virtual void new_node(string plugin_type, + string plugin_uri, + string node_path, + bool is_polyphonic, + uint32_t num_ports); - virtual void new_port(const string& path, - const string& data_type, - bool is_output); + virtual void new_port(string path, + string data_type, + bool is_output); - virtual void connection(const string& src_port_path, - const string& dst_port_path); + virtual void connection(string src_port_path, + string dst_port_path); protected: ModelClientInterface() {} diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp index 496e02db..f544e812 100644 --- a/src/libs/client/NodeModel.cpp +++ b/src/libs/client/NodeModel.cpp @@ -119,6 +119,8 @@ NodeModel::add_program(int bank, int program, const string& name) { m_banks[bank][program] = name; } + + void NodeModel::remove_program(int bank, int program) { @@ -127,5 +129,30 @@ NodeModel::remove_program(int bank, int program) m_banks.erase(bank); } + +void +NodeModel::x(float a) +{ + if (m_x != a) { + m_x = a; + char temp_buf[16]; + snprintf(temp_buf, 16, "%f", a); + set_metadata("module-x", temp_buf); + } +} + + +void +NodeModel::y(float a) +{ + if (m_y != a) { + m_y = a; + char temp_buf[16]; + snprintf(temp_buf, 16, "%f", a); + set_metadata("module-y", temp_buf); + } +} + + } // namespace Client } // namespace Ingen diff --git a/src/libs/client/NodeModel.h b/src/libs/client/NodeModel.h index 6ab6b873..2a8b6973 100644 --- a/src/libs/client/NodeModel.h +++ b/src/libs/client/NodeModel.h @@ -67,9 +67,9 @@ public: virtual bool polyphonic() const { return m_polyphonic; } void polyphonic(bool b) { m_polyphonic = b; } float x() const { return m_x; } - void x(float a) { m_x = a; } float y() const { return m_y; } - void y(float a) { m_y = a; } + void x(float a); + void y(float a); // Signals sigc::signal<void, CountedPtr<PortModel> > new_port_sig; diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index 1d52caa3..ae607af1 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -70,7 +70,7 @@ OSCClientReceiver::start() cout << "[OSCClientReceiver] Started OSC listener on port " << lo_server_thread_get_port(_st) << endl; } - // FIXME + // Print all incoming messages lo_server_thread_add_method(_st, NULL, NULL, generic_cb, NULL); //lo_server_thread_add_method(_st, "/om/response/ok", "i", om_response_ok_cb, this); diff --git a/src/libs/client/OSCEngineSender.h b/src/libs/client/OSCEngineSender.h index 3335a91f..2603667a 100644 --- a/src/libs/client/OSCEngineSender.h +++ b/src/libs/client/OSCEngineSender.h @@ -49,7 +49,7 @@ public: inline size_t next_id() { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } - void enable_responses() { _id = 0; } + void set_next_response_id(int32_t id) { _id = id; } void disable_responses() { _id = -1; } void attach(int32_t ping_id, bool block); diff --git a/src/libs/client/PatchLibrarian.h b/src/libs/client/PatchLibrarian.h index a41d47e3..cd4b4b7a 100644 --- a/src/libs/client/PatchLibrarian.h +++ b/src/libs/client/PatchLibrarian.h @@ -22,6 +22,7 @@ #include <string> #include <libxml/tree.h> #include <cassert> +#include "util/CountedPtr.h" //#include "DummyModelClientInterface.h" using std::string; @@ -46,7 +47,7 @@ class PatchLibrarian public: // FIXME: return booleans and set an errstr that can be checked or something? - PatchLibrarian(ModelEngineInterface* _engine) + PatchLibrarian(CountedPtr<ModelEngineInterface> _engine) : _patch_search_path("."), _engine(_engine) { assert(_engine); @@ -63,8 +64,8 @@ public: private: string translate_load_path(const string& path); - string _patch_search_path; - ModelEngineInterface* const _engine; + string _patch_search_path; + CountedPtr<ModelEngineInterface> _engine; /// Translations of paths from the loading file to actual paths (for deprecated patches) std::map<string, string> _load_path_translations; diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp index 5afec7ab..5b1348b2 100644 --- a/src/libs/client/PatchModel.cpp +++ b/src/libs/client/PatchModel.cpp @@ -168,7 +168,7 @@ PatchModel::add_connection(CountedPtr<ConnectionModel> cm) //assert(cm->dst_port_path().parent().parent() == m_path); assert(cm->patch_path() == path()); - cerr << "PatchModel::add_connection: " << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; + //cerr << "PatchModel::add_connection: " << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; CountedPtr<ConnectionModel> existing = get_connection(cm->src_port_path(), cm->dst_port_path()); diff --git a/src/libs/client/PortModel.h b/src/libs/client/PortModel.h index 37e312f3..3aedc639 100644 --- a/src/libs/client/PortModel.h +++ b/src/libs/client/PortModel.h @@ -47,11 +47,11 @@ public: m_hint(hint), m_default_val(default_val), m_min_val(min), - m_user_min(min), + //m_user_min(min), m_max_val(max), - m_user_max(max), + //m_user_max(max), m_current_val(default_val), - m_connected(false) + m_connections(0) { } @@ -62,26 +62,25 @@ public: m_hint(NONE), m_default_val(0.0f), m_min_val(0.0f), - m_user_min(0.0f), + //m_user_min(0.0f), m_max_val(0.0f), - m_user_max(0.0f), + //m_user_max(0.0f), m_current_val(0.0f), - m_connected(false) + m_connections(0) { } inline float min_val() const { return m_min_val; } - inline float user_min() const { return m_user_min; } - inline void user_min(float f) { m_user_min = f; } + inline float user_min() const { return atof(get_metadata("min").c_str()); } // FIXME: haaack + //inline void user_min(float f) { m_user_min = f; } inline float default_val() const { return m_default_val; } inline void default_val(float f) { m_default_val = f; } inline float max_val() const { return m_max_val; } - inline float user_max() const { return m_user_max; } - inline void user_max(float f) { m_user_max = f; } + inline float user_max() const { return atof(get_metadata("max").c_str()); } + //inline void user_max(float f) { m_user_max = f; } inline float value() const { return m_current_val; } inline void value(float f) { m_current_val = f; control_change_sig.emit(f); } - inline bool connected() { return m_connected; } - inline void connected(bool b) { m_connected = b; } + inline bool connected() { return (m_connections > 0); } inline Type type() { return m_type; } inline bool is_input() const { return (m_direction == INPUT); } @@ -96,8 +95,13 @@ public: inline bool operator==(const PortModel& pm) { return (m_path == pm.m_path); } + void connected_to(CountedPtr<PortModel> p) { ++m_connections; connection_sig.emit(p); } + void disconnected_from(CountedPtr<PortModel> p) { --m_connections; disconnection_sig.emit(p); } + // Signals - sigc::signal<void, float> control_change_sig; ///< "Control" ports only + sigc::signal<void, float> control_change_sig; ///< "Control" ports only + sigc::signal<void, CountedPtr<PortModel> > connection_sig; + sigc::signal<void, CountedPtr<PortModel> > disconnection_sig; private: // Prevent copies (undefined) @@ -109,11 +113,11 @@ private: Hint m_hint; float m_default_val; float m_min_val; - float m_user_min; + //float m_user_min; float m_max_val; - float m_user_max; + //float m_user_max; float m_current_val; - bool m_connected; + size_t m_connections; }; typedef list<CountedPtr<PortModel> > PortModelList; diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h index de76f9c1..cef7d27d 100644 --- a/src/libs/client/SigClientInterface.h +++ b/src/libs/client/SigClientInterface.h @@ -39,26 +39,26 @@ public: // See the corresponding emitting functions below for parameter meanings - sigc::signal<void, int32_t,bool,const string&> response_sig; - sigc::signal<void> bundle_begin_sig; - sigc::signal<void> bundle_end_sig; - sigc::signal<void, const string&> error_sig; - sigc::signal<void, uint32_t> num_plugins_sig; - sigc::signal<void, const string&, const string&, const string&> new_plugin_sig; - sigc::signal<void, const string&, uint32_t> new_patch_sig; - sigc::signal<void, const string&, const string&, const string&, bool, uint32_t> new_node_sig; - sigc::signal<void, const string&, const string&, bool> new_port_sig; - sigc::signal<void, const string&> patch_enabled_sig; - sigc::signal<void, const string&> patch_disabled_sig; - sigc::signal<void, const string&> patch_cleared_sig; - sigc::signal<void, const string&, const string&> object_renamed_sig; - sigc::signal<void, const string&> object_destroyed_sig; - sigc::signal<void, const string&, const string&> connection_sig; - sigc::signal<void, const string&, const string&> disconnection_sig; - sigc::signal<void, const string&, const string&, const string&> metadata_update_sig; - sigc::signal<void, const string&, float> control_change_sig; - sigc::signal<void, const string&, uint32_t, uint32_t, const string&> program_add_sig; - sigc::signal<void, const string&, uint32_t, uint32_t> program_remove_sig; + sigc::signal<void, int32_t, bool, string> response_sig; + sigc::signal<void> bundle_begin_sig; + sigc::signal<void> bundle_end_sig; + sigc::signal<void, string> error_sig; + sigc::signal<void, uint32_t> num_plugins_sig; + sigc::signal<void, string, string, string> new_plugin_sig; + sigc::signal<void, string, uint32_t> new_patch_sig; + sigc::signal<void, string, string, string, bool, uint32_t> new_node_sig; + sigc::signal<void, string, string, bool> new_port_sig; + sigc::signal<void, string> patch_enabled_sig; + sigc::signal<void, string> patch_disabled_sig; + sigc::signal<void, string> patch_cleared_sig; + sigc::signal<void, string, string> object_renamed_sig; + sigc::signal<void, string> object_destroyed_sig; + sigc::signal<void, string, string> connection_sig; + sigc::signal<void, string, string> disconnection_sig; + sigc::signal<void, string, string, string> metadata_update_sig; + sigc::signal<void, string, float> control_change_sig; + sigc::signal<void, string, uint32_t, uint32_t, string> program_add_sig; + sigc::signal<void, string, uint32_t, uint32_t> program_remove_sig; protected: SigClientInterface() {} diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index 7fd011b7..71dc06a2 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -62,7 +62,7 @@ Store::add_object(CountedPtr<ObjectModel> object) m_objects[object->path()] = object; - cout << "[Store] Added " << object->path() << endl; + //cout << "[Store] Added " << object->path() << endl; } @@ -75,7 +75,7 @@ Store::remove_object(const string& path) assert((*i).second->path() == path); CountedPtr<ObjectModel> result = (*i).second; m_objects.erase(i); - cout << "[Store] Removed " << path << endl; + //cout << "[Store] Removed " << path << endl; return result; } else { cerr << "[Store] Unable to find object " << path << " to remove." << endl; @@ -163,11 +163,11 @@ Store::port(const string& path) void Store::add_plugin(CountedPtr<PluginModel> pm) { - if (m_plugins.find(pm->uri()) != m_plugins.end()) { - cerr << "DUPE PLUGIN: " << pm->uri() << endl; - } else { + //if (m_plugins.find(pm->uri()) != m_plugins.end()) { + // cerr << "DUPE PLUGIN: " << pm->uri() << endl; + //} else { m_plugins[pm->uri()] = pm; - } + //} } @@ -363,6 +363,9 @@ Store::connection_event(const Path& src_port_path, const Path& dst_port_path) assert(src_port); assert(dst_port); + src_port->connected_to(dst_port); + dst_port->connected_to(src_port); + CountedPtr<ConnectionModel> cm = new ConnectionModel(src_port, dst_port); CountedPtr<PatchModel> patch = this->object(cm->patch_path()); @@ -385,6 +388,9 @@ Store::disconnection_event(const Path& src_port_path, const Path& dst_port_path) assert(src_port); assert(dst_port); + + src_port->disconnected_from(dst_port); + dst_port->disconnected_from(src_port); CountedPtr<ConnectionModel> cm = new ConnectionModel(src_port, dst_port); diff --git a/src/libs/client/ThreadedSigClientInterface.cpp b/src/libs/client/ThreadedSigClientInterface.cpp index dd4503e7..28719598 100644 --- a/src/libs/client/ThreadedSigClientInterface.cpp +++ b/src/libs/client/ThreadedSigClientInterface.cpp @@ -33,6 +33,7 @@ ThreadedSigClientInterface::push_sig(Closure ev) // (Very) slow busy-wait if the queue is full // FIXME: Make this wait on a signal from process_sigs iff this happens while (!success) { + //printf("push %zu\n", _sigs.fill()); success = _sigs.push(ev); if (!success) { if (first) { @@ -55,8 +56,10 @@ ThreadedSigClientInterface::emit_signals() { // Process a maximum of queue-size events, to prevent locking the GTK // thread indefinitely while processing continually arriving events + const size_t limit = _sigs.capacity(); size_t num_processed = 0; - while (!_sigs.is_empty() && num_processed++ < _sigs.capacity()/2) { + while (!_sigs.is_empty() && num_processed++ < limit) { + //printf("emit %zu\n", _sigs.fill()); Closure& ev = _sigs.pop(); ev(); ev.disconnect(); diff --git a/src/libs/client/ThreadedSigClientInterface.h b/src/libs/client/ThreadedSigClientInterface.h index afc756c4..5a677034 100644 --- a/src/libs/client/ThreadedSigClientInterface.h +++ b/src/libs/client/ThreadedSigClientInterface.h @@ -39,7 +39,7 @@ namespace Client { * function, which fires all enqueued signals up until the present. You can * use this in a GTK idle callback for receiving thread safe engine signals. */ -class ThreadedSigClientInterface : virtual public SigClientInterface +class ThreadedSigClientInterface : public SigClientInterface { public: ThreadedSigClientInterface(uint32_t queue_size) @@ -64,61 +64,66 @@ public: {} - // FIXME + // FIXME: make this insert bundle-boundary-events, where the GTK thread + // process all events between start and finish in one cycle, guaranteed + // (no more node jumping) void bundle_begin() {} void bundle_end() {} + + void transfer_begin() {} + void transfer_end() {} void num_plugins(uint32_t num) { _num_plugins = num; } - void response(int32_t id, bool success, const string& msg) + void response(int32_t id, bool success, string msg) { push_sig(sigc::bind(response_slot, id, success, msg)); } - void error(const string& msg) + void error(string msg) { push_sig(sigc::bind(error_slot, msg)); } - void new_plugin(const string& type, const string& uri, const string& name) + void new_plugin(string type, string uri, string name) { push_sig(sigc::bind(new_plugin_slot, type, uri, name)); } - void new_patch(const string& path, uint32_t poly) + void new_patch(string path, uint32_t poly) { push_sig(sigc::bind(new_patch_slot, path, poly)); } - void new_node(const string& plugin_type, const string& plugin_uri, const string& node_path, bool is_polyphonic, uint32_t num_ports) + void new_node(string plugin_type, string plugin_uri, string node_path, bool is_polyphonic, uint32_t num_ports) { push_sig(sigc::bind(new_node_slot, plugin_type, plugin_uri, node_path, is_polyphonic, num_ports)); } - void new_port(const string& path, const string& data_type, bool is_output) + void new_port(string path, string data_type, bool is_output) { push_sig(sigc::bind(new_port_slot, path, data_type, is_output)); } - void connection(const string& src_port_path, const string& dst_port_path) + void connection(string src_port_path, string dst_port_path) { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); } - void object_destroyed(const string& path) + void object_destroyed(string path) { push_sig(sigc::bind(object_destroyed_slot, path)); } - void patch_enabled(const string& path) + void patch_enabled(string path) { push_sig(sigc::bind(patch_enabled_slot, path)); } - void patch_disabled(const string& path) + void patch_disabled(string path) { push_sig(sigc::bind(patch_disabled_slot, path)); } - void patch_cleared(const string& path) + void patch_cleared(string path) { push_sig(sigc::bind(patch_cleared_slot, path)); } - void object_renamed(const string& old_path, const string& new_path) + void object_renamed(string old_path, string new_path) { push_sig(sigc::bind(object_renamed_slot, old_path, new_path)); } - void disconnection(const string& src_port_path, const string& dst_port_path) + void disconnection(string src_port_path, string dst_port_path) { push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); } - void metadata_update(const string& path, const string& key, const string& value) + void metadata_update(string path, string key, string value) { push_sig(sigc::bind(metadata_update_slot, path, key, value)); } - void control_change(const string& port_path, float value) + void control_change(string port_path, float value) { push_sig(sigc::bind(control_change_slot, port_path, value)); } - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) + void program_add(string path, uint32_t bank, uint32_t program, string name) { push_sig(sigc::bind(program_add_slot, path, bank, program, name)); } - void program_remove(const string& path, uint32_t bank, uint32_t program) + void program_remove(string path, uint32_t bank, uint32_t program) { push_sig(sigc::bind(program_remove_slot, path, bank, program)); } /** Process all queued events - Called from GTK thread to emit signals. */ diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index 355d4232..181e5a2c 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -42,9 +42,6 @@ namespace Ingen { void ClientBroadcaster::register_client(const ClientKey key, CountedPtr<ClientInterface> client) { - assert(key.type() == ClientKey::OSC_URL); - assert(key.uri() != ""); - bool found = false; for (ClientList::iterator i = _clients.begin(); i != _clients.end(); ++i) if ((*i).first == key) @@ -126,12 +123,10 @@ ClientBroadcaster::send_error(const string& msg) (*i).second->error(msg); } - -/* FIXME: Make a copy method for list and just make a copy and pass it here - * instead of this global+locking mess */ void -ClientBroadcaster::send_plugins_to(ClientInterface* client, const list<Plugin*>& plugin_list) +ClientBroadcaster::send_plugins_to(CountedPtr<ClientInterface> client, const list<Plugin*>& plugin_list) { +#if 0 // FIXME: This probably isn't actually thread safe const list<Plugin*> plugs = plugin_list; // make a copy @@ -175,6 +170,23 @@ ClientBroadcaster::send_plugins_to(ClientInterface* client, const list<Plugin*>& } for (list<lo_bundle>::const_iterator i = msgs.begin(); i != msgs.end(); ++i) lo_message_free(*i); +#endif + client->transfer_begin(); + + for (list<Plugin*>::const_iterator i = plugin_list.begin(); i != plugin_list.end(); ++i) { + const Plugin* const plugin = *i; + client->new_plugin(plugin->type_string(), plugin->uri(), plugin->name()); + } + + client->transfer_end(); +} + + +void +ClientBroadcaster::send_plugins(const list<Plugin*>& plugin_list) +{ + for (ClientList::const_iterator c = _clients.begin(); c != _clients.end(); ++c) + send_plugins_to((*c).second, plugin_list); } diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h index adc0e7e9..ed4bec4e 100644 --- a/src/libs/engine/ClientBroadcaster.h +++ b/src/libs/engine/ClientBroadcaster.h @@ -66,10 +66,11 @@ public: // Error that isn't the direct result of a request void send_error(const string& msg); - void send_plugins_to(ClientInterface* client, const list<Plugin*>& plugin_list); + //void send_node_creation_messages(const Node* const node); + void send_plugins(const list<Plugin*>& plugin_list); void send_patch(const Patch* const p); void send_node(const Node* const node); void send_port(const Port* port); @@ -85,6 +86,8 @@ public: void send_control_change(const string& port_path, float value); void send_program_add(const string& node_path, int bank, int program, const string& name); void send_program_remove(const string& node_path, int bank, int program); + + void send_plugins_to(CountedPtr<ClientInterface>, const list<Plugin*>& plugin_list); private: typedef list<pair<ClientKey, CountedPtr<ClientInterface> > > ClientList; diff --git a/src/libs/engine/DSSINode.cpp b/src/libs/engine/DSSINode.cpp index 11fda753..df94c775 100644 --- a/src/libs/engine/DSSINode.cpp +++ b/src/libs/engine/DSSINode.cpp @@ -276,7 +276,7 @@ DSSINode::update_programs(bool send_events) iter->second.find(descriptor->Program)->second != descriptor->Name) { _banks[descriptor->Bank][descriptor->Program] = descriptor->Name; if (send_events) { - _engine.client_broadcaster()->send_program_add(path(), descriptor->Bank, + _engine.broadcaster()->send_program_add(path(), descriptor->Bank, descriptor->Program, descriptor->Name); } @@ -291,7 +291,7 @@ DSSINode::update_programs(bool send_events) set_iter != to_be_deleted.end(); ++set_iter) { _banks[set_iter->first].erase(set_iter->second); if (send_events) - _engine.client_broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); + _engine.broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); if (_banks[set_iter->first].size() == 0) _banks.erase(set_iter->first); } diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp index ebe8e4f7..94f964dc 100644 --- a/src/libs/engine/Engine.cpp +++ b/src/libs/engine/Engine.cpp @@ -60,7 +60,7 @@ Engine::Engine(AudioDriver* audio_driver) #endif m_maid(new Maid(maid_queue_size)), m_post_processor(new PostProcessor(*m_maid, post_processor_queue_size)), - m_client_broadcaster(new ClientBroadcaster()), + m_broadcaster(new ClientBroadcaster()), m_object_store(new ObjectStore()), m_node_factory(new NodeFactory()), #ifdef HAVE_LASH @@ -85,7 +85,7 @@ Engine::~Engine() } delete m_object_store; - delete m_client_broadcaster; + delete m_broadcaster; delete m_node_factory; delete m_midi_driver; delete m_audio_driver; @@ -114,13 +114,7 @@ Engine::main() // Loop until quit flag is set (by OSCReceiver) while ( ! m_quit_flag) { nanosleep(&main_rate, NULL); -#ifdef HAVE_LASH - // Process any pending LASH events - if (lash_driver->enabled()) - lash_driver->process_events(); -#endif - // Run the maid (garbage collector) - m_maid->cleanup(); + main_iteration(); } cout << "[Main] Done main loop." << endl; @@ -134,6 +128,25 @@ Engine::main() } +/** Run one iteration of the main loop. + * + * NOT realtime safe (this is where deletion actually occurs) + */ +bool +Engine::main_iteration() +{ +#ifdef HAVE_LASH + // Process any pending LASH events + if (lash_driver->enabled()) + lash_driver->process_events(); +#endif + // Run the maid (garbage collector) + m_maid->cleanup(); + + return !m_quit_flag; +} + + void Engine::activate() { diff --git a/src/libs/engine/Engine.h b/src/libs/engine/Engine.h index 35192bb5..1f84d867 100644 --- a/src/libs/engine/Engine.h +++ b/src/libs/engine/Engine.h @@ -53,7 +53,8 @@ public: Engine(AudioDriver* audio_driver = 0); ~Engine(); - int main(); + int main(); + bool main_iteration(); /** Set the quit flag that should kill all threads and exit cleanly. * Note that it will take some time. */ @@ -62,6 +63,8 @@ public: void activate(); void deactivate(); + bool activated() { return m_activated; } + void set_event_source(EventSource* es) { m_event_source = es; } EventSource* event_source() const { return m_event_source; } @@ -69,7 +72,7 @@ public: MidiDriver* midi_driver() const { return m_midi_driver; } Maid* maid() const { return m_maid; } PostProcessor* post_processor() const { return m_post_processor; } - ClientBroadcaster* client_broadcaster() const { return m_client_broadcaster; } + ClientBroadcaster* broadcaster() const { return m_broadcaster; } ObjectStore* object_store() const { return m_object_store; } NodeFactory* node_factory() const { return m_node_factory; } LashDriver* lash_driver() const { return m_lash_driver; } @@ -87,7 +90,7 @@ private: MidiDriver* m_midi_driver; Maid* m_maid; PostProcessor* m_post_processor; - ClientBroadcaster* m_client_broadcaster; + ClientBroadcaster* m_broadcaster; ObjectStore* m_object_store; NodeFactory* m_node_factory; LashDriver* m_lash_driver; diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp index b01f8900..76550d0b 100644 --- a/src/libs/engine/LADSPANode.cpp +++ b/src/libs/engine/LADSPANode.cpp @@ -110,8 +110,11 @@ LADSPANode::instantiate() _ports->at(j) = port; } - assert(_ports->at(j) != NULL); - Sample default_val = default_port_value(j); + assert(port); + assert(_ports->at(j) == port); + + Sample default_val, min, max; + get_port_limits(j, default_val, min, max); // Set default value if (port->buffer_size() == 1) { @@ -119,6 +122,12 @@ LADSPANode::instantiate() } else { ((TypedPort<Sample>*)port)->set_value(0.0f, 0); } + + char tmp_buf[16]; + snprintf(tmp_buf, 16, "%f", min); + port->set_metadata("min", tmp_buf); + snprintf(tmp_buf, 16, "%f", max); + port->set_metadata("max", tmp_buf); } return true; @@ -262,12 +271,9 @@ LADSPANode::get_port_vals(ulong port_index, PortInfo* info) #endif -Sample -LADSPANode::default_port_value(ulong port_index) +void +LADSPANode::get_port_limits(unsigned long port_index, Sample& normal, Sample& lower, Sample& upper) { - LADSPA_Data normal = 0.0f; - LADSPA_Data upper = 0.0f; - LADSPA_Data lower = 0.0f; LADSPA_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor; /* set upper and lower, possibly adjusted to the sample rate */ @@ -328,10 +334,6 @@ LADSPANode::default_port_value(ulong port_index) normal = upper; } } - - cerr << path() << " Port " << port_index << " LADSPA Default value: " << normal << endl; - // FIXME: set min/max as metadata - return normal; } diff --git a/src/libs/engine/LADSPANode.h b/src/libs/engine/LADSPANode.h index 7fc78fb6..6c5d6a5d 100644 --- a/src/libs/engine/LADSPANode.h +++ b/src/libs/engine/LADSPANode.h @@ -54,7 +54,7 @@ protected: LADSPANode& operator=(const LADSPANode&); //void get_port_vals(ulong port_index, PortInfo* info); - Sample default_port_value(ulong port_index); + void get_port_limits(unsigned long port_index, Sample& default_value, Sample& lower_bound, Sample& upper_bound); const LADSPA_Descriptor* _descriptor; LADSPA_Handle* _instances; diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index 1f3b4d45..daf6db6c 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -26,6 +26,7 @@ libingen_la_SOURCES = \ OSCEngineReceiver.h \ OSCEngineReceiver.cpp \ Responder.h \ + DirectResponder.h \ OSCResponder.h \ OSCResponder.cpp \ ClientKey.h \ diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index 2532064e..abba3c33 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -84,7 +84,7 @@ void NodeBase::send_creation_messages(ClientInterface* client) const { cerr << "FIXME: send_creation\n"; - //_engine.client_broadcaster()->send_node_to(client, this); + //_engine.broadcaster()->send_node_to(client, this); } */ diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp index 7bac3bd8..9ab03a73 100644 --- a/src/libs/engine/NodeFactory.cpp +++ b/src/libs/engine/NodeFactory.cpp @@ -145,9 +145,9 @@ NodeFactory::load_plugin(const Plugin* a_plugin, // DEPRECATED: Search by lib name / plug label if (a_plugin->uri().length() == 0) { assert(a_plugin->lib_name().length() > 0 && a_plugin->plug_label().length() > 0); - cerr << "Searching for: " << a_plugin->lib_name() << " : " << a_plugin->plug_label() << endl; + //cerr << "Searching for: " << a_plugin->lib_name() << " : " << a_plugin->plug_label() << endl; for (list<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - cerr << (*i)->lib_name() << " : " << (*i)->plug_label() << endl; + //cerr << (*i)->lib_name() << " : " << (*i)->plug_label() << endl; if (a_plugin->lib_name() == (*i)->lib_name() && a_plugin->plug_label() == (*i)->plug_label()) { plugin = *i; break; @@ -155,7 +155,6 @@ NodeFactory::load_plugin(const Plugin* a_plugin, } } else { // Search by URI - cerr << "Searching for " << name << " by URI" << endl; for (list<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { if (a_plugin->uri() == (*i)->uri()) { plugin = *i; diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index 65fb89fe..068c461a 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -34,9 +34,41 @@ using std::cout; using std::cerr; using std::endl; namespace Ingen { - +void +OSCClientSender::bundle_begin() +{ + // FIXME +} + +void +OSCClientSender::bundle_end() +{ + // FIXME +} + + +void +OSCClientSender::transfer_begin() +{ + //_transfer = lo_bundle_new(LO_TT_IMMEDIATE); +} + + +void +OSCClientSender::transfer_end() +{ + /*assert(_transfer); + lo_send_bundle(_address, _transfer); + lo_bundle_free(_transfer); + _transfer = NULL;*/ +} + + /*! \page client_osc_namespace Client OSC Namespace Documentation * + * <p>NOTE: this comment doesn't really apply any longer.. sort of. + * but maybe it still should.. maybe. so it remains...</p> + * * <p>These are all the messages sent from the engine to the client. * Communication takes place over two distinct bands: control band and * notification band.</p> @@ -57,29 +89,16 @@ namespace Ingen { */ -/* Documentation for namespace portion implemented in Responder.cpp */ - -/** \page client_osc_namespace - * \n - * <h3>Notification Band</h3> - */ /** \page client_osc_namespace - * <p> \b /om/response/ok - Respond successfully to a user command - * \arg \b responder-id (int) - Responder ID this is a response to - * </p> \n \n - */ - -/** \page client_osc_namespace - * <p> \b /om/response/error - Respond negatively to a user command - * \arg \b responder-id (int) - Request ID this is a response to + * <p> \b /om/response - Respond to a user command + * \arg \b response-id (int) - Request ID this is a response to + * \arg \b success (boolean int) - Whether response is affirmative or an error * \arg \b message (string) - Error message (natural language text) * </p> \n \n */ - - void -OSCClientSender::response(int32_t id, bool success, const string& msg) +OSCClientSender::response(int32_t id, bool success, string msg) { if (lo_send(_address, "/om/response", "iis", id, success ? 1 : 0, msg.c_str()) < 0) { cerr << "Unable to send response " << id << "! (" @@ -101,7 +120,7 @@ OSCClientSender::response(int32_t id, bool success, const string& msg) * user command, ie "unexpected" errors.</p> \n \n */ void -OSCClientSender::error(const string& msg) +OSCClientSender::error(string msg) { lo_send(_address, "/om/error", "s", msg.c_str()); } @@ -198,9 +217,9 @@ OSCClientSender::plugins() * this one (/om/new_node), followed by a series of /om/new_port commands, * followed by /om/new_node_end. </p> \n \n */ -void OSCClientSender::new_node(const string& plugin_type, - const string& plugin_uri, - const string& node_path, +void OSCClientSender::new_node(string plugin_type, + string plugin_uri, + string node_path, bool is_polyphonic, uint32_t num_ports) { @@ -310,8 +329,8 @@ void OSCClientSender::new_node(const string& plugin_type, * as metadata.</p> \n \n */ void -OSCClientSender::new_port(const string& path, - const string& data_type, +OSCClientSender::new_port(string path, + string data_type, bool is_output) { //PortInfo* info = port->port_info(); @@ -330,7 +349,7 @@ OSCClientSender::new_port(const string& path, * \arg \b path (string) - Path of object (which no longer exists) </p> \n \n */ void -OSCClientSender::object_destroyed(const string& path) +OSCClientSender::object_destroyed(string path) { assert(path != "/"); @@ -343,7 +362,7 @@ OSCClientSender::object_destroyed(const string& path) * \arg \b path (string) - Path of patch (which is now empty)</p> \n \n */ void -OSCClientSender::patch_cleared(const string& patch_path) +OSCClientSender::patch_cleared(string patch_path) { lo_send(_address, "/om/patch_cleared", "s", patch_path.c_str()); } @@ -354,7 +373,7 @@ OSCClientSender::patch_cleared(const string& patch_path) * \arg \b path (string) - Path of enabled patch</p> \n \n */ void -OSCClientSender::patch_enabled(const string& patch_path) +OSCClientSender::patch_enabled(string patch_path) { lo_send(_address, "/om/patch_enabled", "s", patch_path.c_str()); } @@ -365,7 +384,7 @@ OSCClientSender::patch_enabled(const string& patch_path) * \arg \b path (string) - Path of disabled patch</p> \n \n */ void -OSCClientSender::patch_disabled(const string& patch_path) +OSCClientSender::patch_disabled(string patch_path) { lo_send(_address, "/om/patch_disabled", "s", patch_path.c_str()); } @@ -377,7 +396,7 @@ OSCClientSender::patch_disabled(const string& patch_path) * \arg \b dst-path (string) - Path of the destination port</p> \n \n */ void -OSCClientSender::connection(const string& src_port_path, const string& dst_port_path) +OSCClientSender::connection(string src_port_path, string dst_port_path) { lo_send(_address, "/om/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str()); } @@ -389,7 +408,7 @@ OSCClientSender::connection(const string& src_port_path, const string& dst_port_ * \arg \b dst-path (string) - Path of the destination port</p> \n \n */ void -OSCClientSender::disconnection(const string& src_port_path, const string& dst_port_path) +OSCClientSender::disconnection(string src_port_path, string dst_port_path) { lo_send(_address, "/om/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str()); } @@ -402,7 +421,7 @@ OSCClientSender::disconnection(const string& src_port_path, const string& dst_po * \arg \b value (string)</p> \n \n */ void -OSCClientSender::metadata_update(const string& path, const string& key, const string& value) +OSCClientSender::metadata_update(string path, string key, string value) { lo_send(_address, "/om/metadata/update", "sss", path.c_str(), key.c_str(), value.c_str()); } @@ -417,7 +436,7 @@ OSCClientSender::metadata_update(const string& path, const string& key, const st * changing because of connections to other ports!</p> \n \n */ void -OSCClientSender::control_change(const string& port_path, float value) +OSCClientSender::control_change(string port_path, float value) { lo_send(_address, "/om/control_change", "sf", port_path.c_str(), value); } @@ -430,13 +449,17 @@ OSCClientSender::control_change(const string& port_path, float value) * \arg \b name (string) - Descriptive human-readable name of plugin (ie "ADSR Envelope") */ void -OSCClientSender::new_plugin(const string& type, const string& uri, const string& name) +OSCClientSender::new_plugin(string type, string uri, string name) { lo_message m = lo_message_new(); lo_message_add_string(m, type.c_str()); lo_message_add_string(m, uri.c_str()); lo_message_add_string(m, name.c_str()); - lo_send_message(_address, "/om/plugin", m); + + //if (_transfer) + // lo_bundle_add_message(_transfer, "/om/plugin", m); + //else + lo_send_message(_address, "/om/plugin", m); } @@ -446,7 +469,7 @@ OSCClientSender::new_plugin(const string& type, const string& uri, const string& * \arg \b poly (int) - Polyphony of new patch (\em not a boolean like new_node) </p> \n \n */ void -OSCClientSender::new_patch(const string& path, uint32_t poly) +OSCClientSender::new_patch(string path, uint32_t poly) { lo_send(_address, "/om/new_patch", "si", path.c_str(), poly); @@ -469,7 +492,7 @@ OSCClientSender::new_patch(const string& path, uint32_t poly) * \arg \b new-path (string) - New path of object </p> \n \n */ void -OSCClientSender::object_renamed(const string& old_path, const string& new_path) +OSCClientSender::object_renamed(string old_path, string new_path) { lo_send(_address, "/om/object_renamed", "ss", old_path.c_str(), new_path.c_str()); } @@ -478,7 +501,7 @@ OSCClientSender::object_renamed(const string& old_path, const string& new_path) /** Sends information about a program associated with a DSSI plugin node. */ void -OSCClientSender::program_add(const string& node_path, uint32_t bank, uint32_t program, const string& name) +OSCClientSender::program_add(string node_path, uint32_t bank, uint32_t program, string name) { lo_send(_address, "/om/program_add", "siis", node_path.c_str(), bank, program, name.c_str()); @@ -486,7 +509,7 @@ OSCClientSender::program_add(const string& node_path, uint32_t bank, uint32_t pr void -OSCClientSender::program_remove(const string& node_path, uint32_t bank, uint32_t program) +OSCClientSender::program_remove(string node_path, uint32_t bank, uint32_t program) { lo_send(_address, "/om/program_remove", "sii", node_path.c_str(), bank, program); diff --git a/src/libs/engine/OSCClientSender.h b/src/libs/engine/OSCClientSender.h index 8427c51a..e2404c1a 100644 --- a/src/libs/engine/OSCClientSender.h +++ b/src/libs/engine/OSCClientSender.h @@ -17,6 +17,7 @@ #ifndef OSCCLIENTSENDER_H #define OSCCLIENTSENDER_H +#include <cassert> #include <string> #include <iostream> #include <list> @@ -40,7 +41,8 @@ class OSCClientSender : public Shared::ClientInterface public: OSCClientSender(const string& url) : _url(url), - _address(lo_address_new_from_url(url.c_str())) + _address(lo_address_new_from_url(url.c_str())), + _transfer(NULL) {} virtual ~OSCClientSender() @@ -56,66 +58,68 @@ public: /* *** ClientInterface Implementation Below *** */ - //void client_registration(const string& url, int client_id); + //void client_registration(string url, int client_id); - // need a liblo feature to make this possible :/ - void bundle_begin() {} - void bundle_end() {} + void bundle_begin(); + void bundle_end(); + + void transfer_begin(); + void transfer_end(); - void response(int32_t id, bool success, const string& msg); + void response(int32_t id, bool success, string msg); void num_plugins(uint32_t num); - void error(const string& msg); + void error(string msg); - virtual void new_plugin(const string& type, - const string& uri, - const string& name); + virtual void new_plugin(string type, + string uri, + string name); - virtual void new_patch(const string& path, uint32_t poly); + virtual void new_patch(string path, uint32_t poly); - virtual void new_node(const string& plugin_type, - const string& plugin_uri, - const string& node_path, - bool is_polyphonic, - uint32_t num_ports); + virtual void new_node(string plugin_type, + string plugin_uri, + string node_path, + bool is_polyphonic, + uint32_t num_ports); - virtual void new_port(const string& path, - const string& data_type, - bool is_output); + virtual void new_port(string path, + string data_type, + bool is_output); - virtual void patch_enabled(const string& path); + virtual void patch_enabled(string path); - virtual void patch_disabled(const string& path); + virtual void patch_disabled(string path); - virtual void patch_cleared(const string& path); + virtual void patch_cleared(string path); - virtual void object_destroyed(const string& path); + virtual void object_destroyed(string path); - virtual void object_renamed(const string& old_path, - const string& new_path); + virtual void object_renamed(string old_path, + string new_path); - virtual void connection(const string& src_port_path, - const string& dst_port_path); + virtual void connection(string src_port_path, + string dst_port_path); - virtual void disconnection(const string& src_port_path, - const string& dst_port_path); + virtual void disconnection(string src_port_path, + string dst_port_path); - virtual void metadata_update(const string& subject_path, - const string& predicate, - const string& value); + virtual void metadata_update(string subject_path, + string predicate, + string value); - virtual void control_change(const string& port_path, - float value); + virtual void control_change(string port_path, + float value); - virtual void program_add(const string& node_path, - uint32_t bank, - uint32_t program, - const string& program_name); + virtual void program_add(string node_path, + uint32_t bank, + uint32_t program, + string program_name); - virtual void program_remove(const string& node_path, - uint32_t bank, - uint32_t program); + virtual void program_remove(string node_path, + uint32_t bank, + uint32_t program); private: // Prevent copies (undefined) @@ -124,6 +128,8 @@ private: string _url; lo_address _address; + + lo_bundle _transfer; }; diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 4b1ae496..84c9f0fe 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -47,8 +47,9 @@ using Shared::ClientKey; */ -OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, const char* const port) -: QueuedEngineInterface(engine, queue_size, queue_size), // FIXME +OSCEngineReceiver::OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_size, const char* const port) +: EngineInterface(), + QueuedEngineInterface(engine, queue_size, queue_size), // FIXME _port(port), _server(NULL), _osc_responder(NULL) @@ -65,7 +66,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, const ch } // For debugging, print all incoming OSC messages - lo_server_add_method(_server, NULL, NULL, generic_cb, NULL); + //lo_server_add_method(_server, NULL, NULL, generic_cb, NULL); // Set response address for this message. // It's important this is first and returns nonzero. @@ -119,6 +120,8 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, const ch #endif lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); + + Thread::set_name("OSC Receiver"); } @@ -224,7 +227,9 @@ OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, } else { // Shitty deal, make a new one //cerr << "** Setting response address to " << url << "(2)" << endl; - me->_osc_responder = CountedPtr<OSCResponder>(new OSCResponder(id, url)); + me->_osc_responder = CountedPtr<OSCResponder>( + new OSCResponder(me->_engine->broadcaster(), id, url)); + me->set_responder(me->_osc_responder); // (responder takes ownership of url, no leak) } @@ -232,7 +237,7 @@ OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, // Otherwise we have a NULL responder, definitely need to set a new one } else { //cerr << "** null responder\n"; - me->_osc_responder = CountedPtr<OSCResponder>(new OSCResponder(id, url)); + me->_osc_responder = CountedPtr<OSCResponder>(new OSCResponder(me->_engine->broadcaster(), id, url)); me->set_responder(me->_osc_responder); //cerr << "** Setting response address to " << url << "(2)" << endl; } @@ -900,7 +905,7 @@ OSCEngineReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv string error_msg = "Unknown command: "; error_msg.append(path).append(" ").append(types); - OSCResponder(0, url).respond_error(error_msg); + OSCResponder(NULL, 0, url).respond_error(error_msg); return 0; } diff --git a/src/libs/engine/OSCEngineReceiver.h b/src/libs/engine/OSCEngineReceiver.h index cc2d7350..793286d4 100644 --- a/src/libs/engine/OSCEngineReceiver.h +++ b/src/libs/engine/OSCEngineReceiver.h @@ -20,6 +20,7 @@ #include "config.h" #include <string> #include <lo/lo.h> +#include "util/CountedPtr.h" #include "QueuedEngineInterface.h" #include "OSCResponder.h" using std::string; @@ -59,7 +60,7 @@ inline static int name##_cb(LO_HANDLER_ARGS, void* myself)\ class OSCEngineReceiver : public QueuedEngineInterface { public: - OSCEngineReceiver(Engine& engine, size_t queue_size, const char* const port); + OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_size, const char* const port); ~OSCEngineReceiver(); void activate(); diff --git a/src/libs/engine/OSCResponder.cpp b/src/libs/engine/OSCResponder.cpp index 50619089..a6d68721 100644 --- a/src/libs/engine/OSCResponder.cpp +++ b/src/libs/engine/OSCResponder.cpp @@ -30,8 +30,9 @@ namespace Ingen { /** Construct an OSCResponder from \a addr. * Takes ownership of @a url. */ -OSCResponder::OSCResponder(int32_t id, char* url) +OSCResponder::OSCResponder(ClientBroadcaster* broadcaster, int32_t id, char* url) : Responder() +, _broadcaster(broadcaster) , _id(id) , _url(url) , _addr(NULL) @@ -75,5 +76,15 @@ OSCResponder::respond_error(const string& msg) } } + +CountedPtr<ClientInterface> +OSCResponder::client() +{ + if (_broadcaster) + return _broadcaster->client(client_key()); + else + return NULL; +} + } // namespace OM diff --git a/src/libs/engine/OSCResponder.h b/src/libs/engine/OSCResponder.h index 78b40894..767375dc 100644 --- a/src/libs/engine/OSCResponder.h +++ b/src/libs/engine/OSCResponder.h @@ -24,6 +24,8 @@ namespace Ingen { +class ClientBroadcaster; + /** Responder for (liblo) OSC clients. * @@ -38,20 +40,26 @@ namespace Ingen { class OSCResponder : public Responder { public: - OSCResponder(int32_t id, char* url); + OSCResponder(ClientBroadcaster* broadcaster, int32_t id, char* url); ~OSCResponder(); + void set_id(int32_t id) { _id = id; } + void respond_ok(); void respond_error(const string& msg); const char* url() const { return _url; } ClientKey client_key() { return ClientKey(ClientKey::OSC_URL, _url); } + + CountedPtr<ClientInterface> client(); + private: - int32_t _id; - char* const _url; - lo_address _addr; + ClientBroadcaster* _broadcaster; + int32_t _id; + char* const _url; + lo_address _addr; }; diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index 257deb59..bcbe4e68 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -294,7 +294,7 @@ Patch::remove_port(const Port* port) Array<Node*>* Patch::build_process_order() const { - cerr << "*********** BUILDING PROCESS ORDER FOR " << path() << endl; + //cerr << "*********** BUILDING PROCESS ORDER FOR " << path() << endl; Array<Node*>* const process_order = new Array<Node*>(_nodes.size(), NULL); @@ -334,12 +334,14 @@ Patch::build_process_order() const } }*/ + /* cerr << "----------------------------------------\n"; for (size_t i=0; i < process_order->size(); ++i) { assert(process_order->at(i)); cerr << process_order->at(i)->path() << endl; } cerr << "----------------------------------------\n"; + */ assert(process_order->size() == _nodes.size()); diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index 4d38f91c..919d3054 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -23,7 +23,7 @@ namespace Ingen { -QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size) +QueuedEngineInterface::QueuedEngineInterface(CountedPtr<Engine> engine, size_t queued_size, size_t stamped_size) : QueuedEventSource(queued_size, stamped_size) , _responder(CountedPtr<Responder>(new Responder())) // NULL responder , _engine(engine) @@ -34,7 +34,7 @@ QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, SampleCount QueuedEngineInterface::now() const { - return _engine.audio_driver()->frame_time(); + return _engine->audio_driver()->frame_time(); } /** Set the Responder to send responses to commands with, once the commands @@ -50,6 +50,14 @@ QueuedEngineInterface::set_responder(CountedPtr<Responder> responder) void +QueuedEngineInterface::set_next_response_id(int32_t id) +{ + if (_responder) + _responder->set_id(id); +} + + +void QueuedEngineInterface::disable_responses() { static CountedPtr<Responder> null_responder(new Responder()); @@ -64,14 +72,14 @@ QueuedEngineInterface::disable_responses() void QueuedEngineInterface::register_client(ClientKey key, CountedPtr<ClientInterface> client) { - push_queued(new RegisterClientEvent(_engine, _responder, now(), key, client)); + push_queued(new RegisterClientEvent(*_engine.get(), _responder, now(), key, client)); } void QueuedEngineInterface::unregister_client(ClientKey key) { - push_queued(new UnregisterClientEvent(_engine, _responder, now(), key)); + push_queued(new UnregisterClientEvent(*_engine.get(), _responder, now(), key)); } @@ -80,7 +88,7 @@ QueuedEngineInterface::unregister_client(ClientKey key) void QueuedEngineInterface::load_plugins() { - push_queued(new LoadPluginsEvent(_engine, _responder, now())); + push_queued(new LoadPluginsEvent(*_engine.get(), _responder, now())); } @@ -88,14 +96,14 @@ QueuedEngineInterface::load_plugins() void QueuedEngineInterface::activate() { - push_queued(new ActivateEvent(_engine, _responder, now())); + push_queued(new ActivateEvent(*_engine.get(), _responder, now())); } void QueuedEngineInterface::deactivate() { - push_queued(new DeactivateEvent(_engine, _responder, now())); + push_queued(new DeactivateEvent(*_engine.get(), _responder, now())); } @@ -103,7 +111,7 @@ void QueuedEngineInterface::quit() { _responder->respond_ok(); - _engine.quit(); + _engine->quit(); } @@ -114,7 +122,7 @@ void QueuedEngineInterface::create_patch(const string& path, uint32_t poly) { - push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); + push_queued(new CreatePatchEvent(*_engine.get(), _responder, now(), path, poly)); } @@ -123,7 +131,7 @@ void QueuedEngineInterface::create_port(const string& path, const string& data_type, bool direction) { - push_queued(new AddPortEvent(_engine, _responder, now(), path, data_type, direction)); + push_queued(new AddPortEvent(*_engine.get(), _responder, now(), path, data_type, direction)); } @@ -139,7 +147,7 @@ QueuedEngineInterface::create_node(const string& path, plugin->set_type(plugin_type); plugin->uri(plugin_uri); - push_queued(new AddNodeEvent(_engine, _responder, now(), path, plugin, polyphonic)); + push_queued(new AddNodeEvent(*_engine.get(), _responder, now(), path, plugin, polyphonic)); } @@ -157,42 +165,42 @@ QueuedEngineInterface::create_node(const string& path, plugin->lib_name(plugin_lib); plugin->plug_label(plugin_label); - push_queued(new AddNodeEvent(_engine, _responder, now(), path, plugin, polyphonic)); + push_queued(new AddNodeEvent(*_engine.get(), _responder, now(), path, plugin, polyphonic)); } void QueuedEngineInterface::rename(const string& old_path, const string& new_name) { - push_queued(new RenameEvent(_engine, _responder, now(), old_path, new_name)); + push_queued(new RenameEvent(*_engine.get(), _responder, now(), old_path, new_name)); } void QueuedEngineInterface::destroy(const string& path) { - push_queued(new DestroyEvent(_engine, _responder, now(), this, path)); + push_queued(new DestroyEvent(*_engine.get(), _responder, now(), this, path)); } void QueuedEngineInterface::clear_patch(const string& patch_path) { - push_queued(new ClearPatchEvent(_engine, _responder, now(), patch_path)); + push_queued(new ClearPatchEvent(*_engine.get(), _responder, now(), patch_path)); } void QueuedEngineInterface::enable_patch(const string& patch_path) { - push_queued(new EnablePatchEvent(_engine, _responder, now(), patch_path)); + push_queued(new EnablePatchEvent(*_engine.get(), _responder, now(), patch_path)); } void QueuedEngineInterface::disable_patch(const string& patch_path) { - push_queued(new DisablePatchEvent(_engine, _responder, now(), patch_path)); + push_queued(new DisablePatchEvent(*_engine.get(), _responder, now(), patch_path)); } @@ -200,7 +208,7 @@ void QueuedEngineInterface::connect(const string& src_port_path, const string& dst_port_path) { - push_queued(new ConnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); + push_queued(new ConnectionEvent(*_engine.get(), _responder, now(), src_port_path, dst_port_path)); } @@ -209,14 +217,14 @@ void QueuedEngineInterface::disconnect(const string& src_port_path, const string& dst_port_path) { - push_queued(new DisconnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); + push_queued(new DisconnectionEvent(*_engine.get(), _responder, now(), src_port_path, dst_port_path)); } void QueuedEngineInterface::disconnect_all(const string& node_path) { - push_queued(new DisconnectNodeEvent(_engine, _responder, now(), node_path)); + push_queued(new DisconnectNodeEvent(*_engine.get(), _responder, now(), node_path)); } @@ -224,7 +232,7 @@ void QueuedEngineInterface::set_port_value(const string& port_path, float value) { - push_stamped(new SetPortValueEvent(_engine, _responder, now(), port_path, value)); + push_stamped(new SetPortValueEvent(*_engine.get(), _responder, now(), port_path, value)); } @@ -233,7 +241,7 @@ QueuedEngineInterface::set_port_value(const string& port_path, uint32_t voice, float value) { - push_stamped(new SetPortValueEvent(_engine, _responder, now(), voice, port_path, value)); + push_stamped(new SetPortValueEvent(*_engine.get(), _responder, now(), voice, port_path, value)); } @@ -241,7 +249,7 @@ void QueuedEngineInterface::set_port_value_queued(const string& port_path, float value) { - push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), port_path, value)); + push_queued(new SetPortValueQueuedEvent(*_engine.get(), _responder, now(), port_path, value)); } @@ -250,14 +258,14 @@ QueuedEngineInterface::set_program(const string& node_path, uint32_t bank, uint32_t program) { - push_queued(new DSSIProgramEvent(_engine, _responder, now(), node_path, bank, program)); + push_queued(new DSSIProgramEvent(*_engine.get(), _responder, now(), node_path, bank, program)); } void QueuedEngineInterface::midi_learn(const string& node_path) { - push_queued(new MidiLearnEvent(_engine, _responder, now(), node_path)); + push_queued(new MidiLearnEvent(*_engine.get(), _responder, now(), node_path)); } @@ -266,7 +274,7 @@ QueuedEngineInterface::set_metadata(const string& path, const string& predicate, const string& value) { - push_queued(new SetMetadataEvent(_engine, _responder, now(), path, predicate, value)); + push_queued(new SetMetadataEvent(*_engine.get(), _responder, now(), path, predicate, value)); } @@ -275,28 +283,32 @@ QueuedEngineInterface::set_metadata(const string& path, void QueuedEngineInterface::ping() { - push_queued(new PingQueuedEvent(_engine, _responder, now())); + if (_engine->activated()) { + push_queued(new PingQueuedEvent(*_engine.get(), _responder, now())); + } else if (_responder) { + _responder->respond_ok(); + } } void QueuedEngineInterface::request_port_value(const string& port_path) { - push_queued(new RequestPortValueEvent(_engine, _responder, now(), port_path)); + push_queued(new RequestPortValueEvent(*_engine.get(), _responder, now(), port_path)); } void QueuedEngineInterface::request_plugins() { - push_queued(new RequestPluginsEvent(_engine, _responder, now())); + push_queued(new RequestPluginsEvent(*_engine.get(), _responder, now())); } void QueuedEngineInterface::request_all_objects() { - push_queued(new RequestAllObjectsEvent(_engine, _responder, now())); + push_queued(new RequestAllObjectsEvent(*_engine.get(), _responder, now())); } diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h index c5904a2e..1e35738f 100644 --- a/src/libs/engine/QueuedEngineInterface.h +++ b/src/libs/engine/QueuedEngineInterface.h @@ -25,6 +25,7 @@ #include "interface/ClientInterface.h" #include "interface/ClientKey.h" #include "QueuedEventSource.h" +#include "Engine.h" #include "Responder.h" using std::string; @@ -56,12 +57,14 @@ class Engine; * events and get pushed directly into the realtime event queue. Should that * be separated into a different interface/client? */ -class QueuedEngineInterface : public QueuedEventSource, public EngineInterface +class QueuedEngineInterface : public QueuedEventSource, public virtual EngineInterface { public: - QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size); + QueuedEngineInterface(CountedPtr<Engine> engine, size_t queued_size, size_t stamped_size); virtual ~QueuedEngineInterface() {} + void set_next_response_id(int32_t id); + virtual void set_responder(CountedPtr<Responder> responder); virtual void disable_responses(); @@ -151,10 +154,10 @@ protected: /** Where responses to current messages will go. */ CountedPtr<Responder> _responder; + CountedPtr<Engine> _engine; + private: SampleCount now() const; - - Engine& _engine; }; diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp index 915b7811..08e1c63e 100644 --- a/src/libs/engine/QueuedEventSource.cpp +++ b/src/libs/engine/QueuedEventSource.cpp @@ -36,6 +36,8 @@ QueuedEventSource::QueuedEventSource(size_t queued_size, size_t stamped_size) _events = (QueuedEvent**)calloc(_size, sizeof(QueuedEvent*)); mlock(_events, _size * sizeof(QueuedEvent*)); + + Thread::set_name("PreProcessor"); } @@ -151,15 +153,10 @@ QueuedEventSource::_whipped() QueuedEvent* const ev = _events[_prepared_back]; assert(ev); - if (ev == NULL) { - cerr << "[QueuedEventSource] ERROR: Signalled, but event is NULL." << endl; - return; - } - - assert(ev); + assert(!ev->is_prepared()); - ev->pre_process(); + assert(ev->is_prepared()); _prepared_back = (_prepared_back+1) % _size; diff --git a/src/libs/engine/Responder.h b/src/libs/engine/Responder.h index 162af23f..3976883d 100644 --- a/src/libs/engine/Responder.h +++ b/src/libs/engine/Responder.h @@ -21,11 +21,13 @@ #include <string> #include "util/CountedPtr.h" #include "interface/ClientKey.h" +#include "interface/ClientInterface.h" using std::string; namespace Ingen { using Shared::ClientKey; +using Shared::ClientInterface; /** Class to handle responding to clients. @@ -49,7 +51,10 @@ public: Responder() {} virtual ~Responder() {} - virtual ClientKey client_key() { return ClientKey(); } + virtual ClientKey client_key() { return ClientKey(); } + virtual CountedPtr<ClientInterface> client() { return NULL; } + + virtual void set_id(int32_t id) {} virtual void respond_ok() {} virtual void respond_error(const string& msg) {} diff --git a/src/libs/engine/TypedPort.cpp b/src/libs/engine/TypedPort.cpp index 484dcaf7..4cc184e6 100644 --- a/src/libs/engine/TypedPort.cpp +++ b/src/libs/engine/TypedPort.cpp @@ -65,8 +65,6 @@ TypedPort<Sample>::set_value(Sample val, size_t offset) offset = 0; assert(offset < _buffer_size); - cerr << path() << " setting value " << val << endl; - for (size_t v=0; v < _poly; ++v) m_buffers.at(v)->set(val, offset); } diff --git a/src/libs/engine/events/ActivateEvent.cpp b/src/libs/engine/events/ActivateEvent.cpp index 9d8162ec..c63c86e1 100644 --- a/src/libs/engine/events/ActivateEvent.cpp +++ b/src/libs/engine/events/ActivateEvent.cpp @@ -24,18 +24,9 @@ namespace Ingen { ActivateEvent::ActivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { -} - - -void -ActivateEvent::pre_process() -{ - QueuedEvent::pre_process(); - _engine.activate(); } - void ActivateEvent::post_process() { diff --git a/src/libs/engine/events/ActivateEvent.h b/src/libs/engine/events/ActivateEvent.h index 26ee5b84..696fc0de 100644 --- a/src/libs/engine/events/ActivateEvent.h +++ b/src/libs/engine/events/ActivateEvent.h @@ -31,7 +31,6 @@ class ActivateEvent : public QueuedEvent public: ActivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); - void pre_process(); void post_process(); }; diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp index 5287c7cd..19ff6bf5 100644 --- a/src/libs/engine/events/AddNodeEvent.cpp +++ b/src/libs/engine/events/AddNodeEvent.cpp @@ -117,8 +117,8 @@ AddNodeEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - //_engine.client_broadcaster()->send_node_creation_messages(m_node); - _engine.client_broadcaster()->send_node(m_node); + //_engine.broadcaster()->send_node_creation_messages(m_node); + _engine.broadcaster()->send_node(m_node); } } diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp index 7b034f43..06ddae94 100644 --- a/src/libs/engine/events/AddPortEvent.cpp +++ b/src/libs/engine/events/AddPortEvent.cpp @@ -126,7 +126,7 @@ AddPortEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - _engine.client_broadcaster()->send_port(_patch_port); + _engine.broadcaster()->send_port(_patch_port); } } diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp index e73fd376..3518dc03 100644 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ b/src/libs/engine/events/ClearPatchEvent.cpp @@ -103,7 +103,7 @@ ClearPatchEvent::post_process() // Reply _responder->respond_ok(); - _engine.client_broadcaster()->send_patch_cleared(m_patch_path); + _engine.broadcaster()->send_patch_cleared(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index b873bccb..7c97de03 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -250,7 +250,7 @@ TypedConnectionEvent<T>::post_process() _responder->respond_ok(); - _engine.client_broadcaster()->send_connection(m_connection); + _engine.broadcaster()->send_connection(m_connection); } else { _responder->respond_error("Unable to make connection."); } diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp index d66a3ff9..7532291b 100644 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ b/src/libs/engine/events/CreatePatchEvent.cpp @@ -121,10 +121,10 @@ CreatePatchEvent::post_process() _responder->respond_ok(); // Don't want to send nodes that have been added since prepare() - //_engine.client_broadcaster()->send_node_creation_messages(m_patch); + //_engine.broadcaster()->send_node_creation_messages(m_patch); // Patches are always empty on creation, so this is fine - _engine.client_broadcaster()->send_patch(m_patch); + _engine.broadcaster()->send_patch(m_patch); } else if (m_error == OBJECT_EXISTS) { string msg = "Unable to create patch: "; diff --git a/src/libs/engine/events/DSSIConfigureEvent.cpp b/src/libs/engine/events/DSSIConfigureEvent.cpp index de79a083..fb006444 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.cpp +++ b/src/libs/engine/events/DSSIConfigureEvent.cpp @@ -63,7 +63,7 @@ DSSIConfigureEvent::post_process() } else { string key = "dssi-configure--"; key += m_key; - _engine.client_broadcaster()->send_metadata_update(m_node_path, key, m_val); + _engine.broadcaster()->send_metadata_update(m_node_path, key, m_val); } } diff --git a/src/libs/engine/events/DSSIProgramEvent.cpp b/src/libs/engine/events/DSSIProgramEvent.cpp index 4545268a..d602b57c 100644 --- a/src/libs/engine/events/DSSIProgramEvent.cpp +++ b/src/libs/engine/events/DSSIProgramEvent.cpp @@ -67,7 +67,7 @@ DSSIProgramEvent::post_process() // sends program as metadata in the form bank/program char* temp_buf = new char[16]; snprintf(temp_buf, 16, "%d/%d", m_bank, m_program); - _engine.client_broadcaster()->send_metadata_update(m_node_path, "dssi-program", temp_buf); + _engine.broadcaster()->send_metadata_update(m_node_path, "dssi-program", temp_buf); } } diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index dd172e7f..ced323a1 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -34,16 +34,16 @@ namespace Ingen { -DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex) -: QueuedEvent(engine, responder, true, source), +DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool lock_mutex) +: QueuedEvent(engine, responder, time, true, source), m_path(path), m_node(NULL), m_patch_listnode(NULL), m_store_treenode(NULL), m_process_order(NULL), - m_disconnect_event(NULL), - m_parent_disconnect_event(NULL) + m_disconnect_event(NULL) { + assert(_source); } @@ -54,8 +54,7 @@ DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, Samp m_patch_listnode(NULL), m_store_treenode(NULL), m_process_order(NULL), - m_disconnect_event(NULL), - m_parent_disconnect_event(NULL) + m_disconnect_event(NULL) { } @@ -63,7 +62,6 @@ DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, Samp DestroyEvent::~DestroyEvent() { delete m_disconnect_event; - delete m_parent_disconnect_event; } @@ -86,14 +84,6 @@ DestroyEvent::pre_process() m_disconnect_event->pre_process(); } - // Create a recursive disconnect event for the parent port, if a bridge node - cerr << "FIXME: Destroy bridge\n"; - /*Port* parent_port = m_patch_listnode->elem()->as_port(); - if (parent_port != NULL) { // Bridge node - m_parent_disconnect_event = new DisconnectPortEvent(Engine& engine, parent_port); - m_parent_disconnect_event->pre_process(); - }*/ - if (m_node->parent_patch()->enabled()) { m_process_order = m_node->parent_patch()->build_process_order(); // Remove node to be removed from the process order so it isn't executed by @@ -125,8 +115,6 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) if (m_disconnect_event != NULL) m_disconnect_event->execute(nframes, start, end); - if (m_parent_disconnect_event != NULL) - m_parent_disconnect_event->execute(nframes, start, end); if (m_node->parent_patch()->process_order() != NULL) _engine.maid()->push(m_node->parent_patch()->process_order()); @@ -151,9 +139,7 @@ DestroyEvent::post_process() _responder->respond_ok(); if (m_disconnect_event != NULL) m_disconnect_event->post_process(); - if (m_parent_disconnect_event != NULL) - m_parent_disconnect_event->post_process(); - _engine.client_broadcaster()->send_destroyed(m_path); + _engine.broadcaster()->send_destroyed(m_path); _engine.maid()->push(m_patch_listnode); _engine.maid()->push(m_node); } else { diff --git a/src/libs/engine/events/DestroyEvent.h b/src/libs/engine/events/DestroyEvent.h index 6eda8006..92b1c194 100644 --- a/src/libs/engine/events/DestroyEvent.h +++ b/src/libs/engine/events/DestroyEvent.h @@ -44,8 +44,8 @@ class DisconnectPortEvent; class DestroyEvent : public QueuedEvent { public: - DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex = true); - DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* node, bool lock_mutex = true); + DestroyEvent(Engine& engine, CountedPtr<Responder> responder, FrameTime timestamp, QueuedEventSource* source, const string& path, bool lock_mutex = true); + DestroyEvent(Engine& engine, CountedPtr<Responder> responder, FrameTime timestamp, Node* node, bool lock_mutex = true); ~DestroyEvent(); void pre_process(); @@ -53,13 +53,12 @@ public: void post_process(); private: - Path m_path; - Node* m_node; - ListNode<Node*>* m_patch_listnode; + Path m_path; + Node* m_node; + ListNode<Node*>* m_patch_listnode; TreeNode<GraphObject*>* m_store_treenode; - Array<Node*>* m_process_order; // Patch's new process order - DisconnectNodeEvent* m_disconnect_event; - DisconnectPortEvent* m_parent_disconnect_event; // used for input/output nodes + Array<Node*>* m_process_order; // Patch's new process order + DisconnectNodeEvent* m_disconnect_event; }; diff --git a/src/libs/engine/events/DisablePatchEvent.cpp b/src/libs/engine/events/DisablePatchEvent.cpp index 299e4fdc..064dd9fd 100644 --- a/src/libs/engine/events/DisablePatchEvent.cpp +++ b/src/libs/engine/events/DisablePatchEvent.cpp @@ -58,7 +58,7 @@ DisablePatchEvent::post_process() { if (m_patch != NULL) { _responder->respond_ok(); - _engine.client_broadcaster()->send_patch_disable(m_patch_path); + _engine.broadcaster()->send_patch_disable(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/DisconnectNodeEvent.cpp b/src/libs/engine/events/DisconnectNodeEvent.cpp index c1a965ad..df85e1db 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.cpp +++ b/src/libs/engine/events/DisconnectNodeEvent.cpp @@ -53,7 +53,7 @@ DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, CountedPtr<Responder> r */ DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, Node* node) : QueuedEvent(engine), - m_node_path(""), + m_node_path(node->path()), m_patch(node->parent_patch()), m_node(node), m_succeeded(true), diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp index c246e9dc..7e050369 100644 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ b/src/libs/engine/events/DisconnectionEvent.cpp @@ -271,7 +271,7 @@ TypedDisconnectionEvent<T>::post_process() _responder->respond_ok(); - _engine.client_broadcaster()->send_disconnection(m_src_port->path(), m_dst_port->path()); + _engine.broadcaster()->send_disconnection(m_src_port->path(), m_dst_port->path()); } else { _responder->respond_error("Unable to disconnect ports."); } diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp index 132aefcc..01144013 100644 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ b/src/libs/engine/events/EnablePatchEvent.cpp @@ -70,7 +70,7 @@ EnablePatchEvent::post_process() { if (m_patch != NULL) { _responder->respond_ok(); - _engine.client_broadcaster()->send_patch_enable(m_patch_path); + _engine.broadcaster()->send_patch_enable(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp index 6962387b..daf61378 100644 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ b/src/libs/engine/events/LoadPluginsEvent.cpp @@ -18,6 +18,7 @@ #include "Responder.h" #include "Engine.h" #include "NodeFactory.h" +#include "ClientBroadcaster.h" #include <iostream> using std::cerr; @@ -28,10 +29,22 @@ namespace Ingen { LoadPluginsEvent::LoadPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { - cerr << "LOADING PLUGINS\n"; - _engine.node_factory()->load_plugins(); } +void +LoadPluginsEvent::pre_process() +{ + _engine.node_factory()->load_plugins(); + + // FIXME: send the changes (added and removed plugins) instead of the entire list each time + + // Take a copy to send in the post processing thread (to avoid problems + // because std::list isn't thread safe) + _plugins = _engine.node_factory()->plugins(); + cerr << "loaded " << _plugins.size() << "plugins.\n"; + + QueuedEvent::pre_process(); +} void LoadPluginsEvent::post_process() diff --git a/src/libs/engine/events/LoadPluginsEvent.h b/src/libs/engine/events/LoadPluginsEvent.h index ae784e3a..a143d812 100644 --- a/src/libs/engine/events/LoadPluginsEvent.h +++ b/src/libs/engine/events/LoadPluginsEvent.h @@ -17,10 +17,13 @@ #ifndef LOADPLUGINSEVENT_H #define LOADPLUGINSEVENT_H +#include <list> #include "QueuedEvent.h" namespace Ingen { +class Plugin; + /** Loads all plugins into the internal plugin database (in NodeFactory). * @@ -31,7 +34,11 @@ class LoadPluginsEvent : public QueuedEvent public: LoadPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); + void pre_process(); void post_process(); + +private: + std::list<Plugin*> _plugins; }; diff --git a/src/libs/engine/events/MidiLearnEvent.cpp b/src/libs/engine/events/MidiLearnEvent.cpp index 822573e0..c56db8d8 100644 --- a/src/libs/engine/events/MidiLearnEvent.cpp +++ b/src/libs/engine/events/MidiLearnEvent.cpp @@ -30,7 +30,7 @@ namespace Ingen { void MidiLearnResponseEvent::post_process() { - _engine.client_broadcaster()->send_control_change(m_port_path, m_value); + _engine.broadcaster()->send_control_change(m_port_path, m_value); } diff --git a/src/libs/engine/events/RegisterClientEvent.cpp b/src/libs/engine/events/RegisterClientEvent.cpp index e35b7fdb..81cb3b81 100644 --- a/src/libs/engine/events/RegisterClientEvent.cpp +++ b/src/libs/engine/events/RegisterClientEvent.cpp @@ -36,7 +36,7 @@ RegisterClientEvent::RegisterClientEvent(Engine& engine, CountedPtr<Responder> void RegisterClientEvent::pre_process() { - _engine.client_broadcaster()->register_client(_key, _client); + _engine.broadcaster()->register_client(_key, _client); QueuedEvent::pre_process(); } diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp index 465f4946..82fe3737 100644 --- a/src/libs/engine/events/RenameEvent.cpp +++ b/src/libs/engine/events/RenameEvent.cpp @@ -103,7 +103,7 @@ RenameEvent::post_process() if (m_error == NO_ERROR) { _responder->respond_ok(); - _engine.client_broadcaster()->send_rename(m_old_path, m_new_path); + _engine.broadcaster()->send_rename(m_old_path, m_new_path); } else { if (m_error == OBJECT_EXISTS) msg.append("Object already exists at ").append(m_new_path); diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp index 5eb780b3..f51a514e 100644 --- a/src/libs/engine/events/RequestAllObjectsEvent.cpp +++ b/src/libs/engine/events/RequestAllObjectsEvent.cpp @@ -25,8 +25,7 @@ namespace Ingen { RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp), - m_client(CountedPtr<ClientInterface>(NULL)) +: QueuedEvent(engine, responder, timestamp) { } @@ -34,7 +33,7 @@ RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, CountedPtr<Respon void RequestAllObjectsEvent::pre_process() { - m_client = _engine.client_broadcaster()->client(_responder->client_key()); + m_client = _engine.broadcaster()->client(_responder->client_key()); QueuedEvent::pre_process(); } diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp index 03d84d7f..e2169f54 100644 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ b/src/libs/engine/events/RequestMetadataEvent.cpp @@ -41,7 +41,7 @@ RequestMetadataEvent::RequestMetadataEvent(Engine& engine, CountedPtr<Responder> void RequestMetadataEvent::pre_process() { - m_client = _engine.client_broadcaster()->client(_responder->client_key()); + m_client = _engine.broadcaster()->client(_responder->client_key()); if (m_client) { m_object = _engine.object_store()->find(m_path); diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp index 9efb2388..789be0ea 100644 --- a/src/libs/engine/events/RequestPluginsEvent.cpp +++ b/src/libs/engine/events/RequestPluginsEvent.cpp @@ -24,8 +24,7 @@ namespace Ingen { RequestPluginsEvent::RequestPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp), - m_client(CountedPtr<ClientInterface>(NULL)) +: QueuedEvent(engine, responder, timestamp) { } @@ -33,7 +32,7 @@ RequestPluginsEvent::RequestPluginsEvent(Engine& engine, CountedPtr<Responder> r void RequestPluginsEvent::pre_process() { - m_client = _engine.client_broadcaster()->client(_responder->client_key()); + m_client = _engine.broadcaster()->client(_responder->client_key()); // Take a copy to send in the post processing thread (to avoid problems // because std::list isn't thread safe) @@ -47,7 +46,7 @@ void RequestPluginsEvent::post_process() { if (m_client) { - _engine.client_broadcaster()->send_plugins_to(m_client.get(), m_plugins); + _engine.broadcaster()->send_plugins_to(m_client, m_plugins); _responder->respond_ok(); } else { _responder->respond_error("Unable to find client to send plugins"); diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp index 830ef852..12dea975 100644 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ b/src/libs/engine/events/RequestPortValueEvent.cpp @@ -41,7 +41,7 @@ RequestPortValueEvent::RequestPortValueEvent(Engine& engine, CountedPtr<Responde void RequestPortValueEvent::pre_process() { - m_client = _engine.client_broadcaster()->client(_responder->client_key()); + m_client = _engine.broadcaster()->client(_responder->client_key()); m_port = _engine.object_store()->find_port(m_port_path); QueuedEvent::pre_process(); diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp index 1ce5d6f4..428437e3 100644 --- a/src/libs/engine/events/SetMetadataEvent.cpp +++ b/src/libs/engine/events/SetMetadataEvent.cpp @@ -70,7 +70,7 @@ SetMetadataEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - _engine.client_broadcaster()->send_metadata_update(m_path, m_key, m_value); + _engine.broadcaster()->send_metadata_update(m_path, m_key, m_value); } } diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 4018139a..efe53b37 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -78,13 +78,13 @@ SetPortValueEvent::post_process() assert(m_port != NULL); _responder->respond_ok(); - _engine.client_broadcaster()->send_control_change(m_port_path, m_val); + _engine.broadcaster()->send_control_change(m_port_path, m_val); // Send patch port control change, if this is a bridge port /*Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { assert(parent_port->type() == DataType::FLOAT); - _engine.client_broadcaster()->send_control_change(parent_port->path(), m_val); + _engine.broadcaster()->send_control_change(parent_port->path(), m_val); }*/ } else if (m_error == PORT_NOT_FOUND) { diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index caee68a6..dcbec0be 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -69,9 +69,9 @@ SetPortValueQueuedEvent::pre_process() void SetPortValueQueuedEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - assert(_time >= start && _time <= end); - QueuedEvent::execute(nframes, start, end); + + assert(_time >= start && _time <= end); if (m_error == NO_ERROR) { assert(m_port != NULL); @@ -90,13 +90,13 @@ SetPortValueQueuedEvent::post_process() assert(m_port != NULL); _responder->respond_ok(); - _engine.client_broadcaster()->send_control_change(m_port_path, m_val); + _engine.broadcaster()->send_control_change(m_port_path, m_val); // Send patch port control change, if this is a bridge port /*Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { assert(parent_port->type() == DataType::FLOAT); - _engine.client_broadcaster()->send_control_change(parent_port->path(), m_val); + _engine.broadcaster()->send_control_change(parent_port->path(), m_val); }*/ } else if (m_error == PORT_NOT_FOUND) { diff --git a/src/libs/engine/events/UnregisterClientEvent.cpp b/src/libs/engine/events/UnregisterClientEvent.cpp index 13709959..310df7c5 100644 --- a/src/libs/engine/events/UnregisterClientEvent.cpp +++ b/src/libs/engine/events/UnregisterClientEvent.cpp @@ -33,7 +33,7 @@ UnregisterClientEvent::UnregisterClientEvent(Engine& engine, CountedPtr<Responde void UnregisterClientEvent::post_process() { - if (_engine.client_broadcaster()->unregister_client(_key)) + if (_engine.broadcaster()->unregister_client(_key)) _responder->respond_ok(); else _responder->respond_error("Unable to unregister client"); diff --git a/src/progs/demolition/DemolitionClientInterface.cpp b/src/progs/demolition/DemolitionClientInterface.cpp index 1c3d7aa1..a0704028 100644 --- a/src/progs/demolition/DemolitionClientInterface.cpp +++ b/src/progs/demolition/DemolitionClientInterface.cpp @@ -30,7 +30,7 @@ DemolitionClientInterface::~DemolitionClientInterface() void -DemolitionClientInterface::error(const string& msg) +DemolitionClientInterface::error(string msg) { } @@ -50,19 +50,19 @@ DemolitionClientInterface::new_port_model(PortModel* port_model) void -DemolitionClientInterface::object_destroyed(const string& path) +DemolitionClientInterface::object_destroyed(string path) { m_model->remove_object(path); } void -DemolitionClientInterface::patch_enabled(const string& path) +DemolitionClientInterface::patch_enabled(string path) { } void -DemolitionClientInterface::patch_disabled(const string& path) +DemolitionClientInterface::patch_disabled(string path) { } @@ -75,7 +75,7 @@ DemolitionClientInterface::new_node_model(NodeModel* nm) void -DemolitionClientInterface::object_renamed(const string& old_path, const string& new_path) +DemolitionClientInterface::object_renamed(string old_path, string new_path) { m_model->object_renamed(old_path, new_path); } @@ -89,14 +89,14 @@ DemolitionClientInterface::connection_model(ConnectionModel* cm) void -DemolitionClientInterface::disconnection(const string& src_port_path, const string& dst_port_path) +DemolitionClientInterface::disconnection(string src_port_path, string dst_port_path) { m_model->remove_connection(src_port_path, dst_port_path); } void -DemolitionClientInterface::control_change(const string& port_path, float value) +DemolitionClientInterface::control_change(string port_path, float value) { } diff --git a/src/progs/demolition/DemolitionClientInterface.h b/src/progs/demolition/DemolitionClientInterface.h index 303de621..83539afc 100644 --- a/src/progs/demolition/DemolitionClientInterface.h +++ b/src/progs/demolition/DemolitionClientInterface.h @@ -42,32 +42,35 @@ public: void bundle_begin() {} void bundle_end() {} + + void transfer_begin() {} + void transfer_end() {} void num_plugins(uint32_t num) {} - void response(int32_t id, bool success, const string& msg) {} + void response(int32_t id, bool success, string msg) {} // OSC thread functions - void error(const string& msg); + void error(string msg); - void new_plugin(const string& type, - const string& uri, - const string& name) {} + void new_plugin(string type, + string uri, + string name) {} void new_patch_model(PatchModel* const pm); void new_port_model(PortModel* const port_model); - void object_destroyed(const string& path); - void patch_enabled(const string& path); - void patch_disabled(const string& path); - void patch_cleared(const string& path) { throw; } + void object_destroyed(string path); + void patch_enabled(string path); + void patch_disabled(string path); + void patch_cleared(string path) { throw; } void new_node_model(NodeModel* const nm); - void object_renamed(const string& old_path, const string& new_path); + void object_renamed(string old_path, string new_path); void connection_model(ConnectionModel* const cm); - void disconnection(const string& src_port_path, const string& dst_port_path); - void metadata_update(const string& path, const string& key, const string& value) {} - void control_change(const string& port_path, float value); + void disconnection(string src_port_path, string dst_port_path); + void metadata_update(string path, string key, string value) {} + void control_change(string port_path, float value); void new_plugin_model(PluginModel* const pi); - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) {}; - void program_remove(const string& path, uint32_t bank, uint32_t program) {}; + void program_add(string path, uint32_t bank, uint32_t program, string name) {}; + void program_remove(string path, uint32_t bank, uint32_t program) {}; private: DemolitionModel* m_model; diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index 1a7d7760..ecf94a92 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -35,7 +35,6 @@ #include "PatchWindow.h" #include "MessagesWindow.h" #include "ConfigWindow.h" -#include "Controller.h" #include "GladeFactory.h" #include "util/Path.h" #include "ObjectModel.h" @@ -44,6 +43,7 @@ #include "Configuration.h" #include "ConnectWindow.h" #include "Store.h" +#include "Loader.h" #ifdef HAVE_LASH #include "LashController.h" #endif @@ -61,9 +61,9 @@ class OmPort; App* App::_instance = 0; -App::App(CountedPtr<SigClientInterface> listener) -: _listener(listener), - _store(new Store(listener)), +App::App() +: _store(NULL), + _loader(NULL), _configuration(new Configuration()), _about_dialog(NULL), _enable_signal(true) @@ -71,16 +71,13 @@ App::App(CountedPtr<SigClientInterface> listener) Glib::RefPtr<Gnome::Glade::Xml> glade_xml = GladeFactory::new_glade_reference(); 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("messages_win", _messages_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_derived("config_win", _config_window); glade_xml->get_widget("about_win", _about_dialog); + _config_window->configuration(_configuration); - - glade_xml->get_widget_derived("messages_win", _messages_window); } @@ -89,12 +86,28 @@ App::~App() } void -App::instantiate(CountedPtr<SigClientInterface>& listener) +App::instantiate() { if (!_instance) - _instance = new App(listener); + _instance = new App(); } + +void +App::attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client) +{ + assert( ! _engine); + assert( ! _client); + assert( ! _store); + assert( ! _loader); + + _engine = engine; + _client = client; + _store = new Store(client); + _loader = new Loader(engine); +} + + void App::error_message(const string& str) { diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 2d56e445..06d52ca3 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -34,6 +34,7 @@ namespace Ingen { namespace Client { class PluginModel; class Store; class SigClientInterface; + class ModelEngineInterface; } } using namespace Ingen::Client; @@ -59,6 +60,7 @@ class PatchTreeView; class PatchTreeWindow; class ConnectWindow; class Configuration; +class Loader; /** Singleton master class most everything is contained within. @@ -81,7 +83,9 @@ public: void add_patch_window(PatchWindow* pw); void remove_patch_window(PatchWindow* pw); - int num_open_patch_windows(); + int num_open_patch_windows(); + + void attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client); ConnectWindow* connect_window() const { return _connect_window; } Gtk::Dialog* about_dialog() const { return _about_dialog; } @@ -90,22 +94,23 @@ public: PatchTreeWindow* patch_tree() const { return _patch_tree_window; } Configuration* configuration() const { return _configuration; } Store* store() const { return _store; } + Loader* loader() const { return _loader; } - const CountedPtr<SigClientInterface>& client() const { return _listener; } - - static void instantiate(CountedPtr<SigClientInterface>& listener); + const CountedPtr<ModelEngineInterface>& engine() const { return _engine; } + const CountedPtr<SigClientInterface>& client() const { return _client; } static inline App& instance() { assert(_instance); return *_instance; } + static void instantiate(); protected: - App(CountedPtr<SigClientInterface> listener); + App(); static App* _instance; - //bool connect_callback(); - //bool idle_callback(); - - CountedPtr<SigClientInterface> _listener; - Store* _store; + CountedPtr<ModelEngineInterface> _engine; + CountedPtr<SigClientInterface> _client; + + Store* _store; + Loader* _loader; Configuration* _configuration; @@ -116,7 +121,6 @@ protected: 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, diff --git a/src/progs/ingenuity/Configuration.cpp b/src/progs/ingenuity/Configuration.cpp index 4cb473cb..e383cf87 100644 --- a/src/progs/ingenuity/Configuration.cpp +++ b/src/progs/ingenuity/Configuration.cpp @@ -25,7 +25,8 @@ #include "PatchController.h" #include "PatchModel.h" #include "OmFlowCanvas.h" -#include "Controller.h" +#include "Loader.h" +#include "App.h" using std::cerr; using std::cout; using std::endl; using std::map; using std::string; @@ -131,7 +132,8 @@ Configuration::save_settings(string filename) void Configuration::apply_settings() { - Controller::instance().set_patch_path(m_patch_path); + cerr << "FIXME: patch path" << endl; + //App::instance().loader()->set_patch_path(m_patch_path); } diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp index d4027e20..16b2adea 100644 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ b/src/progs/ingenuity/ConnectWindow.cpp @@ -14,26 +14,62 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "ConnectWindow.h" #include <string> #include <time.h> #include <sys/time.h> #include <stdlib.h> +#include "config.h" +#include "ConnectWindow.h" #include "interface/ClientKey.h" +#include "OSCModelEngineInterface.h" +#include "OSCClientReceiver.h" #include "ThreadedSigClientInterface.h" -#include "Controller.h" #include "Store.h" #include "PatchController.h" #include "PatchModel.h" #include "App.h" +#ifdef MONOLITHIC_INGENUITY + #include "engine/QueuedEngineInterface.h" + #include "engine/Engine.h" + #include "engine/DirectResponder.h" + #include "engine/tuning.h" +#endif using Ingen::Client::ThreadedSigClientInterface; +using Ingen::QueuedEngineInterface; namespace Ingenuity { +// Paste together some interfaces to get the combination we want + + +struct OSCSigEmitter : public OSCClientReceiver, public ThreadedSigClientInterface { +public: + OSCSigEmitter(size_t queue_size, int listen_port) + : Ingen::Shared::ClientInterface() + , OSCClientReceiver(listen_port) + , ThreadedSigClientInterface(queue_size) + { + } +}; + + +struct QueuedModelEngineInterface : public QueuedEngineInterface, public ModelEngineInterface { + QueuedModelEngineInterface(CountedPtr<Ingen::Engine> engine) + : Ingen::Shared::EngineInterface() + , Ingen::QueuedEngineInterface(engine, Ingen::event_queue_size, Ingen::event_queue_size) + { + QueuedEventSource::start(); + } +}; + + +// ConnectWindow + + ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::Dialog(cobject) -, _client(NULL) +, _mode(CONNECT_REMOTE) , _ping_id(-1) , _attached(false) { @@ -61,9 +97,8 @@ ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome:: void ConnectWindow::start() { - _client = App::instance().client(); - assert(_client); resize(100, 100); + init(); show(); } @@ -78,38 +113,82 @@ ConnectWindow::init() _disconnect_button->set_sensitive(false); _port_spinbutton->set_sensitive(false); _launch_radio->set_sensitive(true); +#ifdef MONOLITHIC_INGENUITY + _internal_radio->set_sensitive(true); +#else _internal_radio->set_sensitive(false); +#endif server_toggled(); _progress_label->set_text(string("Disconnected")); } +/** Launch (if applicable) and connect to the Engine. + * + * This will create the EngineInterface and ClientInterface and initialize + * the App with them. + */ void ConnectWindow::connect() { + assert(!_attached); + assert(!App::instance().engine()); + assert(!App::instance().client()); + _connect_button->set_sensitive(false); - if (_server_radio->get_active()) { - Controller::instance().set_engine_url(_url_entry->get_text()); + if (_mode == CONNECT_REMOTE) { + CountedPtr<ModelEngineInterface> engine(new OSCModelEngineInterface(_url_entry->get_text())); + OSCSigEmitter* ose = new OSCSigEmitter(1024, 16181); // FIXME: args + CountedPtr<SigClientInterface> client(ose); + App::instance().attach(engine, client); + Glib::signal_timeout().connect( sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); + + Glib::signal_timeout().connect( + sigc::mem_fun(ose, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); - } else if (_launch_radio->get_active()) { + } else if (_mode == LAUNCH_REMOTE) { + /* int port = _port_spinbutton->get_value_as_int(); char port_str[6]; snprintf(port_str, 6, "%u", port); const string port_arg = string("--port=").append(port_str); - Controller::instance().set_engine_url( + App::instance().engine()->set_engine_url( string("osc.udp://localhost:").append(port_str)); if (fork() == 0) { // child - cerr << "Executing 'om " << port_arg << "' ..." << endl; - execlp("om", port_arg.c_str(), 0); + cerr << "Executing 'ingen " << port_arg << "' ..." << endl; + execlp("ingen", port_arg.c_str(), (char*)NULL); } else { Glib::signal_timeout().connect( sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); - } + }*/ + throw; +#ifdef MONOLITHIC_INGENUITY + } else if (_mode == INTERNAL) { + CountedPtr<Ingen::Engine> engine(new Ingen::Engine()); + QueuedModelEngineInterface* qmei = new QueuedModelEngineInterface(engine); + CountedPtr<ModelEngineInterface> engine_interface(qmei); + ThreadedSigClientInterface* tsci = new ThreadedSigClientInterface(Ingen::event_queue_size); + CountedPtr<SigClientInterface> client(tsci); + + App::instance().attach(engine_interface, client); + + qmei->set_responder(CountedPtr<Ingen::Responder>(new Ingen::DirectResponder(client, 1))); + engine->set_event_source(qmei); + + Glib::signal_timeout().connect( + sigc::mem_fun(engine.get(), &Ingen::Engine::main_iteration), 1000); + + Glib::signal_timeout().connect( + sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); + + Glib::signal_timeout().connect( + sigc::mem_fun(tsci, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); +#endif } } @@ -152,6 +231,7 @@ ConnectWindow::server_toggled() { _url_entry->set_sensitive(true); _port_spinbutton->set_sensitive(false); + _mode = CONNECT_REMOTE; } @@ -160,15 +240,16 @@ ConnectWindow::launch_toggled() { _url_entry->set_sensitive(false); _port_spinbutton->set_sensitive(true); + _mode = LAUNCH_REMOTE; } void ConnectWindow::internal_toggled() { - // Not quite yet... _url_entry->set_sensitive(false); _port_spinbutton->set_sensitive(false); + _mode = INTERNAL; } @@ -188,44 +269,47 @@ ConnectWindow::gtk_callback() /* Connecting to engine */ if (stage == 0) { + assert(!_attached); - assert(_client); + assert(App::instance().engine()); + assert(App::instance().client()); // FIXME - //assert(!Controller::instance().is_attached()); - _progress_label->set_text(string("Connecting to engine at ").append( - Controller::instance().engine_url()).append("...")); + //assert(!App::instance().engine()->is_attached()); + _progress_label->set_text("Connecting to engine..."); present(); - _client->response_sig.connect(sigc::mem_fun(this, &ConnectWindow::response_received)); + App::instance().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); + App::instance().engine()->set_next_response_id(_ping_id); + App::instance().engine()->ping(); ++stage; } else if (stage == 1) { if (_attached) { - Controller::instance().activate(); + App::instance().engine()->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(_ping_id); + App::instance().engine()->set_next_response_id(_ping_id); + App::instance().engine()->ping(); last = now; } } } else if (stage == 2) { _progress_label->set_text(string("Registering as client...")); - //Controller::instance().register_client(Controller::instance().client_hooks()); + //App::instance().engine()->register_client(App::instance().engine()->client_hooks()); // FIXME //auto_ptr<ClientInterface> client(new ThreadedSigClientInterface(); - Controller::instance().register_client(ClientKey(), _client); - Controller::instance().load_plugins(); + App::instance().engine()->register_client(ClientKey(), App::instance().client()); + App::instance().engine()->load_plugins(); ++stage; } else if (stage == 3) { // Register idle callback to process events and whatnot @@ -238,7 +322,7 @@ ConnectWindow::gtk_callback() 5, G_PRIORITY_DEFAULT_IDLE);*/ _progress_label->set_text(string("Requesting plugins...")); - Controller::instance().request_plugins(); + App::instance().engine()->request_plugins(); ++stage; } else if (stage == 4) { // Wait for first plugins message @@ -261,7 +345,7 @@ ConnectWindow::gtk_callback() //} } else if (stage == 6) { _progress_label->set_text(string("Waiting for root patch...")); - Controller::instance().request_all_objects(); + App::instance().engine()->request_all_objects(); ++stage; } else if (stage == 7) { if (App::instance().store()->num_objects() > 0) { @@ -272,8 +356,7 @@ ConnectWindow::gtk_callback() ++stage; } } else if (stage == 8) { - _progress_label->set_text(string("Connected to engine at ").append( - Controller::instance().engine_url())); + _progress_label->set_text("Connected to engine"); ++stage; } else if (stage == 9) { stage = -1; diff --git a/src/progs/ingenuity/ConnectWindow.h b/src/progs/ingenuity/ConnectWindow.h index fba6b9d8..d74f6032 100644 --- a/src/progs/ingenuity/ConnectWindow.h +++ b/src/progs/ingenuity/ConnectWindow.h @@ -46,6 +46,8 @@ public: void response_received(int32_t id, bool, string) { if ((id) == _ping_id) _attached = true; } private: + enum Mode { CONNECT_REMOTE, LAUNCH_REMOTE, INTERNAL }; + void server_toggled(); void launch_toggled(); void internal_toggled(); @@ -57,8 +59,7 @@ private: bool gtk_callback(); - CountedPtr<SigClientInterface> _client; - + Mode _mode; int32_t _ping_id; bool _attached; diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp index 7c84d898..93a1cb5b 100644 --- a/src/progs/ingenuity/ControlGroups.cpp +++ b/src/progs/ingenuity/ControlGroups.cpp @@ -14,12 +14,14 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <cmath> +#include <iostream> +#include "ModelEngineInterface.h" #include "ControlGroups.h" #include "ControlPanel.h" #include "PortModel.h" -#include "Controller.h" -#include <cmath> -#include <iostream> +#include "App.h" + using std::cerr; using std::cout; using std::endl; using namespace Ingen::Client; @@ -53,9 +55,10 @@ ControlGroup::ControlGroup(ControlPanel* panel, CountedPtr<PortModel> pm, bool s void ControlGroup::metadata_update(const string& key, const string& value) { - if (key == "user-min") + // FIXME: this isn't right + if (key == "user-min" || key == "min") set_min(atof(value.c_str())); - else if (key == "user-max") + else if (key == "user-max" || key == "max") set_max(atof(value.c_str())); } @@ -79,10 +82,12 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel m_slider.set_increments(1.0, 10.0); // Compensate for crazy plugins + // FIXME + /* if (m_port_model->user_max() <= m_port_model->user_min()) { m_port_model->user_max(m_port_model->user_min() + 1.0); m_slider.set_range(m_port_model->user_min(), m_port_model->user_max()); - } + }*/ m_slider.property_draw_value() = false; set_name(pm->name()); @@ -205,7 +210,7 @@ SliderControlGroup::min_changed() if (m_enable_signal) { char temp_buf[16]; snprintf(temp_buf, 16, "%f", min); - Controller::instance().set_metadata(m_port_model->path(), "user-min", temp_buf); + App::instance().engine()->set_metadata(m_port_model->path(), "user-min", temp_buf); } } @@ -226,7 +231,7 @@ SliderControlGroup::max_changed() if (m_enable_signal) { char temp_buf[16]; snprintf(temp_buf, 16, "%f", max); - Controller::instance().set_metadata(m_port_model->path(), "user-max", temp_buf); + App::instance().engine()->set_metadata(m_port_model->path(), "user-max", temp_buf); } } @@ -281,11 +286,11 @@ SliderControlGroup::slider_pressed(GdkEvent* ev) //cerr << "Pressed: " << ev->type << endl; if (ev->type == GDK_BUTTON_PRESS) { m_enabled = false; - cerr << "SLIDER FIXME\n"; + //cerr << "SLIDER FIXME\n"; //GtkClientInterface::instance()->set_ignore_port(m_port_model->path()); } else if (ev->type == GDK_BUTTON_RELEASE) { m_enabled = true; - cerr << "SLIDER FIXME\n"; + //cerr << "SLIDER FIXME\n"; //GtkClientInterface::instance()->clear_ignore_port(); } diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp index 82d2beba..0841a818 100644 --- a/src/progs/ingenuity/ControlPanel.cpp +++ b/src/progs/ingenuity/ControlPanel.cpp @@ -14,13 +14,14 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "App.h" +#include "ModelEngineInterface.h" #include "ControlPanel.h" #include "PatchModel.h" #include "NodeModel.h" #include "PortModel.h" #include "ControlGroups.h" #include "PatchController.h" -#include "Controller.h" namespace Ingenuity { @@ -124,6 +125,10 @@ ControlPanel::add_port(PortController* port) cg->disable(); else cg->enable(); + + cerr << "FIXME: Control panel add port\n"; + // pm->connection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::connection), pm)) + // pm->disconnection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::disconnection), pm)) } //port->set_control_panel(this); @@ -223,10 +228,10 @@ ControlPanel::value_changed(const Path& port_path, float val) // m_mirror->set_port_value(port_path, val); if (m_all_voices_radio->get_active()) { - Controller::instance().set_port_value(port_path, val); + App::instance().engine()->set_port_value(port_path, val); } else { int voice = m_voice_spinbutton->get_value_as_int(); - Controller::instance().set_port_value(port_path, voice, val); + App::instance().engine()->set_port_value(port_path, voice, val); } } } diff --git a/src/progs/ingenuity/Controller.cpp b/src/progs/ingenuity/Controller.cpp deleted file mode 100644 index a007ece8..00000000 --- a/src/progs/ingenuity/Controller.cpp +++ /dev/null @@ -1,175 +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 "PatchModel.h" -#include "PatchController.h" -#include "OSCModelEngineInterface.h" -#include "PatchLibrarian.h" -#include "Controller.h" -#include "Loader.h" -#include "interface/ClientKey.h" - -namespace Ingenuity { - - -/// Singleton instance -Controller* Controller::_instance = 0; - - -Controller::Controller(const string& engine_url) -: OSCModelEngineInterface(engine_url), - m_patch_librarian(new PatchLibrarian(this)), - m_loader(new Loader(m_patch_librarian)) -{ - m_loader->launch(); -} - - -Controller::~Controller() -{ - // FIXME - //if (is_attached()) { - unregister_client(ClientKey()); // FIXME - //detach(); - //} - - delete m_loader; - delete m_patch_librarian; -} - - -/** "Attach" to the Om engine. - * See documentation OSCModelEngineInterface::attach. - */ -void -Controller::attach(int32_t ping_id) -{ - OSCModelEngineInterface::attach(ping_id, false); -} - -/* -void -Controller::register_client_and_wait() -{ -// int id = get_next_request_id(); -// set_wait_response_id(id); - OSCModelEngineInterface::register_client(); -// wait_for_response(); - cout << "[Controller] Registered with engine. maybe. fixme." << endl; -} -*/ -void Controller::set_engine_url(const string& url) { _engine_url = url; } - -void -Controller::create_node_from_model(const NodeModel* nm) -{ - //push_added_node(nm); - OSCModelEngineInterface::create_node_from_model(nm); - char temp_buf[16]; - snprintf(temp_buf, 16, "%f", nm->x()); - set_metadata(nm->path(), "module-x", temp_buf); - snprintf(temp_buf, 16, "%f", nm->y()); - set_metadata(nm->path(), "module-y", temp_buf); -} - -void -Controller::create_patch_from_model(const PatchModel* pm) -{ - //push_added_patch(pm); - - //int id = get_next_request_id(); - //set_wait_response_id(id); - OSCModelEngineInterface::create_patch_from_model(pm); - if (pm->parent()) { - // wait_for_response(); - char temp_buf[16]; - snprintf(temp_buf, 16, "%f", pm->x()); - set_metadata(pm->path(), "module-x", temp_buf); - snprintf(temp_buf, 16, "%f", pm->y()); - set_metadata(pm->path(), "module-y", temp_buf); - } - enable_patch(pm->path()); -} - - -void -Controller::set_patch_path(const string& path) -{ - m_patch_librarian->path(path); -} - - -/** Load patch in a seperate thread. - * This will return immediately and the patch will be loaded in the background. - * FIXME: merge parameter makes no sense, always true */ -void -Controller::load_patch(PatchModel* model, bool wait, bool merge) -{ - //push_added_patch(model); - m_loader->load_patch(model, wait, merge); -} - - -/** Load patch in a seperate thread. - * This will return immediately and the patch will be saved in the background. */ -void -Controller::save_patch(PatchModel* model, const string& filename, bool recursive) -{ - m_loader->save_patch(model, filename, recursive); -} - - -#if 0 -/** Returns the added node with the given path and removes it from the cache. - */ -NodeModel* -Controller::yank_added_node(const string& path) -{ - NodeModel* nm = NULL; - - for (list<NodeModel*>::iterator i = m_added_nodes.begin(); i != m_added_nodes.end(); ++i) { - if ((*i)->path() == path) { - nm = *i; - m_added_nodes.erase(i); - break; - } - } - - return nm; -} - - -/** Returns the added patch with the given path and removes it from the cache. - */ -PatchModel* -Controller::yank_added_patch(const string& path) -{ - PatchModel* pm = NULL; - - for (list<PatchModel*>::iterator i = m_added_patches.begin(); i != m_added_patches.end(); ++i) { - if ((*i)->path() == path) { - pm = *i; - m_added_patches.erase(i); - break; - } - } - - return pm; -} -#endif - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/Controller.h b/src/progs/ingenuity/Controller.h deleted file mode 100644 index 6a855758..00000000 --- a/src/progs/ingenuity/Controller.h +++ /dev/null @@ -1,110 +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 - */ - -#ifndef CONTROLLER_H -#define CONTROLLER_H - -#include <cassert> -#include <string> -#include <list> -#include <glibmm.h> -#include "PluginModel.h" -#include "OSCModelEngineInterface.h" - -namespace Ingen { namespace Client { -class PatchModel; -class NodeModel; -class PatchLibrarian; -} } - -using std::string; using std::list; -using namespace Ingen::Client; - -namespace Ingenuity { - -class PatchController; -class Loader; - - -/** Singleton engine controller for the entire app. - * - * This is hardly more than a trivial wrapper for OSCModelEngineInterface, suggesting something - * needs a rethink around here.. - * - * This needs to be either eliminated or the name changed to OmController. Probably - * best to keep around in case multiple engine control support comes around? - * - * \ingroup Ingenuity - */ -class Controller : public OSCModelEngineInterface -{ -public: - ~Controller(); - - void attach(int32_t ping_id); - - //void register_client_and_wait(); - - void set_engine_url(const string& url); - - void create_node_from_model(const NodeModel* nm); - - void load_patch(PatchModel* model, bool wait = true, bool merge = false); - void save_patch(PatchModel* model, const string& filename, bool recursive); - - void create_patch_from_model(const PatchModel* pm); - - //void lash_restore_finished(); - - void set_patch_path(const string& path); - - /* - void push_added_node(NodeModel* nm) { m_added_nodes.push_back(nm); } - NodeModel* yank_added_node(const string& path); - - void push_added_patch(PatchModel* pm) { m_added_patches.push_back(pm); } - PatchModel* yank_added_patch(const string& path); - */ - - static void instantiate(const string& engine_url) - { if (!_instance) _instance = new Controller(engine_url); } - - inline static Controller& instance() { assert(_instance); return *_instance; } - -private: - Controller(const string& engine_url); - static Controller* _instance; - - PatchLibrarian* m_patch_librarian; - Loader* m_loader; - - /** Used to cache added nodes so client can remember some values when the - * new node notification comes (location, etc). Used to prevent the node - * jumping locations during the delay between new node and the module-x/y - * metadata notifications */ - //list<NodeModel*> m_added_nodes; - - /** Used to cache added patches in the same was as m_added_nodes. Used to - * rember filename so File->Save can work without prompting (filename can't - * be sent to the server as metadata, because a client on another machine - * doesn't want that information) */ - //list<PatchModel*> m_added_patches; -}; - - -} // namespace Ingenuity - -#endif // CONTROLLER_H diff --git a/src/progs/ingenuity/DSSIController.cpp b/src/progs/ingenuity/DSSIController.cpp index 7419f8c1..6bc75c70 100644 --- a/src/progs/ingenuity/DSSIController.cpp +++ b/src/progs/ingenuity/DSSIController.cpp @@ -20,9 +20,10 @@ #include <dirent.h> #include <unistd.h> #include <sys/stat.h> +#include "App.h" #include "NodeModel.h" #include "DSSIModule.h" -#include "Controller.h" +#include "ModelEngineInterface.h" namespace Ingenuity { @@ -115,7 +116,7 @@ DSSIController::update_program_menu() void DSSIController::send_program_change(int bank, int program) { - Controller::instance().set_program(node_model()->path(), bank, program); + App::instance().engine()->set_program(node_model()->path(), bank, program); } @@ -142,12 +143,14 @@ DSSIController::create_module(OmFlowCanvas* canvas) bool DSSIController::attempt_to_show_gui() { + cerr << "FIXME: DSSI GUI" << endl; +#if 0 // Shamelessley "inspired by" jack-dssi-host // Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton. const bool verbose = false; - string engine_url = Controller::instance().engine_url(); + string engine_url = App::instance().engine()->engine_url(); // Hack off last character if it's a / if (engine_url[engine_url.length()-1] == '/') engine_url = engine_url.substr(0, engine_url.length()-1); @@ -263,6 +266,7 @@ DSSIController::attempt_to_show_gui() free(subpath); free(dllBase); +#endif return false; } diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp index 81726f2a..a847e0fd 100644 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ b/src/progs/ingenuity/LoadPatchWindow.cpp @@ -21,7 +21,8 @@ #include "Configuration.h" #include "PatchController.h" #include "PatchModel.h" -#include "Controller.h" +#include "ModelEngineInterface.h" +#include "Loader.h" namespace Ingenuity { @@ -108,14 +109,14 @@ LoadPatchWindow::ok_clicked() poly = m_poly_spinbutton->get_value_as_int(); if (m_replace) - Controller::instance().clear_patch(m_patch_controller->model()->path()); + App::instance().engine()->clear_patch(m_patch_controller->model()->path()); PatchModel* pm = new PatchModel(m_patch_controller->model()->path(), poly); pm->filename(get_filename()); pm->set_metadata("filename", get_filename()); pm->set_parent(m_patch_controller->patch_model()->parent()); - //Controller::instance().push_added_patch(pm); - Controller::instance().load_patch(pm, true, true); + //App::instance().engine()->push_added_patch(pm); + App::instance().loader()->load_patch(pm, true, true); hide(); } diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 99fd4704..b6c2ca67 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -22,12 +22,12 @@ #include "PatchController.h" #include "PatchView.h" #include "NodeModel.h" -#include "Controller.h" #include "App.h" #include "PatchWindow.h" #include "OmFlowCanvas.h" #include "PatchModel.h" #include "Store.h" +#include "ModelEngineInterface.h" using std::cout; using std::cerr; using std::endl; @@ -294,7 +294,7 @@ LoadPluginWindow::add_clicked() nm->x(m_new_module_x); nm->y(m_new_module_y); - Controller::instance().create_node_from_model(nm); + App::instance().engine()->create_node_from_model(nm); ++m_plugin_name_offset; m_node_name_entry->set_text(generate_module_name(m_plugin_name_offset)); diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp index 0ec98771..832c917f 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp @@ -23,9 +23,10 @@ #include "PatchView.h" #include "OmFlowCanvas.h" #include "NodeModel.h" -#include "Controller.h" #include "PatchModel.h" #include "Configuration.h" +#include "ModelEngineInterface.h" +#include "Loader.h" namespace Ingenuity { @@ -163,7 +164,7 @@ LoadSubpatchWindow::ok_clicked() pm->set_metadata("module-x", temp_buf); snprintf(temp_buf, 16, "%16f", m_new_module_y); pm->set_metadata("module-y", temp_buf); - Controller::instance().load_patch(pm); + App::instance().loader()->load_patch(pm, true, false); App::instance().configuration()->set_patch_folder(pm->filename().substr(0, pm->filename().find_last_of("/"))); diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp index 13a4e896..fed49603 100644 --- a/src/progs/ingenuity/Loader.cpp +++ b/src/progs/ingenuity/Loader.cpp @@ -140,14 +140,25 @@ SaveSessionEvent::execute() //////// Loader ////////// -Loader::Loader(PatchLibrarian* const patch_librarian) -: m_patch_librarian(patch_librarian), +Loader::Loader(CountedPtr<ModelEngineInterface> engine) +: m_patch_librarian(new PatchLibrarian(engine)), m_event(NULL), m_thread_exit_flag(false) { assert(m_patch_librarian != NULL); pthread_mutex_init(&m_mutex, NULL); pthread_cond_init(&m_cond, NULL); + + // FIXME: rework this so the thread is only present when it's doing something (save mem) + launch(); +} + + +Loader::~Loader() +{ + m_thread_exit_flag = true; + pthread_join(m_thread, NULL); + delete m_patch_librarian; } diff --git a/src/progs/ingenuity/Loader.h b/src/progs/ingenuity/Loader.h index df9166d2..7ff6f189 100644 --- a/src/progs/ingenuity/Loader.h +++ b/src/progs/ingenuity/Loader.h @@ -19,18 +19,19 @@ #include <string> #include <cassert> +#include "ModelEngineInterface.h" using std::string; namespace Ingen { namespace Client { class PatchLibrarian; class PatchModel; + class ModelEngineInterface; } } -using Ingen::Client::PatchLibrarian; -using Ingen::Client::PatchModel; - +using namespace Ingen::Client; namespace Ingenuity { - + + /** Event to run in the Loader thread. * * \ingroup Ingenuity @@ -113,15 +114,17 @@ private: * * This is a seperate thread so it can send all the loading message without * blocking everything else, so the app can respond to the incoming events - * caused as a result of the patch loading. + * caused as a result of the patch loading, while the patch loads. * * \ingroup Ingenuity */ class Loader { public: - Loader(PatchLibrarian* const patch_librarian); - ~Loader() { m_thread_exit_flag = true; } + Loader(CountedPtr<ModelEngineInterface> engine); + ~Loader(); + + PatchLibrarian& librarian() { return *m_patch_librarian; } void launch(); void exit() { m_thread_exit_flag = true; } diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am index aa04d3fb..a014286c 100644 --- a/src/progs/ingenuity/Makefile.am +++ b/src/progs/ingenuity/Makefile.am @@ -6,10 +6,16 @@ MAINTAINERCLEANFILES = Makefile.in sharefilesdir = $(pkgdatadir) dist_sharefiles_DATA = ingenuity.glade om-icon.png -AM_CXXFLAGS = -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/client -DPKGDATADIR=\"$(pkgdatadir)\" @GTKMM_CFLAGS@ @LIBGLADEMM_CFLAGS@ @GNOMECANVASMM_CFLAGS@ @LOSC_CFLAGS@ @LASH_CFLAGS@ @FLOWCANVAS_CFLAGS@ -DWITH_RTTI +AM_CXXFLAGS = -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/client -DPKGDATADIR=\"$(pkgdatadir)\" @GTKMM_CFLAGS@ @LIBGLADEMM_CFLAGS@ @GNOMECANVASMM_CFLAGS@ @LOSC_CFLAGS@ @LASH_CFLAGS@ @FLOWCANVAS_CFLAGS@ ingenuity_LDADD = @GTKMM_LIBS@ @LIBGLADEMM_LIBS@ @GNOMECANVASMM_LIBS@ @LOSC_LIBS@ @LASH_LIBS@ @FLOWCANVAS_LIBS@ ../../libs/client/libomclient.la ingenuity_DEPENDENCIES = ../../libs/client/libomclient.la +# FIXME: make engine have a separate include dir +if MONOLITHIC_INGENUITY +AM_CXXFLAGS += -I$(top_srcdir)/src/libs +ingenuity_LDADD += @JACK_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @SLV2_LIBS@ -lrt ../../libs/engine/libingen.la +ingenuity_DEPENDENCIES += ../../libs/engine/libingen.la +endif bin_PROGRAMS = ingenuity ingenuity_SOURCES = \ @@ -24,8 +30,6 @@ ingenuity_SOURCES = \ Configuration.cpp \ GladeFactory.h \ GladeFactory.cpp \ - Controller.h \ - Controller.cpp \ GtkObjectController.h \ GtkObjectController.cpp \ PatchController.h \ diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp index 84f9bb7f..49122a21 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ b/src/progs/ingenuity/NewSubpatchWindow.cpp @@ -14,12 +14,13 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "App.h" +#include "ModelEngineInterface.h" #include "NewSubpatchWindow.h" #include "PatchController.h" #include "PatchView.h" #include "OmFlowCanvas.h" #include "NodeModel.h" -#include "Controller.h" #include "PatchModel.h" namespace Ingenuity { @@ -98,7 +99,7 @@ NewSubpatchWindow::ok_clicked() pm->set_metadata("module-x", temp_buf); snprintf(temp_buf, 16, "%16f", m_new_module_y); pm->set_metadata("module-y", temp_buf); - Controller::instance().create_patch_from_model(pm); + App::instance().engine()->create_patch_from_model(pm); hide(); } diff --git a/src/progs/ingenuity/NodeController.cpp b/src/progs/ingenuity/NodeController.cpp index bd98346b..331a714e 100644 --- a/src/progs/ingenuity/NodeController.cpp +++ b/src/progs/ingenuity/NodeController.cpp @@ -17,6 +17,7 @@ #include "NodeController.h" #include <iostream> #include <gtkmm.h> +#include "App.h" #include "OmModule.h" #include "NodeModel.h" #include "PortModel.h" @@ -28,11 +29,11 @@ #include "OmFlowCanvas.h" #include "RenameWindow.h" #include "GladeFactory.h" -#include "Controller.h" #include "PatchWindow.h" #include "PatchModel.h" #include "NodePropertiesWindow.h" #include "Store.h" +#include "ModelEngineInterface.h" using std::cerr; using std::endl; namespace Ingenuity { @@ -199,7 +200,7 @@ NodeController::add_port(CountedPtr<PortModel> pm) assert(pm->parent() == node_model()); assert(node_model()->get_port(pm->name()) == pm); - cout << "[NodeController] Adding port " << pm->path() << endl; + //cout << "[NodeController] Adding port " << pm->path() << endl; // FIXME: leak PortController* pc = new PortController(pm); @@ -240,7 +241,7 @@ NodeController::show_control_window() void NodeController::on_menu_destroy() { - Controller::instance().destroy(node_model()->path()); + App::instance().engine()->destroy(node_model()->path()); } @@ -298,7 +299,7 @@ NodeController::on_menu_clone() nm->polyphonic(node_model()->polyphonic()); nm->x(node_model()->x() + 20); nm->y(node_model()->y() + 20); - Controller::instance().create_node_from_model(nm); + App::instance().engine()->create_node_from_model(nm); */ } @@ -306,13 +307,13 @@ NodeController::on_menu_clone() void NodeController::on_menu_learn() { - Controller::instance().midi_learn(node_model()->path()); + App::instance().engine()->midi_learn(node_model()->path()); } void NodeController::on_menu_disconnect_all() { - Controller::instance().disconnect_all(node_model()->path()); + App::instance().engine()->disconnect_all(node_model()->path()); } diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp index 7d4bd3a4..ac5f8beb 100644 --- a/src/progs/ingenuity/OmFlowCanvas.cpp +++ b/src/progs/ingenuity/OmFlowCanvas.cpp @@ -17,7 +17,8 @@ #include "OmFlowCanvas.h" #include <cassert> #include <flowcanvas/FlowCanvas.h> -#include "Controller.h" +#include "App.h" +#include "ModelEngineInterface.h" #include "PatchController.h" #include "PatchModel.h" #include "PatchWindow.h" @@ -106,19 +107,19 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) + src->name() + "-" + dst->name()); nm->x(dst->module()->property_x() - dst->module()->width() - 20); nm->y(dst->module()->property_y()); - Controller::instance().create_node_from_model(nm); - Controller::instance().connect(src->model()->path(), nm->path() + "/MIDI_In"); - Controller::instance().connect(nm->path() + "/Out_(CR)", dst->model()->path()); - Controller::instance().midi_learn(nm->path()); + App::instance().engine()->create_node_from_model(nm); + App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); + App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); + App::instance().engine()->midi_learn(nm->path()); // Set control node range to port's user range - Controller::instance().set_port_value_queued(nm->path().base_path() + "Min", + App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Min", atof(dst->model()->get_metadata("user-min").c_str())); - Controller::instance().set_port_value_queued(nm->path().base_path() + "Max", + App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Max", atof(dst->model()->get_metadata("user-max").c_str())); } else { - Controller::instance().connect(src->model()->path(), + App::instance().engine()->connect(src->model()->path(), dst->model()->path()); } } @@ -130,7 +131,7 @@ OmFlowCanvas::disconnect(const Port* src_port, const Port* dst_port) assert(src_port != NULL); assert(dst_port != NULL); - Controller::instance().disconnect(((OmPort*)src_port)->model()->path(), + App::instance().engine()->disconnect(((OmPort*)src_port)->model()->path(), ((OmPort*)dst_port)->model()->path()); } @@ -168,7 +169,7 @@ void OmFlowCanvas::destroy_selected() { for (list<Module*>::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) - Controller::instance().destroy(((OmModule*)(*m))->node()->path()); + App::instance().engine()->destroy(((OmModule*)(*m))->node()->path()); } @@ -193,13 +194,13 @@ void OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_output) { const Path& path = m_patch_controller->path().base_path() + generate_port_name(name); - Controller::instance().create_port(path, type, is_output); + App::instance().engine()->create_port(path, type, is_output); char temp_buf[16]; snprintf(temp_buf, 16, "%d", m_last_click_x); - Controller::instance().set_metadata(path, "module-x", temp_buf); + App::instance().engine()->set_metadata(path, "module-x", temp_buf); snprintf(temp_buf, 16, "%d", m_last_click_y); - Controller::instance().set_metadata(path, "module-y", temp_buf); + App::instance().engine()->set_metadata(path, "module-y", temp_buf); } @@ -221,7 +222,7 @@ void OmFlowCanvas::menu_add_audio_input() { string name = "audio_in"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "AUDIO", false); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", false); } @@ -229,7 +230,7 @@ void OmFlowCanvas::menu_add_audio_output() { string name = "audio_out"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "AUDIO", true); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", true); } @@ -237,7 +238,7 @@ void OmFlowCanvas::menu_add_control_input() { string name = "control_in"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "CONTROL", false); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", false); } @@ -245,7 +246,7 @@ void OmFlowCanvas::menu_add_control_output() { string name = "control_out"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "CONTROL", true); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", true); } @@ -253,7 +254,7 @@ void OmFlowCanvas::menu_add_midi_input() { string name = "midi_in"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "MIDI", false); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", false); } @@ -261,7 +262,7 @@ void OmFlowCanvas::menu_add_midi_output() { string name = "midi_out"; - Controller::instance().create_port(m_patch_controller->path().base_path() + name, "MIDI", true); + App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", true); } */ diff --git a/src/progs/ingenuity/OmModule.cpp b/src/progs/ingenuity/OmModule.cpp index 2de109ea..e34665a7 100644 --- a/src/progs/ingenuity/OmModule.cpp +++ b/src/progs/ingenuity/OmModule.cpp @@ -16,7 +16,8 @@ #include "OmModule.h" #include <cassert> -#include "Controller.h" +#include "App.h" +#include "ModelEngineInterface.h" #include "OmFlowCanvas.h" #include "PatchModel.h" #include "NodeModel.h" @@ -64,12 +65,12 @@ OmModule::store_location() m_node->node_model()->x(property_x()); snprintf(temp_buf, 16, "%f", m_node->node_model()->x()); m_node->node_model()->set_metadata("module-x", temp_buf); // just in case? - Controller::instance().set_metadata(m_node->node_model()->path(), "module-x", temp_buf); + App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-x", temp_buf); m_node->node_model()->y(property_y()); snprintf(temp_buf, 16, "%f", m_node->node_model()->y()); m_node->node_model()->set_metadata("module-y", temp_buf); // just in case? - Controller::instance().set_metadata(m_node->node_model()->path(), "module-y", temp_buf); + App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-y", temp_buf); } diff --git a/src/progs/ingenuity/OmPortModule.cpp b/src/progs/ingenuity/OmPortModule.cpp index c1a54378..e5c5fca6 100644 --- a/src/progs/ingenuity/OmPortModule.cpp +++ b/src/progs/ingenuity/OmPortModule.cpp @@ -16,7 +16,8 @@ #include "OmPortModule.h" #include <cassert> -#include "Controller.h" +#include "App.h" +#include "ModelEngineInterface.h" #include "OmFlowCanvas.h" #include "PatchModel.h" #include "NodeModel.h" @@ -50,12 +51,12 @@ OmPortModule::store_location() //m_port->port_model()->x(property_x()); snprintf(temp_buf, 16, "%f", property_x().get_value()); //m_port->port_model()->set_metadata("module-x", temp_buf); // just in case? - Controller::instance().set_metadata(m_port->port_model()->path(), "module-x", temp_buf); + App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-x", temp_buf); //m_port->port_model()->y(property_y()); snprintf(temp_buf, 16, "%f", property_y().get_value()); //m_port->port_model()->set_metadata("module-y", temp_buf); // just in case? - Controller::instance().set_metadata(m_port->port_model()->path(), "module-y", temp_buf); + App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-y", temp_buf); } diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp index 49c7491c..86e548c7 100644 --- a/src/progs/ingenuity/PatchController.cpp +++ b/src/progs/ingenuity/PatchController.cpp @@ -27,7 +27,6 @@ #include "PatchView.h" #include "flowcanvas/Module.h" #include "PluginModel.h" -#include "Controller.h" #include "SubpatchModule.h" #include "DSSIModule.h" #include "PatchWindow.h" @@ -390,34 +389,8 @@ PatchController::create_connection(CountedPtr<ConnectionModel> cm) cm->src_port_path().name(), dst_parent_name, cm->dst_port_path().name()); - - // Disable control slider from destination node control window - - cerr << "FIXME: create_connection\n"; - /*PortController* p = Store::instance().port(cm->dst_port_path()); - assert(p != NULL); - - if (p->control_panel() != NULL) - p->control_panel()->disable_port(p->path());*/ - - // FIXME: don't use canvas as a model (search object store) - /*OmModule* m = (OmModule*)m_patch_view->canvas()->find_module( - cm->dst_port_path().parent().name()); - - if (m != NULL) { - OmPort* p = m->port(cm->dst_port_path().name()); - if (p != NULL && p->connections().size() == 1) { - p->model()->connected(true); - assert(m->node_model()->controller() != NULL); - NodeControlWindow* cw = (((NodeController*) - m->node_model()->controller())->control_window()); - if (cw != NULL) - cw->control_panel()->disable_port(cm->dst_port_path()); - } - }*/ } - NodeController* PatchController::create_controller_for_node(CountedPtr<NodeModel> node) { @@ -529,8 +502,6 @@ PatchController::add_port(CountedPtr<PortModel> pm) assert(pm->parent() == m_patch_model); assert(patch_model()->get_port(pm->name())); - cerr << "ADDING PORT " << pm->name() << "TO PATCH: " << patch_model()->path() << endl; - //cerr << "[PatchController] Adding port " << pm->path() << endl; /*if (patch_model()->get_port(pm->name())) { diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp index 0c5fdcf0..47bfc485 100644 --- a/src/progs/ingenuity/PatchTreeWindow.cpp +++ b/src/progs/ingenuity/PatchTreeWindow.cpp @@ -14,8 +14,10 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "App.h" +#include "ModelEngineInterface.h" +#include "OSCEngineSender.h" #include "PatchTreeWindow.h" -#include "Controller.h" #include "PatchController.h" #include "PatchWindow.h" #include "SubpatchModule.h" @@ -70,7 +72,8 @@ PatchTreeWindow::add_patch(PatchController* pc) Gtk::TreeModel::iterator iter = m_patch_treestore->append(); Gtk::TreeModel::Row row = *iter; if (pm->path() == "/") { - string root_name = Controller::instance().engine_url(); + CountedPtr<OSCEngineSender> osc_sender = App::instance().engine(); + string root_name = osc_sender ? osc_sender->engine_url() : "Internal"; // Hack off trailing '/' if it's there (ugly) //if (root_name.substr(root_name.length()-1,1) == "/") // root_name = root_name.substr(0, root_name.length()-1); @@ -178,12 +181,12 @@ PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) if ( ! pc->patch_model()->enabled()) { if (m_enable_signal) - Controller::instance().enable_patch(patch_path); + App::instance().engine()->enable_patch(patch_path); //pc->enable(); row[m_patch_tree_columns.enabled_col] = true; } else { if (m_enable_signal) - Controller::instance().disable_patch(patch_path); + App::instance().engine()->disable_patch(patch_path); //pc->disable(); row[m_patch_tree_columns.enabled_col] = false; } diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp index 41e74b1c..644e0253 100644 --- a/src/progs/ingenuity/PatchView.cpp +++ b/src/progs/ingenuity/PatchView.cpp @@ -19,6 +19,7 @@ #include <cassert> #include <fstream> #include "App.h" +#include "ModelEngineInterface.h" #include "OmFlowCanvas.h" #include "PatchController.h" #include "LoadPluginWindow.h" @@ -28,7 +29,6 @@ #include "NodeControlWindow.h" #include "PatchPropertiesWindow.h" #include "PatchTreeWindow.h" -#include "Controller.h" namespace Ingenuity { @@ -101,10 +101,10 @@ PatchView::process_toggled() return; if (m_process_checkbutton->get_active()) { - Controller::instance().enable_patch(m_patch->model()->path()); + App::instance().engine()->enable_patch(m_patch->model()->path()); App::instance().patch_tree()->patch_enabled(m_patch->model()->path()); } else { - Controller::instance().disable_patch(m_patch->model()->path()); + App::instance().engine()->disable_patch(m_patch->model()->path()); App::instance().patch_tree()->patch_disabled(m_patch->model()->path()); } } diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index 69e8f7de..60fa966b 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -19,6 +19,7 @@ #include <cassert> #include <fstream> #include "App.h" +#include "ModelEngineInterface.h" #include "PatchView.h" #include "OmFlowCanvas.h" #include "PatchController.h" @@ -32,10 +33,10 @@ #include "ConfigWindow.h" #include "MessagesWindow.h" #include "PatchTreeWindow.h" -#include "Controller.h" #include "BreadCrumb.h" #include "Store.h" #include "ConnectWindow.h" +#include "Loader.h" namespace Ingenuity { @@ -88,7 +89,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad m_load_subpatch_window->set_transient_for(*this); m_menu_view_control_window->property_sensitive() = false; - //m_status_bar->push(Controller::instance().engine_url()); + //m_status_bar->push(App::instance().engine()->engine_url()); //m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false); /*m_menu_open->signal_activate().connect( @@ -397,7 +398,7 @@ PatchWindow::event_save() if (model->filename() == "") event_save_as(); else - Controller::instance().save_patch(model, model->filename(), false); + App::instance().loader()->save_patch(model, model->filename(), false); } @@ -452,7 +453,7 @@ PatchWindow::event_save_as() fin.close(); if (confirm) { - Controller::instance().save_patch(m_patch->patch_model().get(), filename, recursive); + App::instance().loader()->save_patch(m_patch->patch_model().get(), filename, recursive); m_patch->patch_model()->filename(filename); } } @@ -544,7 +545,7 @@ PatchWindow::event_quit() if (ret == 1) { App::instance().quit(); } else if (ret == 2) { - Controller::instance().quit(); + App::instance().engine()->quit(); App::instance().quit(); } // Otherwise cancelled, do nothing @@ -554,14 +555,14 @@ PatchWindow::event_quit() void PatchWindow::event_destroy() { - Controller::instance().destroy(m_patch->model()->path()); + App::instance().engine()->destroy(m_patch->model()->path()); } void PatchWindow::event_clear() { - Controller::instance().clear_patch(m_patch->model()->path()); + App::instance().engine()->clear_patch(m_patch->model()->path()); } void diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp index a26c14eb..0668a9e0 100644 --- a/src/progs/ingenuity/PortController.cpp +++ b/src/progs/ingenuity/PortController.cpp @@ -57,7 +57,7 @@ PortController::destroy() void PortController::create_module(OmFlowCanvas* canvas) { - cerr << "Creating port module " << m_model->path() << endl; + //cerr << "Creating port module " << m_model->path() << endl; const string x_str = m_model->get_metadata("module-x"); const string y_str = m_model->get_metadata("module-y"); @@ -99,8 +99,6 @@ PortController::metadata_update(const string& key, const string& value) m_control_panel->set_range_max(m_model->path(), atof(value.c_str())); } */ - cerr << "FIXME: PortController::metadata_update" << endl; - if (m_module != NULL) { if (key == "module-x") { float x = atof(value.c_str()); diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp index 52f5bc98..dfe4b07b 100644 --- a/src/progs/ingenuity/RenameWindow.cpp +++ b/src/progs/ingenuity/RenameWindow.cpp @@ -17,11 +17,11 @@ #include "RenameWindow.h" #include <cassert> #include <string> -#include "Controller.h" #include "ObjectModel.h" #include "GtkObjectController.h" #include "Store.h" #include "App.h" +#include "ModelEngineInterface.h" using std::string; namespace Ingenuity { @@ -105,7 +105,7 @@ RenameWindow::ok_clicked() assert(name.length() > 0); assert(name.find("/") == string::npos); - Controller::instance().rename(m_object->model()->path(), name); + App::instance().engine()->rename(m_object->model()->path(), name); hide(); } diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp index 3133c7c9..36fecff3 100644 --- a/src/progs/ingenuity/SubpatchModule.cpp +++ b/src/progs/ingenuity/SubpatchModule.cpp @@ -17,6 +17,8 @@ #include "SubpatchModule.h" #include <cassert> #include <iostream> +#include "App.h" +#include "ModelEngineInterface.h" #include "OmModule.h" #include "NodeControlWindow.h" #include "PatchModel.h" @@ -24,7 +26,6 @@ #include "OmFlowCanvas.h" #include "PatchController.h" #include "OmPort.h" -#include "Controller.h" using std::cerr; using std::cout; using std::endl; namespace Ingenuity { @@ -96,7 +97,7 @@ SubpatchModule::show_dialog() void SubpatchModule::menu_remove() { - Controller::instance().destroy(m_patch->model()->path()); + App::instance().engine()->destroy(m_patch->model()->path()); } } // namespace Ingenuity diff --git a/src/progs/ingenuity/main.cpp b/src/progs/ingenuity/main.cpp index 034a1c85..d200c3d6 100644 --- a/src/progs/ingenuity/main.cpp +++ b/src/progs/ingenuity/main.cpp @@ -18,34 +18,14 @@ #include "cmdline.h" #include "ConnectWindow.h" #include "App.h" -#include "Store.h" -#include "Controller.h" #include "Configuration.h" #ifdef HAVE_LASH #include "LashController.h" #endif -#include "ThreadedSigClientInterface.h" -#include "OSCClientReceiver.h" -using Ingen::Shared::ClientInterface; using namespace Ingenuity; -class OSCSigEmitter : public OSCClientReceiver, public ThreadedSigClientInterface { -public: - OSCSigEmitter(size_t queue_size, int listen_port) - : Ingen::Shared::ClientInterface() - , OSCClientReceiver(listen_port) - , ThreadedSigClientInterface(queue_size) - { - Glib::signal_timeout().connect( - sigc::mem_fun((ThreadedSigClientInterface*)this, - &ThreadedSigClientInterface::emit_signals), - 5, G_PRIORITY_DEFAULT_IDLE); - } -}; - - int main(int argc, char** argv) { @@ -68,26 +48,22 @@ main(int argc, char** argv) Gnome::Canvas::init(); Gtk::Main gtk_main(argc, argv); - CountedPtr<SigClientInterface> emitter(new OSCSigEmitter(1024, 16181)); - /* Instantiate all singletons */ - App::instantiate(emitter); - - Controller::instantiate(engine_url); + App::instantiate(); /* Load settings */ App::instance().configuration()->load_settings(); App::instance().configuration()->apply_settings(); - #ifdef HAVE_LASH +#ifdef HAVE_LASH lash_args_t* lash_args = lash_extract_args(&argc, &argv); - #endif +#endif //gtk_main.signal_quit().connect(sigc::ptr_fun(cleanup)); - #ifdef HAVE_LASH +#ifdef HAVE_LASH LashController* lash_controller = new LashController(lash_args); - #endif +#endif App::instance().connect_window()->start(); gtk_main.run(); diff --git a/src/progs/server/Makefile.am b/src/progs/server/Makefile.am index 7b0f1625..fc5b770b 100644 --- a/src/progs/server/Makefile.am +++ b/src/progs/server/Makefile.am @@ -1,11 +1,11 @@ -AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events -fno-exceptions -fno-rtti +AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events -fno-exceptions MAINTAINERCLEANFILES = Makefile.in # # Stand-alone engine # -if BUILD_ENGINE +if BUILD_SERVER bin_PROGRAMS = ingen ingen_DEPENDENCIES = ../../libs/engine/libingen.la @@ -16,7 +16,7 @@ ingen_SOURCES = \ cmdline.h \ cmdline.c -endif # BUILD_ENGINE +endif # BUILD_SERVER ## diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp index 926a739f..cd79a7b4 100644 --- a/src/progs/server/main.cpp +++ b/src/progs/server/main.cpp @@ -34,7 +34,7 @@ using std::cout; using std::endl; using std::cerr; using namespace Ingen; -Engine* engine; +CountedPtr<Engine> engine; void @@ -140,7 +140,7 @@ main(int argc, char** argv) engine = new Engine(); OSCEngineReceiver* receiver = new OSCEngineReceiver( - *engine, pre_processor_queue_size, args_info.port_arg); + engine, pre_processor_queue_size, args_info.port_arg); receiver->activate(); engine->set_event_source(receiver); @@ -157,7 +157,6 @@ main(int argc, char** argv) delete lash_driver; #endif - delete engine; delete receiver; } |