Shared ptr lifetime management for sockets.

This commit is contained in:
Robin Davies
2024-10-05 02:13:49 -04:00
parent db03a7e47f
commit 6f268daec9
3 changed files with 152 additions and 316 deletions
+129 -306
View File
@@ -118,18 +118,11 @@ void PiPedalModel::Close()
}
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t {subscribers.begin(),subscribers.end()};
for (auto&subscriber: t)
{
t[i] = this->subscribers[i];
subscriber->Close();
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->Close();
}
delete[] t;
this->subscribers.resize(0);
oldAudioHost = std::move(this->audioHost);
@@ -299,25 +292,25 @@ IPiPedalModelSubscriber *PiPedalModel::GetNotificationSubscriber(int64_t clientI
{
if (subscribers[i]->GetClientId() == clientId)
{
return subscribers[i];
return subscribers[i].get();
}
}
return nullptr;
}
void PiPedalModel::AddNotificationSubscription(IPiPedalModelSubscriber *pSubscriber)
void PiPedalModel::AddNotificationSubscription(std::shared_ptr<IPiPedalModelSubscriber> pSubscriber)
{
std::lock_guard<std::recursive_mutex> lock(mutex);
this->subscribers.push_back(pSubscriber);
}
void PiPedalModel::RemoveNotificationSubsription(IPiPedalModelSubscriber *pSubscriber)
void PiPedalModel::RemoveNotificationSubsription(std::shared_ptr<IPiPedalModelSubscriber> pSubscriber)
{
{
std::lock_guard<std::recursive_mutex> lock(mutex);
for (auto it = this->subscribers.begin(); it != this->subscribers.end(); ++it)
{
if ((*it) == pSubscriber)
if ((*it).get() == pSubscriber.get())
{
this->subscribers.erase(it);
break;
@@ -378,19 +371,11 @@ void PiPedalModel::OnNotifyMaybeLv2StateChanged(uint64_t instanceId)
item->stateUpdateCount(item->stateUpdateCount() + 1);
Lv2PluginState newState = item->lv2State();
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnLv2StateChanged(instanceId, newState);
}
size_t n = this->subscribers.size();
{
for (size_t i = 0; i < n; ++i)
{
t[i]->OnLv2StateChanged(instanceId, newState);
}
}
delete[] t;
}
}
}
@@ -403,19 +388,11 @@ void PiPedalModel::SetInputVolume(float value)
this->pedalboard.input_volume_db(value);
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnInputVolumeChanged(value);
}
size_t n = this->subscribers.size();
{
for (size_t i = 0; i < n; ++i)
{
t[i]->OnInputVolumeChanged(value);
}
}
delete[] t;
this->SetPresetChanged(-1, true);
}
@@ -427,19 +404,11 @@ void PiPedalModel::SetOutputVolume(float value)
std::lock_guard<std::recursive_mutex> lock(mutex);
this->pedalboard.output_volume_db(value);
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnOutputVolumeChanged(value);
}
size_t n = this->subscribers.size();
{
for (size_t i = 0; i < n; ++i)
{
t[i]->OnOutputVolumeChanged(value);
}
}
delete[] t;
this->SetPresetChanged(-1, true);
}
@@ -477,19 +446,11 @@ void PiPedalModel::SetControl(int64_t clientId, int64_t pedalItemId, const std::
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnControlChanged(clientId, pedalItemId, symbol, value);
}
size_t n = this->subscribers.size();
{
for (size_t i = 0; i < n; ++i)
{
t[i]->OnControlChanged(clientId, pedalItemId, symbol, value);
}
}
delete[] t;
this->SetPresetChanged(clientId, true);
}
@@ -499,33 +460,21 @@ void PiPedalModel::SetControl(int64_t clientId, int64_t pedalItemId, const std::
void PiPedalModel::FireJackConfigurationChanged(const JackConfiguration &jackConfiguration)
{
// noify subscribers.
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnJackConfigurationChanged(jackConfiguration);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnJackConfigurationChanged(jackConfiguration);
}
delete[] t;
}
void PiPedalModel::FireBanksChanged(int64_t clientId)
{
// noify subscribers.
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnBankIndexChanged(this->storage.GetBanks());
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnBankIndexChanged(this->storage.GetBanks());
}
delete[] t;
}
void PiPedalModel::FirePedalboardChanged(int64_t clientId, bool loadAudioThread)
@@ -542,17 +491,11 @@ void PiPedalModel::FirePedalboardChanged(int64_t clientId, bool loadAudioThread)
}
}
// noify subscribers.
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnPedalboardChanged(clientId, this->pedalboard);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnPedalboardChanged(clientId, this->pedalboard);
}
delete[] t;
}
void PiPedalModel::SetPedalboard(int64_t clientId, Pedalboard &pedalboard)
{
@@ -653,17 +596,11 @@ void PiPedalModel::SetPedalboardItemEnable(int64_t clientId, int64_t pedalItemId
this->pedalboard.SetItemEnabled(pedalItemId, enabled);
// Notify clients.
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnItemEnabledChanged(clientId, pedalItemId, enabled);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnItemEnabledChanged(clientId, pedalItemId, enabled);
}
delete[] t;
this->SetPresetChanged(clientId, true);
// Notify audo thread.
@@ -709,18 +646,11 @@ void PiPedalModel::FireSelectedSnapshotChanged(int64_t selectedSnapshot)
std::lock_guard<std::recursive_mutex> guard{mutex};
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnSelectedSnapshotChanged(selectedSnapshot);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnSelectedSnapshotChanged(selectedSnapshot);
}
delete[] t;
}
}
@@ -729,21 +659,15 @@ void PiPedalModel::FirePresetChanged(bool changed)
std::lock_guard<std::recursive_mutex> guard{mutex};
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
PresetIndex presets;
GetPresets(&presets);
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnPresetChanged(changed);
subscriber->OnPresetChanged(changed);
}
delete[] t;
}
}
@@ -751,22 +675,15 @@ void PiPedalModel::FirePresetsChanged(int64_t clientId)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
PresetIndex presets;
GetPresets(&presets);
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnPresetsChanged(clientId, presets);
subscriber->OnPresetsChanged(clientId, presets);
}
delete[] t;
}
}
void PiPedalModel::FirePluginPresetsChanged(const std::string &pluginUri)
@@ -774,18 +691,11 @@ void PiPedalModel::FirePluginPresetsChanged(const std::string &pluginUri)
std::lock_guard<std::recursive_mutex> guard{mutex};
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnPluginPresetsChanged(pluginUri);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnPluginPresetsChanged(pluginUri);
}
delete[] t;
}
}
@@ -888,7 +798,39 @@ int64_t PiPedalModel::UploadBank(BankFile &bankFile, int64_t uploadAfter)
void PiPedalModel::NextBank(Direction direction)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
auto bankIndex = this->GetBankIndex();
if (bankIndex.entries().size() == 0)
{
return;
}
size_t index = 0;
for (size_t i = 0; i < bankIndex.entries().size(); ++i)
{
auto&entry = bankIndex.entries()[i];
if (entry.instanceId() == bankIndex.selectedBank())
{
index = i;
break;
}
}
if (direction == Direction::Increase)
{
++index;
if (index >= bankIndex.entries().size())
{
index = 0;
}
} else {
if (index == 0)
{
index = bankIndex.entries().size()-1;
} else {
--index;
}
}
this->OpenBank(-1,bankIndex.entries()[index].instanceId());
}
void PiPedalModel::NextPreset(Direction direction)
{
@@ -932,7 +874,6 @@ void PiPedalModel::NextPreset(Direction direction)
LoadPreset(-1, index.presets()[currentPresetIndex].instanceId());
}
void PiPedalModel::OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest &request)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
@@ -942,7 +883,9 @@ void PiPedalModel::OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest
if (request.direction < 0)
{
NextPreset();
} else {
}
else
{
PreviousPreset();
}
}
@@ -1102,18 +1045,10 @@ void PiPedalModel::SetGovernorSettings(const std::string &governor)
this->storage.SetGovernorSettings(governor);
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnGovernorSettingsChanged(governor);
}
delete[] t;
subscriber->OnGovernorSettingsChanged(governor);
}
}
@@ -1136,21 +1071,13 @@ void PiPedalModel::SetWifiConfigSettings(const WifiConfigSettings &wifiConfigSet
#endif
{
// yyy: review locking semantics here. This is wrong. Convert to shared pointers?
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
WifiConfigSettings settingsWithNoSecrets = storage.GetWifiConfigSettings(); // (the passwordless version)
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnWifiConfigSettingsChanged(settingsWithNoSecrets);
subscriber->OnWifiConfigSettingsChanged(settingsWithNoSecrets);
}
delete[] t;
}
}
@@ -1209,20 +1136,13 @@ void PiPedalModel::SetWifiDirectConfigSettings(const WifiDirectConfigSettings &w
this->storage.SetWifiDirectConfigSettings(wifiDirectConfigSettings);
{
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
WifiDirectConfigSettings tWifiDirectConfigSettings = storage.GetWifiDirectConfigSettings(); // (the passwordless version)
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnWifiDirectConfigSettingsChanged(tWifiDirectConfigSettings);
subscriber->OnWifiDirectConfigSettingsChanged(tWifiDirectConfigSettings);
}
delete[] t;
// update NSD-SD announement.
UpdateDnsSd();
@@ -1242,25 +1162,16 @@ WifiDirectConfigSettings PiPedalModel::GetWifiDirectConfigSettings()
void PiPedalModel::SetShowStatusMonitor(bool show)
{
IPiPedalModelSubscriber **t;
size_t n;
{
std::lock_guard<std::recursive_mutex> lock(mutex); // copy atomically.
t = new IPiPedalModelSubscriber *[this->subscribers.size()];
n = this->subscribers.size();
storage.SetShowStatusMonitor(show);
// Notify clients.
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnShowStatusMonitorChanged(show);
}
for (size_t i = 0; i < n; ++i)
{
t[i]->OnShowStatusMonitorChanged(show);
}
delete[] t;
}
}
bool PiPedalModel::GetShowStatusMonitor()
@@ -1376,20 +1287,13 @@ void PiPedalModel::FireChannelSelectionChanged(int64_t clientId)
std::lock_guard<std::recursive_mutex> guard{mutex};
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
JackChannelSelection channelSelection = storage.GetJackChannelSelection(this->jackConfiguration);
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnChannelSelectionChanged(clientId, channelSelection);
subscriber->OnChannelSelectionChanged(clientId, channelSelection);
}
delete[] t;
}
}
@@ -1449,17 +1353,11 @@ void PiPedalModel::OnNotifyMidiValueChanged(int64_t instanceId, int portIndex, f
{
this->pedalboard.SetItemEnabled(instanceId, value != 0);
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnItemEnabledChanged(-1, instanceId, value != 0);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnItemEnabledChanged(-1, instanceId, value != 0);
}
delete[] t;
this->SetPresetChanged(-1, true);
return;
@@ -1477,17 +1375,11 @@ void PiPedalModel::OnNotifyMidiValueChanged(int64_t instanceId, int portIndex, f
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
{
t[i] = this->subscribers[i];
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i]->OnMidiValueChanged(instanceId, symbol, value);
}
delete[] t;
this->SetPresetChanged(-1, true);
return;
@@ -1505,17 +1397,11 @@ void PiPedalModel::OnNotifyVusSubscription(const std::vector<VuUpdate> &updates)
for (size_t i = 0; i < updates.size(); ++i)
{
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnVuMeterUpdate(updates);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnVuMeterUpdate(updates);
}
delete[] t;
}
}
@@ -1792,17 +1678,11 @@ void PiPedalModel::SetJackServerSettings(const JackServerSettings &jackServerSet
this->jackServerSettings = jackServerSettings;
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnJackServerSettingsChanged(jackServerSettings);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnJackServerSettingsChanged(jackServerSettings);
}
delete[] t;
#if ALSA_HOST
storage.SetJackServerSettings(jackServerSettings);
@@ -2009,17 +1889,11 @@ void PiPedalModel::LoadPluginPreset(int64_t pluginInstanceId, uint64_t presetIns
{
audioHost->SetPluginPreset(pluginInstanceId, presetValues.controls);
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnLoadPluginPreset(pluginInstanceId, presetValues.controls);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnLoadPluginPreset(pluginInstanceId, presetValues.controls);
}
delete[] t;
}
else
{
@@ -2130,40 +2004,27 @@ void PiPedalModel::OnNotifyPathPatchPropertyReceived(
if (this->audioHost)
{
this->audioHost->OnNotifyPathPatchPropertyReceived(instanceId,pathPatchPropertyUri,atomString);
this->audioHost->OnNotifyPathPatchPropertyReceived(instanceId, pathPatchPropertyUri, atomString);
}
if (pedalboardItem == nullptr)
{
Lv2Log::error(SS("OnNotifyPathPatchPropertyReceived: " << pathPatchPropertyUri << " discarded."));
return;
return;
}
Lv2Log::error(SS("OnNotifyPathPatchPropertyReceived: " << pathPatchPropertyUri <<": " << atomString));
auto i = pedalboardItem->pathProperties_.find(pathPatchPropertyUri);
if (i != pedalboardItem->pathProperties_.end())
{
pedalboardItem->pathProperties_[pathPatchPropertyUri] = atomString;
std::vector<IPiPedalModelSubscriber *> t;
t.reserve(subscribers.size());
for (auto subscriber : subscribers)
{
t.push_back(subscriber);
}
for (auto subscriber : t)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
subscriber->OnNotifyPathPatchPropertyChanged(
instanceId,
pathPatchPropertyUri,
atomString);
}
}
}
@@ -2287,16 +2148,10 @@ void PiPedalModel::SetFavorites(const std::map<std::string, bool> &favorites)
storage.SetFavorites(favorites);
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
std::vector<IPiPedalModelSubscriber *> t;
t.reserve(this->subscribers.size());
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t.push_back(this->subscribers[i]);
}
for (size_t i = 0; i < t.size(); ++i)
{
t[i]->OnFavoritesChanged(favorites);
subscriber->OnFavoritesChanged(favorites);
}
}
std::vector<MidiBinding> PiPedalModel::GetSystemMidiBidings()
@@ -2314,17 +2169,11 @@ void PiPedalModel::SetSystemMidiBindings(std::vector<MidiBinding> &bindings)
this->audioHost->SetSystemMidiBindings(bindings);
}
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnSystemMidiBindingsChanged(bindings);
}
size_t n = this->subscribers.size();
for (size_t i = 0; i < n; ++i)
{
t[i]->OnSystemMidiBindingsChanged(bindings);
}
delete[] t;
}
std::vector<std::string> PiPedalModel::GetFileList(const UiFileProperty &fileProperty)
@@ -2421,7 +2270,7 @@ bool PiPedalModel::LoadCurrentPedalboard()
{
// then we can send a snapshot update instead!
Snapshot snapshot = pedalboard.MakeSnapshotFromCurrentSettings(previousPedalboard);
audioHost->LoadSnapshot(snapshot,pluginHost);
audioHost->LoadSnapshot(snapshot, pluginHost);
this->previousPedalboard = this->pedalboard;
return true;
}
@@ -2443,16 +2292,11 @@ void PiPedalModel::OnNotifyLv2RealtimeError(int64_t instanceId, const std::strin
// Notify clients.
size_t n = subscribers.size();
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[n];
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnErrorMessage(error);
}
for (size_t i = 0; i < n; ++i)
{
t[i]->OnErrorMessage(error);
}
delete[] t;
}
std::filesystem::path PiPedalModel::GetPluginUploadDirectory() const
{
@@ -2465,17 +2309,11 @@ void PiPedalModel::OnLv2PluginsChanged()
std::lock_guard<std::recursive_mutex> lock(mutex);
{
// Notify clients.
size_t n = subscribers.size();
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[n];
for (size_t i = 0; i < n; ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t[i] = this->subscribers[i];
subscriber->OnLv2PluginsChanging();
}
for (size_t i = 0; i < n; ++i)
{
t[i]->OnLv2PluginsChanging();
}
delete[] t;
}
std::thread(
[this]()
@@ -2506,15 +2344,8 @@ void PiPedalModel::FireUpdateStatusChanged(const UpdateStatus &updateStatus)
{
std::lock_guard<std::recursive_mutex> lock(mutex);
std::vector<IPiPedalModelSubscriber *> t;
t.reserve(subscribers.size());
for (auto subscriber : subscribers)
{
t.push_back(subscriber);
}
for (auto subscriber : t)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
subscriber->OnUpdateStatusChanged(updateStatus);
}
@@ -2667,16 +2498,10 @@ void PiPedalModel::OnNetworkChanging(bool ethernetConnected, bool hotspotConnect
});
// take a snapshot incase a client unsusbscribes in the notification handler (in which case the mutex won't protect us)
std::vector<IPiPedalModelSubscriber *> t;
t.reserve(this->subscribers.size());
for (size_t i = 0; i < subscribers.size(); ++i)
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
t.push_back(this->subscribers[i]);
}
for (size_t i = 0; i < t.size(); ++i)
{
t[i]->OnNetworkChanging(hotspotConnected);
subscriber->OnNetworkChanging(hotspotConnected);
}
}
void PiPedalModel::OnNetworkChanged(bool ethernetConnected, bool hotspotConnected)
@@ -2764,5 +2589,3 @@ void PiPedalModel::RequestShutdown(bool restart)
}
}
}
+5 -3
View File
@@ -54,6 +54,8 @@ namespace pipedal
class IPiPedalModelSubscriber
{
public:
using ptr = std::shared_ptr<IPiPedalModelSubscriber>;
virtual int64_t GetClientId() = 0;
virtual void OnItemEnabledChanged(int64_t clientId, int64_t pedalItemId, bool enabled) = 0;
virtual void OnControlChanged(int64_t clientId, int64_t pedalItemId, const std::string &symbol, float value) = 0;
@@ -175,7 +177,7 @@ namespace pipedal
std::shared_ptr<Lv2Pedalboard> lv2Pedalboard;
std::filesystem::path webRoot;
std::vector<IPiPedalModelSubscriber *> subscribers;
std::vector<std::shared_ptr<IPiPedalModelSubscriber>> subscribers;
void SetPresetChanged(int64_t clientId, bool value, bool changeSnapshotSelect = true);
void FireSelectedSnapshotChanged(int64_t selectedSnapshot);
void FirePresetsChanged(int64_t clientId);
@@ -311,8 +313,8 @@ namespace pipedal
void LoadPluginPreset(int64_t pluginInstanceId, uint64_t presetInstanceId);
void AddNotificationSubscription(IPiPedalModelSubscriber *pSubscriber);
void RemoveNotificationSubsription(IPiPedalModelSubscriber *pSubscriber);
void AddNotificationSubscription(std::shared_ptr<IPiPedalModelSubscriber> pSubscriber);
void RemoveNotificationSubsription(std::shared_ptr<IPiPedalModelSubscriber> pSubscriber);
void SetPedalboardItemEnable(int64_t clientId, int64_t instanceId, bool enabled);
void SetControl(int64_t clientId, int64_t pedalItemId, const std::string &symbol, float value);
+18 -7
View File
@@ -477,7 +477,7 @@ JSON_MAP_REFERENCE(Vst3ControlChangedBody, value)
JSON_MAP_REFERENCE(Vst3ControlChangedBody, state)
JSON_MAP_END()
class PiPedalSocketHandler : public SocketHandler, public IPiPedalModelSubscriber
class PiPedalSocketHandler : public SocketHandler, public IPiPedalModelSubscriber, public std::enable_shared_from_this<PiPedalSocketHandler>
{
private:
AdminClient &GetAdminClient() const
@@ -552,6 +552,8 @@ public:
{
FinalCleanup();
}
Lv2Log::error("PiPedalSocketHandler deleted");
}
bool finalCleanup = false;
@@ -572,18 +574,21 @@ public:
}
activeVuSubscriptions.resize(0);
model.RemoveNotificationSubsription(this);
model.RemoveNotificationSubsription(shared_from_this());
// Warning: potentially deleted after return.
}
virtual void Close()
{
if (closed)
return;
closed = true;
{
auto selfHolder = shared_from_this(); // keep ourselves alive until we return.
closed = true;
FinalCleanup(); // do it while we can. &model will no longer be valid after this. ( :-( )
SocketHandler::Close();
FinalCleanup(); // do it while we can. &model will no longer be valid after this. ( :-( )
SocketHandler::Close();
}
}
PiPedalSocketHandler(PiPedalModel &model)
@@ -1259,7 +1264,7 @@ public:
}
else if (message == "hello")
{
this->model.AddNotificationSubscription(this);
this->model.AddNotificationSubscription(shared_from_this());
Reply(replyTo, "ehlo", clientId);
}
else if (message == "setJackSettings")
@@ -1626,6 +1631,10 @@ public:
}
protected:
virtual void onSocketClosed() override {
SocketHandler::OnSocketClosed();
this->Close();
}
virtual void onReceive(const std::string_view &text)
{
view_istream<char> s(text);
@@ -2061,6 +2070,7 @@ private:
std::atomic<uint64_t> PiPedalSocketHandler::nextClientId = 0;
class PiPedalSocketFactory : public ISocketFactory
{
private:
@@ -2088,6 +2098,7 @@ public:
}
};
std::shared_ptr<ISocketFactory> pipedal::MakePiPedalSocketFactory(PiPedalModel &model)
{
return std::make_shared<PiPedalSocketFactory>(model);