mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-22 02:45:49 -04:00
fix crash if event listener is destroyed while they are being iterated
This commit is contained in:
parent
f662251d98
commit
2efe772329
3 changed files with 19 additions and 2 deletions
loader
|
@ -133,6 +133,8 @@ namespace geode {
|
|||
private:
|
||||
friend EventListenerProtocol;
|
||||
|
||||
static std::unordered_set<EventListenerProtocol*>& removedListeners();
|
||||
|
||||
public:
|
||||
Mod* sender;
|
||||
|
||||
|
@ -144,6 +146,12 @@ namespace geode {
|
|||
|
||||
virtual ~Event();
|
||||
|
||||
/**
|
||||
* Get all active event listeners. You may use this to sort listeners
|
||||
* that have an explicit order. You should never add/remove listeners
|
||||
* manually however - use the enable() and disable() functions for that
|
||||
* @warning Do not add/remove listeners manually
|
||||
*/
|
||||
static std::vector<EventListenerProtocol*>& listeners();
|
||||
/**
|
||||
* Move an event listener to the front of the queue so it is always hit
|
||||
|
|
|
@ -8,6 +8,7 @@ void EventListenerProtocol::enable() {
|
|||
}
|
||||
|
||||
void EventListenerProtocol::disable() {
|
||||
Event::removedListeners().insert(this);
|
||||
ranges::remove(Event::listeners(), this);
|
||||
}
|
||||
|
||||
|
@ -21,12 +22,20 @@ void Event::postFrom(Mod* m) {
|
|||
if (m) this->sender = m;
|
||||
|
||||
std::vector<EventListenerProtocol*> listeners_copy = Event::listeners();
|
||||
|
||||
for (auto h : listeners_copy) {
|
||||
// if an event listener gets destroyed in the middle of this loop, we
|
||||
// need to handle that
|
||||
if (Event::removedListeners().count(h)) continue;
|
||||
if (h->passThrough(this) == ListenerResult::Stop) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Event::removedListeners().clear();
|
||||
}
|
||||
|
||||
std::unordered_set<EventListenerProtocol*>& Event::removedListeners() {
|
||||
static std::unordered_set<EventListenerProtocol*> listeners;
|
||||
return listeners;
|
||||
}
|
||||
|
||||
std::vector<EventListenerProtocol*>& Event::listeners() {
|
||||
|
|
|
@ -559,7 +559,7 @@ bool IndexItemInfoPopup::init(IndexItemHandle item, ModListLayer* list) {
|
|||
|
||||
void IndexItemInfoPopup::onInstallProgress(ModInstallEvent* event) {
|
||||
std::visit(makeVisitor {
|
||||
[&](UpdateFinished) {
|
||||
[&](UpdateFinished const&) {
|
||||
this->setInstallStatus(std::nullopt);
|
||||
|
||||
FLAlertLayer::create(
|
||||
|
|
Loading…
Reference in a new issue