Fix potential crashes when adding or removing macro segments

I wrongly assumed that std::deque would guarantee that pointers to
elements in deque would not be invalidated by insert() or erase() but
this is not the case it seems.

""
An erase in the middle of the deque invalidates all the iterators and
references to elements of the deque. An erase at either end of the deque
invalidates only the iterators and the references to the erased
elements.
""

I guess I got lucky noone ran into these sorts of crashes for now?
This commit is contained in:
WarmUpTill 2022-02-18 21:23:26 +01:00 committed by WarmUpTill
parent 354ef56070
commit 8e3eb8519b
6 changed files with 51 additions and 0 deletions

View File

@ -54,6 +54,8 @@ public:
void HighlightCondition(int idx);
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
void SetActionData(Macro &m);
void SetConditionData(Macro &m);
void ConnectControlSignals(MacroActionEdit *);
void ConnectControlSignals(MacroConditionEdit *);
void SwapActions(Macro *m, int pos1, int pos2);

View File

@ -34,6 +34,7 @@ public:
std::shared_ptr<MacroAction> * = nullptr,
const std::string &id = "scene_switch");
void UpdateEntryData(const std::string &id);
void SetEntryData(std::shared_ptr<MacroAction> *);
private slots:
void ActionSelectionChanged(const QString &text);

View File

@ -38,6 +38,7 @@ public:
bool IsRootNode();
void SetRootNode(bool);
void UpdateEntryData(const std::string &id);
void SetEntryData(std::shared_ptr<MacroCondition> *);
private slots:
void LogicSelectionChanged(int idx);

View File

@ -128,6 +128,11 @@ void MacroActionEdit::UpdateEntryData(const std::string &id)
SetFocusPolicyOfWidgets();
}
void MacroActionEdit::SetEntryData(std::shared_ptr<MacroAction> *data)
{
_entryData = data;
}
MacroSegment *MacroActionEdit::Data()
{
return _entryData->get();
@ -165,6 +170,7 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
clearLayout(actionsList->ContentLayout(), idx);
PopulateMacroActions(*macro, idx);
HighlightAction(idx);
SetActionData(*macro);
}
void AdvSceneSwitcher::on_actionAdd_clicked()
@ -208,6 +214,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
clearLayout(actionsList->ContentLayout(), idx);
PopulateMacroActions(*macro, idx);
SetActionData(*macro);
}
void AdvSceneSwitcher::on_actionRemove_clicked()

View File

@ -188,6 +188,11 @@ void MacroConditionEdit::UpdateEntryData(const std::string &id)
SetFocusPolicyOfWidgets();
}
void MacroConditionEdit::SetEntryData(std::shared_ptr<MacroCondition> *data)
{
_entryData = data;
}
void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
{
if (_loading || !_entryData) {
@ -293,6 +298,7 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
clearLayout(conditionsList->ContentLayout(), idx);
PopulateMacroConditions(*macro, idx);
HighlightCondition(idx);
SetConditionData(*macro);
}
void AdvSceneSwitcher::on_conditionAdd_clicked()
@ -339,6 +345,7 @@ void AdvSceneSwitcher::RemoveMacroCondition(int idx)
clearLayout(conditionsList->ContentLayout(), idx);
PopulateMacroConditions(*macro, idx);
SetConditionData(*macro);
}
void AdvSceneSwitcher::on_conditionRemove_clicked()

View File

@ -254,6 +254,39 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
conditionsList->SetHelpMsgVisible(conditions.size() == 0);
}
void AdvSceneSwitcher::SetActionData(Macro &m)
{
auto &actions = m.Actions();
for (int idx = 0; idx < actionsList->ContentLayout()->count(); idx++) {
auto item = actionsList->ContentLayout()->itemAt(idx);
if (!item) {
continue;
}
auto widget = static_cast<MacroActionEdit *>(item->widget());
if (!widget) {
continue;
}
widget->SetEntryData(&*(actions.begin() + idx));
}
}
void AdvSceneSwitcher::SetConditionData(Macro &m)
{
auto &conditions = m.Conditions();
for (int idx = 0; idx < conditionsList->ContentLayout()->count();
idx++) {
auto item = conditionsList->ContentLayout()->itemAt(idx);
if (!item) {
continue;
}
auto widget = static_cast<MacroConditionEdit *>(item->widget());
if (!widget) {
continue;
}
widget->SetEntryData(&*(conditions.begin() + idx));
}
}
void AdvSceneSwitcher::SetEditMacro(Macro &m)
{
{