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