Changeset - r17477:761eed726354
[Not reviewed]
master
0 3 0
frosch - 13 years ago 2011-03-13 21:32:13
frosch@openttd.org
(svn r22242) -Codechange: Let OnInvalidateData() decide itself what to do immediately in command scope, and what to do asynchronously in GUI-scope.
3 files changed with 36 insertions and 33 deletions:
0 comments (0 inline, 0 general)
src/window.cpp
Show inline comments
 
@@ -2481,46 +2481,55 @@ void SetWindowClassesDirty(WindowClass c
 

	
 
/**
 
 * 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);
 
		}
 
	}
 
}
src/window_func.h
Show inline comments
 
@@ -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();
src/window_gui.h
Show inline comments
 
@@ -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();
 
	}
0 comments (0 inline, 0 general)