Changeset - r8925:2b882cd5b1b6
[Not reviewed]
master
0 7 1
rubidium - 16 years ago 2008-04-13 19:25:14
rubidium@openttd.org
(svn r12695) -Codechange: only allocate window structs when needed. Based on a patch by Alberth.
8 files changed with 115 insertions and 85 deletions:
0 comments (0 inline, 0 general)
source.list
Show inline comments
 
@@ -103,12 +103,13 @@ window.cpp
 
# Header Files
 
ai/ai.h
 
aircraft.h
 
airport.h
 
airport_movement.h
 
core/alloc_func.hpp
 
core/alloc_type.hpp
 
articulated_vehicles.h
 
autoreplace_base.h
 
autoreplace_func.h
 
autoreplace_gui.h
 
autoreplace_type.h
 
autoslope.h
src/core/alloc_func.hpp
Show inline comments
 
@@ -87,59 +87,7 @@ template <typename T> FORCEINLINE T* Rea
 

	
 
	t_ptr = (T*)realloc(t_ptr, num_elements * sizeof(T));
 
	if (t_ptr == NULL) ReallocError(num_elements * sizeof(T));
 
	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 */
src/core/alloc_type.hpp
Show inline comments
 
new file 100644
 

	
 
/* $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 */
src/misc.cpp
Show inline comments
 
@@ -21,13 +21,13 @@
 
#include "map_func.h"
 
#include "date_func.h"
 
#include "vehicle_func.h"
 
#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"
 

	
 
char _name_array[512][32];
 

	
src/pathfind.cpp
Show inline comments
 
@@ -14,13 +14,13 @@
 
#include "debug.h"
 
#include "tunnel_map.h"
 
#include "settings_type.h"
 
#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. */
 
static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
 
{
 
	uint hash, val, offs;
src/viewport.cpp
Show inline comments
 
@@ -24,13 +24,13 @@
 
#include "strings_func.h"
 
#include "zoom_func.h"
 
#include "vehicle_func.h"
 
#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"
 

	
 
enum {
 
	VIEWPORT_DRAW_MEM = (65536 * 2),
src/window.cpp
Show inline comments
 
@@ -22,20 +22,18 @@
 

	
 
#include "table/sprites.h"
 

	
 
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;
 

	
 
int _scrollbar_start_pos;
 
int _scrollbar_size;
 
@@ -430,12 +428,14 @@ void DeleteWindow(Window *w)
 
	/* Find the window in the z-array, and effectively remove it
 
	 * by moving all windows after it one to the left */
 
	Window **wz = FindWindowZPosition(w);
 
	if (wz == NULL) return;
 
	memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
 
	_last_z_window--;
 

	
 
	delete w;
 
}
 

	
 
/**
 
 * Find a window by its class and window number
 
 * @param cls Window class
 
 * @param number Number of the window within the window class
 
@@ -652,34 +652,12 @@ void AssignWidgetToWindow(Window *w, con
 
	} else {
 
		w->widget = NULL;
 
		w->widget_count = 0;
 
	}
 
}
 

	
 
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
 
 * See AllocateWindow() for description of arguments.
 
 * Only addition here is window_number, which is the window_number being assigned to the new window
 
 * @param x offset in pixels from the left of the screen
 
@@ -694,23 +672,24 @@ static Window *FindFreeWindow()
 
 * @param window_number number being assigned to the new window
 
 * @param data the data to be given during the WE_CREATE message
 
 * @return Window pointer of the newly created window */
 
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;
 
	w->left = x;
 
	w->top = y;
 
	w->width = min_width;
 
@@ -1054,13 +1033,12 @@ Window *FindWindowFromPt(int x, int y)
 
 * (re)initialize the windowing system
 
 */
 
void InitWindowSystem()
 
{
 
	IConsoleClose();
 

	
 
	memset(&_windows, 0, sizeof(_windows));
 
	_last_z_window = _z_windows;
 
	InitViewports();
 
	_no_scroll = 0;
 
}
 

	
 
/**
src/window_gui.h
Show inline comments
 
@@ -7,12 +7,13 @@
 

	
 
#include "core/bitmath_func.hpp"
 
#include "vehicle_type.h"
 
#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.
 
 */
 
static const int MAX_NUMBER_OF_WINDOWS = 25;
 

	
 
@@ -286,13 +287,13 @@ struct WindowMessage {
 
	int lparam;
 
};
 

	
 
/**
 
 * 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
 

	
 
	int left;   ///< x position of left edge of the window
 
	int top;    ///< y position of top edge of the window
0 comments (0 inline, 0 general)