From 4fccf65944bbae7fa9fb4029ef18197eafcd4453 Mon Sep 17 00:00:00 2001 From: dave Date: Sat, 14 Oct 2006 05:51:23 +0000 Subject: [PATCH] Fixed Patchage dynamic reconnection. git-svn-id: http://svn.drobilla.net/lad@166 a436a847-0d15-0410-975c-d299462d15a1 --- flowcanvas/configure.ac | 16 +++--- flowcanvas/flowcanvas/Module.h | 3 +- flowcanvas/src/FlowCanvas.cpp | 90 ++++++++++++++++++++-------------- patchage/configure.ac | 10 ++++ patchage/src/AlsaDriver.cpp | 2 +- patchage/src/JackDriver.cpp | 10 ++-- patchage/src/LashDriver.cpp | 1 - patchage/src/Patchage.cpp | 15 ++++-- raul/raul/SharedPtr.h | 5 ++ 9 files changed, 94 insertions(+), 58 deletions(-) diff --git a/flowcanvas/configure.ac b/flowcanvas/configure.ac index f91e3959..912dc9bf 100644 --- a/flowcanvas/configure.ac +++ b/flowcanvas/configure.ac @@ -41,14 +41,14 @@ CXXFLAGS="$CXXFLAGS -pipe -fmessage-length=139 -fdiagnostics-show-location=every CFLAGS="$CFLAGS -pipe -fmessage-length=139 -fdiagnostics-show-location=every-line" # Boost shared_ptr debugging -pointer_debug="no" -AC_ARG_ENABLE(pointer_debug, - [AS_HELP_STRING(--enable-pointer-debug, [Enable smart pointer debugging (no)])], - [pointer_debug="$enableval"]) -if test "$pointer_debug" = "yes"; then - CFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" - CXXFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" -fi +#pointer_debug="no" +#AC_ARG_ENABLE(pointer_debug, +# [AS_HELP_STRING(--enable-pointer-debug, [Enable smart pointer debugging (no)])], +# [pointer_debug="$enableval"]) +#if test "$pointer_debug" = "yes"; then +# CFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" +# CXXFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" +#fi PKG_CHECK_MODULES(GTKMM, gtkmm-2.4) PKG_CHECK_MODULES(GNOMECANVASMM, libgnomecanvasmm-2.6) diff --git a/flowcanvas/flowcanvas/Module.h b/flowcanvas/flowcanvas/Module.h index 0c4cc4bb..e4e07ecf 100644 --- a/flowcanvas/flowcanvas/Module.h +++ b/flowcanvas/flowcanvas/Module.h @@ -47,6 +47,7 @@ public: inline boost::shared_ptr get_port(const string& name) const; void add_port(boost::shared_ptr port); + void remove_port(boost::shared_ptr port); boost::shared_ptr remove_port(const string& name); boost::shared_ptr port_at(double x, double y); @@ -82,8 +83,6 @@ public: int base_color() const { return 0x1F2A3CFF; } protected: - void remove_port(boost::shared_ptr port); - bool module_event(GdkEvent* event); bool is_within(const Gnome::Canvas::Rect& rect); diff --git a/flowcanvas/src/FlowCanvas.cpp b/flowcanvas/src/FlowCanvas.cpp index 015bdd32..707b8be0 100644 --- a/flowcanvas/src/FlowCanvas.cpp +++ b/flowcanvas/src/FlowCanvas.cpp @@ -412,8 +412,8 @@ FlowCanvas::are_connected(boost::shared_ptr port1, boost::shared_ptr ConnectionList::const_iterator c; for (c = m_connections.begin(); c != m_connections.end(); ++c) { - boost::shared_ptr src = (*c)->source().lock(); - boost::shared_ptr dst = (*c)->dest().lock(); + const boost::shared_ptr src = (*c)->source().lock(); + const boost::shared_ptr dst = (*c)->dest().lock(); if (!src || !dst) continue; @@ -432,8 +432,8 @@ FlowCanvas::get_connection(boost::shared_ptr port1, boost::shared_ptr src = (*i)->source().lock(); - boost::shared_ptr dst = (*i)->dest().lock(); + const boost::shared_ptr src = (*i)->source().lock(); + const boost::shared_ptr dst = (*i)->dest().lock(); if (!src || !dst) continue; @@ -482,8 +482,8 @@ FlowCanvas::add_connection(boost::shared_ptr port1, boost::shared_ptr c) { - boost::shared_ptr src = c->source().lock(); - boost::shared_ptr dst = c->dest().lock(); + const boost::shared_ptr src = c->source().lock(); + const boost::shared_ptr dst = c->dest().lock(); if (src && dst) { src->add_connection(c); @@ -505,10 +505,16 @@ FlowCanvas::remove_connection(boost::shared_ptr connection) ConnectionList::iterator i = find(m_connections.begin(), m_connections.end(), connection); if (i != m_connections.end()) { - boost::shared_ptr c = *i; + const boost::shared_ptr c = *i; + + const boost::shared_ptr src = c->source().lock(); + const boost::shared_ptr dst = c->dest().lock(); - c->source().lock()->remove_connection(c); - c->dest().lock()->remove_connection(c); + if (src) + src->remove_connection(c); + + if (dst) + dst->remove_connection(c); m_connections.erase(i); } @@ -532,8 +538,12 @@ FlowCanvas::destroy_all_flagged_connections() if ((*c)->flagged()) { ConnectionList::iterator next = c; ++next; - (*c)->source().lock()->remove_connection(*c); - (*c)->dest().lock()->remove_connection(*c); + const boost::shared_ptr src = (*c)->source().lock(); + const boost::shared_ptr dst = (*c)->dest().lock(); + if (src) + src->remove_connection(*c); + if (dst) + dst->remove_connection(*c); m_connections.erase(c); c = next; } else { @@ -551,8 +561,12 @@ FlowCanvas::destroy_all_connections() m_remove_objects = false; for (ConnectionList::iterator c = m_connections.begin(); c != m_connections.end(); ++c) { - (*c)->source().lock()->remove_connection(*c); - (*c)->dest().lock()->remove_connection(*c); + const boost::shared_ptr src = (*c)->source().lock(); + const boost::shared_ptr dst = (*c)->dest().lock(); + if (src) + src->remove_connection(*c); + if (dst) + dst->remove_connection(*c); } m_connections.clear(); @@ -898,18 +912,20 @@ FlowCanvas::connection_drag_handler(GdkEvent* event) if (p) { boost::shared_ptr m = p->module().lock(); - if (p != m_selected_port) { - if (snapped_port) - snapped_port->set_highlighted(false); - p->set_highlighted(true); - snapped_port = p; + if (m) { + if (p != m_selected_port) { + if (snapped_port) + snapped_port->set_highlighted(false); + p->set_highlighted(true); + snapped_port = p; + } + drag_module->property_x() = m->property_x().get_value(); + drag_module->m_module_box.property_x2() = m->m_module_box.property_x2().get_value(); + drag_module->property_y() = m->property_y().get_value(); + drag_module->m_module_box.property_y2() = m->m_module_box.property_y2().get_value(); + drag_port->property_x() = p->property_x().get_value(); + drag_port->property_y() = p->property_y().get_value(); } - drag_module->property_x() = m->property_x().get_value(); - drag_module->m_module_box.property_x2() = m->m_module_box.property_x2().get_value(); - drag_module->property_y() = m->property_y().get_value(); - drag_module->m_module_box.property_y2() = m->m_module_box.property_y2().get_value(); - drag_port->property_x() = p->property_x().get_value(); - drag_port->property_y() = p->property_y().get_value(); } else { // off the port now, unsnap if (snapped_port) snapped_port->set_highlighted(false); @@ -939,18 +955,20 @@ FlowCanvas::connection_drag_handler(GdkEvent* event) if (p && p->is_input() != m_connect_port->is_input()) { boost::shared_ptr m = p->module().lock(); - p->set_highlighted(true); - snapped_port = p; - snapped = true; - // Make drag module and port exactly the same size/loc as the snapped - drag_module->move_to(m->property_x().get_value(), m->property_y().get_value()); - drag_module->set_width(m->width()); - drag_module->set_height(m->height()); - drag_port->property_x() = p->property_x().get_value(); - drag_port->property_y() = p->property_y().get_value(); - // Make the drag port as wide as the snapped port so the connection coords are the same - drag_port->m_rect.property_x2() = p->m_rect.property_x2().get_value(); - drag_port->m_rect.property_y2() = p->m_rect.property_y2().get_value(); + if (m) { + p->set_highlighted(true); + snapped_port = p; + snapped = true; + // Make drag module and port exactly the same size/loc as the snapped + drag_module->move_to(m->property_x().get_value(), m->property_y().get_value()); + drag_module->set_width(m->width()); + drag_module->set_height(m->height()); + drag_port->property_x() = p->property_x().get_value(); + drag_port->property_y() = p->property_y().get_value(); + // Make the drag port as wide as the snapped port so the connection coords are the same + drag_port->m_rect.property_x2() = p->m_rect.property_x2().get_value(); + drag_port->m_rect.property_y2() = p->m_rect.property_y2().get_value(); + } } else { drag_module->property_x() = x; drag_module->property_y() = y - 7; // FIXME: s#7#cursor_height/2# diff --git a/patchage/configure.ac b/patchage/configure.ac index 4e3bedd5..a3c18a43 100644 --- a/patchage/configure.ac +++ b/patchage/configure.ac @@ -98,6 +98,16 @@ if test "$strict" = "yes"; then CXXFLAGS="$CXXFLAGS -ansi -Wall -Wextra -Wno-unused-parameter -Wconversion -Winit-self -Woverloaded-virtual -Wsign-promo" fi +# Boost shared_ptr debugging +pointer_debug="no" +AC_ARG_ENABLE(pointer_debug, + [AS_HELP_STRING(--enable-pointer-debug, [Enable smart pointer debugging (no)])], + [pointer_debug="$enableval"]) +if test "$pointer_debug" = "yes"; then + CFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" + CXXFLAGS+=" -DBOOST_SP_ENABLE_DEBUG_HOOKS" +fi + # Bolt on a few specific flags to CXXFLAGS that should always be used CXXFLAGS="$CXXFLAGS -pipe -Wall -fmessage-length=139 -fdiagnostics-show-location=every-line" CFLAGS="$CFLAGS -pipe -Wall -fmessage-length=139 -fdiagnostics-show-location=every-line" diff --git a/patchage/src/AlsaDriver.cpp b/patchage/src/AlsaDriver.cpp index f868af9e..eb93dac3 100644 --- a/patchage/src/AlsaDriver.cpp +++ b/patchage/src/AlsaDriver.cpp @@ -73,7 +73,7 @@ AlsaDriver::attach(bool /*launch_daemon*/) void AlsaDriver::detach() { - if (m_seq != NULL) { + if (m_seq) { pthread_cancel(m_refresh_thread); pthread_join(m_refresh_thread, NULL); snd_seq_close(m_seq); diff --git a/patchage/src/JackDriver.cpp b/patchage/src/JackDriver.cpp index 8bfea6f4..eef6b2f4 100644 --- a/patchage/src/JackDriver.cpp +++ b/patchage/src/JackDriver.cpp @@ -75,12 +75,12 @@ JackDriver::attach(bool launch_daemon) void JackDriver::detach() { - if (m_client != NULL) { + if (m_client) { jack_deactivate(m_client); jack_client_close(m_client); m_client = NULL; - signal_detached.emit(); destroy_all_ports(); + signal_detached.emit(); m_app->status_message("[JACK] Detached"); } } @@ -97,12 +97,12 @@ JackDriver::destroy_all_ports() for (PortVector::iterator p = ports.begin(); p != ports.end(); ++p) { boost::shared_ptr port = boost::dynamic_pointer_cast(*p); if (port && port->type() == JACK_AUDIO || port->type() == JACK_MIDI) { - port.reset(); + m->second->remove_port(port); } } if (m->second->ports().empty()) - m->second.reset(); + m_app->canvas()->remove_module(m->second->name()); } } @@ -144,8 +144,8 @@ JackDriver::refresh() if (m_client == NULL) { // Shutdown if (m_is_dirty) { - signal_detached.emit(); destroy_all_ports(); + signal_detached.emit(); } m_is_dirty = false; m_mutex.unlock(); diff --git a/patchage/src/LashDriver.cpp b/patchage/src/LashDriver.cpp index 7989aa96..73478422 100644 --- a/patchage/src/LashDriver.cpp +++ b/patchage/src/LashDriver.cpp @@ -67,7 +67,6 @@ LashDriver::attach(bool launch_daemon) void LashDriver::detach() { - // FIXME: send some notification that we're gone?? m_client = NULL; m_app->status_message("[LASH] Detached"); signal_detached.emit(); diff --git a/patchage/src/Patchage.cpp b/patchage/src/Patchage.cpp index ace5e244..bf7ad88d 100644 --- a/patchage/src/Patchage.cpp +++ b/patchage/src/Patchage.cpp @@ -28,6 +28,8 @@ #include "LashDriver.h" #endif +// FIXME: include to avoid undefined reference to boost SP debug hooks stuff +#include Patchage::Patchage(int argc, char** argv) : @@ -47,6 +49,8 @@ Patchage::Patchage(int argc, char** argv) m_state_manager = new StateManager(); m_canvas = boost::shared_ptr(new PatchageFlowCanvas(this, 1600*2, 1200*2)); m_jack_driver = new JackDriver(this); + m_jack_driver->signal_detached.connect(sigc::mem_fun(this, &Patchage::queue_refresh)); + #ifdef HAVE_ALSA m_alsa_driver = new AlsaDriver(this); #endif @@ -108,6 +112,7 @@ Patchage::Patchage(int argc, char** argv) xml->get_widget("zoom_normal_but", m_zoom_normal_button); update_state(); + m_main_paned->set_position(m_main_paned->get_height() - 20); m_canvas_scrolledwindow->add(*m_canvas); //m_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(m_canvas, &FlowCanvas::scroll_event_handler)); @@ -142,7 +147,6 @@ Patchage::Patchage(int argc, char** argv) m_menu_help_about->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_help_about)); attach_menu_items(); - m_main_paned->set_position(m_main_paned->get_height() - 20); m_canvas->show(); } @@ -231,15 +235,16 @@ Patchage::update_state() for (ModuleMap::iterator i = m_canvas->modules().begin(); i != m_canvas->modules().end(); ++i) (*i).second->load_location(); - cerr << "[Patchage] Resizing window: (" << m_state_manager->get_window_size().x - << "," << m_state_manager->get_window_size().y << ")" << endl; + //cerr << "[Patchage] Resizing window: (" << m_state_manager->get_window_size().x + // << "," << m_state_manager->get_window_size().y << ")" << endl; m_main_window->resize( static_cast(m_state_manager->get_window_size().x), static_cast(m_state_manager->get_window_size().y)); - cerr << "[Patchage] Moving window: (" << m_state_manager->get_window_location().x - << "," << m_state_manager->get_window_location().y << ")" << endl; + //cerr << "[Patchage] Moving window: (" << m_state_manager->get_window_location().x + // << "," << m_state_manager->get_window_location().y << ")" << endl; + m_main_window->move( static_cast(m_state_manager->get_window_location().x), static_cast(m_state_manager->get_window_location().y)); diff --git a/raul/raul/SharedPtr.h b/raul/raul/SharedPtr.h index c6e72a18..89600a99 100644 --- a/raul/raul/SharedPtr.h +++ b/raul/raul/SharedPtr.h @@ -51,6 +51,11 @@ namespace boost { #include +#ifdef BOOST_AC_USE_PTHREADS +#error "Boost is using mutex locking for pointer reference counting." +#error "This is VERY slow. Please report your platform." +#endif + #define SharedPtr boost::shared_ptr #define PtrCast boost::dynamic_pointer_cast