00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "ai_abstractlist.hpp"
00013 #include "../../debug.h"
00014 #include "../../script/squirrel.hpp"
00015
00019 class AIAbstractListSorter {
00020 protected:
00021 AIAbstractList *list;
00022
00023 public:
00027 virtual ~AIAbstractListSorter() { }
00028
00032 virtual int32 Begin() = 0;
00033
00037 virtual void End() = 0;
00038
00042 virtual int32 Next() = 0;
00043
00047 virtual bool HasNext() = 0;
00048
00052 virtual void Remove(int item) = 0;
00053 };
00054
00058 class AIAbstractListSorterValueAscending : public AIAbstractListSorter {
00059 private:
00060 AIAbstractList::AIAbstractListBucket::iterator bucket_iter;
00061 AIAbstractList::AIItemList *bucket_list;
00062 AIAbstractList::AIItemList::iterator bucket_list_iter;
00063 bool has_no_more_items;
00064 int32 item_next;
00065
00066 public:
00067 AIAbstractListSorterValueAscending(AIAbstractList *list)
00068 {
00069 this->list = list;
00070 this->End();
00071 }
00072
00073 int32 Begin()
00074 {
00075 if (this->list->buckets.empty()) return 0;
00076 this->has_no_more_items = false;
00077
00078 this->bucket_iter = this->list->buckets.begin();
00079 this->bucket_list = &(*this->bucket_iter).second;
00080 this->bucket_list_iter = this->bucket_list->begin();
00081 this->item_next = *this->bucket_list_iter;
00082
00083 int32 item_current = this->item_next;
00084 FindNext();
00085 return item_current;
00086 }
00087
00088 void End()
00089 {
00090 this->bucket_list = NULL;
00091 this->has_no_more_items = true;
00092 this->item_next = 0;
00093 }
00094
00095 void FindNext()
00096 {
00097 if (this->bucket_list == NULL) {
00098 this->has_no_more_items = true;
00099 return;
00100 }
00101
00102 this->bucket_list_iter++;
00103 if (this->bucket_list_iter == this->bucket_list->end()) {
00104 this->bucket_iter++;
00105 if (this->bucket_iter == this->list->buckets.end()) {
00106 this->bucket_list = NULL;
00107 return;
00108 }
00109 this->bucket_list = &(*this->bucket_iter).second;
00110 this->bucket_list_iter = this->bucket_list->begin();
00111 }
00112 this->item_next = *this->bucket_list_iter;
00113 }
00114
00115 int32 Next()
00116 {
00117 if (!this->HasNext()) return 0;
00118
00119 int32 item_current = this->item_next;
00120 FindNext();
00121 return item_current;
00122 }
00123
00124 void Remove(int item)
00125 {
00126 if (!this->HasNext()) return;
00127
00128
00129 if (item == this->item_next) {
00130 FindNext();
00131 return;
00132 }
00133 }
00134
00135 bool HasNext()
00136 {
00137 return !(this->list->buckets.empty() || this->has_no_more_items);
00138 }
00139 };
00140
00144 class AIAbstractListSorterValueDescending : public AIAbstractListSorter {
00145 private:
00146 AIAbstractList::AIAbstractListBucket::iterator bucket_iter;
00147 AIAbstractList::AIItemList *bucket_list;
00148 AIAbstractList::AIItemList::iterator bucket_list_iter;
00149 bool has_no_more_items;
00150 int32 item_next;
00151
00152 public:
00153 AIAbstractListSorterValueDescending(AIAbstractList *list)
00154 {
00155 this->list = list;
00156 this->End();
00157 }
00158
00159 int32 Begin()
00160 {
00161 if (this->list->buckets.empty()) return 0;
00162 this->has_no_more_items = false;
00163
00164
00165 this->bucket_iter = this->list->buckets.begin();
00166 for (size_t i = this->list->buckets.size(); i > 1; i--) this->bucket_iter++;
00167 this->bucket_list = &(*this->bucket_iter).second;
00168
00169
00170 this->bucket_list_iter = this->bucket_list->begin();
00171 for (size_t i = this->bucket_list->size(); i > 1; i--) this->bucket_list_iter++;
00172 this->item_next = *this->bucket_list_iter;
00173
00174 int32 item_current = this->item_next;
00175 FindNext();
00176 return item_current;
00177 }
00178
00179 void End()
00180 {
00181 this->bucket_list = NULL;
00182 this->has_no_more_items = true;
00183 this->item_next = 0;
00184 }
00185
00186 void FindNext()
00187 {
00188 if (this->bucket_list == NULL) {
00189 this->has_no_more_items = true;
00190 return;
00191 }
00192
00193 if (this->bucket_list_iter == this->bucket_list->begin()) {
00194 if (this->bucket_iter == this->list->buckets.begin()) {
00195 this->bucket_list = NULL;
00196 return;
00197 }
00198 this->bucket_iter--;
00199 this->bucket_list = &(*this->bucket_iter).second;
00200
00201 this->bucket_list_iter = this->bucket_list->begin();
00202 for (size_t i = this->bucket_list->size(); i > 1; i--) this->bucket_list_iter++;
00203 } else {
00204 this->bucket_list_iter--;
00205 }
00206 this->item_next = *this->bucket_list_iter;
00207 }
00208
00209 int32 Next()
00210 {
00211 if (!this->HasNext()) return 0;
00212
00213 int32 item_current = this->item_next;
00214 FindNext();
00215 return item_current;
00216 }
00217
00218 void Remove(int item)
00219 {
00220 if (!this->HasNext()) return;
00221
00222
00223 if (item == this->item_next) {
00224 FindNext();
00225 return;
00226 }
00227 }
00228
00229 bool HasNext()
00230 {
00231 return !(this->list->buckets.empty() || this->has_no_more_items);
00232 }
00233 };
00234
00238 class AIAbstractListSorterItemAscending : public AIAbstractListSorter {
00239 private:
00240 AIAbstractList::AIAbstractListMap::iterator item_iter;
00241 bool has_no_more_items;
00242 int32 item_next;
00243
00244 public:
00245 AIAbstractListSorterItemAscending(AIAbstractList *list)
00246 {
00247 this->list = list;
00248 this->End();
00249 }
00250
00251 int32 Begin()
00252 {
00253 if (this->list->items.empty()) return 0;
00254 this->has_no_more_items = false;
00255
00256 this->item_iter = this->list->items.begin();
00257 this->item_next = (*this->item_iter).first;
00258
00259 int32 item_current = this->item_next;
00260 FindNext();
00261 return item_current;
00262 }
00263
00264 void End()
00265 {
00266 this->has_no_more_items = true;
00267 }
00268
00269 void FindNext()
00270 {
00271 if (this->item_iter == this->list->items.end()) {
00272 this->has_no_more_items = true;
00273 return;
00274 }
00275 this->item_iter++;
00276 if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
00277 }
00278
00279 int32 Next()
00280 {
00281 if (!this->HasNext()) return 0;
00282
00283 int32 item_current = this->item_next;
00284 FindNext();
00285 return item_current;
00286 }
00287
00288 void Remove(int item)
00289 {
00290 if (!this->HasNext()) return;
00291
00292
00293 if (item == this->item_next) {
00294 FindNext();
00295 return;
00296 }
00297 }
00298
00299 bool HasNext()
00300 {
00301 return !(this->list->items.empty() || this->has_no_more_items);
00302 }
00303 };
00304
00308 class AIAbstractListSorterItemDescending : public AIAbstractListSorter {
00309 private:
00310 AIAbstractList::AIAbstractListMap::iterator item_iter;
00311 bool has_no_more_items;
00312 int32 item_next;
00313
00314 public:
00315 AIAbstractListSorterItemDescending(AIAbstractList *list)
00316 {
00317 this->list = list;
00318 this->End();
00319 }
00320
00321 int32 Begin()
00322 {
00323 if (this->list->items.empty()) return 0;
00324 this->has_no_more_items = false;
00325
00326 this->item_iter = this->list->items.begin();
00327 for (size_t i = this->list->items.size(); i > 1; i--) this->item_iter++;
00328 this->item_next = (*this->item_iter).first;
00329
00330 int32 item_current = this->item_next;
00331 FindNext();
00332 return item_current;
00333 }
00334
00335 void End()
00336 {
00337 this->has_no_more_items = true;
00338 }
00339
00340 void FindNext()
00341 {
00342 if (this->item_iter == this->list->items.end()) {
00343 this->has_no_more_items = true;
00344 return;
00345 }
00346 this->item_iter--;
00347 if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
00348 }
00349
00350 int32 Next()
00351 {
00352 if (!this->HasNext()) return 0;
00353
00354 int32 item_current = this->item_next;
00355 FindNext();
00356 return item_current;
00357 }
00358
00359 void Remove(int item)
00360 {
00361 if (!this->HasNext()) return;
00362
00363
00364 if (item == this->item_next) {
00365 FindNext();
00366 return;
00367 }
00368 }
00369
00370 bool HasNext()
00371 {
00372 return !(this->list->items.empty() || this->has_no_more_items);
00373 }
00374 };
00375
00376
00377
00378 AIAbstractList::AIAbstractList()
00379 {
00380
00381 this->sorter = new AIAbstractListSorterValueDescending(this);
00382 this->sorter_type = SORT_BY_VALUE;
00383 this->sort_ascending = false;
00384 this->initialized = false;
00385 this->modifications = 0;
00386 }
00387
00388 AIAbstractList::~AIAbstractList()
00389 {
00390 delete this->sorter;
00391 }
00392
00393 bool AIAbstractList::HasItem(int32 item)
00394 {
00395 return this->items.count(item) == 1;
00396 }
00397
00398 void AIAbstractList::Clear()
00399 {
00400 this->modifications++;
00401
00402 this->items.clear();
00403 this->buckets.clear();
00404 this->sorter->End();
00405 }
00406
00407 void AIAbstractList::AddItem(int32 item)
00408 {
00409 this->modifications++;
00410
00411 if (this->HasItem(item)) return;
00412
00413 this->items[item] = 0;
00414 this->buckets[0].insert(item);
00415 }
00416
00417 void AIAbstractList::RemoveItem(int32 item)
00418 {
00419 this->modifications++;
00420
00421 if (!this->HasItem(item)) return;
00422
00423 int32 value = this->GetValue(item);
00424
00425 this->sorter->Remove(item);
00426 this->buckets[value].erase(item);
00427 if (this->buckets[value].empty()) this->buckets.erase(value);
00428 this->items.erase(item);
00429 }
00430
00431 int32 AIAbstractList::Begin()
00432 {
00433 this->initialized = true;
00434 return this->sorter->Begin();
00435 }
00436
00437 int32 AIAbstractList::Next()
00438 {
00439 if (this->initialized == false) {
00440 DEBUG(ai, 0, "ERROR: Next() is invalid as Begin() is never called");
00441 return false;
00442 }
00443 return this->sorter->Next();
00444 }
00445
00446 bool AIAbstractList::IsEmpty()
00447 {
00448 return this->items.empty();
00449 }
00450
00451 bool AIAbstractList::HasNext()
00452 {
00453 if (this->initialized == false) {
00454 DEBUG(ai, 0, "ERROR: HasNext() is invalid as Begin() is never called");
00455 return false;
00456 }
00457 return this->sorter->HasNext();
00458 }
00459
00460 int32 AIAbstractList::Count()
00461 {
00462 return (int32)this->items.size();
00463 }
00464
00465 int32 AIAbstractList::GetValue(int32 item)
00466 {
00467 if (!this->HasItem(item)) return 0;
00468
00469 return this->items[item];
00470 }
00471
00472 bool AIAbstractList::SetValue(int32 item, int32 value)
00473 {
00474 this->modifications++;
00475
00476 if (!this->HasItem(item)) return false;
00477
00478 int32 value_old = this->GetValue(item);
00479
00480 this->sorter->Remove(item);
00481 this->buckets[value_old].erase(item);
00482 if (this->buckets[value_old].empty()) this->buckets.erase(value_old);
00483 this->items[item] = value;
00484 this->buckets[value].insert(item);
00485
00486 return true;
00487 }
00488
00489 void AIAbstractList::Sort(SorterType sorter, bool ascending)
00490 {
00491 this->modifications++;
00492
00493 if (sorter != SORT_BY_VALUE && sorter != SORT_BY_ITEM) return;
00494 if (sorter == this->sorter_type && ascending == this->sort_ascending) return;
00495
00496 delete this->sorter;
00497 switch (sorter) {
00498 case SORT_BY_ITEM:
00499 if (ascending) {
00500 this->sorter = new AIAbstractListSorterItemAscending(this);
00501 } else {
00502 this->sorter = new AIAbstractListSorterItemDescending(this);
00503 }
00504 break;
00505
00506 case SORT_BY_VALUE:
00507 if (ascending) {
00508 this->sorter = new AIAbstractListSorterValueAscending(this);
00509 } else {
00510 this->sorter = new AIAbstractListSorterValueDescending(this);
00511 }
00512 break;
00513
00514 default:
00515 this->Sort(SORT_BY_ITEM, false);
00516 return;
00517 }
00518 this->sorter_type = sorter;
00519 this->sort_ascending = ascending;
00520 }
00521
00522 void AIAbstractList::AddList(AIAbstractList *list)
00523 {
00524 AIAbstractListMap *list_items = &list->items;
00525 for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
00526 this->AddItem((*iter).first);
00527 this->SetValue((*iter).first, (*iter).second);
00528 }
00529 }
00530
00531 void AIAbstractList::RemoveAboveValue(int32 value)
00532 {
00533 this->modifications++;
00534
00535 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00536 next_iter = iter; next_iter++;
00537 if ((*iter).second > value) this->items.erase(iter);
00538 }
00539
00540 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00541 next_iter = iter; next_iter++;
00542 if ((*iter).first > value) this->buckets.erase(iter);
00543 }
00544 }
00545
00546 void AIAbstractList::RemoveBelowValue(int32 value)
00547 {
00548 this->modifications++;
00549
00550 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00551 next_iter = iter; next_iter++;
00552 if ((*iter).second < value) this->items.erase(iter);
00553 }
00554
00555 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00556 next_iter = iter; next_iter++;
00557 if ((*iter).first < value) this->buckets.erase(iter);
00558 }
00559 }
00560
00561 void AIAbstractList::RemoveBetweenValue(int32 start, int32 end)
00562 {
00563 this->modifications++;
00564
00565 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00566 next_iter = iter; next_iter++;
00567 if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
00568 }
00569
00570 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00571 next_iter = iter; next_iter++;
00572 if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
00573 }
00574 }
00575
00576 void AIAbstractList::RemoveValue(int32 value)
00577 {
00578 this->modifications++;
00579
00580 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00581 next_iter = iter; next_iter++;
00582 if ((*iter).second == value) this->items.erase(iter);
00583 }
00584
00585 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00586 next_iter = iter; next_iter++;
00587 if ((*iter).first == value) this->buckets.erase(iter);
00588 }
00589 }
00590
00591 void AIAbstractList::RemoveTop(int32 count)
00592 {
00593 this->modifications++;
00594
00595 if (!this->sort_ascending) {
00596 this->Sort(this->sorter_type, !this->sort_ascending);
00597 this->RemoveBottom(count);
00598 this->Sort(this->sorter_type, !this->sort_ascending);
00599 return;
00600 }
00601
00602 switch (this->sorter_type) {
00603 default: NOT_REACHED();
00604 case SORT_BY_VALUE:
00605 for (AIAbstractListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter = this->buckets.begin()) {
00606 AIItemList *items = &(*iter).second;
00607 size_t size = items->size();
00608 for (AIItemList::iterator iter = items->begin(); iter != items->end(); iter = items->begin()) {
00609 if (--count < 0) return;
00610 this->RemoveItem(*iter);
00611
00612
00613
00614 if (--size == 0) break;
00615 }
00616 }
00617 break;
00618
00619 case SORT_BY_ITEM:
00620 for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter = this->items.begin()) {
00621 if (--count < 0) return;
00622 this->RemoveItem((*iter).first);
00623 }
00624 break;
00625 }
00626 }
00627
00628 void AIAbstractList::RemoveBottom(int32 count)
00629 {
00630 this->modifications++;
00631
00632 if (!this->sort_ascending) {
00633 this->Sort(this->sorter_type, !this->sort_ascending);
00634 this->RemoveTop(count);
00635 this->Sort(this->sorter_type, !this->sort_ascending);
00636 return;
00637 }
00638
00639 switch (this->sorter_type) {
00640 default: NOT_REACHED();
00641 case SORT_BY_VALUE:
00642 for (AIAbstractListBucket::reverse_iterator iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = this->buckets.rbegin()) {
00643 AIItemList *items = &(*iter).second;
00644 size_t size = items->size();
00645 for (AIItemList::reverse_iterator iter = items->rbegin(); iter != items->rend(); iter = items->rbegin()) {
00646 if (--count < 0) return;
00647 this->RemoveItem(*iter);
00648
00649
00650
00651 if (--size == 0) break;
00652 }
00653 }
00654
00655 case SORT_BY_ITEM:
00656 for (AIAbstractListMap::reverse_iterator iter = this->items.rbegin(); iter != this->items.rend(); iter = this->items.rbegin()) {
00657 if (--count < 0) return;
00658 this->RemoveItem((*iter).first);
00659 }
00660 break;
00661 }
00662 }
00663
00664 void AIAbstractList::RemoveList(AIAbstractList *list)
00665 {
00666 this->modifications++;
00667
00668 AIAbstractListMap *list_items = &list->items;
00669 for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
00670 this->RemoveItem((*iter).first);
00671 }
00672 }
00673
00674 void AIAbstractList::KeepAboveValue(int32 value)
00675 {
00676 this->modifications++;
00677
00678 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00679 next_iter = iter; next_iter++;
00680 if ((*iter).second <= value) this->items.erase(iter);
00681 }
00682
00683 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00684 next_iter = iter; next_iter++;
00685 if ((*iter).first <= value) this->buckets.erase(iter);
00686 }
00687 }
00688
00689 void AIAbstractList::KeepBelowValue(int32 value)
00690 {
00691 this->modifications++;
00692
00693 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00694 next_iter = iter; next_iter++;
00695 if ((*iter).second >= value) this->items.erase(iter);
00696 }
00697
00698 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00699 next_iter = iter; next_iter++;
00700 if ((*iter).first >= value) this->buckets.erase(iter);
00701 }
00702 }
00703
00704 void AIAbstractList::KeepBetweenValue(int32 start, int32 end)
00705 {
00706 this->modifications++;
00707
00708 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00709 next_iter = iter; next_iter++;
00710 if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
00711 }
00712
00713 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00714 next_iter = iter; next_iter++;
00715 if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
00716 }
00717 }
00718
00719 void AIAbstractList::KeepValue(int32 value)
00720 {
00721 this->modifications++;
00722
00723 for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
00724 next_iter = iter; next_iter++;
00725 if ((*iter).second != value) this->items.erase(iter);
00726 }
00727
00728 for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
00729 next_iter = iter; next_iter++;
00730 if ((*iter).first != value) this->buckets.erase(iter);
00731 }
00732 }
00733
00734 void AIAbstractList::KeepTop(int32 count)
00735 {
00736 this->modifications++;
00737
00738 this->RemoveBottom(this->Count() - count);
00739 }
00740
00741 void AIAbstractList::KeepBottom(int32 count)
00742 {
00743 this->modifications++;
00744
00745 this->RemoveTop(this->Count() - count);
00746 }
00747
00748 void AIAbstractList::KeepList(AIAbstractList *list)
00749 {
00750 this->modifications++;
00751
00752 AIAbstractList tmp;
00753 for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
00754 tmp.AddItem((*iter).first);
00755 tmp.SetValue((*iter).first, (*iter).second);
00756 }
00757
00758 tmp.RemoveList(list);
00759 this->RemoveList(&tmp);
00760 }
00761
00762 SQInteger AIAbstractList::_get(HSQUIRRELVM vm)
00763 {
00764 if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR;
00765
00766 SQInteger idx;
00767 sq_getinteger(vm, 2, &idx);
00768
00769 if (!this->HasItem(idx)) return SQ_ERROR;
00770
00771 sq_pushinteger(vm, this->GetValue(idx));
00772 return 1;
00773 }
00774
00775 SQInteger AIAbstractList::_nexti(HSQUIRRELVM vm)
00776 {
00777 if (sq_gettype(vm, 2) == OT_NULL) {
00778 if (this->IsEmpty()) {
00779 sq_pushnull(vm);
00780 return 1;
00781 }
00782 sq_pushinteger(vm, this->Begin());
00783 return 1;
00784 }
00785
00786 SQInteger idx;
00787 sq_getinteger(vm, 2, &idx);
00788
00789 int val = this->Next();
00790 if (!this->HasNext()) {
00791 sq_pushnull(vm);
00792 return 1;
00793 }
00794
00795 sq_pushinteger(vm, val);
00796 return 1;
00797 }
00798
00799 SQInteger AIAbstractList::Valuate(HSQUIRRELVM vm)
00800 {
00801 this->modifications++;
00802
00803
00804 int nparam = sq_gettop(vm) - 1;
00805
00806 if (nparam < 1) {
00807 return sq_throwerror(vm, _SC("You need to give a least a Valuator as parameter to AIAbstractList::Valuate"));
00808 }
00809
00810
00811
00812
00813 SQObjectType valuator_type = sq_gettype(vm, 2);
00814 if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) {
00815 return sq_throwerror(vm, _SC("parameter 1 has an invalid type (expected function)"));
00816 }
00817
00818
00819
00820 bool backup_allow = AIObject::GetAllowDoCommand();
00821 AIObject::SetAllowDoCommand(false);
00822
00823
00824 sq_push(vm, 2);
00825
00826
00827 this->buckets.clear();
00828
00829
00830 int begin_modification_count = this->modifications;
00831
00832 for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
00833
00834 sq_pushroottable(vm);
00835
00836 sq_pushinteger(vm, (*iter).first);
00837 for (int i = 0; i < nparam - 1; i++) {
00838 sq_push(vm, i + 3);
00839 }
00840
00841
00842 if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) {
00843 AIObject::SetAllowDoCommand(backup_allow);
00844 return SQ_ERROR;
00845 }
00846
00847
00848 SQInteger value;
00849 switch (sq_gettype(vm, -1)) {
00850 case OT_INTEGER: {
00851 sq_getinteger(vm, -1, &value);
00852 } break;
00853
00854 case OT_BOOL: {
00855 SQBool v;
00856 sq_getbool(vm, -1, &v);
00857 value = v ? 1 : 0;
00858 } break;
00859
00860 default: {
00861
00862 sq_pop(vm, nparam + 4);
00863
00864 AIObject::SetAllowDoCommand(backup_allow);
00865 return sq_throwerror(vm, _SC("return value of valuator is not valid (not integer/bool)"));
00866 }
00867 }
00868
00869
00870 if (begin_modification_count != this->modifications) {
00871
00872 sq_pop(vm, nparam + 4);
00873
00874 AIObject::SetAllowDoCommand(backup_allow);
00875 return sq_throwerror(vm, _SC("modifying valuated list outside of valuator function"));
00876 }
00877
00878 (*iter).second = (int32)value;
00879 this->buckets[(int32)value].insert((*iter).first);
00880
00881
00882 sq_poptop(vm);
00883
00884 Squirrel::DecreaseOps(vm, 5);
00885 }
00886
00887
00888
00889
00890
00891 sq_pop(vm, nparam + 3);
00892
00893 AIObject::SetAllowDoCommand(backup_allow);
00894 return 0;
00895 }