author | truelight |
Sat, 14 Apr 2007 20:17:36 +0000 | |
branch | noai |
changeset 9593 | 012f29f59906 |
parent 9592 | c5c09cfde63a |
child 9594 | 5009a30f320a |
--- a/projects/openttd.vcproj Sat Apr 14 20:01:25 2007 +0000 +++ b/projects/openttd.vcproj Sat Apr 14 20:17:36 2007 +0000 @@ -1027,6 +1027,9 @@ Name="AI API" Filter=""> <File + RelativePath=".\..\src\ai\api\ai_abstractlist.hpp"> + </File> + <File RelativePath=".\..\src\ai\api\ai_accounting.hpp"> </File> <File @@ -1097,6 +1100,9 @@ Name="AI API Implementation" Filter=""> <File + RelativePath=".\..\src\ai\api\ai_abstractlist.cpp"> + </File> + <File RelativePath=".\..\src\ai\api\ai_accounting.cpp"> </File> <File
--- a/projects/openttd_vs80.vcproj Sat Apr 14 20:01:25 2007 +0000 +++ b/projects/openttd_vs80.vcproj Sat Apr 14 20:17:36 2007 +0000 @@ -1588,6 +1588,10 @@ Name="AI API" > <File + RelativePath=".\..\src\ai\api\ai_abstractlist.hpp" + > + </File> + <File RelativePath=".\..\src\ai\api\ai_accounting.hpp" > </File> @@ -1680,6 +1684,10 @@ Name="AI API Implementation" > <File + RelativePath=".\..\src\ai\api\ai_abstractlist.cpp" + > + </File> + <File RelativePath=".\..\src\ai\api\ai_accounting.cpp" > </File>
--- a/source.list Sat Apr 14 20:01:25 2007 +0000 +++ b/source.list Sat Apr 14 20:17:36 2007 +0000 @@ -314,6 +314,7 @@ ai/NoAI/NoAI.hpp # AI API +ai/api/ai_abstractlist.hpp ai/api/ai_accounting.hpp ai/api/ai_base.hpp ai/api/ai_cargo.hpp @@ -338,6 +339,7 @@ ai/api/ai_vehicle.hpp # AI API Implementation +ai/api/ai_abstractlist.cpp ai/api/ai_accounting.cpp ai/api/ai_base.cpp ai/api/ai_cargo.cpp
--- a/src/ai/ai_squirrel.cpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/ai_squirrel.cpp Sat Apr 14 20:17:36 2007 +0000 @@ -195,6 +195,7 @@ /* Register all classes */ squirrel_register_std(this->engine); + SQAIAbstractListRegister(this->engine); SQAIAccountingRegister(this->engine); SQAIBaseRegister(this->engine); SQAICargoRegister(this->engine);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_abstractlist.cpp Sat Apr 14 20:17:36 2007 +0000 @@ -0,0 +1,378 @@ +/* $Id$ */ + +/** @file ai_abstractlist.cpp Implementation of AIAbstractList */ + +#include "ai_abstractlist.hpp" + +/** + * Base class for any AIAbstractList sorter. + */ +class AIAbstractListSorter { +protected: + AIAbstractList *list; + +public: + /** + * Virtual dtor, needed to mute warnings. + */ + virtual ~AIAbstractListSorter() { } + + /** + * Get the first item of the sorter. + */ + virtual int32 Begin() = 0; + + /** + * Get the next item of the sorter. + */ + virtual int32 Next() = 0; + + /** + * See if there is a next item of the sorter. + */ + virtual bool HasNext() = 0; +}; + +/** + * Sort by value, ascending. + */ +class AIAbstractListSorterValueAscending : public AIAbstractListSorter { +private: + AIAbstractList::AIAbstractListBucket::iterator bucket_iter; + AIAbstractList::AIItemList *bucket_list; + AIAbstractList::AIItemList::iterator bucket_list_iter; + +public: + AIAbstractListSorterValueAscending(AIAbstractList *list) + { + this->list = list; + } + + int32 Begin() + { + this->bucket_iter = this->list->buckets.begin(); + this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list_iter = this->bucket_list->begin(); + return *bucket_list_iter; + } + + int32 Next() + { + this->bucket_list_iter++; + if (this->bucket_list_iter == this->bucket_list->end()) { + this->bucket_iter++; + if (this->bucket_iter == this->list->buckets.end()) return 0; + this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list_iter = this->bucket_list->begin(); + } + return *bucket_list_iter; + } + + bool HasNext() + { + return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end(); + } +}; + +/** + * Sort by value, descending. + */ +class AIAbstractListSorterValueDescending : public AIAbstractListSorter { +private: + AIAbstractList::AIAbstractListBucket::reverse_iterator bucket_iter; + AIAbstractList::AIItemList *bucket_list; + AIAbstractList::AIItemList::reverse_iterator bucket_list_iter; + +public: + AIAbstractListSorterValueDescending(AIAbstractList *list) + { + this->list = list; + } + + int32 Begin() + { + this->bucket_iter = this->list->buckets.rbegin(); + this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list_iter = this->bucket_list->rbegin(); + return *bucket_list_iter; + } + + int32 Next() + { + this->bucket_list_iter++; + if (this->bucket_list_iter == this->bucket_list->rend()) { + this->bucket_iter++; + if (this->bucket_iter == this->list->buckets.rend()) return 0; + this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list_iter = this->bucket_list->rbegin(); + } + return *bucket_list_iter; + } + + bool HasNext() + { + return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend(); + } +}; + +/** + * Sort by item, ascending. + */ +class AIAbstractListSorterItemAscending : public AIAbstractListSorter { +private: + AIAbstractList::AIAbstractListMap::iterator item_iter; + +public: + AIAbstractListSorterItemAscending(AIAbstractList *list) + { + this->list = list; + } + + int32 Begin() + { + this->item_iter = this->list->items.begin(); + return (*this->item_iter).first; + } + + int32 Next() + { + this->item_iter++; + return (*this->item_iter).first; + } + + bool HasNext() + { + return this->item_iter != this->list->items.end(); + } +}; + +/** + * Sort by item, descending. + */ +class AIAbstractListSorterItemDescending : public AIAbstractListSorter { +private: + AIAbstractList::AIAbstractListMap::reverse_iterator item_iter; + +public: + AIAbstractListSorterItemDescending(AIAbstractList *list) + { + this->list = list; + } + + int32 Begin() + { + this->item_iter = this->list->items.rbegin(); + return (*this->item_iter).first; + } + + int32 Next() + { + this->item_iter++; + return (*this->item_iter).first; + } + + bool HasNext() + { + return this->item_iter != this->list->items.rend(); + } +}; + + + +AIAbstractList::AIAbstractList() +{ + /* Default sorter */ + this->sorter = new AIAbstractListSorterValueDescending(this); +} + +AIAbstractList::~AIAbstractList() +{ + delete this->sorter; +} + +bool AIAbstractList::HasItem(int32 item) +{ + return this->items.count(item) == 1; +} + +void AIAbstractList::Clear() +{ + this->items.clear(); + this->buckets.clear(); +} + +void AIAbstractList::AddItem(int32 item) +{ + if (this->HasItem(item)) return; + + this->items[item] = 0; + this->buckets[0].insert(item); +} + +void AIAbstractList::RemoveItem(int32 item) +{ + if (!this->HasItem(item)) return; + + this->buckets[this->GetValue(item)].erase(item); + this->items.erase(item); +} + +int32 AIAbstractList::Begin() +{ + return this->sorter->Begin(); +} + +int32 AIAbstractList::Next() +{ + return this->sorter->Next(); +} + +bool AIAbstractList::IsEmpty() +{ + return this->items.empty(); +} + +bool AIAbstractList::HasNext() +{ + return this->sorter->HasNext(); +} + +int32 AIAbstractList::Count() +{ + return this->items.size(); +} + +int32 AIAbstractList::GetValue(int32 item) +{ + if (!this->HasItem(item)) return 0; + + return this->items[item]; +} + +void AIAbstractList::SortByItem(bool ascending) +{ + delete this->sorter; + if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this); + else this->sorter = new AIAbstractListSorterItemDescending(this); +} + +void AIAbstractList::SortByValue(bool ascending) +{ + delete this->sorter; + if (ascending) this->sorter = new AIAbstractListSorterValueAscending(this); + else this->sorter = new AIAbstractListSorterValueDescending(this); +} + +void AIAbstractList::RemoveAboveValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second > value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first > value) this->buckets.erase(iter); + } +} + +void AIAbstractList::RemoveBelowValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second < value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first < value) this->buckets.erase(iter); + } +} + +void AIAbstractList::RemoveBetweenValue(int32 start, int32 end) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second > start && (*iter).second < end) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter); + } +} + +void AIAbstractList::RemoveValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second == value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first == value) this->buckets.erase(iter); + } +} + +void AIAbstractList::KeepAboveValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second <= value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first <= value) this->buckets.erase(iter); + } +} + +void AIAbstractList::KeepBelowValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second >= value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first >= value) this->buckets.erase(iter); + } +} + +void AIAbstractList::KeepBetweenValue(int32 start, int32 end) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter); + } +} + +void AIAbstractList::KeepValue(int32 value) +{ + for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).second != value) this->items.erase(iter); + } + + for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { + next_iter = iter; next_iter++; + if ((*iter).first != value) this->buckets.erase(iter); + } +} + +void AIAbstractList::Valuate(const AIAbstractList::Valuator &proc) +{ + this->buckets.clear(); + for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { + int32 value = proc.Valuate((*iter).first); + (*iter).second = value; + this->buckets[value].insert((*iter).first); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_abstractlist.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -0,0 +1,238 @@ +/* $Id$ */ + +/** @file ai_abstractlist.hpp a linked list which can keep item/value pairs */ + +#ifndef AI_ABSTRACTLIST_HPP +#define AI_ABSTRACTLIST_HPP + +#include "ai_object.hpp" +#include <map> +#include <set> + +class AIAbstractListSorter; + +/** + * Class that creates a linked list which can keep item/value pairs. + */ +class AIAbstractList : public AIObject { +private: + AIAbstractListSorter *sorter; + +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. + * @param item the item to remove. If not existing, it is ignored. + */ + void RemoveItem(int32 item); + +public: + /** + * The name of the class, needed by several sub-processes. + */ + static const char *GetClassName() { return "AIAbstractList"; } + + /** + * Constructor of the AIAbstractList. + */ + AIAbstractList(); + + /** + * Destructor of the AIAbstractList. + */ + ~AIAbstractList(); + + /** + * Clear the list, making Count() returning 0 and IsEmpty() returning true. + */ + void Clear(); + + /** + * Check if an item is in the list. + * @param item the item to check for. + * @return true if the item is in the list. + */ + bool HasItem(int32 item); + + /** + * Go to the beginning of the list. + * @return the item value of the first item. + */ + int32 Begin(); + + /** + * Go to the next item in the list. + * @return the item value of the next item. + * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list. + */ + int32 Next(); + + /** + * Check if a list is empty. + * @return true if the list is empty. + **/ + bool IsEmpty(); + + /** + * Check if there is a next element. In other words, if this is true, + * Next() will return a valid item. + * @return true if there is a next item. + */ + bool HasNext(); + + /** + * Returns the amount of items in the list. + * @return amount of items in the list. + */ + 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); + + /** + * Sort this list by item-value. + * @param ascending if true, lowest value is on top, else at bottom. + * @note the current item stays at the same place. + */ + void SortByItem(bool ascending); + + /** + * Sort this list by the value of the items. + * @param ascending if true, lowest value is on top, else at bottom. + * @note the current item stays at the same place. + */ + void SortByValue(bool ascending); + + /** + * 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); + + /** + * Removes all items with a value above start and below end. + * @param start the lower bound of the to be removed values (exclusive). + * @param end the upper bound of the to be removed valuens (exclusive). + */ + void RemoveBetweenValue(int32 start, int32 end); + + /** + * Remove all items with this value. + * @param value the value to remove. + */ + void RemoveValue(int32 value); + + /** + * Keep all items with a higher value than 'value'. + * @param value the value above which all items are kept. + */ + void KeepAboveValue(int32 value); + + /** + * Keep all items with a lower value than 'value'. + * @param value the value below which all items are kept. + */ + void KeepBelowValue(int32 value); + + /** + * Keep all items with a value above start and below end. + * @param start the lower bound of the to be kept values (exclusive). + * @param end the upper bound of the to be kept values (exclusive). + */ + void KeepBetweenValue(int32 start, int32 end); + + /** + * Keep all items with this value. + * @param value the value to keep. + **/ + void KeepValue(int32 value); + + /** + * The definition how valuators should look. + */ + class Valuator { + /* Make this valuator a friend of AIAbstractList, so we can access the private. + * Nobody else should ever call Valuate. */ + friend class AIAbstractList; + public: + /** + * Virtual destructor, needed to make compilers happy. + */ + virtual ~Valuator() {} + + private: + virtual int32 Valuate(int32 item) const = 0; + }; + + /** + * Give all items a value defined by the valuator you give. + * @note the valuator should be a valid instance. + */ + void Valuate(const AIAbstractList::Valuator &proc); +}; + +#ifdef DEFINE_SQUIRREL_CLASS +namespace SQConvert { + /* Allow inner classes/structs to be used as Squirrel parameters */ + template <> const AIAbstractList::Valuator &GetParam(ForceType<const AIAbstractList::Valuator &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList::Valuator *)instance; } + + /* Allow AIAbstractList to be used as Squirrel parameter */ + template <> AIAbstractList *GetParam(ForceType<AIAbstractList *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIAbstractList *)instance; } +}; // namespace SQConvert + +void SQAIAbstractListRegister(Squirrel *engine) { + DefSQClass <AIAbstractList> SQAIAbstractList("AIAbstractList"); + SQAIAbstractList.PreRegister(engine); + SQAIAbstractList.AddConstructor(engine); + + SQAIAbstractList.DefSQStaticMethod(engine, &AIAbstractList::GetClassName, "GetClassName", 1, "x"); + + 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::SortByItem, "SortByItem", 2, "xb"); + SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SortByValue, "SortByValue", 2, "xb"); + 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::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::Valuate, "Valuate", 2, "xx"); + + SQAIAbstractList.PostRegister(engine); +} +#endif /* DEFINE_SQUIRREL_CLASS */ + +#endif /* AI_LIST_HPP */
--- a/src/ai/api/ai_list.cpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_list.cpp Sat Apr 14 20:17:36 2007 +0000 @@ -1,378 +1,11 @@ -/* $Id$ */ - -/** @file ai_list.cpp Implementation of AIList */ - #include "ai_list.hpp" -/** - * Base class for any AIList sorter. - */ -class AIListSorter { -protected: - AIList *list; - -public: - /** - * Virtual dtor, needed to mute warnings. - */ - virtual ~AIListSorter() { } - - /** - * Get the first item of the sorter. - */ - virtual int32 Begin() = 0; - - /** - * Get the next item of the sorter. - */ - virtual int32 Next() = 0; - - /** - * See if there is a next item of the sorter. - */ - virtual bool HasNext() = 0; -}; - -/** - * Sort by value, ascending. - */ -class AIListSorterValueAscending : public AIListSorter { -private: - AIList::AIListBucket::iterator bucket_iter; - AIList::AIItemList *bucket_list; - AIList::AIItemList::iterator bucket_list_iter; - -public: - AIListSorterValueAscending(AIList *list) - { - this->list = list; - } - - int32 Begin() - { - this->bucket_iter = this->list->buckets.begin(); - this->bucket_list = &(*this->bucket_iter).second; - this->bucket_list_iter = this->bucket_list->begin(); - return *bucket_list_iter; - } - - int32 Next() - { - this->bucket_list_iter++; - if (this->bucket_list_iter == this->bucket_list->end()) { - this->bucket_iter++; - if (this->bucket_iter == this->list->buckets.end()) return 0; - this->bucket_list = &(*this->bucket_iter).second; - this->bucket_list_iter = this->bucket_list->begin(); - } - return *bucket_list_iter; - } - - bool HasNext() - { - return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end(); - } -}; - -/** - * Sort by value, descending. - */ -class AIListSorterValueDescending : public AIListSorter { -private: - AIList::AIListBucket::reverse_iterator bucket_iter; - AIList::AIItemList *bucket_list; - AIList::AIItemList::reverse_iterator bucket_list_iter; - -public: - AIListSorterValueDescending(AIList *list) - { - this->list = list; - } - - int32 Begin() - { - this->bucket_iter = this->list->buckets.rbegin(); - this->bucket_list = &(*this->bucket_iter).second; - this->bucket_list_iter = this->bucket_list->rbegin(); - return *bucket_list_iter; - } - - int32 Next() - { - this->bucket_list_iter++; - if (this->bucket_list_iter == this->bucket_list->rend()) { - this->bucket_iter++; - if (this->bucket_iter == this->list->buckets.rend()) return 0; - this->bucket_list = &(*this->bucket_iter).second; - this->bucket_list_iter = this->bucket_list->rbegin(); - } - return *bucket_list_iter; - } - - bool HasNext() - { - return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend(); - } -}; - -/** - * Sort by item, ascending. - */ -class AIListSorterItemAscending : public AIListSorter { -private: - AIList::AIListMap::iterator item_iter; - -public: - AIListSorterItemAscending(AIList *list) - { - this->list = list; - } - - int32 Begin() - { - this->item_iter = this->list->items.begin(); - return (*this->item_iter).first; - } - - int32 Next() - { - this->item_iter++; - return (*this->item_iter).first; - } - - bool HasNext() - { - return this->item_iter != this->list->items.end(); - } -}; - -/** - * Sort by item, descending. - */ -class AIListSorterItemDescending : public AIListSorter { -private: - AIList::AIListMap::reverse_iterator item_iter; - -public: - AIListSorterItemDescending(AIList *list) - { - this->list = list; - } - - int32 Begin() - { - this->item_iter = this->list->items.rbegin(); - return (*this->item_iter).first; - } - - int32 Next() - { - this->item_iter++; - return (*this->item_iter).first; - } - - bool HasNext() - { - return this->item_iter != this->list->items.rend(); - } -}; - - - -AIList::AIList() -{ - /* Default sorter */ - this->sorter = new AIListSorterValueDescending(this); -} - -AIList::~AIList() -{ - delete this->sorter; -} - -bool AIList::HasItem(int32 item) -{ - return this->items.count(item) == 1; -} - -void AIList::Clear() -{ - this->items.clear(); - this->buckets.clear(); -} - void AIList::AddItem(int32 item) { - if (this->HasItem(item)) return; - - this->items[item] = 0; - this->buckets[0].insert(item); + AIAbstractList::AddItem(item); } void AIList::RemoveItem(int32 item) { - if (!this->HasItem(item)) return; - - this->buckets[this->GetValue(item)].erase(item); - this->items.erase(item); -} - -int32 AIList::Begin() -{ - return this->sorter->Begin(); -} - -int32 AIList::Next() -{ - return this->sorter->Next(); -} - -bool AIList::IsEmpty() -{ - return this->items.empty(); -} - -bool AIList::HasNext() -{ - return this->sorter->HasNext(); -} - -int32 AIList::Count() -{ - return this->items.size(); -} - -int32 AIList::GetValue(int32 item) -{ - if (!this->HasItem(item)) return 0; - - return this->items[item]; -} - -void AIList::SortByItem(bool ascending) -{ - delete this->sorter; - if (ascending) this->sorter = new AIListSorterItemAscending(this); - else this->sorter = new AIListSorterItemDescending(this); -} - -void AIList::SortByValue(bool ascending) -{ - delete this->sorter; - if (ascending) this->sorter = new AIListSorterValueAscending(this); - else this->sorter = new AIListSorterValueDescending(this); -} - -void AIList::RemoveAboveValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second > value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first > value) this->buckets.erase(iter); - } -} - -void AIList::RemoveBelowValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second < value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first < value) this->buckets.erase(iter); - } + AIAbstractList::RemoveItem(item); } - -void AIList::RemoveBetweenValue(int32 start, int32 end) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second > start && (*iter).second < end) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter); - } -} - -void AIList::RemoveValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second == value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first == value) this->buckets.erase(iter); - } -} - -void AIList::KeepAboveValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second <= value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first <= value) this->buckets.erase(iter); - } -} - -void AIList::KeepBelowValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second >= value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first >= value) this->buckets.erase(iter); - } -} - -void AIList::KeepBetweenValue(int32 start, int32 end) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter); - } -} - -void AIList::KeepValue(int32 value) -{ - for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second != value) this->items.erase(iter); - } - - for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).first != value) this->buckets.erase(iter); - } -} - -void AIList::Valuate(const AIList::Valuator &proc) -{ - this->buckets.clear(); - for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { - int32 value = proc.Valuate((*iter).first); - (*iter).second = value; - this->buckets[value].insert((*iter).first); - } -}
--- a/src/ai/api/ai_list.hpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_list.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -1,237 +1,51 @@ /* $Id$ */ -/** @file ai_list.hpp a linked list which can keep item/value pairs */ +/** @file ai_list.hpp a simple list which you can manipulate */ #ifndef AI_LIST_HPP #define AI_LIST_HPP -#include "ai_object.hpp" -#include <map> -#include <set> - -class AIListSorter; +#include "ai_abstractlist.hpp" /** - * Class that creates a linked list which can keep item/value pairs. + * Class that creates a simple list of tiles which you can manipulate. */ -class AIList : public AIObject { -private: - AIListSorter *sorter; - +class AIList : public AIAbstractList { public: - typedef std::set<int32> AIItemList; ///< The list of items inside the bucket - typedef std::map<int32, AIItemList> AIListBucket; ///< The bucket list per value - typedef std::map<int32, int32> AIListMap; ///< List per item - - AIListMap items; ///< The items in the list - AIListBucket buckets; ///< The items in the list, sorted by value - -public: - /** * The name of the class, needed by several sub-processes. */ static const char *GetClassName() { return "AIList"; } - /** - * Constructor of the AIList. - */ - AIList(); - +public: /** - * Destructor of the AIList. - */ - ~AIList(); - - /** - * Clear the list, making Count() returning 0 and IsEmpty() returning true. - */ - void Clear(); - - /** - * 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. + * Add an item to the list. + * @param item the item to add. */ void AddItem(int32 item); /** - * Remove a single item from the list. - * @param item the item to remove. If not existing, it is ignored. + * Remove the item from the list. + * @param item the item to remove. */ void RemoveItem(int32 item); - - /** - * Check if an item is in the list. - * @param item the item to check for. - * @return true if the item is in the list. - */ - bool HasItem(int32 item); - - /** - * Go to the beginning of the list. - * @return the item value of the first item. - */ - int32 Begin(); - - /** - * Go to the next item in the list. - * @return the item value of the next item. - * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list. - */ - int32 Next(); - - /** - * Check if a list is empty. - * @return true if the list is empty. - **/ - bool IsEmpty(); - - /** - * Check if there is a next element. In other words, if this is true, - * Next() will return a valid item. - * @return true if there is a next item. - */ - bool HasNext(); - - /** - * Returns the amount of items in the list. - * @return amount of items in the list. - */ - 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); - - /** - * Sort this list by item-value. - * @param ascending if true, lowest value is on top, else at bottom. - * @note the current item stays at the same place. - */ - void SortByItem(bool ascending); - - /** - * Sort this list by the value of the items. - * @param ascending if true, lowest value is on top, else at bottom. - * @note the current item stays at the same place. - */ - void SortByValue(bool ascending); - - /** - * 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); - - /** - * Removes all items with a value above start and below end. - * @param start the lower bound of the to be removed values (exclusive). - * @param end the upper bound of the to be removed valuens (exclusive). - */ - void RemoveBetweenValue(int32 start, int32 end); - - /** - * Remove all items with this value. - * @param value the value to remove. - */ - void RemoveValue(int32 value); - - /** - * Keep all items with a higher value than 'value'. - * @param value the value above which all items are kept. - */ - void KeepAboveValue(int32 value); - - /** - * Keep all items with a lower value than 'value'. - * @param value the value below which all items are kept. - */ - void KeepBelowValue(int32 value); - - /** - * Keep all items with a value above start and below end. - * @param start the lower bound of the to be kept values (exclusive). - * @param end the upper bound of the to be kept values (exclusive). - */ - void KeepBetweenValue(int32 start, int32 end); - - /** - * Keep all items with this value. - * @param value the value to keep. - **/ - void KeepValue(int32 value); - - /** - * The definition how valuators should look. - */ - class Valuator { - /* Make this valuator a friend of AIList, so we can access the private. - * Nobody else should ever call Valuate. */ - friend class AIList; - public: - /** - * Virtual destructor, needed to make compilers happy. - */ - virtual ~Valuator() {} - - private: - virtual int32 Valuate(int32 item) const = 0; - }; - - /** - * Give all items a value defined by the valuator you give. - * @note the valuator should be a valid instance. - */ - void Valuate(const AIList::Valuator &proc); }; #ifdef DEFINE_SQUIRREL_CLASS namespace SQConvert { - /* Allow inner classes/structs to be used as Squirrel parameters */ - template <> const AIList::Valuator &GetParam(ForceType<const AIList::Valuator &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIList::Valuator *)instance; } - /* Allow AIList to be used as Squirrel parameter */ template <> AIList *GetParam(ForceType<AIList *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIList *)instance; } }; // namespace SQConvert void SQAIListRegister(Squirrel *engine) { DefSQClass <AIList> SQAIList("AIList"); - SQAIList.PreRegister(engine); + SQAIList.PreRegister(engine, "AIAbstractList"); SQAIList.AddConstructor(engine); SQAIList.DefSQStaticMethod(engine, &AIList::GetClassName, "GetClassName", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::Clear, "Clear", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::AddItem, "AddItem", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::RemoveItem, "RemoveItem", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::HasItem, "HasItem", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::Begin, "Begin", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::Next, "Next", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::IsEmpty, "IsEmpty", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::HasNext, "HasNext", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::Count, "Count", 1, "x"); - SQAIList.DefSQMethod(engine, &AIList::GetValue, "GetValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::SortByItem, "SortByItem", 2, "xb"); - SQAIList.DefSQMethod(engine, &AIList::SortByValue, "SortByValue", 2, "xb"); - SQAIList.DefSQMethod(engine, &AIList::RemoveAboveValue, "RemoveAboveValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::RemoveBelowValue, "RemoveBelowValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii"); - SQAIList.DefSQMethod(engine, &AIList::RemoveValue, "RemoveValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::KeepAboveValue, "KeepAboveValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::KeepBelowValue, "KeepBelowValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::KeepBetweenValue, "KeepBetweenValue", 3, "xii"); - SQAIList.DefSQMethod(engine, &AIList::KeepValue, "KeepValue", 2, "xi"); - SQAIList.DefSQMethod(engine, &AIList::Valuate, "Valuate", 2, "xx"); + SQAIList.DefSQMethod(engine, &AIList::AddItem, "AddItem", 2, "xi"); + SQAIList.DefSQMethod(engine, &AIList::RemoveItem, "RemoveItem", 2, "xi"); SQAIList.PostRegister(engine); }
--- a/src/ai/api/ai_tilelist.hpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_tilelist.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -5,12 +5,12 @@ #ifndef AI_TILELIST_HPP #define AI_TILELIST_HPP -#include "ai_list.hpp" +#include "ai_abstractlist.hpp" /** * Class that creates a simple list of tiles which you can manipulate. */ -class AITileList : public AIList { +class AITileList : public AIAbstractList { public: /** * The name of the class, needed by several sub-processes. @@ -67,7 +67,7 @@ void SQAITileListRegister(Squirrel *engine) { DefSQClass <AITileList> SQAITileList("AITileList"); - SQAITileList.PreRegister(engine, "AIList"); + SQAITileList.PreRegister(engine, "AIAbstractList"); SQAITileList.AddConstructor(engine); SQAITileList.DefSQStaticMethod(engine, &AITileList::GetClassName, "GetClassName", 1, "x");
--- a/src/ai/api/ai_tilelist_valuator.hpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_tilelist_valuator.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -5,14 +5,14 @@ #ifndef AI_TILELIST_VALUATOR_HPP #define AI_TILELIST_VALUATOR_HPP -#include "ai_list.hpp" +#include "ai_abstractlist.hpp" /** * Check if tiles are buildable for entries in an AITownList instance. * @note resulting items are of the type bool (0 = not buildable, 1 = buildable) * @note the input items are of the type TileIndex */ -class AITileListBuildable : public AIList::Valuator { +class AITileListBuildable : public AIAbstractList::Valuator { public: /** * The name of the class, needed by several sub-processes.
--- a/src/ai/api/ai_townlist.hpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_townlist.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -5,12 +5,12 @@ #ifndef AI_TOWNLIST_HPP #define AI_TOWNLIST_HPP -#include "ai_list.hpp" +#include "ai_abstractlist.hpp" /** * Class that creates a list of current towns. */ -class AITownList : public AIList { +class AITownList : public AIAbstractList { public: /** * The name of the class, needed by several sub-processes. @@ -31,7 +31,7 @@ void SQAITownListRegister(Squirrel *engine) { DefSQClass <AITownList> SQAITownList("AITownList"); - SQAITownList.PreRegister(engine, "AIList"); + SQAITownList.PreRegister(engine, "AIAbstractList"); SQAITownList.AddConstructor(engine); SQAITownList.DefSQStaticMethod(engine, &AITownList::GetClassName, "GetClassName", 1, "x");
--- a/src/ai/api/ai_townlist_valuator.hpp Sat Apr 14 20:01:25 2007 +0000 +++ b/src/ai/api/ai_townlist_valuator.hpp Sat Apr 14 20:17:36 2007 +0000 @@ -5,14 +5,14 @@ #ifndef AI_TOWNLIST_VALUATOR_HPP #define AI_TOWNLIST_VALUATOR_HPP -#include "ai_list.hpp" +#include "ai_abstractlist.hpp" /** * Get the population for entries in an AITownList instance. * @note resulting items are of the type int32 * @note the input items are of the type TownID */ -class AITownListGetPopulation : public AIList::Valuator { +class AITownListGetPopulation : public AIAbstractList::Valuator { public: /** * The name of the class, needed by several sub-processes. @@ -45,7 +45,7 @@ * @note resulting items are of the type TileIndex * @note the input items are of the type TownID */ -class AITownListGetLocation : public AIList::Valuator { +class AITownListGetLocation : public AIAbstractList::Valuator { public: /** * The name of the class, needed by several sub-processes.