From eb6ea8e81d628e905eeb6cb6a176d07e4b2a0a34 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Mon, 15 Apr 2019 14:03:24 +0200 Subject: [PATCH] Fix #5893: Invalidate widget only if it's visible Remove the widget_invalidate() call after changing a guest's guest_heading_to_ride_id, because that call fails a debug assertion if the guest window is open and the currently active tab is not the "overview" tab. In Release builds (if assertion is disabled), widget_invalidate() might access the widgets array out of bounds. Instead, introduce a new flag PEEP_INVALIDATE_PEEP_ACTION for window_invalidate_flags in the peep struct and set that flag. The guest window update function then makes sure to invalidate the label if the flag is set. The flag could be used in other places to reduce libopenrct2 dependency on window_*() calls (see #6808), but this commit only cares about cases where the assertion would fail. --- src/openrct2-ui/windows/Guest.cpp | 10 +++++++-- src/openrct2/interface/Window.h | 1 - src/openrct2/peep/Guest.cpp | 35 ++++--------------------------- src/openrct2/peep/Peep.h | 1 + 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 0913983a95..1f11beff28 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -62,7 +62,6 @@ enum WINDOW_GUEST_WIDGET_IDX { WIDX_RIDE_SCROLL = 10 }; -validate_global_widx(WC_PEEP, WIDX_ACTION_LBL); validate_global_widx(WC_PEEP, WIDX_PICKUP); static rct_widget window_guest_overview_widgets[] = { @@ -1090,6 +1089,8 @@ void window_guest_overview_invalidate(rct_window* w) */ void window_guest_overview_update(rct_window* w) { + Peep* peep = GET_PEEP(w->number); + int32_t var_496 = w->var_496; var_496++; var_496 %= 24; @@ -1098,6 +1099,12 @@ void window_guest_overview_update(rct_window* w) widget_invalidate(w, WIDX_TAB_1); widget_invalidate(w, WIDX_TAB_2); + if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_ACTION) + { + peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_ACTION; + widget_invalidate(w, WIDX_ACTION_LBL); + } + w->list_information_type += 2; if ((w->highlighted_item & 0xFFFF) == 0xFFFF) @@ -1116,7 +1123,6 @@ void window_guest_overview_update(rct_window* w) int32_t random = util_rand() & 0xFFFF; if (random <= 0x2AAA) { - Peep* peep = GET_PEEP(w->number); peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, PEEP_THOUGHT_ITEM_NONE); } } diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 6835f620cf..613109b785 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -489,7 +489,6 @@ enum #define WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON 25 #define WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON 30 #define WC_PEEP__WIDX_PATROL 11 -#define WC_PEEP__WIDX_ACTION_LBL 12 #define WC_PEEP__WIDX_PICKUP 13 #define WC_TRACK_DESIGN_LIST__WIDX_ROTATE 8 #define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3 diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index e952c3ada1..38d863bf43 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1485,13 +1485,7 @@ void Guest::OnExitRide(ride_id_t rideIndex) guest_heading_to_ride_id = rideIndex; peep_is_lost_countdown = 200; peep_reset_pathfind_goal(this); - - rct_window* w = window_find_by_number(WC_PEEP, sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; } if (peep_should_preferred_intensity_increase(this)) @@ -1550,14 +1544,7 @@ void Guest::PickRideToGoOn() guest_heading_to_ride_id = ride->id; peep_is_lost_countdown = 200; peep_reset_pathfind_goal(this); - - // Invalidate windows - auto w = window_find_by_number(WC_PEEP, sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; // Make peep look at their map if they have one if (item_standard_flags & PEEP_ITEM_MAP) @@ -2133,15 +2120,8 @@ static void peep_tried_to_enter_full_queue(Peep* peep, Ride* ride) static void peep_reset_ride_heading(Peep* peep) { - rct_window* w; - peep->guest_heading_to_ride_id = RIDE_ID_NULL; - w = window_find_by_number(WC_PEEP, peep->sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; } static void peep_ride_is_too_intense(Guest* peep, Ride* ride, bool peepAtRide) @@ -2956,14 +2936,7 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) peep->guest_heading_to_ride_id = closestRideIndex; peep->peep_is_lost_countdown = 200; peep_reset_pathfind_goal(peep); - - // Invalidate windows - rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; peep->time_lost = 0; } diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 1d6550a47f..035a60b6d4 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -511,6 +511,7 @@ enum PeepInvalidate PEEP_INVALIDATE_PEEP_2 = 1 << 2, PEEP_INVALIDATE_PEEP_INVENTORY = 1 << 3, PEEP_INVALIDATE_STAFF_STATS = 1 << 4, + PEEP_INVALIDATE_PEEP_ACTION = 1 << 5 // Currently set only when guest_heading_to_ride_id is changed }; // Flags used by peep_should_go_on_ride()