summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2009-05-22 15:13:50 +0000
committersmatz <smatz@openttd.org>2009-05-22 15:13:50 +0000
commit62a7948af0ca9eb3b190a54918201e1075edcbbc (patch)
tree27a79b7850682cd43cac2462c3410ed8b567c4b2 /src
parent04723b240ebc7384954f73590be517ad2a47ce04 (diff)
downloadopenttd-62a7948af0ca9eb3b190a54918201e1075edcbbc.tar.xz
(svn r16378) -Codechange: replace OldPool with simpler Pool. Compilation time, binary size and run time (with asserts disabled) should be improved
Diffstat (limited to 'src')
-rw-r--r--src/aircraft_cmd.cpp10
-rw-r--r--src/articulated_vehicles.cpp4
-rw-r--r--src/autoreplace.cpp9
-rw-r--r--src/autoreplace_base.h13
-rw-r--r--src/cargopacket.cpp15
-rw-r--r--src/cargopacket.h17
-rw-r--r--src/company_base.h26
-rw-r--r--src/company_cmd.cpp11
-rw-r--r--src/core/pool.hpp284
-rw-r--r--src/core/pool_func.hpp139
-rw-r--r--src/core/random_func.cpp2
-rw-r--r--src/date.cpp6
-rw-r--r--src/depot.cpp9
-rw-r--r--src/depot_base.h9
-rw-r--r--src/engine.cpp10
-rw-r--r--src/engine_base.h9
-rw-r--r--src/group.h11
-rw-r--r--src/group_cmd.cpp26
-rw-r--r--src/group_gui.cpp10
-rw-r--r--src/industry.h15
-rw-r--r--src/industry_cmd.cpp24
-rw-r--r--src/misc_gui.cpp2
-rw-r--r--src/network/core/tcp_game.cpp8
-rw-r--r--src/network/core/tcp_game.h8
-rw-r--r--src/network/network.cpp14
-rw-r--r--src/network/network_base.h9
-rw-r--r--src/network/network_chat_gui.cpp13
-rw-r--r--src/network/network_type.h9
-rw-r--r--src/newgrf.cpp5
-rw-r--r--src/newgrf_spritegroup.cpp8
-rw-r--r--src/newgrf_spritegroup.h9
-rw-r--r--src/oldpool.cpp81
-rw-r--r--src/oldpool.h385
-rw-r--r--src/oldpool_func.h63
-rw-r--r--src/openttd.cpp73
-rw-r--r--src/order_base.h36
-rw-r--r--src/order_cmd.cpp43
-rw-r--r--src/order_gui.cpp2
-rw-r--r--src/road_cmd.cpp8
-rw-r--r--src/road_cmd.h2
-rw-r--r--src/saveload/afterload.cpp2
-rw-r--r--src/saveload/oldloader.cpp4
-rw-r--r--src/saveload/oldloader_sl.cpp55
-rw-r--r--src/saveload/order_sl.cpp27
-rw-r--r--src/saveload/saveload.cpp18
-rw-r--r--src/saveload/strings_sl.cpp1
-rw-r--r--src/saveload/town_sl.cpp6
-rw-r--r--src/saveload/vehicle_sl.cpp4
-rw-r--r--src/signs.cpp9
-rw-r--r--src/signs_base.h9
-rw-r--r--src/station.cpp16
-rw-r--r--src/station_base.h28
-rw-r--r--src/station_cmd.cpp16
-rw-r--r--src/station_func.h1
-rw-r--r--src/strings.cpp12
-rw-r--r--src/town.h17
-rw-r--r--src/town_cmd.cpp29
-rw-r--r--src/train_cmd.cpp8
-rw-r--r--src/vehicle.cpp20
-rw-r--r--src/vehicle_base.h29
-rw-r--r--src/vehicle_type.h6
-rw-r--r--src/water_map.h2
-rw-r--r--src/waypoint.cpp14
-rw-r--r--src/waypoint.h11
-rw-r--r--src/waypoint_cmd.cpp2
-rw-r--r--src/waypoint_gui.cpp1
66 files changed, 816 insertions, 968 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 25ba931b0..287a99cb7 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -589,8 +589,11 @@ static void CheckIfAircraftNeedsService(Vehicle *v)
}
const Station *st = Station::Get(v->current_order.GetDestination());
+
+ assert(st != NULL);
+
/* only goto depot if the target airport has terminals (eg. it is airport) */
- if (st->IsValid() && st->airport_tile != INVALID_TILE && st->Airport()->terminals != NULL) {
+ if (st->airport_tile != INVALID_TILE && st->Airport()->terminals != NULL) {
// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
// v->u.air.targetairport = st->index;
v->current_order.MakeGoToDepot(st->index, ODTFB_SERVICE);
@@ -1535,7 +1538,7 @@ static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *a
return;
}
- if (!v->current_order.IsValid()) return;
+ if (v->current_order.IsType(OT_NOTHING)) return;
/* if the block of the next position is busy, stay put */
if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
@@ -2036,8 +2039,9 @@ bool Aircraft::Tick()
for (uint i = 0; i != 2; i++) {
/* stop if the aircraft was deleted */
+ VehicleID index = this->index;
if (!AircraftEventHandler(this, i)) return false;
- assert(this->IsValid());
+ assert(Vehicle::Get(index) == this);
assert(IsNormalAircraft(this));
}
diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp
index a271ee7ce..43cb29c58 100644
--- a/src/articulated_vehicles.cpp
+++ b/src/articulated_vehicles.cpp
@@ -21,9 +21,9 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
* either, so it doesn't matter how many articulated parts there are. */
if (!Vehicle::CanAllocateItem()) return 0;
- Vehicle *v = NULL;;
+ Vehicle *v = NULL;
if (!purchase_window) {
- v = new InvalidVehicle();
+ v = new Vehicle();
v->engine_type = engine_type;
}
diff --git a/src/autoreplace.cpp b/src/autoreplace.cpp
index f6a714401..d2fa17ba9 100644
--- a/src/autoreplace.cpp
+++ b/src/autoreplace.cpp
@@ -6,9 +6,10 @@
#include "command_func.h"
#include "group.h"
#include "autoreplace_base.h"
-#include "oldpool_func.h"
+#include "core/pool_func.hpp"
-DEFINE_OLD_POOL_GENERIC(EngineRenew, EngineRenew)
+EngineRenewPool _enginerenew_pool("EngineRenew");
+INSTANTIATE_POOL_METHODS(EngineRenew)
/**
* Retrieves the EngineRenew that specifies the replacement of the given
@@ -101,7 +102,5 @@ CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, Group
void InitializeEngineRenews()
{
- /* Clean the engine renew pool and create 1 block in it */
- _EngineRenew_pool.CleanPool();
- _EngineRenew_pool.AddBlockToPool();
+ _enginerenew_pool.CleanPool();
}
diff --git a/src/autoreplace_base.h b/src/autoreplace_base.h
index 5037c16f0..f37f68655 100644
--- a/src/autoreplace_base.h
+++ b/src/autoreplace_base.h
@@ -5,7 +5,7 @@
#ifndef AUTOREPLACE_BASE_H
#define AUTOREPLACE_BASE_H
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "autoreplace_type.h"
typedef uint16 EngineRenewID;
@@ -15,23 +15,22 @@ typedef uint16 EngineRenewID;
* placed here so the only exception to this rule, the saveload code, can use
* it.
*/
-DECLARE_OLD_POOL(EngineRenew, EngineRenew, 3, 8000)
+typedef Pool<EngineRenew, EngineRenewID, 16, 64000> EngineRenewPool;
+extern EngineRenewPool _enginerenew_pool;
/**
* Struct to store engine replacements. DO NOT USE outside of engine.c. Is
* placed here so the only exception to this rule, the saveload code, can use
* it.
*/
-struct EngineRenew : PoolItem<EngineRenew, EngineRenewID, &_EngineRenew_pool> {
+struct EngineRenew : EngineRenewPool::PoolItem<&_enginerenew_pool> {
EngineID from;
EngineID to;
EngineRenew *next;
GroupID group_id;
- EngineRenew(EngineID from = INVALID_ENGINE, EngineID to = INVALID_ENGINE) : from(from), to(to), next(NULL) {}
- ~EngineRenew() { this->from = INVALID_ENGINE; }
-
- inline bool IsValid() const { return this->from != INVALID_ENGINE; }
+ EngineRenew(EngineID from = INVALID_ENGINE, EngineID to = INVALID_ENGINE) : from(from), to(to) {}
+ ~EngineRenew() {}
};
#define FOR_ALL_ENGINE_RENEWS_FROM(var, start) FOR_ALL_ITEMS_FROM(EngineRenew, enginerenew_index, var, start)
diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp
index cd5524c57..b2ce7ed3b 100644
--- a/src/cargopacket.cpp
+++ b/src/cargopacket.cpp
@@ -4,16 +4,15 @@
#include "stdafx.h"
#include "station_base.h"
-#include "oldpool_func.h"
+#include "core/pool_func.hpp"
/* Initialize the cargopacket-pool */
-DEFINE_OLD_POOL_GENERIC(CargoPacket, CargoPacket)
+CargoPacketPool _cargopacket_pool("CargoPacket");
+INSTANTIATE_POOL_METHODS(CargoPacket)
void InitializeCargoPackets()
{
- /* Clean the cargo packet pool and create 1 block in it */
- _CargoPacket_pool.CleanPool();
- _CargoPacket_pool.AddBlockToPool();
+ _cargopacket_pool.CleanPool();
}
CargoPacket::CargoPacket(StationID source, uint16 count)
@@ -30,11 +29,6 @@ CargoPacket::CargoPacket(StationID source, uint16 count)
this->paid_for = false;
}
-CargoPacket::~CargoPacket()
-{
- this->count = 0;
-}
-
bool CargoPacket::SameSource(const CargoPacket *cp) const
{
return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit && this->paid_for == cp->paid_for;
@@ -104,7 +98,6 @@ uint CargoList::DaysInTransit() const
void CargoList::Append(CargoPacket *cp)
{
assert(cp != NULL);
- assert(cp->IsValid());
for (List::iterator it = packets.begin(); it != packets.end(); it++) {
if ((*it)->SameSource(cp) && (*it)->count + cp->count <= 65535) {
diff --git a/src/cargopacket.h b/src/cargopacket.h
index 739e7f3ed..26b38342c 100644
--- a/src/cargopacket.h
+++ b/src/cargopacket.h
@@ -5,7 +5,7 @@
#ifndef CARGOPACKET_H
#define CARGOPACKET_H
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "economy_type.h"
#include "tile_type.h"
#include "station_type.h"
@@ -15,13 +15,13 @@ typedef uint32 CargoPacketID;
struct CargoPacket;
/** We want to use a pool */
-DECLARE_OLD_POOL(CargoPacket, CargoPacket, 10, 1000)
-
+typedef Pool<CargoPacket, CargoPacketID, 1024, 1048576> CargoPacketPool;
+extern CargoPacketPool _cargopacket_pool;
/**
* Container for cargo from the same location and time
*/
-struct CargoPacket : PoolItem<CargoPacket, CargoPacketID, &_CargoPacket_pool> {
+struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> {
Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo
TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain)
TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle
@@ -40,14 +40,7 @@ struct CargoPacket : PoolItem<CargoPacket, CargoPacketID, &_CargoPacket_pool> {
CargoPacket(StationID source = INVALID_STATION, uint16 count = 0);
/** Destroy the packet */
- virtual ~CargoPacket();
-
-
- /**
- * Is this a valid cargo packet ?
- * @return true if and only it is valid
- */
- inline bool IsValid() const { return this->count != 0; }
+ ~CargoPacket() { }
/**
* Checks whether the cargo packet is from (exactly) the same source
diff --git a/src/company_base.h b/src/company_base.h
index bffe89b11..192a8deba 100644
--- a/src/company_base.h
+++ b/src/company_base.h
@@ -6,7 +6,7 @@
#define COMPANY_BASE_H
#include "company_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "road_type.h"
#include "rail_type.h"
#include "date_type.h"
@@ -25,13 +25,11 @@ struct CompanyEconomyEntry {
Money company_value;
};
-/* The third parameter and the number after >> MUST be the same,
- * otherwise more (or less) companies will be allowed to be
- * created than what MAX_COMPANIES specifies!
- */
-DECLARE_OLD_POOL(Company, Company, 1, (MAX_COMPANIES + 1) >> 1)
+typedef Pool<Company, CompanyByte, 1, MAX_COMPANIES> CompanyPool;
+extern CompanyPool _company_pool;
-struct Company : PoolItem<Company, CompanyByte, &_Company_pool> {
+
+struct Company : CompanyPool::PoolItem<&_company_pool> {
Company(uint16 name_1 = 0, bool is_ai = false);
~Company();
@@ -81,13 +79,6 @@ struct Company : PoolItem<Company, CompanyByte, &_Company_pool> {
EngineRenewList engine_renew_list; ///< Defined later
CompanySettings settings; ///< settings specific for each company
uint16 *num_engines; ///< caches the number of engines of each type the company owns (no need to save this)
-
- inline bool IsValid() const { return this->name_1 != 0; }
-
- static inline bool IsValidID(CompanyID company)
- {
- return company < MAX_COMPANIES && (uint)company < Company::GetPoolSize() && Company::Get(company)->IsValid();
- }
};
#define FOR_ALL_COMPANIES_FROM(var, start) FOR_ALL_ITEMS_FROM(Company, company_index, var, start)
@@ -95,12 +86,7 @@ struct Company : PoolItem<Company, CompanyByte, &_Company_pool> {
static inline byte ActiveCompanyCount()
{
- const Company *c;
- byte count = 0;
-
- FOR_ALL_COMPANIES(c) count++;
-
- return count;
+ return (byte)Company::GetNumItems();
}
Money CalculateCompanyValue(const Company *c);
diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
index ef694d8f2..504ea3875 100644
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -28,7 +28,7 @@
#include "road_func.h"
#include "rail.h"
#include "sprite.h"
-#include "oldpool_func.h"
+#include "core/pool_func.hpp"
#include "table/strings.h"
@@ -40,7 +40,8 @@ CompanyManagerFace _company_manager_face; ///< for company manager face storage
uint _next_competitor_start; ///< the number of ticks before the next AI is started
uint _cur_company_tick_index; ///< used to generate a name for one company that doesn't have a name yet per tick
-DEFINE_OLD_POOL_GENERIC(Company, Company)
+CompanyPool _company_pool("Company");
+INSTANTIATE_POOL_METHODS(Company)
Company::Company(uint16 name_1, bool is_ai) :
name_1(name_1),
@@ -59,7 +60,6 @@ Company::~Company()
if (CleaningPool()) return;
DeleteCompanyWindows(this->index);
- this->name_1 = 0;
}
/**
@@ -421,7 +421,7 @@ void ResetCompanyLivery(Company *c)
*/
Company *DoStartupNewCompany(bool is_ai)
{
- if (ActiveCompanyCount() == MAX_COMPANIES || !Company::CanAllocateItem()) return NULL;
+ if (!Company::CanAllocateItem()) return NULL;
/* we have to generate colour before this company is valid */
Colours colour = GenerateCompanyColour();
@@ -489,8 +489,7 @@ static void MaybeStartNewCompany()
void InitializeCompanies()
{
- _Company_pool.CleanPool();
- _Company_pool.AddBlockToPool();
+ _company_pool.CleanPool();
_cur_company_tick_index = 0;
}
diff --git a/src/core/pool.hpp b/src/core/pool.hpp
new file mode 100644
index 000000000..7c95803f7
--- /dev/null
+++ b/src/core/pool.hpp
@@ -0,0 +1,284 @@
+/* $Id$ */
+
+/** @file pool.hpp Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */
+
+#ifndef POOL_HPP
+#define POOL_HPP
+
+template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size>
+struct Pool {
+ static const size_t MAX_SIZE = Tmax_size; ///< Make template parameter accessible from outside
+
+ const char * const name; ///< Name of this pool
+
+ size_t size; ///< Current allocated size
+ size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
+ size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
+ size_t items; ///< Number of used indexes (non-NULL)
+
+ bool cleaning; ///< True if cleaning pool (deleting all items)
+
+ Titem **data; ///< Pointer to array of pointers to Titem
+
+ /** Constructor */
+ Pool(const char *name);
+ /** Destroys all items in the pool and resets all member variables */
+ void CleanPool();
+
+ /**
+ * Returs Titem with given index
+ * @param index of item to get
+ * @return pointer to Titem
+ * @pre index < this->first_unused
+ */
+ FORCEINLINE Titem *Get(size_t index)
+ {
+ assert(index < this->first_unused);
+ return this->data[index];
+ }
+
+ /**
+ * Tests whether given index can be used to get valid (non-NULL) Titem
+ * @param index index to examine
+ * @return true if PoolItem::Get(index) will return non-NULL pointer
+ */
+ FORCEINLINE bool IsValidID(size_t index)
+ {
+ return index < this->first_unused && this->Get(index) != NULL;
+ }
+
+ /**
+ * Tests whether we can allocate 'n' items
+ * @param n number of items we want to allocate
+ * @return true if 'n' items can be allocated
+ */
+ FORCEINLINE bool CanAllocate(size_t n = 1)
+ {
+ return this->items <= Tmax_size - n;
+ }
+
+ /** Base class for all PoolItems */
+ template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size> *Tpool>
+ struct PoolItem {
+ Tindex index; ///< Index of this pool item
+
+ /**
+ * Allocates space for new Titem
+ * @param size size of Titem
+ * @return pointer to allocated memory
+ * @note can never fail (return NULL), use CanAllocate() to check first!
+ */
+ FORCEINLINE void *operator new(size_t size)
+ {
+ return Tpool->GetNew(size);
+ }
+
+ /**
+ * Marks Titem as free. Its memory is released
+ * @param p memory to free
+ * @note the item has to be allocated in the pool!
+ */
+ FORCEINLINE void operator delete(void *p)
+ {
+ Titem *pn = (Titem *)p;
+ assert(pn == Tpool->Get(pn->index));
+ Tpool->FreeItem(pn->index);
+ }
+
+ /**
+ * Allocates space for new Titem with given index
+ * @param size size of Titem
+ * @param index index of item
+ * @return pointer to allocated memory
+ * @note can never fail (return NULL), use CanAllocate() to check first!
+ * @pre index has to be unused! Else it will crash
+ */
+ FORCEINLINE void *operator new(size_t size, size_t index)
+ {
+ return Tpool->GetNew(size, index);
+ }
+
+ /**
+ * Deletes item with given index.
+ * @param p Titem memory to release
+ * @param index index of item
+ * @note never use this! Only for internal use
+ * (called automatically when constructor of Titem uses throw())
+ */
+ FORCEINLINE void operator delete(void *p, size_t index)
+ {
+ assert(p == Tpool->Get(index));
+ Tpool->FreeItem(index);
+ }
+
+
+ /**
+ * Allocates space for new Titem at given memory address
+ * @param size size of Titem
+ * @param ptr where are we allocating the item?
+ * @return pointer to allocated memory (== ptr)
+ * @note use of this is strongly discouraged
+ * @pre the memory must not be allocated in the Pool!
+ */
+ FORCEINLINE void *operator new(size_t size, void *ptr)
+ {
+ for (size_t i = 0; i < Tpool->first_unused; i++) {
+ /* Don't allow creating new objects over existing.
+ * Even if we called the destructor and reused this memory,
+ * we don't know whether 'size' and size of currently allocated
+ * memory are the same (because of possible inheritance).
+ * Use { size_t index = item->index; delete item; new (index) item; }
+ * instead to make sure destructor is called and no memory leaks. */
+ assert(ptr != Tpool->data[i]);
+ }
+ return ptr;
+ }
+
+ /**
+ * Deletes item that was allocated by the function above
+ * @param p Titem memory to release
+ * @param ptr parameter given to operator new
+ * @note never use this! Only for internal use
+ * (called automatically when constructor of Titem uses throw())
+ */
+ FORCEINLINE void operator delete(void *p, void *ptr)
+ {
+ assert(p == ptr);
+ for (size_t i = 0; i < Tpool->first_unused; i++) {
+ assert(ptr != Tpool->data[i]);
+ }
+ }
+
+
+ /** Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() */
+
+ /**
+ * Tests whether we can allocate 'n' items
+ * @param n number of items we want to allocate
+ * @return true if 'n' items can be allocated
+ */
+ static FORCEINLINE bool CanAllocateItem(size_t n = 1)
+ {
+ return Tpool->CanAllocate(n);
+ }
+
+ /**
+ * Returns current state of pool cleaning - yes or no
+ * @return true iff we are cleaning the pool now
+ */
+ static FORCEINLINE bool CleaningPool()
+ {
+ return Tpool->cleaning;
+ }
+
+ /**
+ * Tests whether given index can be used to get valid (non-NULL) Titem
+ * @param index index to examine
+ * @return true if PoolItem::Get(index) will return non-NULL pointer
+ */
+ static FORCEINLINE bool IsValidID(size_t index)
+ {
+ return Tpool->IsValidID(index);
+ }
+
+ /**
+ * Returs Titem with given index
+ * @param index of item to get
+ * @return pointer to Titem
+ * @pre index < this->first_unused
+ */
+ static FORCEINLINE Titem *Get(size_t index)
+ {
+ return Tpool->Get(index);
+ }
+
+ /**
+ * Returs Titem with given index
+ * @param index of item to get
+ * @return pointer to Titem
+ * @note returns NULL for invalid index
+ */
+ static FORCEINLINE Titem *GetIfValid(size_t index)
+ {
+ return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
+ }
+
+ /**
+ * Returns first unused index. Useful when iterating over
+ * all pool items.
+ * @return first unused index
+ */
+ static FORCEINLINE size_t GetPoolSize()
+ {
+ return Tpool->first_unused;
+ }
+
+ /**
+ * Returns number of valid items in the pool
+ * @return number of valid items in the pool
+ */
+ static FORCEINLINE size_t GetNumItems()
+ {
+ return Tpool->items;
+ }
+ };
+
+private:
+ static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t); ///< Contant to indicate we can't allocate any more items
+
+ /**
+ * Makes given index valid
+ * @param size size of item
+ * @param index index of item
+ * @pre index < this->size
+ * @pre this->Get(index) == NULL
+ */
+ void *AllocateItem(size_t size, size_t index);
+
+ /**
+ * Resizes the pool so 'index' can be addressed
+ * @param index index we will allocate later
+ * @pre index >= this->size
+ * @pre index < Tmax_size
+ */
+ void ResizeFor(size_t index);
+
+ /**
+ * Searches for first free index
+ * @return first free index, NO_FREE_ITEM on failure
+ */
+ size_t FindFirstFree();
+
+ /**
+ * Allocates new item
+ * @param size size of item
+ * @return pointer to allocated item
+ * @note error() on failure! (no free item)
+ */
+ void *GetNew(size_t size);
+
+ /**
+ * Allocates new item with given index
+ * @param size size of item
+ * @param index index of item
+ * @return pointer to allocated item
+ * @note usererror() on failure! (index out of range or already used)
+ */
+ void *GetNew(size_t size, size_t index);
+
+ /**
+ * Deallocates memory used by this index and marks item as free
+ * @param index item to deallocate
+ * @pre unit is allocated (non-NULL)
+ * @note 'delete NULL' doesn't cause call of this function, so it is safe
+ */
+ void FreeItem(size_t index);
+};
+
+#define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
+ for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
+ if ((var = type::Get(iter)) != NULL)
+
+#define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
+
+#endif /* POOL_HPP */
diff --git a/src/core/pool_func.hpp b/src/core/pool_func.hpp
new file mode 100644
index 000000000..df9e2692f
--- /dev/null
+++ b/src/core/pool_func.hpp
@@ -0,0 +1,139 @@
+/* $Id$ */
+
+/** @file pool_func.hpp Some methods of Pool are placed here in order to reduce compilation time and binary size. */
+
+#ifndef POOL_FUNC_HPP
+#define POOL_FUNC_HPP
+
+#include "alloc_func.hpp"
+#include "mem_func.hpp"
+#include "pool.hpp"
+
+#define DEFINE_POOL_METHOD(type) \
+ template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size> \
+ type Pool<Titem, Tindex, Tgrowth_step, Tmax_size>
+
+DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
+ name(name),
+ size(0),
+ first_free(0),
+ first_unused(0),
+ items(0),
+ cleaning(false),
+ data(NULL)
+{ }
+
+DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index)
+{
+ assert(index >= this->size);
+ assert(index < Tmax_size);
+
+ size_t new_size = min(Tmax_size, Align(index + 1, Tgrowth_step));
+
+ this->data = ReallocT(this->data, new_size);
+ MemSetT(this->data + this->size, 0, new_size - this->size);
+
+ this->size = new_size;
+}
+
+DEFINE_POOL_METHOD(inline size_t)::FindFirstFree()
+{
+ size_t index = this->first_free;
+
+ for (; index < this->first_unused; index++) {
+ if (this->data[index] == NULL) return index;
+ }
+
+ if (index < this->size) {
+ return index;
+ }
+
+ assert(index == this->size);
+ assert(this->first_unused == this->size);
+
+ if (index < Tmax_size) {
+ this->ResizeFor(index);
+ return index;
+ }
+
+ assert(this->items == Tmax_size);
+
+ return NO_FREE_ITEM;
+}
+
+DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
+{
+ assert(this->data[index] == NULL);
+
+ this->first_unused = max(this->first_unused, index + 1);
+ this->items++;
+
+ Titem *item = this->data[index] = (Titem *)CallocT<byte>(size);
+ item->index = (uint)index;
+ return item;
+}
+
+DEFINE_POOL_METHOD(void *)::GetNew(size_t size)
+{
+ size_t index = this->FindFirstFree();
+
+ if (index == NO_FREE_ITEM) {
+ error("%s: no more free items", this->name);
+ }
+
+ this->first_free = index + 1;
+ return this->AllocateItem(size, index);
+}
+
+DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index)
+{
+ if (index >= Tmax_size) {
+ usererror("failed loading savegame: %s index " PRINTF_SIZE " out of range (" PRINTF_SIZE ")", this->name, index, Tmax_size);
+ }
+
+ if (index >= this->size) this->ResizeFor(index);
+
+ if (this->data[index] != NULL) {
+ usererror("failed loading savegame: %s index " PRINTF_SIZE " already in use", this->name, index);
+ }
+
+ return this->AllocateItem(size, index);
+}
+
+DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
+{
+ assert(index < this->size);
+ assert(this->data[index] != NULL);
+ free(this->data[index]);
+ this->data[index] = NULL;
+ this->first_free = min(this->first_free, index);
+ this->items--;
+}
+
+DEFINE_POOL_METHOD(void)::CleanPool()
+{
+ this->cleaning = true;
+ for (size_t i = 0; i < this->first_unused; i++) {
+ delete this->Get(i); // 'delete NULL;' is very valid
+ }
+ assert(this->items == 0);
+ free(this->data);
+ this->first_unused = this->first_free = this->size = 0;
+ this->data = NULL;
+ this->cleaning = false;
+}
+
+#undef DEFINE_POOL_METHOD
+
+/**
+ * Force instantiation of pool methods so we don't get linker errors.
+ * Only methods accessed from methods defined in pool.hpp need to be
+ * forcefully instantiated.
+ */
+#define INSTANTIATE_POOL_METHODS(name) \
+ template void * name ## Pool::GetNew(size_t size); \
+ template void * name ## Pool::GetNew(size_t size, size_t index); \
+ template void name ## Pool::FreeItem(size_t index); \
+ template void name ## Pool::CleanPool();
+
+#endif /* POOL_FUNC_HPP */
diff --git a/src/core/random_func.cpp b/src/core/random_func.cpp
index 6e9cb0a94..4e2897625 100644
--- a/src/core/random_func.cpp
+++ b/src/core/random_func.cpp
@@ -40,7 +40,7 @@ void SetRandomSeed(uint32 seed)
uint32 DoRandom(int line, const char *file)
{
- if (_networking && (NetworkClientSocket::Get(0)->status != STATUS_INACTIVE || !_network_server)) {
+ if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != STATUS_INACTIVE))) {
printf("Random [%d/%d] %s:%d\n", _frame_counter, (byte)_current_company, file, line);
}
diff --git a/src/date.cpp b/src/date.cpp
index 858c65119..2f297591d 100644
--- a/src/date.cpp
+++ b/src/date.cpp
@@ -184,12 +184,10 @@ static const Month _autosave_months[] = {
*/
static void RunVehicleDayProc(uint daytick)
{
- uint total = Vehicle::GetPoolSize();
-
- for (uint i = daytick; i < total; i += DAY_TICKS) {
+ for (size_t i = daytick; i < Vehicle::GetPoolSize(); i += DAY_TICKS) {
Vehicle *v = Vehicle::Get(i);
- if (v->IsValid()) {
+ if (v != NULL) {
/* Call the 32-day callback if needed */
CheckVehicle32Day(v);
v->OnNewDay();
diff --git a/src/depot.cpp b/src/depot.cpp
index e73490071..b034e8531 100644
--- a/src/depot.cpp
+++ b/src/depot.cpp
@@ -6,12 +6,13 @@
#include "depot_base.h"
#include "order_func.h"
#include "window_func.h"
-#include "oldpool_func.h"
#include "core/bitmath_func.hpp"
#include "tile_map.h"
#include "water_map.h"
+#include "core/pool_func.hpp"
-DEFINE_OLD_POOL_GENERIC(Depot, Depot)
+DepotPool _depot_pool("Depot");
+INSTANTIATE_POOL_METHODS(Depot)
/**
* Gets a depot from a tile
@@ -48,11 +49,9 @@ Depot::~Depot()
/* Delete the depot-window */
DeleteWindowById(WC_VEHICLE_DEPOT, this->xy);
- this->xy = INVALID_TILE;
}
void InitializeDepots()
{
- _Depot_pool.CleanPool();
- _Depot_pool.AddBlockToPool();
+ _depot_pool.CleanPool();
}
diff --git a/src/depot_base.h b/src/depot_base.h
index 350eaee8f..b4e47cb60 100644
--- a/src/depot_base.h
+++ b/src/depot_base.h
@@ -7,19 +7,18 @@
#include "tile_type.h"
#include "depot_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "town_type.h"
-DECLARE_OLD_POOL(Depot, Depot, 3, 8000)
+typedef Pool<Depot, DepotID, 64, 64000> DepotPool;
+extern DepotPool _depot_pool;
-struct Depot : PoolItem<Depot, DepotID, &_Depot_pool> {
+struct Depot : DepotPool::PoolItem<&_depot_pool> {
TileIndex xy;
TownID town_index;
Depot(TileIndex xy = INVALID_TILE) : xy(xy) {}
~Depot();
-
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
};
Depot *GetDepotByTile(TileIndex tile);
diff --git a/src/engine.cpp b/src/engine.cpp
index 24918c11c..262729c19 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -18,15 +18,16 @@
#include "date_func.h"
#include "autoreplace_gui.h"
#include "string_func.h"
-#include "oldpool_func.h"
#include "ai/ai.hpp"
#include "vehicle_func.h"
#include "settings_type.h"
+#include "core/pool_func.hpp"
#include "table/strings.h"
#include "table/engines.h"
-DEFINE_OLD_POOL_GENERIC(Engine, Engine)
+EnginePool _engine_pool("Engine");
+INSTANTIATE_POOL_METHODS(Engine)
EngineOverrideManager _engine_mngr;
@@ -356,7 +357,7 @@ EngineID EngineOverrideManager::GetID(VehicleType type, uint16 grf_local_id, uin
*/
void SetCachedEngineCounts()
{
- uint engines = Engine::GetPoolSize();
+ size_t engines = Engine::GetPoolSize();
/* Set up the engine count for all companies */
Company *c;
@@ -392,8 +393,7 @@ void SetCachedEngineCounts()
void SetupEngines()
{
- _Engine_pool.CleanPool();
- _Engine_pool.AddBlockToPool();
+ _engine_pool.CleanPool();
assert(_engine_mngr.Length() >= _engine_mngr.NUM_DEFAULT_ENGINES);
const EngineIDMapping *end = _engine_mngr.End();
diff --git a/src/engine_base.h b/src/engine_base.h
index e3e055164..3e53564e4 100644
--- a/src/engine_base.h
+++ b/src/engine_base.h
@@ -7,12 +7,13 @@
#include "engine_type.h"
#include "economy_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "core/smallvec_type.hpp"
-DECLARE_OLD_POOL(Engine, Engine, 6, 10000)
+typedef Pool<Engine, EngineID, 64, 64000> EnginePool;
+extern EnginePool _engine_pool;
-struct Engine : PoolItem<Engine, EngineID, &_Engine_pool> {
+struct Engine : EnginePool::PoolItem<&_engine_pool> {
char *name; ///< Custom name of engine
Date intro_date;
Date age;
@@ -49,8 +50,6 @@ struct Engine : PoolItem<Engine, EngineID, &_Engine_pool> {
Engine(VehicleType type, EngineID base);
~Engine();
- inline bool IsValid() const { return this->info.climates != 0; }
-
CargoID GetDefaultCargoType() const;
bool CanCarryCargo() const;
uint GetDisplayDefaultCapacity() const;
diff --git a/src/group.h b/src/group.h
index 193568ca0..e60f66c43 100644
--- a/src/group.h
+++ b/src/group.h
@@ -6,14 +6,15 @@
#define GROUP_H
#include "group_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "company_type.h"
#include "vehicle_type.h"
#include "engine_type.h"
-DECLARE_OLD_POOL(Group, Group, 5, 2047)
+typedef Pool<Group, GroupID, 16, 64000> GroupPool;
+extern GroupPool _group_pool;
-struct Group : PoolItem<Group, GroupID, &_Group_pool> {
+struct Group : GroupPool::PoolItem<&_group_pool> {
char *name; ///< Group Name
uint16 num_vehicle; ///< Number of vehicles wich belong to the group
@@ -24,9 +25,7 @@ struct Group : PoolItem<Group, GroupID, &_Group_pool> {
uint16 *num_engines; ///< Caches the number of engines of each type the company owns (no need to save this)
Group(CompanyID owner = INVALID_COMPANY);
- virtual ~Group();
-
- bool IsValid() const;
+ ~Group();
};
diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp
index 030bf6918..1c1b78fee 100644
--- a/src/group_cmd.cpp
+++ b/src/group_cmd.cpp
@@ -14,13 +14,16 @@
#include "autoreplace_func.h"
#include "string_func.h"
#include "company_func.h"
-#include "oldpool_func.h"
#include "core/alloc_func.hpp"
+#include "core/pool_func.hpp"
#include "table/strings.h"
GroupID _new_group_id;
+GroupPool _group_pool("Group");
+INSTANTIATE_POOL_METHODS(Group)
+
/**
* Update the num engines of a groupID. Decrease the old one and increase the new one
* @note called in SetTrainGroupID and UpdateTrainGroupID
@@ -40,32 +43,25 @@ static inline void UpdateNumEngineGroup(EngineID i, GroupID old_g, GroupID new_g
}
-DEFINE_OLD_POOL_GENERIC(Group, Group)
-
Group::Group(Owner owner)
{
this->owner = owner;
- if (this->IsValid()) this->num_engines = CallocT<uint16>(Engine::GetPoolSize());
+ if (!Company::IsValidID(owner)) return;
+
+ this->num_engines = CallocT<uint16>(Engine::GetPoolSize());
}
Group::~Group()
{
free(this->name);
- this->owner = INVALID_OWNER;
free(this->num_engines);
}
-bool Group::IsValid() const
-{
- return this->owner != INVALID_OWNER;
-}
-
void InitializeGroup()
{
- _Group_pool.CleanPool();
- _Group_pool.AddBlockToPool();
+ _group_pool.CleanPool();
}
@@ -334,7 +330,7 @@ CommandCost CmdSetGroupReplaceProtection(TileIndex tile, DoCommandFlag flags, ui
*/
void RemoveVehicleFromGroup(const Vehicle *v)
{
- if (!v->IsValid() || !v->IsPrimaryVehicle()) return;
+ if (!v->IsPrimaryVehicle()) return;
if (!IsDefaultGroupID(v->group_id)) DecreaseGroupNumVehicle(v->group_id);
}
@@ -350,7 +346,7 @@ void SetTrainGroupID(Vehicle *v, GroupID new_g)
{
if (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g)) return;
- assert(v->IsValid() && v->type == VEH_TRAIN && IsFrontEngine(v));
+ assert(v->type == VEH_TRAIN && IsFrontEngine(v));
for (Vehicle *u = v; u != NULL; u = u->Next()) {
if (IsEngineCountable(u)) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g);
@@ -372,7 +368,7 @@ void SetTrainGroupID(Vehicle *v, GroupID new_g)
*/
void UpdateTrainGroupID(Vehicle *v)
{
- assert(v->IsValid() && v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v)));
+ assert(v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v)));
GroupID new_g = IsFrontEngine(v) ? v->group_id : (GroupID)DEFAULT_GROUP;
for (Vehicle *u = v; u != NULL; u = u->Next()) {
diff --git a/src/group_gui.cpp b/src/group_gui.cpp
index 248025563..bf262b2ab 100644
--- a/src/group_gui.cpp
+++ b/src/group_gui.cpp
@@ -533,22 +533,18 @@ public:
case GRP_WIDGET_LIST_VEHICLE: { // Matrix Vehicle
uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)this->resize.step_height;
- const Vehicle *v;
-
if (id_v >= this->vscroll.cap) return; // click out of bounds
id_v += this->vscroll.pos;
if (id_v >= this->vehicles.Length()) return; // click out of list bound
- v = this->vehicles[id_v];
+ const Vehicle *v = this->vehicles[id_v];
this->vehicle_sel = v->index;
- if (v->IsValid()) {
- SetObjectToPlaceWnd(v->GetImage(DIR_W), GetVehiclePalette(v), HT_DRAG, this);
- _cursor.vehchain = true;
- }
+ SetObjectToPlaceWnd(v->GetImage(DIR_W), GetVehiclePalette(v), HT_DRAG, this);
+ _cursor.vehchain = true;
this->SetDirty();
break;
diff --git a/src/industry.h b/src/industry.h
index a99e8fc09..e3a4292e6 100644
--- a/src/industry.h
+++ b/src/industry.h
@@ -5,7 +5,7 @@
#ifndef INDUSTRY_H
#define INDUSTRY_H
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "core/random_func.hpp"
#include "newgrf_storage.h"
#include "cargo_type.h"
@@ -90,12 +90,13 @@ enum IndustryBehaviour {
DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour);
-DECLARE_OLD_POOL(Industry, Industry, 3, 8000)
+typedef Pool<Industry, IndustryID, 64, 64000> IndustryPool;
+extern IndustryPool _industry_pool;
/**
* Defines the internal data of a functionnal industry
*/
-struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> {
+struct Industry : IndustryPool::PoolItem<&_industry_pool> {
typedef PersistentStorageArray<uint32, 16> PersistentStorage;
TileIndex xy; ///< coordinates of the primary tile the industry is built one
@@ -134,8 +135,6 @@ struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> {
Industry(TileIndex tile = INVALID_TILE) : xy(tile) {}
~Industry();
-
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
};
struct IndustryTileTable {
@@ -265,12 +264,11 @@ void BuildIndustriesLegend();
/* industry_cmd.cpp */
void SetIndustryDailyChanges();
-extern int _total_industries; // general counter
extern uint16 _industry_counts[NUM_INDUSTRYTYPES]; // Number of industries per type ingame
static inline uint GetNumIndustries()
{
- return _total_industries;
+ return (uint)Industry::GetNumItems();
}
/** Increment the count of industries for this type
@@ -280,7 +278,6 @@ static inline void IncIndustryTypeCount(IndustryType type)
{
assert(type < INVALID_INDUSTRYTYPE);
_industry_counts[type]++;
- _total_industries++;
}
/** Decrement the count of industries for this type
@@ -290,7 +287,6 @@ static inline void DecIndustryTypeCount(IndustryType type)
{
assert(type < INVALID_INDUSTRYTYPE);
_industry_counts[type]--;
- _total_industries--;
}
/** get the count of industries for this type
@@ -306,7 +302,6 @@ static inline uint8 GetIndustryTypeCount(IndustryType type)
* This way, we centralize all counts activities */
static inline void ResetIndustryCounts()
{
- _total_industries = 0;
memset(&_industry_counts, 0, sizeof(_industry_counts));
}
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 23ff10046..754cee0fe 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -30,22 +30,24 @@
#include "date_func.h"
#include "vehicle_func.h"
#include "sound_func.h"
-#include "oldpool_func.h"
#include "animated_tile_func.h"
#include "effectvehicle_func.h"
#include "ai/ai.hpp"
+#include "core/pool_func.hpp"
#include "table/strings.h"
#include "table/industry_land.h"
#include "table/build_industry.h"
+IndustryPool _industry_pool("Industry");
+INSTANTIATE_POOL_METHODS(Industry)
+
void ShowIndustryViewWindow(int industry);
void BuildOilRig(TileIndex tile);
static byte _industry_sound_ctr;
static TileIndex _industry_sound_tile;
-int _total_industries; ///< General counter
uint16 _industry_counts[NUM_INDUSTRYTYPES]; ///< Number of industries per type ingame
IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
@@ -80,8 +82,6 @@ void ResetIndustryCreationProbility(IndustryType type)
_industry_specs[type].appear_creation[_settings_game.game_creation.landscape] = 0;
}
-DEFINE_OLD_POOL_GENERIC(Industry, Industry)
-
/**
* Retrieve the type for this industry. Although it is accessed by a tile,
* it will return the general type of industry, and not the sprite index
@@ -95,7 +95,8 @@ IndustryType GetIndustryType(TileIndex tile)
assert(IsTileType(tile, MP_INDUSTRY));
const Industry *ind = GetIndustryByTile(tile);
- return ind->IsValid() ? ind->type : (IndustryType)IT_INVALID;
+ assert(ind != NULL);
+ return ind->type;
}
/**
@@ -132,10 +133,7 @@ Industry::~Industry()
/* Industry can also be destroyed when not fully initialized.
* This means that we do not have to clear tiles either. */
- if (this->width == 0) {
- this->xy = INVALID_TILE;
- return;
- }
+ if (this->width == 0) return;
BEGIN_TILE_LOOP(tile_cur, this->width, this->height, this->xy);
if (IsTileType(tile_cur, MP_INDUSTRY)) {
@@ -167,7 +165,6 @@ Industry::~Industry()
DeleteSubsidyWithIndustry(this->index);
DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
- this->xy = INVALID_TILE;
}
static void IndustryDrawSugarMine(const TileInfo *ti)
@@ -1624,7 +1621,7 @@ static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCo
/* We need to return a non-NULL pointer to tell we have created an industry.
* However, we haven't created a real one (no DC_EXEC), so return a fake one. */
- return Industry::Get(0);
+ return (Industry *)-1;
}
/** Build/Fund an industry
@@ -2011,7 +2008,7 @@ int WhoCanServiceIndustry(Industry *ind)
if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
/* Vehicle visits a station to load or unload */
Station *st = Station::Get(o->GetDestination());
- if (!st->IsValid()) continue;
+ assert(st != NULL);
/* Same cargo produced by industry is dropped here => not serviced by vehicle v */
if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
@@ -2323,8 +2320,7 @@ void IndustryMonthlyLoop()
void InitializeIndustries()
{
- _Industry_pool.CleanPool();
- _Industry_pool.AddBlockToPool();
+ _industry_pool.CleanPool();
ResetIndustryCounts();
_industry_sound_tile = 0;
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index e373373a6..643abfb67 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -184,7 +184,7 @@ public:
/* Local authority */
SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
- if (t != NULL && t->IsValid()) {
+ if (t != NULL) {
SetDParam(0, STR_TOWN);
SetDParam(1, t->index);
}
diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp
index d34ace4bf..b4bb52190 100644
--- a/src/network/core/tcp_game.cpp
+++ b/src/network/core/tcp_game.cpp
@@ -13,16 +13,16 @@
#include "../network_internal.h"
#include "packet.h"
#include "tcp_game.h"
+#include "../../core/pool_func.hpp"
#include "table/strings.h"
-#include "../../oldpool_func.h"
/** Make very sure the preconditions given in network_type.h are actually followed */
-assert_compile(MAX_CLIENT_SLOTS == (MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK) << NCI_BITS_PER_POOL_BLOCK);
assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
+assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
-typedef ClientIndex NetworkClientSocketID;
-DEFINE_OLD_POOL_GENERIC(NetworkClientSocket, NetworkClientSocket);
+NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket");
+INSTANTIATE_POOL_METHODS(NetworkClientSocket)
NetworkClientSocket::NetworkClientSocket(ClientID client_id)
{
diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h
index bfc82f17f..d01a3d9a8 100644
--- a/src/network/core/tcp_game.h
+++ b/src/network/core/tcp_game.h
@@ -12,6 +12,7 @@
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
+#include "../../core/pool.hpp"
/**
* Enum with all types of UDP packets.
@@ -76,12 +77,12 @@ enum ClientStatus {
STATUS_ACTIVE, ///< The client is active within in the game
};
-
class NetworkClientSocket;
-DECLARE_OLD_POOL(NetworkClientSocket, NetworkClientSocket, NCI_BITS_PER_POOL_BLOCK, MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK);
+typedef Pool<NetworkClientSocket, ClientIndex, 8, MAX_CLIENT_SLOTS> NetworkClientSocketPool;
+extern NetworkClientSocketPool _networkclientsocket_pool;
/** Base socket handler for all TCP sockets */
-class NetworkClientSocket : public PoolItem<NetworkClientSocket, ClientIndex, &_NetworkClientSocket_pool>, public NetworkTCPSocketHandler {
+class NetworkClientSocket : public NetworkClientSocketPool::PoolItem<&_networkclientsocket_pool>, public NetworkTCPSocketHandler {
/* TODO: rewrite into a proper class */
private:
NetworkClientInfo *info; ///< Client info related to this socket
@@ -100,7 +101,6 @@ public:
NetworkClientSocket(ClientID client_id = INVALID_CLIENT_ID);
~NetworkClientSocket();
- inline bool IsValid() const { return this->IsConnected(); }
inline void SetInfo(NetworkClientInfo *info) { assert(info != NULL && this->info == NULL); this->info = info; }
inline NetworkClientInfo *GetInfo() const { return this->info; }
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 4d407e2b0..266ce506d 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -32,16 +32,18 @@
#include "../landscape_type.h"
#include "../rev.h"
#include "../core/alloc_func.hpp"
+#include "../core/pool_func.hpp"
#ifdef DEBUG_DUMP_COMMANDS
#include "../fileio_func.h"
#endif /* DEBUG_DUMP_COMMANDS */
#include "table/strings.h"
-#include "../oldpool_func.h"
DECLARE_POSTFIX_INCREMENT(ClientID);
-typedef ClientIndex NetworkClientInfoID;
-DEFINE_OLD_POOL_GENERIC(NetworkClientInfo, NetworkClientInfo);
+assert_compile(NetworkClientInfoPool::MAX_SIZE == NetworkClientSocketPool::MAX_SIZE);
+
+NetworkClientInfoPool _networkclientinfo_pool("NetworkClientInfo");
+INSTANTIATE_POOL_METHODS(NetworkClientInfo)
bool _networking; ///< are we in networking mode?
bool _network_server; ///< network-server is active
@@ -557,10 +559,8 @@ static bool NetworkListen()
/** Resets both pools used for network clients */
static void InitializeNetworkPools()
{
- _NetworkClientSocket_pool.CleanPool();
- _NetworkClientSocket_pool.AddBlockToPool();
- _NetworkClientInfo_pool.CleanPool();
- _NetworkClientInfo_pool.AddBlockToPool();
+ _networkclientsocket_pool.CleanPool();
+ _networkclientinfo_pool.CleanPool();
}
/* Close all current connections */
diff --git a/src/network/network_base.h b/src/network/network_base.h
index 700541b49..2714217cd 100644
--- a/src/network/network_base.h
+++ b/src/network/network_base.h
@@ -8,11 +8,12 @@
#ifdef ENABLE_NETWORK
#include "network_type.h"
-#include "../oldpool.h"
+#include "../core/pool.hpp"
-DECLARE_OLD_POOL(NetworkClientInfo, NetworkClientInfo, NCI_BITS_PER_POOL_BLOCK, MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK);
+typedef Pool<NetworkClientInfo, ClientIndex, 8, MAX_CLIENT_SLOTS> NetworkClientInfoPool;
+extern NetworkClientInfoPool _networkclientinfo_pool;
-struct NetworkClientInfo : PoolItem<NetworkClientInfo, ClientIndex, &_NetworkClientInfo_pool> {
+struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_pool> {
ClientID client_id; ///< Client identifier (same as ClientState->client_id)
char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the client
byte client_lang; ///< The language of the client
@@ -23,8 +24,6 @@ struct NetworkClientInfo : PoolItem<NetworkClientInfo, ClientIndex, &_NetworkCli
NetworkClientInfo(ClientID client_id = INVALID_CLIENT_ID) : client_id(client_id) {}
~NetworkClientInfo() { client_id = INVALID_CLIENT_ID; }
-
- inline bool IsValid() const { return client_id != INVALID_CLIENT_ID; }
};
#define FOR_ALL_CLIENT_INFOS_FROM(var, start) FOR_ALL_ITEMS_FROM(NetworkClientInfo, clientinfo_index, var, start)
diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp
index 9f896c185..4284f15d7 100644
--- a/src/network/network_chat_gui.cpp
+++ b/src/network/network_chat_gui.cpp
@@ -303,14 +303,11 @@ struct NetworkChatWindow : public QueryStringBaseWindow {
/* First, try clients */
if (*item < MAX_CLIENT_SLOTS) {
- if (*item < NetworkClientInfo::GetPoolSize()) {
- /* Skip inactive clients */
- NetworkClientInfo *ci;
- FOR_ALL_CLIENT_INFOS_FROM(ci, *item) break;
- if (ci != NULL) {
- *item = ci->index;
- return ci->client_name;
- }
+ /* Skip inactive clients */
+ NetworkClientInfo *ci;
+ FOR_ALL_CLIENT_INFOS_FROM(ci, *item) {
+ *item = ci->index;
+ return ci->client_name;
}
*item = MAX_CLIENT_SLOTS;
}
diff --git a/src/network/network_type.h b/src/network/network_type.h
index 7e27d398c..4bdb64429 100644
--- a/src/network/network_type.h
+++ b/src/network/network_type.h
@@ -16,13 +16,10 @@ enum {
/** How many clients can we have */
MAX_CLIENTS = 255,
- /** The number of bits per pool client block */
- NCI_BITS_PER_POOL_BLOCK = 3, // => 8 items per block
/**
- * The number of slots; must be a multiple of (1 << NCI_BITS_PER_POOL_BLOCK)
- * and be at least 1 more than MAX_CLIENTS. It must furthermore be less than
- * or equal to 256 as client indices (sent over the network) are 8 bits.
- * It needs 1 more for the dedicated server.
+ * The number of slots; must be at least 1 more than MAX_CLIENTS. It must
+ * furthermore be less than or equal to 256 as client indices (sent over
+ * the network) are 8 bits. It needs 1 more for the dedicated server.
*/
MAX_CLIENT_SLOTS = 256,
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 06aafc09d..d5ed0d69c 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -378,7 +378,7 @@ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 intern
if (static_access) return NULL;
- uint engine_pool_size = Engine::GetPoolSize();
+ size_t engine_pool_size = Engine::GetPoolSize();
/* ... it's not, so create a new one based off an existing engine */
Engine *e = new Engine(type, internal_id);
@@ -5623,8 +5623,7 @@ static void ResetNewGRFData()
_grf_id_overrides.clear();
InitializeSoundPool();
- _SpriteGroup_pool.CleanPool();
- _SpriteGroup_pool.AddBlockToPool();
+ _spritegroup_pool.CleanPool();
}
static void BuildCargoTranslationMap()
diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp
index c4b400210..d29c193e3 100644
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -3,13 +3,13 @@
/** @file newgrf_spritegroup.cpp Handling of primarily NewGRF action 2. */
#include "stdafx.h"
-#include "oldpool.h"
#include "newgrf.h"
#include "newgrf_spritegroup.h"
#include "sprite.h"
-#include "oldpool_func.h"
+#include "core/pool_func.hpp"
-DEFINE_OLD_POOL_GENERIC(SpriteGroup, SpriteGroup)
+SpriteGroupPool _spritegroup_pool("SpriteGroup");
+INSTANTIATE_POOL_METHODS(SpriteGroup)
SpriteGroup::~SpriteGroup()
{
@@ -37,8 +37,6 @@ SpriteGroup::~SpriteGroup()
default:
break;
}
-
- this->type = SGT_INVALID;
}
TemporaryStorageArray<uint32, 0x110> _temp_store;
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
index 1e745480b..ebaa908ea 100644
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -11,7 +11,7 @@
#include "gfx_type.h"
#include "engine_type.h"
#include "tile_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "newgrf_cargo.h"
#include "newgrf_callbacks.h"
@@ -184,10 +184,11 @@ enum SpriteGroupType {
};
typedef uint32 SpriteGroupID;
-DECLARE_OLD_POOL(SpriteGroup, SpriteGroup, 9, 250)
+typedef Pool<SpriteGroup, SpriteGroupID, 512, 64000> SpriteGroupPool;
+extern SpriteGroupPool _spritegroup_pool;
/* Common wrapper for all the different sprite group types */
-struct SpriteGroup : PoolItem<SpriteGroup, SpriteGroupID, &_SpriteGroup_pool> {
+struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
SpriteGroup(SpriteGroupType type = SGT_INVALID) :
type(type)
{
@@ -206,8 +207,6 @@ struct SpriteGroup : PoolItem<SpriteGroup, SpriteGroupID, &_SpriteGroup_pool> {
TileLayoutSpriteGroup layout;
IndustryProductionSpriteGroup indprod;
} g;
-
- inline bool IsValid() const { return this->type != SGT_INVALID; }
};
diff --git a/src/oldpool.cpp b/src/oldpool.cpp
deleted file mode 100644
index 7cec9d597..000000000
--- a/src/oldpool.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* $Id$ */
-
-/** @file oldpool.cpp Implementation of the old pool. */
-
-#include "stdafx.h"
-#include "debug.h"
-#include "oldpool.h"
-#include "core/alloc_func.hpp"
-
-/**
- * Clean a pool in a safe way (does free all blocks)
- */
-void OldMemoryPoolBase::CleanPool()
-{
- uint i;
-
- DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", this->name);
-
- this->cleaning_pool = true;
- /* Free all blocks */
- for (i = 0; i < this->current_blocks; i++) {
- if (this->clean_block_proc != NULL) {
- this->clean_block_proc(i * (1 << this->block_size_bits), (i + 1) * (1 << this->block_size_bits) - 1);
- }
- free(this->blocks[i]);
- }
- this->cleaning_pool = false;
-
- /* Free the block itself */
- free(this->blocks);
-
- /* Clear up some critical data */
- this->total_items = 0;
- this->current_blocks = 0;
- this->blocks = NULL;
- this->first_free_index = 0;
-}
-
-/**
- * This function tries to increase the size of array by adding
- * 1 block too it
- *
- * @return Returns false if the pool could not be increased
- */
-bool OldMemoryPoolBase::AddBlockToPool()
-{
- /* Is the pool at his max? */
- if (this->max_blocks == this->current_blocks) return false;
-
- this->total_items = (this->current_blocks + 1) * (1 << this->block_size_bits);
-
- DEBUG(misc, 4, "[Pool] (%s) increasing size of pool to %d items (%d bytes)", this->name, this->total_items, this->total_items * this->item_size);
-
- /* Increase the poolsize */
- this->blocks = ReallocT(this->blocks, this->current_blocks + 1);
-
- /* Allocate memory to the new block item */
- this->blocks[this->current_blocks] = CallocT<byte>(this->item_size * (1 << this->block_size_bits));
-
- /* Call a custom function if defined (e.g. to fill indexes) */
- if (this->new_block_proc != NULL) this->new_block_proc(this->current_blocks * (1 << this->block_size_bits));
-
- /* We have a new block */
- this->current_blocks++;
-
- return true;
-}
-
-/**
- * Adds blocks to the pool if needed (and possible) till index fits inside the pool
- *
- * @return Returns false if adding failed
- */
-bool OldMemoryPoolBase::AddBlockIfNeeded(uint index)
-{
- while (index >= this->total_items) {
- if (!this->AddBlockToPool()) return false;
- }
-
- return true;
-}
diff --git a/src/oldpool.h b/src/oldpool.h
deleted file mode 100644
index 17b791ed7..000000000
--- a/src/oldpool.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/* $Id$ */
-
-/** @file oldpool.h Base for the old pool. */
-
-#ifndef OLDPOOL_H
-#define OLDPOOL_H
-
-#include "core/math_func.hpp"
-
-/* The function that is called after a new block is added
- start_item is the first item of the new made block */
-typedef void OldMemoryPoolNewBlock(uint start_item);
-/* The function that is called before a block is cleaned up */
-typedef void OldMemoryPoolCleanBlock(uint start_item, uint end_item);
-
-/**
- * Stuff for dynamic vehicles. Use the wrappers to access the OldMemoryPool
- * please try to avoid manual calls!
- */
-struct OldMemoryPoolBase {
- void CleanPool();
- bool AddBlockToPool();
- bool AddBlockIfNeeded(uint index);
-
-protected:
- OldMemoryPoolBase(const char *name, uint max_blocks, uint block_size_bits, uint item_size,
- OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) :
- name(name), max_blocks(max_blocks), block_size_bits(block_size_bits),
- new_block_proc(new_block_proc), clean_block_proc(clean_block_proc), current_blocks(0),
- total_items(0), cleaning_pool(false), item_size(item_size), first_free_index(0), blocks(NULL) {}
-
- const char *name; ///< Name of the pool (just for debugging)
-
- const uint max_blocks; ///< The max amount of blocks this pool can have
- const uint block_size_bits; ///< The size of each block in bits
-
- /** Pointer to a function that is called after a new block is added */
- OldMemoryPoolNewBlock *new_block_proc;
- /** Pointer to a function that is called to clean a block */
- OldMemoryPoolCleanBlock *clean_block_proc;
-
- uint current_blocks; ///< How many blocks we have in our pool
- uint total_items; ///< How many items we now have in this pool
-
- bool cleaning_pool; ///< Are we currently cleaning the pool?
-public:
- const uint item_size; ///< How many bytes one block is
- uint first_free_index; ///< The index of the first free pool item in this pool
- byte **blocks; ///< An array of blocks (one block hold all the items)
-
- /**
- * Check if the index of pool item being deleted is lower than cached first_free_index
- * @param index index of pool item
- * @note usage of min() will result in better code on some architectures
- */
- inline void UpdateFirstFreeIndex(uint index)
- {
- first_free_index = min(first_free_index, index);
- }
-
- /**
- * Get the size of this pool, i.e. the total number of items you
- * can put into it at the current moment; the pool might still
- * be able to increase the size of the pool.
- * @return the size of the pool
- */
- inline uint GetSize() const
- {
- return this->total_items;
- }
-
- /**
- * Can this pool allocate more blocks, i.e. is the maximum amount
- * of allocated blocks not yet reached?
- * @return the if and only if the amount of allocable blocks is
- * less than the amount of allocated blocks.
- */
- inline bool CanAllocateMoreBlocks() const
- {
- return this->current_blocks < this->max_blocks;
- }
-
- /**
- * Get the maximum number of allocable blocks.
- * @return the numebr of blocks
- */
- inline uint GetBlockCount() const
- {
- return this->current_blocks;
- }
-
- /**
- * Get the name of this pool.
- * @return the name
- */
- inline const char *GetName() const
- {
- return this->name;
- }
-
- /**
- * Is the pool in the cleaning phase?
- * @return true if it is
- */
- inline bool CleaningPool() const
- {
- return this->cleaning_pool;
- }
-};
-
-template <typename T>
-struct OldMemoryPool : public OldMemoryPoolBase {
- OldMemoryPool(const char *name, uint max_blocks, uint block_size_bits, uint item_size,
- OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) :
- OldMemoryPoolBase(name, max_blocks, block_size_bits, item_size, new_block_proc, clean_block_proc) {}
-
- /**
- * Get the pool entry at the given index.
- * @param index the index into the pool
- * @pre index < this->GetSize()
- * @return the pool entry.
- */
- inline T *Get(uint index) const
- {
- assert(index < this->GetSize());
- return (T*)(this->blocks[index >> this->block_size_bits] +
- (index & ((1 << this->block_size_bits) - 1)) * this->item_size);
- }
-};
-
-/**
- * Generic function to initialize a new block in a pool.
- * @param start_item the first item that needs to be initialized
- */
-template <typename T, OldMemoryPool<T> *Tpool>
-static void PoolNewBlock(uint start_item)
-{
- for (T *t = Tpool->Get(start_item); t != NULL; t = (t->index + 1U < Tpool->GetSize()) ? Tpool->Get(t->index + 1U) : NULL) {
- t = new (t) T();
- t->index = start_item++;
- }
-}
-
-/**
- * Generic function to free a new block in a pool.
- * @param start_item the first item that needs to be cleaned
- * @param end_item the last item that needs to be cleaned
- */
-template <typename T, OldMemoryPool<T> *Tpool>
-static void PoolCleanBlock(uint start_item, uint end_item)
-{
- for (uint i = start_item; i <= end_item; i++) {
- T *t = Tpool->Get(i);
- delete t;
- }
-}
-
-/**
- * Template providing a predicate to allow STL containers of
- * pointers to pool items to be sorted by index.
- */
-template <typename T>
-struct PoolItemIndexLess {
- /**
- * The actual comparator.
- * @param lhs the left hand side of the comparison.
- * @param rhs the right hand side of the comparison.
- * @return true if lhs' index is less than rhs' index.
- */
- bool operator()(const T *lhs, const T *rhs) const
- {
- return lhs->index < rhs->index;
- }
-};
-
-/**
- * Generalization for all pool items that are saved in the savegame.
- * It specifies all the mechanics to access the pool easily.
- */
-template <typename T, typename Tid, OldMemoryPool<T> *Tpool>
-struct PoolItem {
- /**
- * The pool-wide index of this object.
- */
- Tid index;
-
- /**
- * We like to have the correct class destructed.
- * @warning It is called even for object allocated on stack,
- * so it is not present in the TPool!
- * Then, index is undefined, not associated with TPool in any way.
- * @note The idea is to free up allocated memory etc.
- */
- virtual ~PoolItem()
- {
-
- }
-
- /**
- * Constructor of given class.
- * @warning It is called even for object allocated on stack,
- * so it may not be present in TPool!
- * Then, index is undefined, not associated with TPool in any way.
- * @note The idea is to initialize variables (except index)
- */
- PoolItem()
- {
-
- }
-
- /**
- * An overriden version of new that allocates memory on the pool.
- * @param size the size of the variable (unused)
- * @pre CanAllocateItem()
- * @return the memory that is 'allocated'
- */
- void *operator new(size_t size)
- {
- return AllocateRaw();
- }
-
- /**
- * 'Free' the memory allocated by the overriden new.
- * @param p the memory to 'free'
- * @note we only update Tpool->first_free_index
- */
- void operator delete(void *p)
- {
- Tpool->UpdateFirstFreeIndex(((T*)p)->index);
- }
-
- /**
- * An overriden version of new, so you can directly allocate a new object with
- * the correct index when one is loading the savegame.
- * @param size the size of the variable (unused)
- * @param index the index of the object
- * @return the memory that is 'allocated'
- */
- void *operator new(size_t size, int index)
- {
- if (!Tpool->AddBlockIfNeeded(index)) error("%s: failed loading savegame: too many %s", Tpool->GetName(), Tpool->GetName());
-
- return Tpool->Get(index);
- }
-
- /**
- * 'Free' the memory allocated by the overriden new.
- * @param p the memory to 'free'
- * @param index the original parameter given to create the memory
- * @note we only update Tpool->first_free_index
- */
- void operator delete(void *p, int index)
- {
- Tpool->UpdateFirstFreeIndex(index);
- }
-
- /**
- * An overriden version of new, so you can use the vehicle instance
- * instead of a newly allocated piece of memory.
- * @param size the size of the variable (unused)
- * @param pn the already existing object to use as 'storage' backend
- * @return the memory that is 'allocated'
- */
- void *operator new(size_t size, T *pn)
- {
- return pn;
- }
-
- /**
- * 'Free' the memory allocated by the overriden new.
- * @param p the memory to 'free'
- * @param pn the pointer that was given to 'new' on creation.
- * @note we only update Tpool->first_free_index
- */
- void operator delete(void *p, T *pn)
- {
- Tpool->UpdateFirstFreeIndex(pn->index);
- }
-
- /**
- * Get item with given index
- * @param index item to get
- */
- static FORCEINLINE T *Get(uint index)
- {
- return Tpool->Get(index);
- }
-
- /**
- * Get item with given index
- * @param index item to get
- * @return NULL for invalid items
- */
- static FORCEINLINE T *GetIfValid(uint index)
- {
- if (index >= Tpool->GetSize()) return NULL;
- T *item = Tpool->Get(index);
- return item->IsValid() ? item : NULL;
- }
-
- /**
- * Returns size of the pool (in number of items)
- * @return size of the pool
- */
- static FORCEINLINE uint GetPoolSize()
- {
- return Tpool->GetSize();
- }
-
- /**
- * Tests if given ID belongs to valid pool item
- * @return is given ID valid?
- */
- static FORCEINLINE bool IsValidID(uint index)
- {
- return index < Tpool->GetSize() && Tpool->Get(index)->IsValid();
- }
-
-private:
- static T *AllocateSafeRaw(uint &first);
-
-protected:
- /**
- * Allocate a pool item; possibly allocate a new block in the pool.
- * @pre CanAllocateItem()
- * @return the allocated pool item.
- */
- static inline T *AllocateRaw()
- {
- return AllocateSafeRaw(Tpool->first_free_index);
- }
-
- /**
- * Allocate a pool item; possibly allocate a new block in the pool.
- * @param first the first pool item to start searching
- * @pre CanAllocateItem()
- * @return the allocated pool item.
- */
- static inline T *AllocateRaw(uint &first)
- {
- if (first >= Tpool->GetSize() && !Tpool->AddBlockToPool()) return NULL;
-
- return AllocateSafeRaw(first);
- }
-
- /**
- * Are we cleaning this pool?
- * @return true if we are
- */
- static inline bool CleaningPool()
- {
- return Tpool->CleaningPool();
- }
-
-public:
- static bool CanAllocateItem(uint count = 1);
-};
-
-
-#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
- enum { \
- name##_POOL_BLOCK_SIZE_BITS = block_size_bits, \
- name##_POOL_MAX_BLOCKS = max_blocks \
- };
-
-
-#define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \
- OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
- extern OldMemoryPool<type> _##name##_pool;
-
-
-#define DEFINE_OLD_POOL_GENERIC(name, type) \
- OldMemoryPool<type> _##name##_pool( \
- #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \
- PoolNewBlock<type, &_##name##_pool>, PoolCleanBlock<type, &_##name##_pool>); \
- template type *PoolItem<type, type##ID, &_##name##_pool>::AllocateSafeRaw(uint &first); \
- template bool PoolItem<type, type##ID, &_##name##_pool>::CanAllocateItem(uint count);
-
-#define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
- for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
- if ((var = type::Get(iter))->IsValid())
-
-#define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
-
-#endif /* OLDPOOL_H */
diff --git a/src/oldpool_func.h b/src/oldpool_func.h
deleted file mode 100644
index 82b451617..000000000
--- a/src/oldpool_func.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $Id$ */
-
-/** @file oldpool_func.h Functions related to the old pool. */
-
-#ifndef OLDPOOL_FUNC_H
-#define OLDPOOL_FUNC_H
-
-#include "oldpool.h"
-
-/**
- * Allocate a pool item; possibly allocate a new block in the pool.
- * @param first the first pool item to start searching
- * @pre first <= Tpool->GetSize()
- * @pre CanAllocateItem()
- * @return the allocated pool item
- */
-template<typename T, typename Tid, OldMemoryPool<T> *Tpool> T *PoolItem<T, Tid, Tpool>::AllocateSafeRaw(uint &first)
-{
- uint last_minus_one = Tpool->GetSize() - 1;
-
- for (T *t = Tpool->Get(first); t != NULL; t = ((uint)t->index < last_minus_one) ? Tpool->Get(t->index + 1U) : NULL) {
- if (!t->IsValid()) {
- first = t->index;
- Tid index = t->index;
-
- memset(t, 0, Tpool->item_size);
- t->index = index;
- return t;
- }
- }
-
- /* Check if we can add a block to the pool */
- if (Tpool->AddBlockToPool()) return AllocateRaw(first);
-
- /* One should *ALWAYS* be sure to have enough space before making vehicles! */
- NOT_REACHED();
-}
-
-/**
- * Check whether we can allocate an item in this pool. This to prevent the
- * need to actually construct the object and then destructing it again,
- * which could be *very* costly.
- * @param count the number of items to create
- * @return true if and only if at least count items can be allocated.
- */
-template<typename T, typename Tid, OldMemoryPool<T> *Tpool> bool PoolItem<T, Tid, Tpool>::CanAllocateItem(uint count)
-{
- uint last_minus_one = Tpool->GetSize() - 1;
- uint orig_count = count;
-
- for (T *t = Tpool->Get(Tpool->first_free_index); count > 0 && t != NULL; t = ((uint)t->index < last_minus_one) ? Tpool->Get(t->index + 1U) : NULL) {
- if (!t->IsValid()) count--;
- }
-
- if (count == 0) return true;
-
- /* Check if we can add a block to the pool */
- if (Tpool->AddBlockToPool()) return CanAllocateItem(orig_count);
-
- return false;
-}
-
-#endif /* OLDPOOL_FUNC_H */
diff --git a/src/openttd.cpp b/src/openttd.cpp
index cd2840664..3b5ff715a 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -291,7 +291,6 @@ static void InitializeDynamicVariables()
_house_mngr.ResetMapping();
_industry_mngr.ResetMapping();
_industile_mngr.ResetMapping();
- _Company_pool.AddBlockToPool();
}
@@ -316,16 +315,17 @@ static void ShutdownGame()
/* Uninitialize variables that are allocated dynamically */
GamelogReset();
- _Town_pool.CleanPool();
- _Industry_pool.CleanPool();
- _Station_pool.CleanPool();
- _Vehicle_pool.CleanPool();
- _Sign_pool.CleanPool();
- _Order_pool.CleanPool();
- _Group_pool.CleanPool();
- _CargoPacket_pool.CleanPool();
- _Engine_pool.CleanPool();
- _Company_pool.CleanPool();
+ _town_pool.CleanPool();
+ _industry_pool.CleanPool();
+ _station_pool.CleanPool();
+ _roadstop_pool.CleanPool();
+ _vehicle_pool.CleanPool();
+ _sign_pool.CleanPool();
+ _order_pool.CleanPool();
+ _group_pool.CleanPool();
+ _cargopacket_pool.CleanPool();
+ _engine_pool.CleanPool();
+ _company_pool.CleanPool();
free(_config_file);
@@ -1034,6 +1034,55 @@ void SwitchToMode(SwitchMode new_mode)
}
+#include "depot_base.h"
+#include "autoreplace_base.h"
+#include "waypoint.h"
+#include "network/core/tcp_game.h"
+#include "network/network_base.h"
+/** Make sure everything is valid. Will be removed in future. */
+static void CheckPools()
+{
+ const Depot *d;
+ FOR_ALL_DEPOTS(d) assert(IsRoadDepotTile(d->xy) || IsRailDepotTile(d->xy) || IsShipDepotTile(d->xy) || IsHangarTile(d->xy));
+ const Industry *i;
+ FOR_ALL_INDUSTRIES(i) assert(IsValidTile(i->xy));
+ const Engine *e;
+ FOR_ALL_ENGINES(e) assert(e->info.climates != 0);
+ const Order *o;
+ FOR_ALL_ORDERS(o) assert(!o->IsType(OT_NOTHING));
+ const OrderList *ol;
+ FOR_ALL_ORDER_LISTS(ol) assert(ol->GetNumOrders() != INVALID_VEH_ORDER_ID && ol->GetNumVehicles() != 0);
+ const Town *t;
+ FOR_ALL_TOWNS(t) assert(IsValidTile(t->xy));
+ const Group *g;
+ FOR_ALL_GROUPS(g) assert(g->owner != INVALID_OWNER);
+ const EngineRenew *er;
+ FOR_ALL_ENGINE_RENEWS(er) assert(er->from != INVALID_ENGINE);
+ const Waypoint *wp;
+ FOR_ALL_WAYPOINTS(wp) assert(IsValidTile(wp->xy));
+ const Company *c;
+ FOR_ALL_COMPANIES(c) assert(c->name_1 != 0);
+ const CargoPacket *cp;
+ FOR_ALL_CARGOPACKETS(cp) assert(cp->count != 0);
+#ifdef ENABLE_NETWORK
+ const NetworkClientSocket *ncs;
+ FOR_ALL_CLIENT_SOCKETS(ncs) assert(ncs->IsConnected());
+ const NetworkClientInfo *nci;
+ FOR_ALL_CLIENT_INFOS(nci) assert(nci->client_id != INVALID_CLIENT_ID);
+#endif
+ const Station *st;
+ FOR_ALL_STATIONS(st) assert(IsValidTile(st->xy));
+ const RoadStop *rs;
+ FOR_ALL_ROADSTOPS(rs) assert(IsValidTile(rs->xy));
+ const Sign *si;
+ FOR_ALL_SIGNS(si) assert(si->owner != INVALID_OWNER);
+ const Vehicle *v;
+ FOR_ALL_VEHICLES(v) assert(v->type != VEH_INVALID);
+
+ FOR_ALL_ORDER_LISTS(ol) ol->DebugCheckSanity();
+}
+
+
/**
* State controlling game loop.
* The state must not be changed from anywhere but here.
@@ -1048,6 +1097,8 @@ void StateGameLoop()
}
if (IsGeneratingWorld()) return;
+ CheckPools();
+
ClearStorageChanges(false);
if (_game_mode == GM_EDITOR) {
diff --git a/src/order_base.h b/src/order_base.h
index 544c31b2d..6630efe64 100644
--- a/src/order_base.h
+++ b/src/order_base.h
@@ -6,7 +6,7 @@
#define ORDER_BASE_H
#include "order_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "core/bitmath_func.hpp"
#include "cargo_type.h"
#include "depot_type.h"
@@ -14,15 +14,17 @@
#include "vehicle_type.h"
#include "waypoint_type.h"
-DECLARE_OLD_POOL(Order, Order, 6, 1000)
-DECLARE_OLD_POOL(OrderList, OrderList, 4, 4000)
+typedef Pool<Order, OrderID, 256, 64000> OrderPool;
+typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
+extern OrderPool _order_pool;
+extern OrderListPool _orderlist_pool;
/* If you change this, keep in mind that it is saved on 3 places:
* - Load_ORDR, all the global orders
* - Vehicle -> current_order
* - REF_ORDER (all REFs are currently limited to 16 bits!!)
*/
-struct Order : PoolItem<Order, OrderID, &_Order_pool> {
+struct Order : OrderPool::PoolItem<&_order_pool> {
private:
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
friend void Load_VEHS(); ///< Loading of ancient vehicles.
@@ -42,7 +44,7 @@ public:
uint16 travel_time; ///< How long in ticks the journey to this destination should take.
Order() : refit_cargo(CT_NO_REFIT) {}
- ~Order() { this->type = OT_NOTHING; }
+ ~Order() {}
/**
* Create an order based on a packed representation of that order.
@@ -51,12 +53,6 @@ public:
Order(uint32 packed);
/**
- * Check if a Order really exists.
- * @return true if the order is valid.
- */
- inline bool IsValid() const { return this->type != OT_NOTHING; }
-
- /**
* Check whether this order is of the given type.
* @param type the type to check against.
* @return true if the order matches.
@@ -246,7 +242,7 @@ public:
/** Shared order list linking together the linked list of orders and the list
* of vehicles sharing this order list.
*/
-struct OrderList : PoolItem<OrderList, OrderListID, &_OrderList_pool> {
+struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
private:
friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain
friend const struct SaveLoad *GetOrderListDescription(); ///< Saving and loading of order lists.
@@ -265,16 +261,20 @@ public:
timetable_duration(0) { }
/** Create an order list with the given order chain for the given vehicle.
- * @param chain is the pointer to the first order of the order chain
- * @param v is any vehicle of the shared order vehicle chain (does not need to be the first)
+ * @param chain pointer to the first order of the order chain
+ * @param v any vehicle using this orderlist
*/
- OrderList(Order *chain, Vehicle *v);
+ OrderList(Order *chain, Vehicle *v) { this->Initialize(chain, v); }
/** Destructor. Invalidates OrderList for re-usage by the pool. */
- ~OrderList() { this->num_orders = INVALID_VEH_ORDER_ID; }
+ ~OrderList() {}
- /** Checks, if this is a valid order list. */
- inline bool IsValid() const { return this->num_orders != INVALID_VEH_ORDER_ID; }
+ /**
+ * Recomputes everything.
+ * @param chain first order in the chain
+ * @param v one of vehicle that is using this orderlist
+ */
+ void Initialize(Order *chain, Vehicle *v);
/**
* Get the first order of the order chain.
diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp
index 230137efa..c3bb1384f 100644
--- a/src/order_cmd.cpp
+++ b/src/order_cmd.cpp
@@ -17,9 +17,9 @@
#include "newgrf_cargo.h"
#include "timetable.h"
#include "vehicle_func.h"
-#include "oldpool_func.h"
#include "depot_base.h"
#include "settings_type.h"
+#include "core/pool_func.hpp"
#include "table/strings.h"
@@ -33,8 +33,10 @@ assert_compile(sizeof(DestinationID) >= sizeof(StationID));
TileIndex _backup_orders_tile;
BackuppedOrders _backup_orders_data;
-DEFINE_OLD_POOL_GENERIC(Order, Order);
-DEFINE_OLD_POOL_GENERIC(OrderList, OrderList);
+OrderPool _order_pool("Order");
+INSTANTIATE_POOL_METHODS(Order)
+OrderListPool _orderlist_pool("OrderList");
+INSTANTIATE_POOL_METHODS(OrderList)
void Order::Free()
{
@@ -176,17 +178,21 @@ void Order::AssignOrder(const Order &other)
this->travel_time = other.travel_time;
}
-
-OrderList::OrderList(Order *chain, Vehicle *v) :
- first(chain), num_orders(0), num_vehicles(1), first_shared(v),
- timetable_duration(0)
+void OrderList::Initialize(Order *chain, Vehicle *v)
{
+ this->first = chain;
+ this->first_shared = v;
+
+ this->num_orders = 0;
+ this->num_vehicles = 1;
+ this->timetable_duration = 0;
+
for (Order *o = this->first; o != NULL; o = o->next) {
++this->num_orders;
this->timetable_duration += o->wait_time + o->travel_time;
}
- for (Vehicle *u = v->PreviousShared(); u != NULL; u = u->PreviousShared()) {
+ for (Vehicle *u = this->first_shared->PreviousShared(); u != NULL; u = u->PreviousShared()) {
++this->num_vehicles;
this->first_shared = u;
}
@@ -197,7 +203,7 @@ OrderList::OrderList(Order *chain, Vehicle *v) :
void OrderList::FreeChain(bool keep_orderlist)
{
Order *next;
- for(Order *o = this->first; o != NULL; o = next) {
+ for (Order *o = this->first; o != NULL; o = next) {
next = o->next;
delete o;
}
@@ -1143,10 +1149,13 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
(*order_dst)->AssignOrder(*order);
order_dst = &(*order_dst)->next;
}
- if (dst->orders.list == NULL) dst->orders.list = new OrderList(first, dst);
- else {
+ if (dst->orders.list == NULL) {
+ dst->orders.list = new OrderList(first, dst);
+ } else {
assert(dst->orders.list->GetFirstOrder() == NULL);
- new (dst->orders.list) OrderList(first, dst);
+ assert(!dst->orders.list->IsShared());
+ delete dst->orders.list;
+ dst->orders.list = new OrderList(first, dst);
}
InvalidateVehicleOrder(dst, -1);
@@ -1272,7 +1281,7 @@ void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *bak)
* order number is one more than the current amount of orders, and because
* in network the commands are queued before send, the second insert always
* fails in test mode. By bypassing the test-mode, that no longer is a problem. */
- for (uint i = 0; bak->order[i].IsValid(); i++) {
+ for (uint i = 0; !bak->order[i].IsType(OT_NOTHING); i++) {
Order o = bak->order[i];
/* Conditional orders need to have their destination to be valid on insertion. */
if (o.IsType(OT_CONDITIONAL)) o.SetConditionSkipToOrder(0);
@@ -1291,7 +1300,7 @@ void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *bak)
}
/* Fix the conditional orders' destination. */
- for (uint i = 0; bak->order[i].IsValid(); i++) {
+ for (uint i = 0; !bak->order[i].IsType(OT_NOTHING); i++) {
if (!bak->order[i].IsType(OT_CONDITIONAL)) continue;
if (!DoCommandP(0, v->index + (i << 16), MOF_LOAD | (bak->order[i].GetConditionSkipToOrder() << 4),
@@ -1776,11 +1785,9 @@ bool Order::ShouldStopAtStation(const Vehicle *v, StationID station) const
void InitializeOrders()
{
- _Order_pool.CleanPool();
- _Order_pool.AddBlockToPool();
+ _order_pool.CleanPool();
- _OrderList_pool.CleanPool();
- _OrderList_pool.AddBlockToPool();
+ _orderlist_pool.CleanPool();
_backup_orders_tile = 0;
}
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 1f6958471..e44c27f9a 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -1088,7 +1088,7 @@ public:
if (v != NULL && this->HandleOrderVehClick(v)) return;
const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
- if (!cmd.IsValid()) return;
+ if (cmd.IsType(OT_NOTHING)) return;
if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
/* With quick goto the Go To button stays active */
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index 356d1696e..30b606bc3 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -1243,11 +1243,13 @@ void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt)
}
}
-/** Updates cached nearest town for all road tiles
+/**
+ * Updates cached nearest town for all road tiles
* @param invalidate are we just invalidating cached data?
+ * @param ignore town that should be ignored (because we are deleting it now)
* @pre invalidate == true implies _generating_world == true
*/
-void UpdateNearestTownForRoadTiles(bool invalidate)
+void UpdateNearestTownForRoadTiles(bool invalidate, const Town *ignore)
{
assert(!invalidate || _generating_world);
@@ -1255,7 +1257,7 @@ void UpdateNearestTownForRoadTiles(bool invalidate)
if (IsTileType(t, MP_ROAD) && !HasTownOwnedRoad(t)) {
TownID tid = (TownID)INVALID_TOWN;
if (!invalidate) {
- const Town *town = CalcClosestTownFromTile(t);
+ const Town *town = CalcClosestTownFromTile(t, UINT_MAX, ignore);
if (town != NULL) tid = town->index;
}
SetTownIndex(t, tid);
diff --git a/src/road_cmd.h b/src/road_cmd.h
index 00235a3b3..d1ff2b8d0 100644
--- a/src/road_cmd.h
+++ b/src/road_cmd.h
@@ -8,6 +8,6 @@
#include "direction_type.h"
void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt);
-void UpdateNearestTownForRoadTiles(bool invalidate);
+void UpdateNearestTownForRoadTiles(bool invalidate, const struct Town *ignore = NULL);
#endif /* ROAD_CMD_H */
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index e350b343e..f32af8537 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -1457,7 +1457,7 @@ bool AfterLoadGame()
Vehicle *v;
FOR_ALL_VEHICLES(v) {
- if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && !v->orders.list->GetFirstOrder()->IsValid()) {
+ if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && v->orders.list->GetFirstOrder()->IsType(OT_NOTHING)) {
v->orders.list->FreeChain();
v->orders.list = NULL;
}
diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp
index 1feb3e4fa..25589a03c 100644
--- a/src/saveload/oldloader.cpp
+++ b/src/saveload/oldloader.cpp
@@ -148,8 +148,8 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
default: NOT_REACHED();
}
- /* Sanity check */
- assert(base_ptr != NULL || chunk->ptr != NULL);
+ /* When both pointers are NULL, we are just skipping data */
+ if (base_ptr == NULL && chunk->ptr == NULL) continue;
/* Writing to the var: bits 8 to 15 have the VAR type */
if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp
index ca63e7c1e..5e6202401 100644
--- a/src/saveload/oldloader_sl.cpp
+++ b/src/saveload/oldloader_sl.cpp
@@ -160,6 +160,8 @@ void FixOldVehicles()
Vehicle *v;
FOR_ALL_VEHICLES(v) {
+ if (v->next != NULL) v->next = Vehicle::Get((size_t)v->next);
+
/* For some reason we need to correct for this */
switch (v->spritenum) {
case 0xfd: break;
@@ -578,7 +580,7 @@ static bool LoadOldTown(LoadgameState *ls, int num)
t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
}
} else {
- t->xy = INVALID_TILE;
+ delete t;
}
return true;
@@ -594,12 +596,15 @@ static bool LoadOldOrder(LoadgameState *ls, int num)
{
if (!LoadChunk(ls, NULL, order_chunk)) return false;
- new (num) Order(UnpackOldOrder(_old_order));
+ Order *o = new (num) Order(UnpackOldOrder(_old_order));
- /* Relink the orders to eachother (in the orders for one vehicle are behind eachother,
- * with an invalid order (OT_NOTHING) as indication that it is the last order */
- if (num > 0 && Order::Get(num)->IsValid()) {
- Order::Get(num - 1)->next = Order::Get(num);
+ if (o->IsType(OT_NOTHING)) {
+ delete o;
+ } else {
+ /* Relink the orders to eachother (in the orders for one vehicle are behind eachother,
+ * with an invalid order (OT_NOTHING) as indication that it is the last order */
+ Order *prev = Order::GetIfValid(num - 1);
+ if (prev != NULL) prev->next = o;
}
return true;
@@ -642,7 +647,7 @@ static bool LoadOldDepot(LoadgameState *ls, int num)
if (d->xy != 0) {
d->town_index = RemapTownIndex(_old_town_index);
} else {
- d->xy = INVALID_TILE;
+ delete d;
}
return true;
@@ -823,7 +828,7 @@ static bool LoadOldStation(LoadgameState *ls, int num)
st->string_id = RemapOldStringID(_old_string_id);
}
} else {
- st->xy = INVALID_TILE;
+ delete st;
}
return true;
@@ -895,7 +900,7 @@ static bool LoadOldIndustry(LoadgameState *ls, int num)
IncIndustryTypeCount(i->type);
} else {
- i->xy = INVALID_TILE;
+ delete i;
}
return true;
@@ -1142,19 +1147,22 @@ static const OldChunks vehicle_empty_chunk[] = {
static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
{
- Vehicle *v = Vehicle::Get(_current_vehicle_id);
+ Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
uint temp = ls->total_read;
bool res;
- switch (v->type) {
- default: NOT_REACHED();
- case VEH_INVALID : res = LoadChunk(ls, NULL, vehicle_empty_chunk); break;
- case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
- case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
- case VEH_SHIP : res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
- case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
- case VEH_EFFECT : res = LoadChunk(ls, &v->u.effect, vehicle_effect_chunk); break;
- case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
+ if (v == NULL) {
+ res = LoadChunk(ls, NULL, vehicle_empty_chunk);
+ } else {
+ switch (v->type) {
+ default: NOT_REACHED();
+ case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
+ case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
+ case VEH_SHIP : res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
+ case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
+ case VEH_EFFECT : res = LoadChunk(ls, &v->u.effect, vehicle_effect_chunk); break;
+ case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
+ }
}
/* This chunk size should always be 10 bytes */
@@ -1271,7 +1279,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
uint type = ReadByte(ls);
switch (type) {
default: return false;
- case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break;
+ case 0x00 /* VEH_INVALID */: v = NULL; break;
case 0x25 /* MONORAIL */:
case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
@@ -1282,6 +1290,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
}
if (!LoadChunk(ls, v, vehicle_chunk)) return false;
+ if (v == NULL) continue;
SpriteID sprite = v->cur_image;
/* no need to override other sprites */
@@ -1347,7 +1356,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
/* Read the vehicle type and allocate the right vehicle */
switch (ReadByte(ls)) {
default: NOT_REACHED();
- case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break;
+ case 0x00 /* VEH_INVALID */: v = NULL; break;
case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break;
@@ -1355,7 +1364,9 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
case 0x14 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break;
case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
}
+
if (!LoadChunk(ls, v, vehicle_chunk)) return false;
+ if (v == NULL) continue;
_old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
@@ -1373,7 +1384,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
}
v->current_order.AssignOrder(UnpackOldOrder(_old_order));
- if (_old_next_ptr != 0xFFFF) v->next = Vehicle::GetPoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : Vehicle::Get(_old_next_ptr);
+ if (_old_next_ptr != 0xFFFF) v->next = (Vehicle *)_old_next_ptr;
if (_cargo_count != 0) {
CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count);
diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp
index 6325b3cca..d9283a2be 100644
--- a/src/saveload/order_sl.cpp
+++ b/src/saveload/order_sl.cpp
@@ -81,7 +81,7 @@ Order UnpackOldOrder(uint16 packed)
* Sanity check
* TTD stores invalid orders as OT_NOTHING with non-zero flags/station
*/
- if (!order.IsValid() && packed != 0) order.MakeDummy();
+ if (order.IsType(OT_NOTHING) && packed != 0) order.MakeDummy();
return order;
}
@@ -123,7 +123,6 @@ static void Load_ORDR()
/* Version older than 5.2 did not have a ->next pointer. Convert them
* (in the old days, the orderlist was 5000 items big) */
size_t len = SlGetFieldLength();
- uint i;
if (CheckSavegameVersion(5)) {
/* Pre-version 5 had an other layout for orders
@@ -133,9 +132,9 @@ static void Load_ORDR()
SlArray(orders, len, SLE_UINT16);
- for (i = 0; i < len; ++i) {
- Order *order = new (i) Order();
- order->AssignOrder(UnpackVersion4Order(orders[i]));
+ for (size_t i = 0; i < len; ++i) {
+ Order *o = new (i) Order();
+ o->AssignOrder(UnpackVersion4Order(orders[i]));
}
free(orders);
@@ -145,7 +144,7 @@ static void Load_ORDR()
SlArray(orders, len, SLE_UINT32);
- for (i = 0; i < len; ++i) {
+ for (size_t i = 0; i < len; ++i) {
new (i) Order(orders[i]);
}
@@ -153,12 +152,17 @@ static void Load_ORDR()
}
/* Update all the next pointer */
- for (i = 1; i < len; ++i) {
+ Order *o;
+ FOR_ALL_ORDERS(o) {
+ /* Delete invalid orders */
+ if (o->IsType(OT_NOTHING)) {
+ delete o;
+ continue;
+ }
/* The orders were built like this:
- * While the order is valid, set the previous will get it's next pointer set
- * We start with index 1 because no order will have the first in it's next pointer */
- if (Order::Get(i)->IsValid())
- Order::Get(i - 1)->next = Order::Get(i);
+ * While the order is valid, set the previous will get its next pointer set */
+ Order *prev = Order::GetIfValid(order_index - 1);
+ if (prev != NULL) prev->next = o;
}
} else {
int index;
@@ -172,6 +176,7 @@ static void Load_ORDR()
static void Ptrs_ORDR()
{
+ /* Orders from old savegames have pointers corrected in Load_ORDR */
if (CheckSavegameVersionOldStyle(5, 2)) return;
Order *o;
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index 9389bdab2..9735970d9 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -739,8 +739,8 @@ void SlArray(void *array, size_t length, VarType conv)
}
-static uint ReferenceToInt(const void *obj, SLRefType rt);
-static void *IntToReference(uint index, SLRefType rt);
+static size_t ReferenceToInt(const void *obj, SLRefType rt);
+static void *IntToReference(size_t index, SLRefType rt);
/**
@@ -782,15 +782,15 @@ void SlList(void *list, SLRefType conv)
PtrList::iterator iter;
for (iter = l->begin(); iter != l->end(); ++iter) {
void *ptr = *iter;
- SlWriteUint32(ReferenceToInt(ptr, conv));
+ SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
}
break;
}
case SLA_LOAD: {
- uint length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
+ size_t length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
/* Load each reference and push to the end of the list */
- for (uint i = 0; i < length; i++) {
+ for (size_t i = 0; i < length; i++) {
size_t data = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
l->push_back((void *)data);
}
@@ -899,10 +899,10 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
case SL_REF: // Reference variable, translate
switch (_sl.action) {
case SLA_SAVE:
- SlWriteUint32(ReferenceToInt(*(void **)ptr, (SLRefType)conv));
+ SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
break;
case SLA_LOAD:
- *(size_t *)ptr = (size_t)(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32());
+ *(size_t *)ptr = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
break;
case SLA_PTRS:
*(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
@@ -1470,7 +1470,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
* @param rt SLRefType type of the object the index is being sought of
* @return Return the pointer converted to an index of the type pointed to
*/
-static uint ReferenceToInt(const void *obj, SLRefType rt)
+static size_t ReferenceToInt(const void *obj, SLRefType rt)
{
assert(_sl.action == SLA_SAVE);
@@ -1505,7 +1505,7 @@ static uint ReferenceToInt(const void *obj, SLRefType rt)
assert_compile(sizeof(size_t) <= sizeof(void *));
-static void *IntToReference(uint index, SLRefType rt)
+static void *IntToReference(size_t index, SLRefType rt)
{
assert(_sl.action == SLA_PTRS);
diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp
index 6813c2c06..c39a036c9 100644
--- a/src/saveload/strings_sl.cpp
+++ b/src/saveload/strings_sl.cpp
@@ -4,6 +4,7 @@
#include "../stdafx.h"
#include "../core/alloc_func.hpp"
+#include "../core/math_func.hpp"
#include "../string_func.h"
#include "saveload_internal.h"
diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp
index 584727918..2528be2a6 100644
--- a/src/saveload/town_sl.cpp
+++ b/src/saveload/town_sl.cpp
@@ -10,8 +10,6 @@
#include "saveload.h"
-extern uint _total_towns;
-
/**
* Check and update town and house values.
*
@@ -181,13 +179,9 @@ static void Load_TOWN()
{
int index;
- _total_towns = 0;
-
while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town();
SlObject(t, _town_desc);
-
- _total_towns++;
}
}
diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp
index ae904dbd5..a44bb6960 100644
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -208,7 +208,7 @@ void UpdateOldAircraft()
*/
static void CheckValidVehicles()
{
- uint total_engines = Engine::GetPoolSize();
+ size_t total_engines = Engine::GetPoolSize();
EngineID first_engine[4] = { INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE };
Engine *e;
@@ -282,7 +282,7 @@ void AfterLoadVehicles(bool part_of_load)
}
} else { // OrderList was saved as such, only recalculate not saved values
if (v->PreviousShared() == NULL) {
- new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
+ v->orders.list->Initialize(v->orders.list->first, v);
}
}
}
diff --git a/src/signs.cpp b/src/signs.cpp
index d1a3e7452..3da538a71 100644
--- a/src/signs.cpp
+++ b/src/signs.cpp
@@ -10,12 +10,13 @@
#include "viewport_func.h"
#include "zoom_func.h"
#include "functions.h"
-#include "oldpool_func.h"
+#include "core/pool_func.hpp"
#include "table/strings.h"
/* Initialize the sign-pool */
-DEFINE_OLD_POOL_GENERIC(Sign, Sign)
+SignPool _sign_pool("Sign");
+INSTANTIATE_POOL_METHODS(Sign)
Sign::Sign(Owner owner)
{
@@ -29,7 +30,6 @@ Sign::~Sign()
if (CleaningPool()) return;
DeleteRenameSignWindow(this->index);
- this->owner = INVALID_OWNER;
}
/**
@@ -80,6 +80,5 @@ void MarkSignDirty(Sign *si)
*/
void InitializeSigns()
{
- _Sign_pool.CleanPool();
- _Sign_pool.AddBlockToPool();
+ _sign_pool.CleanPool();
}
diff --git a/src/signs_base.h b/src/signs_base.h
index e037fdc44..e4fa3f9c4 100644
--- a/src/signs_base.h
+++ b/src/signs_base.h
@@ -8,11 +8,12 @@
#include "signs_type.h"
#include "viewport_type.h"
#include "tile_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
-DECLARE_OLD_POOL(Sign, Sign, 2, 16000)
+typedef Pool<Sign, SignID, 16, 64000> SignPool;
+extern SignPool _sign_pool;
-struct Sign : PoolItem<Sign, SignID, &_Sign_pool> {
+struct Sign : SignPool::PoolItem<&_sign_pool> {
char *name;
ViewportSign sign;
int32 x;
@@ -27,8 +28,6 @@ struct Sign : PoolItem<Sign, SignID, &_Sign_pool> {
/** Destroy the sign */
~Sign();
-
- inline bool IsValid() const { return this->owner != INVALID_OWNER; }
};
#define FOR_ALL_SIGNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Sign, sign_index, var, start)
diff --git a/src/station.cpp b/src/station.cpp
index aff65dda6..03d7a9db8 100644
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -20,9 +20,15 @@
#include "aircraft.h"
#include "vehicle_gui.h"
#include "settings_type.h"
+#include "core/pool_func.hpp"
#include "table/strings.h"
+StationPool _station_pool("Station");
+INSTANTIATE_POOL_METHODS(Station)
+RoadStopPool _roadstop_pool("RoadStop");
+INSTANTIATE_POOL_METHODS(RoadStop)
+
Station::Station(TileIndex tile)
{
DEBUG(station, cDebugCtorLevel, "I+%3d", index);
@@ -88,8 +94,6 @@ Station::~Station()
/* Remove all news items */
DeleteStationNews(this->index);
- xy = INVALID_TILE;
-
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
for (CargoID c = 0; c < NUM_CARGO; c++) {
@@ -460,8 +464,6 @@ RoadStop::~RoadStop()
assert(num_vehicles == 0);
DEBUG(ms, cDebugCtorLevel , "I- at %d[0x%x]", xy, xy);
-
- xy = INVALID_TILE;
}
/** Checks whether there is a free bay in this road stop */
@@ -546,3 +548,9 @@ RoadStop *RoadStop::GetNextRoadStop(const Vehicle *v) const
return NULL;
}
+
+void InitializeStations()
+{
+ _station_pool.CleanPool();
+ _roadstop_pool.CleanPool();
+}
diff --git a/src/station_base.h b/src/station_base.h
index 218f1aa9e..1b580db2b 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -7,7 +7,7 @@
#include "station_type.h"
#include "airport.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "cargopacket.h"
#include "cargo_type.h"
#include "town_type.h"
@@ -20,8 +20,10 @@
#include "viewport_type.h"
#include <list>
-DECLARE_OLD_POOL(Station, Station, 6, 1000)
-DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000)
+typedef Pool<Station, StationID, 32, 64000> StationPool;
+typedef Pool<RoadStop, RoadStopID, 32, 64000> RoadStopPool;
+extern StationPool _station_pool;
+extern RoadStopPool _roadstop_pool;
static const byte INITIAL_STATION_RATING = 175;
@@ -48,7 +50,7 @@ struct GoodsEntry {
};
/** A Stop for a Road Vehicle */
-struct RoadStop : PoolItem<RoadStop, RoadStopID, &_RoadStop_pool> {
+struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> {
static const int cDebugCtorLevel = 5; ///< Debug level on which Contructor / Destructor messages are printed
static const uint LIMIT = 16; ///< The maximum amount of roadstops that are allowed at a single station
static const uint MAX_BAY_COUNT = 2; ///< The maximum number of loading bays
@@ -60,13 +62,7 @@ struct RoadStop : PoolItem<RoadStop, RoadStopID, &_RoadStop_pool> {
struct RoadStop *next; ///< Next stop of the given type at this station
RoadStop(TileIndex tile = INVALID_TILE);
- virtual ~RoadStop();
-
- /**
- * Determines whether a road stop exists
- * @return true if and only is the road stop exists
- */
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
+ ~RoadStop();
/* For accessing status */
bool HasFreeBay() const;
@@ -110,7 +106,7 @@ struct StationRect : public Rect {
};
/** Station data structure */
-struct Station : PoolItem<Station, StationID, &_Station_pool> {
+struct Station : StationPool::PoolItem<&_station_pool> {
public:
RoadStop *GetPrimaryRoadStop(RoadStopType type) const
{
@@ -173,7 +169,7 @@ public:
static const int cDebugCtorLevel = 5;
Station(TileIndex tile = INVALID_TILE);
- virtual ~Station();
+ ~Station();
void AddFacility(byte new_facility_bit, TileIndex facil_xy);
@@ -195,12 +191,6 @@ public:
uint GetPlatformLength(TileIndex tile) const;
bool IsBuoy() const;
- /**
- * Determines whether a station exists
- * @return true if and only is the station exists
- */
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
-
uint GetCatchmentRadius() const;
};
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 4334dfe8c..fe2422c32 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -29,16 +29,11 @@
#include "date_func.h"
#include "vehicle_func.h"
#include "string_func.h"
-#include "oldpool_func.h"
#include "animated_tile_func.h"
#include "elrail_func.h"
#include "table/strings.h"
-DEFINE_OLD_POOL_GENERIC(Station, Station)
-DEFINE_OLD_POOL_GENERIC(RoadStop, RoadStop)
-
-
/**
* Check whether the given tile is a hangar.
* @param t the tile to of whether it is a hangar.
@@ -3200,17 +3195,6 @@ static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
return CMD_ERROR;
}
-void InitializeStations()
-{
- /* Clean the station pool and create 1 block in it */
- _Station_pool.CleanPool();
- _Station_pool.AddBlockToPool();
-
- /* Clean the roadstop pool and create 1 block in it */
- _RoadStop_pool.CleanPool();
- _RoadStop_pool.AddBlockToPool();
-}
-
static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
{
if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
diff --git a/src/station_func.h b/src/station_func.h
index 7e548835a..a8396a7ee 100644
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -7,7 +7,6 @@
#include "station_type.h"
#include "sprite.h"
-#include "oldpool.h"
#include "rail_type.h"
#include "road_type.h"
#include "tile_type.h"
diff --git a/src/strings.cpp b/src/strings.cpp
index 2e04113b5..8b2c4e3a3 100644
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -669,7 +669,7 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
int64 args[2];
/* industry not valid anymore? */
- if (!i->IsValid()) break;
+ assert(i != NULL);
/* First print the town name and the industry type name. */
args[0] = i->town->index;
@@ -829,7 +829,7 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
case SCC_WAYPOINT_NAME: { // {WAYPOINT}
Waypoint *wp = Waypoint::Get(GetInt32(&argv));
- assert(wp->IsValid());
+ assert(wp != NULL);
if (wp->name != NULL) {
buff = strecpy(buff, wp->name, last);
@@ -885,7 +885,7 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
const Town *t = Town::Get(GetInt32(&argv));
int64 temp[1];
- assert(t->IsValid());
+ assert(t != NULL);
temp[0] = t->townnameparts;
uint32 grfid = t->townnamegrfid;
@@ -911,7 +911,7 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
case SCC_GROUP_NAME: { // {GROUP}
const Group *g = Group::Get(GetInt32(&argv));
- assert(g->IsValid());
+ assert(g != NULL);
if (g->name != NULL) {
buff = strecpy(buff, g->name, last);
@@ -928,6 +928,8 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
EngineID engine = (EngineID)GetInt32(&argv);
const Engine *e = Engine::Get(engine);
+ assert(e != NULL);
+
if (e->name != NULL) {
buff = strecpy(buff, e->name, last);
} else {
@@ -939,6 +941,8 @@ static char *FormatString(char *buff, const char *str, const int64 *argv, uint c
case SCC_VEHICLE_NAME: { // {VEHICLE}
const Vehicle *v = Vehicle::Get(GetInt32(&argv));
+ assert(v != NULL);
+
if (v->name != NULL) {
buff = strecpy(buff, v->name, last);
} else {
diff --git a/src/town.h b/src/town.h
index ead399d0c..076037881 100644
--- a/src/town.h
+++ b/src/town.h
@@ -5,7 +5,7 @@
#ifndef TOWN_H
#define TOWN_H
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "core/bitmath_func.hpp"
#include "core/random_func.hpp"
#include "cargo_type.h"
@@ -100,9 +100,10 @@ struct BuildingCounts {
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum number of towns a user can specify in customisation
-DECLARE_OLD_POOL(Town, Town, 3, 8000)
+typedef Pool<Town, TownID, 64, 64000> TownPool;
+extern TownPool _town_pool;
-struct Town : PoolItem<Town, TownID, &_Town_pool> {
+struct Town : TownPool::PoolItem<&_town_pool> {
TileIndex xy;
/* Current population of people and amount of houses. */
@@ -183,13 +184,11 @@ struct Town : PoolItem<Town, TownID, &_Town_pool> {
/**
* Creates a new town
*/
- Town(TileIndex tile = INVALID_TILE);
+ Town(TileIndex tile = INVALID_TILE) : xy(tile) { }
/** Destroy the town */
~Town();
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
-
void InitializeLayout(TownLayout layout);
/** Calculate the max town noise
@@ -297,9 +296,7 @@ TileIndexDiff GetHouseNorthPart(HouseID &house);
static inline uint GetNumTowns()
{
- extern uint _total_towns;
-
- return _total_towns;
+ return (uint)Town::GetNumItems();
}
/**
@@ -324,7 +321,7 @@ static inline Town *GetRandomTown()
return Town::Get(index);
}
-Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
+Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX, const Town *ignore = NULL);
#define FOR_ALL_TOWNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Town, town_index, var, start)
#define FOR_ALL_TOWNS(var) FOR_ALL_TOWNS_FROM(var, 0)
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 2f5efb70d..a93de7620 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -34,7 +34,6 @@
#include "window_func.h"
#include "string_func.h"
#include "newgrf_cargo.h"
-#include "oldpool_func.h"
#include "economy_func.h"
#include "station_func.h"
#include "cheat_type.h"
@@ -42,11 +41,11 @@
#include "animated_tile_func.h"
#include "date_func.h"
#include "core/smallmap_type.hpp"
+#include "core/pool_func.hpp"
#include "table/strings.h"
#include "table/town_land.h"
-uint _total_towns;
HouseSpec _house_specs[HOUSE_MAX];
Town *_cleared_town;
@@ -56,13 +55,8 @@ uint32 _cur_town_ctr; ///< iterator through all towns in OnTick_Town
uint32 _cur_town_iter; ///< frequency iterator at the same place
/* Initialize the town-pool */
-DEFINE_OLD_POOL_GENERIC(Town, Town)
-
-Town::Town(TileIndex tile)
-{
- if (tile != INVALID_TILE) _total_towns++;
- this->xy = tile;
-}
+TownPool _town_pool("Town");
+INSTANTIATE_POOL_METHODS(Town)
Town::~Town()
{
@@ -76,7 +70,6 @@ Town::~Town()
* and remove from list of sorted towns */
DeleteWindowById(WC_TOWN_VIEW, this->index);
InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0);
- _total_towns--;
/* Delete all industries belonging to the town */
FOR_ALL_INDUSTRIES(i) if (i->town == this) delete i;
@@ -110,9 +103,7 @@ Town::~Town()
MarkWholeScreenDirty();
- this->xy = INVALID_TILE;
-
- UpdateNearestTownForRoadTiles(false);
+ UpdateNearestTownForRoadTiles(false, this);
}
/**
@@ -2689,13 +2680,14 @@ bool CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags)
}
-Town *CalcClosestTownFromTile(TileIndex tile, uint threshold)
+Town *CalcClosestTownFromTile(TileIndex tile, uint threshold, const Town *ignore)
{
Town *t;
uint best = threshold;
Town *best_town = NULL;
FOR_ALL_TOWNS(t) {
+ if (t == ignore) continue;
uint dist = DistanceManhattan(tile, t->xy);
if (dist < best) {
best = dist;
@@ -2713,6 +2705,7 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold)
case MP_ROAD:
if (!HasTownOwnedRoad(tile)) {
TownID tid = GetTownIndex(tile);
+
if (tid == (TownID)INVALID_TOWN) {
/* in the case we are generating "many random towns", this value may be INVALID_TOWN */
if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
@@ -2720,8 +2713,8 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold)
return NULL;
}
+ assert(Town::IsValidID(tid));
Town *town = Town::Get(tid);
- assert(town->IsValid());
if (DistanceManhattan(tile, town->xy) >= threshold) town = NULL;
@@ -2861,16 +2854,12 @@ void TownsYearlyLoop()
void InitializeTowns()
{
- /* Clean the town pool and create 1 block in it */
- _Town_pool.CleanPool();
- _Town_pool.AddBlockToPool();
+ _town_pool.CleanPool();
memset(_subsidies, 0, sizeof(_subsidies));
for (Subsidy *s = _subsidies; s != endof(_subsidies); s++) {
s->cargo_type = CT_INVALID;
}
-
- _total_towns = 0;
}
static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index e60df0daf..a2e731c65 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -4282,7 +4282,7 @@ static bool TrainLocoHandler(Vehicle *v, bool mode)
/* exit if train is stopped */
if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return true;
- bool valid_order = v->current_order.IsValid() && v->current_order.GetType() != OT_CONDITIONAL;
+ bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL;
if (ProcessOrders(v) && CheckReverseTrain(v)) {
v->load_unload_time_rem = 0;
v->cur_speed = 0;
@@ -4300,7 +4300,7 @@ static bool TrainLocoHandler(Vehicle *v, bool mode)
if (!mode) HandleLocomotiveSmokeCloud(v);
/* We had no order but have an order now, do look ahead. */
- if (!valid_order && v->current_order.IsValid()) {
+ if (!valid_order && !v->current_order.IsType(OT_NOTHING)) {
CheckNextTrainTile(v);
}
@@ -4428,10 +4428,12 @@ bool Train::Tick()
this->current_order_time++;
+ VehicleID index = this->index;
+
if (!TrainLocoHandler(this, false)) return false;
/* make sure vehicle wasn't deleted. */
- assert(this->IsValid());
+ assert(Vehicle::Get(index) == this);
assert(IsFrontEngine(this));
return TrainLocoHandler(this, true);
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 2127d6aec..961e9ee4b 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -31,12 +31,12 @@
#include "vehicle_func.h"
#include "autoreplace_func.h"
#include "autoreplace_gui.h"
-#include "oldpool_func.h"
#include "ai/ai.hpp"
#include "core/smallmap_type.hpp"
#include "depot_func.h"
#include "settings_type.h"
#include "network/network.h"
+#include "core/pool_func.hpp"
#include "table/sprites.h"
#include "table/strings.h"
@@ -50,7 +50,8 @@ uint16 _returned_refit_capacity;
/* Initialize the vehicle-pool */
-DEFINE_OLD_POOL_GENERIC(Vehicle, Vehicle)
+VehiclePool _vehicle_pool("Vehicle");
+INSTANTIATE_POOL_METHODS(Vehicle)
/** Function to tell if a vehicle needs to be autorenewed
* @param *c The vehicle owner
@@ -462,8 +463,7 @@ static AutoreplaceMap _vehicles_to_autoreplace;
void InitializeVehicles()
{
- _Vehicle_pool.CleanPool();
- _Vehicle_pool.AddBlockToPool();
+ _vehicle_pool.CleanPool();
_vehicles_to_autoreplace.Reset();
ResetVehiclePosHash();
@@ -571,12 +571,7 @@ Vehicle::~Vehicle()
delete v;
UpdateVehiclePosHash(this, INVALID_COORD, 0);
- this->next_hash = NULL;
- this->next_new_hash = NULL;
-
DeleteVehicleNews(this->index, INVALID_STRING_ID);
-
- this->type = VEH_INVALID;
}
/** Adds a vehicle to the list of vehicles, that visited a depot this tick
@@ -605,9 +600,12 @@ void CallVehicleTicks()
Vehicle *v;
FOR_ALL_VEHICLES(v) {
/* Vehicle could be deleted in this tick */
- if (!v->Tick()) continue;
+ if (!v->Tick()) {
+ assert(Vehicle::Get(vehicle_index) == NULL);
+ continue;
+ }
- assert(v->IsValid());
+ assert(Vehicle::Get(vehicle_index) == v);
switch (v->type) {
default: break;
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index 087833cb6..955c4f3fe 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -16,7 +16,7 @@
#include "date_type.h"
#include "company_base.h"
#include "company_type.h"
-#include "oldpool.h"
+#include "core/pool.hpp"
#include "order_base.h"
#include "cargopacket.h"
#include "texteff.hpp"
@@ -189,15 +189,18 @@ struct VehicleShip {
TrackBitsByte state;
};
-DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
+typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
+extern VehiclePool _vehicle_pool;
/* Some declarations of functions, so we can make them friendly */
struct SaveLoad;
extern const SaveLoad *GetVehicleDescription(VehicleType vt);
struct LoadgameState;
extern bool LoadOldVehicle(LoadgameState *ls, int num);
+extern bool AfterLoadGame();
+extern void FixOldVehicles();
-struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
+struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle {
private:
Vehicle *next; ///< pointer to the next vehicle in the chain
Vehicle *previous; ///< NOSAVE: pointer to the previous vehicle in the chain
@@ -207,6 +210,8 @@ private:
Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
public:
friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
+ friend bool AfterLoadGame();
+ friend void FixOldVehicles();
friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the previous and first pointers while loading
friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading
@@ -624,24 +629,6 @@ struct DisasterVehicle : public Vehicle {
bool Tick();
};
-/**
- * This class 'wraps' Vehicle; you do not actually instantiate this class.
- * You create a Vehicle using AllocateVehicle, so it is added to the pool
- * and you reinitialize that to a Train using:
- * v = new (v) Train();
- *
- * As side-effect the vehicle type is set correctly.
- */
-struct InvalidVehicle : public Vehicle {
- /** Initializes the Vehicle to a invalid vehicle */
- InvalidVehicle() { this->type = VEH_INVALID; }
-
- /** We want to 'destruct' the right class. */
- virtual ~InvalidVehicle() {}
-
- const char *GetTypeString() const { return "invalid vehicle"; }
-};
-
#define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start)
#define FOR_ALL_VEHICLES(var) FOR_ALL_VEHICLES_FROM(var, 0)
diff --git a/src/vehicle_type.h b/src/vehicle_type.h
index 76d552b3e..d1152ace3 100644
--- a/src/vehicle_type.h
+++ b/src/vehicle_type.h
@@ -28,12 +28,6 @@ struct Vehicle;
struct BaseVehicle
{
VehicleTypeByte type; ///< Type of vehicle
-
- /**
- * Is this vehicle a valid vehicle?
- * @return true if and only if the vehicle is valid.
- */
- inline bool IsValid() const { return this->type != VEH_INVALID; }
};
static const VehicleID INVALID_VEHICLE = 0xFFFF;
diff --git a/src/water_map.h b/src/water_map.h
index be6c22b90..3d2f77d99 100644
--- a/src/water_map.h
+++ b/src/water_map.h
@@ -5,6 +5,8 @@
#ifndef WATER_MAP_H
#define WATER_MAP_H
+#include "core/math_func.hpp"
+
enum WaterTileType {
WATER_TILE_CLEAR,
WATER_TILE_COAST,
diff --git a/src/waypoint.cpp b/src/waypoint.cpp
index f35628492..96a9e5025 100644
--- a/src/waypoint.cpp
+++ b/src/waypoint.cpp
@@ -11,10 +11,11 @@
#include "waypoint.h"
#include "window_func.h"
#include "newgrf_station.h"
-#include "oldpool_func.h"
#include "order_func.h"
+#include "core/pool_func.hpp"
-DEFINE_OLD_POOL_GENERIC(Waypoint, Waypoint)
+WaypointPool _waypoint_pool("Waypoint");
+INSTANTIATE_POOL_METHODS(Waypoint)
/**
* Update all signs
@@ -79,11 +80,6 @@ void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype)
}
}
-Waypoint::Waypoint(TileIndex tile)
-{
- this->xy = tile;
-}
-
Waypoint::~Waypoint()
{
free(this->name);
@@ -93,11 +89,9 @@ Waypoint::~Waypoint()
RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index);
RedrawWaypointSign(this);
- this->xy = INVALID_TILE;
}
void InitializeWaypoints()
{
- _Waypoint_pool.CleanPool();
- _Waypoint_pool.AddBlockToPool();
+ _waypoint_pool.CleanPool();
}
diff --git a/src/waypoint.h b/src/waypoint.h
index 7e6f9f12a..eb388e86d 100644
--- a/src/waypoint.h
+++ b/src/waypoint.h
@@ -6,17 +6,18 @@
#define WAYPOINT_H
#include "waypoint_type.h"
-#include "oldpool.h"
#include "rail_map.h"
#include "command_type.h"
#include "station_type.h"
#include "town_type.h"
#include "viewport_type.h"
#include "date_type.h"
+#include "core/pool.hpp"
-DECLARE_OLD_POOL(Waypoint, Waypoint, 3, 8000)
+typedef Pool<Waypoint, WaypointID, 32, 64000> WaypointPool;
+extern WaypointPool _waypoint_pool;
-struct Waypoint : PoolItem<Waypoint, WaypointID, &_Waypoint_pool> {
+struct Waypoint : WaypointPool::PoolItem<&_waypoint_pool> {
TileIndex xy; ///< Tile of waypoint
TownID town_index; ///< Town associated with the waypoint
@@ -34,10 +35,8 @@ struct Waypoint : PoolItem<Waypoint, WaypointID, &_Waypoint_pool> {
byte deleted; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
- Waypoint(TileIndex tile = INVALID_TILE);
+ Waypoint(TileIndex tile = INVALID_TILE) : xy(tile) { }
~Waypoint();
-
- inline bool IsValid() const { return this->xy != INVALID_TILE; }
};
#define FOR_ALL_WAYPOINTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Waypoint, waypoint_index, var, start)
diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp
index 468d216cb..ae3980edf 100644
--- a/src/waypoint_cmd.cpp
+++ b/src/waypoint_cmd.cpp
@@ -74,7 +74,7 @@ static void MakeDefaultWaypointName(Waypoint *wp)
Waypoint *lwp = Waypoint::Get(cid);
/* check only valid waypoints... */
- if (lwp->IsValid() && wp != lwp) {
+ if (lwp != NULL && wp != lwp) {
/* only waypoints with 'generic' name within the same city */
if (lwp->name == NULL && lwp->town_index == wp->town_index) {
/* if lwp->town_cn < next, uint will overflow to '+inf' */
diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp
index 10f067677..9d0ac7189 100644
--- a/src/waypoint_gui.cpp
+++ b/src/waypoint_gui.cpp
@@ -144,6 +144,5 @@ static const WindowDesc _waypoint_view_desc(
void ShowWaypointWindow(const Waypoint *wp)
{
- if (!wp->IsValid()) return; // little safety
AllocateWindowDescFront<WaypointWindow>(&_waypoint_view_desc, wp->index);
}