(svn r12695) -Codechange: only allocate window structs when needed. Based on a patch by Alberth.
authorrubidium
Sun, 13 Apr 2008 19:25:14 +0000
changeset 8925 e0d37ce1eba8
parent 8924 7063881d180a
child 8926 888a242c523f
(svn r12695) -Codechange: only allocate window structs when needed. Based on a patch by Alberth.
source.list
src/core/alloc_func.hpp
src/core/alloc_type.hpp
src/misc.cpp
src/pathfind.cpp
src/viewport.cpp
src/window.cpp
src/window_gui.h
--- a/source.list	Sun Apr 13 19:06:30 2008 +0000
+++ b/source.list	Sun Apr 13 19:25:14 2008 +0000
@@ -106,6 +106,7 @@
 airport.h
 airport_movement.h
 core/alloc_func.hpp
+core/alloc_type.hpp
 articulated_vehicles.h
 autoreplace_base.h
 autoreplace_func.h
--- a/src/core/alloc_func.hpp	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/core/alloc_func.hpp	Sun Apr 13 19:25:14 2008 +0000
@@ -90,56 +90,4 @@
 	return t_ptr;
 }
 
-/**
- * A small 'wrapper' for allocations that can be done on most OSes on the
- * stack, but are just too large to fit in the stack on devices with a small
- * stack such as the NDS.
- * So when it is possible a stack allocation is made, otherwise a heap
- * allocation is made and this is freed once the struct goes out of scope.
- * @param T      the type to make the allocation for
- * @param length the amount of items to allocate
- */
-template <typename T, size_t length>
-struct SmallStackSafeStackAlloc {
-#if !defined(__NDS__)
-	/** Storing the data on the stack */
-	T data[length];
-#else
-	/** Storing it on the heap */
-	T *data;
-	/** The length (in elements) of data in this allocator. */
-	size_t len;
-
-	/** Allocating the memory */
-	SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
-	/** And freeing when it goes out of scope */
-	~SmallStackSafeStackAlloc() { free(data); }
-#endif
-
-	/**
-	 * Gets a pointer to the data stored in this wrapper.
-	 * @return the pointer.
-	 */
-	inline operator T* () { return data; }
-
-	/**
-	 * Gets a pointer to the data stored in this wrapper.
-	 * @return the pointer.
-	 */
-	inline T* operator -> () { return data; }
-
-	/**
-	 * Gets a pointer to the last data element stored in this wrapper.
-	 * @note needed because endof does not work properly for pointers.
-	 * @return the 'endof' pointer.
-	 */
-	inline T* EndOf() {
-#if !defined(__NDS__)
-		return endof(data);
-#else
-		return &data[len];
-#endif
-	}
-};
-
 #endif /* ALLOC_FUNC_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/alloc_type.hpp	Sun Apr 13 19:25:14 2008 +0000
@@ -0,0 +1,102 @@
+
+/* $Id$ */
+
+/** @file alloc_type.hpp Helper types related to the allocation of memory */
+
+#ifndef ALLOC_TYPE_HPP
+#define ALLOC_TYPE_HPP
+
+#include "alloc_func.hpp"
+
+/**
+ * A small 'wrapper' for allocations that can be done on most OSes on the
+ * stack, but are just too large to fit in the stack on devices with a small
+ * stack such as the NDS.
+ * So when it is possible a stack allocation is made, otherwise a heap
+ * allocation is made and this is freed once the struct goes out of scope.
+ * @param T      the type to make the allocation for
+ * @param length the amount of items to allocate
+ */
+template <typename T, size_t length>
+struct SmallStackSafeStackAlloc {
+#if !defined(__NDS__)
+	/** Storing the data on the stack */
+	T data[length];
+#else
+	/** Storing it on the heap */
+	T *data;
+	/** The length (in elements) of data in this allocator. */
+	size_t len;
+
+	/** Allocating the memory */
+	SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
+	/** And freeing when it goes out of scope */
+	~SmallStackSafeStackAlloc() { free(data); }
+#endif
+
+	/**
+	 * Gets a pointer to the data stored in this wrapper.
+	 * @return the pointer.
+	 */
+	inline operator T* () { return data; }
+
+	/**
+	 * Gets a pointer to the data stored in this wrapper.
+	 * @return the pointer.
+	 */
+	inline T* operator -> () { return data; }
+
+	/**
+	 * Gets a pointer to the last data element stored in this wrapper.
+	 * @note needed because endof does not work properly for pointers.
+	 * @return the 'endof' pointer.
+	 */
+	inline T* EndOf() {
+#if !defined(__NDS__)
+		return endof(data);
+#else
+		return &data[len];
+#endif
+	}
+};
+
+/**
+ * Base class that provides memory initialization on dynamically created objects.
+ * All allocated memory will be zeroed.
+ */
+class ZeroedMemoryAllocator
+{
+public:
+	ZeroedMemoryAllocator() {}
+	virtual ~ZeroedMemoryAllocator() {}
+
+	/**
+	 * Memory allocator for a single class instance.
+	 * @param size the amount of bytes to allocate.
+	 * @return the given amounts of bytes zeroed.
+	 */
+	void *operator new(size_t size) { return CallocT<byte>(size); }
+
+	/**
+	 * Memory allocator for an array of class instances.
+	 * @param size the amount of bytes to allocate.
+	 * @return the given amounts of bytes zeroed.
+	 */
+	void *operator new[](size_t size) { return CallocT<byte>(size); }
+
+	/**
+	 * Memory release for a single class instance.
+	 * @param ptr  the memory to free.
+	 * @param size the amount of allocated memory (unused).
+	 */
+	void operator delete(void *ptr, size_t size) { free(ptr); }
+
+	/**
+	 * Memory release for an array of class instances.
+	 * @param ptr  the memory to free.
+	 * @param size the amount of allocated memory (unused).
+	 */
+	void operator delete[](void *ptr, size_t size) { free(ptr); }
+};
+
+#endif /* ALLOC_TYPE_HPP */
--- a/src/misc.cpp	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/misc.cpp	Sun Apr 13 19:25:14 2008 +0000
@@ -24,7 +24,7 @@
 #include "texteff.hpp"
 #include "string_func.h"
 #include "gfx_func.h"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
 
 #include "table/strings.h"
 #include "table/sprites.h"
--- a/src/pathfind.cpp	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/pathfind.cpp	Sun Apr 13 19:25:14 2008 +0000
@@ -17,7 +17,7 @@
 #include "depot.h"
 #include "tunnelbridge_map.h"
 #include "core/random_func.hpp"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
 #include "tunnelbridge.h"
 
 /* remember which tiles we have already visited so we don't visit them again. */
--- a/src/viewport.cpp	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/viewport.cpp	Sun Apr 13 19:25:14 2008 +0000
@@ -27,7 +27,7 @@
 #include "player_func.h"
 #include "settings_type.h"
 #include "station_func.h"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
 
 #include "table/sprites.h"
 #include "table/strings.h"
--- a/src/window.cpp	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/window.cpp	Sun Apr 13 19:25:14 2008 +0000
@@ -25,14 +25,12 @@
 static Point _drag_delta; ///< delta between mouse cursor and upper left corner of dragged window
 static Window *_mouseover_last_w = NULL; ///< Window of the last MOUSEOVER event
 
-static Window _windows[MAX_NUMBER_OF_WINDOWS];
-
 /**
  * List of windows opened at the screen.
  * Uppermost window is at  _z_windows[_last_z_window - 1],
  * bottom window is at _z_windows[0]
  */
-Window *_z_windows[lengthof(_windows)];
+Window *_z_windows[MAX_NUMBER_OF_WINDOWS];
 Window **_last_z_window; ///< always points to the next free space in the z-array
 
 Point _cursorpos_drag_start;
@@ -433,6 +431,8 @@
 	if (wz == NULL) return;
 	memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
 	_last_z_window--;
+
+	delete w;
 }
 
 /**
@@ -655,28 +655,6 @@
 	}
 }
 
-static Window *FindFreeWindow()
-{
-	Window *w;
-
-	for (w = _windows; w < endof(_windows); w++) {
-		Window* const *wz;
-		bool window_in_use = false;
-
-		FOR_ALL_WINDOWS(wz) {
-			if (*wz == w) {
-				window_in_use = true;
-				break;
-			}
-		}
-
-		if (!window_in_use) return w;
-	}
-
-	assert(_last_z_window == endof(_z_windows));
-	return NULL;
-}
-
 /** Open a new window.
  * This function is called from AllocateWindow() or AllocateWindowDesc()
  * See descriptions for those functions for usage
@@ -697,17 +675,18 @@
 static Window *LocalAllocateWindow(int x, int y, int min_width, int min_height, int def_width, int def_height,
 				WindowProc *proc, WindowClass cls, const Widget *widget, int window_number, void *data)
 {
-	Window *w = FindFreeWindow();
+	Window *w;
 
 	/* We have run out of windows, close one and use that as the place for our new one */
-	if (w == NULL) {
+	if (_last_z_window == endof(_z_windows)) {
 		w = FindDeletableWindow();
 		if (w == NULL) w = ForceFindDeletableWindow();
 		DeleteWindow(w);
 	}
 
+	w = new Window;
+
 	/* Set up window properties */
-	memset(w, 0, sizeof(*w));
 	w->window_class = cls;
 	w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
 	w->caption_color = 0xFF;
@@ -1057,7 +1036,6 @@
 {
 	IConsoleClose();
 
-	memset(&_windows, 0, sizeof(_windows));
 	_last_z_window = _z_windows;
 	InitViewports();
 	_no_scroll = 0;
--- a/src/window_gui.h	Sun Apr 13 19:06:30 2008 +0000
+++ b/src/window_gui.h	Sun Apr 13 19:25:14 2008 +0000
@@ -10,6 +10,7 @@
 #include "viewport_type.h"
 #include "player_type.h"
 #include "strings_type.h"
+#include "core/alloc_type.hpp"
 
 /**
  * The maximum number of windows that can be opened.
@@ -289,7 +290,7 @@
 /**
  * Data structure for an opened window
  */
-struct Window {
+struct Window : ZeroedMemoryAllocator {
 	uint16 flags4;              ///< Window flags, @see WindowFlags
 	WindowClass window_class;   ///< Window class
 	WindowNumber window_number; ///< Window number within the window class