| 826 | } |
| 827 | |
| 828 | SQInteger ScriptList::Valuate(HSQUIRRELVM vm) |
| 829 | { |
| 830 | this->modifications++; |
| 831 | |
| 832 | /* The first parameter is the instance of ScriptList. */ |
| 833 | int nparam = sq_gettop(vm) - 1; |
| 834 | |
| 835 | if (nparam < 1) { |
| 836 | return sq_throwerror(vm, "You need to give at least a Valuator as parameter to ScriptList::Valuate"); |
| 837 | } |
| 838 | |
| 839 | /* Make sure the valuator function is really a function, and not any |
| 840 | * other type. It's parameter 2 for us, but for the user it's the |
| 841 | * first parameter they give. */ |
| 842 | SQObjectType valuator_type = sq_gettype(vm, 2); |
| 843 | if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) { |
| 844 | return sq_throwerror(vm, "parameter 1 has an invalid type (expected function)"); |
| 845 | } |
| 846 | |
| 847 | /* Don't allow docommand from a Valuator, as we can't resume in |
| 848 | * mid C++-code. */ |
| 849 | ScriptObject::DisableDoCommandScope disabler{}; |
| 850 | |
| 851 | /* Limit the total number of ops that can be consumed by a valuate operation */ |
| 852 | SQOpsLimiter limiter(vm, MAX_VALUATE_OPS, "valuator function"); |
| 853 | |
| 854 | /* Push the function to call */ |
| 855 | sq_push(vm, 2); |
| 856 | |
| 857 | for (const auto &item : this->items) { |
| 858 | /* Check for changing of items. */ |
| 859 | int previous_modification_count = this->modifications; |
| 860 | |
| 861 | /* Push the root table as instance object, this is what squirrel does for meta-functions. */ |
| 862 | sq_pushroottable(vm); |
| 863 | /* Push all arguments for the valuator function. */ |
| 864 | sq_pushinteger(vm, item.first); |
| 865 | for (int i = 0; i < nparam - 1; i++) { |
| 866 | sq_push(vm, i + 3); |
| 867 | } |
| 868 | |
| 869 | /* Call the function. Squirrel pops all parameters and pushes the return value. */ |
| 870 | if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQFalse))) { |
| 871 | return SQ_ERROR; |
| 872 | } |
| 873 | |
| 874 | /* Retrieve the return value */ |
| 875 | SQInteger value; |
| 876 | switch (sq_gettype(vm, -1)) { |
| 877 | case OT_INTEGER: { |
| 878 | sq_getinteger(vm, -1, &value); |
| 879 | break; |
| 880 | } |
| 881 | |
| 882 | case OT_BOOL: { |
| 883 | SQBool v; |
| 884 | sq_getbool(vm, -1, &v); |
| 885 | value = v ? 1 : 0; |
nothing calls this directly
no test coverage detected