| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- $#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,
- VAR_RECT,
- VAR_INTVECTOR3,
- VAR_INT64,
- MAX_VAR_TYPES
- };
- struct ResourceRef
- {
- ResourceRef();
- ResourceRef(StringHash type);
- ResourceRef(StringHash type, String name);
- ResourceRef(String 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);
- // NOTE: do not change the constructor overloads order without also changing the manually coded implementation below
- Variant();
- Variant(const Variant& value); // This overload works for all Lua types that are convertible into a Variant
- Variant(const char* type, const char* value); // For storing a numerical type into Variant , value could be just a number
- Variant(VariantType type, const char* value);
- ~Variant();
- void Clear();
- bool operator ==(const Variant& rhs) const; // rhs can be any Lua types convertible into a Variant
- void Set(const Variant& rhs); // rhs can be any Lua types convertible into a Variant
- void* Get(const char* type = 0) const; // "Generic" get which is only possible in Lua scripting
- // All below getters are preserved for backward compatibility and for compatibility with C++ and AngelScript API
- int GetInt() const;
- unsigned GetUInt() const;
- long long int GetInt64() const;
- unsigned long long int GetUInt64() const;
- StringHash GetStringHash() const;
- 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;
- 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 Rect& GetRect() const;
- const IntRect& GetIntRect() const;
- const IntVector2& GetIntVector2() const;
- const IntVector3& GetIntVector3() 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)
- // Forward declaration
- static int tolua_CoreLuaAPI_Variant_new00(lua_State* tolua_S);
- static int tolua_CoreLuaAPI_Variant_new00_local(lua_State* tolua_S);
- static bool VariantNewImpl(lua_State* tolua_S, bool gc)
- {
- tolua_Error tolua_err;
- if (tolua_isusertable(tolua_S, 1, "Variant", 0, &tolua_err) && lua_gettop(tolua_S) == 2)
- {
- Variant* tolua_ret = Mtolua_new(Variant());
- ToluaToVariant(tolua_S, 2, 0, *tolua_ret);
- tolua_pushusertype(tolua_S, static_cast<void*>(tolua_ret), "Variant");
- if (gc)
- tolua_register_gc(tolua_S, lua_gettop(tolua_S));
- return true;
- }
- return false;
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new01
- static int tolua_CoreLuaAPI_Variant_new01(lua_State* tolua_S)
- {
- return VariantNewImpl(tolua_S, false) ? 1 : 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)
- {
- return VariantNewImpl(tolua_S, true) ? 1 : tolua_CoreLuaAPI_Variant_new00_local(tolua_S);
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant__eq00
- static int tolua_CoreLuaAPI_Variant__eq00(lua_State* tolua_S)
- {
- #ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (tolua_isusertype(tolua_S, 1, "const Variant", 0, &tolua_err) && lua_gettop(tolua_S) == 2)
- #endif
- {
- const Variant* self = static_cast<const Variant*>(tolua_tousertype(tolua_S, 1, 0));
- Variant rhs;
- ToluaToVariant(tolua_S, 2, 0, rhs);
- #ifndef TOLUA_RELEASE
- if (!self)
- tolua_error(tolua_S, "invalid 'self' in function 'operator=='", NULL);
- else
- #endif
- {
- tolua_pushboolean(tolua_S, self->operator ==(rhs));
- return 1;
- }
- }
- #ifndef TOLUA_RELEASE
- tolua_error(tolua_S, "#ferror in function '.eq'.", &tolua_err);
- return 0;
- #endif
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_Set00
- static int tolua_CoreLuaAPI_Variant_Set00(lua_State* tolua_S)
- {
- #ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (tolua_isusertype(tolua_S, 1, "Variant", 0, &tolua_err) && lua_gettop(tolua_S) == 2)
- #endif
- {
- Variant * self = static_cast<Variant*>(tolua_tousertype(tolua_S, 1, 0));
- Variant rhs;
- ToluaToVariant(tolua_S, 2, 0, rhs);
- const char* type = tolua_tostring(tolua_S, 3, 0);
- #ifndef TOLUA_RELEASE
- if (!self)
- tolua_error(tolua_S, "invalid 'self' in function 'Set'", NULL);
- else
- #endif
- {
- *self = rhs;
- return 0;
- }
- }
- #ifndef TOLUA_RELEASE
- tolua_error(tolua_S, "#ferror in function 'Set'.", &tolua_err);
- return 0;
- #endif
- }
- #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_Get00
- static int tolua_CoreLuaAPI_Variant_Get00(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))
- #endif
- {
- const Variant* self = static_cast<const Variant*>(tolua_tousertype(tolua_S, 1, 0));
- const char* type = tolua_tostring(tolua_S, 2, 0);
- #ifndef TOLUA_RELEASE
- if (!self)
- tolua_error(tolua_S, "invalid 'self' in function 'Get'", NULL);
- else
- #endif
- {
- ToluaPushVariant(tolua_S, self, type);
- return 1;
- }
- }
- #ifndef TOLUA_RELEASE
- tolua_error(tolua_S, "#ferror in function 'Get'.", &tolua_err);
- return 0;
- #endif
- }
- #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
- {
- // Use the safer version which first check the type provided through Lua script to prevent VM crashes on invalid type
- ToluaPushRegisteredUserType(tolua_S, static_cast<void*>(self->GetVoidPtr()), 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
- {
- ToluaPushRegisteredUserType(tolua_S, static_cast<void*>(self->GetPtr()), 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 if (t == LUA_TUSERDATA)
- {
- tolua_Error error;
- if (tolua_isusertype(tolua_S, 2, "StringHash", 0, &error))
- key = *static_cast<StringHash*>(tolua_tousertype(tolua_S, 2, 0));
- }
- Variant* variant = key ? static_cast<const VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key) : 0;
- 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 if (t == LUA_TUSERDATA)
- {
- tolua_Error error;
- if (tolua_isusertype(tolua_S, 2, "StringHash", 0, &error))
- key = *static_cast<StringHash*>(tolua_tousertype(tolua_S, 2, 0));
- else
- return 0;
- }
- else
- return 0;
- Variant& variant = static_cast<VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key); // autovivification
- ToluaToVariant(tolua_S, 3, 0, variant);
- 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;
- }
- $}
|