6 #include "openttd.h" |
6 #include "openttd.h" |
7 #include "station.h" |
7 #include "station.h" |
8 #include "cargopacket.h" |
8 #include "cargopacket.h" |
9 #include "saveload.h" |
9 #include "saveload.h" |
10 |
10 |
11 /** Cache for speeding up lookups in AllocateRaw */ |
|
12 static uint _first_free_cargo_packet_index; |
|
13 |
|
14 /** |
|
15 * Called if a new block is added to the station-pool |
|
16 */ |
|
17 static void CargoPacketPoolNewBlock(uint cpart_item) |
|
18 { |
|
19 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
20 * TODO - This is just a temporary stage, this will be removed. */ |
|
21 for (CargoPacket *cp = GetCargoPacket(cpart_item); cp != NULL; cp = (cp->index + 1U < GetCargoPacketPoolSize()) ? GetCargoPacket(cp->index + 1U) : NULL) cp->index = cpart_item++; |
|
22 } |
|
23 |
|
24 static void CargoPacketPoolCleanBlock(uint cpart_item, uint end_item) |
|
25 { |
|
26 for (uint i = cpart_item; i <= end_item; i++) { |
|
27 CargoPacket *cp = GetCargoPacket(i); |
|
28 if (cp->IsValid()) cp->~CargoPacket(); |
|
29 } |
|
30 } |
|
31 |
|
32 /* Initialize the cargopacket-pool */ |
11 /* Initialize the cargopacket-pool */ |
33 DEFINE_OLD_POOL(CargoPacket, CargoPacket, CargoPacketPoolNewBlock, CargoPacketPoolCleanBlock) |
12 DEFINE_OLD_POOL_GENERIC(CargoPacket, CargoPacket) |
34 |
13 |
35 void InitializeCargoPackets() |
14 void InitializeCargoPackets() |
36 { |
15 { |
37 _first_free_cargo_packet_index = 0; |
|
38 /* Clean the cargo packet pool and create 1 block in it */ |
16 /* Clean the cargo packet pool and create 1 block in it */ |
39 CleanPool(&_CargoPacket_pool); |
17 _CargoPacket_pool.CleanPool(); |
40 AddBlockToPool(&_CargoPacket_pool); |
18 _CargoPacket_pool.AddBlockToPool(); |
41 |
19 |
42 /* Check whether our &cargolist == &cargolist.packets "hack" works */ |
20 /* Check whether our &cargolist == &cargolist.packets "hack" works */ |
43 CargoList::AssertOnWrongPacketOffset(); |
21 CargoList::AssertOnWrongPacketOffset(); |
44 } |
22 } |
45 |
23 |
57 this->paid_for = false; |
35 this->paid_for = false; |
58 } |
36 } |
59 |
37 |
60 CargoPacket::~CargoPacket() |
38 CargoPacket::~CargoPacket() |
61 { |
39 { |
62 if (this->index < _first_free_cargo_packet_index) _first_free_cargo_packet_index = this->index; |
|
63 this->count = 0; |
40 this->count = 0; |
64 } |
41 } |
65 |
42 |
66 bool CargoPacket::SameSource(CargoPacket *cp) |
43 bool CargoPacket::SameSource(CargoPacket *cp) |
67 { |
44 { |
68 return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit && this->paid_for == cp->paid_for; |
45 return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit && this->paid_for == cp->paid_for; |
69 } |
|
70 |
|
71 void *CargoPacket::operator new(size_t size) |
|
72 { |
|
73 CargoPacket *cp = AllocateRaw(); |
|
74 return cp; |
|
75 } |
|
76 |
|
77 void *CargoPacket::operator new(size_t size, CargoPacket::ID cp_idx) |
|
78 { |
|
79 if (!AddBlockIfNeeded(&_CargoPacket_pool, cp_idx)) |
|
80 error("CargoPackets: failed loading savegame: too many cargo packets"); |
|
81 |
|
82 CargoPacket *cp = GetCargoPacket(cp_idx); |
|
83 return cp; |
|
84 } |
|
85 |
|
86 void CargoPacket::operator delete(void *p) |
|
87 { |
|
88 } |
|
89 |
|
90 void CargoPacket::operator delete(void *p, CargoPacket::ID cp_idx) |
|
91 { |
|
92 } |
|
93 |
|
94 /*static*/ CargoPacket *CargoPacket::AllocateRaw() |
|
95 { |
|
96 CargoPacket *cp = NULL; |
|
97 |
|
98 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
99 * TODO - This is just a temporary stage, this will be removed. */ |
|
100 for (cp = GetCargoPacket(_first_free_cargo_packet_index); cp != NULL; cp = (cp->index + 1U < GetCargoPacketPoolSize()) ? GetCargoPacket(cp->index + 1U) : NULL) { |
|
101 if (!cp->IsValid()) { |
|
102 CargoPacket::ID index = cp->index; |
|
103 |
|
104 memset(cp, 0, sizeof(CargoPacket)); |
|
105 cp->index = index; |
|
106 _first_free_cargo_packet_index = cp->index; |
|
107 return cp; |
|
108 } |
|
109 } |
|
110 |
|
111 /* Check if we can add a block to the pool */ |
|
112 if (AddBlockToPool(&_CargoPacket_pool)) return AllocateRaw(); |
|
113 |
|
114 error("CargoPackets: too many cargo packets"); |
|
115 } |
46 } |
116 |
47 |
117 static const SaveLoad _cargopacket_desc[] = { |
48 static const SaveLoad _cargopacket_desc[] = { |
118 SLE_VAR(CargoPacket, source, SLE_UINT16), |
49 SLE_VAR(CargoPacket, source, SLE_UINT16), |
119 SLE_VAR(CargoPacket, source_xy, SLE_UINT32), |
50 SLE_VAR(CargoPacket, source_xy, SLE_UINT32), |
139 static void Load_CAPA() |
70 static void Load_CAPA() |
140 { |
71 { |
141 int index; |
72 int index; |
142 |
73 |
143 while ((index = SlIterateArray()) != -1) { |
74 while ((index = SlIterateArray()) != -1) { |
144 if (!AddBlockIfNeeded(&_CargoPacket_pool, index)) { |
75 CargoPacket *cp = new (index) CargoPacket(); |
145 error("CargoPackets: failed loading savegame: too many cargo packets"); |
|
146 } |
|
147 |
|
148 CargoPacket *cp = GetCargoPacket(index); |
|
149 SlObject(cp, _cargopacket_desc); |
76 SlObject(cp, _cargopacket_desc); |
150 } |
77 } |
151 } |
78 } |
152 |
79 |
153 extern const ChunkHandler _cargopacket_chunk_handlers[] = { |
80 extern const ChunkHandler _cargopacket_chunk_handlers[] = { |