(svn r16378) -Codechange: replace OldPool with simpler Pool. Compilation time, binary size and run time (with asserts disabled) should be improved

pull/155/head
smatz 15 years ago
parent 7eb14aa49f
commit 50624d5c0f

@ -643,10 +643,6 @@
RelativePath=".\..\src\npf.cpp"
>
</File>
<File
RelativePath=".\..\src\oldpool.cpp"
>
</File>
<File
RelativePath=".\..\src\openttd.cpp"
>
@ -1251,14 +1247,6 @@
RelativePath=".\..\src\video\null_v.h"
>
</File>
<File
RelativePath=".\..\src\oldpool.h"
>
</File>
<File
RelativePath=".\..\src\oldpool_func.h"
>
</File>
<File
RelativePath=".\..\src\openttd.h"
>
@ -1687,6 +1675,14 @@
RelativePath=".\..\src\core\overflowsafe_type.hpp"
>
</File>
<File
RelativePath=".\..\src\core\pool.hpp"
>
</File>
<File
RelativePath=".\..\src\core\pool_func.hpp"
>
</File>
<File
RelativePath=".\..\src\core\random_func.cpp"
>

@ -640,10 +640,6 @@
RelativePath=".\..\src\npf.cpp"
>
</File>
<File
RelativePath=".\..\src\oldpool.cpp"
>
</File>
<File
RelativePath=".\..\src\openttd.cpp"
>
@ -1248,14 +1244,6 @@
RelativePath=".\..\src\video\null_v.h"
>
</File>
<File
RelativePath=".\..\src\oldpool.h"
>
</File>
<File
RelativePath=".\..\src\oldpool_func.h"
>
</File>
<File
RelativePath=".\..\src\openttd.h"
>
@ -1684,6 +1672,14 @@
RelativePath=".\..\src\core\overflowsafe_type.hpp"
>
</File>
<File
RelativePath=".\..\src\core\pool.hpp"
>
</File>
<File
RelativePath=".\..\src\core\pool_func.hpp"
>
</File>
<File
RelativePath=".\..\src\core\random_func.cpp"
>

@ -48,7 +48,6 @@ network/network_gamelist.cpp
network/network_server.cpp
network/network_udp.cpp
npf.cpp
oldpool.cpp
openttd.cpp
os_timer.cpp
#if WIN32
@ -243,8 +242,6 @@ npf.h
music/null_m.h
sound/null_s.h
video/null_v.h
oldpool.h
oldpool_func.h
openttd.h
order_base.h
order_func.h
@ -367,6 +364,8 @@ core/math_func.cpp
core/math_func.hpp
core/mem_func.hpp
core/overflowsafe_type.hpp
core/pool.hpp
core/pool_func.hpp
core/random_func.cpp
core/random_func.hpp
core/smallmap_type.hpp

@ -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));
}

@ -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;
}

@ -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();
}

@ -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)

@ -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) {

@ -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

@ -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);

@ -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;
}

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

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

@ -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);
}

@ -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();

@ -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();
}

@ -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);

@ -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();

@ -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;

@ -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();
};

@ -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()) {

@ -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;

@ -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));
}

@ -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;

@ -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);
}

@ -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)
{

@ -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; }

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

@ -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)

@ -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;
}

@ -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,

@ -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()

@ -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;

@ -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; }
};

@ -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;
}

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

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

@ -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) {

@ -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.
@ -50,12 +52,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.
@ -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.

@ -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;
}

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

@ -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);

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

@ -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;
}

@ -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;

@ -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);

@ -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;

@ -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);

@ -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"

@ -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++;
}
}

@ -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);
}
}
}

@ -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();
}

@ -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)

@ -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();
}

@ -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;
};

@ -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()) {

@ -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"

@ -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 {

@ -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)

@ -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)

@ -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);

@ -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;

@ -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)

@ -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;

@ -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,

@ -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();
}

@ -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)

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

@ -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);
}

Loading…
Cancel
Save