Merge pull request #535 from adxeproject/ccvalue-int64-support

Add `CCValue` int64_t/uint64_t support
This commit is contained in:
halx99 2021-11-09 15:03:10 +08:00 committed by GitHub
commit 382f33a704
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 69 deletions

View File

@ -27,6 +27,7 @@ adxe-1.0 ??
[HIGHLIGHT] Modularize all optional extension, move from engine core to folder extensions
[HIGHLIGHT] Improve thirdparty libs building, 99% of them build from sources or github actions with latest toolchain, see also: `adxeproject/buildware`
[HIGHLIGHT] Add new API `Director::setChildrenIndexerEnabled` for speed up getChildByTag & getChildByName support
[NEW] Add `CCValue` int64_t/uint64_t support
[FIX] Fix uniform location mismatch when more than 1 spine with different shaders
[FIX] Fix imgui draw frame cause afterimage when game scene nothing to draw
[FIX] Set global Z value of label debug layer to be the same as the parent label to fix display issue

View File

@ -45,21 +45,33 @@ Value::Value() : _type(Type::NONE)
memset(&_field, 0, sizeof(_field));
}
Value::Value(unsigned char v) : _type(Type::INTEGER)
Value::Value(unsigned char v) : _type(Type::INT_UI32)
{
_field.uintVal = v;
}
Value::Value(int v) : _type(Type::INTEGER)
Value::Value(int v) : _type(Type::INT_I32)
{
_field.intVal = v;
}
Value::Value(unsigned int v) : _type(Type::UNSIGNED)
Value::Value(unsigned int v) : _type(Type::INT_UI32)
{
_field.uintVal = v;
}
/** Create a Value by an integer value. */
Value::Value(int64_t v) : _type(Type::INT_I64)
{
_field.int64Val = v;
}
/** Create a Value by an integer value. */
Value::Value(uint64_t v) : _type(Type::INT_UI64)
{
_field.uint64Val = v;
}
Value::Value(float v) : _type(Type::FLOAT)
{
_field.floatVal = v;
@ -141,13 +153,10 @@ Value& Value::operator=(const Value& other)
{
reset(other._type);
switch (other._type)
switch (other.getTypeFamily())
{
case Type::INTEGER:
_field.intVal = other._field.intVal;
break;
case Type::UNSIGNED:
_field.uintVal = other._field.uintVal;
_field.uint64Val = other._field.uint64Val;
break;
case Type::FLOAT:
_field.floatVal = other._field.floatVal;
@ -198,12 +207,9 @@ Value& Value::operator=(Value&& other)
if (this != &other)
{
clear();
switch (other._type)
switch (other.getTypeFamily())
{
case Type::INTEGER:
_field.intVal = other._field.intVal;
break;
case Type::UNSIGNED:
_field.uintVal = other._field.uintVal;
break;
case Type::FLOAT:
@ -241,25 +247,39 @@ Value& Value::operator=(Value&& other)
Value& Value::operator=(unsigned char v)
{
reset(Type::UNSIGNED);
reset(Type::INT_UI32);
_field.uintVal = v;
return *this;
}
Value& Value::operator=(int v)
{
reset(Type::INTEGER);
reset(Type::INT_I32);
_field.intVal = v;
return *this;
}
Value& Value::operator=(unsigned int v)
{
reset(Type::UNSIGNED);
reset(Type::INT_UI32);
_field.uintVal = v;
return *this;
}
Value& Value::operator=(int64_t v)
{
reset(Type::INT_I64);
_field.int64Val = v;
return *this;
}
Value& Value::operator=(uint64_t v)
{
reset(Type::INT_UI64);
_field.uint64Val = v;
return *this;
}
Value& Value::operator=(float v)
{
reset(Type::FLOAT);
@ -366,12 +386,16 @@ bool Value::operator==(const Value& v) const
return false;
if (this->isNull())
return true;
switch (_type)
switch (getType())
{
case Type::INTEGER:
case Type::INT_I32:
return v._field.intVal == this->_field.intVal;
case Type::UNSIGNED:
case Type::INT_UI32:
return v._field.uintVal == this->_field.uintVal;
case Type::INT_I64:
return v._field.int64Val == this->_field.int64Val;
case Type::INT_UI64:
return v._field.int64Val == this->_field.int64Val;
case Type::BOOLEAN:
return v._field.boolVal == this->_field.boolVal;
case Type::STRING:
@ -439,11 +463,14 @@ unsigned char Value::asByte(unsigned char defaultValue) const
switch (_type)
{
case Type::INTEGER:
return static_cast<unsigned char>(_field.intVal);
case Type::UNSIGNED:
case Type::INT_UI32:
return static_cast<unsigned char>(_field.uintVal);
case Type::INT_I32:
return static_cast<unsigned char>(_field.intVal);
case Type::INT_I64:
return static_cast<unsigned char>(_field.int64Val);
case Type::INT_UI64:
return static_cast<unsigned char>(_field.uint64Val);
case Type::STRING:
return static_cast<unsigned char>(atoi(_field.strVal->c_str()));
@ -468,12 +495,14 @@ int Value::asInt(int defaultValue) const
"Only base type (bool, string, float, double, int) could be converted");
switch (_type)
{
case Type::INTEGER:
return _field.intVal;
case Type::UNSIGNED:
CCASSERT(_field.uintVal < INT_MAX, "Can only convert values < INT_MAX");
return (int)_field.uintVal;
case Type::INT_I32:
return (_field.intVal);
case Type::INT_UI32:
return static_cast<int>(_field.uintVal);
case Type::INT_I64:
return static_cast<int>(_field.int64Val);
case Type::INT_UI64:
return static_cast<int>(_field.uint64Val);
case Type::STRING:
return atoi(_field.strVal->c_str());
@ -492,18 +521,20 @@ int Value::asInt(int defaultValue) const
}
}
unsigned int Value::asUnsignedInt(unsigned int defaultValue) const
unsigned int Value::asUint(unsigned int defaultValue) const
{
CCASSERT(_type != Type::VECTOR && _type != Type::MAP && _type != Type::INT_KEY_MAP,
"Only base type (bool, string, float, double, int) could be converted");
switch (_type)
{
case Type::UNSIGNED:
return _field.uintVal;
case Type::INTEGER:
CCASSERT(_field.intVal >= 0, "Only values >= 0 can be converted to unsigned");
case Type::INT_UI32:
return (_field.uintVal);
case Type::INT_I32:
return static_cast<unsigned int>(_field.intVal);
case Type::INT_I64:
return static_cast<unsigned int>(_field.int64Val);
case Type::INT_UI64:
return static_cast<unsigned int>(_field.uint64Val);
case Type::STRING:
// NOTE: strtoul is required (need to augment on unsupported platforms)
@ -523,6 +554,72 @@ unsigned int Value::asUnsignedInt(unsigned int defaultValue) const
}
}
int64_t Value::asInt64(int64_t defaultValue) const
{
CCASSERT(_type != Type::VECTOR && _type != Type::MAP && _type != Type::INT_KEY_MAP,
"Only base type (bool, string, float, double, int) could be converted");
switch (_type)
{
case Type::INT_I64:
return (_field.int64Val);
case Type::INT_I32:
return static_cast<int64_t>(_field.intVal);
case Type::INT_UI32:
return static_cast<int64_t>(_field.uintVal);
case Type::INT_UI64:
return static_cast<int64_t>(_field.uint64Val);
case Type::STRING:
// NOTE: strtoul is required (need to augment on unsupported platforms)
return static_cast<int64_t>(strtoul(_field.strVal->c_str(), nullptr, 10));
case Type::FLOAT:
return static_cast<int64_t>(_field.floatVal);
case Type::DOUBLE:
return static_cast<int64_t>(_field.doubleVal);
case Type::BOOLEAN:
return _field.boolVal ? 1u : 0u;
default:
return defaultValue;
}
}
uint64_t Value::asUint64(uint64_t defaultValue) const
{
CCASSERT(_type != Type::VECTOR && _type != Type::MAP && _type != Type::INT_KEY_MAP,
"Only base type (bool, string, float, double, int) could be converted");
switch (_type)
{
case Type::INT_UI64:
return (_field.uint64Val);
case Type::INT_I32:
return static_cast<uint64_t>(_field.intVal);
case Type::INT_UI32:
return static_cast<uint64_t>(_field.uintVal);
case Type::INT_I64:
return static_cast<uint64_t>(_field.int64Val);
case Type::STRING:
// NOTE: strtoul is required (need to augment on unsupported platforms)
return static_cast<uint64_t>(strtoull(_field.strVal->c_str(), nullptr, 10));
case Type::FLOAT:
return static_cast<uint64_t>(_field.floatVal);
case Type::DOUBLE:
return static_cast<uint64_t>(_field.doubleVal);
case Type::BOOLEAN:
return _field.boolVal ? 1u : 0u;
default:
return defaultValue;
}
}
float Value::asFloat(float defaultValue) const
{
CCASSERT(_type != Type::VECTOR && _type != Type::MAP && _type != Type::INT_KEY_MAP,
@ -535,11 +632,14 @@ float Value::asFloat(float defaultValue) const
case Type::STRING:
return static_cast<float>(utils::atof(_field.strVal->c_str()));
case Type::INTEGER:
case Type::INT_I32:
return static_cast<float>(_field.intVal);
case Type::UNSIGNED:
case Type::INT_UI32:
return static_cast<float>(_field.uintVal);
case Type::INT_I64:
return static_cast<float>(_field.int64Val);
case Type::INT_UI64:
return static_cast<float>(_field.uint64Val);
case Type::DOUBLE:
return static_cast<float>(_field.doubleVal);
@ -564,11 +664,14 @@ double Value::asDouble(double defaultValue) const
case Type::STRING:
return static_cast<double>(utils::atof(_field.strVal->c_str()));
case Type::INTEGER:
case Type::INT_I32:
return static_cast<double>(_field.intVal);
case Type::UNSIGNED:
case Type::INT_UI32:
return static_cast<double>(_field.uintVal);
case Type::INT_I64:
return static_cast<double>(_field.int64Val);
case Type::INT_UI64:
return static_cast<double>(_field.uint64Val);
case Type::FLOAT:
return static_cast<double>(_field.floatVal);
@ -593,11 +696,14 @@ bool Value::asBool(bool defaultValue) const
case Type::STRING:
return (*_field.strVal == "0" || *_field.strVal == "false") ? false : true;
case Type::INTEGER:
return _field.intVal == 0 ? false : true;
case Type::UNSIGNED:
return _field.uintVal == 0 ? false : true;
case Type::INT_I32:
return !!_field.intVal;
case Type::INT_UI32:
return !!_field.uintVal;
case Type::INT_I64:
return !!_field.int64Val;
case Type::INT_UI64:
return !!_field.uint64Val;
case Type::FLOAT:
return _field.floatVal == 0.0f ? false : true;
@ -629,12 +735,18 @@ std::string Value::asString() const
size_t n = 0;
switch (_type)
{
case Type::INTEGER:
case Type::INT_I32:
ret = std::to_string(_field.intVal);
break;
case Type::UNSIGNED:
case Type::INT_UI32:
ret = std::to_string(_field.uintVal);
break;
case Type::INT_I64:
ret = std::to_string(_field.int64Val);
break;
case Type::INT_UI64:
ret = std::to_string(_field.uint64Val);
break;
case Type::FLOAT:
ret.resize(NUMBER_MAX_DIGITS);
n = snprintf(&ret.front(), NUMBER_MAX_DIGITS + 1, "%.*g", 7 /*precision*/, _field.floatVal);
@ -760,11 +872,10 @@ static std::string visit(const Value& v, int depth)
{
std::stringstream ret;
switch (v.getType())
switch (v.getTypeFamily())
{
case Value::Type::NONE:
case Value::Type::INTEGER:
case Value::Type::UNSIGNED:
case Value::Type::FLOAT:
case Value::Type::DOUBLE:
case Value::Type::BOOLEAN:
@ -798,13 +909,10 @@ std::string Value::getDescription() const
void Value::clear()
{
// Free memory the old value allocated
switch (_type)
switch (getTypeFamily())
{
case Type::INTEGER:
_field.intVal = 0;
break;
case Type::UNSIGNED:
_field.uintVal = 0u;
_field.uint64Val = 0;
break;
case Type::FLOAT:
_field.floatVal = 0.0f;

View File

@ -72,6 +72,12 @@ public:
/** Create a Value by an unsigned value. */
explicit Value(unsigned int v);
/** Create a Value by an integer value. */
explicit Value(int64_t v);
/** Create a Value by an integer value. */
explicit Value(uint64_t v);
/** Create a Value by a float value. */
explicit Value(float v);
@ -123,6 +129,10 @@ public:
Value& operator= (int v);
/** Assignment operator, assign from integer to Value. */
Value& operator= (unsigned int v);
/** Assignment operator, assign from integer to Value. */
Value& operator=(int64_t v);
/** Assignment operator, assign from integer to Value. */
Value& operator=(uint64_t v);
/** Assignment operator, assign from float to Value. */
Value& operator= (float v);
/** Assignment operator, assign from double to Value. */
@ -164,7 +174,12 @@ public:
/** Gets as an integer value. Will convert to integer if possible, or will trigger assert error. */
int asInt(int defaultValue = 0) const;
/** Gets as an unsigned value. Will convert to unsigned if possible, or will trigger assert error. */
unsigned int asUnsignedInt(unsigned defaultValue = 0) const;
unsigned int asUint(unsigned int defaultValue = 0) const;
unsigned int asUnsignedInt(unsigned int defaultValue = 0) const { return asUint(defaultValue); }
/** Gets as an integer value. Will convert to integer if possible, or will trigger assert error. */
int64_t asInt64(int64_t defaultValue = 0) const;
/** Gets as an unsigned value. Will convert to unsigned if possible, or will trigger assert error. */
uint64_t asUint64(uint64_t defaultValue = 0) const;
/** Gets as a float value. Will convert to float if possible, or will trigger assert error. */
float asFloat(float defaultValue = 0.0f) const;
/** Gets as a double value. Will convert to double if possible, or will trigger assert error. */
@ -199,14 +214,12 @@ public:
bool isNull() const { return _type == Type::NONE; }
/** Value type wrapped by Value. */
enum class Type
enum class Type : uint32_t
{
/// no value is wrapped, an empty Value
NONE = 0,
/// wrap integer
INTEGER,
/// wrap unsigned
UNSIGNED,
/// wrap float
FLOAT,
/// wrap double
@ -220,12 +233,22 @@ public:
/// wrap ValueMap
MAP,
/// wrap ValueMapIntKey
INT_KEY_MAP
INT_KEY_MAP,
MASK_UNSIGNED = 1 << 17,
MASK_64BIT = 1 << 18,
INT_I32 = INTEGER,
INT_UI32 = INTEGER | MASK_UNSIGNED,
INT_I64 = INTEGER | MASK_64BIT,
INT_UI64 = INTEGER | MASK_64BIT | MASK_UNSIGNED,
};
/** Gets the value type. */
Type getType() const { return _type; }
/** Gets the value type family. */
Type getTypeFamily() const { return (Type)((uint32_t)_type & 0xFFFFu); }
/** Gets the description of the class. */
std::string getDescription() const;
@ -237,6 +260,8 @@ private:
{
int intVal;
unsigned int uintVal;
int64_t int64Val;
uint64_t uint64Val;
float floatVal;
double doubleVal;
bool boolVal;

View File

@ -2344,7 +2344,7 @@ void fontdefinition_to_luaval(lua_State* L,const FontDefinition& inValue)
void ccvalue_to_luaval(lua_State* L,const cocos2d::Value& inValue)
{
const Value& obj = inValue;
switch (obj.getType())
switch (obj.getTypeFamily())
{
case Value::Type::BOOLEAN:
lua_pushboolean(L, obj.asBool());
@ -2354,7 +2354,7 @@ void ccvalue_to_luaval(lua_State* L,const cocos2d::Value& inValue)
lua_pushnumber(L, obj.asDouble());
break;
case Value::Type::INTEGER:
lua_pushinteger(L, obj.asInt());
lua_pushinteger(L, obj.asInt64());
break;
case Value::Type::STRING:
lua_pushstring(L, obj.asStringRef().c_str());
@ -2383,7 +2383,7 @@ void ccvaluemap_to_luaval(lua_State* L,const cocos2d::ValueMap& inValue)
{
std::string key = iter->first;
const Value& obj = iter->second;
switch (obj.getType())
switch (obj.getTypeFamily())
{
case Value::Type::BOOLEAN:
{
@ -2403,7 +2403,7 @@ void ccvaluemap_to_luaval(lua_State* L,const cocos2d::ValueMap& inValue)
case Value::Type::INTEGER:
{
lua_pushstring(L, key.c_str());
lua_pushinteger(L, obj.asInt());
lua_pushinteger(L, obj.asInt64());
lua_rawset(L, -3);
}
break;
@ -2455,7 +2455,7 @@ void ccvaluemapintkey_to_luaval(lua_State* L, const cocos2d::ValueMapIntKey& inV
const Value& obj = iter->second;
switch (obj.getType())
switch (obj.getTypeFamily())
{
case Value::Type::BOOLEAN:
{
@ -2475,7 +2475,7 @@ void ccvaluemapintkey_to_luaval(lua_State* L, const cocos2d::ValueMapIntKey& inV
case Value::Type::INTEGER:
{
lua_pushstring(L, key.c_str());
lua_pushinteger(L, obj.asInt());
lua_pushinteger(L, obj.asInt64());
lua_rawset(L, -3);
}
break;
@ -2522,7 +2522,7 @@ void ccvaluevector_to_luaval(lua_State* L, const cocos2d::ValueVector& inValue)
int index = 1;
for (const auto& obj : inValue)
{
switch (obj.getType())
switch (obj.getTypeFamily())
{
case Value::Type::BOOLEAN:
{
@ -2544,7 +2544,7 @@ void ccvaluevector_to_luaval(lua_State* L, const cocos2d::ValueVector& inValue)
case Value::Type::INTEGER:
{
lua_pushnumber(L, (lua_Number)index);
lua_pushnumber(L, obj.asInt());
lua_pushnumber(L, obj.asInt64());
lua_rawset(L, -3);
++index;
}

View File

@ -322,12 +322,12 @@ ValueTypeJudgeInTable* ValueTypeJudgeInTable::create(ValueMap valueMap)
int index = 0;
for (const auto& iter : valueMap)
{
Value::Type type = iter.second.getType();
Value::Type type = iter.second.getTypeFamily();
if (type == Value::Type::STRING) {
CCLOG("The type of index %d is string", index);
}
if (type == Value::Type::INTEGER || type == Value::Type::DOUBLE || type == Value::Type::FLOAT || type == Value::Type::BYTE) {
if (type == Value::Type::INTEGER || type == Value::Type::DOUBLE || type == Value::Type::FLOAT) {
CCLOG("The type of index %d is number", index);
}