truelight@9579: /* $Id$ */ truelight@9579: truebrain@9833: /** @file ai_abstractlist.cpp Implementation of AIAbstractList. */ truelight@9579: truebrain@9814: #include truelight@9593: #include "ai_abstractlist.hpp" truebrain@9752: #include "../../debug.h" truelight@9579: truelight@9579: /** truelight@9593: * Base class for any AIAbstractList sorter. truelight@9579: */ truelight@9593: class AIAbstractListSorter { truelight@9579: protected: truelight@9593: AIAbstractList *list; truelight@9579: truelight@9579: public: truelight@9579: /** truelight@9579: * Virtual dtor, needed to mute warnings. truelight@9579: */ truelight@9593: virtual ~AIAbstractListSorter() { } truelight@9579: truelight@9579: /** truelight@9579: * Get the first item of the sorter. truelight@9579: */ truelight@9579: virtual int32 Begin() = 0; truelight@9579: truelight@9579: /** truelight@9579: * Get the next item of the sorter. truelight@9579: */ truelight@9579: virtual int32 Next() = 0; truelight@9579: truelight@9579: /** truelight@9579: * See if there is a next item of the sorter. truelight@9579: */ truelight@9579: virtual bool HasNext() = 0; truelight@9579: }; truelight@9579: truelight@9579: /** truelight@9579: * Sort by value, ascending. truelight@9579: */ truelight@9593: class AIAbstractListSorterValueAscending : public AIAbstractListSorter { truelight@9579: private: truelight@9593: AIAbstractList::AIAbstractListBucket::iterator bucket_iter; truelight@9593: AIAbstractList::AIItemList *bucket_list; truelight@9593: AIAbstractList::AIItemList::iterator bucket_list_iter; truelight@9579: truelight@9579: public: truelight@9593: AIAbstractListSorterValueAscending(AIAbstractList *list) truelight@9579: { truelight@9579: this->list = list; truebrain@9752: this->bucket_list = NULL; truelight@9579: } truelight@9579: truelight@9579: int32 Begin() truelight@9579: { truelight@9606: if (this->list->buckets.empty()) return 0; truelight@9606: truelight@9579: this->bucket_iter = this->list->buckets.begin(); truelight@9579: this->bucket_list = &(*this->bucket_iter).second; truelight@9579: this->bucket_list_iter = this->bucket_list->begin(); truelight@9579: return *bucket_list_iter; truelight@9579: } truelight@9579: truelight@9579: int32 Next() truelight@9579: { truebrain@9752: if (this->list->buckets.empty() || this->bucket_list == NULL) return 0; truelight@9606: truelight@9579: this->bucket_list_iter++; truelight@9579: if (this->bucket_list_iter == this->bucket_list->end()) { truelight@9579: this->bucket_iter++; truelight@9579: if (this->bucket_iter == this->list->buckets.end()) return 0; truelight@9579: this->bucket_list = &(*this->bucket_iter).second; truelight@9579: this->bucket_list_iter = this->bucket_list->begin(); truelight@9579: } truelight@9579: return *bucket_list_iter; truelight@9579: } truelight@9579: truelight@9579: bool HasNext() truelight@9579: { truebrain@9752: if (this->list->buckets.empty() || this->bucket_list == NULL) return false; truelight@9606: truelight@9579: return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end(); truelight@9579: } truelight@9579: }; truelight@9579: truelight@9579: /** truelight@9579: * Sort by value, descending. truelight@9579: */ truelight@9593: class AIAbstractListSorterValueDescending : public AIAbstractListSorter { truelight@9579: private: truelight@9593: AIAbstractList::AIAbstractListBucket::reverse_iterator bucket_iter; truelight@9593: AIAbstractList::AIItemList *bucket_list; truelight@9593: AIAbstractList::AIItemList::reverse_iterator bucket_list_iter; truelight@9579: truelight@9579: public: truelight@9593: AIAbstractListSorterValueDescending(AIAbstractList *list) truelight@9579: { truelight@9579: this->list = list; truebrain@9752: this->bucket_list = NULL; truelight@9579: } truelight@9579: truelight@9579: int32 Begin() truelight@9579: { truelight@9606: if (this->list->buckets.empty()) return 0; truelight@9606: truelight@9579: this->bucket_iter = this->list->buckets.rbegin(); truelight@9579: this->bucket_list = &(*this->bucket_iter).second; truelight@9579: this->bucket_list_iter = this->bucket_list->rbegin(); truelight@9579: return *bucket_list_iter; truelight@9579: } truelight@9579: truelight@9579: int32 Next() truelight@9579: { truebrain@9752: if (this->list->buckets.empty() || this->bucket_list == NULL) return 0; truelight@9606: truelight@9579: this->bucket_list_iter++; truelight@9579: if (this->bucket_list_iter == this->bucket_list->rend()) { truelight@9579: this->bucket_iter++; truelight@9579: if (this->bucket_iter == this->list->buckets.rend()) return 0; truelight@9579: this->bucket_list = &(*this->bucket_iter).second; truelight@9579: this->bucket_list_iter = this->bucket_list->rbegin(); truelight@9579: } truelight@9579: return *bucket_list_iter; truelight@9579: } truelight@9579: truelight@9579: bool HasNext() truelight@9579: { truebrain@9752: if (this->list->buckets.empty() || this->bucket_list == NULL) return false; truelight@9606: truelight@9579: return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend(); truelight@9579: } truelight@9579: }; truelight@9579: truelight@9579: /** truelight@9579: * Sort by item, ascending. truelight@9579: */ truelight@9593: class AIAbstractListSorterItemAscending : public AIAbstractListSorter { truelight@9579: private: truelight@9593: AIAbstractList::AIAbstractListMap::iterator item_iter; truelight@9579: truelight@9579: public: truelight@9593: AIAbstractListSorterItemAscending(AIAbstractList *list) truelight@9579: { truelight@9579: this->list = list; truelight@9579: } truelight@9579: truelight@9579: int32 Begin() truelight@9579: { truelight@9606: if (this->list->items.empty()) return 0; truelight@9606: truelight@9579: this->item_iter = this->list->items.begin(); truelight@9579: return (*this->item_iter).first; truelight@9579: } truelight@9579: truelight@9579: int32 Next() truelight@9579: { truelight@9606: if (this->list->items.empty()) return 0; truelight@9606: truelight@9579: this->item_iter++; truelight@9579: return (*this->item_iter).first; truelight@9579: } truelight@9579: truelight@9579: bool HasNext() truelight@9579: { truelight@9606: if (this->list->items.empty()) return false; truelight@9606: truelight@9579: return this->item_iter != this->list->items.end(); truelight@9579: } truelight@9579: }; truelight@9579: truelight@9579: /** truelight@9579: * Sort by item, descending. truelight@9579: */ truelight@9593: class AIAbstractListSorterItemDescending : public AIAbstractListSorter { truelight@9579: private: truelight@9593: AIAbstractList::AIAbstractListMap::reverse_iterator item_iter; truelight@9579: truelight@9579: public: truelight@9593: AIAbstractListSorterItemDescending(AIAbstractList *list) truelight@9579: { truelight@9579: this->list = list; truelight@9579: } truelight@9579: truelight@9579: int32 Begin() truelight@9579: { truelight@9606: if (this->list->items.empty()) return 0; truelight@9606: truelight@9579: this->item_iter = this->list->items.rbegin(); truelight@9579: return (*this->item_iter).first; truelight@9579: } truelight@9579: truelight@9579: int32 Next() truelight@9579: { truelight@9606: if (this->list->items.empty()) return 0; truelight@9606: truelight@9579: this->item_iter++; truelight@9579: return (*this->item_iter).first; truelight@9579: } truelight@9579: truelight@9579: bool HasNext() truelight@9579: { truelight@9606: if (this->list->items.empty()) return false; truelight@9606: truelight@9579: return this->item_iter != this->list->items.rend(); truelight@9579: } truelight@9579: }; truelight@9579: truelight@9579: truelight@9579: truelight@9593: AIAbstractList::AIAbstractList() truelight@9579: { truelight@9579: /* Default sorter */ rubidium@9665: this->sorter = new AIAbstractListSorterValueDescending(this); rubidium@9665: this->sorter_type = SORT_BY_VALUE; rubidium@9665: this->sort_ascending = false; truebrain@9752: this->initialized = false; truelight@9579: } truelight@9579: truelight@9593: AIAbstractList::~AIAbstractList() truelight@9579: { truelight@9579: delete this->sorter; truelight@9579: } truelight@9579: truelight@9593: bool AIAbstractList::HasItem(int32 item) truelight@9579: { truelight@9579: return this->items.count(item) == 1; truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::Clear() truelight@9579: { truelight@9579: this->items.clear(); truelight@9579: this->buckets.clear(); truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::AddItem(int32 item) truelight@9579: { truelight@9579: if (this->HasItem(item)) return; truelight@9579: truelight@9579: this->items[item] = 0; truelight@9579: this->buckets[0].insert(item); truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::RemoveItem(int32 item) truelight@9579: { truelight@9579: if (!this->HasItem(item)) return; truelight@9579: truelight@9579: this->buckets[this->GetValue(item)].erase(item); truelight@9664: if (this->buckets[this->GetValue(item)].empty()) this->buckets.erase(this->GetValue(item)); truelight@9579: this->items.erase(item); truelight@9579: } truelight@9579: truelight@9593: int32 AIAbstractList::Begin() truelight@9579: { truebrain@9752: this->initialized = true; truelight@9579: return this->sorter->Begin(); truelight@9579: } truelight@9579: truelight@9593: int32 AIAbstractList::Next() truelight@9579: { truebrain@9752: if (this->initialized == false) { truebrain@9755: DEBUG(ai, 0, "ERROR: Next() is invalid as Begin() is never called"); truebrain@9752: return false; truebrain@9752: } truelight@9579: return this->sorter->Next(); truelight@9579: } truelight@9579: truelight@9593: bool AIAbstractList::IsEmpty() truelight@9579: { truelight@9579: return this->items.empty(); truelight@9579: } truelight@9579: truelight@9593: bool AIAbstractList::HasNext() truelight@9579: { truebrain@9752: if (this->initialized == false) { truebrain@9752: DEBUG(ai, 0, "ERROR: HasNext() is invalid as Begin() is never called"); truebrain@9752: return false; truebrain@9752: } truelight@9579: return this->sorter->HasNext(); truelight@9579: } truelight@9579: truelight@9593: int32 AIAbstractList::Count() truelight@9579: { truelight@9579: return this->items.size(); truelight@9579: } truelight@9579: truelight@9593: int32 AIAbstractList::GetValue(int32 item) truelight@9579: { truelight@9579: if (!this->HasItem(item)) return 0; truelight@9579: truelight@9579: return this->items[item]; truelight@9579: } truelight@9579: truelight@9664: bool AIAbstractList::SetValue(int32 item, int32 value) truelight@9664: { truelight@9664: if (!this->HasItem(item)) return false; truelight@9664: truelight@9664: this->buckets[this->GetValue(item)].erase(item); truelight@9664: if (this->buckets[this->GetValue(item)].empty()) this->buckets.erase(this->GetValue(item)); truelight@9664: this->items[item] = value; truelight@9664: this->buckets[value].insert(item); truelight@9664: truelight@9664: return true; truelight@9664: } truelight@9664: rubidium@9665: void AIAbstractList::Sort(SorterType sorter, bool ascending) truelight@9579: { rubidium@9665: if (sorter == this->sorter_type && ascending == this->sort_ascending) return; rubidium@9665: truelight@9579: delete this->sorter; rubidium@9665: switch (sorter) { rubidium@9665: case SORT_BY_ITEM: rubidium@9665: if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this); rubidium@9665: else this->sorter = new AIAbstractListSorterItemDescending(this); rubidium@9665: break; truelight@9579: rubidium@9665: case SORT_BY_VALUE: rubidium@9702: if (ascending) this->sorter = new AIAbstractListSorterValueAscending(this); rubidium@9702: else this->sorter = new AIAbstractListSorterValueDescending(this); rubidium@9665: break; rubidium@9665: rubidium@9665: default: rubidium@9665: this->Sort(SORT_BY_ITEM, false); rubidium@9665: return; rubidium@9665: } rubidium@9665: this->sorter_type = sorter; rubidium@9665: this->sort_ascending = ascending; truelight@9579: } truelight@9579: truebrain@9796: void AIAbstractList::AddList(AIAbstractList *list) truebrain@9796: { truebrain@9796: AIAbstractListMap *list_items = &list->items; truebrain@9796: for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) { truebrain@9796: this->AddItem((*iter).first); truebrain@9796: this->SetValue((*iter).first, (*iter).second); truebrain@9796: } truebrain@9796: } truebrain@9796: truelight@9593: void AIAbstractList::RemoveAboveValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second > value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first > value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::RemoveBelowValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second < value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first < value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::RemoveBetweenValue(int32 start, int32 end) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second > start && (*iter).second < end) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::RemoveValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second == value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first == value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: rubidium@9665: void AIAbstractList::RemoveTop(int32 count) rubidium@9665: { rubidium@9665: if (!this->sort_ascending) { rubidium@9665: this->Sort(this->sorter_type, !this->sort_ascending); rubidium@9665: this->RemoveBottom(count); rubidium@9665: this->Sort(this->sorter_type, !this->sort_ascending); rubidium@9665: return; rubidium@9665: } rubidium@9665: rubidium@9665: switch (this->sorter_type) { rubidium@9665: default: NOT_REACHED(); rubidium@9665: case SORT_BY_VALUE: glx@9731: for (AIAbstractListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter = this->buckets.begin()) { rubidium@9665: AIItemList *items = &(*iter).second; glx@9731: size_t size = items->size(); glx@9731: for (AIItemList::iterator iter = items->begin(); iter != items->end(); iter = items->begin()) { rubidium@9665: if (--count < 0) return; rubidium@9665: this->RemoveItem(*iter); glx@9731: /* When the last item is removed from the bucket, the bucket itself is removed. glx@9731: * This means that the iterators can be invalid after a call to RemoveItem. glx@9731: */ glx@9731: if (--size == 0) break; rubidium@9665: } rubidium@9665: } rubidium@9665: break; rubidium@9665: rubidium@9665: case SORT_BY_ITEM: glx@9731: for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter = this->items.begin()) { rubidium@9665: if (--count < 0) return; rubidium@9665: this->RemoveItem((*iter).first); rubidium@9665: } rubidium@9665: break; rubidium@9665: } rubidium@9665: } rubidium@9665: rubidium@9665: void AIAbstractList::RemoveBottom(int32 count) rubidium@9665: { rubidium@9665: if (!this->sort_ascending) { rubidium@9665: this->Sort(this->sorter_type, !this->sort_ascending); rubidium@9665: this->RemoveTop(count); rubidium@9665: this->Sort(this->sorter_type, !this->sort_ascending); rubidium@9665: return; rubidium@9665: } rubidium@9665: rubidium@9665: switch (this->sorter_type) { rubidium@9665: default: NOT_REACHED(); rubidium@9665: case SORT_BY_VALUE: glx@9731: for (AIAbstractListBucket::reverse_iterator iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = this->buckets.rbegin()) { rubidium@9665: AIItemList *items = &(*iter).second; glx@9731: size_t size = items->size(); glx@9731: for (AIItemList::reverse_iterator iter = items->rbegin(); iter != items->rend(); iter = items->rbegin()) { rubidium@9665: if (--count < 0) return; glx@9731: this->RemoveItem(*iter); glx@9731: /* When the last item is removed from the bucket, the bucket itself is removed. glx@9731: * This means that the iterators can be invalid after a call to RemoveItem. rubidium@9721: */ glx@9731: if (--size == 0) break; rubidium@9665: } rubidium@9665: } rubidium@9665: rubidium@9665: case SORT_BY_ITEM: glx@9731: for (AIAbstractListMap::reverse_iterator iter = this->items.rbegin(); iter != this->items.rend(); iter = this->items.rbegin()) { rubidium@9665: if (--count < 0) return; rubidium@9665: this->RemoveItem((*iter).first); rubidium@9665: } rubidium@9665: break; rubidium@9665: } rubidium@9665: } rubidium@9665: rubidium@9665: void AIAbstractList::RemoveList(AIAbstractList *list) rubidium@9665: { rubidium@9665: AIAbstractListMap *list_items = &list->items; rubidium@9665: for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) { rubidium@9665: this->RemoveItem((*iter).first); rubidium@9665: } rubidium@9665: } rubidium@9665: truelight@9593: void AIAbstractList::KeepAboveValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second <= value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first <= value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::KeepBelowValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second >= value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first >= value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::KeepBetweenValue(int32 start, int32 end) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: truelight@9593: void AIAbstractList::KeepValue(int32 value) truelight@9579: { truelight@9593: for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).second != value) this->items.erase(iter); truelight@9579: } truelight@9579: truelight@9593: for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) { truelight@9581: next_iter = iter; next_iter++; truelight@9579: if ((*iter).first != value) this->buckets.erase(iter); truelight@9579: } truelight@9579: } truelight@9579: rubidium@9665: void AIAbstractList::KeepTop(int32 count) rubidium@9665: { rubidium@9665: this->RemoveBottom(this->Count() - count); rubidium@9665: } rubidium@9665: rubidium@9665: void AIAbstractList::KeepBottom(int32 count) rubidium@9665: { rubidium@9665: this->RemoveTop(this->Count() - count); rubidium@9665: } rubidium@9665: rubidium@9665: void AIAbstractList::KeepList(AIAbstractList *list) rubidium@9665: { rubidium@9665: AIAbstractList tmp; rubidium@9665: for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { rubidium@9665: tmp.AddItem((*iter).first); rubidium@9665: tmp.SetValue((*iter).first, (*iter).second); rubidium@9665: } rubidium@9665: rubidium@9665: tmp.RemoveList(list); rubidium@9665: this->RemoveList(&tmp); rubidium@9665: } rubidium@9665: truebrain@9814: SQInteger AIAbstractList::Valuate(HSQUIRRELVM vm) { truebrain@9814: int nparam = sq_gettop(vm) - 2; truebrain@9814: truebrain@9814: /* Get the list instance and the function to call */ truebrain@9814: HSQOBJECT obj_list, obj_func; truebrain@9814: sq_getstackobj(vm, 1, &obj_list); truebrain@9814: sq_getstackobj(vm, 2, &obj_func); truebrain@9814: truebrain@9814: /* Read the params */ truebrain@9814: HSQOBJECT obj_params[10]; truebrain@9814: assert(nparam < 10); truebrain@9814: for (int i = 0; i < nparam; i++) { truebrain@9814: sq_getstackobj(vm, i + 3, &obj_params[i]); truebrain@9772: } truebrain@9814: /* Remove all unneeded stuff */ truebrain@9814: sq_pop(vm, nparam + 1); truebrain@9772: truebrain@9814: /* Walk all items, and query the result */ truelight@9579: this->buckets.clear(); truelight@9593: for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { truebrain@9814: /* The function to call */ truebrain@9814: sq_pushobject(vm, obj_func); truebrain@9814: /* The 'list' instance; this is most likely wrong, but we need to send something ;) */ truebrain@9814: sq_pushobject(vm, obj_list); truebrain@9814: truebrain@9814: /* Now send the params */ truebrain@9814: sq_pushinteger(vm, (*iter).first); truebrain@9814: for (int i = 0; i < nparam; i++) { truebrain@9814: sq_pushobject(vm, obj_params[i]); truebrain@9814: } truebrain@9814: truebrain@9814: /* Call the function */ truebrain@9814: if (SQ_FAILED(sq_call(vm, nparam + 2, SQTrue, SQTrue))) return -1; truebrain@9814: truebrain@9814: /* Retreive the return value */ truebrain@9814: SQInteger value; truebrain@9814: switch (sq_gettype(vm, -1)) { truebrain@9814: case OT_INTEGER: { truebrain@9814: sq_getinteger(vm, -1, &value); truebrain@9814: } break; truebrain@9814: truebrain@9814: case OT_BOOL: { truebrain@9814: SQBool v; truebrain@9814: sq_getbool(vm, -1, &v); truebrain@9814: value = v ? 1 : 0; truebrain@9814: } break; truebrain@9814: truebrain@9814: default: { glx@9819: sq_throwerror(vm, _SC("return value of valuator is not valid (not integer/bool)")); truebrain@9814: return -1; truebrain@9814: } truebrain@9814: } truebrain@9814: /* Remove junk */ truebrain@9814: sq_pop(vm, 2); truebrain@9814: truelight@9579: (*iter).second = value; truelight@9579: this->buckets[value].insert((*iter).first); truelight@9579: } truebrain@9814: truebrain@9814: return 0; truelight@9579: }