OSC: Never, ever bind a shared_ptr<T> to a signal
This fixes crashes when controllable are destroyed, or OSC surface is disabled (signals retain a reference).
This commit is contained in:
parent
2816c85324
commit
86a4447805
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2018 Len Ovens <len@ovenwerks.net>
|
* Copyright (C) 2017-2018 Len Ovens <len@ovenwerks.net>
|
||||||
|
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -90,12 +91,12 @@ OSCCueObserver::refresh_strip (std::shared_ptr<ARDOUR::Stripable> new_strip, Sor
|
|||||||
_strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::name_changed, this,_1, 0), OSC::instance());
|
_strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::name_changed, this,_1, 0), OSC::instance());
|
||||||
name_changed (ARDOUR::Properties::name, 0);
|
name_changed (ARDOUR::Properties::name, 0);
|
||||||
|
|
||||||
_strip->mute_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_change_message, this, X_("/cue/mute"), 0, _strip->mute_control()), OSC::instance());
|
_strip->mute_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_change_message, this, X_("/cue/mute"), 0, std::weak_ptr<Controllable>(_strip->mute_control())), OSC::instance());
|
||||||
send_change_message (X_("/cue/mute"), 0, _strip->mute_control());
|
send_change_message (X_("/cue/mute"), 0, _strip->mute_control());
|
||||||
|
|
||||||
gain_timeout.push_back (0);
|
gain_timeout.push_back (0);
|
||||||
_last_gain[0] = -1; // unused
|
_last_gain[0] = -1; // unused
|
||||||
_strip->gain_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_gain_message, this, 0, _strip->gain_control(), false), OSC::instance());
|
_strip->gain_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_gain_message, this, 0, std::weak_ptr<Controllable>(_strip->gain_control()), false), OSC::instance());
|
||||||
send_gain_message (0, _strip->gain_control(), true);
|
send_gain_message (0, _strip->gain_control(), true);
|
||||||
|
|
||||||
send_init ();
|
send_init ();
|
||||||
@ -163,13 +164,14 @@ OSCCueObserver::send_init()
|
|||||||
if (send->gain_control()) {
|
if (send->gain_control()) {
|
||||||
gain_timeout.push_back (0);
|
gain_timeout.push_back (0);
|
||||||
_last_gain[i + 1] = -1.0;
|
_last_gain[i + 1] = -1.0;
|
||||||
send->gain_control()->Changed.connect (send_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_gain_message, this, i + 1, send->gain_control(), false), OSC::instance());
|
send->gain_control()->Changed.connect (send_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_gain_message, this, i + 1, std::weak_ptr<Controllable>(send->gain_control()), false), OSC::instance());
|
||||||
send_gain_message (i + 1, send->gain_control(), true);
|
send_gain_message (i + 1, send->gain_control(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Processor> proc = std::dynamic_pointer_cast<Processor> (send);
|
std::shared_ptr<Processor> proc = std::dynamic_pointer_cast<Processor> (send);
|
||||||
proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_enabled_message, this, X_("/cue/send/enable"), i + 1, proc), OSC::instance());
|
std::weak_ptr<Processor> wproc (proc);
|
||||||
send_enabled_message (X_("/cue/send/enable"), i + 1, proc);
|
proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, std::bind (&OSCCueObserver::send_enabled_message, this, X_("/cue/send/enable"), i + 1, wproc), OSC::instance());
|
||||||
|
send_enabled_message (X_("/cue/send/enable"), i + 1, wproc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,8 +220,12 @@ OSCCueObserver::name_changed (const PBD::PropertyChange& what_changed, uint32_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OSCCueObserver::send_change_message (string path, uint32_t id, std::shared_ptr<Controllable> controllable)
|
OSCCueObserver::send_change_message (string path, uint32_t id, std::weak_ptr<Controllable> weak_controllable)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<Controllable> controllable = weak_controllable.lock ();
|
||||||
|
if (!controllable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (id) {
|
if (id) {
|
||||||
path = string_compose("%1/%2", path, id);
|
path = string_compose("%1/%2", path, id);
|
||||||
}
|
}
|
||||||
@ -228,8 +234,12 @@ OSCCueObserver::send_change_message (string path, uint32_t id, std::shared_ptr<C
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OSCCueObserver::send_gain_message (uint32_t id, std::shared_ptr<Controllable> controllable, bool force)
|
OSCCueObserver::send_gain_message (uint32_t id, std::weak_ptr<Controllable> weak_controllable, bool force)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<Controllable> controllable = weak_controllable.lock ();
|
||||||
|
if (!controllable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_last_gain[id] != controllable->get_value()) {
|
if (_last_gain[id] != controllable->get_value()) {
|
||||||
_last_gain[id] = controllable->get_value();
|
_last_gain[id] = controllable->get_value();
|
||||||
} else {
|
} else {
|
||||||
@ -247,8 +257,12 @@ OSCCueObserver::send_gain_message (uint32_t id, std::shared_ptr<Controllable> c
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OSCCueObserver::send_enabled_message (std::string path, uint32_t id, std::shared_ptr<ARDOUR::Processor> proc)
|
OSCCueObserver::send_enabled_message (std::string path, uint32_t id, std::weak_ptr<ARDOUR::Processor> weak_proc)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<ARDOUR::Processor> proc = weak_proc.lock ();
|
||||||
|
if (!proc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (id) {
|
if (id) {
|
||||||
_osc.float_message_with_id (path, id, (float) proc->enabled(), true, addr);
|
_osc.float_message_with_id (path, id, (float) proc->enabled(), true, addr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2018 Len Ovens <len@ovenwerks.net>
|
* Copyright (C) 2017-2018 Len Ovens <len@ovenwerks.net>
|
||||||
|
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -64,9 +65,9 @@ class OSCCueObserver
|
|||||||
std::map<uint32_t,float> _last_gain;
|
std::map<uint32_t,float> _last_gain;
|
||||||
|
|
||||||
void name_changed (const PBD::PropertyChange& what_changed, uint32_t id);
|
void name_changed (const PBD::PropertyChange& what_changed, uint32_t id);
|
||||||
void send_change_message (std::string path, uint32_t id, std::shared_ptr<PBD::Controllable> controllable);
|
void send_change_message (std::string path, uint32_t id, std::weak_ptr<PBD::Controllable> controllable);
|
||||||
void send_gain_message (uint32_t id, std::shared_ptr<PBD::Controllable> controllable, bool force);
|
void send_gain_message (uint32_t id, std::weak_ptr<PBD::Controllable> controllable, bool force);
|
||||||
void send_enabled_message (std::string path, uint32_t id, std::shared_ptr<ARDOUR::Processor> proc);
|
void send_enabled_message (std::string path, uint32_t id, std::weak_ptr<ARDOUR::Processor> proc);
|
||||||
void send_init (void);
|
void send_init (void);
|
||||||
void send_end (uint32_t new_sends_size);
|
void send_end (uint32_t new_sends_size);
|
||||||
void send_restart (void);
|
void send_restart (void);
|
||||||
|
Loading…
Reference in New Issue
Block a user