summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2008-04-13 19:25:14 +0000
committerrubidium <rubidium@openttd.org>2008-04-13 19:25:14 +0000
commit9a73b698d4045fcf19a46193cecde62bb9626bae (patch)
tree62fb23e679baa7d7fef852eba8960e2a582d1f52
parent04138ddffca9a2614849e5040501c2e4ee0311fd (diff)
downloadopenttd-9a73b698d4045fcf19a46193cecde62bb9626bae.tar.xz
(svn r12695) -Codechange: only allocate window structs when needed. Based on a patch by Alberth.
-rw-r--r--source.list1
-rw-r--r--src/core/alloc_func.hpp52
-rw-r--r--src/core/alloc_type.hpp102
-rw-r--r--src/misc.cpp2
-rw-r--r--src/pathfind.cpp2
-rw-r--r--src/viewport.cpp2
-rw-r--r--src/window.cpp36
-rw-r--r--src/window_gui.h3
8 files changed, 115 insertions, 85 deletions
diff --git a/source.list b/source.list
index f08c4302d..fd1276978 100644
--- a/source.list
+++ b/source.list
@@ -106,6 +106,7 @@ aircraft.h
airport.h
airport_movement.h
core/alloc_func.hpp
+core/alloc_type.hpp
articulated_vehicles.h
autoreplace_base.h
autoreplace_func.h
diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp
index 57a5fc3d4..2a31f8637 100644
--- a/src/core/alloc_func.hpp
+++ b/src/core/alloc_func.hpp
@@ -90,56 +90,4 @@ template <typename T> FORCEINLINE T* ReallocT(T *t_ptr, size_t num_elements)
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 */
diff --git a/src/core/alloc_type.hpp b/src/core/alloc_type.hpp
new file mode 100644
index 000000000..4146e5ca3
--- /dev/null
+++ b/src/core/alloc_type.hpp
@@ -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 */
diff --git a/src/misc.cpp b/src/misc.cpp
index a9c65b774..6a3d199ed 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -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"
diff --git a/src/pathfind.cpp b/src/pathfind.cpp
index e16836b17..89435aa39 100644
--- a/src/pathfind.cpp
+++ b/src/pathfind.cpp
@@ -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. */
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 8f7a1df2d..008d949a9 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -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"
diff --git a/src/window.cpp b/src/window.cpp
index 082f1c302..ac5ec8022 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -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 @@ void DeleteWindow(Window *w)
if (wz == NULL) return;
memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
_last_z_window--;
+
+ delete w;
}
/**
@@ -655,28 +655,6 @@ void AssignWidgetToWindow(Window *w, const Widget *widget)
}
}
-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 *FindFreeWindow()
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 @@ void InitWindowSystem()
{
IConsoleClose();
- memset(&_windows, 0, sizeof(_windows));
_last_z_window = _z_windows;
InitViewports();
_no_scroll = 0;
diff --git a/src/window_gui.h b/src/window_gui.h
index 330a6f6e9..665bcde22 100644
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -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 @@ struct WindowMessage {
/**
* 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