mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-29 16:53:51 +01:00
JAWS fix?: Now do the delay of event handling...
... Queue, don't immediately process, TrackList events, and if listeners want to hold pointers to tracks, let them use weak_ptr or shared_ptr
This commit is contained in:
@@ -857,19 +857,18 @@ void TrackList::RecalcPositions(TrackNodePointer node)
|
|||||||
|
|
||||||
void TrackList::DeletionEvent()
|
void TrackList::DeletionEvent()
|
||||||
{
|
{
|
||||||
wxCommandEvent e(EVT_TRACKLIST_DELETION);
|
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_DELETION);
|
||||||
|
// wxWidgets will own the event object
|
||||||
// PRL: ProcessEvent, not QueueEvent! Listeners may need their last
|
QueueEvent(e.release());
|
||||||
// chance to examine some removed tracks that are about to be destroyed.
|
|
||||||
ProcessEvent(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackList::ResizingEvent(TrackNodePointer node)
|
void TrackList::ResizingEvent(TrackNodePointer node)
|
||||||
{
|
{
|
||||||
wxCommandEvent e(EVT_TRACKLIST_RESIZING);
|
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_RESIZING);
|
||||||
if (!isNull(node))
|
if (!isNull(node))
|
||||||
e.SetClientData(node->get());
|
e->SetClientData(node->get());
|
||||||
ProcessEvent(e);
|
// wxWidgets will own the event object
|
||||||
|
QueueEvent(e.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
|
void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
|
||||||
@@ -951,8 +950,6 @@ auto TrackList::Replace(Track * t, value_type &&with) -> value_type
|
|||||||
pTrack->SetOwner(this, node);
|
pTrack->SetOwner(this, node);
|
||||||
RecalcPositions(node);
|
RecalcPositions(node);
|
||||||
|
|
||||||
// PRL: Note: Send the event while t (now in holder) is not yet
|
|
||||||
// destroyed, so pointers to t that listeners may have are not dangling.
|
|
||||||
DeletionEvent();
|
DeletionEvent();
|
||||||
ResizingEvent(node);
|
ResizingEvent(node);
|
||||||
}
|
}
|
||||||
@@ -974,8 +971,6 @@ TrackNodePointer TrackList::Remove(Track *t)
|
|||||||
RecalcPositions(result);
|
RecalcPositions(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRL: Note: Send the event while t (now in holder) is not yet
|
|
||||||
// destroyed, so pointers to t that listeners may have are not dangling.
|
|
||||||
DeletionEvent();
|
DeletionEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,9 +982,6 @@ void TrackList::Clear(bool sendEvent)
|
|||||||
ListOfTracks tempList;
|
ListOfTracks tempList;
|
||||||
tempList.swap( *this );
|
tempList.swap( *this );
|
||||||
if (sendEvent)
|
if (sendEvent)
|
||||||
// PRL: Note: Send the event while tempList is not yet
|
|
||||||
// destroyed, so pointers to tracks that listeners may have are not
|
|
||||||
// dangling.
|
|
||||||
DeletionEvent();
|
DeletionEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -489,9 +489,6 @@ DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_RESIZING, -1);
|
|||||||
|
|
||||||
// Posted when a track has been deleted from a tracklist.
|
// Posted when a track has been deleted from a tracklist.
|
||||||
// Also posted when one track replaces another
|
// Also posted when one track replaces another
|
||||||
// When a track has been removed, the event is processed before the track
|
|
||||||
// is destroyed, so that listeners that stored a pointer to the track can still
|
|
||||||
// use it and correctly check whether the list still contains it.
|
|
||||||
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_DELETION, -1);
|
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_DELETION, -1);
|
||||||
|
|
||||||
class TrackList final : public wxEvtHandler, public ListOfTracks
|
class TrackList final : public wxEvtHandler, public ListOfTracks
|
||||||
|
|||||||
@@ -2534,6 +2534,16 @@ wxRect TrackPanel::FindTrackRect( const Track * target, bool label )
|
|||||||
target->GetHeight()
|
target->GetHeight()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PRL: I think the following very old comment misused the term "race
|
||||||
|
// condition" for a bug that happened with only a single thread. I think the
|
||||||
|
// real problem referred to, was that this function could be reached, via
|
||||||
|
// TrackPanelAx callbacks, during low-level operations while the TrackList
|
||||||
|
// was not in a consistent state. Therefore GetLinked() did not imply
|
||||||
|
// that GetLink() was not null.
|
||||||
|
// Now the problem is fixed by delaying the handling of events generated
|
||||||
|
// by TrackList.
|
||||||
|
|
||||||
|
// Old comment:
|
||||||
// The check for a null linked track is necessary because there's
|
// The check for a null linked track is necessary because there's
|
||||||
// a possible race condition between the time the 2 linked tracks
|
// a possible race condition between the time the 2 linked tracks
|
||||||
// are added and when wxAccessible methods are called. This is
|
// are added and when wxAccessible methods are called. This is
|
||||||
|
|||||||
Reference in New Issue
Block a user