diff --git a/src/scriptengine/scriptarray.cpp b/src/scriptengine/scriptarray.cpp index 8557c8cb9..055c7433b 100644 --- a/src/scriptengine/scriptarray.cpp +++ b/src/scriptengine/scriptarray.cpp @@ -23,8 +23,8 @@ static asFREEFUNC_t userFree = asFreeMem; // Allows the application to set which memory routines should be used by the array object void CScriptArray::SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc) { - userAlloc = allocFunc; - userFree = freeFunc; + userAlloc = allocFunc; + userFree = freeFunc; } static void RegisterScriptArray_Native(asIScriptEngine *engine); @@ -32,17 +32,17 @@ static void RegisterScriptArray_Generic(asIScriptEngine *engine); struct SArrayBuffer { - asDWORD maxElements; - asDWORD numElements; - asBYTE data[1]; + asDWORD maxElements; + asDWORD numElements; + asBYTE data[1]; }; struct SArrayCache { - asIScriptFunction *cmpFunc; - asIScriptFunction *eqFunc; - int cmpFuncReturnCode; // To allow better error message in case of multiple matches - int eqFuncReturnCode; + asIScriptFunction *cmpFunc; + asIScriptFunction *eqFunc; + int cmpFuncReturnCode; // To allow better error message in case of multiple matches + int eqFuncReturnCode; }; // We just define a number here that we assume nobody else is using for @@ -52,74 +52,74 @@ const asPWORD ARRAY_CACHE = 1000; static void CleanupTypeInfoArrayCache(asITypeInfo *type) { - SArrayCache *cache = reinterpret_cast(type->GetUserData(ARRAY_CACHE)); - if( cache ) - { - cache->~SArrayCache(); - userFree(cache); - } + SArrayCache *cache = reinterpret_cast(type->GetUserData(ARRAY_CACHE)); + if( cache ) + { + cache->~SArrayCache(); + userFree(cache); + } } CScriptArray* CScriptArray::Create(asITypeInfo *ti, asUINT length) { - // Allocate the memory - void *mem = userAlloc(sizeof(CScriptArray)); - if( mem == 0 ) - { - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); + // Allocate the memory + void *mem = userAlloc(sizeof(CScriptArray)); + if( mem == 0 ) + { + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); - return 0; - } + return 0; + } - // Initialize the object - CScriptArray *a = new(mem) CScriptArray(length, ti); + // Initialize the object + CScriptArray *a = new(mem) CScriptArray(length, ti); - return a; + return a; } CScriptArray* CScriptArray::Create(asITypeInfo *ti, void *initList) { - // Allocate the memory - void *mem = userAlloc(sizeof(CScriptArray)); - if( mem == 0 ) - { - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); + // Allocate the memory + void *mem = userAlloc(sizeof(CScriptArray)); + if( mem == 0 ) + { + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); - return 0; - } + return 0; + } - // Initialize the object - CScriptArray *a = new(mem) CScriptArray(ti, initList); + // Initialize the object + CScriptArray *a = new(mem) CScriptArray(ti, initList); - return a; + return a; } CScriptArray* CScriptArray::Create(asITypeInfo *ti, asUINT length, void *defVal) { - // Allocate the memory - void *mem = userAlloc(sizeof(CScriptArray)); - if( mem == 0 ) - { - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); + // Allocate the memory + void *mem = userAlloc(sizeof(CScriptArray)); + if( mem == 0 ) + { + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); - return 0; - } + return 0; + } - // Initialize the object - CScriptArray *a = new(mem) CScriptArray(length, defVal, ti); + // Initialize the object + CScriptArray *a = new(mem) CScriptArray(length, defVal, ti); - return a; + return a; } CScriptArray* CScriptArray::Create(asITypeInfo *ti) { - return CScriptArray::Create(ti, asUINT(0)); + return CScriptArray::Create(ti, asUINT(0)); } // This optional callback is called when the template type is first used by the compiler. @@ -129,1224 +129,1224 @@ CScriptArray* CScriptArray::Create(asITypeInfo *ti) // i.e. no asOBJ_GC flag. static bool ScriptArrayTemplateCallback(asITypeInfo *ti, bool &dontGarbageCollect) { - // Make sure the subtype can be instantiated with a default factory/constructor, - // otherwise we won't be able to instantiate the elements. - int typeId = ti->GetSubTypeId(); - if( typeId == asTYPEID_VOID ) - return false; - if( (typeId & asTYPEID_MASK_OBJECT) && !(typeId & asTYPEID_OBJHANDLE) ) - { - asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId); - asDWORD flags = subtype->GetFlags(); - if( (flags & asOBJ_VALUE) && !(flags & asOBJ_POD) ) - { - // Verify that there is a default constructor - bool found = false; - for( asUINT n = 0; n < subtype->GetBehaviourCount(); n++ ) - { - asEBehaviours beh; - asIScriptFunction *func = subtype->GetBehaviourByIndex(n, &beh); - if( beh != asBEHAVE_CONSTRUCT ) continue; + // Make sure the subtype can be instantiated with a default factory/constructor, + // otherwise we won't be able to instantiate the elements. + int typeId = ti->GetSubTypeId(); + if( typeId == asTYPEID_VOID ) + return false; + if( (typeId & asTYPEID_MASK_OBJECT) && !(typeId & asTYPEID_OBJHANDLE) ) + { + asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId); + asDWORD flags = subtype->GetFlags(); + if( (flags & asOBJ_VALUE) && !(flags & asOBJ_POD) ) + { + // Verify that there is a default constructor + bool found = false; + for( asUINT n = 0; n < subtype->GetBehaviourCount(); n++ ) + { + asEBehaviours beh; + asIScriptFunction *func = subtype->GetBehaviourByIndex(n, &beh); + if( beh != asBEHAVE_CONSTRUCT ) continue; - if( func->GetParamCount() == 0 ) - { - // Found the default constructor - found = true; - break; - } - } + if( func->GetParamCount() == 0 ) + { + // Found the default constructor + found = true; + break; + } + } - if( !found ) - { - // There is no default constructor - // TODO: Should format the message to give the name of the subtype for better understanding - ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default constructor"); - return false; - } - } - else if( (flags & asOBJ_REF) ) - { - bool found = false; + if( !found ) + { + // There is no default constructor + // TODO: Should format the message to give the name of the subtype for better understanding + ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default constructor"); + return false; + } + } + else if( (flags & asOBJ_REF) ) + { + bool found = false; - // If value assignment for ref type has been disabled then the array - // can be created if the type has a default factory function - if( !ti->GetEngine()->GetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE) ) - { - // Verify that there is a default factory - for( asUINT n = 0; n < subtype->GetFactoryCount(); n++ ) - { - asIScriptFunction *func = subtype->GetFactoryByIndex(n); - if( func->GetParamCount() == 0 ) - { - // Found the default factory - found = true; - break; - } - } - } + // If value assignment for ref type has been disabled then the array + // can be created if the type has a default factory function + if( !ti->GetEngine()->GetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE) ) + { + // Verify that there is a default factory + for( asUINT n = 0; n < subtype->GetFactoryCount(); n++ ) + { + asIScriptFunction *func = subtype->GetFactoryByIndex(n); + if( func->GetParamCount() == 0 ) + { + // Found the default factory + found = true; + break; + } + } + } - if( !found ) - { - // No default factory - // TODO: Should format the message to give the name of the subtype for better understanding - ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default factory"); - return false; - } - } + if( !found ) + { + // No default factory + // TODO: Should format the message to give the name of the subtype for better understanding + ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default factory"); + return false; + } + } - // If the object type is not garbage collected then the array also doesn't need to be - if( !(flags & asOBJ_GC) ) - dontGarbageCollect = true; - } - else if( !(typeId & asTYPEID_OBJHANDLE) ) - { - // Arrays with primitives cannot form circular references, - // thus there is no need to garbage collect them - dontGarbageCollect = true; - } - else - { - assert( typeId & asTYPEID_OBJHANDLE ); + // If the object type is not garbage collected then the array also doesn't need to be + if( !(flags & asOBJ_GC) ) + dontGarbageCollect = true; + } + else if( !(typeId & asTYPEID_OBJHANDLE) ) + { + // Arrays with primitives cannot form circular references, + // thus there is no need to garbage collect them + dontGarbageCollect = true; + } + else + { + assert( typeId & asTYPEID_OBJHANDLE ); - // It is not necessary to set the array as garbage collected for all handle types. - // If it is possible to determine that the handle cannot refer to an object type - // that can potentially form a circular reference with the array then it is not - // necessary to make the array garbage collected. - asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId); - asDWORD flags = subtype->GetFlags(); - if( !(flags & asOBJ_GC) ) - { - if( (flags & asOBJ_SCRIPT_OBJECT) ) - { - // Even if a script class is by itself not garbage collected, it is possible - // that classes that derive from it may be, so it is not possible to know - // that no circular reference can occur. - if( (flags & asOBJ_NOINHERIT) ) - { - // A script class declared as final cannot be inherited from, thus - // we can be certain that the object cannot be garbage collected. - dontGarbageCollect = true; - } - } - else - { - // For application registered classes we assume the application knows - // what it is doing and don't mark the array as garbage collected unless - // the type is also garbage collected. - dontGarbageCollect = true; - } - } - } + // It is not necessary to set the array as garbage collected for all handle types. + // If it is possible to determine that the handle cannot refer to an object type + // that can potentially form a circular reference with the array then it is not + // necessary to make the array garbage collected. + asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId); + asDWORD flags = subtype->GetFlags(); + if( !(flags & asOBJ_GC) ) + { + if( (flags & asOBJ_SCRIPT_OBJECT) ) + { + // Even if a script class is by itself not garbage collected, it is possible + // that classes that derive from it may be, so it is not possible to know + // that no circular reference can occur. + if( (flags & asOBJ_NOINHERIT) ) + { + // A script class declared as final cannot be inherited from, thus + // we can be certain that the object cannot be garbage collected. + dontGarbageCollect = true; + } + } + else + { + // For application registered classes we assume the application knows + // what it is doing and don't mark the array as garbage collected unless + // the type is also garbage collected. + dontGarbageCollect = true; + } + } + } - // The type is ok - return true; + // The type is ok + return true; } // Registers the template array type void RegisterScriptArray(asIScriptEngine *engine, bool defaultArray) { - if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0 ) - RegisterScriptArray_Native(engine); - else - RegisterScriptArray_Generic(engine); + if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0 ) + RegisterScriptArray_Native(engine); + else + RegisterScriptArray_Generic(engine); - if( defaultArray ) - { - int r = engine->RegisterDefaultArrayType("array"); assert( r >= 0 ); - UNUSED_VAR(r); - } + if( defaultArray ) + { + int r = engine->RegisterDefaultArrayType("array"); assert( r >= 0 ); + UNUSED_VAR(r); + } } static void RegisterScriptArray_Native(asIScriptEngine *engine) { - int r = 0; - UNUSED_VAR(r); + int r = 0; + UNUSED_VAR(r); - // Register the object type user data clean up - engine->SetTypeInfoUserDataCleanupCallback(CleanupTypeInfoArrayCache, ARRAY_CACHE); + // Register the object type user data clean up + engine->SetTypeInfoUserDataCleanupCallback(CleanupTypeInfoArrayCache, ARRAY_CACHE); - // Register the array type as a template - r = engine->RegisterObjectType("array", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 ); + // Register the array type as a template + r = engine->RegisterObjectType("array", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 ); - // Register a callback for validating the subtype before it is used - r = engine->RegisterObjectBehaviour("array", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptArrayTemplateCallback), asCALL_CDECL); assert( r >= 0 ); + // Register a callback for validating the subtype before it is used + r = engine->RegisterObjectBehaviour("array", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptArrayTemplateCallback), asCALL_CDECL); assert( r >= 0 ); - // Templates receive the object type as the first parameter. To the script writer this is hidden - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, asUINT), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length, const T &in value)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, asUINT, void *), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); + // Templates receive the object type as the first parameter. To the script writer this is hidden + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, asUINT), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length, const T &in value)", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, asUINT, void *), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); - // Register the factory that will be used for initialization lists - r = engine->RegisterObjectBehaviour("array", asBEHAVE_LIST_FACTORY, "array@ f(int&in type, int&in list) {repeat T}", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, void*), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); + // Register the factory that will be used for initialization lists + r = engine->RegisterObjectBehaviour("array", asBEHAVE_LIST_FACTORY, "array@ f(int&in type, int&in list) {repeat T}", asFUNCTIONPR(CScriptArray::Create, (asITypeInfo*, void*), CScriptArray*), asCALL_CDECL); assert( r >= 0 ); - // The memory management methods - r = engine->RegisterObjectBehaviour("array", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptArray,AddRef), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptArray,Release), asCALL_THISCALL); assert( r >= 0 ); + // The memory management methods + r = engine->RegisterObjectBehaviour("array", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptArray,AddRef), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptArray,Release), asCALL_THISCALL); assert( r >= 0 ); - // The index operator returns the template subtype - r = engine->RegisterObjectMethod("array", "T &opIndex(uint index)", asMETHODPR(CScriptArray, At, (asUINT), void*), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "const T &opIndex(uint index) const", asMETHODPR(CScriptArray, At, (asUINT) const, const void*), asCALL_THISCALL); assert( r >= 0 ); + // The index operator returns the template subtype + r = engine->RegisterObjectMethod("array", "T &opIndex(uint index)", asMETHODPR(CScriptArray, At, (asUINT), void*), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "const T &opIndex(uint index) const", asMETHODPR(CScriptArray, At, (asUINT) const, const void*), asCALL_THISCALL); assert( r >= 0 ); - // The assignment operator - r = engine->RegisterObjectMethod("array", "array &opAssign(const array&in)", asMETHOD(CScriptArray, operator=), asCALL_THISCALL); assert( r >= 0 ); + // The assignment operator + r = engine->RegisterObjectMethod("array", "array &opAssign(const array&in)", asMETHOD(CScriptArray, operator=), asCALL_THISCALL); assert( r >= 0 ); - // Other methods - r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const T&in value)", asMETHODPR(CScriptArray, InsertAt, (asUINT, void *), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const array& arr)", asMETHODPR(CScriptArray, InsertAt, (asUINT, const CScriptArray &), void), asCALL_THISCALL); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void insertLast(const T&in value)", asMETHOD(CScriptArray, InsertLast), asCALL_THISCALL); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void removeAt(uint index)", asMETHOD(CScriptArray, RemoveAt), asCALL_THISCALL); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void removeLast()", asMETHOD(CScriptArray, RemoveLast), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void removeRange(uint start, uint count)", asMETHOD(CScriptArray, RemoveRange), asCALL_THISCALL); assert(r >= 0); - // TODO: Should length() and resize() be deprecated as the property accessors do the same thing? - r = engine->RegisterObjectMethod("array", "uint length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void reserve(uint length)", asMETHOD(CScriptArray, Reserve), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void resize(uint length)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortAsc()", asMETHODPR(CScriptArray, SortAsc, (), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortAsc(uint startAt, uint count)", asMETHODPR(CScriptArray, SortAsc, (asUINT, asUINT), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortDesc()", asMETHODPR(CScriptArray, SortDesc, (), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortDesc(uint startAt, uint count)", asMETHODPR(CScriptArray, SortDesc, (asUINT, asUINT), void), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void reverse()", asMETHOD(CScriptArray, Reverse), asCALL_THISCALL); assert( r >= 0 ); - // The token 'if_handle_then_const' tells the engine that if the type T is a handle, then it should refer to a read-only object - r = engine->RegisterObjectMethod("array", "int find(const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, Find, (void*) const, int), asCALL_THISCALL); assert( r >= 0 ); - // TODO: It should be "int find(const T&in value, uint startAt = 0) const" - r = engine->RegisterObjectMethod("array", "int find(uint startAt, const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, Find, (asUINT, void*) const, int), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "int findByRef(const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, FindByRef, (void*) const, int), asCALL_THISCALL); assert( r >= 0 ); - // TODO: It should be "int findByRef(const T&in value, uint startAt = 0) const" - r = engine->RegisterObjectMethod("array", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, FindByRef, (asUINT, void*) const, int), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "bool opEquals(const array&in) const", asMETHOD(CScriptArray, operator==), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "bool isEmpty() const", asMETHOD(CScriptArray, IsEmpty), asCALL_THISCALL); assert( r >= 0 ); + // Other methods + r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const T&in value)", asMETHODPR(CScriptArray, InsertAt, (asUINT, void *), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const array& arr)", asMETHODPR(CScriptArray, InsertAt, (asUINT, const CScriptArray &), void), asCALL_THISCALL); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void insertLast(const T&in value)", asMETHOD(CScriptArray, InsertLast), asCALL_THISCALL); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void removeAt(uint index)", asMETHOD(CScriptArray, RemoveAt), asCALL_THISCALL); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void removeLast()", asMETHOD(CScriptArray, RemoveLast), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void removeRange(uint start, uint count)", asMETHOD(CScriptArray, RemoveRange), asCALL_THISCALL); assert(r >= 0); + // TODO: Should length() and resize() be deprecated as the property accessors do the same thing? + r = engine->RegisterObjectMethod("array", "uint length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void reserve(uint length)", asMETHOD(CScriptArray, Reserve), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void resize(uint length)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortAsc()", asMETHODPR(CScriptArray, SortAsc, (), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortAsc(uint startAt, uint count)", asMETHODPR(CScriptArray, SortAsc, (asUINT, asUINT), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortDesc()", asMETHODPR(CScriptArray, SortDesc, (), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortDesc(uint startAt, uint count)", asMETHODPR(CScriptArray, SortDesc, (asUINT, asUINT), void), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void reverse()", asMETHOD(CScriptArray, Reverse), asCALL_THISCALL); assert( r >= 0 ); + // The token 'if_handle_then_const' tells the engine that if the type T is a handle, then it should refer to a read-only object + r = engine->RegisterObjectMethod("array", "int find(const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, Find, (void*) const, int), asCALL_THISCALL); assert( r >= 0 ); + // TODO: It should be "int find(const T&in value, uint startAt = 0) const" + r = engine->RegisterObjectMethod("array", "int find(uint startAt, const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, Find, (asUINT, void*) const, int), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "int findByRef(const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, FindByRef, (void*) const, int), asCALL_THISCALL); assert( r >= 0 ); + // TODO: It should be "int findByRef(const T&in value, uint startAt = 0) const" + r = engine->RegisterObjectMethod("array", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asMETHODPR(CScriptArray, FindByRef, (asUINT, void*) const, int), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "bool opEquals(const array&in) const", asMETHOD(CScriptArray, operator==), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "bool isEmpty() const", asMETHOD(CScriptArray, IsEmpty), asCALL_THISCALL); assert( r >= 0 ); - // Sort with callback for comparison - r = engine->RegisterFuncdef("bool array::less(const T&in a, const T&in b)"); - r = engine->RegisterObjectMethod("array", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asMETHODPR(CScriptArray, Sort, (asIScriptFunction*, asUINT, asUINT), void), asCALL_THISCALL); assert(r >= 0); + // Sort with callback for comparison + r = engine->RegisterFuncdef("bool array::less(const T&in a, const T&in b)"); + r = engine->RegisterObjectMethod("array", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asMETHODPR(CScriptArray, Sort, (asIScriptFunction*, asUINT, asUINT), void), asCALL_THISCALL); assert(r >= 0); - // Register virtual properties - r = engine->RegisterObjectMethod("array", "uint get_length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void set_length(uint)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL); assert( r >= 0 ); + // Register virtual properties + r = engine->RegisterObjectMethod("array", "uint get_length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void set_length(uint)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL); assert( r >= 0 ); - // Register GC behaviours in case the array needs to be garbage collected - r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptArray, GetRefCount), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptArray, SetFlag), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptArray, GetFlag), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptArray, EnumReferences), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptArray, ReleaseAllHandles), asCALL_THISCALL); assert( r >= 0 ); + // Register GC behaviours in case the array needs to be garbage collected + r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptArray, GetRefCount), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptArray, SetFlag), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptArray, GetFlag), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptArray, EnumReferences), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptArray, ReleaseAllHandles), asCALL_THISCALL); assert( r >= 0 ); #if AS_USE_STLNAMES == 1 - // Same as length - r = engine->RegisterObjectMethod("array", "uint size() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); - // Same as isEmpty - r = engine->RegisterObjectMethod("array", "bool empty() const", asMETHOD(CScriptArray, IsEmpty), asCALL_THISCALL); assert( r >= 0 ); - // Same as insertLast - r = engine->RegisterObjectMethod("array", "void push_back(const T&in)", asMETHOD(CScriptArray, InsertLast), asCALL_THISCALL); assert( r >= 0 ); - // Same as removeLast - r = engine->RegisterObjectMethod("array", "void pop_back()", asMETHOD(CScriptArray, RemoveLast), asCALL_THISCALL); assert( r >= 0 ); - // Same as insertAt - r = engine->RegisterObjectMethod("array", "void insert(uint index, const T&in value)", asMETHODPR(CScriptArray, InsertAt, (asUINT, void *), void), asCALL_THISCALL); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void insert(uint index, const array& arr)", asMETHODPR(CScriptArray, InsertAt, (asUINT, const CScriptArray &), void), asCALL_THISCALL); assert(r >= 0); - // Same as removeAt - r = engine->RegisterObjectMethod("array", "void erase(uint)", asMETHOD(CScriptArray, RemoveAt), asCALL_THISCALL); assert( r >= 0 ); + // Same as length + r = engine->RegisterObjectMethod("array", "uint size() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL); assert( r >= 0 ); + // Same as isEmpty + r = engine->RegisterObjectMethod("array", "bool empty() const", asMETHOD(CScriptArray, IsEmpty), asCALL_THISCALL); assert( r >= 0 ); + // Same as insertLast + r = engine->RegisterObjectMethod("array", "void push_back(const T&in)", asMETHOD(CScriptArray, InsertLast), asCALL_THISCALL); assert( r >= 0 ); + // Same as removeLast + r = engine->RegisterObjectMethod("array", "void pop_back()", asMETHOD(CScriptArray, RemoveLast), asCALL_THISCALL); assert( r >= 0 ); + // Same as insertAt + r = engine->RegisterObjectMethod("array", "void insert(uint index, const T&in value)", asMETHODPR(CScriptArray, InsertAt, (asUINT, void *), void), asCALL_THISCALL); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void insert(uint index, const array& arr)", asMETHODPR(CScriptArray, InsertAt, (asUINT, const CScriptArray &), void), asCALL_THISCALL); assert(r >= 0); + // Same as removeAt + r = engine->RegisterObjectMethod("array", "void erase(uint)", asMETHOD(CScriptArray, RemoveAt), asCALL_THISCALL); assert( r >= 0 ); #endif } CScriptArray &CScriptArray::operator=(const CScriptArray &other) { - // Only perform the copy if the array types are the same - if( &other != this && - other.GetArrayObjectType() == GetArrayObjectType() ) - { - // Make sure the arrays are of the same size - Resize(other.buffer->numElements); + // Only perform the copy if the array types are the same + if( &other != this && + other.GetArrayObjectType() == GetArrayObjectType() ) + { + // Make sure the arrays are of the same size + Resize(other.buffer->numElements); - // Copy the value of each element - CopyBuffer(buffer, other.buffer); - } + // Copy the value of each element + CopyBuffer(buffer, other.buffer); + } - return *this; + return *this; } CScriptArray::CScriptArray(asITypeInfo *ti, void *buf) { - // The object type should be the template instance of the array - assert( ti && string(ti->GetName()) == "array" ); + // The object type should be the template instance of the array + assert( ti && string(ti->GetName()) == "array" ); - refCount = 1; - gcFlag = false; - objType = ti; - objType->AddRef(); - buffer = 0; + refCount = 1; + gcFlag = false; + objType = ti; + objType->AddRef(); + buffer = 0; - Precache(); + Precache(); - asIScriptEngine *engine = ti->GetEngine(); + asIScriptEngine *engine = ti->GetEngine(); - // Determine element size - if( subTypeId & asTYPEID_MASK_OBJECT ) - elementSize = sizeof(asPWORD); - else - elementSize = engine->GetSizeOfPrimitiveType(subTypeId); + // Determine element size + if( subTypeId & asTYPEID_MASK_OBJECT ) + elementSize = sizeof(asPWORD); + else + elementSize = engine->GetSizeOfPrimitiveType(subTypeId); - // Determine the initial size from the buffer - asUINT length = *(asUINT*)buf; + // Determine the initial size from the buffer + asUINT length = *(asUINT*)buf; - // Make sure the array size isn't too large for us to handle - if( !CheckMaxSize(length) ) - { - // Don't continue with the initialization - return; - } + // Make sure the array size isn't too large for us to handle + if( !CheckMaxSize(length) ) + { + // Don't continue with the initialization + return; + } - // Copy the values of the array elements from the buffer - if( (ti->GetSubTypeId() & asTYPEID_MASK_OBJECT) == 0 ) - { - CreateBuffer(&buffer, length); + // Copy the values of the array elements from the buffer + if( (ti->GetSubTypeId() & asTYPEID_MASK_OBJECT) == 0 ) + { + CreateBuffer(&buffer, length); - // Copy the values of the primitive type into the internal buffer - if( length > 0 ) - memcpy(At(0), (((asUINT*)buf)+1), length * elementSize); - } - else if( ti->GetSubTypeId() & asTYPEID_OBJHANDLE ) - { - CreateBuffer(&buffer, length); + // Copy the values of the primitive type into the internal buffer + if( length > 0 ) + memcpy(At(0), (((asUINT*)buf)+1), length * elementSize); + } + else if( ti->GetSubTypeId() & asTYPEID_OBJHANDLE ) + { + CreateBuffer(&buffer, length); - // Copy the handles into the internal buffer - if( length > 0 ) - memcpy(At(0), (((asUINT*)buf)+1), length * elementSize); + // Copy the handles into the internal buffer + if( length > 0 ) + memcpy(At(0), (((asUINT*)buf)+1), length * elementSize); - // With object handles it is safe to clear the memory in the received buffer - // instead of increasing the ref count. It will save time both by avoiding the - // call the increase ref, and also relieve the engine from having to release - // its references too - memset((((asUINT*)buf)+1), 0, length * elementSize); - } - else if( ti->GetSubType()->GetFlags() & asOBJ_REF ) - { - // Only allocate the buffer, but not the objects - subTypeId |= asTYPEID_OBJHANDLE; - CreateBuffer(&buffer, length); - subTypeId &= ~asTYPEID_OBJHANDLE; + // With object handles it is safe to clear the memory in the received buffer + // instead of increasing the ref count. It will save time both by avoiding the + // call the increase ref, and also relieve the engine from having to release + // its references too + memset((((asUINT*)buf)+1), 0, length * elementSize); + } + else if( ti->GetSubType()->GetFlags() & asOBJ_REF ) + { + // Only allocate the buffer, but not the objects + subTypeId |= asTYPEID_OBJHANDLE; + CreateBuffer(&buffer, length); + subTypeId &= ~asTYPEID_OBJHANDLE; - // Copy the handles into the internal buffer - if( length > 0 ) - memcpy(buffer->data, (((asUINT*)buf)+1), length * elementSize); + // Copy the handles into the internal buffer + if( length > 0 ) + memcpy(buffer->data, (((asUINT*)buf)+1), length * elementSize); - // For ref types we can do the same as for handles, as they are - // implicitly stored as handles. - memset((((asUINT*)buf)+1), 0, length * elementSize); - } - else - { - // TODO: Optimize by calling the copy constructor of the object instead of - // constructing with the default constructor and then assigning the value - // TODO: With C++11 ideally we should be calling the move constructor, instead - // of the copy constructor as the engine will just discard the objects in the - // buffer afterwards. - CreateBuffer(&buffer, length); + // For ref types we can do the same as for handles, as they are + // implicitly stored as handles. + memset((((asUINT*)buf)+1), 0, length * elementSize); + } + else + { + // TODO: Optimize by calling the copy constructor of the object instead of + // constructing with the default constructor and then assigning the value + // TODO: With C++11 ideally we should be calling the move constructor, instead + // of the copy constructor as the engine will just discard the objects in the + // buffer afterwards. + CreateBuffer(&buffer, length); - // For value types we need to call the opAssign for each individual object - for( asUINT n = 0; n < length; n++ ) - { - void *obj = At(n); - asBYTE *srcObj = (asBYTE*)buf; - srcObj += 4 + n*ti->GetSubType()->GetSize(); - engine->AssignScriptObject(obj, srcObj, ti->GetSubType()); - } - } + // For value types we need to call the opAssign for each individual object + for( asUINT n = 0; n < length; n++ ) + { + void *obj = At(n); + asBYTE *srcObj = (asBYTE*)buf; + srcObj += 4 + n*ti->GetSubType()->GetSize(); + engine->AssignScriptObject(obj, srcObj, ti->GetSubType()); + } + } - // Notify the GC of the successful creation - if( objType->GetFlags() & asOBJ_GC ) - objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); + // Notify the GC of the successful creation + if( objType->GetFlags() & asOBJ_GC ) + objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); } CScriptArray::CScriptArray(asUINT length, asITypeInfo *ti) { - // The object type should be the template instance of the array - assert( ti && string(ti->GetName()) == "array" ); + // The object type should be the template instance of the array + assert( ti && string(ti->GetName()) == "array" ); - refCount = 1; - gcFlag = false; - objType = ti; - objType->AddRef(); - buffer = 0; + refCount = 1; + gcFlag = false; + objType = ti; + objType->AddRef(); + buffer = 0; - Precache(); + Precache(); - // Determine element size - if( subTypeId & asTYPEID_MASK_OBJECT ) - elementSize = sizeof(asPWORD); - else - elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId); + // Determine element size + if( subTypeId & asTYPEID_MASK_OBJECT ) + elementSize = sizeof(asPWORD); + else + elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId); - // Make sure the array size isn't too large for us to handle - if( !CheckMaxSize(length) ) - { - // Don't continue with the initialization - return; - } + // Make sure the array size isn't too large for us to handle + if( !CheckMaxSize(length) ) + { + // Don't continue with the initialization + return; + } - CreateBuffer(&buffer, length); + CreateBuffer(&buffer, length); - // Notify the GC of the successful creation - if( objType->GetFlags() & asOBJ_GC ) - objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); + // Notify the GC of the successful creation + if( objType->GetFlags() & asOBJ_GC ) + objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); } CScriptArray::CScriptArray(const CScriptArray &other) { - refCount = 1; - gcFlag = false; - objType = other.objType; - objType->AddRef(); - buffer = 0; + refCount = 1; + gcFlag = false; + objType = other.objType; + objType->AddRef(); + buffer = 0; - Precache(); + Precache(); - elementSize = other.elementSize; + elementSize = other.elementSize; - if( objType->GetFlags() & asOBJ_GC ) - objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); + if( objType->GetFlags() & asOBJ_GC ) + objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); - CreateBuffer(&buffer, 0); + CreateBuffer(&buffer, 0); - // Copy the content - *this = other; + // Copy the content + *this = other; } CScriptArray::CScriptArray(asUINT length, void *defVal, asITypeInfo *ti) { - // The object type should be the template instance of the array - assert( ti && string(ti->GetName()) == "array" ); + // The object type should be the template instance of the array + assert( ti && string(ti->GetName()) == "array" ); - refCount = 1; - gcFlag = false; - objType = ti; - objType->AddRef(); - buffer = 0; + refCount = 1; + gcFlag = false; + objType = ti; + objType->AddRef(); + buffer = 0; - Precache(); + Precache(); - // Determine element size - if( subTypeId & asTYPEID_MASK_OBJECT ) - elementSize = sizeof(asPWORD); - else - elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId); + // Determine element size + if( subTypeId & asTYPEID_MASK_OBJECT ) + elementSize = sizeof(asPWORD); + else + elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId); - // Make sure the array size isn't too large for us to handle - if( !CheckMaxSize(length) ) - { - // Don't continue with the initialization - return; - } + // Make sure the array size isn't too large for us to handle + if( !CheckMaxSize(length) ) + { + // Don't continue with the initialization + return; + } - CreateBuffer(&buffer, length); + CreateBuffer(&buffer, length); - // Notify the GC of the successful creation - if( objType->GetFlags() & asOBJ_GC ) - objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); + // Notify the GC of the successful creation + if( objType->GetFlags() & asOBJ_GC ) + objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType); - // Initialize the elements with the default value - for( asUINT n = 0; n < GetSize(); n++ ) - SetValue(n, defVal); + // Initialize the elements with the default value + for( asUINT n = 0; n < GetSize(); n++ ) + SetValue(n, defVal); } void CScriptArray::SetValue(asUINT index, void *value) { - // At() will take care of the out-of-bounds checking, though - // if called from the application then nothing will be done - void *ptr = At(index); - if( ptr == 0 ) return; + // At() will take care of the out-of-bounds checking, though + // if called from the application then nothing will be done + void *ptr = At(index); + if( ptr == 0 ) return; - if( (subTypeId & ~asTYPEID_MASK_SEQNBR) && !(subTypeId & asTYPEID_OBJHANDLE) ) - objType->GetEngine()->AssignScriptObject(ptr, value, objType->GetSubType()); - else if( subTypeId & asTYPEID_OBJHANDLE ) - { - void *tmp = *(void**)ptr; - *(void**)ptr = *(void**)value; - objType->GetEngine()->AddRefScriptObject(*(void**)value, objType->GetSubType()); - if( tmp ) - objType->GetEngine()->ReleaseScriptObject(tmp, objType->GetSubType()); - } - else if( subTypeId == asTYPEID_BOOL || - subTypeId == asTYPEID_INT8 || - subTypeId == asTYPEID_UINT8 ) - *(char*)ptr = *(char*)value; - else if( subTypeId == asTYPEID_INT16 || - subTypeId == asTYPEID_UINT16 ) - *(short*)ptr = *(short*)value; - else if( subTypeId == asTYPEID_INT32 || - subTypeId == asTYPEID_UINT32 || - subTypeId == asTYPEID_FLOAT || - subTypeId > asTYPEID_DOUBLE ) // enums have a type id larger than doubles - *(int*)ptr = *(int*)value; - else if( subTypeId == asTYPEID_INT64 || - subTypeId == asTYPEID_UINT64 || - subTypeId == asTYPEID_DOUBLE ) - *(double*)ptr = *(double*)value; + if( (subTypeId & ~asTYPEID_MASK_SEQNBR) && !(subTypeId & asTYPEID_OBJHANDLE) ) + objType->GetEngine()->AssignScriptObject(ptr, value, objType->GetSubType()); + else if( subTypeId & asTYPEID_OBJHANDLE ) + { + void *tmp = *(void**)ptr; + *(void**)ptr = *(void**)value; + objType->GetEngine()->AddRefScriptObject(*(void**)value, objType->GetSubType()); + if( tmp ) + objType->GetEngine()->ReleaseScriptObject(tmp, objType->GetSubType()); + } + else if( subTypeId == asTYPEID_BOOL || + subTypeId == asTYPEID_INT8 || + subTypeId == asTYPEID_UINT8 ) + *(char*)ptr = *(char*)value; + else if( subTypeId == asTYPEID_INT16 || + subTypeId == asTYPEID_UINT16 ) + *(short*)ptr = *(short*)value; + else if( subTypeId == asTYPEID_INT32 || + subTypeId == asTYPEID_UINT32 || + subTypeId == asTYPEID_FLOAT || + subTypeId > asTYPEID_DOUBLE ) // enums have a type id larger than doubles + *(int*)ptr = *(int*)value; + else if( subTypeId == asTYPEID_INT64 || + subTypeId == asTYPEID_UINT64 || + subTypeId == asTYPEID_DOUBLE ) + *(double*)ptr = *(double*)value; } CScriptArray::~CScriptArray() { - if( buffer ) - { - DeleteBuffer(buffer); - buffer = 0; - } - if( objType ) objType->Release(); + if( buffer ) + { + DeleteBuffer(buffer); + buffer = 0; + } + if( objType ) objType->Release(); } asUINT CScriptArray::GetSize() const { - return buffer->numElements; + return buffer->numElements; } bool CScriptArray::IsEmpty() const { - return buffer->numElements == 0; + return buffer->numElements == 0; } void CScriptArray::Reserve(asUINT maxElements) { - if( maxElements <= buffer->maxElements ) - return; + if( maxElements <= buffer->maxElements ) + return; - if( !CheckMaxSize(maxElements) ) - return; + if( !CheckMaxSize(maxElements) ) + return; - // Allocate memory for the buffer - SArrayBuffer *newBuffer = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1 + elementSize*maxElements)); - if( newBuffer ) - { - newBuffer->numElements = buffer->numElements; - newBuffer->maxElements = maxElements; - } - else - { - // Out of memory - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); - return; - } + // Allocate memory for the buffer + SArrayBuffer *newBuffer = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1 + elementSize*maxElements)); + if( newBuffer ) + { + newBuffer->numElements = buffer->numElements; + newBuffer->maxElements = maxElements; + } + else + { + // Out of memory + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); + return; + } - // As objects in arrays of objects are not stored inline, it is safe to use memcpy here - // since we're just copying the pointers to objects and not the actual objects. - memcpy(newBuffer->data, buffer->data, buffer->numElements*elementSize); + // As objects in arrays of objects are not stored inline, it is safe to use memcpy here + // since we're just copying the pointers to objects and not the actual objects. + memcpy(newBuffer->data, buffer->data, buffer->numElements*elementSize); - // Release the old buffer - userFree(buffer); + // Release the old buffer + userFree(buffer); - buffer = newBuffer; + buffer = newBuffer; } void CScriptArray::Resize(asUINT numElements) { - if( !CheckMaxSize(numElements) ) - return; + if( !CheckMaxSize(numElements) ) + return; - Resize((int)numElements - (int)buffer->numElements, (asUINT)-1); + Resize((int)numElements - (int)buffer->numElements, (asUINT)-1); } void CScriptArray::RemoveRange(asUINT start, asUINT count) { - if (count == 0) - return; + if (count == 0) + return; - if( buffer == 0 || start > buffer->numElements ) - { - // If this is called from a script we raise a script exception - asIScriptContext *ctx = asGetActiveContext(); - if (ctx) - ctx->SetException("Index out of bounds"); - return; - } + if( buffer == 0 || start > buffer->numElements ) + { + // If this is called from a script we raise a script exception + asIScriptContext *ctx = asGetActiveContext(); + if (ctx) + ctx->SetException("Index out of bounds"); + return; + } - // Cap count to the end of the array - if (start + count > buffer->numElements) - count = buffer->numElements - start; + // Cap count to the end of the array + if (start + count > buffer->numElements) + count = buffer->numElements - start; - // Destroy the elements that are being removed - Destruct(buffer, start, start + count); + // Destroy the elements that are being removed + Destruct(buffer, start, start + count); - // Compact the elements - // As objects in arrays of objects are not stored inline, it is safe to use memmove here - // since we're just copying the pointers to objects and not the actual objects. - memmove(buffer->data + start*elementSize, buffer->data + (start + count)*elementSize, (buffer->numElements - start - count)*elementSize); - buffer->numElements -= count; + // Compact the elements + // As objects in arrays of objects are not stored inline, it is safe to use memmove here + // since we're just copying the pointers to objects and not the actual objects. + memmove(buffer->data + start*elementSize, buffer->data + (start + count)*elementSize, (buffer->numElements - start - count)*elementSize); + buffer->numElements -= count; } // Internal void CScriptArray::Resize(int delta, asUINT at) { - if( delta < 0 ) - { - if( -delta > (int)buffer->numElements ) - delta = -(int)buffer->numElements; - if( at > buffer->numElements + delta ) - at = buffer->numElements + delta; - } - else if( delta > 0 ) - { - // Make sure the array size isn't too large for us to handle - if( delta > 0 && !CheckMaxSize(buffer->numElements + delta) ) - return; + if( delta < 0 ) + { + if( -delta > (int)buffer->numElements ) + delta = -(int)buffer->numElements; + if( at > buffer->numElements + delta ) + at = buffer->numElements + delta; + } + else if( delta > 0 ) + { + // Make sure the array size isn't too large for us to handle + if( delta > 0 && !CheckMaxSize(buffer->numElements + delta) ) + return; - if( at > buffer->numElements ) - at = buffer->numElements; - } + if( at > buffer->numElements ) + at = buffer->numElements; + } - if( delta == 0 ) return; + if( delta == 0 ) return; - if( buffer->maxElements < buffer->numElements + delta ) - { - // Allocate memory for the buffer - SArrayBuffer *newBuffer = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1 + elementSize*(buffer->numElements + delta))); - if( newBuffer ) - { - newBuffer->numElements = buffer->numElements + delta; - newBuffer->maxElements = newBuffer->numElements; - } - else - { - // Out of memory - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); - return; - } + if( buffer->maxElements < buffer->numElements + delta ) + { + // Allocate memory for the buffer + SArrayBuffer *newBuffer = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1 + elementSize*(buffer->numElements + delta))); + if( newBuffer ) + { + newBuffer->numElements = buffer->numElements + delta; + newBuffer->maxElements = newBuffer->numElements; + } + else + { + // Out of memory + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); + return; + } - // As objects in arrays of objects are not stored inline, it is safe to use memcpy here - // since we're just copying the pointers to objects and not the actual objects. - memcpy(newBuffer->data, buffer->data, at*elementSize); - if( at < buffer->numElements ) - memcpy(newBuffer->data + (at+delta)*elementSize, buffer->data + at*elementSize, (buffer->numElements-at)*elementSize); + // As objects in arrays of objects are not stored inline, it is safe to use memcpy here + // since we're just copying the pointers to objects and not the actual objects. + memcpy(newBuffer->data, buffer->data, at*elementSize); + if( at < buffer->numElements ) + memcpy(newBuffer->data + (at+delta)*elementSize, buffer->data + at*elementSize, (buffer->numElements-at)*elementSize); - // Initialize the new elements with default values - Construct(newBuffer, at, at+delta); + // Initialize the new elements with default values + Construct(newBuffer, at, at+delta); - // Release the old buffer - userFree(buffer); + // Release the old buffer + userFree(buffer); - buffer = newBuffer; - } - else if( delta < 0 ) - { - Destruct(buffer, at, at-delta); - // As objects in arrays of objects are not stored inline, it is safe to use memmove here - // since we're just copying the pointers to objects and not the actual objects. - memmove(buffer->data + at*elementSize, buffer->data + (at-delta)*elementSize, (buffer->numElements - (at-delta))*elementSize); - buffer->numElements += delta; - } - else - { - // As objects in arrays of objects are not stored inline, it is safe to use memmove here - // since we're just copying the pointers to objects and not the actual objects. - memmove(buffer->data + (at+delta)*elementSize, buffer->data + at*elementSize, (buffer->numElements - at)*elementSize); - Construct(buffer, at, at+delta); - buffer->numElements += delta; - } + buffer = newBuffer; + } + else if( delta < 0 ) + { + Destruct(buffer, at, at-delta); + // As objects in arrays of objects are not stored inline, it is safe to use memmove here + // since we're just copying the pointers to objects and not the actual objects. + memmove(buffer->data + at*elementSize, buffer->data + (at-delta)*elementSize, (buffer->numElements - (at-delta))*elementSize); + buffer->numElements += delta; + } + else + { + // As objects in arrays of objects are not stored inline, it is safe to use memmove here + // since we're just copying the pointers to objects and not the actual objects. + memmove(buffer->data + (at+delta)*elementSize, buffer->data + at*elementSize, (buffer->numElements - at)*elementSize); + Construct(buffer, at, at+delta); + buffer->numElements += delta; + } } // internal bool CScriptArray::CheckMaxSize(asUINT numElements) { - // This code makes sure the size of the buffer that is allocated - // for the array doesn't overflow and becomes smaller than requested + // This code makes sure the size of the buffer that is allocated + // for the array doesn't overflow and becomes smaller than requested - asUINT maxSize = 0xFFFFFFFFul - sizeof(SArrayBuffer) + 1; - if( elementSize > 0 ) - maxSize /= elementSize; + asUINT maxSize = 0xFFFFFFFFul - sizeof(SArrayBuffer) + 1; + if( elementSize > 0 ) + maxSize /= elementSize; - if( numElements > maxSize ) - { - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Too large array size"); + if( numElements > maxSize ) + { + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Too large array size"); - return false; - } + return false; + } - // OK - return true; + // OK + return true; } asITypeInfo *CScriptArray::GetArrayObjectType() const { - return objType; + return objType; } int CScriptArray::GetArrayTypeId() const { - return objType->GetTypeId(); + return objType->GetTypeId(); } int CScriptArray::GetElementTypeId() const { - return subTypeId; + return subTypeId; } void CScriptArray::InsertAt(asUINT index, void *value) { - if( index > buffer->numElements ) - { - // If this is called from a script we raise a script exception - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Index out of bounds"); - return; - } + if( index > buffer->numElements ) + { + // If this is called from a script we raise a script exception + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Index out of bounds"); + return; + } - // Make room for the new element - Resize(1, index); + // Make room for the new element + Resize(1, index); - // Set the value of the new element - SetValue(index, value); + // Set the value of the new element + SetValue(index, value); } void CScriptArray::InsertAt(asUINT index, const CScriptArray &arr) { - if (index > buffer->numElements) - { - asIScriptContext *ctx = asGetActiveContext(); - if (ctx) - ctx->SetException("Index out of bounds"); - return; - } + if (index > buffer->numElements) + { + asIScriptContext *ctx = asGetActiveContext(); + if (ctx) + ctx->SetException("Index out of bounds"); + return; + } - if (objType != arr.objType) - { - // This shouldn't really be possible to happen when - // called from a script, but let's check for it anyway - asIScriptContext *ctx = asGetActiveContext(); - if (ctx) - ctx->SetException("Mismatching array types"); - return; - } + if (objType != arr.objType) + { + // This shouldn't really be possible to happen when + // called from a script, but let's check for it anyway + asIScriptContext *ctx = asGetActiveContext(); + if (ctx) + ctx->SetException("Mismatching array types"); + return; + } - asUINT elements = arr.GetSize(); - Resize(elements, index); - if (&arr != this) - { - for (asUINT n = 0; n < arr.GetSize(); n++) - { - // This const cast is allowed, since we know the - // value will only be used to make a copy of it - void *value = const_cast(arr.At(n)); - SetValue(index + n, value); - } - } - else - { - // The array that is being inserted is the same as this one. - // So we should iterate over the elements before the index, - // and then the elements after - for (asUINT n = 0; n < index; n++) - { - // This const cast is allowed, since we know the - // value will only be used to make a copy of it - void *value = const_cast(arr.At(n)); - SetValue(index + n, value); - } + asUINT elements = arr.GetSize(); + Resize(elements, index); + if (&arr != this) + { + for (asUINT n = 0; n < arr.GetSize(); n++) + { + // This const cast is allowed, since we know the + // value will only be used to make a copy of it + void *value = const_cast(arr.At(n)); + SetValue(index + n, value); + } + } + else + { + // The array that is being inserted is the same as this one. + // So we should iterate over the elements before the index, + // and then the elements after + for (asUINT n = 0; n < index; n++) + { + // This const cast is allowed, since we know the + // value will only be used to make a copy of it + void *value = const_cast(arr.At(n)); + SetValue(index + n, value); + } - for (asUINT n = index + elements, m = 0; n < arr.GetSize(); n++, m++) - { - // This const cast is allowed, since we know the - // value will only be used to make a copy of it - void *value = const_cast(arr.At(n)); - SetValue(index + index + m, value); - } - } + for (asUINT n = index + elements, m = 0; n < arr.GetSize(); n++, m++) + { + // This const cast is allowed, since we know the + // value will only be used to make a copy of it + void *value = const_cast(arr.At(n)); + SetValue(index + index + m, value); + } + } } void CScriptArray::InsertLast(void *value) { - InsertAt(buffer->numElements, value); + InsertAt(buffer->numElements, value); } void CScriptArray::RemoveAt(asUINT index) { - if( index >= buffer->numElements ) - { - // If this is called from a script we raise a script exception - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Index out of bounds"); - return; - } + if( index >= buffer->numElements ) + { + // If this is called from a script we raise a script exception + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Index out of bounds"); + return; + } - // Remove the element - Resize(-1, index); + // Remove the element + Resize(-1, index); } void CScriptArray::RemoveLast() { - RemoveAt(buffer->numElements-1); + RemoveAt(buffer->numElements-1); } // Return a pointer to the array element. Returns 0 if the index is out of bounds const void *CScriptArray::At(asUINT index) const { - if( buffer == 0 || index >= buffer->numElements ) - { - // If this is called from a script we raise a script exception - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Index out of bounds"); - return 0; - } + if( buffer == 0 || index >= buffer->numElements ) + { + // If this is called from a script we raise a script exception + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Index out of bounds"); + return 0; + } - if( (subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) - return *(void**)(buffer->data + elementSize*index); - else - return buffer->data + elementSize*index; + if( (subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) + return *(void**)(buffer->data + elementSize*index); + else + return buffer->data + elementSize*index; } void *CScriptArray::At(asUINT index) { - return const_cast(const_cast(this)->At(index)); + return const_cast(const_cast(this)->At(index)); } void *CScriptArray::GetBuffer() { - return buffer->data; + return buffer->data; } // internal void CScriptArray::CreateBuffer(SArrayBuffer **buf, asUINT numElements) { - *buf = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1+elementSize*numElements)); + *buf = reinterpret_cast(userAlloc(sizeof(SArrayBuffer)-1+elementSize*numElements)); - if( *buf ) - { - (*buf)->numElements = numElements; - (*buf)->maxElements = numElements; - Construct(*buf, 0, numElements); - } - else - { - // Oops, out of memory - asIScriptContext *ctx = asGetActiveContext(); - if( ctx ) - ctx->SetException("Out of memory"); - } + if( *buf ) + { + (*buf)->numElements = numElements; + (*buf)->maxElements = numElements; + Construct(*buf, 0, numElements); + } + else + { + // Oops, out of memory + asIScriptContext *ctx = asGetActiveContext(); + if( ctx ) + ctx->SetException("Out of memory"); + } } // internal void CScriptArray::DeleteBuffer(SArrayBuffer *buf) { - Destruct(buf, 0, buf->numElements); + Destruct(buf, 0, buf->numElements); - // Free the buffer - userFree(buf); + // Free the buffer + userFree(buf); } // internal void CScriptArray::Construct(SArrayBuffer *buf, asUINT start, asUINT end) { - if( (subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) - { - // Create an object using the default constructor/factory for each element - void **max = (void**)(buf->data + end * sizeof(void*)); - void **d = (void**)(buf->data + start * sizeof(void*)); + if( (subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) + { + // Create an object using the default constructor/factory for each element + void **max = (void**)(buf->data + end * sizeof(void*)); + void **d = (void**)(buf->data + start * sizeof(void*)); - asIScriptEngine *engine = objType->GetEngine(); - asITypeInfo *subType = objType->GetSubType(); + asIScriptEngine *engine = objType->GetEngine(); + asITypeInfo *subType = objType->GetSubType(); - for( ; d < max; d++ ) - { - *d = (void*)engine->CreateScriptObject(subType); - if( *d == 0 ) - { - // Set the remaining entries to null so the destructor - // won't attempt to destroy invalid objects later - memset(d, 0, sizeof(void*)*(max-d)); + for( ; d < max; d++ ) + { + *d = (void*)engine->CreateScriptObject(subType); + if( *d == 0 ) + { + // Set the remaining entries to null so the destructor + // won't attempt to destroy invalid objects later + memset(d, 0, sizeof(void*)*(max-d)); - // There is no need to set an exception on the context, - // as CreateScriptObject has already done that - return; - } - } - } - else - { - // Set all elements to zero whether they are handles or primitives - void *d = (void*)(buf->data + start * elementSize); - memset(d, 0, (end-start)*elementSize); - } + // There is no need to set an exception on the context, + // as CreateScriptObject has already done that + return; + } + } + } + else + { + // Set all elements to zero whether they are handles or primitives + void *d = (void*)(buf->data + start * elementSize); + memset(d, 0, (end-start)*elementSize); + } } // internal void CScriptArray::Destruct(SArrayBuffer *buf, asUINT start, asUINT end) { - if( subTypeId & asTYPEID_MASK_OBJECT ) - { - asIScriptEngine *engine = objType->GetEngine(); + if( subTypeId & asTYPEID_MASK_OBJECT ) + { + asIScriptEngine *engine = objType->GetEngine(); - void **max = (void**)(buf->data + end * sizeof(void*)); - void **d = (void**)(buf->data + start * sizeof(void*)); + void **max = (void**)(buf->data + end * sizeof(void*)); + void **d = (void**)(buf->data + start * sizeof(void*)); - for( ; d < max; d++ ) - { - if( *d ) - engine->ReleaseScriptObject(*d, objType->GetSubType()); - } - } + for( ; d < max; d++ ) + { + if( *d ) + engine->ReleaseScriptObject(*d, objType->GetSubType()); + } + } } // internal bool CScriptArray::Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache) { - if( !asc ) - { - // Swap items - const void *TEMP = a; - a = b; - b = TEMP; - } + if( !asc ) + { + // Swap items + const void *TEMP = a; + a = b; + b = TEMP; + } - if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) - { - // Simple compare of values - switch( subTypeId ) - { - #define COMPARE(T) *((T*)a) < *((T*)b) - case asTYPEID_BOOL: return COMPARE(bool); - case asTYPEID_INT8: return COMPARE(signed char); - case asTYPEID_UINT8: return COMPARE(unsigned char); - case asTYPEID_INT16: return COMPARE(signed short); - case asTYPEID_UINT16: return COMPARE(unsigned short); - case asTYPEID_INT32: return COMPARE(signed int); - case asTYPEID_UINT32: return COMPARE(unsigned int); - case asTYPEID_FLOAT: return COMPARE(float); - case asTYPEID_DOUBLE: return COMPARE(double); - default: return COMPARE(signed int); // All enums fall in this case - #undef COMPARE - } - } - else - { - int r = 0; + if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) + { + // Simple compare of values + switch( subTypeId ) + { + #define COMPARE(T) *((T*)a) < *((T*)b) + case asTYPEID_BOOL: return COMPARE(bool); + case asTYPEID_INT8: return COMPARE(signed char); + case asTYPEID_UINT8: return COMPARE(unsigned char); + case asTYPEID_INT16: return COMPARE(signed short); + case asTYPEID_UINT16: return COMPARE(unsigned short); + case asTYPEID_INT32: return COMPARE(signed int); + case asTYPEID_UINT32: return COMPARE(unsigned int); + case asTYPEID_FLOAT: return COMPARE(float); + case asTYPEID_DOUBLE: return COMPARE(double); + default: return COMPARE(signed int); // All enums fall in this case + #undef COMPARE + } + } + else + { + int r = 0; - if( subTypeId & asTYPEID_OBJHANDLE ) - { - // Allow sort to work even if the array contains null handles - if( *(void**)a == 0 ) return true; - if( *(void**)b == 0 ) return false; - } + if( subTypeId & asTYPEID_OBJHANDLE ) + { + // Allow sort to work even if the array contains null handles + if( *(void**)a == 0 ) return true; + if( *(void**)b == 0 ) return false; + } - // Execute object opCmp - if( cache && cache->cmpFunc ) - { - // TODO: Add proper error handling - r = ctx->Prepare(cache->cmpFunc); assert(r >= 0); + // Execute object opCmp + if( cache && cache->cmpFunc ) + { + // TODO: Add proper error handling + r = ctx->Prepare(cache->cmpFunc); assert(r >= 0); - if( subTypeId & asTYPEID_OBJHANDLE ) - { - r = ctx->SetObject(*((void**)a)); assert(r >= 0); - r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); - } - else - { - r = ctx->SetObject((void*)a); assert(r >= 0); - r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); - } + if( subTypeId & asTYPEID_OBJHANDLE ) + { + r = ctx->SetObject(*((void**)a)); assert(r >= 0); + r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); + } + else + { + r = ctx->SetObject((void*)a); assert(r >= 0); + r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); + } - r = ctx->Execute(); + r = ctx->Execute(); - if( r == asEXECUTION_FINISHED ) - { - return (int)ctx->GetReturnDWord() < 0; - } - } - } + if( r == asEXECUTION_FINISHED ) + { + return (int)ctx->GetReturnDWord() < 0; + } + } + } - return false; + return false; } void CScriptArray::Reverse() { - asUINT size = GetSize(); + asUINT size = GetSize(); - if( size >= 2 ) - { - asBYTE TEMP[16]; + if( size >= 2 ) + { + asBYTE TEMP[16]; - for( asUINT i = 0; i < size / 2; i++ ) - { - Copy(TEMP, GetArrayItemPointer(i)); - Copy(GetArrayItemPointer(i), GetArrayItemPointer(size - i - 1)); - Copy(GetArrayItemPointer(size - i - 1), TEMP); - } - } + for( asUINT i = 0; i < size / 2; i++ ) + { + Copy(TEMP, GetArrayItemPointer(i)); + Copy(GetArrayItemPointer(i), GetArrayItemPointer(size - i - 1)); + Copy(GetArrayItemPointer(size - i - 1), TEMP); + } + } } bool CScriptArray::operator==(const CScriptArray &other) const { - if( objType != other.objType ) - return false; + if( objType != other.objType ) + return false; - if( GetSize() != other.GetSize() ) - return false; + if( GetSize() != other.GetSize() ) + return false; - asIScriptContext *cmpContext = 0; - bool isNested = false; + asIScriptContext *cmpContext = 0; + bool isNested = false; - if( subTypeId & ~asTYPEID_MASK_SEQNBR ) - { - // Try to reuse the active context - cmpContext = asGetActiveContext(); - if( cmpContext ) - { - if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) - isNested = true; - else - cmpContext = 0; - } - if( cmpContext == 0 ) - { - // TODO: Ideally this context would be retrieved from a pool, so we don't have to - // create a new one everytime. We could keep a context with the array object - // but that would consume a lot of resources as each context is quite heavy. - cmpContext = objType->GetEngine()->CreateContext(); - } - } + if( subTypeId & ~asTYPEID_MASK_SEQNBR ) + { + // Try to reuse the active context + cmpContext = asGetActiveContext(); + if( cmpContext ) + { + if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) + isNested = true; + else + cmpContext = 0; + } + if( cmpContext == 0 ) + { + // TODO: Ideally this context would be retrieved from a pool, so we don't have to + // create a new one everytime. We could keep a context with the array object + // but that would consume a lot of resources as each context is quite heavy. + cmpContext = objType->GetEngine()->CreateContext(); + } + } - // Check if all elements are equal - bool isEqual = true; - SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); - for( asUINT n = 0; n < GetSize(); n++ ) - if( !Equals(At(n), other.At(n), cmpContext, cache) ) - { - isEqual = false; - break; - } + // Check if all elements are equal + bool isEqual = true; + SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); + for( asUINT n = 0; n < GetSize(); n++ ) + if( !Equals(At(n), other.At(n), cmpContext, cache) ) + { + isEqual = false; + break; + } - if( cmpContext ) - { - if( isNested ) - { - asEContextState state = cmpContext->GetState(); - cmpContext->PopState(); - if( state == asEXECUTION_ABORTED ) - cmpContext->Abort(); - } - else - cmpContext->Release(); - } + if( cmpContext ) + { + if( isNested ) + { + asEContextState state = cmpContext->GetState(); + cmpContext->PopState(); + if( state == asEXECUTION_ABORTED ) + cmpContext->Abort(); + } + else + cmpContext->Release(); + } - return isEqual; + return isEqual; } // internal bool CScriptArray::Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const { - if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) - { - // Simple compare of values - switch( subTypeId ) - { - #define COMPARE(T) *((T*)a) == *((T*)b) - case asTYPEID_BOOL: return COMPARE(bool); - case asTYPEID_INT8: return COMPARE(signed char); - case asTYPEID_UINT8: return COMPARE(unsigned char); - case asTYPEID_INT16: return COMPARE(signed short); - case asTYPEID_UINT16: return COMPARE(unsigned short); - case asTYPEID_INT32: return COMPARE(signed int); - case asTYPEID_UINT32: return COMPARE(unsigned int); - case asTYPEID_FLOAT: return COMPARE(float); - case asTYPEID_DOUBLE: return COMPARE(double); - default: return COMPARE(signed int); // All enums fall here - #undef COMPARE - } - } - else - { - int r = 0; + if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) + { + // Simple compare of values + switch( subTypeId ) + { + #define COMPARE(T) *((T*)a) == *((T*)b) + case asTYPEID_BOOL: return COMPARE(bool); + case asTYPEID_INT8: return COMPARE(signed char); + case asTYPEID_UINT8: return COMPARE(unsigned char); + case asTYPEID_INT16: return COMPARE(signed short); + case asTYPEID_UINT16: return COMPARE(unsigned short); + case asTYPEID_INT32: return COMPARE(signed int); + case asTYPEID_UINT32: return COMPARE(unsigned int); + case asTYPEID_FLOAT: return COMPARE(float); + case asTYPEID_DOUBLE: return COMPARE(double); + default: return COMPARE(signed int); // All enums fall here + #undef COMPARE + } + } + else + { + int r = 0; - if( subTypeId & asTYPEID_OBJHANDLE ) - { - // Allow the find to work even if the array contains null handles - if( *(void**)a == *(void**)b ) return true; - } + if( subTypeId & asTYPEID_OBJHANDLE ) + { + // Allow the find to work even if the array contains null handles + if( *(void**)a == *(void**)b ) return true; + } - // Execute object opEquals if available - if( cache && cache->eqFunc ) - { - // TODO: Add proper error handling - r = ctx->Prepare(cache->eqFunc); assert(r >= 0); + // Execute object opEquals if available + if( cache && cache->eqFunc ) + { + // TODO: Add proper error handling + r = ctx->Prepare(cache->eqFunc); assert(r >= 0); - if( subTypeId & asTYPEID_OBJHANDLE ) - { - r = ctx->SetObject(*((void**)a)); assert(r >= 0); - r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); - } - else - { - r = ctx->SetObject((void*)a); assert(r >= 0); - r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); - } + if( subTypeId & asTYPEID_OBJHANDLE ) + { + r = ctx->SetObject(*((void**)a)); assert(r >= 0); + r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); + } + else + { + r = ctx->SetObject((void*)a); assert(r >= 0); + r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); + } - r = ctx->Execute(); + r = ctx->Execute(); - if( r == asEXECUTION_FINISHED ) - return ctx->GetReturnByte() != 0; + if( r == asEXECUTION_FINISHED ) + return ctx->GetReturnByte() != 0; - return false; - } + return false; + } - // Execute object opCmp if available - if( cache && cache->cmpFunc ) - { - // TODO: Add proper error handling - r = ctx->Prepare(cache->cmpFunc); assert(r >= 0); + // Execute object opCmp if available + if( cache && cache->cmpFunc ) + { + // TODO: Add proper error handling + r = ctx->Prepare(cache->cmpFunc); assert(r >= 0); - if( subTypeId & asTYPEID_OBJHANDLE ) - { - r = ctx->SetObject(*((void**)a)); assert(r >= 0); - r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); - } - else - { - r = ctx->SetObject((void*)a); assert(r >= 0); - r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); - } + if( subTypeId & asTYPEID_OBJHANDLE ) + { + r = ctx->SetObject(*((void**)a)); assert(r >= 0); + r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0); + } + else + { + r = ctx->SetObject((void*)a); assert(r >= 0); + r = ctx->SetArgObject(0, (void*)b); assert(r >= 0); + } - r = ctx->Execute(); + r = ctx->Execute(); - if( r == asEXECUTION_FINISHED ) - return (int)ctx->GetReturnDWord() == 0; + if( r == asEXECUTION_FINISHED ) + return (int)ctx->GetReturnDWord() == 0; - return false; - } - } + return false; + } + } - return false; + return false; } int CScriptArray::FindByRef(void *ref) const { - return FindByRef(0, ref); + return FindByRef(0, ref); } int CScriptArray::FindByRef(asUINT startAt, void *ref) const { - // Find the matching element by its reference - asUINT size = GetSize(); - if( subTypeId & asTYPEID_OBJHANDLE ) - { - // Dereference the pointer - ref = *(void**)ref; - for( asUINT i = startAt; i < size; i++ ) - { - if( *(void**)At(i) == ref ) - return i; - } - } - else - { - // Compare the reference directly - for( asUINT i = startAt; i < size; i++ ) - { - if( At(i) == ref ) - return i; - } - } + // Find the matching element by its reference + asUINT size = GetSize(); + if( subTypeId & asTYPEID_OBJHANDLE ) + { + // Dereference the pointer + ref = *(void**)ref; + for( asUINT i = startAt; i < size; i++ ) + { + if( *(void**)At(i) == ref ) + return i; + } + } + else + { + // Compare the reference directly + for( asUINT i = startAt; i < size; i++ ) + { + if( At(i) == ref ) + return i; + } + } - return -1; + return -1; } int CScriptArray::Find(void *value) const { - return Find(0, value); + return Find(0, value); } int CScriptArray::Find(asUINT startAt, void *value) const { - // Check if the subtype really supports find() - // TODO: Can't this be done at compile time too by the template callback - SArrayCache *cache = 0; - if( subTypeId & ~asTYPEID_MASK_SEQNBR ) - { - cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); - if( !cache || (cache->cmpFunc == 0 && cache->eqFunc == 0) ) - { - asIScriptContext *ctx = asGetActiveContext(); - asITypeInfo* subType = objType->GetEngine()->GetTypeInfoById(subTypeId); + // Check if the subtype really supports find() + // TODO: Can't this be done at compile time too by the template callback + SArrayCache *cache = 0; + if( subTypeId & ~asTYPEID_MASK_SEQNBR ) + { + cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); + if( !cache || (cache->cmpFunc == 0 && cache->eqFunc == 0) ) + { + asIScriptContext *ctx = asGetActiveContext(); + asITypeInfo* subType = objType->GetEngine()->GetTypeInfoById(subTypeId); - // Throw an exception - if( ctx ) - { - char tmp[512]; + // Throw an exception + if( ctx ) + { + char tmp[512]; - if( cache && cache->eqFuncReturnCode == asMULTIPLE_FUNCTIONS ) + if( cache && cache->eqFuncReturnCode == asMULTIPLE_FUNCTIONS ) #if defined(_MSC_VER) && _MSC_VER >= 1500 && !defined(__S3E__) - sprintf_s(tmp, 512, "Type '%s' has multiple matching opEquals or opCmp methods", subType->GetName()); + sprintf_s(tmp, 512, "Type '%s' has multiple matching opEquals or opCmp methods", subType->GetName()); #else - sprintf(tmp, "Type '%s' has multiple matching opEquals or opCmp methods", subType->GetName()); + sprintf(tmp, "Type '%s' has multiple matching opEquals or opCmp methods", subType->GetName()); #endif - else + else #if defined(_MSC_VER) && _MSC_VER >= 1500 && !defined(__S3E__) - sprintf_s(tmp, 512, "Type '%s' does not have a matching opEquals or opCmp method", subType->GetName()); + sprintf_s(tmp, 512, "Type '%s' does not have a matching opEquals or opCmp method", subType->GetName()); #else - sprintf(tmp, "Type '%s' does not have a matching opEquals or opCmp method", subType->GetName()); + sprintf(tmp, "Type '%s' does not have a matching opEquals or opCmp method", subType->GetName()); #endif - ctx->SetException(tmp); - } + ctx->SetException(tmp); + } - return -1; - } - } + return -1; + } + } - asIScriptContext *cmpContext = 0; - bool isNested = false; + asIScriptContext *cmpContext = 0; + bool isNested = false; - if( subTypeId & ~asTYPEID_MASK_SEQNBR ) - { - // Try to reuse the active context - cmpContext = asGetActiveContext(); - if( cmpContext ) - { - if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) - isNested = true; - else - cmpContext = 0; - } - if( cmpContext == 0 ) - { - // TODO: Ideally this context would be retrieved from a pool, so we don't have to - // create a new one everytime. We could keep a context with the array object - // but that would consume a lot of resources as each context is quite heavy. - cmpContext = objType->GetEngine()->CreateContext(); - } - } + if( subTypeId & ~asTYPEID_MASK_SEQNBR ) + { + // Try to reuse the active context + cmpContext = asGetActiveContext(); + if( cmpContext ) + { + if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) + isNested = true; + else + cmpContext = 0; + } + if( cmpContext == 0 ) + { + // TODO: Ideally this context would be retrieved from a pool, so we don't have to + // create a new one everytime. We could keep a context with the array object + // but that would consume a lot of resources as each context is quite heavy. + cmpContext = objType->GetEngine()->CreateContext(); + } + } - // Find the matching element - int ret = -1; - asUINT size = GetSize(); + // Find the matching element + int ret = -1; + asUINT size = GetSize(); - for( asUINT i = startAt; i < size; i++ ) - { - // value passed by reference - if( Equals(At(i), value, cmpContext, cache) ) - { - ret = (int)i; - break; - } - } + for( asUINT i = startAt; i < size; i++ ) + { + // value passed by reference + if( Equals(At(i), value, cmpContext, cache) ) + { + ret = (int)i; + break; + } + } - if( cmpContext ) - { - if( isNested ) - { - asEContextState state = cmpContext->GetState(); - cmpContext->PopState(); - if( state == asEXECUTION_ABORTED ) - cmpContext->Abort(); - } - else - cmpContext->Release(); - } + if( cmpContext ) + { + if( isNested ) + { + asEContextState state = cmpContext->GetState(); + cmpContext->PopState(); + if( state == asEXECUTION_ABORTED ) + cmpContext->Abort(); + } + else + cmpContext->Release(); + } - return ret; + return ret; } @@ -1357,7 +1357,7 @@ int CScriptArray::Find(asUINT startAt, void *value) const // the heap and the array stores the pointers to the objects void CScriptArray::Copy(void *dst, void *src) { - memcpy(dst, src, elementSize); + memcpy(dst, src, elementSize); } @@ -1365,475 +1365,475 @@ void CScriptArray::Copy(void *dst, void *src) // Return pointer to array item (object handle or primitive value) void *CScriptArray::GetArrayItemPointer(int index) { - return buffer->data + index * elementSize; + return buffer->data + index * elementSize; } // internal // Return pointer to data in buffer (object or primitive) void *CScriptArray::GetDataPointer(void *buf) { - if ((subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) - { - // Real address of object - return reinterpret_cast(*(size_t*)buf); - } - else - { - // Primitive is just a raw data - return buf; - } + if ((subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) ) + { + // Real address of object + return reinterpret_cast(*(size_t*)buf); + } + else + { + // Primitive is just a raw data + return buf; + } } // Sort ascending void CScriptArray::SortAsc() { - Sort(0, GetSize(), true); + Sort(0, GetSize(), true); } // Sort ascending void CScriptArray::SortAsc(asUINT startAt, asUINT count) { - Sort(startAt, count, true); + Sort(startAt, count, true); } // Sort descending void CScriptArray::SortDesc() { - Sort(0, GetSize(), false); + Sort(0, GetSize(), false); } // Sort descending void CScriptArray::SortDesc(asUINT startAt, asUINT count) { - Sort(startAt, count, false); + Sort(startAt, count, false); } // internal void CScriptArray::Sort(asUINT startAt, asUINT count, bool asc) { - // Subtype isn't primitive and doesn't have opCmp - SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); - if( subTypeId & ~asTYPEID_MASK_SEQNBR ) - { - if( !cache || cache->cmpFunc == 0 ) - { - asIScriptContext *ctx = asGetActiveContext(); - asITypeInfo* subType = objType->GetEngine()->GetTypeInfoById(subTypeId); + // Subtype isn't primitive and doesn't have opCmp + SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); + if( subTypeId & ~asTYPEID_MASK_SEQNBR ) + { + if( !cache || cache->cmpFunc == 0 ) + { + asIScriptContext *ctx = asGetActiveContext(); + asITypeInfo* subType = objType->GetEngine()->GetTypeInfoById(subTypeId); - // Throw an exception - if( ctx ) - { - char tmp[512]; + // Throw an exception + if( ctx ) + { + char tmp[512]; - if( cache && cache->cmpFuncReturnCode == asMULTIPLE_FUNCTIONS ) + if( cache && cache->cmpFuncReturnCode == asMULTIPLE_FUNCTIONS ) #if defined(_MSC_VER) && _MSC_VER >= 1500 && !defined(__S3E__) - sprintf_s(tmp, 512, "Type '%s' has multiple matching opCmp methods", subType->GetName()); + sprintf_s(tmp, 512, "Type '%s' has multiple matching opCmp methods", subType->GetName()); #else - sprintf(tmp, "Type '%s' has multiple matching opCmp methods", subType->GetName()); + sprintf(tmp, "Type '%s' has multiple matching opCmp methods", subType->GetName()); #endif - else + else #if defined(_MSC_VER) && _MSC_VER >= 1500 && !defined(__S3E__) - sprintf_s(tmp, 512, "Type '%s' does not have a matching opCmp method", subType->GetName()); + sprintf_s(tmp, 512, "Type '%s' does not have a matching opCmp method", subType->GetName()); #else - sprintf(tmp, "Type '%s' does not have a matching opCmp method", subType->GetName()); + sprintf(tmp, "Type '%s' does not have a matching opCmp method", subType->GetName()); #endif - ctx->SetException(tmp); - } + ctx->SetException(tmp); + } - return; - } - } + return; + } + } - // No need to sort - if( count < 2 ) - { - return; - } + // No need to sort + if( count < 2 ) + { + return; + } - int start = startAt; - int end = startAt + count; + int start = startAt; + int end = startAt + count; - // Check if we could access invalid item while sorting - if( start >= (int)buffer->numElements || end > (int)buffer->numElements ) - { - asIScriptContext *ctx = asGetActiveContext(); + // Check if we could access invalid item while sorting + if( start >= (int)buffer->numElements || end > (int)buffer->numElements ) + { + asIScriptContext *ctx = asGetActiveContext(); - // Throw an exception - if( ctx ) - { - ctx->SetException("Index out of bounds"); - } + // Throw an exception + if( ctx ) + { + ctx->SetException("Index out of bounds"); + } - return; - } + return; + } - asBYTE tmp[16]; - asIScriptContext *cmpContext = 0; - bool isNested = false; + asBYTE tmp[16]; + asIScriptContext *cmpContext = 0; + bool isNested = false; - if( subTypeId & ~asTYPEID_MASK_SEQNBR ) - { - // Try to reuse the active context - cmpContext = asGetActiveContext(); - if( cmpContext ) - { - if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) - isNested = true; - else - cmpContext = 0; - } - if( cmpContext == 0 ) - { - cmpContext = objType->GetEngine()->RequestContext(); - } - } + if( subTypeId & ~asTYPEID_MASK_SEQNBR ) + { + // Try to reuse the active context + cmpContext = asGetActiveContext(); + if( cmpContext ) + { + if( cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0 ) + isNested = true; + else + cmpContext = 0; + } + if( cmpContext == 0 ) + { + cmpContext = objType->GetEngine()->RequestContext(); + } + } - // Insertion sort - for( int i = start + 1; i < end; i++ ) - { - Copy(tmp, GetArrayItemPointer(i)); + // Insertion sort + for( int i = start + 1; i < end; i++ ) + { + Copy(tmp, GetArrayItemPointer(i)); - int j = i - 1; + int j = i - 1; - while( j >= start && Less(GetDataPointer(tmp), At(j), asc, cmpContext, cache) ) - { - Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j)); - j--; - } + while( j >= start && Less(GetDataPointer(tmp), At(j), asc, cmpContext, cache) ) + { + Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j)); + j--; + } - Copy(GetArrayItemPointer(j + 1), tmp); - } + Copy(GetArrayItemPointer(j + 1), tmp); + } - if( cmpContext ) - { - if( isNested ) - { - asEContextState state = cmpContext->GetState(); - cmpContext->PopState(); - if( state == asEXECUTION_ABORTED ) - cmpContext->Abort(); - } - else - objType->GetEngine()->ReturnContext(cmpContext); - } + if( cmpContext ) + { + if( isNested ) + { + asEContextState state = cmpContext->GetState(); + cmpContext->PopState(); + if( state == asEXECUTION_ABORTED ) + cmpContext->Abort(); + } + else + objType->GetEngine()->ReturnContext(cmpContext); + } } // Sort with script callback for comparing elements void CScriptArray::Sort(asIScriptFunction *func, asUINT startAt, asUINT count) { - // No need to sort - if (count < 2) - return; + // No need to sort + if (count < 2) + return; - // Check if we could access invalid item while sorting - asUINT start = startAt; - asUINT end = asQWORD(startAt) + asQWORD(count) >= (asQWORD(1)<<32) ? 0xFFFFFFFF : startAt + count; - if (end > buffer->numElements) - end = buffer->numElements; + // Check if we could access invalid item while sorting + asUINT start = startAt; + asUINT end = asQWORD(startAt) + asQWORD(count) >= (asQWORD(1)<<32) ? 0xFFFFFFFF : startAt + count; + if (end > buffer->numElements) + end = buffer->numElements; - if (start >= buffer->numElements) - { - asIScriptContext *ctx = asGetActiveContext(); + if (start >= buffer->numElements) + { + asIScriptContext *ctx = asGetActiveContext(); - // Throw an exception - if (ctx) - ctx->SetException("Index out of bounds"); + // Throw an exception + if (ctx) + ctx->SetException("Index out of bounds"); - return; - } + return; + } - asBYTE tmp[16]; - asIScriptContext *cmpContext = 0; - bool isNested = false; + asBYTE tmp[16]; + asIScriptContext *cmpContext = 0; + bool isNested = false; - // Try to reuse the active context - cmpContext = asGetActiveContext(); - if (cmpContext) - { - if (cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0) - isNested = true; - else - cmpContext = 0; - } - if (cmpContext == 0) - cmpContext = objType->GetEngine()->RequestContext(); + // Try to reuse the active context + cmpContext = asGetActiveContext(); + if (cmpContext) + { + if (cmpContext->GetEngine() == objType->GetEngine() && cmpContext->PushState() >= 0) + isNested = true; + else + cmpContext = 0; + } + if (cmpContext == 0) + cmpContext = objType->GetEngine()->RequestContext(); - // Insertion sort - for (asUINT i = start + 1; i < end; i++) - { - Copy(tmp, GetArrayItemPointer(i)); + // Insertion sort + for (asUINT i = start + 1; i < end; i++) + { + Copy(tmp, GetArrayItemPointer(i)); - asUINT j = i - 1; + asUINT j = i - 1; - while (j != 0xFFFFFFFF && j >= start ) - { - cmpContext->Prepare(func); - cmpContext->SetArgAddress(0, GetDataPointer(tmp)); - cmpContext->SetArgAddress(1, At(j)); - int r = cmpContext->Execute(); - if (r != asEXECUTION_FINISHED) - break; - if (*(bool*)(cmpContext->GetAddressOfReturnValue())) - { - Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j)); - j--; - } - else - break; - } + while (j != 0xFFFFFFFF && j >= start ) + { + cmpContext->Prepare(func); + cmpContext->SetArgAddress(0, GetDataPointer(tmp)); + cmpContext->SetArgAddress(1, At(j)); + int r = cmpContext->Execute(); + if (r != asEXECUTION_FINISHED) + break; + if (*(bool*)(cmpContext->GetAddressOfReturnValue())) + { + Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j)); + j--; + } + else + break; + } - Copy(GetArrayItemPointer(j + 1), tmp); - } + Copy(GetArrayItemPointer(j + 1), tmp); + } - if (cmpContext) - { - if (isNested) - { - asEContextState state = cmpContext->GetState(); - cmpContext->PopState(); - if (state == asEXECUTION_ABORTED) - cmpContext->Abort(); - } - else - objType->GetEngine()->ReturnContext(cmpContext); - } + if (cmpContext) + { + if (isNested) + { + asEContextState state = cmpContext->GetState(); + cmpContext->PopState(); + if (state == asEXECUTION_ABORTED) + cmpContext->Abort(); + } + else + objType->GetEngine()->ReturnContext(cmpContext); + } } // internal void CScriptArray::CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src) { - asIScriptEngine *engine = objType->GetEngine(); - if( subTypeId & asTYPEID_OBJHANDLE ) - { - // Copy the references and increase the reference counters - if( dst->numElements > 0 && src->numElements > 0 ) - { - int count = dst->numElements > src->numElements ? src->numElements : dst->numElements; + asIScriptEngine *engine = objType->GetEngine(); + if( subTypeId & asTYPEID_OBJHANDLE ) + { + // Copy the references and increase the reference counters + if( dst->numElements > 0 && src->numElements > 0 ) + { + int count = dst->numElements > src->numElements ? src->numElements : dst->numElements; - void **max = (void**)(dst->data + count * sizeof(void*)); - void **d = (void**)dst->data; - void **s = (void**)src->data; + void **max = (void**)(dst->data + count * sizeof(void*)); + void **d = (void**)dst->data; + void **s = (void**)src->data; - for( ; d < max; d++, s++ ) - { - void *tmp = *d; - *d = *s; - if( *d ) - engine->AddRefScriptObject(*d, objType->GetSubType()); - // Release the old ref after incrementing the new to avoid problem incase it is the same ref - if( tmp ) - engine->ReleaseScriptObject(tmp, objType->GetSubType()); - } - } - } - else - { - if( dst->numElements > 0 && src->numElements > 0 ) - { - int count = dst->numElements > src->numElements ? src->numElements : dst->numElements; - if( subTypeId & asTYPEID_MASK_OBJECT ) - { - // Call the assignment operator on all of the objects - void **max = (void**)(dst->data + count * sizeof(void*)); - void **d = (void**)dst->data; - void **s = (void**)src->data; + for( ; d < max; d++, s++ ) + { + void *tmp = *d; + *d = *s; + if( *d ) + engine->AddRefScriptObject(*d, objType->GetSubType()); + // Release the old ref after incrementing the new to avoid problem incase it is the same ref + if( tmp ) + engine->ReleaseScriptObject(tmp, objType->GetSubType()); + } + } + } + else + { + if( dst->numElements > 0 && src->numElements > 0 ) + { + int count = dst->numElements > src->numElements ? src->numElements : dst->numElements; + if( subTypeId & asTYPEID_MASK_OBJECT ) + { + // Call the assignment operator on all of the objects + void **max = (void**)(dst->data + count * sizeof(void*)); + void **d = (void**)dst->data; + void **s = (void**)src->data; - asITypeInfo *subType = objType->GetSubType(); - for( ; d < max; d++, s++ ) - engine->AssignScriptObject(*d, *s, subType); - } - else - { - // Primitives are copied byte for byte - memcpy(dst->data, src->data, count*elementSize); - } - } - } + asITypeInfo *subType = objType->GetSubType(); + for( ; d < max; d++, s++ ) + engine->AssignScriptObject(*d, *s, subType); + } + else + { + // Primitives are copied byte for byte + memcpy(dst->data, src->data, count*elementSize); + } + } + } } // internal // Precache some info void CScriptArray::Precache() { - subTypeId = objType->GetSubTypeId(); + subTypeId = objType->GetSubTypeId(); - // Check if it is an array of objects. Only for these do we need to cache anything - // Type ids for primitives and enums only has the sequence number part - if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) - return; + // Check if it is an array of objects. Only for these do we need to cache anything + // Type ids for primitives and enums only has the sequence number part + if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) + return; - // The opCmp and opEquals methods are cached because the searching for the - // methods is quite time consuming if a lot of array objects are created. + // The opCmp and opEquals methods are cached because the searching for the + // methods is quite time consuming if a lot of array objects are created. - // First check if a cache already exists for this array type - SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); - if( cache ) return; + // First check if a cache already exists for this array type + SArrayCache *cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); + if( cache ) return; - // We need to make sure the cache is created only once, even - // if multiple threads reach the same point at the same time - asAcquireExclusiveLock(); + // We need to make sure the cache is created only once, even + // if multiple threads reach the same point at the same time + asAcquireExclusiveLock(); - // Now that we got the lock, we need to check again to make sure the - // cache wasn't created while we were waiting for the lock - cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); - if( cache ) - { - asReleaseExclusiveLock(); - return; - } + // Now that we got the lock, we need to check again to make sure the + // cache wasn't created while we were waiting for the lock + cache = reinterpret_cast(objType->GetUserData(ARRAY_CACHE)); + if( cache ) + { + asReleaseExclusiveLock(); + return; + } - // Create the cache - cache = reinterpret_cast(userAlloc(sizeof(SArrayCache))); - memset(cache, 0, sizeof(SArrayCache)); + // Create the cache + cache = reinterpret_cast(userAlloc(sizeof(SArrayCache))); + memset(cache, 0, sizeof(SArrayCache)); - // If the sub type is a handle to const, then the methods must be const too - bool mustBeConst = (subTypeId & asTYPEID_HANDLETOCONST) ? true : false; + // If the sub type is a handle to const, then the methods must be const too + bool mustBeConst = (subTypeId & asTYPEID_HANDLETOCONST) ? true : false; - asITypeInfo *subType = objType->GetEngine()->GetTypeInfoById(subTypeId); - if( subType ) - { - for( asUINT i = 0; i < subType->GetMethodCount(); i++ ) - { - asIScriptFunction *func = subType->GetMethodByIndex(i); + asITypeInfo *subType = objType->GetEngine()->GetTypeInfoById(subTypeId); + if( subType ) + { + for( asUINT i = 0; i < subType->GetMethodCount(); i++ ) + { + asIScriptFunction *func = subType->GetMethodByIndex(i); - if( func->GetParamCount() == 1 && (!mustBeConst || func->IsReadOnly()) ) - { - asDWORD flags = 0; - int returnTypeId = func->GetReturnTypeId(&flags); + if( func->GetParamCount() == 1 && (!mustBeConst || func->IsReadOnly()) ) + { + asDWORD flags = 0; + int returnTypeId = func->GetReturnTypeId(&flags); - // The method must not return a reference - if( flags != asTM_NONE ) - continue; + // The method must not return a reference + if( flags != asTM_NONE ) + continue; - // opCmp returns an int and opEquals returns a bool - bool isCmp = false, isEq = false; - if( returnTypeId == asTYPEID_INT32 && strcmp(func->GetName(), "opCmp") == 0 ) - isCmp = true; - if( returnTypeId == asTYPEID_BOOL && strcmp(func->GetName(), "opEquals") == 0 ) - isEq = true; + // opCmp returns an int and opEquals returns a bool + bool isCmp = false, isEq = false; + if( returnTypeId == asTYPEID_INT32 && strcmp(func->GetName(), "opCmp") == 0 ) + isCmp = true; + if( returnTypeId == asTYPEID_BOOL && strcmp(func->GetName(), "opEquals") == 0 ) + isEq = true; - if( !isCmp && !isEq ) - continue; + if( !isCmp && !isEq ) + continue; - // The parameter must either be a reference to the subtype or a handle to the subtype - int paramTypeId; - func->GetParam(0, ¶mTypeId, &flags); + // The parameter must either be a reference to the subtype or a handle to the subtype + int paramTypeId; + func->GetParam(0, ¶mTypeId, &flags); - if( (paramTypeId & ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) != (subTypeId & ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) ) - continue; + if( (paramTypeId & ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) != (subTypeId & ~(asTYPEID_OBJHANDLE|asTYPEID_HANDLETOCONST)) ) + continue; - if( (flags & asTM_INREF) ) - { - if( (paramTypeId & asTYPEID_OBJHANDLE) || (mustBeConst && !(flags & asTM_CONST)) ) - continue; - } - else if( paramTypeId & asTYPEID_OBJHANDLE ) - { - if( mustBeConst && !(paramTypeId & asTYPEID_HANDLETOCONST) ) - continue; - } - else - continue; + if( (flags & asTM_INREF) ) + { + if( (paramTypeId & asTYPEID_OBJHANDLE) || (mustBeConst && !(flags & asTM_CONST)) ) + continue; + } + else if( paramTypeId & asTYPEID_OBJHANDLE ) + { + if( mustBeConst && !(paramTypeId & asTYPEID_HANDLETOCONST) ) + continue; + } + else + continue; - if( isCmp ) - { - if( cache->cmpFunc || cache->cmpFuncReturnCode ) - { - cache->cmpFunc = 0; - cache->cmpFuncReturnCode = asMULTIPLE_FUNCTIONS; - } - else - cache->cmpFunc = func; - } - else if( isEq ) - { - if( cache->eqFunc || cache->eqFuncReturnCode ) - { - cache->eqFunc = 0; - cache->eqFuncReturnCode = asMULTIPLE_FUNCTIONS; - } - else - cache->eqFunc = func; - } - } - } - } + if( isCmp ) + { + if( cache->cmpFunc || cache->cmpFuncReturnCode ) + { + cache->cmpFunc = 0; + cache->cmpFuncReturnCode = asMULTIPLE_FUNCTIONS; + } + else + cache->cmpFunc = func; + } + else if( isEq ) + { + if( cache->eqFunc || cache->eqFuncReturnCode ) + { + cache->eqFunc = 0; + cache->eqFuncReturnCode = asMULTIPLE_FUNCTIONS; + } + else + cache->eqFunc = func; + } + } + } + } - if( cache->eqFunc == 0 && cache->eqFuncReturnCode == 0 ) - cache->eqFuncReturnCode = asNO_FUNCTION; - if( cache->cmpFunc == 0 && cache->cmpFuncReturnCode == 0 ) - cache->cmpFuncReturnCode = asNO_FUNCTION; + if( cache->eqFunc == 0 && cache->eqFuncReturnCode == 0 ) + cache->eqFuncReturnCode = asNO_FUNCTION; + if( cache->cmpFunc == 0 && cache->cmpFuncReturnCode == 0 ) + cache->cmpFuncReturnCode = asNO_FUNCTION; - // Set the user data only at the end so others that retrieve it will know it is complete - objType->SetUserData(cache, ARRAY_CACHE); + // Set the user data only at the end so others that retrieve it will know it is complete + objType->SetUserData(cache, ARRAY_CACHE); - asReleaseExclusiveLock(); + asReleaseExclusiveLock(); } // GC behaviour void CScriptArray::EnumReferences(asIScriptEngine *engine) { - // TODO: If garbage collection can be done from a separate thread, then this method must be - // protected so that it doesn't get lost during the iteration if the array is modified + // TODO: If garbage collection can be done from a separate thread, then this method must be + // protected so that it doesn't get lost during the iteration if the array is modified - // If the array is holding handles, then we need to notify the GC of them - if( subTypeId & asTYPEID_MASK_OBJECT ) - { - void **d = (void**)buffer->data; - for( asUINT n = 0; n < buffer->numElements; n++ ) - { - if( d[n] ) - engine->GCEnumCallback(d[n]); - } - } + // If the array is holding handles, then we need to notify the GC of them + if( subTypeId & asTYPEID_MASK_OBJECT ) + { + void **d = (void**)buffer->data; + for( asUINT n = 0; n < buffer->numElements; n++ ) + { + if( d[n] ) + engine->GCEnumCallback(d[n]); + } + } } // GC behaviour void CScriptArray::ReleaseAllHandles(asIScriptEngine *) { - // Resizing to zero will release everything - Resize(0); + // Resizing to zero will release everything + Resize(0); } void CScriptArray::AddRef() const { - // Clear the GC flag then increase the counter - gcFlag = false; - asAtomicInc(refCount); + // Clear the GC flag then increase the counter + gcFlag = false; + asAtomicInc(refCount); } void CScriptArray::Release() const { - // Clearing the GC flag then descrease the counter - gcFlag = false; - if( asAtomicDec(refCount) == 0 ) - { - // When reaching 0 no more references to this instance - // exists and the object should be destroyed - this->~CScriptArray(); - userFree(const_cast(this)); - } + // Clearing the GC flag then descrease the counter + gcFlag = false; + if( asAtomicDec(refCount) == 0 ) + { + // When reaching 0 no more references to this instance + // exists and the object should be destroyed + this->~CScriptArray(); + userFree(const_cast(this)); + } } // GC behaviour int CScriptArray::GetRefCount() { - return refCount; + return refCount; } // GC behaviour void CScriptArray::SetFlag() { - gcFlag = true; + gcFlag = true; } // GC behaviour bool CScriptArray::GetFlag() { - return gcFlag; + return gcFlag; } //-------------------------------------------- @@ -1841,304 +1841,304 @@ bool CScriptArray::GetFlag() static void ScriptArrayFactory_Generic(asIScriptGeneric *gen) { - asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); + asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti); } static void ScriptArrayFactory2_Generic(asIScriptGeneric *gen) { - asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); - asUINT length = gen->GetArgDWord(1); + asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); + asUINT length = gen->GetArgDWord(1); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, length); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, length); } static void ScriptArrayListFactory_Generic(asIScriptGeneric *gen) { - asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); - void *buf = gen->GetArgAddress(1); + asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); + void *buf = gen->GetArgAddress(1); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, buf); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, buf); } static void ScriptArrayFactoryDefVal_Generic(asIScriptGeneric *gen) { - asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); - asUINT length = gen->GetArgDWord(1); - void *defVal = gen->GetArgAddress(2); + asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); + asUINT length = gen->GetArgDWord(1); + void *defVal = gen->GetArgAddress(2); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, length, defVal); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = CScriptArray::Create(ti, length, defVal); } static void ScriptArrayTemplateCallback_Generic(asIScriptGeneric *gen) { - asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); - bool *dontGarbageCollect = *(bool**)gen->GetAddressOfArg(1); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = ScriptArrayTemplateCallback(ti, *dontGarbageCollect); + asITypeInfo *ti = *(asITypeInfo**)gen->GetAddressOfArg(0); + bool *dontGarbageCollect = *(bool**)gen->GetAddressOfArg(1); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = ScriptArrayTemplateCallback(ti, *dontGarbageCollect); } static void ScriptArrayAssignment_Generic(asIScriptGeneric *gen) { - CScriptArray *other = (CScriptArray*)gen->GetArgObject(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - *self = *other; - gen->SetReturnObject(self); + CScriptArray *other = (CScriptArray*)gen->GetArgObject(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + *self = *other; + gen->SetReturnObject(self); } static void ScriptArrayEquals_Generic(asIScriptGeneric *gen) { - CScriptArray *other = (CScriptArray*)gen->GetArgObject(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnByte(self->operator==(*other)); + CScriptArray *other = (CScriptArray*)gen->GetArgObject(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + gen->SetReturnByte(self->operator==(*other)); } static void ScriptArrayFind_Generic(asIScriptGeneric *gen) { - void *value = gen->GetArgAddress(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnDWord(self->Find(value)); + void *value = gen->GetArgAddress(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + gen->SetReturnDWord(self->Find(value)); } static void ScriptArrayFind2_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - void *value = gen->GetArgAddress(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnDWord(self->Find(index, value)); + asUINT index = gen->GetArgDWord(0); + void *value = gen->GetArgAddress(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + gen->SetReturnDWord(self->Find(index, value)); } static void ScriptArrayFindByRef_Generic(asIScriptGeneric *gen) { - void *value = gen->GetArgAddress(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnDWord(self->FindByRef(value)); + void *value = gen->GetArgAddress(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + gen->SetReturnDWord(self->FindByRef(value)); } static void ScriptArrayFindByRef2_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - void *value = gen->GetArgAddress(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnDWord(self->FindByRef(index, value)); + asUINT index = gen->GetArgDWord(0); + void *value = gen->GetArgAddress(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + gen->SetReturnDWord(self->FindByRef(index, value)); } static void ScriptArrayAt_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); + asUINT index = gen->GetArgDWord(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnAddress(self->At(index)); + gen->SetReturnAddress(self->At(index)); } static void ScriptArrayInsertAt_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - void *value = gen->GetArgAddress(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->InsertAt(index, value); + asUINT index = gen->GetArgDWord(0); + void *value = gen->GetArgAddress(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->InsertAt(index, value); } static void ScriptArrayInsertAtArray_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - CScriptArray *array = (CScriptArray*)gen->GetArgAddress(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->InsertAt(index, *array); + asUINT index = gen->GetArgDWord(0); + CScriptArray *array = (CScriptArray*)gen->GetArgAddress(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->InsertAt(index, *array); } static void ScriptArrayRemoveAt_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->RemoveAt(index); + asUINT index = gen->GetArgDWord(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->RemoveAt(index); } static void ScriptArrayRemoveRange_Generic(asIScriptGeneric *gen) { - asUINT start = gen->GetArgDWord(0); - asUINT count = gen->GetArgDWord(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->RemoveRange(start, count); + asUINT start = gen->GetArgDWord(0); + asUINT count = gen->GetArgDWord(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->RemoveRange(start, count); } static void ScriptArrayInsertLast_Generic(asIScriptGeneric *gen) { - void *value = gen->GetArgAddress(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->InsertLast(value); + void *value = gen->GetArgAddress(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->InsertLast(value); } static void ScriptArrayRemoveLast_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->RemoveLast(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->RemoveLast(); } static void ScriptArrayLength_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); - gen->SetReturnDWord(self->GetSize()); + gen->SetReturnDWord(self->GetSize()); } static void ScriptArrayResize_Generic(asIScriptGeneric *gen) { - asUINT size = gen->GetArgDWord(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); + asUINT size = gen->GetArgDWord(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->Resize(size); + self->Resize(size); } static void ScriptArrayReserve_Generic(asIScriptGeneric *gen) { - asUINT size = gen->GetArgDWord(0); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->Reserve(size); + asUINT size = gen->GetArgDWord(0); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->Reserve(size); } static void ScriptArraySortAsc_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->SortAsc(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->SortAsc(); } static void ScriptArrayReverse_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->Reverse(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->Reverse(); } static void ScriptArrayIsEmpty_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->IsEmpty(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->IsEmpty(); } static void ScriptArraySortAsc2_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - asUINT count = gen->GetArgDWord(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->SortAsc(index, count); + asUINT index = gen->GetArgDWord(0); + asUINT count = gen->GetArgDWord(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->SortAsc(index, count); } static void ScriptArraySortDesc_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->SortDesc(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->SortDesc(); } static void ScriptArraySortDesc2_Generic(asIScriptGeneric *gen) { - asUINT index = gen->GetArgDWord(0); - asUINT count = gen->GetArgDWord(1); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->SortDesc(index, count); + asUINT index = gen->GetArgDWord(0); + asUINT count = gen->GetArgDWord(1); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->SortDesc(index, count); } static void ScriptArraySortCallback_Generic(asIScriptGeneric *gen) { - asIScriptFunction *callback = (asIScriptFunction*)gen->GetArgAddress(0); - asUINT startAt = gen->GetArgDWord(1); - asUINT count = gen->GetArgDWord(2); - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->Sort(callback, startAt, count); + asIScriptFunction *callback = (asIScriptFunction*)gen->GetArgAddress(0); + asUINT startAt = gen->GetArgDWord(1); + asUINT count = gen->GetArgDWord(2); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->Sort(callback, startAt, count); } static void ScriptArrayAddRef_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->AddRef(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->AddRef(); } static void ScriptArrayRelease_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->Release(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->Release(); } static void ScriptArrayGetRefCount_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->GetRefCount(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->GetRefCount(); } static void ScriptArraySetFlag_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - self->SetFlag(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + self->SetFlag(); } static void ScriptArrayGetFlag_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->GetFlag(); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = self->GetFlag(); } static void ScriptArrayEnumReferences_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0); - self->EnumReferences(engine); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0); + self->EnumReferences(engine); } static void ScriptArrayReleaseAllHandles_Generic(asIScriptGeneric *gen) { - CScriptArray *self = (CScriptArray*)gen->GetObject(); - asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0); - self->ReleaseAllHandles(engine); + CScriptArray *self = (CScriptArray*)gen->GetObject(); + asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0); + self->ReleaseAllHandles(engine); } static void RegisterScriptArray_Generic(asIScriptEngine *engine) { - int r = 0; - UNUSED_VAR(r); + int r = 0; + UNUSED_VAR(r); - engine->SetTypeInfoUserDataCleanupCallback(CleanupTypeInfoArrayCache, ARRAY_CACHE); + engine->SetTypeInfoUserDataCleanupCallback(CleanupTypeInfoArrayCache, ARRAY_CACHE); - r = engine->RegisterObjectType("array", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptArrayTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectType("array", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptArrayTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in)", asFUNCTION(ScriptArrayFactory_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length)", asFUNCTION(ScriptArrayFactory2_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length, const T &in value)", asFUNCTION(ScriptArrayFactoryDefVal_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_LIST_FACTORY, "array@ f(int&in, int&in) {repeat T}", asFUNCTION(ScriptArrayListFactory_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptArrayAddRef_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptArrayRelease_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "T &opIndex(uint index)", asFUNCTION(ScriptArrayAt_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "const T &opIndex(uint index) const", asFUNCTION(ScriptArrayAt_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "array &opAssign(const array&in)", asFUNCTION(ScriptArrayAssignment_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in)", asFUNCTION(ScriptArrayFactory_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length)", asFUNCTION(ScriptArrayFactory2_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_FACTORY, "array@ f(int&in, uint length, const T &in value)", asFUNCTION(ScriptArrayFactoryDefVal_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_LIST_FACTORY, "array@ f(int&in, int&in) {repeat T}", asFUNCTION(ScriptArrayListFactory_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptArrayAddRef_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptArrayRelease_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "T &opIndex(uint index)", asFUNCTION(ScriptArrayAt_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "const T &opIndex(uint index) const", asFUNCTION(ScriptArrayAt_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "array &opAssign(const array&in)", asFUNCTION(ScriptArrayAssignment_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const T&in value)", asFUNCTION(ScriptArrayInsertAt_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const array& arr)", asFUNCTION(ScriptArrayInsertAtArray_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void insertLast(const T&in value)", asFUNCTION(ScriptArrayInsertLast_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "void removeAt(uint index)", asFUNCTION(ScriptArrayRemoveAt_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void removeLast()", asFUNCTION(ScriptArrayRemoveLast_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void removeRange(uint start, uint count)", asFUNCTION(ScriptArrayRemoveRange_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "uint length() const", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void reserve(uint length)", asFUNCTION(ScriptArrayReserve_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void resize(uint length)", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortAsc()", asFUNCTION(ScriptArraySortAsc_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortAsc(uint startAt, uint count)", asFUNCTION(ScriptArraySortAsc2_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortDesc()", asFUNCTION(ScriptArraySortDesc_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void sortDesc(uint startAt, uint count)", asFUNCTION(ScriptArraySortDesc2_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void reverse()", asFUNCTION(ScriptArrayReverse_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "int find(const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFind_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "int find(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFind2_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "int findByRef(const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef2_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "bool opEquals(const array&in) const", asFUNCTION(ScriptArrayEquals_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "bool isEmpty() const", asFUNCTION(ScriptArrayIsEmpty_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterFuncdef("bool array::less(const T&in a, const T&in b)"); - r = engine->RegisterObjectMethod("array", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asFUNCTION(ScriptArraySortCallback_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("array", "uint get_length() const", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("array", "void set_length(uint)", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ScriptArrayGetRefCount_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ScriptArraySetFlag_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ScriptArrayGetFlag_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptArrayEnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptArrayReleaseAllHandles_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const T&in value)", asFUNCTION(ScriptArrayInsertAt_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void insertAt(uint index, const array& arr)", asFUNCTION(ScriptArrayInsertAtArray_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void insertLast(const T&in value)", asFUNCTION(ScriptArrayInsertLast_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "void removeAt(uint index)", asFUNCTION(ScriptArrayRemoveAt_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void removeLast()", asFUNCTION(ScriptArrayRemoveLast_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void removeRange(uint start, uint count)", asFUNCTION(ScriptArrayRemoveRange_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "uint length() const", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void reserve(uint length)", asFUNCTION(ScriptArrayReserve_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void resize(uint length)", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortAsc()", asFUNCTION(ScriptArraySortAsc_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortAsc(uint startAt, uint count)", asFUNCTION(ScriptArraySortAsc2_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortDesc()", asFUNCTION(ScriptArraySortDesc_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void sortDesc(uint startAt, uint count)", asFUNCTION(ScriptArraySortDesc2_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void reverse()", asFUNCTION(ScriptArrayReverse_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "int find(const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFind_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "int find(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFind2_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "int findByRef(const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef2_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "bool opEquals(const array&in) const", asFUNCTION(ScriptArrayEquals_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "bool isEmpty() const", asFUNCTION(ScriptArrayIsEmpty_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterFuncdef("bool array::less(const T&in a, const T&in b)"); + r = engine->RegisterObjectMethod("array", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asFUNCTION(ScriptArraySortCallback_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("array", "uint get_length() const", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("array", "void set_length(uint)", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ScriptArrayGetRefCount_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ScriptArraySetFlag_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ScriptArrayGetFlag_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptArrayEnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("array", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptArrayReleaseAllHandles_Generic), asCALL_GENERIC); assert( r >= 0 ); } END_AS_NAMESPACE diff --git a/src/scriptengine/scriptarray.hpp b/src/scriptengine/scriptarray.hpp index e6eb2783a..0097a65c3 100644 --- a/src/scriptengine/scriptarray.hpp +++ b/src/scriptengine/scriptarray.hpp @@ -25,109 +25,109 @@ struct SArrayCache; class CScriptArray { public: - // Set the memory functions that should be used by all CScriptArrays - static void SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc); + // Set the memory functions that should be used by all CScriptArrays + static void SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc); - // Factory functions - static CScriptArray *Create(asITypeInfo *ot); - static CScriptArray *Create(asITypeInfo *ot, asUINT length); - static CScriptArray *Create(asITypeInfo *ot, asUINT length, void *defaultValue); - static CScriptArray *Create(asITypeInfo *ot, void *listBuffer); + // Factory functions + static CScriptArray *Create(asITypeInfo *ot); + static CScriptArray *Create(asITypeInfo *ot, asUINT length); + static CScriptArray *Create(asITypeInfo *ot, asUINT length, void *defaultValue); + static CScriptArray *Create(asITypeInfo *ot, void *listBuffer); - // Memory management - void AddRef() const; - void Release() const; + // Memory management + void AddRef() const; + void Release() const; - // Type information - asITypeInfo *GetArrayObjectType() const; - int GetArrayTypeId() const; - int GetElementTypeId() const; + // Type information + asITypeInfo *GetArrayObjectType() const; + int GetArrayTypeId() const; + int GetElementTypeId() const; - // Get the current size - asUINT GetSize() const; + // Get the current size + asUINT GetSize() const; - // Returns true if the array is empty - bool IsEmpty() const; + // Returns true if the array is empty + bool IsEmpty() const; - // Pre-allocates memory for elements - void Reserve(asUINT maxElements); + // Pre-allocates memory for elements + void Reserve(asUINT maxElements); - // Resize the array - void Resize(asUINT numElements); + // Resize the array + void Resize(asUINT numElements); - // Get a pointer to an element. Returns 0 if out of bounds - void *At(asUINT index); - const void *At(asUINT index) const; + // Get a pointer to an element. Returns 0 if out of bounds + void *At(asUINT index); + const void *At(asUINT index) const; - // Set value of an element. - // The value arg should be a pointer to the value that will be copied to the element. - // Remember, if the array holds handles the value parameter should be the - // address of the handle. The refCount of the object will also be incremented - void SetValue(asUINT index, void *value); + // Set value of an element. + // The value arg should be a pointer to the value that will be copied to the element. + // Remember, if the array holds handles the value parameter should be the + // address of the handle. The refCount of the object will also be incremented + void SetValue(asUINT index, void *value); - // Copy the contents of one array to another (only if the types are the same) - CScriptArray &operator=(const CScriptArray&); + // Copy the contents of one array to another (only if the types are the same) + CScriptArray &operator=(const CScriptArray&); - // Compare two arrays - bool operator==(const CScriptArray &) const; + // Compare two arrays + bool operator==(const CScriptArray &) const; - // Array manipulation - void InsertAt(asUINT index, void *value); - void InsertAt(asUINT index, const CScriptArray &arr); - void InsertLast(void *value); - void RemoveAt(asUINT index); - void RemoveLast(); - void RemoveRange(asUINT start, asUINT count); - void SortAsc(); - void SortDesc(); - void SortAsc(asUINT startAt, asUINT count); - void SortDesc(asUINT startAt, asUINT count); - void Sort(asUINT startAt, asUINT count, bool asc); - void Sort(asIScriptFunction *less, asUINT startAt, asUINT count); - void Reverse(); - int Find(void *value) const; - int Find(asUINT startAt, void *value) const; - int FindByRef(void *ref) const; - int FindByRef(asUINT startAt, void *ref) const; + // Array manipulation + void InsertAt(asUINT index, void *value); + void InsertAt(asUINT index, const CScriptArray &arr); + void InsertLast(void *value); + void RemoveAt(asUINT index); + void RemoveLast(); + void RemoveRange(asUINT start, asUINT count); + void SortAsc(); + void SortDesc(); + void SortAsc(asUINT startAt, asUINT count); + void SortDesc(asUINT startAt, asUINT count); + void Sort(asUINT startAt, asUINT count, bool asc); + void Sort(asIScriptFunction *less, asUINT startAt, asUINT count); + void Reverse(); + int Find(void *value) const; + int Find(asUINT startAt, void *value) const; + int FindByRef(void *ref) const; + int FindByRef(asUINT startAt, void *ref) const; - // Return the address of internal buffer for direct manipulation of elements - void *GetBuffer(); + // Return the address of internal buffer for direct manipulation of elements + void *GetBuffer(); - // GC methods - int GetRefCount(); - void SetFlag(); - bool GetFlag(); - void EnumReferences(asIScriptEngine *engine); - void ReleaseAllHandles(asIScriptEngine *engine); + // GC methods + int GetRefCount(); + void SetFlag(); + bool GetFlag(); + void EnumReferences(asIScriptEngine *engine); + void ReleaseAllHandles(asIScriptEngine *engine); protected: - mutable int refCount; - mutable bool gcFlag; - asITypeInfo *objType; - SArrayBuffer *buffer; - int elementSize; - int subTypeId; + mutable int refCount; + mutable bool gcFlag; + asITypeInfo *objType; + SArrayBuffer *buffer; + int elementSize; + int subTypeId; - // Constructors - CScriptArray(asITypeInfo *ot, void *initBuf); // Called from script when initialized with list - CScriptArray(asUINT length, asITypeInfo *ot); - CScriptArray(asUINT length, void *defVal, asITypeInfo *ot); - CScriptArray(const CScriptArray &other); - virtual ~CScriptArray(); + // Constructors + CScriptArray(asITypeInfo *ot, void *initBuf); // Called from script when initialized with list + CScriptArray(asUINT length, asITypeInfo *ot); + CScriptArray(asUINT length, void *defVal, asITypeInfo *ot); + CScriptArray(const CScriptArray &other); + virtual ~CScriptArray(); - bool Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache); - void *GetArrayItemPointer(int index); - void *GetDataPointer(void *buffer); - void Copy(void *dst, void *src); - void Precache(); - bool CheckMaxSize(asUINT numElements); - void Resize(int delta, asUINT at); - void CreateBuffer(SArrayBuffer **buf, asUINT numElements); - void DeleteBuffer(SArrayBuffer *buf); - void CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src); - void Construct(SArrayBuffer *buf, asUINT start, asUINT end); - void Destruct(SArrayBuffer *buf, asUINT start, asUINT end); - bool Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const; + bool Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache); + void *GetArrayItemPointer(int index); + void *GetDataPointer(void *buffer); + void Copy(void *dst, void *src); + void Precache(); + bool CheckMaxSize(asUINT numElements); + void Resize(int delta, asUINT at); + void CreateBuffer(SArrayBuffer **buf, asUINT numElements); + void DeleteBuffer(SArrayBuffer *buf); + void CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src); + void Construct(SArrayBuffer *buf, asUINT start, asUINT end); + void Destruct(SArrayBuffer *buf, asUINT start, asUINT end); + bool Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const; }; void RegisterScriptArray(asIScriptEngine *engine, bool defaultArray); diff --git a/src/scriptengine/scriptstdstring.cpp b/src/scriptengine/scriptstdstring.cpp index 4da068109..648ebd318 100644 --- a/src/scriptengine/scriptstdstring.cpp +++ b/src/scriptengine/scriptstdstring.cpp @@ -2,10 +2,10 @@ #include // assert() #include // std::stringstream #include // strstr() -#include // sprintf() +#include // sprintf() #include // strtod() #ifndef __psp2__ - #include // setlocale() + #include // setlocale() #endif using namespace std; @@ -31,57 +31,57 @@ END_AS_NAMESPACE class CStdStringFactory : public asIStringFactory { public: - CStdStringFactory() {} - ~CStdStringFactory() - { - // The script engine must release each string - // constant that it has requested - assert(stringCache.size() == 0); - } + CStdStringFactory() {} + ~CStdStringFactory() + { + // The script engine must release each string + // constant that it has requested + assert(stringCache.size() == 0); + } - const void *GetStringConstant(const char *data, asUINT length) - { - string str(data, length); - map_t::iterator it = stringCache.find(str); - if (it != stringCache.end()) - it->second++; - else - it = stringCache.insert(map_t::value_type(str, 1)).first; + const void *GetStringConstant(const char *data, asUINT length) + { + string str(data, length); + map_t::iterator it = stringCache.find(str); + if (it != stringCache.end()) + it->second++; + else + it = stringCache.insert(map_t::value_type(str, 1)).first; - return reinterpret_cast(&it->first); - } + return reinterpret_cast(&it->first); + } - int ReleaseStringConstant(const void *str) - { - if (str == 0) - return asERROR; + int ReleaseStringConstant(const void *str) + { + if (str == 0) + return asERROR; - map_t::iterator it = stringCache.find(*reinterpret_cast(str)); - if (it == stringCache.end()) - return asERROR; + map_t::iterator it = stringCache.find(*reinterpret_cast(str)); + if (it == stringCache.end()) + return asERROR; - it->second--; - if (it->second == 0) - stringCache.erase(it); - return asSUCCESS; - } + it->second--; + if (it->second == 0) + stringCache.erase(it); + return asSUCCESS; + } - int GetRawStringData(const void *str, char *data, asUINT *length) const - { - if (str == 0) - return asERROR; + int GetRawStringData(const void *str, char *data, asUINT *length) const + { + if (str == 0) + return asERROR; - if (length) - *length = (asUINT)reinterpret_cast(str)->length(); + if (length) + *length = (asUINT)reinterpret_cast(str)->length(); - if (data) - memcpy(data, reinterpret_cast(str)->c_str(), reinterpret_cast(str)->length()); + if (data) + memcpy(data, reinterpret_cast(str)->c_str(), reinterpret_cast(str)->length()); - return asSUCCESS; - } + return asSUCCESS; + } - // TODO: Make sure the access to the string cache is thread safe - map_t stringCache; + // TODO: Make sure the access to the string cache is thread safe + map_t stringCache; }; static CStdStringFactory stringFactory; @@ -89,213 +89,213 @@ static CStdStringFactory stringFactory; static void ConstructString(string *thisPointer) { - new(thisPointer) string(); + new(thisPointer) string(); } static void CopyConstructString(const string &other, string *thisPointer) { - new(thisPointer) string(other); + new(thisPointer) string(other); } static void DestructString(string *thisPointer) { - thisPointer->~string(); + thisPointer->~string(); } static string &AddAssignStringToString(const string &str, string &dest) { - // We don't register the method directly because some compilers - // and standard libraries inline the definition, resulting in the - // linker being unable to find the declaration. - // Example: CLang/LLVM with XCode 4.3 on OSX 10.7 - dest += str; - return dest; + // We don't register the method directly because some compilers + // and standard libraries inline the definition, resulting in the + // linker being unable to find the declaration. + // Example: CLang/LLVM with XCode 4.3 on OSX 10.7 + dest += str; + return dest; } // bool string::isEmpty() // bool string::empty() // if AS_USE_STLNAMES == 1 static bool StringIsEmpty(const string &str) { - // We don't register the method directly because some compilers - // and standard libraries inline the definition, resulting in the - // linker being unable to find the declaration - // Example: CLang/LLVM with XCode 4.3 on OSX 10.7 - return str.empty(); + // We don't register the method directly because some compilers + // and standard libraries inline the definition, resulting in the + // linker being unable to find the declaration + // Example: CLang/LLVM with XCode 4.3 on OSX 10.7 + return str.empty(); } static string &AssignUInt64ToString(asQWORD i, string &dest) { - ostringstream stream; - stream << i; - dest = stream.str(); - return dest; + ostringstream stream; + stream << i; + dest = stream.str(); + return dest; } static string &AddAssignUInt64ToString(asQWORD i, string &dest) { - ostringstream stream; - stream << i; - dest += stream.str(); - return dest; + ostringstream stream; + stream << i; + dest += stream.str(); + return dest; } static string AddStringUInt64(const string &str, asQWORD i) { - ostringstream stream; - stream << i; - return str + stream.str(); + ostringstream stream; + stream << i; + return str + stream.str(); } static string AddInt64String(asINT64 i, const string &str) { - ostringstream stream; - stream << i; - return stream.str() + str; + ostringstream stream; + stream << i; + return stream.str() + str; } static string &AssignInt64ToString(asINT64 i, string &dest) { - ostringstream stream; - stream << i; - dest = stream.str(); - return dest; + ostringstream stream; + stream << i; + dest = stream.str(); + return dest; } static string &AddAssignInt64ToString(asINT64 i, string &dest) { - ostringstream stream; - stream << i; - dest += stream.str(); - return dest; + ostringstream stream; + stream << i; + dest += stream.str(); + return dest; } static string AddStringInt64(const string &str, asINT64 i) { - ostringstream stream; - stream << i; - return str + stream.str(); + ostringstream stream; + stream << i; + return str + stream.str(); } static string AddUInt64String(asQWORD i, const string &str) { - ostringstream stream; - stream << i; - return stream.str() + str; + ostringstream stream; + stream << i; + return stream.str() + str; } static string &AssignDoubleToString(double f, string &dest) { - ostringstream stream; - stream << f; - dest = stream.str(); - return dest; + ostringstream stream; + stream << f; + dest = stream.str(); + return dest; } static string &AddAssignDoubleToString(double f, string &dest) { - ostringstream stream; - stream << f; - dest += stream.str(); - return dest; + ostringstream stream; + stream << f; + dest += stream.str(); + return dest; } static string &AssignFloatToString(float f, string &dest) { - ostringstream stream; - stream << f; - dest = stream.str(); - return dest; + ostringstream stream; + stream << f; + dest = stream.str(); + return dest; } static string &AddAssignFloatToString(float f, string &dest) { - ostringstream stream; - stream << f; - dest += stream.str(); - return dest; + ostringstream stream; + stream << f; + dest += stream.str(); + return dest; } static string &AssignBoolToString(bool b, string &dest) { - ostringstream stream; - stream << (b ? "true" : "false"); - dest = stream.str(); - return dest; + ostringstream stream; + stream << (b ? "true" : "false"); + dest = stream.str(); + return dest; } static string &AddAssignBoolToString(bool b, string &dest) { - ostringstream stream; - stream << (b ? "true" : "false"); - dest += stream.str(); - return dest; + ostringstream stream; + stream << (b ? "true" : "false"); + dest += stream.str(); + return dest; } static string AddStringDouble(const string &str, double f) { - ostringstream stream; - stream << f; - return str + stream.str(); + ostringstream stream; + stream << f; + return str + stream.str(); } static string AddDoubleString(double f, const string &str) { - ostringstream stream; - stream << f; - return stream.str() + str; + ostringstream stream; + stream << f; + return stream.str() + str; } static string AddStringFloat(const string &str, float f) { - ostringstream stream; - stream << f; - return str + stream.str(); + ostringstream stream; + stream << f; + return str + stream.str(); } static string AddFloatString(float f, const string &str) { - ostringstream stream; - stream << f; - return stream.str() + str; + ostringstream stream; + stream << f; + return stream.str() + str; } static string AddStringBool(const string &str, bool b) { - ostringstream stream; - stream << (b ? "true" : "false"); - return str + stream.str(); + ostringstream stream; + stream << (b ? "true" : "false"); + return str + stream.str(); } static string AddBoolString(bool b, const string &str) { - ostringstream stream; - stream << (b ? "true" : "false"); - return stream.str() + str; + ostringstream stream; + stream << (b ? "true" : "false"); + return stream.str() + str; } static char *StringCharAt(unsigned int i, string &str) { - if( i >= str.size() ) - { - // Set a script exception - asIScriptContext *ctx = asGetActiveContext(); - ctx->SetException("Out of range"); + if( i >= str.size() ) + { + // Set a script exception + asIScriptContext *ctx = asGetActiveContext(); + ctx->SetException("Out of range"); - // Return a null pointer - return 0; - } + // Return a null pointer + return 0; + } - return &str[i]; + return &str[i]; } // AngelScript signature: // int string::opCmp(const string &in) const static int StringCmp(const string &a, const string &b) { - int cmp = 0; - if( a < b ) cmp = -1; - else if( a > b ) cmp = 1; - return cmp; + int cmp = 0; + if( a < b ) cmp = -1; + else if( a > b ) cmp = 1; + return cmp; } // This function returns the index of the first position where the substring @@ -306,8 +306,8 @@ static int StringCmp(const string &a, const string &b) // int string::findFirst(const string &in sub, uint start = 0) const static int StringFindFirst(const string &sub, asUINT start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.find(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.find(sub, (size_t)(start < 0 ? string::npos : start)); } // This function returns the index of the first position where the one of the bytes in substring @@ -318,8 +318,8 @@ static int StringFindFirst(const string &sub, asUINT start, const string &str) // int string::findFirstOf(const string &in sub, uint start = 0) const static int StringFindFirstOf(const string &sub, asUINT start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.find_first_of(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.find_first_of(sub, (size_t)(start < 0 ? string::npos : start)); } // This function returns the index of the last position where the one of the bytes in substring @@ -330,8 +330,8 @@ static int StringFindFirstOf(const string &sub, asUINT start, const string &str) // int string::findLastOf(const string &in sub, uint start = -1) const static int StringFindLastOf(const string &sub, asUINT start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.find_last_of(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.find_last_of(sub, (size_t)(start < 0 ? string::npos : start)); } // This function returns the index of the first position where a byte other than those in substring @@ -341,8 +341,8 @@ static int StringFindLastOf(const string &sub, asUINT start, const string &str) // int string::findFirstNotOf(const string &in sub, uint start = 0) const static int StringFindFirstNotOf(const string &sub, asUINT start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.find_first_not_of(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.find_first_not_of(sub, (size_t)(start < 0 ? string::npos : start)); } // This function returns the index of the last position where a byte other than those in substring @@ -352,8 +352,8 @@ static int StringFindFirstNotOf(const string &sub, asUINT start, const string &s // int string::findLastNotOf(const string &in sub, uint start = -1) const static int StringFindLastNotOf(const string &sub, asUINT start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.find_last_of(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.find_last_of(sub, (size_t)(start < 0 ? string::npos : start)); } // This function returns the index of the last position where the substring @@ -364,24 +364,24 @@ static int StringFindLastNotOf(const string &sub, asUINT start, const string &st // int string::findLast(const string &in sub, int start = -1) const static int StringFindLast(const string &sub, int start, const string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - return (int)str.rfind(sub, (size_t)(start < 0 ? string::npos : start)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + return (int)str.rfind(sub, (size_t)(start < 0 ? string::npos : start)); } // AngelScript signature: // void string::insert(uint pos, const string &in other) static void StringInsert(unsigned int pos, const string &other, string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - str.insert(pos, other); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + str.insert(pos, other); } // AngelScript signature: // void string::erase(uint pos, int count = -1) static void StringErase(unsigned int pos, int count, string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - str.erase(pos, (size_t)(count < 0 ? string::npos : count)); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + str.erase(pos, (size_t)(count < 0 ? string::npos : count)); } @@ -389,8 +389,8 @@ static void StringErase(unsigned int pos, int count, string &str) // uint string::length() const static asUINT StringLength(const string &str) { - // We don't register the method directly because the return type changes between 32bit and 64bit platforms - return (asUINT)str.length(); + // We don't register the method directly because the return type changes between 32bit and 64bit platforms + return (asUINT)str.length(); } @@ -398,261 +398,261 @@ static asUINT StringLength(const string &str) // void string::resize(uint l) static void StringResize(asUINT l, string &str) { - // We don't register the method directly because the argument types change between 32bit and 64bit platforms - str.resize(l); + // We don't register the method directly because the argument types change between 32bit and 64bit platforms + str.resize(l); } // AngelScript signature: // string formatInt(int64 val, const string &in options, uint width) static string formatInt(asINT64 value, const string &options, asUINT width) { - bool leftJustify = options.find("l") != string::npos; - bool padWithZero = options.find("0") != string::npos; - bool alwaysSign = options.find("+") != string::npos; - bool spaceOnSign = options.find(" ") != string::npos; - bool hexSmall = options.find("h") != string::npos; - bool hexLarge = options.find("H") != string::npos; + bool leftJustify = options.find("l") != string::npos; + bool padWithZero = options.find("0") != string::npos; + bool alwaysSign = options.find("+") != string::npos; + bool spaceOnSign = options.find(" ") != string::npos; + bool hexSmall = options.find("h") != string::npos; + bool hexLarge = options.find("H") != string::npos; - string fmt = "%"; - if( leftJustify ) fmt += "-"; - if( alwaysSign ) fmt += "+"; - if( spaceOnSign ) fmt += " "; - if( padWithZero ) fmt += "0"; + string fmt = "%"; + if( leftJustify ) fmt += "-"; + if( alwaysSign ) fmt += "+"; + if( spaceOnSign ) fmt += " "; + if( padWithZero ) fmt += "0"; #ifdef _WIN32 - fmt += "*I64"; + fmt += "*I64"; #else #ifdef _LP64 - fmt += "*l"; + fmt += "*l"; #else - fmt += "*ll"; + fmt += "*ll"; #endif #endif - if( hexSmall ) fmt += "x"; - else if( hexLarge ) fmt += "X"; - else fmt += "d"; + if( hexSmall ) fmt += "x"; + else if( hexLarge ) fmt += "X"; + else fmt += "d"; - string buf; - buf.resize(width+30); + string buf; + buf.resize(width+30); #if _MSC_VER >= 1400 && !defined(__S3E__) - // MSVC 8.0 / 2005 or newer - sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, value); + // MSVC 8.0 / 2005 or newer + sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, value); #else - sprintf(&buf[0], fmt.c_str(), width, value); + sprintf(&buf[0], fmt.c_str(), width, value); #endif - buf.resize(strlen(&buf[0])); + buf.resize(strlen(&buf[0])); - return buf; + return buf; } // AngelScript signature: // string formatUInt(uint64 val, const string &in options, uint width) static string formatUInt(asQWORD value, const string &options, asUINT width) { - bool leftJustify = options.find("l") != string::npos; - bool padWithZero = options.find("0") != string::npos; - bool alwaysSign = options.find("+") != string::npos; - bool spaceOnSign = options.find(" ") != string::npos; - bool hexSmall = options.find("h") != string::npos; - bool hexLarge = options.find("H") != string::npos; + bool leftJustify = options.find("l") != string::npos; + bool padWithZero = options.find("0") != string::npos; + bool alwaysSign = options.find("+") != string::npos; + bool spaceOnSign = options.find(" ") != string::npos; + bool hexSmall = options.find("h") != string::npos; + bool hexLarge = options.find("H") != string::npos; - string fmt = "%"; - if( leftJustify ) fmt += "-"; - if( alwaysSign ) fmt += "+"; - if( spaceOnSign ) fmt += " "; - if( padWithZero ) fmt += "0"; + string fmt = "%"; + if( leftJustify ) fmt += "-"; + if( alwaysSign ) fmt += "+"; + if( spaceOnSign ) fmt += " "; + if( padWithZero ) fmt += "0"; #ifdef _WIN32 - fmt += "*I64"; + fmt += "*I64"; #else #ifdef _LP64 - fmt += "*l"; + fmt += "*l"; #else - fmt += "*ll"; + fmt += "*ll"; #endif #endif - if( hexSmall ) fmt += "x"; - else if( hexLarge ) fmt += "X"; - else fmt += "u"; + if( hexSmall ) fmt += "x"; + else if( hexLarge ) fmt += "X"; + else fmt += "u"; - string buf; - buf.resize(width+30); + string buf; + buf.resize(width+30); #if _MSC_VER >= 1400 && !defined(__S3E__) - // MSVC 8.0 / 2005 or newer - sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, value); + // MSVC 8.0 / 2005 or newer + sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, value); #else - sprintf(&buf[0], fmt.c_str(), width, value); + sprintf(&buf[0], fmt.c_str(), width, value); #endif - buf.resize(strlen(&buf[0])); + buf.resize(strlen(&buf[0])); - return buf; + return buf; } // AngelScript signature: // string formatFloat(double val, const string &in options, uint width, uint precision) static string formatFloat(double value, const string &options, asUINT width, asUINT precision) { - bool leftJustify = options.find("l") != string::npos; - bool padWithZero = options.find("0") != string::npos; - bool alwaysSign = options.find("+") != string::npos; - bool spaceOnSign = options.find(" ") != string::npos; - bool expSmall = options.find("e") != string::npos; - bool expLarge = options.find("E") != string::npos; + bool leftJustify = options.find("l") != string::npos; + bool padWithZero = options.find("0") != string::npos; + bool alwaysSign = options.find("+") != string::npos; + bool spaceOnSign = options.find(" ") != string::npos; + bool expSmall = options.find("e") != string::npos; + bool expLarge = options.find("E") != string::npos; - string fmt = "%"; - if( leftJustify ) fmt += "-"; - if( alwaysSign ) fmt += "+"; - if( spaceOnSign ) fmt += " "; - if( padWithZero ) fmt += "0"; + string fmt = "%"; + if( leftJustify ) fmt += "-"; + if( alwaysSign ) fmt += "+"; + if( spaceOnSign ) fmt += " "; + if( padWithZero ) fmt += "0"; - fmt += "*.*"; + fmt += "*.*"; - if( expSmall ) fmt += "e"; - else if( expLarge ) fmt += "E"; - else fmt += "f"; + if( expSmall ) fmt += "e"; + else if( expLarge ) fmt += "E"; + else fmt += "f"; - string buf; - buf.resize(width+precision+50); + string buf; + buf.resize(width+precision+50); #if _MSC_VER >= 1400 && !defined(__S3E__) - // MSVC 8.0 / 2005 or newer - sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, precision, value); + // MSVC 8.0 / 2005 or newer + sprintf_s(&buf[0], buf.size(), fmt.c_str(), width, precision, value); #else - sprintf(&buf[0], fmt.c_str(), width, precision, value); + sprintf(&buf[0], fmt.c_str(), width, precision, value); #endif - buf.resize(strlen(&buf[0])); + buf.resize(strlen(&buf[0])); - return buf; + return buf; } // AngelScript signature: // int64 parseInt(const string &in val, uint base = 10, uint &out byteCount = 0) static asINT64 parseInt(const string &val, asUINT base, asUINT *byteCount) { - // Only accept base 10 and 16 - if( base != 10 && base != 16 ) - { - if( byteCount ) *byteCount = 0; - return 0; - } + // Only accept base 10 and 16 + if( base != 10 && base != 16 ) + { + if( byteCount ) *byteCount = 0; + return 0; + } - const char *end = &val[0]; + const char *end = &val[0]; - // Determine the sign - bool sign = false; - if( *end == '-' ) - { - sign = true; - end++; - } - else if( *end == '+' ) - end++; + // Determine the sign + bool sign = false; + if( *end == '-' ) + { + sign = true; + end++; + } + else if( *end == '+' ) + end++; - asINT64 res = 0; - if( base == 10 ) - { - while( *end >= '0' && *end <= '9' ) - { - res *= 10; - res += *end++ - '0'; - } - } - else if( base == 16 ) - { - while( (*end >= '0' && *end <= '9') || - (*end >= 'a' && *end <= 'f') || - (*end >= 'A' && *end <= 'F') ) - { - res *= 16; - if( *end >= '0' && *end <= '9' ) - res += *end++ - '0'; - else if( *end >= 'a' && *end <= 'f' ) - res += *end++ - 'a' + 10; - else if( *end >= 'A' && *end <= 'F' ) - res += *end++ - 'A' + 10; - } - } + asINT64 res = 0; + if( base == 10 ) + { + while( *end >= '0' && *end <= '9' ) + { + res *= 10; + res += *end++ - '0'; + } + } + else if( base == 16 ) + { + while( (*end >= '0' && *end <= '9') || + (*end >= 'a' && *end <= 'f') || + (*end >= 'A' && *end <= 'F') ) + { + res *= 16; + if( *end >= '0' && *end <= '9' ) + res += *end++ - '0'; + else if( *end >= 'a' && *end <= 'f' ) + res += *end++ - 'a' + 10; + else if( *end >= 'A' && *end <= 'F' ) + res += *end++ - 'A' + 10; + } + } - if( byteCount ) - *byteCount = asUINT(size_t(end - val.c_str())); + if( byteCount ) + *byteCount = asUINT(size_t(end - val.c_str())); - if( sign ) - res = -res; + if( sign ) + res = -res; - return res; + return res; } // AngelScript signature: // uint64 parseUInt(const string &in val, uint base = 10, uint &out byteCount = 0) static asQWORD parseUInt(const string &val, asUINT base, asUINT *byteCount) { - // Only accept base 10 and 16 - if (base != 10 && base != 16) - { - if (byteCount) *byteCount = 0; - return 0; - } + // Only accept base 10 and 16 + if (base != 10 && base != 16) + { + if (byteCount) *byteCount = 0; + return 0; + } - const char *end = &val[0]; + const char *end = &val[0]; - asQWORD res = 0; - if (base == 10) - { - while (*end >= '0' && *end <= '9') - { - res *= 10; - res += *end++ - '0'; - } - } - else if (base == 16) - { - while ((*end >= '0' && *end <= '9') || - (*end >= 'a' && *end <= 'f') || - (*end >= 'A' && *end <= 'F')) - { - res *= 16; - if (*end >= '0' && *end <= '9') - res += *end++ - '0'; - else if (*end >= 'a' && *end <= 'f') - res += *end++ - 'a' + 10; - else if (*end >= 'A' && *end <= 'F') - res += *end++ - 'A' + 10; - } - } + asQWORD res = 0; + if (base == 10) + { + while (*end >= '0' && *end <= '9') + { + res *= 10; + res += *end++ - '0'; + } + } + else if (base == 16) + { + while ((*end >= '0' && *end <= '9') || + (*end >= 'a' && *end <= 'f') || + (*end >= 'A' && *end <= 'F')) + { + res *= 16; + if (*end >= '0' && *end <= '9') + res += *end++ - '0'; + else if (*end >= 'a' && *end <= 'f') + res += *end++ - 'a' + 10; + else if (*end >= 'A' && *end <= 'F') + res += *end++ - 'A' + 10; + } + } - if (byteCount) - *byteCount = asUINT(size_t(end - val.c_str())); + if (byteCount) + *byteCount = asUINT(size_t(end - val.c_str())); - return res; + return res; } // AngelScript signature: // double parseFloat(const string &in val, uint &out byteCount = 0) double parseFloat(const string &val, asUINT *byteCount) { - char *end; + char *end; - // WinCE doesn't have setlocale. Some quick testing on my current platform - // still manages to parse the numbers such as "3.14" even if the decimal for the - // locale is ",". + // WinCE doesn't have setlocale. Some quick testing on my current platform + // still manages to parse the numbers such as "3.14" even if the decimal for the + // locale is ",". #if !defined(_WIN32_WCE) && !defined(ANDROID) && !defined(__psp2__) - // Set the locale to C so that we are guaranteed to parse the float value correctly - char *orig = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, "C"); + // Set the locale to C so that we are guaranteed to parse the float value correctly + char *orig = setlocale(LC_NUMERIC, 0); + setlocale(LC_NUMERIC, "C"); #endif - double res = strtod(val.c_str(), &end); + double res = strtod(val.c_str(), &end); #if !defined(_WIN32_WCE) && !defined(ANDROID) && !defined(__psp2__) - // Restore the locale - setlocale(LC_NUMERIC, orig); + // Restore the locale + setlocale(LC_NUMERIC, orig); #endif - if( byteCount ) - *byteCount = asUINT(size_t(end - val.c_str())); + if( byteCount ) + *byteCount = asUINT(size_t(end - val.c_str())); - return res; + return res; } // This function returns a string containing the substring of the input string @@ -662,12 +662,12 @@ double parseFloat(const string &val, asUINT *byteCount) // string string::substr(uint start = 0, int count = -1) const static string StringSubString(asUINT start, int count, const string &str) { - // Check for out-of-bounds - string ret; - if( start < str.length() && count != 0 ) - ret = str.substr(start, (size_t)(count < 0 ? string::npos : count)); + // Check for out-of-bounds + string ret; + if( start < str.length() && count != 0 ) + ret = str.substr(start, (size_t)(count < 0 ? string::npos : count)); - return ret; + return ret; } // String equality comparison. @@ -678,617 +678,617 @@ static string StringSubString(asUINT start, int count, const string &str) // makro, so this wrapper was introduced as work around. static bool StringEquals(const std::string& lhs, const std::string& rhs) { - return lhs == rhs; + return lhs == rhs; } void RegisterStdString_Native(asIScriptEngine *engine) { - int r = 0; - UNUSED_VAR(r); + int r = 0; + UNUSED_VAR(r); - // Register the string type + // Register the string type #if AS_CAN_USE_CPP11 - // With C++11 it is possible to use asGetTypeTraits to automatically determine the correct flags to use - r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asGetTypeTraits()); assert( r >= 0 ); + // With C++11 it is possible to use asGetTypeTraits to automatically determine the correct flags to use + r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asGetTypeTraits()); assert( r >= 0 ); #else - r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 ); + r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 ); #endif - r = engine->RegisterStringFactory("string", &stringFactory); + r = engine->RegisterStringFactory("string", &stringFactory); - // Register the object operator overloads - r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asMETHODPR(string, operator =, (const string&), string&), asCALL_THISCALL); assert( r >= 0 ); - // Need to use a wrapper on Mac OS X 10.7/XCode 4.3 and CLang/LLVM, otherwise the linker fails - r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); -// r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asMETHODPR(string, operator+=, (const string&), string&), asCALL_THISCALL); assert( r >= 0 ); + // Register the object operator overloads + r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asMETHODPR(string, operator =, (const string&), string&), asCALL_THISCALL); assert( r >= 0 ); + // Need to use a wrapper on Mac OS X 10.7/XCode 4.3 and CLang/LLVM, otherwise the linker fails + r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); +// r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asMETHODPR(string, operator+=, (const string&), string&), asCALL_THISCALL); assert( r >= 0 ); - // Need to use a wrapper for operator== otherwise gcc 4.7 fails to compile - r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTIONPR(StringEquals, (const string &, const string &), bool), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmp), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTIONPR(operator +, (const string &, const string &), string), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + // Need to use a wrapper for operator== otherwise gcc 4.7 fails to compile + r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTIONPR(StringEquals, (const string &, const string &), bool), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmp), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTIONPR(operator +, (const string &, const string &), string), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - // The string length can be accessed through methods or through virtual property - r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "uint get_length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "void set_length(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Need to use a wrapper on Mac OS X 10.7/XCode 4.3 and CLang/LLVM, otherwise the linker fails -// r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asMETHOD(string, empty), asCALL_THISCALL); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asFUNCTION(StringIsEmpty), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // The string length can be accessed through methods or through virtual property + r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "uint get_length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "void set_length(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Need to use a wrapper on Mac OS X 10.7/XCode 4.3 and CLang/LLVM, otherwise the linker fails +// r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asMETHOD(string, empty), asCALL_THISCALL); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asFUNCTION(StringIsEmpty), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Register the index operator, both as a mutator and as an inspector - // Note that we don't register the operator[] directly, as it doesn't do bounds checking - r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Register the index operator, both as a mutator and as an inspector + // Note that we don't register the operator[] directly, as it doesn't do bounds checking + r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Automatic conversion from values - r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddStringDouble), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDoubleString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Automatic conversion from values + r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddStringDouble), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDoubleString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(float)", asFUNCTION(AssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(float)", asFUNCTION(AddAssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(float) const", asFUNCTION(AddStringFloat), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(float) const", asFUNCTION(AddFloatString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(float)", asFUNCTION(AssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(float)", asFUNCTION(AddAssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(float) const", asFUNCTION(AddStringFloat), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(float) const", asFUNCTION(AddFloatString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(int64)", asFUNCTION(AssignInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(int64)", asFUNCTION(AddAssignInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(int64) const", asFUNCTION(AddStringInt64), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(int64) const", asFUNCTION(AddInt64String), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(int64)", asFUNCTION(AssignInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(int64)", asFUNCTION(AddAssignInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(int64) const", asFUNCTION(AddStringInt64), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(int64) const", asFUNCTION(AddInt64String), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(uint64)", asFUNCTION(AssignUInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint64)", asFUNCTION(AddAssignUInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(uint64) const", asFUNCTION(AddStringUInt64), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(uint64) const", asFUNCTION(AddUInt64String), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(uint64)", asFUNCTION(AssignUInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint64)", asFUNCTION(AddAssignUInt64ToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(uint64) const", asFUNCTION(AddStringUInt64), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(uint64) const", asFUNCTION(AddUInt64String), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddStringBool), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBoolString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddStringBool), asCALL_CDECL_OBJFIRST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBoolString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Utilities - r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "int findFirst(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "int findFirstOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstOf), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findFirstNotOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstNotOf), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findLast(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "int findLastOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastOf), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findLastNotOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastNotOf), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "void insert(uint pos, const string &in other)", asFUNCTION(StringInsert), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "void erase(uint pos, int count = -1)", asFUNCTION(StringErase), asCALL_CDECL_OBJLAST); assert(r >= 0); + // Utilities + r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "int findFirst(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "int findFirstOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstOf), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findFirstNotOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstNotOf), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findLast(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "int findLastOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastOf), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findLastNotOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastNotOf), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "void insert(uint pos, const string &in other)", asFUNCTION(StringInsert), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "void erase(uint pos, int count = -1)", asFUNCTION(StringErase), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatInt(int64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatInt), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatUInt(uint64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatUInt), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatFloat(double val, const string &in options = \"\", uint width = 0, uint precision = 0)", asFUNCTION(formatFloat), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("int64 parseInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseInt), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("uint64 parseUInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseUInt), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("double parseFloat(const string &in, uint &out byteCount = 0)", asFUNCTION(parseFloat), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatInt(int64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatInt), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatUInt(uint64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatUInt), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatFloat(double val, const string &in options = \"\", uint width = 0, uint precision = 0)", asFUNCTION(formatFloat), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("int64 parseInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseInt), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("uint64 parseUInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseUInt), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("double parseFloat(const string &in, uint &out byteCount = 0)", asFUNCTION(parseFloat), asCALL_CDECL); assert(r >= 0); #if AS_USE_STLNAMES == 1 - // Same as length - r = engine->RegisterObjectMethod("string", "uint size() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Same as isEmpty - r = engine->RegisterObjectMethod("string", "bool empty() const", asFUNCTION(StringIsEmpty), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Same as findFirst - r = engine->RegisterObjectMethod("string", "int find(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 ); - // Same as findLast - r = engine->RegisterObjectMethod("string", "int rfind(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Same as length + r = engine->RegisterObjectMethod("string", "uint size() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Same as isEmpty + r = engine->RegisterObjectMethod("string", "bool empty() const", asFUNCTION(StringIsEmpty), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Same as findFirst + r = engine->RegisterObjectMethod("string", "int find(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 ); + // Same as findLast + r = engine->RegisterObjectMethod("string", "int rfind(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 ); #endif - // TODO: Implement the following - // findAndReplace - replaces a text found in the string - // replaceRange - replaces a range of bytes in the string - // multiply/times/opMul/opMul_r - takes the string and multiplies it n times, e.g. "-".multiply(5) returns "-----" + // TODO: Implement the following + // findAndReplace - replaces a text found in the string + // replaceRange - replaces a range of bytes in the string + // multiply/times/opMul/opMul_r - takes the string and multiplies it n times, e.g. "-".multiply(5) returns "-----" } static void ConstructStringGeneric(asIScriptGeneric * gen) { - new (gen->GetObject()) string(); + new (gen->GetObject()) string(); } static void CopyConstructStringGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetArgObject(0)); - new (gen->GetObject()) string(*a); + string * a = static_cast(gen->GetArgObject(0)); + new (gen->GetObject()) string(*a); } static void DestructStringGeneric(asIScriptGeneric * gen) { - string * ptr = static_cast(gen->GetObject()); - ptr->~string(); + string * ptr = static_cast(gen->GetObject()); + ptr->~string(); } static void AssignStringGeneric(asIScriptGeneric *gen) { - string * a = static_cast(gen->GetArgObject(0)); - string * self = static_cast(gen->GetObject()); - *self = *a; - gen->SetReturnAddress(self); + string * a = static_cast(gen->GetArgObject(0)); + string * self = static_cast(gen->GetObject()); + *self = *a; + gen->SetReturnAddress(self); } static void AddAssignStringGeneric(asIScriptGeneric *gen) { - string * a = static_cast(gen->GetArgObject(0)); - string * self = static_cast(gen->GetObject()); - *self += *a; - gen->SetReturnAddress(self); + string * a = static_cast(gen->GetArgObject(0)); + string * self = static_cast(gen->GetObject()); + *self += *a; + gen->SetReturnAddress(self); } static void StringEqualsGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - string * b = static_cast(gen->GetArgAddress(0)); - *(bool*)gen->GetAddressOfReturnLocation() = (*a == *b); + string * a = static_cast(gen->GetObject()); + string * b = static_cast(gen->GetArgAddress(0)); + *(bool*)gen->GetAddressOfReturnLocation() = (*a == *b); } static void StringCmpGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - string * b = static_cast(gen->GetArgAddress(0)); + string * a = static_cast(gen->GetObject()); + string * b = static_cast(gen->GetArgAddress(0)); - int cmp = 0; - if( *a < *b ) cmp = -1; - else if( *a > *b ) cmp = 1; + int cmp = 0; + if( *a < *b ) cmp = -1; + else if( *a > *b ) cmp = 1; - *(int*)gen->GetAddressOfReturnLocation() = cmp; + *(int*)gen->GetAddressOfReturnLocation() = cmp; } static void StringAddGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - string * b = static_cast(gen->GetArgAddress(0)); - string ret_val = *a + *b; - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + string * b = static_cast(gen->GetArgAddress(0)); + string ret_val = *a + *b; + gen->SetReturnObject(&ret_val); } static void StringLengthGeneric(asIScriptGeneric * gen) { - string * self = static_cast(gen->GetObject()); - *static_cast(gen->GetAddressOfReturnLocation()) = (asUINT)self->length(); + string * self = static_cast(gen->GetObject()); + *static_cast(gen->GetAddressOfReturnLocation()) = (asUINT)self->length(); } static void StringIsEmptyGeneric(asIScriptGeneric * gen) { - string * self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringIsEmpty(*self); + string * self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringIsEmpty(*self); } static void StringResizeGeneric(asIScriptGeneric * gen) { - string * self = static_cast(gen->GetObject()); - self->resize(*static_cast(gen->GetAddressOfArg(0))); + string * self = static_cast(gen->GetObject()); + self->resize(*static_cast(gen->GetAddressOfArg(0))); } static void StringInsert_Generic(asIScriptGeneric *gen) { - string * self = static_cast(gen->GetObject()); - asUINT pos = gen->GetArgDWord(0); - string *other = reinterpret_cast(gen->GetArgAddress(1)); - StringInsert(pos, *other, *self); + string * self = static_cast(gen->GetObject()); + asUINT pos = gen->GetArgDWord(0); + string *other = reinterpret_cast(gen->GetArgAddress(1)); + StringInsert(pos, *other, *self); } static void StringErase_Generic(asIScriptGeneric *gen) { - string * self = static_cast(gen->GetObject()); - asUINT pos = gen->GetArgDWord(0); - int count = int(gen->GetArgDWord(1)); - StringErase(pos, count, *self); + string * self = static_cast(gen->GetObject()); + asUINT pos = gen->GetArgDWord(0); + int count = int(gen->GetArgDWord(1)); + StringErase(pos, count, *self); } static void StringFindFirst_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirst(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirst(*find, start, *self); } static void StringFindLast_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLast(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLast(*find, start, *self); } static void StringFindFirstOf_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirstOf(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirstOf(*find, start, *self); } static void StringFindLastOf_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLastOf(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLastOf(*find, start, *self); } static void StringFindFirstNotOf_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirstNotOf(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindFirstNotOf(*find, start, *self); } static void StringFindLastNotOf_Generic(asIScriptGeneric * gen) { - string *find = reinterpret_cast(gen->GetArgAddress(0)); - asUINT start = gen->GetArgDWord(1); - string *self = reinterpret_cast(gen->GetObject()); - *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLastNotOf(*find, start, *self); + string *find = reinterpret_cast(gen->GetArgAddress(0)); + asUINT start = gen->GetArgDWord(1); + string *self = reinterpret_cast(gen->GetObject()); + *reinterpret_cast(gen->GetAddressOfReturnLocation()) = StringFindLastNotOf(*find, start, *self); } static void formatInt_Generic(asIScriptGeneric * gen) { - asINT64 val = gen->GetArgQWord(0); - string *options = reinterpret_cast(gen->GetArgAddress(1)); - asUINT width = gen->GetArgDWord(2); - new(gen->GetAddressOfReturnLocation()) string(formatInt(val, *options, width)); + asINT64 val = gen->GetArgQWord(0); + string *options = reinterpret_cast(gen->GetArgAddress(1)); + asUINT width = gen->GetArgDWord(2); + new(gen->GetAddressOfReturnLocation()) string(formatInt(val, *options, width)); } static void formatUInt_Generic(asIScriptGeneric * gen) { - asQWORD val = gen->GetArgQWord(0); - string *options = reinterpret_cast(gen->GetArgAddress(1)); - asUINT width = gen->GetArgDWord(2); - new(gen->GetAddressOfReturnLocation()) string(formatUInt(val, *options, width)); + asQWORD val = gen->GetArgQWord(0); + string *options = reinterpret_cast(gen->GetArgAddress(1)); + asUINT width = gen->GetArgDWord(2); + new(gen->GetAddressOfReturnLocation()) string(formatUInt(val, *options, width)); } static void formatFloat_Generic(asIScriptGeneric *gen) { - double val = gen->GetArgDouble(0); - string *options = reinterpret_cast(gen->GetArgAddress(1)); - asUINT width = gen->GetArgDWord(2); - asUINT precision = gen->GetArgDWord(3); - new(gen->GetAddressOfReturnLocation()) string(formatFloat(val, *options, width, precision)); + double val = gen->GetArgDouble(0); + string *options = reinterpret_cast(gen->GetArgAddress(1)); + asUINT width = gen->GetArgDWord(2); + asUINT precision = gen->GetArgDWord(3); + new(gen->GetAddressOfReturnLocation()) string(formatFloat(val, *options, width, precision)); } static void parseInt_Generic(asIScriptGeneric *gen) { - string *str = reinterpret_cast(gen->GetArgAddress(0)); - asUINT base = gen->GetArgDWord(1); - asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(2)); - gen->SetReturnQWord(parseInt(*str,base,byteCount)); + string *str = reinterpret_cast(gen->GetArgAddress(0)); + asUINT base = gen->GetArgDWord(1); + asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(2)); + gen->SetReturnQWord(parseInt(*str,base,byteCount)); } static void parseUInt_Generic(asIScriptGeneric *gen) { - string *str = reinterpret_cast(gen->GetArgAddress(0)); - asUINT base = gen->GetArgDWord(1); - asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(2)); - gen->SetReturnQWord(parseUInt(*str, base, byteCount)); + string *str = reinterpret_cast(gen->GetArgAddress(0)); + asUINT base = gen->GetArgDWord(1); + asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(2)); + gen->SetReturnQWord(parseUInt(*str, base, byteCount)); } static void parseFloat_Generic(asIScriptGeneric *gen) { - string *str = reinterpret_cast(gen->GetArgAddress(0)); - asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(1)); - gen->SetReturnDouble(parseFloat(*str,byteCount)); + string *str = reinterpret_cast(gen->GetArgAddress(0)); + asUINT *byteCount = reinterpret_cast(gen->GetArgAddress(1)); + gen->SetReturnDouble(parseFloat(*str,byteCount)); } static void StringCharAtGeneric(asIScriptGeneric * gen) { - unsigned int index = gen->GetArgDWord(0); - string * self = static_cast(gen->GetObject()); + unsigned int index = gen->GetArgDWord(0); + string * self = static_cast(gen->GetObject()); - if (index >= self->size()) - { - // Set a script exception - asIScriptContext *ctx = asGetActiveContext(); - ctx->SetException("Out of range"); + if (index >= self->size()) + { + // Set a script exception + asIScriptContext *ctx = asGetActiveContext(); + ctx->SetException("Out of range"); - gen->SetReturnAddress(0); - } - else - { - gen->SetReturnAddress(&(self->operator [](index))); - } + gen->SetReturnAddress(0); + } + else + { + gen->SetReturnAddress(&(self->operator [](index))); + } } static void AssignInt2StringGeneric(asIScriptGeneric *gen) { - asINT64 *a = static_cast(gen->GetAddressOfArg(0)); - string *self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self = sstr.str(); - gen->SetReturnAddress(self); + asINT64 *a = static_cast(gen->GetAddressOfArg(0)); + string *self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self = sstr.str(); + gen->SetReturnAddress(self); } static void AssignUInt2StringGeneric(asIScriptGeneric *gen) { - asQWORD *a = static_cast(gen->GetAddressOfArg(0)); - string *self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self = sstr.str(); - gen->SetReturnAddress(self); + asQWORD *a = static_cast(gen->GetAddressOfArg(0)); + string *self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self = sstr.str(); + gen->SetReturnAddress(self); } static void AssignDouble2StringGeneric(asIScriptGeneric *gen) { - double *a = static_cast(gen->GetAddressOfArg(0)); - string *self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self = sstr.str(); - gen->SetReturnAddress(self); + double *a = static_cast(gen->GetAddressOfArg(0)); + string *self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self = sstr.str(); + gen->SetReturnAddress(self); } static void AssignFloat2StringGeneric(asIScriptGeneric *gen) { - float *a = static_cast(gen->GetAddressOfArg(0)); - string *self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self = sstr.str(); - gen->SetReturnAddress(self); + float *a = static_cast(gen->GetAddressOfArg(0)); + string *self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self = sstr.str(); + gen->SetReturnAddress(self); } static void AssignBool2StringGeneric(asIScriptGeneric *gen) { - bool *a = static_cast(gen->GetAddressOfArg(0)); - string *self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << (*a ? "true" : "false"); - *self = sstr.str(); - gen->SetReturnAddress(self); + bool *a = static_cast(gen->GetAddressOfArg(0)); + string *self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << (*a ? "true" : "false"); + *self = sstr.str(); + gen->SetReturnAddress(self); } static void AddAssignDouble2StringGeneric(asIScriptGeneric * gen) { - double * a = static_cast(gen->GetAddressOfArg(0)); - string * self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self += sstr.str(); - gen->SetReturnAddress(self); + double * a = static_cast(gen->GetAddressOfArg(0)); + string * self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self += sstr.str(); + gen->SetReturnAddress(self); } static void AddAssignFloat2StringGeneric(asIScriptGeneric * gen) { - float * a = static_cast(gen->GetAddressOfArg(0)); - string * self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self += sstr.str(); - gen->SetReturnAddress(self); + float * a = static_cast(gen->GetAddressOfArg(0)); + string * self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self += sstr.str(); + gen->SetReturnAddress(self); } static void AddAssignInt2StringGeneric(asIScriptGeneric * gen) { - asINT64 * a = static_cast(gen->GetAddressOfArg(0)); - string * self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self += sstr.str(); - gen->SetReturnAddress(self); + asINT64 * a = static_cast(gen->GetAddressOfArg(0)); + string * self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self += sstr.str(); + gen->SetReturnAddress(self); } static void AddAssignUInt2StringGeneric(asIScriptGeneric * gen) { - asQWORD * a = static_cast(gen->GetAddressOfArg(0)); - string * self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a; - *self += sstr.str(); - gen->SetReturnAddress(self); + asQWORD * a = static_cast(gen->GetAddressOfArg(0)); + string * self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a; + *self += sstr.str(); + gen->SetReturnAddress(self); } static void AddAssignBool2StringGeneric(asIScriptGeneric * gen) { - bool * a = static_cast(gen->GetAddressOfArg(0)); - string * self = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << (*a ? "true" : "false"); - *self += sstr.str(); - gen->SetReturnAddress(self); + bool * a = static_cast(gen->GetAddressOfArg(0)); + string * self = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << (*a ? "true" : "false"); + *self += sstr.str(); + gen->SetReturnAddress(self); } static void AddString2DoubleGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - double * b = static_cast(gen->GetAddressOfArg(0)); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + double * b = static_cast(gen->GetAddressOfArg(0)); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddString2FloatGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - float * b = static_cast(gen->GetAddressOfArg(0)); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + float * b = static_cast(gen->GetAddressOfArg(0)); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddString2IntGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - asINT64 * b = static_cast(gen->GetAddressOfArg(0)); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + asINT64 * b = static_cast(gen->GetAddressOfArg(0)); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddString2UIntGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - asQWORD * b = static_cast(gen->GetAddressOfArg(0)); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + asQWORD * b = static_cast(gen->GetAddressOfArg(0)); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddString2BoolGeneric(asIScriptGeneric * gen) { - string * a = static_cast(gen->GetObject()); - bool * b = static_cast(gen->GetAddressOfArg(0)); - std::stringstream sstr; - sstr << *a << (*b ? "true" : "false"); - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + string * a = static_cast(gen->GetObject()); + bool * b = static_cast(gen->GetAddressOfArg(0)); + std::stringstream sstr; + sstr << *a << (*b ? "true" : "false"); + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddDouble2StringGeneric(asIScriptGeneric * gen) { - double* a = static_cast(gen->GetAddressOfArg(0)); - string * b = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + double* a = static_cast(gen->GetAddressOfArg(0)); + string * b = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddFloat2StringGeneric(asIScriptGeneric * gen) { - float* a = static_cast(gen->GetAddressOfArg(0)); - string * b = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + float* a = static_cast(gen->GetAddressOfArg(0)); + string * b = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddInt2StringGeneric(asIScriptGeneric * gen) { - asINT64* a = static_cast(gen->GetAddressOfArg(0)); - string * b = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + asINT64* a = static_cast(gen->GetAddressOfArg(0)); + string * b = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddUInt2StringGeneric(asIScriptGeneric * gen) { - asQWORD* a = static_cast(gen->GetAddressOfArg(0)); - string * b = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << *a << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + asQWORD* a = static_cast(gen->GetAddressOfArg(0)); + string * b = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << *a << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void AddBool2StringGeneric(asIScriptGeneric * gen) { - bool* a = static_cast(gen->GetAddressOfArg(0)); - string * b = static_cast(gen->GetObject()); - std::stringstream sstr; - sstr << (*a ? "true" : "false") << *b; - std::string ret_val = sstr.str(); - gen->SetReturnObject(&ret_val); + bool* a = static_cast(gen->GetAddressOfArg(0)); + string * b = static_cast(gen->GetObject()); + std::stringstream sstr; + sstr << (*a ? "true" : "false") << *b; + std::string ret_val = sstr.str(); + gen->SetReturnObject(&ret_val); } static void StringSubString_Generic(asIScriptGeneric *gen) { - // Get the arguments - string *str = (string*)gen->GetObject(); - asUINT start = *(int*)gen->GetAddressOfArg(0); - int count = *(int*)gen->GetAddressOfArg(1); + // Get the arguments + string *str = (string*)gen->GetObject(); + asUINT start = *(int*)gen->GetAddressOfArg(0); + int count = *(int*)gen->GetAddressOfArg(1); - // Return the substring - new(gen->GetAddressOfReturnLocation()) string(StringSubString(start, count, *str)); + // Return the substring + new(gen->GetAddressOfReturnLocation()) string(StringSubString(start, count, *str)); } void RegisterStdString_Generic(asIScriptEngine *engine) { - int r = 0; - UNUSED_VAR(r); + int r = 0; + UNUSED_VAR(r); - // Register the string type - r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 ); + // Register the string type + r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 ); - r = engine->RegisterStringFactory("string", &stringFactory); + r = engine->RegisterStringFactory("string", &stringFactory); - // Register the object operator overloads - r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asFUNCTION(AssignStringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringGeneric), asCALL_GENERIC); assert( r >= 0 ); + // Register the object operator overloads + r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructStringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asFUNCTION(AssignStringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTION(StringEqualsGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmpGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTION(StringAddGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTION(StringEqualsGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmpGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTION(StringAddGeneric), asCALL_GENERIC); assert( r >= 0 ); - // Register the object methods - r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "uint get_length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "void set_length(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asFUNCTION(StringIsEmptyGeneric), asCALL_GENERIC); assert( r >= 0 ); + // Register the object methods + r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "uint get_length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "void set_length(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asFUNCTION(StringIsEmptyGeneric), asCALL_GENERIC); assert( r >= 0 ); - // Register the index operator, both as a mutator and as an inspector - r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 ); + // Register the index operator, both as a mutator and as an inspector + r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 ); - // Automatic conversion from values - r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddString2DoubleGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + // Automatic conversion from values + r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddString2DoubleGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(float)", asFUNCTION(AssignFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(float)", asFUNCTION(AddAssignFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(float) const", asFUNCTION(AddString2FloatGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(float) const", asFUNCTION(AddFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(float)", asFUNCTION(AssignFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(float)", asFUNCTION(AddAssignFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(float) const", asFUNCTION(AddString2FloatGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(float) const", asFUNCTION(AddFloat2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(int64)", asFUNCTION(AssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(int64)", asFUNCTION(AddAssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(int64) const", asFUNCTION(AddString2IntGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(int64) const", asFUNCTION(AddInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(int64)", asFUNCTION(AssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(int64)", asFUNCTION(AddAssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(int64) const", asFUNCTION(AddString2IntGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(int64) const", asFUNCTION(AddInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(uint64)", asFUNCTION(AssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint64)", asFUNCTION(AddAssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(uint64) const", asFUNCTION(AddString2UIntGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(uint64) const", asFUNCTION(AddUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(uint64)", asFUNCTION(AssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint64)", asFUNCTION(AddAssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(uint64) const", asFUNCTION(AddString2UIntGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(uint64) const", asFUNCTION(AddUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddString2BoolGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddString2BoolGeneric), asCALL_GENERIC); assert( r >= 0 ); + r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 ); - r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findFirst(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findFirstOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstOf_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findFirstNotOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstNotOf_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findLast(const string &in, int start = -1) const", asFUNCTION(StringFindLast_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findLastOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastOf_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "int findLastNotOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastNotOf_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "void insert(uint pos, const string &in other)", asFUNCTION(StringInsert_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterObjectMethod("string", "void erase(uint pos, int count = -1)", asFUNCTION(StringErase_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findFirst(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findFirstOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstOf_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findFirstNotOf(const string &in, uint start = 0) const", asFUNCTION(StringFindFirstNotOf_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findLast(const string &in, int start = -1) const", asFUNCTION(StringFindLast_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findLastOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastOf_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "int findLastNotOf(const string &in, int start = -1) const", asFUNCTION(StringFindLastNotOf_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "void insert(uint pos, const string &in other)", asFUNCTION(StringInsert_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterObjectMethod("string", "void erase(uint pos, int count = -1)", asFUNCTION(StringErase_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatInt(int64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatInt_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatUInt(uint64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatUInt_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("string formatFloat(double val, const string &in options = \"\", uint width = 0, uint precision = 0)", asFUNCTION(formatFloat_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("int64 parseInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseInt_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("uint64 parseUInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseUInt_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("double parseFloat(const string &in, uint &out byteCount = 0)", asFUNCTION(parseFloat_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatInt(int64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatInt_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatUInt(uint64 val, const string &in options = \"\", uint width = 0)", asFUNCTION(formatUInt_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("string formatFloat(double val, const string &in options = \"\", uint width = 0, uint precision = 0)", asFUNCTION(formatFloat_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("int64 parseInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseInt_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("uint64 parseUInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseUInt_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("double parseFloat(const string &in, uint &out byteCount = 0)", asFUNCTION(parseFloat_Generic), asCALL_GENERIC); assert(r >= 0); } void RegisterStdString(asIScriptEngine * engine) { - if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY")) - RegisterStdString_Generic(engine); - else - RegisterStdString_Native(engine); + if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY")) + RegisterStdString_Generic(engine); + else + RegisterStdString_Native(engine); } END_AS_NAMESPACE diff --git a/src/scriptengine/scriptstdstring_utils.cpp b/src/scriptengine/scriptstdstring_utils.cpp index 3abd02896..a7ebbf22d 100644 --- a/src/scriptengine/scriptstdstring_utils.cpp +++ b/src/scriptengine/scriptstdstring_utils.cpp @@ -22,45 +22,45 @@ BEGIN_AS_NAMESPACE // array@ string::split(const string &in delim) const static CScriptArray *StringSplit(const string &delim, const string &str) { - // Obtain a pointer to the engine - asIScriptContext *ctx = asGetActiveContext(); - asIScriptEngine *engine = ctx->GetEngine(); + // Obtain a pointer to the engine + asIScriptContext *ctx = asGetActiveContext(); + asIScriptEngine *engine = ctx->GetEngine(); - // TODO: This should only be done once - // TODO: This assumes that CScriptArray was already registered - asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array"); + // TODO: This should only be done once + // TODO: This assumes that CScriptArray was already registered + asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array"); - // Create the array object - CScriptArray *array = CScriptArray::Create(arrayType); + // Create the array object + CScriptArray *array = CScriptArray::Create(arrayType); - // Find the existence of the delimiter in the input string - int pos = 0, prev = 0, count = 0; - while( (pos = (int)str.find(delim, prev)) != (int)string::npos ) - { - // Add the part to the array - array->Resize(array->GetSize()+1); - ((string*)array->At(count))->assign(&str[prev], pos-prev); + // Find the existence of the delimiter in the input string + int pos = 0, prev = 0, count = 0; + while( (pos = (int)str.find(delim, prev)) != (int)string::npos ) + { + // Add the part to the array + array->Resize(array->GetSize()+1); + ((string*)array->At(count))->assign(&str[prev], pos-prev); - // Find the next part - count++; - prev = pos + (int)delim.length(); - } + // Find the next part + count++; + prev = pos + (int)delim.length(); + } - // Add the remaining part - array->Resize(array->GetSize()+1); - ((string*)array->At(count))->assign(&str[prev]); + // Add the remaining part + array->Resize(array->GetSize()+1); + ((string*)array->At(count))->assign(&str[prev]); - return array; + return array; } static void StringSplit_Generic(asIScriptGeneric *gen) { - // Get the arguments - string *str = (string*)gen->GetObject(); - string *delim = *(string**)gen->GetAddressOfArg(0); + // Get the arguments + string *str = (string*)gen->GetObject(); + string *delim = *(string**)gen->GetAddressOfArg(0); - // Return the array by handle - *(CScriptArray**)gen->GetAddressOfReturnLocation() = StringSplit(*delim, *str); + // Return the array by handle + *(CScriptArray**)gen->GetAddressOfReturnLocation() = StringSplit(*delim, *str); } @@ -80,50 +80,50 @@ static void StringSplit_Generic(asIScriptGeneric *gen) // string join(const array &in array, const string &in delim) static string StringJoin(const CScriptArray &array, const string &delim) { - // Create the new string - string str = ""; - if( array.GetSize() ) - { - int n; - for( n = 0; n < (int)array.GetSize() - 1; n++ ) - { - str += *(string*)array.At(n); - str += delim; - } + // Create the new string + string str = ""; + if( array.GetSize() ) + { + int n; + for( n = 0; n < (int)array.GetSize() - 1; n++ ) + { + str += *(string*)array.At(n); + str += delim; + } - // Add the last part - str += *(string*)array.At(n); - } + // Add the last part + str += *(string*)array.At(n); + } - return str; + return str; } static void StringJoin_Generic(asIScriptGeneric *gen) { - // Get the arguments - CScriptArray *array = *(CScriptArray**)gen->GetAddressOfArg(0); - string *delim = *(string**)gen->GetAddressOfArg(1); + // Get the arguments + CScriptArray *array = *(CScriptArray**)gen->GetAddressOfArg(0); + string *delim = *(string**)gen->GetAddressOfArg(1); - // Return the string - new(gen->GetAddressOfReturnLocation()) string(StringJoin(*array, *delim)); + // Return the string + new(gen->GetAddressOfReturnLocation()) string(StringJoin(*array, *delim)); } // This is where the utility functions are registered. // The string type must have been registered first. void RegisterStdStringUtils(asIScriptEngine *engine) { - int r; + int r; - if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") ) - { - r = engine->RegisterObjectMethod("string", "array@ split(const string &in) const", asFUNCTION(StringSplit_Generic), asCALL_GENERIC); assert(r >= 0); - r = engine->RegisterGlobalFunction("string join(const array &in, const string &in)", asFUNCTION(StringJoin_Generic), asCALL_GENERIC); assert(r >= 0); - } - else - { - r = engine->RegisterObjectMethod("string", "array@ split(const string &in) const", asFUNCTION(StringSplit), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterGlobalFunction("string join(const array &in, const string &in)", asFUNCTION(StringJoin), asCALL_CDECL); assert(r >= 0); - } + if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") ) + { + r = engine->RegisterObjectMethod("string", "array@ split(const string &in) const", asFUNCTION(StringSplit_Generic), asCALL_GENERIC); assert(r >= 0); + r = engine->RegisterGlobalFunction("string join(const array &in, const string &in)", asFUNCTION(StringJoin_Generic), asCALL_GENERIC); assert(r >= 0); + } + else + { + r = engine->RegisterObjectMethod("string", "array@ split(const string &in) const", asFUNCTION(StringSplit), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterGlobalFunction("string join(const array &in, const string &in)", asFUNCTION(StringJoin), asCALL_CDECL); assert(r >= 0); + } } END_AS_NAMESPACE