summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/oldpool.h175
-rw-r--r--src/station.cpp105
-rw-r--r--src/station.h46
-rw-r--r--src/station_cmd.cpp10
4 files changed, 181 insertions, 155 deletions
diff --git a/src/oldpool.h b/src/oldpool.h
index 80e121cb6..5e5b53c59 100644
--- a/src/oldpool.h
+++ b/src/oldpool.h
@@ -29,14 +29,14 @@ protected:
const char* name; ///< Name of the pool (just for debugging)
- uint max_blocks; ///< The max amount of blocks this pool can have
- uint block_size_bits; ///< The size of each block in bits
- uint item_size; ///< How many bytes one block is
+ 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
+ const uint item_size; ///< How many bytes one block is
/// Pointer to a function that is called after a new block is added
- OldMemoryPoolNewBlock *new_block_proc;
+ const OldMemoryPoolNewBlock *new_block_proc;
/// Pointer to a function that is called to clean a block
- OldMemoryPoolCleanBlock *clean_block_proc;
+ const 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
@@ -44,20 +44,45 @@ protected:
public:
byte **blocks; ///< An array of blocks (one block hold all the items)
- inline uint GetSize()
+ /**
+ * 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;
}
- inline bool CanAllocateMoreBlocks()
+ /**
+ * 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;
}
- inline uint GetBlockCount()
+ /**
+ * 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;
+ }
};
template <typename T>
@@ -66,7 +91,13 @@ struct OldMemoryPool : public OldMemoryPoolBase {
OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) :
OldMemoryPoolBase(name, max_blocks, block_size_bits, item_size, new_block_proc, clean_block_proc) {}
- inline T *Get(uint index)
+ /**
+ * 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] +
@@ -99,11 +130,9 @@ static inline bool AddBlockIfNeeded(OldMemoryPoolBase *array, uint index) { retu
template <typename T, OldMemoryPool<T> *Tpool>
static void PoolNewBlock(uint start_item)
{
- /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
- * TODO - This is just a temporary stage, this will be removed. */
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++;
- t->PreInit();
}
}
@@ -125,6 +154,128 @@ static void PoolCleanBlock(uint start_item, uint end_item)
}
+/**
+ * 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.
+ */
+ virtual ~PoolItem()
+ {
+ }
+
+ /**
+ * Called on each object when the pool is being destroyed, so one
+ * can free allocated memory without the need for freeing for
+ * example orders.
+ */
+ virtual void QuickFree()
+ {
+ }
+
+ /**
+ * An overriden version of new that allocates memory on the pool.
+ * @param size the size of the variable (unused)
+ * @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'
+ */
+ void operator delete(void *p)
+ {
+ }
+
+ /**
+ * 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
+ */
+ void operator delete(void *p, int 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.
+ */
+ void operator delete(void *p, T *pn)
+ {
+ }
+
+ /**
+ * Is this a valid object or not?
+ * @return true if and only if it is valid
+ */
+ virtual bool IsValid() const
+ {
+ return false;
+ }
+
+private:
+ /**
+ * Allocate a pool item; possibly allocate a new block in the pool.
+ * @return the allocated pool item (or NULL when the pool is full).
+ */
+ static T *AllocateRaw()
+ {
+ for (T *t = Tpool->Get(0); t != NULL; t = (t->index + 1U < Tpool->GetSize()) ? Tpool->Get(t->index + 1U) : NULL) {
+ if (!t->IsValid()) {
+ Tid index = t->index;
+
+ memset(t, 0, sizeof(T));
+ t->index = index;
+ return t;
+ }
+ }
+
+ /* Check if we can add a block to the pool */
+ if (Tpool->AddBlockToPool()) return AllocateRaw();
+
+ return NULL;
+ }
+};
+
#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
enum { \
diff --git a/src/station.cpp b/src/station.cpp
index 0f7db16ff..4633f1d18 100644
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -91,29 +91,6 @@ void Station::QuickFree()
free(this->speclist);
}
-void *Station::operator new(size_t size)
-{
- Station *st = AllocateRaw();
- return st;
-}
-
-void *Station::operator new(size_t size, int st_idx)
-{
- if (!AddBlockIfNeeded(&_Station_pool, st_idx))
- error("Stations: failed loading savegame: too many stations");
-
- Station *st = GetStation(st_idx);
- return st;
-}
-
-void Station::operator delete(void *p)
-{
-}
-
-void Station::operator delete(void *p, int st_idx)
-{
-}
-
/** Called when new facility is built on the station. If it is the first facility
* it initializes also 'xy' and 'random_bits' members */
void Station::AddFacility(byte new_facility_bit, TileIndex facil_xy)
@@ -176,30 +153,6 @@ bool Station::TileBelongsToRailStation(TileIndex tile) const
return IsTileType(tile, MP_STATION) && GetStationIndex(tile) == index && IsRailwayStation(tile);
}
-/*static*/ Station *Station::AllocateRaw()
-{
- Station *st = NULL;
-
- /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
- * TODO - This is just a temporary stage, this will be removed. */
- for (st = GetStation(0); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) {
- if (!st->IsValid()) {
- StationID index = st->index;
-
- memset(st, 0, sizeof(Station));
- st->index = index;
- return st;
- }
- }
-
- /* Check if we can add a block to the pool */
- if (AddBlockToPool(&_Station_pool)) return AllocateRaw();
-
- _error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
- return NULL;
-}
-
-
/** Obtain the length of a platform
* @pre tile must be a railway station tile
* @param tile A tile that contains the platform in question
@@ -426,36 +379,6 @@ StationRect& StationRect::operator = (Rect src)
/* RoadStop implementation */
/************************************************************************/
-/** Allocates a new RoadStop onto the pool, or recycles an unsed one
- * @return a pointer to the new roadstop
- */
-void *RoadStop::operator new(size_t size)
-{
- RoadStop *rs = AllocateRaw();
- return rs;
-}
-
-/** Gets a RoadStop with a given index and allocates it when needed
- * @return a pointer to the roadstop
- */
-void *RoadStop::operator new(size_t size, int index)
-{
- if (!AddBlockIfNeeded(&_RoadStop_pool, index)) {
- error("RoadStops: failed loading savegame: too many RoadStops");
- }
-
- RoadStop *rs = GetRoadStop(index);
- return rs;
-}
-
-void RoadStop::operator delete(void *p)
-{
-}
-
-void RoadStop::operator delete(void *p, int index)
-{
-}
-
/** Initializes a RoadStop */
RoadStop::RoadStop(TileIndex tile) :
xy(tile),
@@ -483,37 +406,13 @@ RoadStop::~RoadStop()
DEBUG(ms, cDebugCtorLevel , "I- at %d[0x%x]", xy, xy);
- xy = INVALID_TILE;
-}
-
-/** Low-level function for allocating a RoadStop on the pool */
-RoadStop *RoadStop::AllocateRaw()
-{
- RoadStop *rs;
-
- /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
- * TODO - This is just a temporary stage, this will be removed. */
- for (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
- if (!rs->IsValid()) {
- RoadStopID index = rs->index;
-
- memset(rs, 0, sizeof(*rs));
- rs->index = index;
-
- return rs;
- }
- }
-
- /* Check if we can add a block to the pool */
- if (AddBlockToPool(&_RoadStop_pool)) return AllocateRaw();
-
- return NULL;
+ xy = 0;
}
/** Determines whether a RoadStop is a valid (i.e. existing) one */
bool RoadStop::IsValid() const
{
- return xy != INVALID_TILE;
+ return xy != 0;
}
/** Checks whether there is a free bay in this road stop */
diff --git a/src/station.h b/src/station.h
index e35ce7d3a..b679499d7 100644
--- a/src/station.h
+++ b/src/station.h
@@ -15,6 +15,12 @@
#include "cargopacket.h"
#include <list>
+struct Station;
+struct RoadStop;
+
+DECLARE_OLD_POOL(Station, Station, 6, 1000)
+DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000)
+
static const byte INITIAL_STATION_RATING = 175;
struct GoodsEntry {
@@ -35,7 +41,7 @@ struct GoodsEntry {
};
/** A Stop for a Road Vehicle */
-struct RoadStop {
+struct RoadStop : PoolItem<RoadStop, RoadStopID, &_RoadStop_pool> {
/** Types of RoadStops */
enum Type {
BUS, ///< A standard stop for buses
@@ -47,23 +53,12 @@ struct RoadStop {
static const uint MAX_BAY_COUNT = 2; ///< The maximum number of loading bays
TileIndex xy; ///< Position on the map
- RoadStopID index; ///< Global (i.e. pool-wide) index
byte status; ///< Current status of the Stop. Like which spot is taken. Access using *Bay and *Busy functions.
byte num_vehicles; ///< Number of vehicles currently slotted to this stop
struct RoadStop *next; ///< Next stop of the given type at this station
- RoadStop(TileIndex tile);
- ~RoadStop();
-
- void PreInit() { this->xy = INVALID_TILE; }
- void QuickFree() {}
-
- void *operator new (size_t size);
- void operator delete(void *rs);
-
- /* For loading games */
- void *operator new (size_t size, int index);
- void operator delete(void *rs, int index);
+ RoadStop(TileIndex tile = 0);
+ virtual ~RoadStop();
bool IsValid() const;
@@ -75,8 +70,6 @@ struct RoadStop {
void FreeBay(uint nr);
bool IsEntranceBusy() const;
void SetEntranceBusy(bool busy);
-protected:
- static RoadStop *AllocateRaw();
};
struct StationSpecList {
@@ -108,7 +101,7 @@ struct StationRect : public Rect {
StationRect& operator = (Rect src);
};
-struct Station {
+struct Station : PoolItem<Station, StationID, &_Station_pool> {
public:
RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const
{
@@ -151,7 +144,6 @@ struct Station {
Date build_date;
uint64 airport_flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
- StationID index;
byte last_vehicle_type;
std::list<Vehicle *> loading_vehicles;
@@ -165,19 +157,10 @@ struct Station {
static const int cDebugCtorLevel = 3;
Station(TileIndex tile = 0);
- ~Station();
+ virtual ~Station();
- void PreInit() {}
void QuickFree();
- /* normal new/delete operators. Used when building/removing station */
- void *operator new (size_t size);
- void operator delete(void *p);
-
- /* new/delete operators accepting station index. Used when loading station from savegame. */
- void *operator new (size_t size, int st_idx);
- void operator delete(void *p, int st_idx);
-
void AddFacility(byte new_facility_bit, TileIndex facil_xy);
void MarkDirty() const;
void MarkTilesDirty(bool cargo_change) const;
@@ -186,9 +169,6 @@ struct Station {
uint GetPlatformLength(TileIndex tile) const;
bool IsBuoy() const;
bool IsValid() const;
-
-protected:
- static Station *AllocateRaw();
};
enum StationType {
@@ -238,8 +218,6 @@ void UpdateAllStationVirtCoord();
void RebuildStationLists();
void ResortStationLists();
-DECLARE_OLD_POOL(Station, Station, 6, 1000)
-
static inline StationID GetMaxStationIndex()
{
/* TODO - This isn't the real content of the function, but
@@ -266,8 +244,6 @@ static inline bool IsValidStationID(StationID index)
/* Stuff for ROADSTOPS */
-DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000)
-
#define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) if (rs->IsValid())
#define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0)
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index b5ca877f1..045da52a4 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -927,7 +927,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
} else {
/* allocate and initialize new station */
st = new Station(tile_org);
- if (st == NULL) return CMD_ERROR;
+ if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
st_auto_delete = st;
@@ -1358,7 +1358,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} else {
/* allocate and initialize new station */
st = new Station(tile);
- if (st == NULL) return CMD_ERROR;
+ if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
/* ensure that in case of error (or no DC_EXEC) the new station gets deleted upon return */
st_auto_delete = st;
@@ -1652,7 +1652,7 @@ CommandCost CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* allocate and initialize new station */
st = new Station(tile);
- if (st == NULL) return CMD_ERROR;
+ if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
st_auto_delete = st;
@@ -1774,7 +1774,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* allocate and initialize new station */
Station *st = new Station(tile);
- if (st == NULL) return CMD_ERROR;
+ if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
AutoPtrT<Station> st_auto_delete(st);
@@ -1939,7 +1939,7 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} else {
/* allocate and initialize new station */
st = new Station(tile);
- if (st == NULL) return CMD_ERROR;
+ if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
st_auto_delete = st;