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); sint64 value = lua_tointeger(state, -1);
lua_pop(state, 1); lua_pop(state, 1);
return new CObjectInteger(value); return new CObjectNumber(value);
} }
else else
#endif #endif

@ -175,12 +175,6 @@ void CObject::inPlaceCopy(const CObjectNumber &src)
copyMismatchMsg(src); copyMismatchMsg(src);
} }
void CObject::inPlaceCopy(const CObjectInteger &src)
{
//H_AUTO(R2_CObject_inPlaceCopy)
copyMismatchMsg(src);
}
void CObject::inPlaceCopy(const CObjectTable &src) void CObject::inPlaceCopy(const CObjectTable &src)
{ {
//H_AUTO(R2_CObject_inPlaceCopy) //H_AUTO(R2_CObject_inPlaceCopy)
@ -764,7 +758,15 @@ void CObjectRefId::doSerialize(std::string& out, CSerializeContext& /* context
//----------------------- CObjectNumber ---------------------------------------- //----------------------- 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 const char *CObjectNumber::getTypeAsString() const
{ {
@ -787,19 +789,28 @@ void CObjectNumber::inPlaceCopyTo(CObject &dest) const
void CObjectNumber::inPlaceCopy(const CObjectNumber &src) void CObjectNumber::inPlaceCopy(const CObjectNumber &src)
{ {
//H_AUTO(R2_CObjectNumber_inPlaceCopy) //H_AUTO(R2_CObjectNumber_inPlaceCopy)
_Value = src._Value; m_IsInteger = src.m_IsInteger;
m_Value.Integer = src.m_Value.Integer;
setGhost(src.getGhost()); 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 void CObjectNumber::doSerialize(std::string& out, CSerializeContext& /* context */) const
{ {
//H_AUTO(R2_CObjectNumber_doSerialize) //H_AUTO(R2_CObjectNumber_doSerialize)
nlassert(!getGhost()); nlassert(!getGhost());
if (m_IsInteger)
{
out += NLMISC::toString(m_Value.Integer);
}
else
{
//out.precision(15); //out.precision(15);
std::string value = NLMISC::toString(double(sint64(_Value * 1000.0 + (_Value>=0.0?0.5:-0.5)))/1000.0); 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 // search for first not 0 value from the end
std::string::size_type pos = value.find_last_not_of('0'); std::string::size_type pos = value.find_last_not_of('0');
if (pos != std::string::npos) if (pos != std::string::npos)
@ -809,163 +820,106 @@ void CObjectNumber::doSerialize(std::string& out, CSerializeContext& /* context
value.erase(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) //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); 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; 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) bool CObjectNumber::set(const std::string& key, const std::string & value)
{ {
//H_AUTO(R2_CObjectNumber_set) //H_AUTO(R2_CObjectNumber_set)
//XXX //XXX
BOMB_IF(!key.empty(), "Try to set an element of a table on an object that is not a table", return false); 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); double num;
return true; 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 CObject* CObjectNumber::clone() const
{ {
//H_AUTO(R2_CObjectNumber_clone) //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()); result->setGhost(getGhost());
return result; 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) bool CObjectNumber::setObject(const std::string& /* key */, CObject* value)
{ {
//H_AUTO(R2_CObjectNumber_setObject) //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()); setGhost(value->getGhost());
return true; return true;
} }
bool CObjectNumber::equal(const CObject* other) const bool CObjectNumber::equal(const CObject* other) const
{ {
//H_AUTO(R2_CObjectNumber_equal) if (!other) return false;
if (!other || !other->isNumber()) 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(); 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 // 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 ---------------------------------------- //----------------------- CObjectTable ----------------------------------------
@ -1686,7 +1640,7 @@ CObject* CObjectFactory::newBasic(const std::string & type)
} }
else if (type == "Number") else if (type == "Number")
{ {
return new CObjectNumber(0); return new CObjectNumber((sint64)0);
} }
else if (type == "Table") else if (type == "Table")
{ {
@ -1976,15 +1930,10 @@ void CObjectNumber::dump(const std::string prefix, uint depth) const
{ {
//H_AUTO(R2_CObjectNumber_dump) //H_AUTO(R2_CObjectNumber_dump)
std::string result(depth * 4, ' '); std::string result(depth * 4, ' ');
result += NLMISC::toString("%sNumber, ptr = 0x%p, value = %lf, ghost = %s", prefix.c_str(), this, _Value, _Ghost ? "true" : "false"); if (m_IsInteger)
nlwarning(result.c_str()); 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");
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");
nlwarning(result.c_str()); nlwarning(result.c_str());
} }
@ -3330,13 +3279,13 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
double value; double value;
stream.serial(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); ((CObjectNumber *) data)->set("", value);
return; return;
} }
case ObjectNumberZero: 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); ((CObjectNumber *) data)->set("", 0.0);
return; return;
} }
@ -3344,8 +3293,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
sint32 value; sint32 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
@ -3353,8 +3302,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
uint32 value; uint32 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
@ -3362,8 +3311,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
sint16 value; sint16 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
@ -3371,8 +3320,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
uint16 value; uint16 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
@ -3380,8 +3329,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
sint8 value; sint8 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
@ -3389,8 +3338,8 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
uint8 value; uint8 value;
stream.serial(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); ((CObjectNumber *) data)->set("", (sint64)value);
return; return;
} }
// Do not remove this or it would be impossible to load old session // 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; float value;
stream.serial(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); ((CObjectNumber *) data)->set("", (double)value);
return; return;
} }
@ -3407,7 +3356,7 @@ void CObjectSerializerImpl::serialImpl(NLMISC::IStream& stream, CObject*& data,
{ {
double value; double value;
stream.serial(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); ((CObjectNumber *) data)->set("", value);
return; return;
} }

@ -206,7 +206,6 @@ public:
virtual void inPlaceCopyTo(CObject &dest) const = 0; virtual void inPlaceCopyTo(CObject &dest) const = 0;
virtual void inPlaceCopy(const CObjectString &src); virtual void inPlaceCopy(const CObjectString &src);
virtual void inPlaceCopy(const CObjectNumber &src); virtual void inPlaceCopy(const CObjectNumber &src);
virtual void inPlaceCopy(const CObjectInteger &src);
virtual void inPlaceCopy(const CObjectTable &src); virtual void inPlaceCopy(const CObjectTable &src);
protected: protected:
void copyMismatchMsg(const CObject &src); void copyMismatchMsg(const CObject &src);
@ -287,78 +286,51 @@ class CObjectNumber : public CObject
public: public:
explicit CObjectNumber(double value); 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, sint64 value) NL_OVERRIDE;
virtual bool set(const std::string& key, const std::string&value); 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: protected:
virtual void doSerialize(std::string& out, CSerializeContext& context) const; virtual void doSerialize(std::string& out, CSerializeContext& context) const NL_OVERRIDE;
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 visitInternal(IObjectVisitor &visitor); virtual bool doIsNumber() const NL_OVERRIDE;
private: virtual double doToNumber() const NL_OVERRIDE;
double _Value;
}; virtual bool doIsInteger() const NL_OVERRIDE;
class CObjectInteger : public CObject virtual sint64 doToInteger() const NL_OVERRIDE;
{
public: virtual std::string doToString() const NL_OVERRIDE;
explicit CObjectInteger(sint64 value);
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 void visitInternal(IObjectVisitor &visitor) NL_OVERRIDE;
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);
private: private:
sint64 _Value; bool m_IsInteger;
union
{
double Number;
sint64 Integer;
} m_Value;
}; };
class CObjectTable: public CObject class CObjectTable: public CObject

Loading…
Cancel
Save