瀏覽代碼

Merge pull request #168 from VasiliyRyabtsev/feature/map-apply-extra

Allow additional parameters in array.map()/array.apply() handler
Alberto Demichelis 7 年之前
父節點
當前提交
9bc87aebfc
共有 2 個文件被更改,包括 24 次插入3 次删除
  1. 3 2
      doc/source/reference/language/builtin_functions.rst
  2. 21 1
      squirrel/sqbaselib.cpp

+ 3 - 2
doc/source/reference/language/builtin_functions.rst

@@ -412,12 +412,13 @@ returns the string "(array : pointer)".
 removes all the items from the array
 removes all the items from the array
 
 
 
 
-.. js:function:: array.map(func(a))
+.. js:function:: array.map(func(item_value, [item_index], [array_ref]))
 
 
 Creates a new array of the same size. For each element in the original array invokes the function 'func' and assigns the return value of the function to the corresponding element of the newly created array.
 Creates a new array of the same size. For each element in the original array invokes the function 'func' and assigns the return value of the function to the corresponding element of the newly created array.
+Provided func can accept up to 3 arguments: array item value (required), array item index (optional), reference to array itself (optional).
 
 
 
 
-.. js:function:: array.apply(func(a))
+.. js:function:: array.apply(func([item_value, [item_index], [array_ref]))
 
 
 for each element in the array invokes the function 'func' and replace the original value of the element with the return value of the function.
 for each element in the array invokes the function 'func' and replace the original value of the element with the return value of the function.
 
 

+ 21 - 1
squirrel/sqbaselib.cpp

@@ -596,16 +596,36 @@ static SQInteger array_resize(HSQUIRRELVM v)
 static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
 static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
     SQObjectPtr temp;
     SQObjectPtr temp;
     SQInteger size = src->Size();
     SQInteger size = src->Size();
+    SQObject &closure = stack_get(v, 2);
+    v->Push(closure);
+
+    SQInteger nArgs;
+    if(sq_type(closure) == OT_CLOSURE) {
+        nArgs = _closure(closure)->_function->_nparameters;
+    }
+    else if (sq_type(closure) == OT_NATIVECLOSURE) {
+        SQInteger nParamsCheck = _nativeclosure(closure)->_nparamscheck;
+        if (nParamsCheck > 0)
+            nArgs = nParamsCheck;
+        else // push all params when there is no check or only minimal count set
+            nArgs = 4;
+    }
+
     for(SQInteger n = 0; n < size; n++) {
     for(SQInteger n = 0; n < size; n++) {
         src->Get(n,temp);
         src->Get(n,temp);
         v->Push(src);
         v->Push(src);
         v->Push(temp);
         v->Push(temp);
-        if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) {
+        if (nArgs >= 3)
+            v->Push(SQObjectPtr(n));
+        if (nArgs >= 4)
+            v->Push(src);
+        if(SQ_FAILED(sq_call(v,nArgs,SQTrue,SQFalse))) {
             return SQ_ERROR;
             return SQ_ERROR;
         }
         }
         dest->Set(n,v->GetUp(-1));
         dest->Set(n,v->GetUp(-1));
         v->Pop();
         v->Pop();
     }
     }
+    v->Pop();
     return 0;
     return 0;
 }
 }