|
@@ -499,6 +499,32 @@ static SQInteger table_filter(HSQUIRRELVM v)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static SQInteger table_map(HSQUIRRELVM v)
|
|
|
|
+{
|
|
|
|
+ SQObject &o = stack_get(v, 1);
|
|
|
|
+ SQTable *tbl = _table(o);
|
|
|
|
+ SQInteger nitr, n = 0;
|
|
|
|
+ SQInteger nitems = tbl->CountUsed();
|
|
|
|
+ SQObjectPtr ret = SQArray::Create(_ss(v), nitems);
|
|
|
|
+ SQObjectPtr itr, key, val;
|
|
|
|
+ while ((nitr = tbl->Next(false, itr, key, val)) != -1) {
|
|
|
|
+ itr = (SQInteger)nitr;
|
|
|
|
+
|
|
|
|
+ v->Push(o);
|
|
|
|
+ v->Push(key);
|
|
|
|
+ v->Push(val);
|
|
|
|
+ if (SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
|
|
|
|
+ return SQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+ _array(ret)->Set(n, v->GetUp(-1));
|
|
|
|
+ v->Pop();
|
|
|
|
+ n++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ v->Push(ret);
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
#define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \
|
|
#define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \
|
|
{ \
|
|
{ \
|
|
SQObject &o = stack_get(v, 1); \
|
|
SQObject &o = stack_get(v, 1); \
|
|
@@ -536,6 +562,7 @@ const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
|
|
{_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},
|
|
{_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},
|
|
{_SC("getdelegate"),table_getdelegate,1, _SC(".")},
|
|
{_SC("getdelegate"),table_getdelegate,1, _SC(".")},
|
|
{_SC("filter"),table_filter,2, _SC("tc")},
|
|
{_SC("filter"),table_filter,2, _SC("tc")},
|
|
|
|
+ {_SC("map"),table_map,2, _SC("tc") },
|
|
{_SC("keys"),table_keys,1, _SC("t") },
|
|
{_SC("keys"),table_keys,1, _SC("t") },
|
|
{_SC("values"),table_values,1, _SC("t") },
|
|
{_SC("values"),table_values,1, _SC("t") },
|
|
{NULL,(SQFUNCTION)0,0,NULL}
|
|
{NULL,(SQFUNCTION)0,0,NULL}
|
|
@@ -754,7 +781,7 @@ static SQInteger array_find(HSQUIRRELVM v)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
|
|
|
|
|
|
+static bool _sort_compare(HSQUIRRELVM v, SQArray *arr, SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
|
|
{
|
|
{
|
|
if(func < 0) {
|
|
if(func < 0) {
|
|
if(!v->ObjCmp(a,b,ret)) return false;
|
|
if(!v->ObjCmp(a,b,ret)) return false;
|
|
@@ -765,15 +792,21 @@ static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger
|
|
sq_pushroottable(v);
|
|
sq_pushroottable(v);
|
|
v->Push(a);
|
|
v->Push(a);
|
|
v->Push(b);
|
|
v->Push(b);
|
|
|
|
+ SQObjectPtr *valptr = arr->_values._vals;
|
|
|
|
+ SQUnsignedInteger precallsize = arr->_values.size();
|
|
if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
|
|
if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
|
|
if(!sq_isstring( v->_lasterror))
|
|
if(!sq_isstring( v->_lasterror))
|
|
v->Raise_Error(_SC("compare func failed"));
|
|
v->Raise_Error(_SC("compare func failed"));
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
|
|
|
|
|
|
+ if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
|
|
v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
|
|
v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+ if (precallsize != arr->_values.size() || valptr != arr->_values._vals) {
|
|
|
|
+ v->Raise_Error(_SC("array resized during sort operation"));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
sq_settop(v, top);
|
|
sq_settop(v, top);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -792,7 +825,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg
|
|
maxChild = root2;
|
|
maxChild = root2;
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))
|
|
|
|
|
|
+ if(!_sort_compare(v,arr,arr->_values[root2],arr->_values[root2 + 1],func,ret))
|
|
return false;
|
|
return false;
|
|
if (ret > 0) {
|
|
if (ret > 0) {
|
|
maxChild = root2;
|
|
maxChild = root2;
|
|
@@ -802,7 +835,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))
|
|
|
|
|
|
+ if(!_sort_compare(v,arr,arr->_values[root],arr->_values[maxChild],func,ret))
|
|
return false;
|
|
return false;
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
if (root == maxChild) {
|
|
if (root == maxChild) {
|
|
@@ -1116,6 +1149,7 @@ static SQInteger thread_call(HSQUIRRELVM v)
|
|
SQObjectPtr o = stack_get(v,1);
|
|
SQObjectPtr o = stack_get(v,1);
|
|
if(sq_type(o) == OT_THREAD) {
|
|
if(sq_type(o) == OT_THREAD) {
|
|
SQInteger nparams = sq_gettop(v);
|
|
SQInteger nparams = sq_gettop(v);
|
|
|
|
+ sq_reservestack(_thread(o), nparams + 3);
|
|
_thread(o)->Push(_thread(o)->_roottable);
|
|
_thread(o)->Push(_thread(o)->_roottable);
|
|
for(SQInteger i = 2; i<(nparams+1); i++)
|
|
for(SQInteger i = 2; i<(nparams+1); i++)
|
|
sq_move(_thread(o),v,i);
|
|
sq_move(_thread(o),v,i);
|