CObjectNumber for Lua interop needs to deal with both double and sint64 types, cannot have separate CObjectInteger type

feature/pre-code-move
kaetemi 5 years ago committed by Jan Boon
parent 02270e7113
commit d56eab0420

@ -1245,7 +1245,7 @@ CObject* CComLuaModule::getObjectFromLua(lua_State* state, sint idx)
{
sint64 value = lua_tointeger(state, -1);
lua_pop(state, 1);
return new CObjectInteger(value);
return new CObjectNumber(value);
}
else
#endif

@ -175,12 +175,6 @@ void CObject::inPlaceCopy(const CObjectNumber &src)
copyMismatchMsg(src);
}
void CObject::inPlaceCopy(const CObjectInteger &src)
{
//H_AUTO(R2_CObject_inPlaceCopy)
copyMismatchMsg(src);
}
void CObject::inPlaceCopy(const CObjectTable &src)
{
//H_AUTO(R2_CObject_inPlaceCopy)
@ -764,7 +758,15 @@ void CObjectRefId::doSerialize(std::string& out, CSerializeContext& /* context
//----------------------- CObjectNumber ----------------------------------------
CObjectNumber::CObjectNumber(double value) : CObject(), _Value(value){}
CObjectNumber::CObjectNumber(double value) : CObject(), m_IsInteger(false)
{
m_Value.Integer = value;
}
CObjectNumber::CObjectNumber(sint64 value) : CObject(), m_IsInteger(true)
{
m_Value.Integer = value;
}
const char *CObjectNumber::getTypeAsString() const
{
@ -787,185 +789,137 @@ void CObjectNumber::inPlaceCopyTo(CObject &dest) const
void CObjectNumber::inPlaceCopy(const CObjectNumber &src)
{
//H_AUTO(R2_CObjectNumber_inPlaceCopy)
_Value = src._Value;
m_IsInteger = src.m_IsInteger;
m_Value.Integer = src.m_Value.Integer;
setGhost(src.getGhost());
}
std::string CObjectNumber::doToString() const { return NLMISC::toString("%lf", _Value);}
std::string CObjectNumber::doToString() const { return m_IsInteger ? NLMISC::toString(m_Value.Integer) : NLMISC::toString("%lf", m_Value.Number);}
void CObjectNumber::doSerialize(std::string& out, CSerializeContext& /* context */) const
{
//H_AUTO(R2_CObjectNumber_doSerialize)
nlassert(!getGhost());
//out.precision(15);
std::string value = NLMISC::toString(double(sint64(_Value * 1000.0 + (_Value>=0.0?0.5:-0.5)))/1000.0);
// search for first not 0 value from the end
std::string::size_type pos = value.find_last_not_of('0');
if (pos != std::string::npos)
if (m_IsInteger)
{
out += NLMISC::toString(m_Value.Integer);
}
else
{
// don't remove character at pos if it's another digit
if (value[pos] != '.') ++pos;
value.erase(pos);
//out.precision(15);
double num = getNumberValue();
// TODO: WTF is this for?!
std::string value = NLMISC::toString(double(sint64(num * 1000.0 + (num>=0.0?0.5:-0.5)))/1000.0);
// search for first not 0 value from the end
std::string::size_type pos = value.find_last_not_of('0');
if (pos != std::string::npos)
{
// don't remove character at pos if it's another digit
if (value[pos] != '.') ++pos;
value.erase(pos);
}
out += value;
}
out += value;
}
bool CObjectNumber::set(const std::string& key, double value)
bool CObjectNumber::set(const std::string& key, sint64 value)
{
//H_AUTO(R2_CObjectNumber_set)
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false);
_Value = value;
m_IsInteger = true;
m_Value.Integer = value;
return true;
}
bool CObjectNumber::set(const std::string& key, double value)
{
//H_AUTO(R2_CObjectNumber_set)
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false);
m_IsInteger = false;
m_Value.Number = value;
return true;
}
bool CObjectNumber::set(const std::string& key, const std::string & value)
{
//H_AUTO(R2_CObjectNumber_set)
//XXX
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false);
NLMISC::fromString(value, _Value);
return true;
double num;
sint64 i;
if (NLMISC::fromString(value, num))
{
m_IsInteger = false;
m_Value.Number = num;
}
if (NLMISC::fromString(value, i))
{
m_IsInteger = true;
m_Value.Number = i;
}
return false;
}
double CObjectNumber::doToNumber() const { return _Value; }
CObject* CObjectNumber::clone() const
{
//H_AUTO(R2_CObjectNumber_clone)
CObjectNumber *result = new CObjectNumber(_Value);
CObjectNumber *result = m_IsInteger
? new CObjectNumber(m_Value.Integer)
: new CObjectNumber(m_Value.Number);
result->setGhost(getGhost());
return result;
}
bool CObjectNumber::doIsNumber() const { return true;}
bool CObjectNumber::doIsNumber() const { return !m_IsInteger || (sint64)getNumberValue() == m_Value.Integer;}
double CObjectNumber::doToNumber() const { return getNumberValue(); }
bool CObjectNumber::doIsInteger() const { return m_IsInteger || (double)getIntegerValue() == m_Value.Number;}
sint64 CObjectNumber::doToInteger() const { return getIntegerValue(); }
bool CObjectNumber::setObject(const std::string& /* key */, CObject* value)
{
//H_AUTO(R2_CObjectNumber_setObject)
BOMB_IF(!value->isNumber(), NLMISC::toString("Try to set an element of a type '%s' with a value of type '%s' on an object that is not a number", this->getTypeAsString(), value->getTypeAsString()), return false);
BOMB_IF(!value->isNumber() && !value->isInteger(), NLMISC::toString("Try to set an element of a type '%s' with a value of type '%s' on an object that is not a number", this->getTypeAsString(), value->getTypeAsString()), return false);
_Value = value->toNumber();
if (value->isInteger())
{
m_IsInteger = true;
m_Value.Integer = value->toInteger();
}
else
{
m_IsInteger = false;
m_Value.Number = value->toNumber();
}
setGhost(value->getGhost());
return true;
}
bool CObjectNumber::equal(const CObject* other) const
{
//H_AUTO(R2_CObjectNumber_equal)
if (!other || !other->isNumber()) return false;
if (!other) return false;
if (isInteger())
{
if (!other->isInteger()) return false;
return (getIntegerValue() == other->toInteger());
}
if (!other->isNumber()) return false;
double value = getNumberValue();
double otherValue = other->toNumber();
if (_Value == otherValue) return true;
if (value == otherValue) return true;
// if difference between 2 values less than epsilon, we consider they are equals
return fabs(_Value - otherValue) <= std::numeric_limits<double>::epsilon();
return fabs(value - otherValue) <= std::numeric_limits<double>::epsilon();
}
//----------------------- CObjectInteger ----------------------------------------
CObjectInteger::CObjectInteger(sint64 value) : CObject(), _Value(value){}
const char *CObjectInteger::getTypeAsString() const
{
return "Integer";
}
void CObjectInteger::visitInternal(IObjectVisitor &visitor)
{
//H_AUTO(R2_CObjectInteger_visit)
visitor.visit(*this);
}
void CObjectInteger::inPlaceCopyTo(CObject &dest) const
{
//H_AUTO(R2_CObjectInteger_inPlaceCopyTo)
dest.inPlaceCopy(*this);
}
void CObjectInteger::inPlaceCopy(const CObjectInteger &src)
{
//H_AUTO(R2_CObjectInteger_inPlaceCopy)
_Value = src._Value;
setGhost(src.getGhost());
}
std::string CObjectInteger::doToString() const { return NLMISC::toString(_Value); }
void CObjectInteger::doSerialize(std::string& out, CSerializeContext& /* context */) const
{
//H_AUTO(R2_CObjectInteger_doSerialize)
nlassert(!getGhost());
out += NLMISC::toString(_Value);
}
bool CObjectInteger::set(const std::string& key, sint64 value)
{
//H_AUTO(R2_CObjectInteger_set)
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false);
_Value = value;
return true;
}
bool CObjectInteger::set(const std::string& key, const std::string & value)
{
//H_AUTO(R2_CObjectInteger_set)
//XXX
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false);
NLMISC::fromString(value, _Value);
return true;
}
sint64 CObjectInteger::doToInteger() const { return _Value; }
CObject* CObjectInteger::clone() const
{
//H_AUTO(R2_CObjectInteger_clone)
CObjectInteger *result = new CObjectInteger(_Value);
result->setGhost(getGhost());
return result;
}
bool CObjectInteger::doIsInteger() const { return true;}
bool CObjectInteger::setObject(const std::string& /* key */, CObject* value)
{
//H_AUTO(R2_CObjectInteger_setObject)
BOMB_IF(!value->isInteger(), NLMISC::toString("Try to set an element of a type '%s' with a value of type '%s' on an object that is not an integer", this->getTypeAsString(), value->getTypeAsString()), return false);
_Value = value->toInteger();
setGhost(value->getGhost());
return true;
}
bool CObjectInteger::equal(const CObject* other) const
{
//H_AUTO(R2_CObjectInteger_equal)
if (!other || !other->isInteger()) return false;
sint64 otherValue = other->toInteger();
return _Value == otherValue;
}
//----------------------- CObjectTable ----------------------------------------
@ -1686,7 +1640,7 @@ CObject* CObjectFactory::newBasic(const std::string & type)
}
else if (type == "Number")
{
return new CObjectNumber(0);
return new CObjectNumber((sint64)0);
}
else if (type == "Table")
{
@ -1976,15 +1930,10 @@ void CObjectNumber::dump(const std::string prefix, uint depth) const
{
//H_AUTO(R2_CObjectNumber_dump)
std::string result(depth * 4, ' ');
result += NLMISC::toString("%sNumber, ptr = 0x%p, value = %lf, ghost = %s", prefix.c_str(), this, _Value, _Ghost ? "true" : "false");
nlwarning(result.c_str());
}
void CObjectInteger::dump(const std::string prefix, uint depth) const
{
//H_AUTO(R2_CObjectInteger_dump)
std::string result(depth * 4, ' ');
result += NLMISC::toString("%sInteger, ptr = 0x%p, value = %" NL_I64 "d, ghost = %s", prefix.c_str(), this, _Value, _Ghost ? "true" : "false");
if (m_IsInteger)
result += NLMISC::toString("%sNumber, ptr = 0x%p, isNumber, value = %lf, ghost = %s", prefix.c_str(), this, m_Value.Integer, _Ghost ? "true" : "false");
else
result += NLMISC::toString("%sNumber, ptr = 0x%p, isInteger, value = %lf, ghost = %s", prefix.c_str(), this, m_Value.Number, _Ghost ? "true" : "false");
nlwarning(result.c_str());
}
@ -3330,13 +3279,13 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
double value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", value);
return;
}
case ObjectNumberZero:
{
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", 0.0);
return;
}
@ -3344,8 +3293,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
sint32 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
@ -3353,8 +3302,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
uint32 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
@ -3362,8 +3311,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
sint16 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
@ -3371,8 +3320,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
uint16 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
@ -3380,8 +3329,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
sint8 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
@ -3389,8 +3338,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
uint8 value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (sint64)value);
return;
}
// Do not remove this or it would be impossible to load old session
@ -3398,8 +3347,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
float value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
((CObjectNumber *) data)->set("", value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", (double)value);
return;
}
@ -3407,7 +3356,7 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{
double value;
stream.serial(value);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber(0);
data = serializer->Factory ? serializer->Factory->newBasic("Number") : new CObjectNumber((sint64)0);
((CObjectNumber *) data)->set("", value);
return;
}

@ -206,7 +206,6 @@ public:
virtual void inPlaceCopyTo(CObject &dest) const = 0;
virtual void inPlaceCopy(const CObjectString &src);
virtual void inPlaceCopy(const CObjectNumber &src);
virtual void inPlaceCopy(const CObjectInteger &src);
virtual void inPlaceCopy(const CObjectTable &src);
protected:
void copyMismatchMsg(const CObject &src);
@ -287,78 +286,51 @@ class CObjectNumber : public CObject
public:
explicit CObjectNumber(double value);
explicit CObjectNumber(sint64 value);
virtual const char *getTypeAsString() const;
virtual const char *getTypeAsString() const NL_OVERRIDE;
virtual bool set(const std::string& key, double value);
virtual bool set(const std::string& key, const std::string&value);
virtual bool set(const std::string& key, sint64 value) NL_OVERRIDE;
virtual bool set(const std::string& key, double value) NL_OVERRIDE;
virtual bool set(const std::string& key, const std::string&value) NL_OVERRIDE;
virtual bool setObject(const std::string& key, CObject* value);
virtual bool setObject(const std::string& key, CObject* value) NL_OVERRIDE;
virtual CObject* clone() const;
virtual CObject* clone() const NL_OVERRIDE;
double getValue() const { return _Value; }
double getNumberValue() const { return m_IsInteger ? m_Value.Integer : m_Value.Number; }
sint64 getIntegerValue() const { return m_IsInteger ? m_Value.Integer : m_Value.Number; }
virtual void dump(const std::string prefix = "", uint depth = 0) const;
virtual void dump(const std::string prefix = "", uint depth = 0) const NL_OVERRIDE;
virtual bool equal(const CObject* other) const;
virtual bool equal(const CObject* other) const NL_OVERRIDE;
protected:
virtual void doSerialize(std::string& out, CSerializeContext& context) const;
virtual bool doIsNumber() const;
virtual double doToNumber() const;
virtual std::string doToString() const;
virtual void inPlaceCopyTo(CObject &dest) const;
virtual void inPlaceCopy(const CObjectNumber &src);
virtual void doSerialize(std::string& out, CSerializeContext& context) const NL_OVERRIDE;
virtual void visitInternal(IObjectVisitor &visitor);
virtual bool doIsNumber() const NL_OVERRIDE;
private:
double _Value;
virtual double doToNumber() const NL_OVERRIDE;
};
virtual bool doIsInteger() const NL_OVERRIDE;
class CObjectInteger : public CObject
{
virtual sint64 doToInteger() const NL_OVERRIDE;
public:
explicit CObjectInteger(sint64 value);
virtual std::string doToString() const NL_OVERRIDE;
virtual const char *getTypeAsString() const;
virtual void inPlaceCopyTo(CObject &dest) const NL_OVERRIDE;
virtual void inPlaceCopy(const CObjectNumber &src) NL_OVERRIDE;
virtual bool set(const std::string& key, sint64 value);
virtual bool set(const std::string& key, const std::string &value);
virtual bool setObject(const std::string& key, CObject* value);
virtual CObject* clone() const;
sint64 getValue() const { return _Value; }
virtual void dump(const std::string prefix = "", uint depth = 0) const;
virtual bool equal(const CObject* other) const;
protected:
virtual void doSerialize(std::string& out, CSerializeContext& context) const;
virtual bool doIsInteger() const;
virtual sint64 doToInteger() const;
virtual std::string doToString() const;
virtual void inPlaceCopyTo(CObject &dest) const;
virtual void inPlaceCopy(const CObjectInteger &src);
virtual void visitInternal(IObjectVisitor &visitor);
virtual void visitInternal(IObjectVisitor &visitor) NL_OVERRIDE;
private:
sint64 _Value;
bool m_IsInteger;
union
{
double Number;
sint64 Integer;
} m_Value;
};
class CObjectTable: public CObject

Loading…
Cancel
Save