handle deletion of UI objects between the time that a callback is queued with the UI event loop and the execution of the callback (intrusive, big)

git-svn-id: svn://localhost/ardour2/branches/3.0@6807 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-03-30 15:18:43 +00:00
parent 10c257039d
commit 14b0ca31bc
87 changed files with 468 additions and 349 deletions

View file

@ -240,12 +240,12 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
last_shuttle_request = last_peak_grab = 0; // get_microseconds();
ARDOUR::Diskstream::DiskOverrun.connect (forever_connections, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
ARDOUR::Diskstream::DiskUnderrun.connect (forever_connections, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context());
ARDOUR::Diskstream::DiskOverrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
ARDOUR::Diskstream::DiskUnderrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context());
/* handle dialog requests */
ARDOUR::Session::Dialog.connect (forever_connections, ui_bind (&ARDOUR_UI::session_dialog, this, _1), gui_context());
ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::session_dialog, this, _1), gui_context());
/* handle pending state with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
@ -335,10 +335,10 @@ ARDOUR_UI::create_engine ()
return -1;
}
engine->Stopped.connect (forever_connections, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
engine->Running.connect (forever_connections, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
engine->Halted.connect (forever_connections, boost::bind (&ARDOUR_UI::engine_halted, this), gui_context());
engine->SampleRateChanged.connect (forever_connections, ui_bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
engine->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
engine->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
engine->Halted.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_halted, this), gui_context());
engine->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
post_engine ();
@ -413,7 +413,7 @@ ARDOUR_UI::post_engine ()
update_cpu_load ();
update_sample_rate (engine->frame_rate());
Config->ParameterChanged.connect (forever_connections, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
Config->map_parameters (pc);

View file

@ -485,7 +485,7 @@ ARDOUR_UI::_auditioning_changed (bool onoff)
void
ARDOUR_UI::auditioning_changed (bool onoff)
{
UI::instance()->call_slot (boost::bind (&ARDOUR_UI::_auditioning_changed, this, onoff));
UI::instance()->call_slot (MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::_auditioning_changed, this, onoff));
}
bool

View file

@ -114,15 +114,15 @@ ARDOUR_UI::set_session (Session *s)
Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
_session->RecordStateChanged.connect (_session_connections, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
_session->TransportStateChange.connect (_session_connections, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
_session->DirtyChanged.connect (_session_connections, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
_session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
_session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
_session->Xrun.connect (_session_connections, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
_session->SoloActive.connect (_session_connections, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
_session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
/* Clocks are on by default after we are connected to a session, so show that here.
*/

View file

@ -270,7 +270,7 @@ ARDOUR_UI::toggle_editing_space()
void
ARDOUR_UI::setup_session_options ()
{
_session->config.ParameterChanged.connect (_session_connections, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
boost::function<void (std::string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
_session->config.map_parameters (pc);
}

View file

@ -215,7 +215,7 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
clock_base.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &AudioClock::field_button_release_event), Timecode_Hours));
Session::TimecodeOffsetChanged.connect (_session_connections, boost::bind (&AudioClock::timecode_offset_changed, this), gui_context());
Session::TimecodeOffsetChanged.connect (_session_connections, invalidator (*this), boost::bind (&AudioClock::timecode_offset_changed, this), gui_context());
if (editable) {
setup_events ();

View file

@ -165,7 +165,7 @@ AudioRegionEditor::AudioRegionEditor (Session* s, boost::shared_ptr<AudioRegion>
gain_changed ();
_region->PropertyChanged.connect (state_connection, ui_bind (&AudioRegionEditor::region_changed, this, _1), gui_context());
_region->PropertyChanged.connect (state_connection, invalidator (*this), ui_bind (&AudioRegionEditor::region_changed, this, _1), gui_context());
spin_arrow_grab = false;
@ -246,7 +246,7 @@ AudioRegionEditor::connect_editor_events ()
audition_button.signal_toggled().connect (sigc::mem_fun(*this, &AudioRegionEditor::audition_button_toggled));
_session->AuditionActive.connect (audition_connection, ui_bind (&AudioRegionEditor::audition_state_changed, this, _1), gui_context());
_session->AuditionActive.connect (audition_connection, invalidator (*this), ui_bind (&AudioRegionEditor::audition_state_changed, this, _1), gui_context());
}
void

View file

@ -979,7 +979,7 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
void
AudioRegionView::peaks_ready_handler (uint32_t which)
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&AudioRegionView::create_one_wave, this, which, false));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&AudioRegionView::create_one_wave, this, which, false));
// cerr << "AudioRegionView::peaks_ready_handler() called on " << which << " this: " << this << endl;
}

View file

@ -68,7 +68,7 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
use_rec_regions = tv.editor().show_waveforms_recording ();
Config->ParameterChanged.connect (*this, ui_bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
}
AudioStreamView::~AudioStreamView ()
@ -192,7 +192,7 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
/* catch region going away */
r->DropReferences.connect (*this, boost::bind (&AudioStreamView::remove_region_view, this, boost::weak_ptr<Region> (r)), gui_context());
r->DropReferences.connect (*this, invalidator (*this), boost::bind (&AudioStreamView::remove_region_view, this, boost::weak_ptr<Region> (r)), gui_context());
RegionViewAdded (region_view);
@ -277,7 +277,7 @@ AudioStreamView::playlist_switched (boost::weak_ptr<Diskstream> wds)
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(ds->playlist());
if (apl) {
apl->NewCrossfade.connect (playlist_connections, ui_bind (&AudioStreamView::add_crossfade, this, _1), gui_context());
apl->NewCrossfade.connect (playlist_connections, invalidator (*this), ui_bind (&AudioStreamView::add_crossfade, this, _1), gui_context());
}
}
@ -326,7 +326,7 @@ AudioStreamView::add_crossfade (boost::weak_ptr<Crossfade> wc)
region_color,
*lview, *rview);
cv->set_valid (true);
crossfade->Invalidated.connect (*this, ui_bind (&AudioStreamView::remove_crossfade, this, _1), gui_context());
crossfade->Invalidated.connect (*this, invalidator (*this), ui_bind (&AudioStreamView::remove_crossfade, this, _1), gui_context());
crossfade_views[cv->crossfade] = cv;
if (!_trackview.session()->config.get_xfades_visible() || !crossfades_visible) {
cv->hide ();
@ -462,6 +462,7 @@ AudioStreamView::setup_rec_box ()
if (src) {
sources.push_back (src);
src->PeakRangeReady.connect (rec_data_ready_connections,
invalidator (*this),
ui_bind (&AudioStreamView::rec_peak_range_ready, this, _1, _2, boost::weak_ptr<Source>(src)),
gui_context());
}

View file

@ -109,7 +109,8 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
}
if (_route->panner()) {
_route->panner()->Changed.connect (*this, boost::bind (&AudioTimeAxisView::ensure_pan_views, this, false), gui_context());
_route->panner()->Changed.connect (*this, invalidator (*this),
boost::bind (&AudioTimeAxisView::ensure_pan_views, this, false), gui_context());
}
/* map current state of the route */

View file

@ -54,7 +54,7 @@ AutomationController::AutomationController(boost::shared_ptr<AutomationControl>
_screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
sigc::mem_fun (*this, &AutomationController::display_effective_value));
ac->Changed.connect (_changed_connection, boost::bind (&AutomationController::value_changed, this), gui_context());
ac->Changed.connect (_changed_connection, invalidator (*this), boost::bind (&AutomationController::value_changed, this), gui_context());
}
AutomationController::~AutomationController()
@ -147,7 +147,7 @@ AutomationController::automation_state_changed ()
void
AutomationController::value_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&AutomationController::display_effective_value, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&AutomationController::display_effective_value, this));
}
/** Stop updating our value from our controllable */

View file

@ -86,7 +86,7 @@ AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanv
line->signal_event().connect (sigc::mem_fun (*this, &AutomationLine::event_handler));
alist->StateChanged.connect (_state_connection, boost::bind (&AutomationLine::list_changed, this), gui_context());
alist->StateChanged.connect (_state_connection, invalidator (*this), boost::bind (&AutomationLine::list_changed, this), gui_context());
trackview.session()->register_with_memento_command_factory(alist->id(), this);
@ -115,7 +115,7 @@ AutomationLine::queue_reset ()
{
if (!update_pending) {
update_pending = true;
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&AutomationLine::reset, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&AutomationLine::reset, this));
}
}

View file

@ -61,7 +61,7 @@ AutomationRegionView::init (Gdk::Color const & basic_color, bool /*wfd*/)
set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, ui_bind (&RegionView::region_changed, this, _1), gui_context());
_region->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RegionView::region_changed, this, _1), gui_context());
set_colors ();

View file

@ -129,7 +129,7 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region
display_region(region_view);
/* catch regionview going away */
region->DropReferences.connect (*this, boost::bind (&AutomationStreamView::remove_region_view, this, boost::weak_ptr<Region>(region)), gui_context());
region->DropReferences.connect (*this, invalidator (*this), boost::bind (&AutomationStreamView::remove_region_view, this, boost::weak_ptr<Region>(region)), gui_context());
RegionViewAdded (region_view);

View file

@ -837,7 +837,7 @@ AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
assert(!_line);
assert(line->the_list() == _control->list());
_control->alist()->automation_state_changed.connect (automation_connection, boost::bind (&AutomationTimeAxisView::automation_state_changed, this), gui_context());
_control->alist()->automation_state_changed.connect (automation_connection, invalidator (*this), boost::bind (&AutomationTimeAxisView::automation_state_changed, this), gui_context());
_line = line;
//_controller = AutomationController::create(_session, line->the_list(), _control);

View file

@ -397,7 +397,7 @@ BundleManager::add_bundle (boost::shared_ptr<Bundle> b)
(*i)[_list_model_columns.name] = u->name ();
(*i)[_list_model_columns.bundle] = u;
u->Changed.connect (bundle_connections, ui_bind (&BundleManager::bundle_changed, this, _1, u), gui_context());
u->Changed.connect (bundle_connections, invalidator (*this), ui_bind (&BundleManager::bundle_changed, this, _1, u), gui_context());
}
void

View file

@ -291,9 +291,9 @@ CrossfadeEditor::CrossfadeEditor (Session* s, boost::shared_ptr<Crossfade> xf, d
curve_select_clicked (In);
xfade->PropertyChanged.connect (state_connection, ui_bind (&CrossfadeEditor::xfade_changed, this, _1), gui_context());
xfade->PropertyChanged.connect (state_connection, invalidator (*this), ui_bind (&CrossfadeEditor::xfade_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, ui_bind (&CrossfadeEditor::audition_state_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, invalidator (*this), ui_bind (&CrossfadeEditor::audition_state_changed, this, _1), gui_context());
show_all_children();
}

View file

@ -87,7 +87,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
all_crossfade_properties.add (ARDOUR::Properties::follow_overlap);
crossfade_changed (all_crossfade_properties);
crossfade->PropertyChanged.connect (*this, ui_bind (&CrossfadeView::crossfade_changed, this, _1), gui_context());
crossfade->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&CrossfadeView::crossfade_changed, this, _1), gui_context());
ColorsChanged.connect (sigc::mem_fun (*this, &CrossfadeView::color_handler));
}

View file

@ -628,7 +628,7 @@ Editor::Editor ()
_playlist_selector = new PlaylistSelector();
_playlist_selector->signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
RegionView::RegionViewGoingAway.connect (*this, ui_bind (&Editor::catch_vanishing_regionview, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (*this, invalidator (*this), ui_bind (&Editor::catch_vanishing_regionview, this, _1), gui_context());
/* nudge stuff */
@ -675,19 +675,19 @@ Editor::Editor ()
/* allow external control surfaces/protocols to do various things */
ControlProtocol::ZoomToSession.connect (*this, boost::bind (&Editor::temporal_zoom_session, this), gui_context());
ControlProtocol::ZoomIn.connect (*this, boost::bind (&Editor::temporal_zoom_step, this, false), gui_context());
ControlProtocol::ZoomOut.connect (*this, boost::bind (&Editor::temporal_zoom_step, this, true), gui_context());
ControlProtocol::ScrollTimeline.connect (*this, ui_bind (&Editor::control_scroll, this, _1), gui_context());
BasicUI::AccessAction.connect (*this, ui_bind (&Editor::access_action, this, _1, _2), gui_context());
ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context());
ControlProtocol::ZoomIn.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, false), gui_context());
ControlProtocol::ZoomOut.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, true), gui_context());
ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), ui_bind (&Editor::control_scroll, this, _1), gui_context());
BasicUI::AccessAction.connect (*this, invalidator (*this), ui_bind (&Editor::access_action, this, _1, _2), gui_context());
/* problematic: has to return a value and thus cannot be x-thread */
Session::AskAboutPlaylistDeletion.connect_same_thread (*this, boost::bind (&Editor::playlist_deletion_dialog, this, _1));
Config->ParameterChanged.connect (*this, ui_bind (&Editor::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&Editor::parameter_changed, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, ui_bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
_last_normalization_value = 0;
@ -1068,22 +1068,22 @@ Editor::set_session (Session *t)
but use Gtkmm2ext::UI::instance()->call_slot();
*/
_session->TransportStateChange.connect (_session_connections, boost::bind (&Editor::map_transport_state, this), gui_context());
_session->PositionChanged.connect (_session_connections, ui_bind (&Editor::map_position_change, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, ui_bind (&Editor::handle_new_route, this, _1), gui_context());
_session->DurationChanged.connect (_session_connections, boost::bind (&Editor::handle_new_duration, this), gui_context());
_session->DirtyChanged.connect (_session_connections, boost::bind (&Editor::update_title, this), gui_context());
_session->TimecodeOffsetChanged.connect (_session_connections, boost::bind (&Editor::update_just_timecode, this), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, ui_bind (&Editor::tempo_map_changed, this, _1), gui_context());
_session->Located.connect (_session_connections, boost::bind (&Editor::located, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, ui_bind (&Editor::parameter_changed, this, _1), gui_context());
_session->StateSaved.connect (_session_connections, ui_bind (&Editor::session_state_saved, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, ui_bind (&Editor::add_new_location, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, ui_bind (&Editor::location_gone, this, _1), gui_context());
_session->locations()->changed.connect (_session_connections, boost::bind (&Editor::refresh_location_display, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, ui_bind (&Editor::refresh_location_display_s, this, _1), gui_context());
_session->locations()->end_location()->changed.connect (_session_connections, ui_bind (&Editor::end_location_changed, this, _1), gui_context());
_session->history().Changed.connect (_session_connections, boost::bind (&Editor::history_changed, this), gui_context());
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_transport_state, this), gui_context());
_session->PositionChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::map_position_change, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Editor::handle_new_route, this, _1), gui_context());
_session->DurationChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::handle_new_duration, this), gui_context());
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
_session->TimecodeOffsetChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_just_timecode, this), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::tempo_map_changed, this, _1), gui_context());
_session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::parameter_changed, this, _1), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), ui_bind (&Editor::session_state_saved, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), ui_bind (&Editor::add_new_location, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), ui_bind (&Editor::location_gone, this, _1), gui_context());
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::refresh_location_display_s, this, _1), gui_context());
_session->locations()->end_location()->changed.connect (_session_connections, invalidator (*this), ui_bind (&Editor::end_location_changed, this, _1), gui_context());
_session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
if (Profile->get_sae()) {
BBT_Time bbt;

View file

@ -343,7 +343,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
_primary (p),
_views (v)
{
RegionView::RegionViewGoingAway.connect (death_connection, ui_bind (&RegionDrag::region_going_away, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, invalidator (*this), ui_bind (&RegionDrag::region_going_away, this, _1), gui_context());
}
void

View file

@ -124,11 +124,11 @@ Editor::add_new_location (Location *location)
lam->show ();
}
location->start_changed.connect (*this, ui_bind (&Editor::location_changed, this, _1), gui_context());
location->end_changed.connect (*this, ui_bind (&Editor::location_changed, this, _1), gui_context());
location->changed.connect (*this, ui_bind (&Editor::location_changed, this, _1), gui_context());
location->name_changed.connect (*this, ui_bind (&Editor::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (*this, ui_bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
location->start_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->end_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->name_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (*this, invalidator (*this), ui_bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
pair<Location*,LocationMarkers*> newpair;

View file

@ -129,7 +129,7 @@ EditorRegions::EditorRegions (Editor* e)
//ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (sigc::mem_fun(*this, &Editor::redisplay_regions));
ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (sigc::mem_fun(*this, &EditorRegions::update_all_rows));
ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, ui_bind (&EditorRegions::update_row, this, _1), gui_context());
ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, MISSING_INVALIDATOR, ui_bind (&EditorRegions::update_row, this, _1), gui_context());
}
@ -139,8 +139,8 @@ EditorRegions::set_session (ARDOUR::Session* s)
EditorComponent::set_session (s);
if (_session) {
_session->RegionsAdded.connect (_session_connections, ui_bind (&EditorRegions::handle_new_regions, this, _1), gui_context());
_session->RegionHiddenChange.connect (_session_connections, ui_bind (&EditorRegions::region_hidden, this, _1), gui_context());
_session->RegionsAdded.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&EditorRegions::handle_new_regions, this, _1), gui_context());
_session->RegionHiddenChange.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&EditorRegions::region_hidden, this, _1), gui_context());
}
redisplay ();

View file

@ -586,7 +586,7 @@ EditorRouteGroups::add (RouteGroup* group)
focus = true;
}
group->FlagsChanged.connect (flags_connection, ui_bind (&EditorRouteGroups::flags_changed, this, _1, group), gui_context());
group->FlagsChanged.connect (flags_connection, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::flags_changed, this, _1, group), gui_context());
if (focus) {
TreeViewColumn* col = _display.get_column (0);
@ -680,8 +680,8 @@ EditorRouteGroups::set_session (Session* s)
EditorComponent::set_session (s);
if (_session) {
_session->route_group_added.connect (_session_connections, ui_bind (&EditorRouteGroups::add, this, _1), gui_context());
_session->route_group_removed.connect (_session_connections, boost::bind (&EditorRouteGroups::groups_changed, this), gui_context());
_session->route_group_added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::add, this, _1), gui_context());
_session->route_group_removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::groups_changed, this), gui_context());
}
groups_changed ();

View file

@ -181,7 +181,7 @@ EditorRoutes::EditorRoutes (Editor* e)
_display.signal_button_press_event().connect (sigc::mem_fun (*this, &EditorRoutes::button_press), false);
Route::SyncOrderKeys.connect (*this, ui_bind (&EditorRoutes::sync_order_keys, this, _1), gui_context());
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::sync_order_keys, this, _1), gui_context());
}
void
@ -192,7 +192,7 @@ EditorRoutes::set_session (Session* s)
initial_display ();
if (_session) {
_session->SoloChanged.connect (*this, boost::bind (&EditorRoutes::solo_changed_so_update_mute, this), gui_context());
_session->SoloChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::solo_changed_so_update_mute, this), gui_context());
}
}
@ -423,17 +423,17 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
boost::weak_ptr<Route> wr ((*x)->route());
(*x)->route()->gui_changed.connect (*this, ui_bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
(*x)->route()->PropertyChanged.connect (*this, ui_bind (&EditorRoutes::route_property_changed, this, _1, wr), gui_context());
(*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
(*x)->route()->PropertyChanged.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::route_property_changed, this, _1, wr), gui_context());
if ((*x)->is_track()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
t->diskstream()->RecordEnableChanged.connect (*this, boost::bind (&EditorRoutes::update_rec_display, this), gui_context());
t->diskstream()->RecordEnableChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_rec_display, this), gui_context());
}
(*x)->route()->mute_changed.connect (*this, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
(*x)->route()->solo_changed.connect (*this, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
(*x)->route()->solo_isolated_changed.connect (*this, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
(*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
}
update_rec_display ();

View file

@ -47,8 +47,8 @@ EditorSummary::EditorSummary (Editor* e)
_zoom_dragging (false)
{
Region::RegionPropertyChanged.connect (region_property_connection, boost::bind (&CairoWidget::set_dirty, this), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, ui_bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), ui_bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
}
/** Connect to a session.
@ -62,9 +62,9 @@ EditorSummary::set_session (Session* s)
set_dirty ();
if (_session) {
_session->RegionRemoved.connect (_session_connections, boost::bind (&EditorSummary::set_dirty, this), gui_context());
_session->StartTimeChanged.connect (_session_connections, boost::bind (&EditorSummary::set_dirty, this), gui_context());
_session->EndTimeChanged.connect (_session_connections, boost::bind (&EditorSummary::set_dirty, this), gui_context());
_session->RegionRemoved.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_dirty, this), gui_context());
_session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_dirty, this), gui_context());
_session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_dirty, this), gui_context());
}
}

View file

@ -89,7 +89,7 @@ ExportDialog::set_session (ARDOUR::Session* s)
channel_selector->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings));
file_notebook->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings));
status->Aborting.connect (abort_connection, boost::bind (&ExportDialog::notify_errors, this), gui_context());
status->Aborting.connect (abort_connection, invalidator (*this), boost::bind (&ExportDialog::notify_errors, this), gui_context());
update_warnings ();
}

View file

@ -197,7 +197,7 @@ ExportFileNotebook::FilePage::FilePage (Session * s, ManagerPtr profile_manager,
tab_close_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*parent, &ExportFileNotebook::remove_file_page), this));
profile_manager->FormatListChanged.connect (format_connection, boost::bind (&ExportFormatSelector::update_format_list, &format_selector), gui_context());
profile_manager->FormatListChanged.connect (format_connection, invalidator (*this), boost::bind (&ExportFormatSelector::update_format_list, &format_selector), gui_context());
format_selector.FormatEdited.connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::save_format_to_manager));
format_selector.FormatRemoved.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::remove_format_profile));

View file

@ -127,7 +127,7 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) :
close_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_APPLY);
close_button->set_sensitive (false);
close_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportFormatDialog::end_dialog));
manager.CompleteChanged.connect (*this, ui_bind (&Gtk::Button::set_sensitive, close_button, _1), gui_context());
manager.CompleteChanged.connect (*this, invalidator (*this), ui_bind (&Gtk::Button::set_sensitive, close_button, _1), gui_context());
/* Load state before hooking up the rest of the signals */
@ -319,7 +319,7 @@ ExportFormatDialog::init_format_table ()
row[compatibility_cols.label] = (*it)->name();
WeakCompatPtr ptr (*it);
(*it)->SelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_compatibility_selection, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_compatibility_selection, this, _1, ptr), gui_context());
}
compatibility_view.append_column_editable ("", compatibility_cols.selected);
@ -347,8 +347,8 @@ ExportFormatDialog::init_format_table ()
row[quality_cols.label] = (*it)->name();
WeakQualityPtr ptr (*it);
(*it)->SelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_quality_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, ui_bind (&ExportFormatDialog::change_quality_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_quality_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_quality_compatibility, this, _1, ptr), gui_context());
}
quality_view.append_column ("", quality_cols.label);
@ -369,19 +369,19 @@ ExportFormatDialog::init_format_table ()
row[format_cols.label] = (*it)->name();
WeakFormatPtr ptr (*it);
(*it)->SelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_format_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, ui_bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_format_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
/* Encoding options */
boost::shared_ptr<HasSampleFormat> hsf;
if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (*it)) {
hsf->SampleFormatSelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_sample_format_selection, this, _1, _2), gui_context());
hsf->SampleFormatCompatibleChanged.connect (*this, ui_bind (&ExportFormatDialog::change_sample_format_compatibility, this, _1, _2), gui_context());
hsf->SampleFormatSelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_format_selection, this, _1, _2), gui_context());
hsf->SampleFormatCompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_format_compatibility, this, _1, _2), gui_context());
hsf->DitherTypeSelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_dither_type_selection, this, _1, _2), gui_context());
hsf->DitherTypeCompatibleChanged.connect (*this, ui_bind (&ExportFormatDialog::change_dither_type_compatibility, this, _1, _2), gui_context());
hsf->DitherTypeSelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_dither_type_selection, this, _1, _2), gui_context());
hsf->DitherTypeCompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_dither_type_compatibility, this, _1, _2), gui_context());
}
}
@ -403,8 +403,8 @@ ExportFormatDialog::init_format_table ()
row[sample_rate_cols.label] = (*it)->name();
WeakSampleRatePtr ptr (*it);
(*it)->SelectChanged.connect (*this, ui_bind (&ExportFormatDialog::change_sample_rate_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, ui_bind (&ExportFormatDialog::change_sample_rate_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_rate_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_rate_compatibility, this, _1, ptr), gui_context());
}
sample_rate_view.append_column ("", sample_rate_cols.label);

View file

@ -227,13 +227,13 @@ GainMeterBase::set_controls (boost::shared_ptr<Route> r,
boost::shared_ptr<AutomationControl> gc = amp->gain_control();
gc->alist()->automation_state_changed.connect (model_connections, boost::bind (&GainMeter::gain_automation_state_changed, this), gui_context());
gc->alist()->automation_style_changed.connect (model_connections, boost::bind (&GainMeter::gain_automation_style_changed, this), gui_context());
gc->alist()->automation_state_changed.connect (model_connections, invalidator (*this), boost::bind (&GainMeter::gain_automation_state_changed, this), gui_context());
gc->alist()->automation_style_changed.connect (model_connections, invalidator (*this), boost::bind (&GainMeter::gain_automation_style_changed, this), gui_context());
gain_automation_state_changed ();
}
amp->gain_control()->Changed.connect (model_connections, boost::bind (&GainMeterBase::gain_changed, this), gui_context());
amp->gain_control()->Changed.connect (model_connections, invalidator (*this), boost::bind (&GainMeterBase::gain_changed, this), gui_context());
gain_changed ();
show_gain ();
@ -439,7 +439,7 @@ GainMeterBase::effective_gain_display ()
void
GainMeterBase::gain_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&GainMeterBase::effective_gain_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&GainMeterBase::effective_gain_display, this));
}
void

View file

@ -125,7 +125,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
main_contents.pack_start (hpacker, false, false);
}
pi->ActiveChanged.connect (active_connection, boost::bind (&GenericPluginUI::processor_active_changed, this, boost::weak_ptr<Processor>(pi)), gui_context());
pi->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&GenericPluginUI::processor_active_changed, this, boost::weak_ptr<Processor>(pi)), gui_context());
bypass_button.set_active (!pi->active());
@ -421,7 +421,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
//control_ui->combo->set_value_in_list(true, false);
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
mcontrol->Changed.connect (control_connections, boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
control_ui->pack_start(control_ui->label, true, true);
control_ui->pack_start(*control_ui->combo, false, true);
@ -442,7 +442,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
//control_ui->combo->set_value_in_list(true, false);
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
mcontrol->Changed.connect (control_connections, boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
control_ui->pack_start(control_ui->label, true, true);
control_ui->pack_start(*control_ui->combo, false, true);
@ -467,7 +467,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
// control_ui->pack_start (control_ui->automate_button, false, false);
control_ui->button->signal_clicked().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui));
mcontrol->Changed.connect (control_connections, boost::bind (&GenericPluginUI::toggle_parameter_changed, this, control_ui), gui_context());
mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::toggle_parameter_changed, this, control_ui), gui_context());
if (plugin->get_parameter (port_index) > 0.5){
control_ui->button->set_active(true);
@ -543,8 +543,8 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
automation_state_changed (control_ui);
mcontrol->Changed.connect (control_connections, boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
mcontrol->alist()->automation_state_changed.connect (control_connections, boost::bind (&GenericPluginUI::automation_state_changed, this, control_ui), gui_context());
mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
mcontrol->alist()->automation_state_changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::automation_state_changed, this, control_ui), gui_context());
input_controls.push_back (control_ui);
@ -595,7 +595,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
output_controls.push_back (control_ui);
}
mcontrol->Changed.connect (control_connections, boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
return control_ui;
}
@ -662,7 +662,7 @@ GenericPluginUI::parameter_changed (ControlUI* cui)
{
if (!cui->update_pending) {
cui->update_pending = true;
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&GenericPluginUI::update_control_display, this, cui));
Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, boost::bind (&GenericPluginUI::update_control_display, this, cui));
}
}

View file

@ -47,7 +47,7 @@ GroupTabs::set_session (Session* s)
EditorComponent::set_session (s);
if (_session) {
_session->RouteGroupChanged.connect (_session_connections, boost::bind (&GroupTabs::set_dirty, this), gui_context());
_session->RouteGroupChanged.connect (_session_connections, invalidator (*this), boost::bind (&GroupTabs::set_dirty, this), gui_context());
}
}

View file

@ -25,9 +25,16 @@
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>
namespace sigc {
class trackable;
}
#define ENSURE_GUI_THREAD(obj,method, ...) if (!Gtkmm2ext::UI::instance()->caller_is_self()) { abort (); }
#define gui_context() Gtkmm2ext::UI::instance() /* a UICallback-derived object that specifies the event loop for GUI signal handling */
#define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
extern PBD::EventLoop::InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
#define invalidator(x) __invalidator ((x), __FILE__, __LINE__)
#endif /* __ardour_gtk_gui_thread_h__ */

View file

@ -347,7 +347,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session* sess, boost::shared_ptr<ARD
signal_delete_event().connect (sigc::mem_fun (*this, &PortInsertWindow::wm_delete), false);
pi->DropReferences.connect (going_away_connection, boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context());
pi->DropReferences.connect (going_away_connection, invalidator (*this), boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context());
}
bool

View file

@ -59,7 +59,7 @@ LevelMeter::LevelMeter (Session* s)
{
set_session (s);
set_spacing (1);
Config->ParameterChanged.connect (_parameter_connection, ui_bind (&LevelMeter::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (_parameter_connection, invalidator (*this), ui_bind (&LevelMeter::parameter_changed, this, _1), gui_context());
UI::instance()->theme_changed.connect (sigc::mem_fun(*this, &LevelMeter::on_theme_changed));
ColorsChanged.connect (sigc::mem_fun (*this, &LevelMeter::color_handler));
max_peak = minus_infinity();
@ -85,7 +85,7 @@ LevelMeter::set_meter (PeakMeter* meter)
_meter = meter;
if (_meter) {
_meter->ConfigurationChanged.connect (_configuration_connection, ui_bind (&LevelMeter::configuration_changed, this, _1, _2), gui_context());
_meter->ConfigurationChanged.connect (_configuration_connection, invalidator (*this), ui_bind (&LevelMeter::configuration_changed, this, _1, _2), gui_context());
}
}

View file

@ -282,11 +282,11 @@ LocationEditRow::set_location (Location *loc)
end_clock.set_sensitive (!location->locked());
length_clock.set_sensitive (!location->locked());
location->start_changed.connect (connections, ui_bind (&LocationEditRow::start_changed, this, _1), gui_context());
location->end_changed.connect (connections, ui_bind (&LocationEditRow::end_changed, this, _1), gui_context());
location->name_changed.connect (connections, ui_bind (&LocationEditRow::name_changed, this, _1), gui_context());
location->changed.connect (connections, ui_bind (&LocationEditRow::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (connections, ui_bind (&LocationEditRow::flags_changed, this, _1, _2), gui_context());
location->start_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::start_changed, this, _1), gui_context());
location->end_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::end_changed, this, _1), gui_context());
location->name_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::name_changed, this, _1), gui_context());
location->changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::flags_changed, this, _1, _2), gui_context());
}
void
@ -860,10 +860,10 @@ LocationUI::set_session(ARDOUR::Session* s)
SessionHandlePtr::set_session (s);
if (_session) {
_session->locations()->changed.connect (_session_connections, boost::bind (&LocationUI::refresh_location_list, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, boost::bind (&LocationUI::refresh_location_list, this), gui_context());
_session->locations()->added.connect (_session_connections, ui_bind (&LocationUI::location_added, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, ui_bind (&LocationUI::location_removed, this, _1), gui_context());
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_added, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_removed, this, _1), gui_context());
}
loop_edit_row.set_session (s);

View file

@ -228,7 +228,7 @@ LV2PluginUI::lv2ui_instantiate(const Glib::ustring& title)
}
}
_lv2->ParameterChanged.connect (parameter_connection, ui_bind (&LV2PluginUI::parameter_changed, this, _1, _2), gui_context());
_lv2->ParameterChanged.connect (parameter_connection, invalidator (*this), ui_bind (&LV2PluginUI::parameter_changed, this, _1, _2), gui_context());
}
LV2PluginUI::~LV2PluginUI ()

View file

@ -596,7 +596,7 @@ MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
{
_model = model;
content_connection.disconnect ();
_model->ContentsChanged.connect (content_connection, boost::bind (&MidiRegionView::redisplay_model, this), gui_context());
_model->ContentsChanged.connect (content_connection, invalidator (*this), boost::bind (&MidiRegionView::redisplay_model, this), gui_context());
clear_events ();
@ -1084,7 +1084,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
}
}
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
return ghost;
}

View file

@ -180,7 +180,7 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd,
display_region (region_view, wfd);
/* catch regionview going away */
region->DropReferences.connect (*this, boost::bind (&MidiStreamView::remove_region_view, this, region), gui_context());
region->DropReferences.connect (*this, invalidator (*this), boost::bind (&MidiStreamView::remove_region_view, this, region), gui_context());
RegionViewAdded (region_view);
@ -403,6 +403,7 @@ MidiStreamView::setup_rec_box ()
mds->write_source()->ViewDataRangeReady.connect
(rec_data_ready_connections,
invalidator (*this),
ui_bind (&MidiStreamView::rec_data_range_ready, this, _1, _2, boost::weak_ptr<Source>(mds->write_source())),
gui_context());

View file

@ -142,7 +142,7 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
set_state (*xml_node, Stateful::loading_state_version);
_route->processors_changed.connect (*this, ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
if (is_track()) {
_piano_roll_header = new PianoRollHeader(*midi_view());

View file

@ -256,7 +256,7 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len)
fifo.write (&buf, 1);
if (!update_queued) {
gui_context()->call_slot (boost::bind (&MidiTracer::update, this));
gui_context()->call_slot (invalidator (*this), boost::bind (&MidiTracer::update, this));
update_queued = true;
}
}

View file

@ -259,8 +259,8 @@ MixerStrip::init ()
_packed = false;
_embedded = false;
_session->engine().Stopped.connect (*this, boost::bind (&MixerStrip::engine_stopped, this), gui_context());
_session->engine().Running.connect (*this, boost::bind (&MixerStrip::engine_running, this), gui_context());
_session->engine().Stopped.connect (*this, invalidator (*this), boost::bind (&MixerStrip::engine_stopped, this), gui_context());
_session->engine().Running.connect (*this, invalidator (*this), boost::bind (&MixerStrip::engine_running, this), gui_context());
input_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::input_press), false);
output_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::output_press), false);
@ -361,7 +361,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
boost::shared_ptr<AudioTrack> at = audio_track();
at->FreezeChange.connect (route_connections, boost::bind (&MixerStrip::map_frozen, this), gui_context());
at->FreezeChange.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::map_frozen, this), gui_context());
button_table.attach (*rec_enable_button, 0, 2, 2, 3);
rec_enable_button->set_sensitive (_session->writable());
@ -410,21 +410,21 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
_("Click to Add/Edit Comments"):
_route->comment());
_route->meter_change.connect (route_connections, ui_bind (&MixerStrip::meter_changed, this, _1), gui_context());
_route->input()->changed.connect (route_connections, ui_bind (&MixerStrip::input_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (route_connections, ui_bind (&MixerStrip::output_changed, this, _1, _2), gui_context());
_route->route_group_changed.connect (route_connections, boost::bind (&MixerStrip::route_group_changed, this), gui_context());
_route->meter_change.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::meter_changed, this, _1), gui_context());
_route->input()->changed.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::input_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::output_changed, this, _1, _2), gui_context());
_route->route_group_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::route_group_changed, this), gui_context());
if (_route->panner()) {
_route->panner()->Changed.connect (route_connections, boost::bind (&MixerStrip::connect_to_pan, this), gui_context());
_route->panner()->Changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::connect_to_pan, this), gui_context());
}
if (is_audio_track()) {
audio_track()->DiskstreamChanged.connect (route_connections, boost::bind (&MixerStrip::diskstream_changed, this), gui_context());
audio_track()->DiskstreamChanged.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::diskstream_changed, this), gui_context());
}
_route->comment_changed.connect (route_connections, ui_bind (&MixerStrip::comment_changed, this, _1), gui_context());
_route->gui_changed.connect (route_connections, ui_bind (&MixerStrip::route_gui_changed, this, _1, _2), gui_context());
_route->comment_changed.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::comment_changed, this, _1), gui_context());
_route->gui_changed.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::route_gui_changed, this, _1, _2), gui_context());
set_stuff_from_route ();
@ -925,8 +925,8 @@ MixerStrip::connect_to_pan ()
_route->panner()->control(Evoral::Parameter(PanAutomation)));
if (pan_control) {
pan_control->alist()->automation_state_changed.connect (panstate_connection, boost::bind (&PannerUI::pan_automation_state_changed, &panners), gui_context());
pan_control->alist()->automation_style_changed.connect (panstyle_connection, boost::bind (&PannerUI::pan_automation_style_changed, &panners), gui_context());
pan_control->alist()->automation_state_changed.connect (panstate_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_state_changed, &panners), gui_context());
pan_control->alist()->automation_style_changed.connect (panstyle_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_style_changed, &panners), gui_context());
}
panners.pan_changed (this);
@ -1169,20 +1169,20 @@ MixerStrip::fast_update ()
void
MixerStrip::diskstream_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&MixerStrip::update_diskstream_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&MixerStrip::update_diskstream_display, this));
}
void
MixerStrip::input_changed (IOChange /*change*/, void */*src*/)
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&MixerStrip::update_input_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&MixerStrip::update_input_display, this));
set_width_enum (_width, this);
}
void
MixerStrip::output_changed (IOChange /*change*/, void */*src*/)
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&MixerStrip::update_output_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&MixerStrip::update_output_display, this));
set_width_enum (_width, this);
}
@ -1687,7 +1687,7 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
_current_delivery = send;
send->set_metering (true);
_current_delivery->DropReferences.connect (send_gone_connection, boost::bind (&MixerStrip::revert_to_default_display, this), gui_context());
_current_delivery->DropReferences.connect (send_gone_connection, invalidator (*this), boost::bind (&MixerStrip::revert_to_default_display, this), gui_context());
gain_meter().set_controls (_route, send->meter(), send->amp());
gain_meter().setup_meters ();

View file

@ -77,7 +77,7 @@ Mixer_UI::Mixer_UI ()
strip_redisplay_does_not_sync_order_keys = false;
ignore_sync = false;
Route::SyncOrderKeys.connect (*this, ui_bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
Route::SyncOrderKeys.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
scroller_base.set_name ("MixerWindow");
@ -254,7 +254,7 @@ Mixer_UI::Mixer_UI ()
auto_rebinding = FALSE;
MixerStrip::CatchDeletion.connect (*this, ui_bind (&Mixer_UI::remove_strip, this, _1), gui_context());
MixerStrip::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::remove_strip, this, _1), gui_context());
MonitorSection::setup_knob_images ();
@ -362,7 +362,7 @@ Mixer_UI::add_strip (RouteList& routes)
route->set_order_key (N_("signal"), track_model->children().size()-1);
}
route->PropertyChanged.connect (*this, ui_bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
@ -511,10 +511,10 @@ Mixer_UI::set_session (Session* sess)
initial_track_display ();
_session->RouteAdded.connect (_session_connections, ui_bind (&Mixer_UI::add_strip, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, ui_bind (&Mixer_UI::add_route_group, this, _1), gui_context());
_session->route_group_removed.connect (_session_connections, boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_strip, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_route_group, this, _1), gui_context());
_session->route_group_removed.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context());
route_groups_changed ();
@ -1310,7 +1310,7 @@ Mixer_UI::add_route_group (RouteGroup* group)
focus = true;
}
group->FlagsChanged.connect (*this, ui_bind (&Mixer_UI::group_flags_changed, this, _1, group), gui_context());
group->FlagsChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::group_flags_changed, this, _1, group), gui_context());
if (focus) {
TreeViewColumn* col = group_display.get_column (0);

View file

@ -241,7 +241,7 @@ MonitorSection::MonitorSection (Session* s)
/* catch changes that affect us */
Config->ParameterChanged.connect (config_connection, ui_bind (&MonitorSection::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (config_connection, invalidator (*this), ui_bind (&MonitorSection::parameter_changed, this, _1), gui_context());
}
MonitorSection::~MonitorSection ()

View file

@ -164,7 +164,7 @@ OptionEditor::OptionEditor (Configuration* c, std::string const & t)
show_all_children();
/* Watch out for changes to parameters */
_config->ParameterChanged.connect (config_connection, ui_bind (&OptionEditor::parameter_changed, this, _1), gui_context());
_config->ParameterChanged.connect (config_connection, invalidator (*this), ui_bind (&OptionEditor::parameter_changed, this, _1), gui_context());
}
OptionEditor::~OptionEditor ()

View file

@ -72,8 +72,8 @@ Panner2d::Panner2d (boost::shared_ptr<Panner> p, int32_t h)
allow_y = false;
allow_target = false;
panner->StateChanged.connect (state_connection, boost::bind (&Panner2d::handle_state_change, this), gui_context());
panner->Changed.connect (change_connection, boost::bind (&Panner2d::handle_position_change, this), gui_context());
panner->StateChanged.connect (state_connection, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
panner->Changed.connect (change_connection, invalidator (*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
drag_target = 0;
set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);

View file

@ -151,9 +151,9 @@ PannerUI::set_panner (boost::shared_ptr<Panner> p)
return;
}
_panner->Changed.connect (connections, boost::bind (&PannerUI::panner_changed, this), gui_context());
_panner->LinkStateChanged.connect (connections, boost::bind (&PannerUI::update_pan_linkage, this), gui_context());
_panner->StateChanged.connect (connections, boost::bind (&PannerUI::update_pan_state, this), gui_context());
_panner->Changed.connect (connections, invalidator (*this), boost::bind (&PannerUI::panner_changed, this), gui_context());
_panner->LinkStateChanged.connect (connections, invalidator (*this), boost::bind (&PannerUI::update_pan_linkage, this), gui_context());
_panner->StateChanged.connect (connections, invalidator (*this), boost::bind (&PannerUI::update_pan_state, this), gui_context());
setup_pan ();
@ -410,7 +410,7 @@ PannerUI::setup_pan ()
pan_adjustments.back()->set_value(rx);
pan_adjustments.back()->signal_value_changed().connect (sigc::bind (sigc::mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
_panner->pan_control( asz )->Changed.connect (connections, boost::bind (&PannerUI::pan_value_changed, this, (uint32_t) asz), gui_context());
_panner->pan_control( asz )->Changed.connect (connections, invalidator (*this), boost::bind (&PannerUI::pan_value_changed, this, (uint32_t) asz), gui_context());
bc->set_name ("PanSlider");
bc->set_shadow_type (Gtk::SHADOW_NONE);

View file

@ -115,7 +115,7 @@ PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
// Connect the realtime signal collection callback
_plugin_insert->AnalysisDataGathered.connect (analysis_connection, ui_bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context());
_plugin_insert->AnalysisDataGathered.connect (analysis_connection, invalidator (*this), ui_bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context());
}
PluginEqGui::~PluginEqGui()

View file

@ -74,7 +74,7 @@ PluginSelector::PluginSelector (PluginManager *mgr)
manager = mgr;
in_row_change = false;
manager->PluginListChanged.connect (plugin_list_changed_connection, boost::bind (&PluginSelector::build_plugin_menu, this), gui_context());
manager->PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context());
build_plugin_menu ();
plugin_model = Gtk::ListStore::create (plugin_columns);

View file

@ -142,7 +142,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)), false);
insert->DropReferences.connect (death_connection, boost::bind (&PluginUIWindow::plugin_going_away, this), gui_context());
insert->DropReferences.connect (death_connection, invalidator (*this), boost::bind (&PluginUIWindow::plugin_going_away, this), gui_context());
gint h = _pluginui->get_preferred_height ();
gint w = _pluginui->get_preferred_width ();
@ -390,7 +390,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
save_button.set_name ("PluginSaveButton");
save_button.signal_clicked().connect(sigc::mem_fun(*this, &PlugUIBase::save_plugin_setting));
insert->ActiveChanged.connect (active_connection, boost::bind (&PlugUIBase::processor_active_changed, this, boost::weak_ptr<Processor>(insert)), gui_context());
insert->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&PlugUIBase::processor_active_changed, this, boost::weak_ptr<Processor>(insert)), gui_context());
bypass_button.set_active (!pi->active());
@ -414,7 +414,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
plugin_analysis_expander.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &PlugUIBase::toggle_plugin_analysis));
plugin_analysis_expander.set_expanded(false);
insert->DropReferences.connect (death_connection, boost::bind (&PlugUIBase::plugin_going_away, this), gui_context());
insert->DropReferences.connect (death_connection, invalidator (*this), boost::bind (&PlugUIBase::plugin_going_away, this), gui_context());
}
PlugUIBase::~PlugUIBase()

View file

@ -117,7 +117,7 @@ PortGroup::add_bundle_internal (boost::shared_ptr<Bundle> b, boost::shared_ptr<I
}
BundleRecord* br = new BundleRecord (b, io, colour, has_colour);
b->Changed.connect (br->changed_connection, ui_bind (&PortGroup::bundle_changed, this, _1), gui_context());
b->Changed.connect (br->changed_connection, invalidator (*this), ui_bind (&PortGroup::bundle_changed, this, _1), gui_context());
_bundles.push_back (br);
Changed ();
@ -575,8 +575,8 @@ PortGroupList::add_group (boost::shared_ptr<PortGroup> g)
{
_groups.push_back (g);
g->Changed.connect (_changed_connections, boost::bind (&PortGroupList::emit_changed, this), gui_context());
g->BundleChanged.connect (_bundle_changed_connections, ui_bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context());
g->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_changed, this), gui_context());
g->BundleChanged.connect (_bundle_changed_connections, invalidator (*this), ui_bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context());
emit_changed ();
}

View file

@ -136,10 +136,10 @@ PortMatrix::init ()
for (int i = 0; i < 2; ++i) {
/* watch for the content of _ports[] changing */
_ports[i].Changed.connect (_changed_connections, boost::bind (&PortMatrix::setup, this), gui_context());
_ports[i].Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortMatrix::setup, this), gui_context());
/* and for bundles in _ports[] changing */
_ports[i].BundleChanged.connect (_bundle_changed_connections, boost::bind (&PortMatrix::setup, this), gui_context());
_ports[i].BundleChanged.connect (_bundle_changed_connections, invalidator (*this), boost::bind (&PortMatrix::setup, this), gui_context());
}
/* scrolling stuff */
@ -150,13 +150,13 @@ PortMatrix::init ()
/* Part 2: notice when things have changed that require our subclass to clear and refill _ports[] */
/* watch for routes being added or removed */
_session->RouteAdded.connect (_session_connections, boost::bind (&PortMatrix::routes_changed, this), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::routes_changed, this), gui_context());
/* and also bundles */
_session->BundleAdded.connect (_session_connections, boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
_session->BundleAdded.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
/* and also ports */
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
reconnect_to_routes ();
@ -171,7 +171,7 @@ PortMatrix::reconnect_to_routes ()
boost::shared_ptr<RouteList> routes = _session->get_routes ();
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
(*i)->processors_changed.connect (_route_connections, ui_bind (&PortMatrix::route_processors_changed, this, _1), gui_context());
(*i)->processors_changed.connect (_route_connections, invalidator (*this), ui_bind (&PortMatrix::route_processors_changed, this, _1), gui_context());
}
}

View file

@ -256,7 +256,7 @@ PortMatrixBody::setup ()
PortGroup::BundleList r = _matrix->visible_rows()->bundles ();
for (PortGroup::BundleList::iterator i = r.begin(); i != r.end(); ++i) {
(*i)->bundle->Changed.connect (_bundle_connections, boost::bind (&PortMatrixBody::rebuild_and_draw_row_labels, this), gui_context());
(*i)->bundle->Changed.connect (_bundle_connections, invalidator (*this), boost::bind (&PortMatrixBody::rebuild_and_draw_row_labels, this), gui_context());
}
}
@ -264,7 +264,7 @@ PortMatrixBody::setup ()
if (_matrix->visible_columns()) {
PortGroup::BundleList c = _matrix->visible_columns()->bundles ();
for (PortGroup::BundleList::iterator i = c.begin(); i != c.end(); ++i) {
(*i)->bundle->Changed.connect (_bundle_connections, boost::bind (&PortMatrixBody::rebuild_and_draw_column_labels, this), gui_context());
(*i)->bundle->Changed.connect (_bundle_connections, invalidator (*this), boost::bind (&PortMatrixBody::rebuild_and_draw_column_labels, this), gui_context());
}
}

View file

@ -107,8 +107,8 @@ ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
_active.set_active (_processor->active ());
_active.signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::active_toggled));
_processor->ActiveChanged.connect (active_connection, boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
_processor->PropertyChanged.connect (name_connection, ui_bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
_processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
_processor->PropertyChanged.connect (name_connection, invalidator (*this), ui_bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
}
EventBox&
@ -232,7 +232,7 @@ SendProcessorEntry::SendProcessorEntry (boost::shared_ptr<Send> s, Width w)
_vbox.pack_start (_fader);
_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &SendProcessorEntry::gain_adjusted));
_send->amp()->gain_control()->Changed.connect (send_gain_connection, boost::bind (&SendProcessorEntry::show_gain, this), gui_context());
_send->amp()->gain_control()->Changed.connect (send_gain_connection, invalidator (*this), boost::bind (&SendProcessorEntry::show_gain, this), gui_context());
show_gain ();
}
@ -329,9 +329,9 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
no_processor_redisplay = false;
_route = r;
_route->processors_changed.connect (connections, ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context());
_route->DropReferences.connect (connections, boost::bind (&ProcessorBox::route_going_away, this), gui_context());
_route->PropertyChanged.connect (connections, ui_bind (&ProcessorBox::route_property_changed, this, _1), gui_context());
_route->processors_changed.connect (connections, invalidator (*this), ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context());
_route->DropReferences.connect (connections, invalidator (*this), boost::bind (&ProcessorBox::route_going_away, this), gui_context());
_route->PropertyChanged.connect (connections, invalidator (*this), ui_bind (&ProcessorBox::route_property_changed, this, _1), gui_context());
redisplay_processors ();
}

View file

@ -142,7 +142,7 @@ private:
if ((*i)->input()) {
r[_model.online] = !(*i)->input()->offline();
(*i)->input()->OfflineStatusChanged.connect (port_connections, boost::bind (&MIDIPorts::port_offline_changed, this, (*i)), gui_context());
(*i)->input()->OfflineStatusChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&MIDIPorts::port_offline_changed, this, (*i)), gui_context());
r[_model.trace_input] = (*i)->input()->tracing();
}

View file

@ -33,7 +33,7 @@ using namespace PBD;
*/
RegionSelection::RegionSelection ()
{
RegionView::RegionViewGoingAway.connect (death_connection, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
_current_start = 0;
_current_end = 0;
@ -45,7 +45,7 @@ RegionSelection::RegionSelection ()
RegionSelection::RegionSelection (const RegionSelection& other)
: std::list<RegionView*>()
{
RegionView::RegionViewGoingAway.connect (death_connection, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
_current_start = other._current_start;
_current_end = other._current_end;

View file

@ -80,7 +80,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent,
, wait_for_data(false)
, _time_converter(r->session().tempo_map(), r->position())
{
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (const RegionView& other)
@ -95,7 +95,7 @@ RegionView::RegionView (const RegionView& other)
valid = false;
_pixel_width = other._pixel_width;
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other_region)
@ -114,7 +114,7 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
valid = false;
_pixel_width = other._pixel_width;
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (ArdourCanvas::Group* parent,
@ -178,7 +178,7 @@ RegionView::init (Gdk::Color const & basic_color, bool wfd)
set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, ui_bind (&RegionView::region_changed, this, _1), gui_context());
_region->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RegionView::region_changed, this, _1), gui_context());
group->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));

View file

@ -57,7 +57,7 @@ ReturnUI::ReturnUI (Gtk::Window* parent, boost::shared_ptr<Return> r, Session* s
show_all ();
_return->set_metering (true);
_return->input()->changed.connect (input_change_connection, ui_bind (&ReturnUI::ins_changed, this, _1, _2), gui_context());
_return->input()->changed.connect (input_change_connection, invalidator (*this), ui_bind (&ReturnUI::ins_changed, this, _1, _2), gui_context());
_gpm.setup_meters ();
_gpm.set_fader_name ("ReturnUIFrame");
@ -110,7 +110,7 @@ ReturnUIWindow::ReturnUIWindow (boost::shared_ptr<Return> r, ARDOUR::Session* s)
set_name ("ReturnUIWindow");
r->DropReferences.connect (going_away_connection, boost::bind (&ReturnUIWindow::return_going_away, this), gui_context());
r->DropReferences.connect (going_away_connection, invalidator (*this), boost::bind (&ReturnUIWindow::return_going_away, this), gui_context());
signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window *> (this)));
}

View file

@ -183,8 +183,8 @@ RouteParams_UI::add_routes (RouteList& routes)
//route_select_list.rows().back().select ();
route->PropertyChanged.connect (*this, ui_bind (&RouteParams_UI::route_property_changed, this, _1, boost::weak_ptr<Route>(route)), gui_context());
route->DropReferences.connect (*this, boost::bind (&RouteParams_UI::route_removed, this, boost::weak_ptr<Route>(route)), gui_context());
route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RouteParams_UI::route_property_changed, this, _1, boost::weak_ptr<Route>(route)), gui_context());
route->DropReferences.connect (*this, invalidator (*this), boost::bind (&RouteParams_UI::route_removed, this, boost::weak_ptr<Route>(route)), gui_context());
}
}
@ -299,8 +299,8 @@ RouteParams_UI::setup_latency_frame ()
latency_packer.pack_start (delay_label);
latency_click_connection = latency_apply_button.signal_clicked().connect (sigc::mem_fun (*latency_widget, &LatencyGUI::finish));
_route->signal_latency_changed.connect (latency_connections, boost::bind (&RouteParams_UI::refresh_latency, this), gui_context());
_route->initial_delay_changed.connect (latency_connections, boost::bind (&RouteParams_UI::refresh_latency, this), gui_context());
_route->signal_latency_changed.connect (latency_connections, invalidator (*this), boost::bind (&RouteParams_UI::refresh_latency, this), gui_context());
_route->initial_delay_changed.connect (latency_connections, invalidator (*this), boost::bind (&RouteParams_UI::refresh_latency, this), gui_context());
latency_frame.add (latency_packer);
latency_frame.show_all ();
@ -369,7 +369,7 @@ RouteParams_UI::route_removed (boost::weak_ptr<Route> wr)
return;
}
ENSURE_GUI_THREAD (*this, &RouteParams_UI::route_removed, wr)
ENSURE_GUI_THREAD (*this, invalidator (*this), &RouteParams_UI::route_removed, wr)
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator ri;
@ -405,7 +405,7 @@ RouteParams_UI::set_session (Session *sess)
if (_session) {
boost::shared_ptr<RouteList> r = _session->get_routes();
add_routes (*r);
_session->RouteAdded.connect (_session_connections, ui_bind (&RouteParams_UI::add_routes, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&RouteParams_UI::add_routes, this, _1), gui_context());
start_updating ();
} else {
stop_updating ();
@ -464,7 +464,7 @@ RouteParams_UI::route_selected()
setup_processor_boxes();
setup_latency_frame ();
route->processors_changed.connect (_route_processors_connection, ui_bind (&RouteParams_UI::processors_changed, this, _1), gui_context());
route->processors_changed.connect (_route_processors_connection, invalidator (*this), ui_bind (&RouteParams_UI::processors_changed, this, _1), gui_context());
track_input_label.set_text (_route->name());
@ -528,7 +528,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc)
SendUI *send_ui = new SendUI (this, send, _session);
cleanup_view();
send->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context());
send->DropReferences.connect (_processor_going_away_connection, invalidator (*this), boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context());
_active_view = send_ui;
redir_hpane.add2 (*_active_view);
@ -539,7 +539,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc)
ReturnUI *return_ui = new ReturnUI (this, retrn, _session);
cleanup_view();
retrn->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context());
retrn->DropReferences.connect (_processor_going_away_connection, invalidator (*this), boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor>(proc)), gui_context());
_active_view = return_ui;
redir_hpane.add2 (*_active_view);
@ -550,7 +550,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc)
GenericPluginUI *plugin_ui = new GenericPluginUI (plugin_insert, true);
cleanup_view();
plugin_insert->plugin()->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::plugin_going_away, this, PreFader), gui_context());
plugin_insert->plugin()->DropReferences.connect (_processor_going_away_connection, invalidator (*this), boost::bind (&RouteParams_UI::plugin_going_away, this, PreFader), gui_context());
plugin_ui->start_updating (0);
_active_view = plugin_ui;
@ -562,7 +562,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> proc)
PortInsertUI *portinsert_ui = new PortInsertUI (this, _session, port_insert);
cleanup_view();
port_insert->DropReferences.connect (_processor_going_away_connection, boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor> (proc)), gui_context());
port_insert->DropReferences.connect (_processor_going_away_connection, invalidator (*this), boost::bind (&RouteParams_UI::processor_going_away, this, boost::weak_ptr<Processor> (proc)), gui_context());
_active_view = portinsert_ui;
redir_hpane.pack2 (*_active_view);

View file

@ -94,7 +94,7 @@ RouteRedirectSelection::add (boost::shared_ptr<Route> r)
{
if (find (routes.begin(), routes.end(), r) == routes.end()) {
routes.push_back (r);
r->DropReferences.connect (*this, boost::bind (&RouteRedirectSelection::removed, this, boost::weak_ptr<Route>(r)), gui_context());
r->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&RouteRedirectSelection::removed, this, boost::weak_ptr<Route>(r)), gui_context());
RoutesChanged();
}
}

View file

@ -190,9 +190,9 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
}
controls_hbox.pack_start(gm.get_level_meter(), false, false);
_route->meter_change.connect (*this, ui_bind (&RouteTimeAxisView::meter_changed, this, _1), gui_context());
_route->input()->changed.connect (*this, ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->meter_change.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::meter_changed, this, _1), gui_context());
_route->input()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
@ -231,15 +231,15 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
_y_position = -1;
_route->processors_changed.connect (*this, ui_bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context());
_route->PropertyChanged.connect (*this, ui_bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context());
_route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
if (is_track()) {
track()->TrackModeChanged.connect (*this, boost::bind (&RouteTimeAxisView::track_mode_changed, this), gui_context());
track()->FreezeChange.connect (*this, boost::bind (&RouteTimeAxisView::map_frozen, this), gui_context());
track()->DiskstreamChanged.connect (*this, boost::bind (&RouteTimeAxisView::diskstream_changed, this), gui_context());
get_diskstream()->SpeedChanged.connect (*this, boost::bind (&RouteTimeAxisView::speed_changed, this), gui_context());
track()->TrackModeChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::track_mode_changed, this), gui_context());
track()->FreezeChange.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::map_frozen, this), gui_context());
track()->DiskstreamChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::diskstream_changed, this), gui_context());
get_diskstream()->SpeedChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::speed_changed, this), gui_context());
/* pick up the correct freeze state */
map_frozen ();
@ -517,7 +517,7 @@ RouteTimeAxisView::build_display_menu ()
if (!Profile->get_sae()) {
items.push_back (MenuElem (_("Alignment"), *alignment_menu));
get_diskstream()->AlignmentStyleChanged.connect (route_connections, boost::bind (&RouteTimeAxisView::align_style_changed, this), gui_context());
get_diskstream()->AlignmentStyleChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteTimeAxisView::align_style_changed, this), gui_context());
RadioMenuItem::Group mode_group;
items.push_back (RadioMenuElem (mode_group, _("Normal Mode"), sigc::bind (
@ -552,7 +552,7 @@ RouteTimeAxisView::build_display_menu ()
_ignore_track_mode_change = false;
}
get_diskstream()->AlignmentStyleChanged.connect (route_connections, boost::bind (&RouteTimeAxisView::align_style_changed, this), gui_context());
get_diskstream()->AlignmentStyleChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteTimeAxisView::align_style_changed, this), gui_context());
color_mode_menu = build_color_mode_menu();
if (color_mode_menu) {
@ -1132,13 +1132,13 @@ RouteTimeAxisView::clear_playlist ()
void
RouteTimeAxisView::speed_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&RouteTimeAxisView::reset_samples_per_unit, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_samples_per_unit, this));
}
void
RouteTimeAxisView::diskstream_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&RouteTimeAxisView::update_diskstream_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::update_diskstream_display, this));
}
void

View file

@ -135,11 +135,11 @@ RouteUI::init ()
// show_sends_button->set_self_managed (true);
UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
_session->SoloChanged.connect (_session_connections, boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
_session->TransportStateChange.connect (_session_connections, boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
_session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
Config->ParameterChanged.connect (*this, ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
@ -194,23 +194,23 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
}
if (self_destruct) {
rp->DropReferences.connect (route_connections, boost::bind (&RouteUI::self_delete, this), gui_context());
rp->DropReferences.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::self_delete, this), gui_context());
}
mute_button->set_controllable (_route->mute_control());
solo_button->set_controllable (_route->solo_control());
_route->active_changed.connect (route_connections, boost::bind (&RouteUI::route_active_changed, this), gui_context());
_route->mute_changed.connect (route_connections, ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
_route->solo_changed.connect (route_connections, ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
_route->listen_changed.connect (route_connections, ui_bind (&RouteUI::listen_changed, this, _1), gui_context());
_route->solo_isolated_changed.connect (route_connections, ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
_route->PropertyChanged.connect (route_connections, ui_bind (&RouteUI::property_changed, this, _1), gui_context());
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
_route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
_route->solo_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
_route->listen_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::listen_changed, this, _1), gui_context());
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
_route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
if (_session->writable() && is_track()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
t->diskstream()->RecordEnableChanged.connect (route_connections, boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
t->diskstream()->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
rec_enable_button->show();
rec_enable_button->set_controllable (t->rec_enable_control());
@ -668,14 +668,14 @@ RouteUI::send_blink (bool onoff)
void
RouteUI::solo_changed(void* /*src*/)
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&RouteUI::update_solo_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
}
void
RouteUI::listen_changed(void* /*src*/)
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&RouteUI::update_solo_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
}
int
@ -840,7 +840,7 @@ RouteUI::update_mute_display ()
void
RouteUI::route_rec_enable_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&RouteUI::update_rec_display, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_rec_display, this));
}
void
@ -905,14 +905,14 @@ RouteUI::build_solo_menu (void)
check = new CheckMenuItem(_("Solo Isolate"));
check->set_active (_route->solo_isolated());
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
_route->solo_isolated_changed.connect (route_connections, ui_bind (&RouteUI::solo_isolated_toggle, this, _1, check), gui_context());
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_isolated_toggle, this, _1, check), gui_context());
items.push_back (CheckMenuElem(*check));
check->show_all();
check = new CheckMenuItem(_("Solo Safe"));
check->set_active (_route->solo_safe());
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
_route->solo_safe_changed.connect (route_connections, ui_bind (&RouteUI::solo_safe_toggle, this, _1, check), gui_context());
_route->solo_safe_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_safe_toggle, this, _1, check), gui_context());
items.push_back (CheckMenuElem(*check));
check->show_all();
@ -958,7 +958,7 @@ RouteUI::build_mute_menu(void)
//items.push_back (SeparatorElem());
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
_route->mute_points_changed.connect (route_connections, boost::bind (&RouteUI::muting_change, this), gui_context());
_route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
}
void
@ -1192,7 +1192,7 @@ void
RouteUI::route_active_changed ()
{
if (route_active_menu_item) {
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&CheckMenuItem::set_active, route_active_menu_item, _route->active()));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&CheckMenuItem::set_active, route_active_menu_item, _route->active()));
}
}

View file

@ -56,10 +56,10 @@ Selection::Selection (const PublicEditor* e)
/* we have disambiguate which remove() for the compiler */
void (Selection::*track_remove)(TimeAxisView*) = &Selection::remove;
TimeAxisView::CatchDeletion.connect (*this, ui_bind (track_remove, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, MISSING_INVALIDATOR, ui_bind (track_remove, this, _1), gui_context());
void (Selection::*marker_remove)(Marker*) = &Selection::remove;
Marker::CatchDeletion.connect (*this, ui_bind (marker_remove, this, _1), gui_context());
Marker::CatchDeletion.connect (*this, MISSING_INVALIDATOR, ui_bind (marker_remove, this, _1), gui_context());
}
#if 0

View file

@ -61,8 +61,8 @@ SendUI::SendUI (Gtk::Window* parent, boost::shared_ptr<Send> s, Session* session
_send->set_metering (true);
_send->input()->changed.connect (connections, ui_bind (&SendUI::ins_changed, this, _1, _2), gui_context());
_send->output()->changed.connect (connections, ui_bind (&SendUI::outs_changed, this, _1, _2), gui_context());
_send->input()->changed.connect (connections, invalidator (*this), ui_bind (&SendUI::ins_changed, this, _1, _2), gui_context());
_send->output()->changed.connect (connections, invalidator (*this), ui_bind (&SendUI::outs_changed, this, _1, _2), gui_context());
_panners.set_width (Wide);
_panners.setup_pan ();
@ -130,7 +130,7 @@ SendUIWindow::SendUIWindow (boost::shared_ptr<Send> s, Session* session)
set_name ("SendUIWindow");
s->DropReferences.connect (going_away_connection, boost::bind (&SendUIWindow::send_going_away, this), gui_context());
s->DropReferences.connect (going_away_connection, invalidator (*this), boost::bind (&SendUIWindow::send_going_away, this), gui_context());
signal_delete_event().connect (sigc::bind (
sigc::ptr_fun (just_hide_it),

View file

@ -162,9 +162,9 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
sigc::mem_fun (*_session_config, &SessionConfiguration::set_sync_source)
);
s->MTC_PortChanged.connect (_session_connections, boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
s->MIDIClock_PortChanged.connect (_session_connections, boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
s->config.ParameterChanged.connect (_session_connections, ui_bind (&SessionOptionEditor::follow_sync_state, this, _1, s, ssrc), gui_context());
s->MTC_PortChanged.connect (_session_connections, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
s->MIDIClock_PortChanged.connect (_session_connections, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options, this, s, ssrc), gui_context());
s->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&SessionOptionEditor::follow_sync_state, this, _1, s, ssrc), gui_context());
populate_sync_options (s, ssrc);
follow_sync_state (string ("external-sync"), s, ssrc);

View file

@ -56,7 +56,7 @@ Splash::Splash ()
set_default_size (pixbuf->get_width(), pixbuf->get_height());
the_splash = this;
ARDOUR::BootMessage.connect (msg_connection, ui_bind (&Splash::boot_message, this, _1), gui_context());
ARDOUR::BootMessage.connect (msg_connection, invalidator (*this), ui_bind (&Splash::boot_message, this, _1), gui_context());
}
void

View file

@ -79,12 +79,12 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group)
canvas_rect, &_trackview));
if (_trackview.is_track()) {
_trackview.track()->DiskstreamChanged.connect (*this, boost::bind (&StreamView::diskstream_changed, this), gui_context());
_trackview.get_diskstream()->RecordEnableChanged.connect (*this, boost::bind (&StreamView::rec_enable_changed, this), gui_context());
_trackview.track()->DiskstreamChanged.connect (*this, invalidator (*this), boost::bind (&StreamView::diskstream_changed, this), gui_context());
_trackview.get_diskstream()->RecordEnableChanged.connect (*this, invalidator (*this), boost::bind (&StreamView::rec_enable_changed, this), gui_context());
_trackview.session()->TransportStateChange.connect (*this, boost::bind (&StreamView::transport_changed, this), gui_context());
_trackview.session()->TransportLooped.connect (*this, boost::bind (&StreamView::transport_looped, this), gui_context());
_trackview.session()->RecordStateChanged.connect (*this, boost::bind (&StreamView::sess_rec_enable_changed, this), gui_context());
_trackview.session()->TransportStateChange.connect (*this, invalidator (*this), boost::bind (&StreamView::transport_changed, this), gui_context());
_trackview.session()->TransportLooped.connect (*this, invalidator (*this), boost::bind (&StreamView::transport_looped, this), gui_context());
_trackview.session()->RecordStateChanged.connect (*this, invalidator (*this), boost::bind (&StreamView::sess_rec_enable_changed, this), gui_context());
}
ColorsChanged.connect (sigc::mem_fun (*this, &StreamView::color_handler));
@ -222,7 +222,7 @@ StreamView::display_diskstream (boost::shared_ptr<Diskstream> ds)
{
playlist_switched_connection.disconnect();
playlist_switched (ds);
ds->PlaylistChanged.connect (playlist_switched_connection, boost::bind (&StreamView::playlist_switched, this, boost::weak_ptr<Diskstream> (ds)), gui_context());
ds->PlaylistChanged.connect (playlist_switched_connection, invalidator (*this), boost::bind (&StreamView::playlist_switched, this, boost::weak_ptr<Diskstream> (ds)), gui_context());
}
void
@ -332,10 +332,10 @@ StreamView::playlist_switched (boost::weak_ptr<Diskstream> wds)
/* catch changes */
ds->playlist()->LayeringChanged.connect (playlist_connections, boost::bind (&StreamView::playlist_layered, this, boost::weak_ptr<Diskstream>(ds)), gui_context());
ds->playlist()->RegionAdded.connect (playlist_connections, ui_bind (&StreamView::add_region_view, this, _1), gui_context());
ds->playlist()->RegionRemoved.connect (playlist_connections, ui_bind (&StreamView::remove_region_view, this, _1), gui_context());
// ds->playlist()->ContentsChanged.connect (playlist_connections, boost::bind (&StreamView::redisplay_diskstream, this), gui_context());
ds->playlist()->LayeringChanged.connect (playlist_connections, invalidator (*this), boost::bind (&StreamView::playlist_layered, this, boost::weak_ptr<Diskstream>(ds)), gui_context());
ds->playlist()->RegionAdded.connect (playlist_connections, invalidator (*this), ui_bind (&StreamView::add_region_view, this, _1), gui_context());
ds->playlist()->RegionRemoved.connect (playlist_connections, invalidator (*this), ui_bind (&StreamView::remove_region_view, this, _1), gui_context());
// ds->playlist()->ContentsChanged.connect (playlist_connections, invalidator (*this), boost::bind (&StreamView::redisplay_diskstream, this), gui_context());
}
void
@ -344,9 +344,9 @@ StreamView::diskstream_changed ()
boost::shared_ptr<Track> t;
if ((t = _trackview.track()) != 0) {
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&StreamView::display_diskstream, this, t->diskstream()));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&StreamView::display_diskstream, this, t->diskstream()));
} else {
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&StreamView::undisplay_diskstream, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&StreamView::undisplay_diskstream, this));
}
}
@ -404,7 +404,7 @@ StreamView::transport_looped()
{
// to force a new rec region
rec_active = false;
Gtkmm2ext::UI::instance()->call_slot (boost::bind (&StreamView::setup_rec_box, this));
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&StreamView::setup_rec_box, this));
}
void

View file

@ -71,7 +71,7 @@ TapeAudioRegionView::init (Gdk::Color const & basic_color, bool /*wfw*/)
/* every time the wave data changes and peaks are ready, redraw */
for (uint32_t n = 0; n < audio_region()->n_channels(); ++n) {
audio_region()->audio_source(n)->PeaksReady.connect (*this, boost::bind (&TapeAudioRegionView::update, this, n), gui_context());
audio_region()->audio_source(n)->PeaksReady.connect (*this, invalidator (*this), boost::bind (&TapeAudioRegionView::update, this, n), gui_context());
}
}

View file

@ -183,7 +183,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
ColorsChanged.connect (sigc::mem_fun (*this, &TimeAxisView::color_handler));
GhostRegion::CatchDeletion.connect (*this, ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context());
}
TimeAxisView::~TimeAxisView()

View file

@ -2076,9 +2076,7 @@ int
AudioDiskstream::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many)
{
while (how_many-- && !c->empty()) {
// FIXME: crash (thread safe with RCU?)
// memory leak, when disabled.... :(
//delete c->back();
delete c->back();
c->pop_back();
interpolation.remove_channel_from ();
}
@ -2324,9 +2322,7 @@ AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t bufsize, nframes_t speed_si
AudioDiskstream::ChannelInfo::~ChannelInfo ()
{
if (write_source) {
write_source.reset ();
}
write_source.reset ();
delete [] speed_buffer;
speed_buffer = 0;

View file

@ -159,7 +159,7 @@ AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, Connection& c
*/
if (!(ret = _peaks_built)) {
PeaksReady.connect (connect_here_if_not, doThisWhenReady, event_loop);
PeaksReady.connect (connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
}
return ret;

View file

@ -172,7 +172,7 @@ RCConfiguration::save_state()
const string rcfile = rcfile_path.to_string();
// this test seems bogus?
if (rcfile.length()) {
if (!rcfile.empty()) {
XMLTree tree;
tree.set_root (&get_state());
if (!tree.write (rcfile.c_str())){

View file

@ -191,7 +191,6 @@ Session::silent_process_routes (nframes_t nframes, bool& need_butler)
void
Session::get_diskstream_statistics ()
{
int dret;
float pworst = 1.0f;
float cworst = 1.0f;

View file

@ -163,7 +163,7 @@ Session::process_rtop (SessionEvent* ev)
ev->rt_slot ();
if (ev->event_loop) {
ev->event_loop->call_slot (boost::bind (ev->rt_return, ev));
ev->event_loop->call_slot (MISSING_INVALIDATOR, boost::bind (ev->rt_return, ev));
} else {
warning << string_compose ("programming error: %1", X_("Session RT event queued from thread without a UI - cleanup in RT thread!")) << endmsg;
ev->rt_return (ev);

View file

@ -369,6 +369,19 @@ UI::idle_add (int (*func)(void *), void *arg)
/* END abstract_ui interfaces */
PBD::EventLoop::InvalidationRecord*
__invalidator (sigc::trackable& trackable, const char* file, int line)
{
PBD::EventLoop::InvalidationRecord* ir = new PBD::EventLoop::InvalidationRecord;
ir->file = file;
ir->line = line;
trackable.add_destroy_notify_callback (ir, PBD::EventLoop::invalidate_request);
return ir;
}
void
UI::do_request (UIRequest* req)
{

View file

@ -83,13 +83,13 @@ PopUp::remove ()
gtk_idle_add (idle_delete, this);
}
}
#define ENSURE_GUI_THREAD(slot) \
if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {\
Gtkmm2ext::UI::instance()->call_slot ((slot));\
Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, (slot)); \
return;\
}
void
PopUp::touch ()
{

View file

@ -1,6 +1,9 @@
#include <iostream>
#include "pbd/event_loop.h"
#include "pbd/stacktrace.h"
using namespace PBD;
using namespace std;
Glib::StaticPrivate<EventLoop> EventLoop::thread_event_loop;
@ -17,3 +20,29 @@ EventLoop::set_event_loop_for_thread (EventLoop* loop)
thread_event_loop.set (loop, do_not_delete_the_loop_pointer);
}
void*
EventLoop::invalidate_request (void* data)
{
InvalidationRecord* ir = (InvalidationRecord*) data;
if (ir->event_loop) {
Glib::Mutex::Lock lm (ir->event_loop->slot_invalidation_mutex());
if (ir->request) {
cerr << "Object deleted had outstanding event loop request, IR created @ "
<< ir->file << ':' << ir->line
<< endl;
ir->request->valid = false;
ir->request->invalidation = 0;
} else {
cerr << "No queued request associated with object deletion from "
<< ir->file << ':' << ir->line
<< endl;
}
delete ir;
}
return 0;
}

View file

@ -8,15 +8,22 @@ using namespace PBD;
LocaleGuard::LocaleGuard (const char* str)
{
old = strdup (setlocale (LC_NUMERIC, NULL));
if (strcmp (old, str)) {
setlocale (LC_NUMERIC, str);
}
old = setlocale (LC_NUMERIC, NULL);
if (old) {
old = strdup (old);
if (strcmp (old, str)) {
setlocale (LC_NUMERIC, str);
}
}
}
LocaleGuard::~LocaleGuard ()
{
setlocale (LC_NUMERIC, old);
free ((char*)old);
if (old) {
free ((char*)old);
}
}

View file

@ -61,11 +61,13 @@ AbstractUI<RequestObject>::get_request (RequestType rt)
}
vec.buf[0]->type = rt;
vec.buf[0]->valid = true;
return vec.buf[0];
}
RequestObject* req = new RequestObject;
req->type = rt;
return req;
}
@ -98,10 +100,15 @@ AbstractUI<RequestObject>::handle_ui_requests ()
if (vec.len[0] == 0) {
break;
} else {
request_buffer_map_lock.unlock ();
do_request (vec.buf[0]);
request_buffer_map_lock.lock ();
i->second->increment_read_ptr (1);
if (vec.buf[0]->valid) {
request_buffer_map_lock.unlock ();
do_request (vec.buf[0]);
request_buffer_map_lock.lock ();
if (vec.buf[0]->invalidation) {
vec.buf[0]->invalidation->request = 0;
}
i->second->increment_read_ptr (1);
}
}
}
}
@ -115,6 +122,30 @@ AbstractUI<RequestObject>::handle_ui_requests ()
while (!request_list.empty()) {
RequestObject* req = request_list.front ();
request_list.pop_front ();
/* We need to use this lock, because its the one
returned by slot_invalidation_mutex() and protects
against request invalidation.
*/
request_buffer_map_lock.lock ();
if (!req->valid) {
delete req;
request_buffer_map_lock.unlock ();
continue;
}
/* we're about to execute this request, so its
too late for any invalidation. mark
the request as "done" before we start.
*/
if (req->invalidation) {
req->invalidation->request = 0;
}
request_buffer_map_lock.unlock ();
lm.release ();
do_request (req);
@ -152,14 +183,9 @@ AbstractUI<RequestObject>::send_request (RequestObject *req)
}
template<typename RequestObject> void
AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f)
AbstractUI<RequestObject>::call_slot (InvalidationRecord* invalidation, const boost::function<void()>& f)
{
if (caller_is_self()) {
#ifndef NDEBUG
if (getenv ("DEBUG_THREADED_SIGNALS")) {
std::cerr << "functor called in correct thread for " << name() << " , execute ...\n";
}
#endif
f ();
return;
}
@ -171,11 +197,13 @@ AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f)
}
req->the_slot = f;
#ifndef NDEBUG
if (getenv ("DEBUG_THREADED_SIGNALS")) {
std::cerr << "functor called in wrong thread for " << name() << " (from " << pthread_name() << ") send request ...\n";
}
#endif
req->invalidation = invalidation;
if (invalidation) {
invalidation->request = req;
invalidation->event_loop = this;
}
send_request (req);
}

View file

@ -41,7 +41,8 @@ class AbstractUI : public BaseUI
virtual ~AbstractUI() {}
void register_thread (std::string, pthread_t, std::string, uint32_t num_requests);
void call_slot (const boost::function<void()>&);
void call_slot (EventLoop::InvalidationRecord*, const boost::function<void()>&);
Glib::Mutex& slot_invalidation_mutex() { return request_buffer_map_lock; }
protected:
typedef RingBufferNPT<RequestObject> RequestBuffer;

View file

@ -48,15 +48,6 @@ class BaseUI : virtual public sigc::trackable, public PBD::EventLoop
bool ok() const { return _ok; }
enum RequestType {
range_guarantee = ~0
};
struct BaseRequestObject {
RequestType type;
boost::function<void()> the_slot;
};
static RequestType new_request_type();
static RequestType CallSlot;
static RequestType Quit;

View file

@ -33,7 +33,34 @@ class EventLoop
EventLoop() {}
virtual ~EventLoop() {}
virtual void call_slot (const boost::function<void()>&) = 0;
enum RequestType {
range_guarantee = ~0
};
struct BaseRequestObject;
struct InvalidationRecord {
BaseRequestObject* request;
PBD::EventLoop* event_loop;
const char* file;
int line;
InvalidationRecord() : request (0), event_loop (0) {}
};
static void* invalidate_request (void* data);
struct BaseRequestObject {
RequestType type;
bool valid;
InvalidationRecord* invalidation;
boost::function<void()> the_slot;
BaseRequestObject() : valid (true), invalidation (0) {}
};
virtual void call_slot (InvalidationRecord*, const boost::function<void()>&) = 0;
virtual Glib::Mutex& slot_invalidation_mutex() = 0;
static EventLoop* get_event_loop_for_thread();
static void set_event_loop_for_thread (EventLoop* ui);
@ -45,4 +72,6 @@ class EventLoop
}
#define MISSING_INVALIDATOR 0 // used to mark places where we fail to provide an invalidator
#endif /* __pbd_event_loop_h__ */

View file

@ -88,15 +88,17 @@ public:
}
void connect (ScopedConnectionList& clist,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
clist.add_connection (_signal.connect (boost::bind (&EventLoop::call_slot, event_loop, slot)));
clist.add_connection (_signal.connect (boost::bind (&EventLoop::call_slot, event_loop, ir, slot)));
}
void connect (Connection& c,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
c = _signal.connect (boost::bind (&EventLoop::call_slot, event_loop, slot));
c = _signal.connect (boost::bind (&EventLoop::call_slot, event_loop, ir, slot));
}
typename SignalType::result_type operator()() {
@ -125,20 +127,22 @@ public:
c = _signal.connect (slot);
}
static void compositor (typename boost::function<void(A)> f, EventLoop* event_loop, A arg) {
event_loop->call_slot (boost::bind (f, arg));
static void compositor (typename boost::function<void(A)> f, EventLoop* event_loop, EventLoop::InvalidationRecord* ir, A arg) {
event_loop->call_slot (ir, boost::bind (f, arg));
}
void connect (ScopedConnectionList& clist,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1)));
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1)));
}
void connect (Connection& c,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
c = _signal.connect (boost::bind (&compositor, slot, event_loop, _1));
c = _signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1));
}
@ -168,20 +172,24 @@ public:
c = _signal.connect (slot);
}
static void compositor (typename boost::function<void(A1,A2)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2) {
event_loop->call_slot (boost::bind (f, arg1, arg2));
static void compositor (typename boost::function<void(A1,A2)> f, PBD::EventLoop* event_loop,
EventLoop::InvalidationRecord* ir,
A1 arg1, A2 arg2) {
event_loop->call_slot (ir, boost::bind (f, arg1, arg2));
}
void connect (ScopedConnectionList& clist,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2)));
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2)));
}
void connect (Connection& c,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
c = _signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2));
c = _signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2));
}
typename SignalType::result_type operator()(A1 arg1, A2 arg2) {
@ -210,20 +218,24 @@ public:
c = _signal.connect (slot);
}
static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2, A3 arg3) {
event_loop->call_slot (boost::bind (f, arg1, arg2, arg3));
static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop,
EventLoop::InvalidationRecord* ir,
A1 arg1, A2 arg2, A3 arg3) {
event_loop->call_slot (ir, boost::bind (f, arg1, arg2, arg3));
}
void connect (ScopedConnectionList& clist,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3)));
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2, _3)));
}
void connect (Connection& c,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3)));
c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2, _3)));
}
typename SignalType::result_type operator()(A1 arg1, A2 arg2, A3 arg3) {
@ -252,20 +264,24 @@ public:
c = _signal.connect (slot);
}
static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
event_loop->call_slot (boost::bind (f, arg1, arg2, arg3, arg4));
static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop,
EventLoop::InvalidationRecord* ir,
A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
event_loop->call_slot (ir, boost::bind (f, arg1, arg2, arg3, arg4));
}
void connect (ScopedConnectionList& clist,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4)));
clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2, _3, _4)));
}
void connect (Connection& c,
PBD::EventLoop::InvalidationRecord* ir,
const typename SignalType::slot_function_type& slot,
PBD::EventLoop* event_loop) {
c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4)));
c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, ir, _1, _2, _3, _4)));
}
typename SignalType::result_type operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {

View file

@ -52,7 +52,7 @@ ControlProtocol::ControlProtocol (Session& s, string str, EventLoop* evloop)
_active = false;
session->RouteAdded.connect (*this, boost::protect (boost::bind (&ControlProtocol::add_strip, this, _1)), _event_loop);
session->RouteAdded.connect (*this, MISSING_INVALIDATOR, boost::protect (boost::bind (&ControlProtocol::add_strip, this, _1)), _event_loop);
}
ControlProtocol::~ControlProtocol ()

View file

@ -85,8 +85,8 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
Controllable::CreateBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::create_binding, this, _1, _2, _3));
Controllable::DeleteBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::delete_binding, this, _1));
Session::SendFeedback.connect (*this, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
Route::RemoteControlIDChange.connect (*this, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
reload_maps ();
}

View file

@ -540,23 +540,23 @@ void
MackieControlProtocol::connect_session_signals()
{
// receive routes added
session->RouteAdded.connect(session_connections, ui_bind (&MackieControlProtocol::notify_route_added, this, _1), midi_ui_context());
session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_route_added, this, _1), midi_ui_context());
// receive record state toggled
session->RecordStateChanged.connect(session_connections, ui_bind (&MackieControlProtocol::notify_record_state_changed, this), midi_ui_context());
session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_record_state_changed, this), midi_ui_context());
// receive transport state changed
session->TransportStateChange.connect(session_connections, ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), midi_ui_context());
session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), midi_ui_context());
// receive punch-in and punch-out
Config->ParameterChanged.connect(session_connections, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
session->config.ParameterChanged.connect (session_connections, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
// receive rude solo changed
session->SoloActive.connect(session_connections, ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), midi_ui_context());
session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), midi_ui_context());
// make sure remote id changed signals reach here
// see also notify_route_added
Sorted sorted = get_sorted_routes();
for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
(*it)->RemoteControlIDChanged.connect (route_connections, ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
(*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
}
}
@ -1417,7 +1417,7 @@ MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
typedef ARDOUR::RouteList ARS;
for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
(*it)->RemoteControlIDChanged.connect (route_connections, ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
(*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
}
}

View file

@ -37,35 +37,35 @@ using namespace std;
void RouteSignal::connect()
{
if (_strip.has_solo()) {
_route->solo_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_solo_changed, &_mcp, this), midi_ui_context());
_route->solo_control()->Changed.connect(connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_solo_changed, &_mcp, this), midi_ui_context());
}
if (_strip.has_mute()) {
_route->mute_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_mute_changed, &_mcp, this), midi_ui_context());
_route->mute_control()->Changed.connect(connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_mute_changed, &_mcp, this), midi_ui_context());
}
if (_strip.has_gain()) {
_route->gain_control()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_gain_changed, &_mcp, this, false), midi_ui_context());
_route->gain_control()->Changed.connect(connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_gain_changed, &_mcp, this, false), midi_ui_context());
}
_route->PropertyChanged.connect (connections, ui_bind (&MackieControlProtocol::notify_property_changed, &_mcp, _1, this), midi_ui_context());
_route->PropertyChanged.connect (connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_property_changed, &_mcp, _1, this), midi_ui_context());
if (_route->panner()) {
_route->panner()->Changed.connect(connections, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
_route->panner()->Changed.connect(connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
for ( unsigned int i = 0; i < _route->panner()->npanners(); ++i ) {
_route->panner()->streampanner(i).Changed.connect (connections, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
_route->panner()->streampanner(i).Changed.connect (connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_panner_changed, &_mcp, this, false), midi_ui_context());
}
}
boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
if (trk) {
trk->rec_enable_control()->Changed .connect(connections, ui_bind (&MackieControlProtocol::notify_record_enable_changed, &_mcp, this), midi_ui_context());
trk->rec_enable_control()->Changed .connect(connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_record_enable_changed, &_mcp, this), midi_ui_context());
}
// TODO this works when a currently-banked route is made inactive, but not
// when a route is activated which should be currently banked.
_route->active_changed.connect (connections, ui_bind (&MackieControlProtocol::notify_active_changed, &_mcp, this), midi_ui_context());
_route->active_changed.connect (connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_active_changed, &_mcp, this), midi_ui_context());
// TODO
// SelectedChanged

View file

@ -87,7 +87,7 @@ OSC::OSC (Session& s, uint32_t port)
// "Application Hooks"
session_loaded (s);
session->Exported.connect (*this, ui_bind (&OSC::session_exported, this, _1, _2), this);
session->Exported.connect (*this, MISSING_INVALIDATOR, ui_bind (&OSC::session_exported, this, _1, _2), this);
}
OSC::~OSC()
@ -101,7 +101,7 @@ OSC::do_request (OSCUIRequest* req)
{
if (req->type == CallSlot) {
call_slot (req->the_slot);
call_slot (MISSING_INVALIDATOR, req->the_slot);
} else if (req->type == Quit) {
@ -586,7 +586,7 @@ OSC::listen_to_route (boost::shared_ptr<Route> route, lo_address addr)
*/
if (!route_exists) {
route->DropReferences.connect (*this, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this);
route->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this);
}
}

View file

@ -36,7 +36,7 @@ OSCControllable::OSCControllable (lo_address a, const std::string& p, boost::sha
, addr (a)
, path (p)
{
c->Changed.connect (changed_connection, boost::bind (&OSCControllable::send_change_message, this), OSC::instance());
c->Changed.connect (changed_connection, MISSING_INVALIDATOR, boost::bind (&OSCControllable::send_change_message, this), OSC::instance());
}
OSCControllable::~OSCControllable ()