Changeset - r12557:c2a1f0721f17
[Not reviewed]
master
0 6 0
yexo - 15 years ago 2009-07-31 19:50:01
yexo@openttd.org
(svn r17005) -Add [NoAI]: AIAbstractList::SORT_ASCENDING / SORT_DESCENDING
6 files changed with 48 insertions and 7 deletions:
0 comments (0 inline, 0 general)
bin/ai/regression/regression.nut
Show inline comments
 
@@ -37,119 +37,119 @@ function Regression::TestInit()
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i - 10);
 
		list.RemoveItem(i - 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 2);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_VALUE, true);
 
	list.Sort(AIAbstractList.SORT_BY_VALUE, AIAbstractList.SORT_ASCENDING);
 
	print("");
 
	print(" Value Ascending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i + 10);
 
		list.RemoveItem(i + 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 50);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, false);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_DESCENDING);
 
	print("");
 
	print(" Item Descending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i - 10);
 
		list.RemoveItem(i - 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 2);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
 
	print("");
 
	print(" Item Ascending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i + 10);
 
		list.RemoveItem(i + 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
@@ -524,49 +524,49 @@ function Regression::Group()
 
	print("  MoveVehicle():            " + AIGroup.MoveVehicle(group, vehicle));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(group, 116));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.GROUP_ALL, 116));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.GROUP_DEFAULT, 116));
 
	print("  GetName():                " + AIGroup.GetName(0));
 
	print("  GetName():                " + AIGroup.GetName(1));
 
	print("  AIVehicle.SellVehicle():  " + AIVehicle.SellVehicle(vehicle));
 
	print("  AITile.DemolishTile():    " + AITile.DemolishTile(10000));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(true));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(false));
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(false));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
}
 

	
 
function Regression::Industry()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Industry--");
 
	print("  GetIndustryCount():  " + AIIndustry.GetIndustryCount());
 
	local list = AIIndustryList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		if (AIIndustry.IsValidIndustry(i)) j++;
 
		print("  Industry " + i);
 
		print("    IsValidIndustry(): " + AIIndustry.IsValidIndustry(i));
 
		print("    GetName():         " + AIIndustry.GetName(i));
 
		print("    GetLocation():     " + AIIndustry.GetLocation(i));
 
		print("    IsCargoAccepted(): " + AIIndustry.IsCargoAccepted(i, 1));
 

	
 
		local cargo_list = AICargoList();
 
		for (local j = cargo_list.Begin(); cargo_list.HasNext(); j = cargo_list.Next()) {
 
			if (AIIndustry.IsCargoAccepted(i, j) || AIIndustry.GetLastMonthProduction(i,j) >= 0) {
 
				print("	   GetLastMonthProduction():  " + AIIndustry.GetLastMonthProduction(i, j));
 
				print("	   GetLastMonthTransported(): " + AIIndustry.GetLastMonthTransported(i, j));
 
				print("	   GetStockpiledCargo():      " + AIIndustry.GetStockpiledCargo(i, j));
 
			}
 
		}
 
	}
 
	print("  Valid Industries:    " + j);
 
	print("  GetIndustryCount():  " + AIIndustry.GetIndustryCount());
 
}
 

	
 
function Regression::IndustryList()
 
{
 
	local list = AIIndustryList();
 
@@ -646,49 +646,49 @@ function CustomValuator(list_id)
 
{
 
	return list_id * 4343;
 
}
 

	
 
function Regression::List()
 
{
 
	local list = AIList();
 

	
 
	print("");
 
	print("--List--");
 

	
 
	print("  IsEmpty():     " + list.IsEmpty());
 
	list.AddItem(1, 1);
 
	list.AddItem(2, 2);
 
	for (local i = 1000; i < 1100; i++) {
 
		list.AddItem(i, i);
 
	}
 
	list.RemoveItem(1050);
 
	list.RemoveItem(1150);
 
	list.ChangeItem(1051, 12);
 
	print("  Count():       " + list.Count());
 
	print("  HasItem(1050): " + list.HasItem(1050));
 
	print("  HasItem(1051): " + list.HasItem(1051));
 
	print("  IsEmpty():     " + list.IsEmpty());
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
 
	print("  List Dump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(CustomValuator);
 
	print("  Custom ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(function (a) { return a * 42; });
 
	print("  Custom ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBase.RandItem);
 
	print("  Randomize ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.KeepTop(10);
 
	print("  KeepTop(10):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
@@ -1067,49 +1067,49 @@ function Regression::Road()
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(33417, 33418));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33411 + 256));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33412 + 256));
 
	print("    IsDriveThroughRoadStationTile: " + AIRoad.IsDriveThroughRoadStationTile(33415));
 
	print("    IsBuildable():                 " + AITile.IsBuildable(33415));
 
	print("    GetDriveThroughBackTile():     " + AIRoad.GetDriveThroughBackTile(33415));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33415));
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33415));
 
}
 

	
 
function Regression::Sign()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Sign--");
 
	print("  BuildSign(33410, 'Some Sign'):       " + AISign.BuildSign(33410, "Some Sign"));
 
	print("  BuildSign(33411, 'Test'):            " + AISign.BuildSign(33411, "Test"));
 
	print("  SetName(1, 'Test2'):                 " + AISign.SetName(1, "Test2"));
 
	local sign_id = AISign.BuildSign(33409, "Some other Sign");
 
	print("  BuildSign(33409, 'Some other Sign'): " + sign_id);
 
	print("  RemoveSign(" + sign_id + "):                       " + AISign.RemoveSign(sign_id));
 
	print("");
 
	local list = AISignList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		j++;
 
		print("  Sign " + i);
 
		print("    IsValidSign():   " + AISign.IsValidSign(i));
 
		print("    GetName():       " + AISign.GetName(i));
 
		print("    GetLocation():   " + AISign.GetLocation(i));
 
	}
 
	print("  Valid Signs:       " + j);
 
}
 

	
 
function Regression::Station()
 
{
 
	print("");
 
	print("--Station--");
 
	print("  IsValidStation(0):        " + AIStation.IsValidStation(0));
 
	print("  IsValidStation(1000):     " + AIStation.IsValidStation(1000));
 
	print("  GetName(0):               " + AIStation.GetName(0));
 
	print("  SetName(0):               " + AIStation.SetName(0, "Look, a station"));
 
	print("  GetName(0):               " + AIStation.GetName(0));
 
	print("  GetLocation(1):           " + AIStation.GetLocation(1));
 
	print("  GetLocation(1000):        " + AIStation.GetLocation(1000));
 
	print("  GetStationID(33411):      " + AIStation.GetStationID(33411));
 
	print("  GetStationID(34411):      " + AIStation.GetStationID(34411));
 
	print("  GetCargoWaiting(0, 0):    " + AIStation.GetCargoWaiting(0, 0));
 
@@ -1336,49 +1336,49 @@ function Regression::TileList()
 
	list.Valuate(AITile.GetCargoProduction, 7, 1, 1, 3);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AITileList_StationType(4, AIStation.STATION_BUS_STOP);
 
	print("");
 
	print("--TileList_StationType--");
 
	print("  Count():             " + list.Count());
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::Town()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Town--");
 
	print("  GetTownCount():    " + AITown.GetTownCount());
 
	local list = AITownList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		if (AITown.IsValidTown(i)) j++;
 
		print("  Town " + i);
 
		print("    IsValidTown():   " + AITown.IsValidTown(i));
 
		print("    GetName():       " + AITown.GetName(i));
 
		print("    GetPopulation(): " + AITown.GetPopulation(i));
 
		print("    GetLocation():   " + AITown.GetLocation(i));
 
		print("    GetHouseCount(): " + AITown.GetHouseCount(i));
 
		print("    GetRating():     " + AITown.GetRating(i, AICompany.COMPANY_SELF));
 
	}
 
	print("  Valid Towns:       " + j);
 
	print("  GetTownCount():    " + AITown.GetTownCount());
 
}
 

	
 
function Regression::TownList()
 
{
 
	local list = AITownList();
 

	
 
	print("");
 
	print("--TownList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AITown.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
src/ai/api/ai_abstractlist.hpp
Show inline comments
 
@@ -4,48 +4,53 @@
 
/** @defgroup AIList Classes that create a list of items. */
 

	
 
#ifndef AI_ABSTRACTLIST_HPP
 
#define AI_ABSTRACTLIST_HPP
 

	
 
#include "ai_object.hpp"
 
#include <map>
 
#include <set>
 

	
 
class AIAbstractListSorter;
 

	
 
/**
 
 * Class that creates a list which can keep item/value pairs, which you can walk.
 
 */
 
class AIAbstractList : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIAbstractList"; }
 

	
 
	/** Type of sorter */
 
	enum SorterType {
 
		SORT_BY_VALUE, //!< Sort the list based on the value of the item.
 
		SORT_BY_ITEM,  //!< Sort the list based on the item itself.
 
	};
 

	
 
	/** Sort ascending */
 
	static const bool SORT_ASCENDING = true;
 
	/** Sort descnding */
 
	static const bool SORT_DESCENDING = false;
 

	
 
private:
 
	AIAbstractListSorter *sorter;
 
	SorterType sorter_type;
 
	bool sort_ascending;
 
	bool initialized;
 

	
 
public:
 
	typedef std::set<int32> AIItemList;                       //!< The list of items inside the bucket
 
	typedef std::map<int32, AIItemList> AIAbstractListBucket; //!< The bucket list per value
 
	typedef std::map<int32, int32> AIAbstractListMap;         //!< List per item
 

	
 
	AIAbstractListMap items;           //!< The items in the list
 
	AIAbstractListBucket buckets;      //!< The items in the list, sorted by value
 

	
 
protected:
 
	/**
 
	 * Add a single item to the list.
 
	 * @param item the item to add. Should be unique, otherwise it is ignored.
 
	 * @note the value is set to 0 by default.
 
	 */
 
	void AddItem(int32 item);
 

	
 
	/**
 
	 * Remove a single item from the list.
 
@@ -102,48 +107,49 @@ public:
 
	int32 Count();
 

	
 
	/**
 
	 * Get the value that belongs to this item.
 
	 * @param item the item to get the value from
 
	 * @return the value that belongs to this item.
 
	 */
 
	int32 GetValue(int32 item);
 

	
 
	/**
 
	 * Set a value of an item directly.
 
	 * @param item the item to set the value for.
 
	 * @param value the value to give to the item
 
	 * @return true if we could set the item to value, false otherwise.
 
	 * @note Changing values of items while looping through a list might cause
 
	 *  entries to be skipped. Be very careful with such operations.
 
	 */
 
	bool SetValue(int32 item, int32 value);
 

	
 
	/**
 
	 * Sort this list by the given sorter and direction.
 
	 * @param sorter    the type of sorter to use
 
	 * @param ascending if true, lowest value is on top, else at bottom.
 
	 * @note the current item stays at the same place.
 
	 * @see SORT_ASCENDING SORT_DESCENDING
 
	 */
 
	void Sort(SorterType sorter, bool ascending);
 

	
 
	/**
 
	 * Add one list to an other one.
 
	 * @param list The list that will be added to the caller.
 
	 * @post The list to be added ('list') stays unmodified.
 
	 * @note All added items keep their value as it was in 'list'.
 
	 * @note If the item already exists inside the caller, the value of the
 
	 *  list that is added is set on the item.
 
	 */
 
	void AddList(AIAbstractList *list);
 

	
 
	/**
 
	 * Removes all items with a higher value than 'value'.
 
	 * @param value the value above which all items are removed.
 
	 */
 
	void RemoveAboveValue(int32 value);
 

	
 
	/**
 
	 * Removes all items with a lower value than 'value'.
 
	 * @param value the value below which all items are removed.
 
	 */
 
	void RemoveBelowValue(int32 value);
src/ai/api/ai_abstractlist.hpp.sq
Show inline comments
 
@@ -3,48 +3,51 @@
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIAbstractList::SorterType GetParam(ForceType<AIAbstractList::SorterType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAbstractList::SorterType)tmp; }
 
	template <> int Return<AIAbstractList::SorterType>(HSQUIRRELVM vm, AIAbstractList::SorterType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIAbstractList to be used as Squirrel parameter */
 
	template <> AIAbstractList *GetParam(ForceType<AIAbstractList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAbstractList *)instance; }
 
	template <> AIAbstractList &GetParam(ForceType<AIAbstractList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList *)instance; }
 
	template <> const AIAbstractList *GetParam(ForceType<const AIAbstractList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAbstractList *)instance; }
 
	template <> const AIAbstractList &GetParam(ForceType<const AIAbstractList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList *)instance; }
 
	template <> int Return<AIAbstractList *>(HSQUIRRELVM vm, AIAbstractList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIAbstractList", res, NULL, DefSQDestructorCallback<AIAbstractList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIAbstractList_Register(Squirrel *engine) {
 
	DefSQClass <AIAbstractList> SQAIAbstractList("AIAbstractList");
 
	SQAIAbstractList.PreRegister(engine);
 
	SQAIAbstractList.AddConstructor<void (AIAbstractList::*)(), 1>(engine, "x");
 

	
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_VALUE, "SORT_BY_VALUE");
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_ITEM,  "SORT_BY_ITEM");
 

	
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_ASCENDING,  "SORT_ASCENDING");
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_DESCENDING, "SORT_DESCENDING");
 

	
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Clear,              "Clear",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasItem,            "HasItem",            2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Begin,              "Begin",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Next,               "Next",               1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::IsEmpty,            "IsEmpty",            1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasNext,            "HasNext",            1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Count,              "Count",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::GetValue,           "GetValue",           2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SetValue,           "SetValue",           3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Sort,               "Sort",               3, "xib");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::AddList,            "AddList",            2, "xx");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveAboveValue,   "RemoveAboveValue",   2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBelowValue,   "RemoveBelowValue",   2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveValue,        "RemoveValue",        2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveTop,          "RemoveTop",          2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBottom,       "RemoveBottom",       2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveList,         "RemoveList",         2, "xx");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepAboveValue,     "KeepAboveValue",     2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBelowValue,     "KeepBelowValue",     2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBetweenValue,   "KeepBetweenValue",   3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepValue,          "KeepValue",          2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepTop,            "KeepTop",            2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBottom,         "KeepBottom",         2, "xi");
src/ai/api/squirrel_export.awk
Show inline comments
 
@@ -13,48 +13,49 @@ function array_sort(ARRAY, ELEMENTS, tem
 
			temp = ARRAY[j]
 
			ARRAY[j] = ARRAY[j - 1]
 
			ARRAY[j - 1] = temp
 
	}
 
	return
 
}
 

	
 
function dump_class_templates(name) {
 
	print "	template <> "       name " *GetParam(ForceType<"       name " *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (" name " *)instance; }"
 
	print "	template <> "       name " &GetParam(ForceType<"       name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }"
 
	print "	template <> const " name " *GetParam(ForceType<const " name " *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (" name " *)instance; }"
 
	print "	template <> const " name " &GetParam(ForceType<const " name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }"
 
	if (name == "AIEvent") {
 
		print "	template <> int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"" name "\", res, NULL, DefSQDestructorCallback<" name ">); return 1; }"
 
	} else {
 
		print "	template <> int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"" name "\", res, NULL, DefSQDestructorCallback<" name ">); return 1; }"
 
	}
 
}
 

	
 
BEGIN {
 
	enum_size = 0
 
	enum_value_size = 0
 
	enum_string_to_error_size = 0
 
	enum_error_to_string_size = 0
 
	const_size = 0
 
	struct_size = 0
 
	method_size = 0
 
	static_method_size = 0
 
	virtual_class = "false"
 
	super_cls = ""
 
	cls = ""
 
	start_squirrel_define_on_next_line = "false"
 
	cls_level = 0
 
	RS = "\r|\n"
 
}
 

	
 
/@file/ {
 
	# Break it in two lines, so SVN doesn't replace it
 
	printf "/* $I"
 
	print "d$ */"
 
	print "/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */"
 
	print ""
 
	print "#include \"" $3 "\""
 
}
 

	
 
# Remove the old squirrel stuff
 
/#ifdef DEFINE_SQUIRREL_CLASS/ { squirrel_stuff = "true";  next; }
 
/^#endif \/\* DEFINE_SQUIRREL_CLASS \*\// { if (squirrel_stuff == "true") { squirrel_stuff = "false"; next; } }
 
{ if (squirrel_stuff == "true") next; }
 
@@ -196,48 +197,59 @@ BEGIN {
 
	# Then do the registration functions of the class. */
 
	print "void SQ" cls "_Register(Squirrel *engine) {"
 
	print "	DefSQClass <" cls "> SQ" cls "(\"" cls "\");"
 
	if (super_cls == "AIObject" || super_cls == "AIAbstractList::Valuator") {
 
		print "	SQ" cls ".PreRegister(engine);"
 
	} else {
 
		print "	SQ" cls ".PreRegister(engine, \"" super_cls "\");"
 
	}
 
	if (virtual_class == "false" && super_cls != "AIEvent") {
 
		print "	SQ" cls ".AddConstructor<void (" cls "::*)(" cls_param[0] "), " cls_param[1]">(engine, \"" cls_param[2] "\");"
 
	}
 
	print ""
 

	
 
	# Enum values
 
	mlen = 0
 
	for (i = 1; i <= enum_value_size; i++) {
 
		if (mlen <= length(enum_value[i])) mlen = length(enum_value[i])
 
	}
 
	for (i = 1; i <= enum_value_size; i++) {
 
		print "	SQ" cls ".DefSQConst(engine, " cls "::" enum_value[i] ", " substr(spaces, 1, mlen - length(enum_value[i])) "\""  enum_value[i] "\");"
 
		delete enum_value[i]
 
	}
 
	if (enum_value_size != 0) print ""
 

	
 
	# Const values
 
	mlen = 0
 
	for (i = 1; i <= const_size; i++) {
 
		if (mlen <= length(const_value[i])) mlen = length(const_value[i])
 
	}
 
	for (i = 1; i <= const_size; i++) {
 
		print "	SQ" cls ".DefSQConst(engine, " cls "::" const_value[i] ", " substr(spaces, 1, mlen - length(const_value[i])) "\""  const_value[i] "\");"
 
		delete const_value[i]
 
	}
 
	if (const_size != 0) print ""
 

	
 
	# Mapping of OTTD strings to errors
 
	mlen = 0
 
	for (i = 1; i <= enum_string_to_error_size; i++) {
 
		if (mlen <= length(enum_string_to_error_mapping_string[i])) mlen = length(enum_string_to_error_mapping_string[i])
 
	}
 
	for (i = 1; i <= enum_string_to_error_size; i++) {
 
		print "	AIError::RegisterErrorMap(" enum_string_to_error_mapping_string[i] ", " substr(spaces, 1, mlen - length(enum_string_to_error_mapping_string[i]))  cls "::" enum_string_to_error_mapping_error[i] ");"
 

	
 
		delete enum_string_to_error_mapping_string[i]
 
	}
 
	if (enum_string_to_error_size != 0) print ""
 

	
 
	# Mapping of errors to human 'readable' strings.
 
	mlen = 0
 
	for (i = 1; i <= enum_error_to_string_size; i++) {
 
		if (mlen <= length(enum_error_to_string_mapping[i])) mlen = length(enum_error_to_string_mapping[i])
 
	}
 
	for (i = 1; i <= enum_error_to_string_size; i++) {
 
		print "	AIError::RegisterErrorMapString(" cls "::" enum_error_to_string_mapping[i] ", " substr(spaces, 1, mlen - length(enum_error_to_string_mapping[i])) "\"" enum_error_to_string_mapping[i] "\");"
 
		delete enum_error_to_string_mapping[i]
 
	}
 
	if (enum_error_to_string_size != 0) print ""
 

	
 
	# Static methods
 
@@ -299,48 +311,55 @@ BEGIN {
 
			# enum ErrorMessages {
 
			#	ERR_SOME_ERROR,	// [STR_ITEM1, STR_ITEM2, ...]
 
			# }
 

	
 
			# Set the mappings
 
			if (match($0, "\\[.*\\]") != 0) {
 
				mappings = substr($0, RSTART, RLENGTH);
 
				gsub("([\\[[:space:]\\]])", "", mappings);
 

	
 
				split(mappings, mapitems, ",");
 
				for (i = 1; i <= length(mapitems); i++) {
 
					enum_string_to_error_size++
 
					enum_string_to_error_mapping_string[enum_string_to_error_size] = mapitems[i]
 
					enum_string_to_error_mapping_error[enum_string_to_error_size] = $1
 
				}
 

	
 
				enum_error_to_string_size++
 
				enum_error_to_string_mapping[enum_error_to_string_size] = $1
 
			}
 
		}
 
		next
 
	}
 
}
 

	
 
# Add a const (non-enum) value
 
/^[ 	]*static const \w+ \w+ = \w+;$/ {
 
	const_size++
 
	const_value[const_size] = $4
 
	next
 
}
 

	
 
# Add a method to the list
 
/^.*\(.*\).*$/ {
 
	if (cls_level != 1) next
 
	if (match($0, "~")) next
 

	
 
	is_static = match($0, "static")
 
	if (match($0, "virtual")) {
 
		virtual_class = "true"
 
	}
 
	gsub("virtual", "", $0)
 
	gsub("static", "", $0)
 
	gsub("const", "", $0)
 
	gsub("{.*", "", $0)
 
	param_s = $0
 
	gsub("\\*", "", $0)
 
	gsub("\\(.*", "", $0)
 

	
 
	sub(".*\\(", "", param_s)
 
	sub("\\).*", "", param_s)
 

	
 
	funcname = $2
 
	if ($1 == cls && funcname == "") {
 
		cls_param[0] = param_s
 
		if (param_s == "") next
src/script/squirrel.cpp
Show inline comments
 
@@ -110,48 +110,55 @@ void Squirrel::PrintFunc(HSQUIRRELVM vm,
 
}
 

	
 
void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params, void *userdata, int size)
 
{
 
	sq_pushstring(this->vm, OTTD2FS(method_name), -1);
 

	
 
	if (size != 0) {
 
		void *ptr = sq_newuserdata(vm, size);
 
		memcpy(ptr, userdata, size);
 
	}
 

	
 
	sq_newclosure(this->vm, proc, size != 0 ? 1 : 0);
 
	if (nparam != 0) sq_setparamscheck(this->vm, nparam, OTTD2FS(params));
 
	sq_setnativeclosurename(this->vm, -1, OTTD2FS(method_name));
 
	sq_newslot(this->vm, -3, SQFalse);
 
}
 

	
 
void Squirrel::AddConst(const char *var_name, int value)
 
{
 
	sq_pushstring(this->vm, OTTD2FS(var_name), -1);
 
	sq_pushinteger(this->vm, value);
 
	sq_newslot(this->vm, -3, SQTrue);
 
}
 

	
 
void Squirrel::AddConst(const char *var_name, bool value)
 
{
 
	sq_pushstring(this->vm, OTTD2FS(var_name), -1);
 
	sq_pushbool(this->vm, value);
 
	sq_newslot(this->vm, -3, SQTrue);
 
}
 

	
 
void Squirrel::AddClassBegin(const char *class_name)
 
{
 
	sq_pushroottable(this->vm);
 
	sq_pushstring(this->vm, OTTD2FS(class_name), -1);
 
	sq_newclass(this->vm, SQFalse);
 
}
 

	
 
void Squirrel::AddClassBegin(const char *class_name, const char *parent_class)
 
{
 
	sq_pushroottable(this->vm);
 
	sq_pushstring(this->vm, OTTD2FS(class_name), -1);
 
	sq_pushstring(this->vm, OTTD2FS(parent_class), -1);
 
	if (SQ_FAILED(sq_get(this->vm, -3))) {
 
		DEBUG(misc, 0, "[squirrel] Failed to initialize class '%s' based on parent class '%s'", class_name, parent_class);
 
		DEBUG(misc, 0, "[squirrel] Make sure that '%s' exists before trying to define '%s'", parent_class, class_name);
 
		return;
 
	}
 
	sq_newclass(this->vm, SQTrue);
 
}
 

	
 
void Squirrel::AddClassEnd()
 
{
 
	sq_newslot(vm, -3, SQFalse);
 
	sq_pop(vm, 1);
src/script/squirrel.hpp
Show inline comments
 
@@ -57,48 +57,54 @@ public:
 
	 * @param script The full script-name to load.
 
	 * @return False if loading failed.
 
	 */
 
	bool LoadScript(const char *script);
 
	static bool LoadScript(HSQUIRRELVM vm, const char *script, bool in_root = true);
 

	
 
	/**
 
	 * Load a file to a given VM.
 
	 */
 
	static SQRESULT LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printerror);
 

	
 
	/**
 
	 * Adds a function to the stack. Depending on the current state this means
 
	 *  either a method or a global function.
 
	 */
 
	void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam = 0, const char *params = NULL, void *userdata = NULL, int size = 0);
 

	
 
	/**
 
	 * Adds a const to the stack. Depending on the current state this means
 
	 *  either a const to a class or to the global space.
 
	 */
 
	void AddConst(const char *var_name, int value);
 

	
 
	/**
 
	 * Adds a const to the stack. Depending on the current state this means
 
	 *  either a const to a class or to the global space.
 
	 */
 
	void AddConst(const char *var_name, bool value);
 

	
 
	/**
 
	 * Adds a class to the global scope. Make sure to call AddClassEnd when you
 
	 *  are done adding methods.
 
	 */
 
	void AddClassBegin(const char *class_name);
 

	
 
	/**
 
	 * Adds a class to the global scope, extending 'parent_class'.
 
	 * Make sure to call AddClassEnd when you are done adding methods.
 
	 */
 
	void AddClassBegin(const char *class_name, const char *parent_class);
 

	
 
	/**
 
	 * Finishes adding a class to the global scope. If this isn't called, no
 
	 *  class is really created.
 
	 */
 
	void AddClassEnd();
 

	
 
	/**
 
	 * Resume a VM when it was suspended via a throw.
 
	 */
 
	bool Resume(int suspend = -1);
 

	
 
	/**
 
	 * Tell the VM to do a garbage collection run.
0 comments (0 inline, 0 general)