(svn r1818) -Add: Dynamic orders (up to 64k orders)
authortruelight
Sun, 06 Feb 2005 10:24:57 +0000
changeset 1314 10c3417e9c22
parent 1313 f1013ec3d318
child 1315 183e30bdb5ec
(svn r1818) -Add: Dynamic orders (up to 64k orders)
oldloader.c
order.h
order_cmd.c
order_gui.c
saveload.c
station_cmd.c
ttd.c
--- a/oldloader.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/oldloader.c	Sun Feb 06 10:24:57 2005 +0000
@@ -803,6 +803,9 @@
 	int i;
 
 	for (i = 0; i < num; ++i) {
+		if (!AddBlockIfNeeded(&_order_pool, i))
+			error("Orders: failed loading savegame: too many orders");
+
 		order = GetOrder(i);
 		AssignOrder(order, UnpackOldOrder(*o));
 		/* Recover the next list */
--- a/order.h	Sun Feb 06 10:18:47 2005 +0000
+++ b/order.h	Sun Feb 06 10:24:57 2005 +0000
@@ -1,6 +1,8 @@
 #ifndef ORDER_H
 #define ORDER_H
 
+#include "pool.h"
+
 /* Order types */
 enum {
 	OT_NOTHING       = 0,
@@ -64,17 +66,27 @@
 VARDEF TileIndex _backup_orders_tile;
 VARDEF BackuppedOrders _backup_orders_data[1];
 
-VARDEF Order _orders[5000];
-VARDEF uint32 _orders_size;
+extern MemoryPool _order_pool;
 
+/**
+ * Get the pointer to the order with index 'index'
+ */
 static inline Order *GetOrder(uint index)
 {
-	assert(index < _orders_size);
-	return &_orders[index];
+	return (Order*)GetItemFromPool(&_order_pool, index);
 }
 
-#define FOR_ALL_ORDERS_FROM(o, from) for(o = GetOrder(from); o != &_orders[_orders_size]; o++)
-#define FOR_ALL_ORDERS(o) FOR_ALL_ORDERS_FROM(o, 0)
+/**
+ * Get the current size of the OrderPool
+ */
+static inline uint16 GetOrderPoolSize(void)
+{
+	return _order_pool.total_items;
+}
+
+#define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1 < GetOrderPoolSize()) ? GetOrder(order->index + 1) : NULL)
+#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
+
 
 #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
 
@@ -82,6 +94,10 @@
 {
 	const Order *order;
 
+	/* There is always room if not all blocks in the pool are reserved */
+	if (_order_pool.current_blocks < _order_pool.max_blocks)
+		return true;
+
 	FOR_ALL_ORDERS(order)
 		if (order->type == OT_NOTHING)
 			if (--amount == 0)
--- a/order_cmd.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/order_cmd.c	Sun Feb 06 10:24:57 2005 +0000
@@ -8,6 +8,26 @@
 #include "news.h"
 #include "saveload.h"
 
+enum {
+	/* Max orders: 64000 (64 * 1000) */
+	ORDER_POOL_BLOCK_SIZE_BITS = 6,       /* In bits, so (1 << 6) == 64 */
+	ORDER_POOL_MAX_BLOCKS      = 1000,
+};
+
+/**
+ * Called if a new block is added to the order-pool
+ */
+static void OrderPoolNewBlock(uint start_item)
+{
+	Order *order;
+
+	FOR_ALL_ORDERS_FROM(order, start_item)
+		order->index = start_item++;
+}
+
+/* Initialize the order-pool */
+MemoryPool _order_pool = { "Orders", ORDER_POOL_MAX_BLOCKS, ORDER_POOL_BLOCK_SIZE_BITS, sizeof(Order), &OrderPoolNewBlock, 0, 0, NULL };
+
 /**
  *
  * Unpacks a order from savegames made with TTD(Patch)
@@ -87,13 +107,19 @@
 	FOR_ALL_ORDERS(order) {
 		if (order->type == OT_NOTHING) {
 			uint index = order->index;
+
 			memset(order, 0, sizeof(Order));
 			order->index = index;
 			order->next = NULL;
+
 			return order;
 		}
 	}
 
+	/* Check if we can add a block to the pool */
+	if (AddBlockToPool(&_order_pool))
+		return AllocateOrder();
+
 	return NULL;
 }
 
@@ -906,14 +932,8 @@
 
 void InitializeOrders(void)
 {
-	Order *order;
-	int i;
-
-	memset(&_orders, 0, sizeof(_orders[0]) * _orders_size);
-
-	i = 0;
-	FOR_ALL_ORDERS(order)
-		order->index = i++;
+	CleanPool(&_order_pool);
+	AddBlockToPool(&_order_pool);
 
 	_backup_orders_tile = 0;
 }
@@ -955,22 +975,28 @@
 			uint16 orders[5000];
 
 			len /= sizeof(uint16);
-			assert (len <= _orders_size);
+			assert (len <= lengthof(orders));
 
 			SlArray(orders, len, SLE_UINT16);
 
 			for (i = 0; i < len; ++i) {
+				if (!AddBlockIfNeeded(&_order_pool, i))
+					error("Orders: failed loading savegame: too many orders");
+
 				AssignOrder(GetOrder(i), UnpackVersion4Order(orders[i]));
 			}
 		} else if (_sl.full_version <= 0x501) {
 			uint32 orders[5000];
 
 			len /= sizeof(uint32);
-			assert (len <= _orders_size);
+			assert (len <= lengthof(orders));
 
 			SlArray(orders, len, SLE_UINT32);
 
 			for (i = 0; i < len; ++i) {
+				if (!AddBlockIfNeeded(&_order_pool, i))
+					error("Orders: failed loading savegame: too many orders");
+
 				AssignOrder(GetOrder(i), UnpackOrder(orders[i]));
 			}
 		}
@@ -987,8 +1013,12 @@
 		int index;
 
 		while ((index = SlIterateArray()) != -1) {
-			Order *order = GetOrder(index);
+			Order *order;
 
+			if (!AddBlockIfNeeded(&_order_pool, index))
+				error("Orders: failed loading savegame: too many orders");
+
+			order = GetOrder(index);
 			SlObject(order, _order_desc);
 		}
 	}
--- a/order_gui.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/order_gui.c	Sun Feb 06 10:24:57 2005 +0000
@@ -167,15 +167,6 @@
 	return v;
 }
 
-static Vehicle *GetVehicleOnTile(TileIndex tile, byte owner)
-{
-	FindVehS fs;
-	fs.tile = tile;
-	fs.owner = owner;
-	fs.type = 0;
-	return VehicleFromPos(tile, &fs, (VehicleFromPosProc*)FindVehicleCallb);
-}
-
 static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
 {
 	Order order;
--- a/saveload.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/saveload.c	Sun Feb 06 10:24:57 2005 +0000
@@ -941,7 +941,11 @@
 		return NULL;
 
 	switch (t) {
-		case REF_ORDER:   return GetOrder(r - 1);
+		case REF_ORDER: {
+			if (!AddBlockIfNeeded(&_order_pool, r - 1))
+				error("Orders: failed loading savegame: too many orders");
+			return GetOrder(r - 1);
+		}
 		case REF_VEHICLE: {
 			if (!AddBlockIfNeeded(&_vehicle_pool, r - 1))
 				error("Vehicles: failed loading savegame: too many vehicles");
@@ -959,7 +963,7 @@
 		}
 		case REF_ROADSTOPS: {
 			if (!AddBlockIfNeeded(&_roadstop_pool, r - 1))
-				error("RoadStop: failed loading savegame: too many RoadStops");
+				error("RoadStops: failed loading savegame: too many RoadStops");
 			return GetRoadStop(r - 1);
 		}
 
--- a/station_cmd.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/station_cmd.c	Sun Feb 06 10:24:57 2005 +0000
@@ -3138,7 +3138,7 @@
 		RoadStop *rs;
 
 		if (!AddBlockIfNeeded(&_roadstop_pool, index))
-			error("RoadStop: failed loading savegame: too many RoadStops");
+			error("RoadStops: failed loading savegame: too many RoadStops");
 
 		rs = GetRoadStop(index);
 		SlObject(rs, _roadstop_desc);
--- a/ttd.c	Sun Feb 06 10:18:47 2005 +0000
+++ b/ttd.c	Sun Feb 06 10:24:57 2005 +0000
@@ -440,8 +440,6 @@
 static void InitializeDynamicVariables(void)
 {
 	/* Dynamic stuff needs to be initialized somewhere... */
-	_orders_size    = lengthof(_orders);
-
 	_station_sort  = NULL;
 	_vehicle_sort  = NULL;
 	_town_sort     = NULL;
@@ -456,6 +454,7 @@
 	CleanPool(&_station_pool);
 	CleanPool(&_vehicle_pool);
 	CleanPool(&_sign_pool);
+	CleanPool(&_order_pool);
 
 	free(_station_sort);
 	free(_vehicle_sort);