Skip to content

Commit 5745dd0

Browse files
authored
add mutex for switching address (#1298)
1 parent 83b915c commit 5745dd0

2 files changed

Lines changed: 63 additions & 45 deletions

File tree

src/ui/viewmodels/PointerInspectorViewModel.cpp

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,12 @@ void PointerInspectorViewModel::OnSelectedNodeChanged(int nNewNode)
325325
SetValue(HasSelectedNodeProperty, nNewNode >= PointerNodeViewModel::RootNodeId);
326326

327327
DispatchMemoryRead([this, nNewNode]() {
328-
const auto* pNote = UpdatePointerChain(nNewNode);
329-
LoadNote(pNote);
328+
const auto nSelectedNode = GetSelectedNode();
329+
if (nSelectedNode == nNewNode)
330+
{
331+
const auto* pNote = UpdatePointerChain(nNewNode);
332+
LoadNote(pNote);
333+
}
330334
});
331335
}
332336

@@ -501,62 +505,74 @@ void PointerInspectorViewModel::LoadNote(const ra::data::models::CodeNoteModel*
501505
return;
502506
}
503507

504-
m_bSyncingNote = true;
505-
SetCurrentAddressNote(pNote->GetPrimaryNote());
506-
m_bSyncingNote = false;
508+
{
509+
std::lock_guard<std::mutex> lock(m_mtxLoadNote);
507510

508-
m_pCurrentNote = pNote;
509-
const auto nBaseAddress = m_pCurrentNote->GetPointerAddress();
510-
gsl::index nCount = gsl::narrow_cast<gsl::index>(m_vmFields.Items().Count());
511+
m_bSyncingNote = true;
512+
SetCurrentAddressNote(pNote->GetPrimaryNote());
513+
m_bSyncingNote = false;
511514

512-
gsl::index nInsertIndex = 0;
513-
m_vmFields.Items().BeginUpdate();
514-
pNote->EnumeratePointerNotes([this, &nCount, &nInsertIndex, nBaseAddress]
515-
(ra::data::ByteAddress nAddress, const ra::data::models::CodeNoteModel& pOffsetNote)
516-
{
517-
const auto nOffset = nAddress - nBaseAddress;
518-
const std::wstring sOffset = ra::util::String::Printf(L"+%04x", nOffset);
515+
m_pCurrentNote = pNote;
516+
const auto nBaseAddress = pNote->GetPointerAddress();
517+
gsl::index nCount = gsl::narrow_cast<gsl::index>(m_vmFields.Items().Count());
519518

520-
StructFieldViewModel* pItem = nullptr;
521-
if (nInsertIndex < nCount)
522-
{
523-
pItem = m_vmFields.Items().GetItemAt<StructFieldViewModel>(nInsertIndex);
524-
Expects(pItem != nullptr);
525-
pItem->SetSelected(false);
526-
}
527-
else
519+
gsl::index nInsertIndex = 0;
520+
m_vmFields.Items().BeginUpdate();
521+
pNote->EnumeratePointerNotes([this, &nCount, &nInsertIndex, nBaseAddress]
522+
(ra::data::ByteAddress nAddress, const ra::data::models::CodeNoteModel& pOffsetNote)
528523
{
529-
++nCount;
530-
pItem = &m_vmFields.Items().Add<StructFieldViewModel>();
531-
}
524+
const auto nOffset = nAddress - nBaseAddress;
525+
const std::wstring sOffset = ra::util::String::Printf(L"+%04x", nOffset);
526+
527+
StructFieldViewModel* pItem = nullptr;
528+
if (nInsertIndex < nCount)
529+
{
530+
pItem = m_vmFields.Items().GetItemAt<StructFieldViewModel>(nInsertIndex);
531+
Expects(pItem != nullptr);
532+
pItem->SetSelected(false);
533+
}
534+
else
535+
{
536+
++nCount;
537+
pItem = &m_vmFields.Items().Add<StructFieldViewModel>();
538+
}
532539

533-
pItem->BeginInitialization();
540+
pItem->BeginInitialization();
534541

535-
pItem->m_nOffset = nOffset;
536-
pItem->SetOffset(sOffset);
537-
m_bSyncingNote = true;
538-
SyncField(*pItem, pOffsetNote);
539-
m_bSyncingNote = false;
542+
pItem->m_nOffset = nOffset;
543+
pItem->SetOffset(sOffset);
544+
m_bSyncingNote = true;
545+
SyncField(*pItem, pOffsetNote);
546+
m_bSyncingNote = false;
540547

541-
// EndInitialization does memory reads, so it must be dispatched. we'll do it in a bit
548+
// EndInitialization does memory reads, so it must be dispatched. we'll do it in a bit
542549

543-
++nInsertIndex;
544-
return true;
545-
});
550+
++nInsertIndex;
551+
return true;
552+
});
546553

547-
while (nCount > nInsertIndex)
548-
m_vmFields.Items().RemoveAt(--nCount);
554+
while (nCount > nInsertIndex)
555+
m_vmFields.Items().RemoveAt(--nCount);
556+
}
549557

550-
DispatchMemoryRead([this]() {
551-
for (auto& pItem : m_vmFields.Items())
552-
pItem.EndInitialization();
558+
DispatchMemoryRead([this, pNote]() {
559+
if (pNote == m_pCurrentNote)
560+
{
561+
std::lock_guard lock(m_mtxLoadNote);
562+
if (pNote == m_pCurrentNote)
563+
{
564+
for (auto& pItem : m_vmFields.Items())
565+
pItem.EndInitialization();
553566

554-
UpdateValues();
555-
});
567+
UpdateValues();
568+
}
569+
}
556570

557-
m_vmFields.Items().EndUpdate();
571+
m_vmFields.Items().EndUpdate();
558572

559-
OnSelectedFieldChanged(m_vmFields.GetSingleSelectionIndex());
573+
if (pNote == m_pCurrentNote)
574+
OnSelectedFieldChanged(m_vmFields.GetSingleSelectionIndex());
575+
});
560576
}
561577

562578
static void LoadSubNotes(LookupItemViewModelCollection& vNodes,

src/ui/viewmodels/PointerInspectorViewModel.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ private:
288288
bool m_bSyncingNote = false;
289289
bool m_bRebuildNodes = false;
290290

291+
std::mutex m_mtxLoadNote;
292+
291293
const ra::data::models::CodeNoteModel* m_pCurrentNote = nullptr;
292294
};
293295

0 commit comments

Comments
 (0)