mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r22242) -Codechange: Let OnInvalidateData() decide itself what to do immediately in command scope, and what to do asynchronously in GUI-scope.
This commit is contained in:
parent
ec9540a12a
commit
51ddbbb13d
|
@ -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)
|
* 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.
|
* 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 cls Window class
|
||||||
* @param number Window number within the class
|
* @param number Window number within the class
|
||||||
* @param data The data to invalidate with
|
* @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;
|
Window *w;
|
||||||
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
||||||
if (w->window_class == cls && w->window_number == number) {
|
if (w->window_class == cls && w->window_number == number) {
|
||||||
if (immediately) {
|
w->InvalidateData(data, gui_scope);
|
||||||
w->InvalidateData(data);
|
|
||||||
} else {
|
|
||||||
w->ScheduleInvalidateData(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark window data of all windows of a given class as invalid (in need of re-computing)
|
* 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.
|
* Note that by default the invalidation is not considered to be called from GUI scope.
|
||||||
* The asynchronous execution is important to prevent GUI code being executed from command scope.
|
* See InvalidateWindowData() for details on GUI-scope vs. command-scope.
|
||||||
* @param cls Window class
|
* @param cls Window class
|
||||||
* @param data The data to invalidate with
|
* @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;
|
Window *w;
|
||||||
|
|
||||||
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
FOR_ALL_WINDOWS_FROM_BACK(w) {
|
||||||
if (w->window_class == cls) {
|
if (w->window_class == cls) {
|
||||||
if (immediately) {
|
w->InvalidateData(data, gui_scope);
|
||||||
w->InvalidateData(data);
|
|
||||||
} else {
|
|
||||||
w->ScheduleInvalidateData(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ void ResetWindowSystem();
|
||||||
void SetupColoursAndInitialWindow();
|
void SetupColoursAndInitialWindow();
|
||||||
void InputLoop();
|
void InputLoop();
|
||||||
|
|
||||||
void InvalidateWindowData(WindowClass cls, WindowNumber number, 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 immediately = false);
|
void InvalidateWindowClassesData(WindowClass cls, int data = 0, bool gui_scope = false);
|
||||||
|
|
||||||
void DeleteNonVitalWindows();
|
void DeleteNonVitalWindows();
|
||||||
void DeleteAllNonVitalWindows();
|
void DeleteAllNonVitalWindows();
|
||||||
|
|
|
@ -434,22 +434,16 @@ public:
|
||||||
/**
|
/**
|
||||||
* Mark this window's data as invalid (in need of re-computing)
|
* Mark this window's data as invalid (in need of re-computing)
|
||||||
* @param data The data to invalidate with
|
* @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->SetDirty();
|
||||||
this->OnInvalidateData(data);
|
if (!gui_scope) {
|
||||||
}
|
/* Schedule GUI-scope invalidation for next redraw. */
|
||||||
|
*this->scheduled_invalidation_data.Append() = data;
|
||||||
/**
|
}
|
||||||
* Schedule a invalidation call for next redraw.
|
this->OnInvalidateData(data, gui_scope);
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -458,7 +452,7 @@ public:
|
||||||
void ProcessScheduledInvalidations()
|
void ProcessScheduledInvalidations()
|
||||||
{
|
{
|
||||||
for (int *data = this->scheduled_invalidation_data.Begin(); this->window_class != WC_INVALID && data != this->scheduled_invalidation_data.End(); data++) {
|
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();
|
this->scheduled_invalidation_data.Clear();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue