diff options
author | frosch <frosch@openttd.org> | 2011-03-13 21:32:13 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2011-03-13 21:32:13 +0000 |
commit | 51ddbbb13d3c6277dcd04289623efe6e00e4f1b3 (patch) | |
tree | c540d777fce11f28bb4aa4fbb4411800d730a755 | |
parent | ec9540a12a9170f8b88e1d715c9321edaeeebfd4 (diff) | |
download | openttd-51ddbbb13d3c6277dcd04289623efe6e00e4f1b3.tar.xz |
(svn r22242) -Codechange: Let OnInvalidateData() decide itself what to do immediately in command scope, and what to do asynchronously in GUI-scope.
-rw-r--r-- | src/window.cpp | 43 | ||||
-rw-r--r-- | src/window_func.h | 4 | ||||
-rw-r--r-- | src/window_gui.h | 22 |
3 files changed, 36 insertions, 33 deletions
diff --git a/src/window.cpp b/src/window.cpp index aa02aad11..fdf881117 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2481,46 +2481,55 @@ void SetWindowClassesDirty(WindowClass cls) /** * Mark window data of the window of a given class and specific window number as invalid (in need of re-computing) - * Note that by default the invalidation is not executed immediately but is scheduled till the next redraw. + * + * Note that by default the invalidation is not considered to be called from GUI scope. + * That means only a part of invalidation is executed immediately. The rest is scheduled for the next redraw. * The asynchronous execution is important to prevent GUI code being executed from command scope. + * When not in GUI-scope: + * - OnInvalidateData() may not do test-runs on commands, as they might affect the execution of + * the command which triggered the invalidation. (town rating and such) + * - OnInvalidateData() may not rely on _current_company == _local_company. + * This implies that no NewGRF callbacks may be run. + * + * However, when invalidations are scheduled, then multiple calls may be scheduled before execution starts. Earlier scheduled + * invalidations may be called with invalidation-data, which is already invalid at the point of execution. + * That means some stuff requires to be executed immediately in command scope, while not everything may be executed in command + * scope. While GUI-scope calls have no restrictions on what they may do, they cannot assume the game to still be in the state + * when the invalidation was scheduled; passed IDs may have got invalid in the mean time. + * + * Finally, note that invalidations triggered from commands or the game loop result in OnInvalidateData() being called twice. + * Once in command-scope, once in GUI-scope. So make sure to not process differential-changes twice. + * * @param cls Window class * @param number Window number within the class * @param data The data to invalidate with - * @param immediately If true then do not schedule the event, but execute immediately. + * @param gui_scope Whether the call is done from GUI scope */ -void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool immediately) +void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope) { Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { if (w->window_class == cls && w->window_number == number) { - if (immediately) { - w->InvalidateData(data); - } else { - w->ScheduleInvalidateData(data); - } + w->InvalidateData(data, gui_scope); } } } /** * Mark window data of all windows of a given class as invalid (in need of re-computing) - * Note that by default the invalidation is not executed immediately but is scheduled till the next redraw. - * The asynchronous execution is important to prevent GUI code being executed from command scope. + * Note that by default the invalidation is not considered to be called from GUI scope. + * See InvalidateWindowData() for details on GUI-scope vs. command-scope. * @param cls Window class * @param data The data to invalidate with - * @param immediately If true then do not schedule the event, but execute immediately. + * @param gui_scope Whether the call is done from GUI scope */ -void InvalidateWindowClassesData(WindowClass cls, int data, bool immediately) +void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope) { Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { if (w->window_class == cls) { - if (immediately) { - w->InvalidateData(data); - } else { - w->ScheduleInvalidateData(data); - } + w->InvalidateData(data, gui_scope); } } } diff --git a/src/window_func.h b/src/window_func.h index 43f50111d..604cb1d98 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -34,8 +34,8 @@ void ResetWindowSystem(); void SetupColoursAndInitialWindow(); void InputLoop(); -void InvalidateWindowData(WindowClass cls, WindowNumber number, int data = 0, bool immediately = false); -void InvalidateWindowClassesData(WindowClass cls, int data = 0, bool immediately = false); +void InvalidateWindowData(WindowClass cls, WindowNumber number, int data = 0, bool gui_scope = false); +void InvalidateWindowClassesData(WindowClass cls, int data = 0, bool gui_scope = false); void DeleteNonVitalWindows(); void DeleteAllNonVitalWindows(); diff --git a/src/window_gui.h b/src/window_gui.h index fc5ebeeda..0ec585e34 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -434,22 +434,16 @@ public: /** * Mark this window's data as invalid (in need of re-computing) * @param data The data to invalidate with + * @param gui_scope Whether the funtion is called from GUI scope. */ - void InvalidateData(int data = 0) + void InvalidateData(int data = 0, bool gui_scope = true) { this->SetDirty(); - this->OnInvalidateData(data); - } - - /** - * Schedule a invalidation call for next redraw. - * Important for asynchronous invalidation from commands. - * @param data The data to invalidate with - */ - void ScheduleInvalidateData(int data = 0) - { - this->SetDirty(); - *this->scheduled_invalidation_data.Append() = data; + if (!gui_scope) { + /* Schedule GUI-scope invalidation for next redraw. */ + *this->scheduled_invalidation_data.Append() = data; + } + this->OnInvalidateData(data, gui_scope); } /** @@ -458,7 +452,7 @@ public: void ProcessScheduledInvalidations() { for (int *data = this->scheduled_invalidation_data.Begin(); this->window_class != WC_INVALID && data != this->scheduled_invalidation_data.End(); data++) { - this->OnInvalidateData(*data); + this->OnInvalidateData(*data, true); } this->scheduled_invalidation_data.Clear(); } |