| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- $#include "Core/Variant.h"
- $#include "IO/VectorBuffer.h"
- enum VariantType
- {
- VAR_NONE = 0,
- VAR_INT,
- VAR_BOOL,
- VAR_FLOAT,
- VAR_VECTOR2,
- VAR_VECTOR3,
- VAR_VECTOR4,
- VAR_QUATERNION,
- VAR_COLOR,
- VAR_STRING,
- VAR_BUFFER,
- VAR_VOIDPTR,
- VAR_RESOURCEREF,
- VAR_RESOURCEREFLIST,
- VAR_VARIANTVECTOR,
- VAR_VARIANTMAP,
- VAR_INTRECT,
- VAR_INTVECTOR2,
- VAR_PTR,
- VAR_MATRIX3,
- VAR_MATRIX3X4,
- VAR_MATRIX4,
- VAR_DOUBLE,
- VAR_STRINGVECTOR,
- MAX_VAR_TYPES
- };
- struct ResourceRef
- {
- ResourceRef();
- ResourceRef(StringHash type);
- ResourceRef(StringHash type, String name);
- ResourceRef(const ResourceRef& rhs);
- ~ResourceRef();
- StringHash type_ @ type;
- String name_ @ name;
- bool operator ==(const ResourceRef& rhs) const;
- };
- struct ResourceRefList
- {
- ResourceRefList();
- ResourceRefList(StringHash type);
- ~ResourceRefList();
- StringHash type_ @ type;
- bool operator ==(const ResourceRefList& rhs) const;
- };
- class Variant
- {
- static void _Setup(const char* type);
- Variant();
- //NOTE: do not change the constructor overloads order without also changing the special case handling below
- Variant(const Vector<Variant>& value); // VariantVector and StringVector are special cases as they are converted to Lua tables
- Variant(const Vector<String>& value);
- Variant(void* value); // Non-specific types must be declared first so that they get considered last
- Variant(RefCounted* value);
- Variant(int value);
- Variant(unsigned value);
- Variant(const StringHash& value);
- Variant(bool value);
- Variant(float value);
- Variant(double value);
- Variant(const Vector2& value);
- Variant(const Vector3& value);
- Variant(const Vector4& value);
- Variant(const Quaternion& value);
- Variant(const Color& value);
- Variant(const String value);
- Variant(const char* value);
- Variant(const PODVector<unsigned char>& value);
- Variant(const VectorBuffer& value);
- Variant(const ResourceRef& value);
- Variant(const ResourceRefList& value);
- Variant(const VariantMap& value);
- Variant(const IntRect& value);
- Variant(const IntVector2& value);
- Variant(const Matrix3& value);
- Variant(const Matrix3x4& value);
- Variant(const Matrix4& value);
- Variant(const String type, const String value);
- Variant(VariantType type, const String value);
- Variant(const char* type, const char* value);
- Variant(VariantType type, const char* value);
- Variant(const Variant& value);
- ~Variant();
- void Clear();
- bool operator ==(void* rhs) const;
- bool operator ==(RefCounted* rhs) const;
- bool operator ==(const Variant& rhs) const;
- bool operator ==(int rhs) const;
- bool operator ==(unsigned rhs) const;
- bool operator ==(bool rhs) const;
- bool operator ==(float rhs) const;
- bool operator ==(double rhs) const;
- bool operator ==(const Vector2& rhs);
- bool operator ==(const Vector3& rhs) const;
- bool operator ==(const Vector4& rhs) const;
- bool operator ==(const Quaternion& rhs) const;
- bool operator ==(const Color& rhs) const;
- bool operator ==(const String rhs) const;
- bool operator ==(const PODVector<unsigned char>& rhs) const;
- bool operator ==(const VectorBuffer& rhs) const;
- bool operator ==(const ResourceRef& rhs) const;
- bool operator ==(const ResourceRefList& rhs) const;
- bool operator ==(const Vector<Variant>& rhs) const;
- bool operator ==(const Vector<String>& rhs) const;
- bool operator ==(const VariantMap& rhs) const;
- bool operator ==(const IntRect& rhs) const;
- bool operator ==(const IntVector2& rhs) const;
- bool operator ==(const StringHash& rhs) const;
- bool operator ==(const Matrix3& rhs) const;
- bool operator ==(const Matrix3x4& rhs) const;
- bool operator ==(const Matrix4& rhs) const;
- int GetInt() const;
- unsigned GetUInt() const;
- StringHash GetStringHash();
- bool GetBool() const;
- float GetFloat() const;
- double GetDouble() const;
- const Vector2& GetVector2() const;
- const Vector3& GetVector3() const;
- const Vector4& GetVector4() const;
- const Quaternion& GetQuaternion() const;
- const Color& GetColor() const;
- const String GetString() const;
- const PODVector<unsigned char>& GetBuffer @ GetRawBuffer() const;
- const VectorBuffer GetVectorBuffer @ GetBuffer() const; // For backward compatibility reason, keep the old alias
- void* GetVoidPtr(const char* type) const;
- const ResourceRef& GetResourceRef() const;
- const ResourceRefList& GetResourceRefList() const;
- const Vector<Variant>& GetVariantVector() const;
- const VariantMap& GetVariantMap() const;
- const Vector<String>& GetStringVector() const;
- const IntRect& GetIntRect() const;
- const IntVector2& GetIntVector2() const;
- RefCounted* GetPtr(const char* type) const;
- const Matrix3& GetMatrix3() const;
- const Matrix3x4& GetMatrix3x4() const;
- const Matrix4& GetMatrix4() const;
- VariantType GetType() const;
- String GetTypeName() const;
- String ToString() const;
- bool IsZero() const;
- bool IsEmpty() const;
- tolua_readonly tolua_property__get_set VariantType type;
- tolua_readonly tolua_property__get_set String typeName;
- tolua_readonly tolua_property__is_set bool zero;
- tolua_readonly tolua_property__is_set bool empty;
- };
- $[
- -- Call the setup method and then hide it immediately
- Variant:_Setup("Variant")
- Variant:_Setup("const Variant")
- Variant._Setup = nil
- $]
- ${
- static int VariantToStringEventHandler(lua_State* tolua_S)
- {
- lua_pushstring(tolua_S, static_cast<Variant*>(tolua_tousertype(tolua_S, -1, 0))->ToString().CString());
- return 1;
- }
- static int VariantConcatEventHandler(lua_State* tolua_S)
- {
- // __concat event handler has two operands, check whether the first operand is variant or the second is (one of them must be)
- // This event handler has two code branches to handle both cases differently based on the isFirst flag
- // In case of both operands are variant then the handler handles the case as if it is isFirst case then below lua_concat() call
- // would in turn trigger the handler the second time to handle the second operand using the !isFirst code branch
- bool isFirst = lua_isuserdata(tolua_S, 1);
- if (isFirst)
- lua_pushvalue(tolua_S, 1); // isFirst stack: variant1 operand2 variant1
- VariantToStringEventHandler(tolua_S); // isFirst stack: variant1 operand2 variant1 string1 | !isFirst: operand1 variant2 string2
- if (isFirst)
- {
- lua_replace(tolua_S, 1); // isFirst stack: string1 operand2 variant1
- lua_pop(tolua_S, 1); // isFirst stack: string1 operand2
- }
- else
- lua_remove(tolua_S, -2); // !isFirst stack: operand1 string2
- lua_concat(tolua_S, 2);
- return 1;
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant__Setup00
- static int tolua_CoreLuaAPI_Variant__Setup00(lua_State* tolua_S)
- {
- // Register our own version of metamethod to handle __tostring and __concat events
- luaL_getmetatable(tolua_S, tolua_tostring(tolua_S, 2, 0));
- lua_pushstring(tolua_S, "__tostring");
- lua_pushcfunction(tolua_S, VariantToStringEventHandler);
- lua_rawset(tolua_S, -3);
- lua_pushstring(tolua_S, "__concat");
- lua_pushcfunction(tolua_S, VariantConcatEventHandler);
- lua_rawset(tolua_S, -3);
- lua_pop(tolua_S, 1);
- return 0;
- }
- // NOTE: the index number must match with the above variant constructor overloads order)
- // Special cases handling for converted VariantVector and StringVector as Lua table
- // The auto-generated code are almost correct, except for the tolua_isnoobj() always return false for third index,
- // probably due to another tolua++ bug not setting the stack correctly, instead of noobj, 3rd index contains first table member
- // Forward declaration
- static int tolua_CoreLuaAPI_Variant_new00(lua_State* tolua_S);
- static int tolua_CoreLuaAPI_Variant_new00_local(lua_State* tolua_S);
- // Correct auto-generated code
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new01
- static int tolua_CoreLuaAPI_Variant_new01(lua_State* tolua_S)
- {
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<Variant>(tolua_S,2,"const Vector<Variant>",0,&tolua_err)) /*||
- !tolua_isnoobj(tolua_S,3,&tolua_err)*/
- )
- goto tolua_lerror;
- else
- {
- const Vector<Variant>* value = ((const Vector<Variant>*) ToluaToVector<Variant>(tolua_S,2,0));
- {
- Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
- }
- }
- return 1;
- tolua_lerror:
- return tolua_CoreLuaAPI_Variant_new00(tolua_S);
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new01_local
- static int tolua_CoreLuaAPI_Variant_new01_local(lua_State* tolua_S)
- {
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<Variant>(tolua_S,2,"const Vector<Variant>",0,&tolua_err)) /*||
- !tolua_isnoobj(tolua_S,3,&tolua_err)*/
- )
- goto tolua_lerror;
- else
- {
- const Vector<Variant>* value = ((const Vector<Variant>*) ToluaToVector<Variant>(tolua_S,2,0));
- {
- Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
- tolua_lerror:
- return tolua_CoreLuaAPI_Variant_new00_local(tolua_S);
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new02
- static int tolua_CoreLuaAPI_Variant_new02(lua_State* tolua_S)
- {
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<String>(tolua_S,2,"const Vector<String>",0,&tolua_err)) /*||
- !tolua_isnoobj(tolua_S,3,&tolua_err)*/
- )
- goto tolua_lerror;
- else
- {
- const Vector<String>* value = ((const Vector<String>*) ToluaToVector<String>(tolua_S,2,0));
- {
- Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
- }
- }
- return 1;
- tolua_lerror:
- return tolua_CoreLuaAPI_Variant_new01(tolua_S);
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new02_local
- static int tolua_CoreLuaAPI_Variant_new02_local(lua_State* tolua_S)
- {
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<String>(tolua_S,2,"const Vector<String>",0,&tolua_err)) /*||
- !tolua_isnoobj(tolua_S,3,&tolua_err)*/
- )
- goto tolua_lerror;
- else
- {
- const Vector<String>* value = ((const Vector<String>*) ToluaToVector<String>(tolua_S,2,0));
- {
- Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
- tolua_lerror:
- return tolua_CoreLuaAPI_Variant_new01_local(tolua_S);
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_GetVoidPtr00
- static int tolua_CoreLuaAPI_Variant_GetVoidPtr00(lua_State* tolua_S)
- {
- #ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Variant",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- #endif
- {
- const Variant* self = (const Variant*) tolua_tousertype(tolua_S,1,0);
- const char* type = ((const char*) tolua_tostring(tolua_S,2,0));
- #ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVoidPtr'", NULL);
- #endif
- {
- void* tolua_ret = self->GetVoidPtr();
- tolua_pushusertype(tolua_S, tolua_ret, type);
- }
- }
- return 1;
- #ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetVoidPtr'.",&tolua_err);
- return 0;
- #endif
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_GetPtr00
- static int tolua_CoreLuaAPI_Variant_GetPtr00(lua_State* tolua_S)
- {
- #ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Variant",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- #endif
- {
- const Variant* self = (const Variant*) tolua_tousertype(tolua_S,1,0);
- const char* type = ((const char*) tolua_tostring(tolua_S,2,0));
- #ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPtr'", NULL);
- #endif
- {
- RefCounted* tolua_ret = self->GetPtr();
- tolua_pushusertype(tolua_S, (void*)tolua_ret, type);
- }
- }
- return 1;
- #ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPtr'.",&tolua_err);
- return 0;
- #endif
- }
- $}
- class VariantMap
- {
- static void _Setup(const char* type);
- VariantMap();
- ~VariantMap();
- };
- $[
- VariantMap:_Setup("VariantMap")
- VariantMap:_Setup("const VariantMap")
- VariantMap._Setup = nil
- $]
- ${
- static int VariantMapIndexEventHandler(lua_State* tolua_S)
- {
- int t = lua_type(tolua_S, 2);
- StringHash key;
- if (t == LUA_TSTRING)
- key = StringHash(lua_tostring(tolua_S, 2));
- else if (t == LUA_TNUMBER)
- key = StringHash((unsigned)lua_tonumber(tolua_S, 2));
- else
- {
- lua_pushnil(tolua_S);
- return 1;
- }
- Variant* variant = static_cast<const VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key);
- if (variant)
- tolua_pushusertype(tolua_S, variant, "Variant");
- else
- lua_pushnil(tolua_S);
- return 1;
- }
- static int VariantMapNewIndexEventHandler(lua_State* tolua_S)
- {
- int t = lua_type(tolua_S, 2);
- StringHash key;
- if (t == LUA_TSTRING)
- key = StringHash(lua_tostring(tolua_S, 2));
- else if (t == LUA_TNUMBER)
- key = StringHash((unsigned)lua_tonumber(tolua_S, 2));
- else
- return 0;
- Variant& variant = static_cast<VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key); // autovivification
- switch (lua_type(tolua_S, 3)) // Use the type of lua object to determine the final variant type
- {
- case LUA_TNIL:
- variant = Variant::EMPTY;
- break;
- case LUA_TBOOLEAN:
- variant = (bool)lua_toboolean(tolua_S, 3); // Still need to cast to bool as Lua/LuaJIT return it as int
- break;
- case LUA_TNUMBER:
- {
- // Use the original variant type to further determine the final variant type
- // CAVEAT: if lhs has integral data type and double is desired then lhs needs to be reset first before assigning
- double value = lua_tonumber(tolua_S, 3);
- switch (variant.GetType())
- {
- case VAR_INT:
- variant = (int)value;
- break;
- case VAR_BOOL:
- variant = value != 0.0f;
- break;
- case VAR_FLOAT:
- variant = (float)value;
- break;
- default:
- variant = value;
- }
- }
- break;
- case LUA_TSTRING:
- variant = lua_tostring(tolua_S, 3);
- break;
- case LUA_TUSERDATA:
- {
- if (lua_getmetatable(tolua_S, 3))
- {
- lua_rawget(tolua_S, LUA_REGISTRYINDEX); // registry[mt]
- const char* typeName = lua_tostring(tolua_S, -1);
- lua_pop(tolua_S, 1);
- void* value = tolua_tousertype(tolua_S, 3, 0);
- switch (Variant::GetTypeFromName(typeName))
- {
- case VAR_NONE:
- // Handle special cases
- if (typeName)
- {
- tolua_Error error;
- if (strcmp(typeName, "Variant") == 0)
- variant = *static_cast<Variant*>(value);
- else if (strcmp(typeName, "VectorBuffer") == 0)
- variant = *static_cast<VectorBuffer*>(value);
- else if (tolua_isusertype(tolua_S, 3, "RefCounted", 0, &error))
- variant = static_cast<RefCounted*>(value);
- else
- variant = value; // void*
- }
- break;
- case VAR_VECTOR2:
- variant = *static_cast<Vector2*>(value);
- break;
- case VAR_VECTOR3:
- variant = *static_cast<Vector3*>(value);
- break;
- case VAR_VECTOR4:
- variant = *static_cast<Vector4*>(value);
- break;
- case VAR_QUATERNION:
- variant = *static_cast<Quaternion*>(value);
- break;
- case VAR_COLOR:
- variant = *static_cast<Color*>(value);
- break;
- case VAR_INTRECT:
- variant = *static_cast<IntRect*>(value);
- break;
- case VAR_INTVECTOR2:
- variant = *static_cast<IntVector2*>(value);
- break;
- case VAR_MATRIX3:
- variant = *static_cast<Matrix3*>(value);
- break;
- case VAR_MATRIX3X4:
- variant = *static_cast<Matrix3x4*>(value);
- break;
- case VAR_MATRIX4:
- variant = *static_cast<Matrix4*>(value);
- break;
- case VAR_RESOURCEREF:
- variant = *static_cast<ResourceRef*>(value);
- break;
- case VAR_RESOURCEREFLIST:
- variant = *static_cast<ResourceRefList*>(value);
- break;
- case VAR_VARIANTMAP:
- variant = *static_cast<VariantMap*>(value);
- break;
- default: break;
- }
- };
- }
- break;
- case LUA_TTABLE:
- {
- tolua_Error error;
- if (ToluaIsPODVector<unsigned char>(0.f, tolua_S, 3, "unsigned char", 0, &error))
- variant = *static_cast<PODVector<unsigned char>*>(ToluaToPODVector<unsigned char>(0.f, tolua_S, 3, 0));
- else if (ToluaIsVector<Variant>(tolua_S, 3, "Variant", 0, &error))
- variant = *static_cast<VariantVector*>(ToluaToVector<Variant>(tolua_S, 3, 0));
- else if (ToluaIsVector<String>(tolua_S, 3, "String", 0, &error))
- variant = *static_cast<StringVector*>(ToluaToVector<String>(tolua_S, 3, 0));
- }
- break;
- default: break;
- }
- return 0;
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_VariantMap__Setup00
- static int tolua_CoreLuaAPI_VariantMap__Setup00(lua_State* tolua_S)
- {
- // Register our own version of metamethod to handle __index and __newindex events
- luaL_getmetatable(tolua_S, tolua_tostring(tolua_S, 2, 0));
- lua_pushstring(tolua_S, "__index");
- lua_pushcfunction(tolua_S, VariantMapIndexEventHandler);
- lua_rawset(tolua_S, -3);
- lua_pushstring(tolua_S, "__newindex");
- lua_pushcfunction(tolua_S, VariantMapNewIndexEventHandler);
- lua_rawset(tolua_S, -3);
- lua_pop(tolua_S, 1);
- return 0;
- }
- $}
|