diff --git a/src/script/api/script_list.hpp b/src/script/api/script_list.hpp index 8d227ed938..c89766b8c3 100644 --- a/src/script/api/script_list.hpp +++ b/src/script/api/script_list.hpp @@ -59,35 +59,66 @@ private: ScriptListMap::iterator RemoveIter(ScriptListMap::iterator item_iter); ScriptListValueSet::iterator RemoveValueIter(ScriptListValueSet::iterator value_iter); + template + struct FillListHelper { + using IterType = T; + + auto Iterate() + { + return T::Iterate(); + } + + int OpcodeCharge([[maybe_unused]] int item_count) + { + return (int)(T::GetNumItems() / 2); + } + }; + protected: - template - static void FillList(ScriptList *list, ItemValid item_valid, ItemFilter item_filter) + template + static void FillList(Targs... args) { + FillListT>(FillListHelper{}, args...); + } + + template + static void FillListT(Thelper helper, ScriptList *list, ItemValid item_valid, ItemFilter item_filter) + { + using IterType = typename Thelper::IterType; + int opcode_charge = 0; - for (const T *item : T::Iterate()) { + int item_count = 0; + for (const IterType *item : helper.Iterate()) { + item_count++; if (!item_valid(item)) continue; if (!item_filter(item)) continue; list->AddItem(item->index); opcode_charge += 3; } - ScriptController::DecreaseOps(opcode_charge + (int)(T::GetNumItems() / 2)); + ScriptController::DecreaseOps(opcode_charge + helper.OpcodeCharge(item_count)); } - template - static void FillList(ScriptList *list, ItemValid item_valid) + template + static void FillListT(Thelper helper, ScriptList *list, ItemValid item_valid) { - ScriptList::FillList(list, item_valid, [](const T *) { return true; }); + using IterType = typename Thelper::IterType; + + ScriptList::FillListT(helper, list, item_valid, [](const IterType *) { return true; }); } - template - static void FillList(ScriptList *list) + template + static void FillListT(Thelper helper, ScriptList *list) { - ScriptList::FillList(list, [](const T *) { return true; }); + using IterType = typename Thelper::IterType; + + ScriptList::FillListT(list, [](const IterType *) { return true; }); } - template - static void FillList(HSQUIRRELVM vm, ScriptList *list, ItemValid item_valid) + template + static void FillListT(Thelper helper, HSQUIRRELVM vm, ScriptList *list, ItemValid item_valid) { + using IterType = typename Thelper::IterType; + int nparam = sq_gettop(vm) - 1; if (nparam >= 1) { /* Make sure the filter function is really a function, and not any @@ -109,13 +140,13 @@ protected: if (nparam < 1) { - ScriptList::FillList(list, item_valid); + ScriptList::FillListT(helper, list, item_valid); } else { /* Limit the total number of ops that can be consumed by a filter operation, if a filter function is present */ SQOpsLimiter limiter(vm, MAX_VALUATE_OPS, "list filter function"); - ScriptList::FillList(list, item_valid, - [vm, nparam, backup_allow](const T *item) { + ScriptList::FillListT(helper, list, item_valid, + [vm, nparam, backup_allow](const IterType *item) { /* Push the root table as instance object, this is what squirrel does for meta-functions. */ sq_pushroottable(vm); /* Push all arguments for the valuator function. */ @@ -157,10 +188,12 @@ protected: ScriptObject::SetAllowDoCommand(backup_allow); } - template - static void FillList(HSQUIRRELVM vm, ScriptList *list) + template + static void FillListT(Thelper helper, HSQUIRRELVM vm, ScriptList *list) { - ScriptList::FillList(vm, list, [](const T *) { return true; }); + using IterType = typename Thelper::IterType; + + ScriptList::FillListT(helper, vm, list, [](const IterType *) { return true; }); } public: