/* $Id$ */
/** @file ai_list.hpp a linked list which can keep item/value pairs */
#ifndef AI_LIST_HPP
#define AI_LIST_HPP
#include "ai_object.hpp"
#include <map>
#include <set>
class AIListSorter;
/**
* Class that creates a linked list which can keep item/value pairs.
*/
class AIList : public AIObject {
private:
AIListSorter *sorter;
public:
typedef std::set<int32> AIItemList;
typedef std::map<int32, AIItemList> AIListBucket;
typedef std::map<int32, int32> AIListMap;
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();
/**
* 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.
*/
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);
/**
* 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 {
public:
virtual ~Valuator() {}
virtual int32 Valuate(const int32 item) = 0;
};
/**
* Give all items a value defined by the valuator you give.
* @note the valuator should be a valid instance.
*/
void Valuate(AIList::Valuator *proc);
};
#ifdef DEFINE_SQUIRREL_CLASS
namespace SQConvert {
/* Allow inner classes/structs to be used as Squirrel parameters */
template <> AIList::Valuator *GetParam(ForceType<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.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.PostRegister(engine);
}
#endif /* DEFINE_SQUIRREL_CLASS */
#endif /* AI_LIST_HPP */