mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-05 22:04:57 +00:00
(svn r16378) -Codechange: replace OldPool with simpler Pool. Compilation time, binary size and run time (with asserts disabled) should be improved
This commit is contained in:
parent
04723b240e
commit
62a7948af0
@ -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;
|
||||
}
|
||||
|
||||
|
284
src/core/pool.hpp
Normal file
284
src/core/pool.hpp
Normal file
@ -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 */
|
139
src/core/pool_func.hpp
Normal file
139
src/core/pool_func.hpp
Normal file
@ -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;
|
||||
|
11
src/group.h
11
src/group.h
@ -6,14 +6,15 @@
|
||||
#define GROUP_H
|
||||
|
||||
#include "group_type.h"
|
||||
#include "oldpool.h"
|
||||
#include "core/pool.hpp"
|
||||
#include "company_type.h"
|
||||
#include "vehicle_type.h"
|
||||
#include "engine_type.h"
|
||||
|
||||
DECLARE_OLD_POOL(Group, Group, 5, 2047)
|
||||
typedef Pool<Group, GroupID, 16, 64000> GroupPool;
|
||||
extern GroupPool _group_pool;
|
||||
|
||||
struct Group : PoolItem<Group, GroupID, &_Group_pool> {
|
||||
struct Group : GroupPool::PoolItem<&_group_pool> {
|
||||
char *name; ///< Group Name
|
||||
|
||||
uint16 num_vehicle; ///< Number of vehicles wich belong to the group
|
||||
@ -24,9 +25,7 @@ struct Group : PoolItem<Group, GroupID, &_Group_pool> {
|
||||
uint16 *num_engines; ///< Caches the number of engines of each type the company owns (no need to save this)
|
||||
|
||||
Group(CompanyID owner = INVALID_COMPANY);
|
||||
virtual ~Group();
|
||||
|
||||
bool IsValid() const;
|
||||
~Group();
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
385
src/oldpool.h
385
src/oldpool.h
@ -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 {
|
||||
|
17
src/town.h
17
src/town.h
@ -5,7 +5,7 @@
|
||||
#ifndef TOWN_H
|
||||
#define TOWN_H
|
||||
|
||||
#include "oldpool.h"
|
||||
#include "core/pool.hpp"
|
||||
#include "core/bitmath_func.hpp"
|
||||
#include "core/random_func.hpp"
|
||||
#include "cargo_type.h"
|
||||
@ -100,9 +100,10 @@ struct BuildingCounts {
|
||||
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
|
||||
static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum number of towns a user can specify in customisation
|
||||
|
||||
DECLARE_OLD_POOL(Town, Town, 3, 8000)
|
||||
typedef Pool<Town, TownID, 64, 64000> TownPool;
|
||||
extern TownPool _town_pool;
|
||||
|
||||
struct Town : PoolItem<Town, TownID, &_Town_pool> {
|
||||
struct Town : TownPool::PoolItem<&_town_pool> {
|
||||
TileIndex xy;
|
||||
|
||||
/* Current population of people and amount of houses. */
|
||||
@ -183,13 +184,11 @@ struct Town : PoolItem<Town, TownID, &_Town_pool> {
|
||||
/**
|
||||
* Creates a new town
|
||||
*/
|
||||
Town(TileIndex tile = INVALID_TILE);
|
||||
Town(TileIndex tile = INVALID_TILE) : xy(tile) { }
|
||||
|
||||
/** Destroy the town */
|
||||
~Town();
|
||||
|
||||
inline bool IsValid() const { return this->xy != INVALID_TILE; }
|
||||
|
||||
void InitializeLayout(TownLayout layout);
|
||||
|
||||
/** Calculate the max town noise
|
||||
@ -297,9 +296,7 @@ TileIndexDiff GetHouseNorthPart(HouseID &house);
|
||||
|
||||
static inline uint GetNumTowns()
|
||||
{
|
||||
extern uint _total_towns;
|
||||
|
||||
return _total_towns;
|
||||
return (uint)Town::GetNumItems();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,7 +321,7 @@ static inline Town *GetRandomTown()
|
||||
return Town::Get(index);
|
||||
}
|
||||
|
||||
Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
|
||||
Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX, const Town *ignore = NULL);
|
||||
|
||||
#define FOR_ALL_TOWNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Town, town_index, var, start)
|
||||
#define FOR_ALL_TOWNS(var) FOR_ALL_TOWNS_FROM(var, 0)
|
||||
|
@ -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…
Reference in New Issue
Block a user