Merge branch 'master' into jgrpp
Bump savegame for water regions for ship pathfinder Use ring_buffer for ShipPathCache
This commit is contained in:
@@ -58,6 +58,107 @@ private:
|
||||
ScriptListMap::iterator RemoveIter(ScriptListMap::iterator item_iter);
|
||||
ScriptListValueSet::iterator RemoveValueIter(ScriptListValueSet::iterator value_iter);
|
||||
|
||||
protected:
|
||||
template<typename T, class ItemValid, class ItemFilter>
|
||||
static void FillList(ScriptList *list, ItemValid item_valid, ItemFilter item_filter)
|
||||
{
|
||||
for (const T *item : T::Iterate()) {
|
||||
if (!item_valid(item)) continue;
|
||||
if (!item_filter(item)) continue;
|
||||
list->AddItem(item->index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, class ItemValid>
|
||||
static void FillList(ScriptList *list, ItemValid item_valid)
|
||||
{
|
||||
ScriptList::FillList<T>(list, item_valid, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void FillList(ScriptList *list)
|
||||
{
|
||||
ScriptList::FillList<T>(list, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
template<typename T, class ItemValid>
|
||||
static void FillList(HSQUIRRELVM vm, ScriptList *list, ItemValid item_valid)
|
||||
{
|
||||
int nparam = sq_gettop(vm) - 1;
|
||||
if (nparam >= 1) {
|
||||
/* Make sure the filter function is really a function, and not any
|
||||
* other type. It's parameter 2 for us, but for the user it's the
|
||||
* first parameter they give. */
|
||||
SQObjectType valuator_type = sq_gettype(vm, 2);
|
||||
if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) {
|
||||
throw sq_throwerror(vm, "parameter 1 has an invalid type (expected function)");
|
||||
}
|
||||
|
||||
/* Push the function to call */
|
||||
sq_push(vm, 2);
|
||||
}
|
||||
|
||||
/* Don't allow docommand from a Valuator, as we can't resume in
|
||||
* mid C++-code. */
|
||||
bool backup_allow = ScriptObject::GetAllowDoCommand();
|
||||
ScriptObject::SetAllowDoCommand(false);
|
||||
|
||||
|
||||
if (nparam < 1) {
|
||||
ScriptList::FillList<T>(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<T>(list, item_valid,
|
||||
[vm, nparam, backup_allow](const T *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. */
|
||||
sq_pushinteger(vm, item->index);
|
||||
for (int i = 0; i < nparam - 1; i++) {
|
||||
sq_push(vm, i + 3);
|
||||
}
|
||||
|
||||
/* Call the function. Squirrel pops all parameters and pushes the return value. */
|
||||
if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) {
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "failed to run filter");
|
||||
}
|
||||
|
||||
SQBool add = SQFalse;
|
||||
|
||||
/* Retrieve the return value */
|
||||
switch (sq_gettype(vm, -1)) {
|
||||
case OT_BOOL:
|
||||
sq_getbool(vm, -1, &add);
|
||||
break;
|
||||
|
||||
default:
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "return value of filter is not valid (not bool)");
|
||||
}
|
||||
|
||||
/* Pop the return value. */
|
||||
sq_poptop(vm);
|
||||
|
||||
return add;
|
||||
}
|
||||
);
|
||||
|
||||
/* Pop the filter function */
|
||||
sq_poptop(vm);
|
||||
}
|
||||
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void FillList(HSQUIRRELVM vm, ScriptList *list)
|
||||
{
|
||||
ScriptList::FillList<T>(vm, list, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
public:
|
||||
ScriptListMap items; ///< The items in the list
|
||||
ScriptListValueSet values; ///< The items in the list, sorted by value
|
||||
|
Reference in New Issue
Block a user