mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-08 01:10:28 +00:00
(svn r12695) -Codechange: only allocate window structs when needed. Based on a patch by Alberth.
This commit is contained in:
parent
1fe1b5da80
commit
8ab49198b9
@ -106,6 +106,7 @@ aircraft.h
|
|||||||
airport.h
|
airport.h
|
||||||
airport_movement.h
|
airport_movement.h
|
||||||
core/alloc_func.hpp
|
core/alloc_func.hpp
|
||||||
|
core/alloc_type.hpp
|
||||||
articulated_vehicles.h
|
articulated_vehicles.h
|
||||||
autoreplace_base.h
|
autoreplace_base.h
|
||||||
autoreplace_func.h
|
autoreplace_func.h
|
||||||
|
@ -90,56 +90,4 @@ template <typename T> FORCEINLINE T* ReallocT(T *t_ptr, size_t num_elements)
|
|||||||
return t_ptr;
|
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 */
|
#endif /* ALLOC_FUNC_HPP */
|
||||||
|
102
src/core/alloc_type.hpp
Normal file
102
src/core/alloc_type.hpp
Normal file
@ -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 */
|
@ -24,7 +24,7 @@
|
|||||||
#include "texteff.hpp"
|
#include "texteff.hpp"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "depot.h"
|
#include "depot.h"
|
||||||
#include "tunnelbridge_map.h"
|
#include "tunnelbridge_map.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
#include "tunnelbridge.h"
|
#include "tunnelbridge.h"
|
||||||
|
|
||||||
/* remember which tiles we have already visited so we don't visit them again. */
|
/* remember which tiles we have already visited so we don't visit them again. */
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "station_func.h"
|
#include "station_func.h"
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -25,14 +25,12 @@
|
|||||||
static Point _drag_delta; ///< delta between mouse cursor and upper left corner of dragged window
|
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 *_mouseover_last_w = NULL; ///< Window of the last MOUSEOVER event
|
||||||
|
|
||||||
static Window _windows[MAX_NUMBER_OF_WINDOWS];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of windows opened at the screen.
|
* List of windows opened at the screen.
|
||||||
* Uppermost window is at _z_windows[_last_z_window - 1],
|
* Uppermost window is at _z_windows[_last_z_window - 1],
|
||||||
* bottom window is at _z_windows[0]
|
* 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
|
Window **_last_z_window; ///< always points to the next free space in the z-array
|
||||||
|
|
||||||
Point _cursorpos_drag_start;
|
Point _cursorpos_drag_start;
|
||||||
@ -433,6 +431,8 @@ void DeleteWindow(Window *w)
|
|||||||
if (wz == NULL) return;
|
if (wz == NULL) return;
|
||||||
memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
|
memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
|
||||||
_last_z_window--;
|
_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.
|
/** Open a new window.
|
||||||
* This function is called from AllocateWindow() or AllocateWindowDesc()
|
* This function is called from AllocateWindow() or AllocateWindowDesc()
|
||||||
* See descriptions for those functions for usage
|
* 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,
|
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)
|
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 */
|
/* 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();
|
w = FindDeletableWindow();
|
||||||
if (w == NULL) w = ForceFindDeletableWindow();
|
if (w == NULL) w = ForceFindDeletableWindow();
|
||||||
DeleteWindow(w);
|
DeleteWindow(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w = new Window;
|
||||||
|
|
||||||
/* Set up window properties */
|
/* Set up window properties */
|
||||||
memset(w, 0, sizeof(*w));
|
|
||||||
w->window_class = cls;
|
w->window_class = cls;
|
||||||
w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
||||||
w->caption_color = 0xFF;
|
w->caption_color = 0xFF;
|
||||||
@ -1057,7 +1036,6 @@ void InitWindowSystem()
|
|||||||
{
|
{
|
||||||
IConsoleClose();
|
IConsoleClose();
|
||||||
|
|
||||||
memset(&_windows, 0, sizeof(_windows));
|
|
||||||
_last_z_window = _z_windows;
|
_last_z_window = _z_windows;
|
||||||
InitViewports();
|
InitViewports();
|
||||||
_no_scroll = 0;
|
_no_scroll = 0;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "viewport_type.h"
|
#include "viewport_type.h"
|
||||||
#include "player_type.h"
|
#include "player_type.h"
|
||||||
#include "strings_type.h"
|
#include "strings_type.h"
|
||||||
|
#include "core/alloc_type.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of windows that can be opened.
|
* The maximum number of windows that can be opened.
|
||||||
@ -289,7 +290,7 @@ struct WindowMessage {
|
|||||||
/**
|
/**
|
||||||
* Data structure for an opened window
|
* Data structure for an opened window
|
||||||
*/
|
*/
|
||||||
struct Window {
|
struct Window : ZeroedMemoryAllocator {
|
||||||
uint16 flags4; ///< Window flags, @see WindowFlags
|
uint16 flags4; ///< Window flags, @see WindowFlags
|
||||||
WindowClass window_class; ///< Window class
|
WindowClass window_class; ///< Window class
|
||||||
WindowNumber window_number; ///< Window number within the window class
|
WindowNumber window_number; ///< Window number within the window class
|
||||||
|
Loading…
Reference in New Issue
Block a user