Merge branch 'vartype'

This commit is contained in:
Marc Zinnschlag 2013-03-05 10:59:08 +01:00
commit dc3edc6024
21 changed files with 958 additions and 313 deletions

View file

@ -9,18 +9,6 @@ namespace ESM
// Pixel color value. Standard four-byte rr,gg,bb,aa format.
typedef int32_t Color;
enum VarType
{
VT_Unknown,
VT_None,
VT_Short,
VT_Int,
VT_Long,
VT_Float,
VT_String,
VT_Ignored
};
enum Specialization
{
SPC_Combat = 0,

View file

@ -1,57 +1,24 @@
#include "loadglob.hpp"
#include "esmreader.hpp"
#include "esmwriter.hpp"
namespace ESM
{
void Global::load(ESMReader &esm)
{
std::string tmp = esm.getHNString("FNAM");
if (tmp == "s")
mType = VT_Short;
else if (tmp == "l")
mType = VT_Int;
else if (tmp == "f")
mType = VT_Float;
else
esm.fail("Illegal global variable type " + tmp);
// Note: Both floats and longs are represented as floats.
esm.getHNT(mValue, "FLTV");
}
void Global::save(ESMWriter &esm)
{
switch(mType)
void Global::load (ESMReader &esm)
{
case VT_Short:
esm.writeHNString("FNAM", "s");
break;
case VT_Int:
esm.writeHNString("FNAM", "l");
break;
case VT_Float:
esm.writeHNString("FNAM", "f");
break;
default:
return;
mValue.read (esm, ESM::Variant::Format_Global);
}
void Global::save (ESMWriter &esm)
{
mValue.write (esm, ESM::Variant::Format_Global);
}
esm.writeHNT("FLTV", mValue);
}
void Global::blank()
{
mValue = 0;
mType = VT_Float;
mValue.setType (ESM::VT_None);
}
bool operator== (const Global& left, const Global& right)
{
return left.mId==right.mId && left.mValue==right.mValue && left.mType==right.mType;
return left.mId==right.mId && left.mValue==right.mValue;
}
}

View file

@ -3,7 +3,7 @@
#include <string>
#include "defs.hpp"
#include "variant.hpp"
namespace ESM
{
@ -18,8 +18,7 @@ class ESMWriter;
struct Global
{
std::string mId;
float mValue;
VarType mType;
Variant mValue;
void load(ESMReader &esm);
void save(ESMWriter &esm);

View file

@ -1,104 +1,39 @@
#include "loadgmst.hpp"
#include <stdexcept>
#include "esmreader.hpp"
#include "esmwriter.hpp"
namespace ESM
{
void GameSetting::load(ESMReader &esm)
{
assert(mId != "");
// We are apparently allowed to be empty
if (!esm.hasMoreSubs())
void GameSetting::load (ESMReader &esm)
{
mType = VT_None;
return;
mValue.read (esm, ESM::Variant::Format_Gmst);
}
// Load some data
esm.getSubName();
NAME n = esm.retSubName();
if (n == "STRV")
void GameSetting::save (ESMWriter &esm)
{
mStr = esm.getHString();
mType = VT_String;
mValue.write (esm, ESM::Variant::Format_Gmst);
}
else if (n == "INTV")
{
esm.getHT(mI);
mType = VT_Int;
}
else if (n == "FLTV")
{
esm.getHT(mF);
mType = VT_Float;
}
else
esm.fail("Unwanted subrecord type");
}
void GameSetting::save(ESMWriter &esm)
{
switch(mType)
int GameSetting::getInt() const
{
case VT_String: esm.writeHNString("STRV", mStr); break;
case VT_Int: esm.writeHNT("INTV", mI); break;
case VT_Float: esm.writeHNT("FLTV", mF); break;
default: break;
return mValue.getInteger();
}
}
int GameSetting::getInt() const
{
switch (mType)
float GameSetting::getFloat() const
{
case VT_Float: return static_cast<int> (mF);
case VT_Int: return mI;
default: throw std::runtime_error ("GMST " + mId + " is not of a numeric type");
return mValue.getFloat();
}
}
float GameSetting::getFloat() const
{
switch (mType)
std::string GameSetting::getString() const
{
case VT_Float: return mF;
case VT_Int: return mI;
default: throw std::runtime_error ("GMST " + mId + " is not of a numeric type");
return mValue.getString();
}
}
std::string GameSetting::getString() const
{
if (mType==VT_String)
return mStr;
throw std::runtime_error ("GMST " + mId + " is not a string");
}
void GameSetting::blank()
{
mStr.clear();
mI = 0;
mF = 0;
mType = VT_Float;
mValue.setType (ESM::VT_None);
}
bool operator== (const GameSetting& left, const GameSetting& right)
{
if (left.mType!=right.mType)
return false;
switch (left.mType)
{
case VT_Float: return left.mF==right.mF;
case VT_Int: return left.mI==right.mI;
case VT_String: return left.mStr==right.mStr;
default: return false;
}
return left.mValue==right.mValue;
}
}

View file

@ -3,7 +3,7 @@
#include <string>
#include "defs.hpp"
#include "variant.hpp"
namespace ESM
{
@ -19,14 +19,13 @@ class ESMWriter;
struct GameSetting
{
std::string mId;
// One of these is used depending on the variable type
std::string mStr;
int mI;
float mF;
VarType mType;
Variant mValue;
void load(ESMReader &esm);
/// \todo remove the get* functions (redundant, since mValue as equivalent functions now).
int getInt() const;
///< Throws an exception if GMST is not of type int or float.

View file

@ -84,22 +84,8 @@ void DialInfo::load(ESMReader &esm)
SelectStruct ss;
ss.mSelectRule = esm.getHString();
esm.isEmptyOrGetName();
if (subName.val == REC_INTV)
{
ss.mType = VT_Int;
esm.getHT(ss.mI);
}
else if (subName.val == REC_FLTV)
{
ss.mType = VT_Float;
esm.getHT(ss.mF);
}
else
esm.fail(
"INFO.SCVR must precede INTV or FLTV, not "
+ subName.toString());
ss.mValue.read (esm, Variant::Format_Info);
mSelects.push_back(ss);
@ -152,16 +138,11 @@ void DialInfo::save(ESMWriter &esm)
for (std::vector<SelectStruct>::iterator it = mSelects.begin(); it != mSelects.end(); ++it)
{
esm.writeHNString("SCVR", it->mSelectRule);
switch(it->mType)
{
case VT_Int: esm.writeHNT("INTV", it->mI); break;
case VT_Float: esm.writeHNT("FLTV", it->mF); break;
default: break;
}
it->mValue.write (esm, Variant::Format_Info);
}
esm.writeHNOString("BNAM", mResultScript);
switch(mQuestStatus)
{
case QS_Name: esm.writeHNT("QSTN",'\1'); break;

View file

@ -5,6 +5,7 @@
#include <vector>
#include "defs.hpp"
#include "variant.hpp"
namespace ESM
{
@ -12,8 +13,6 @@ namespace ESM
class ESMReader;
class ESMWriter;
// NOT DONE
/*
* Dialogue information. A series of these follow after DIAL records,
* and form a linked list of dialogue items.
@ -43,9 +42,7 @@ struct DialInfo
struct SelectStruct
{
std::string mSelectRule; // This has a complicated format
float mF; // Only one of 'f' or 'i' is used
int mI;
VarType mType;
Variant mValue;
};
// Journal quest indices (introduced with the quest system in Tribunal)
@ -93,8 +90,7 @@ struct DialInfo
REC_SNAM = 0x4d414e53,
REC_NAME = 0x454d414e,
REC_SCVR = 0x52564353,
REC_INTV = 0x56544e49,
REC_FLTV = 0x56544c46,
REC_BNAM = 0x4d414e42,
REC_QSTN = 0x4e545351,
REC_QSTF = 0x46545351,
@ -106,42 +102,5 @@ struct DialInfo
void save(ESMWriter &esm);
};
/*
Some old and unused D code and comments, that might be useful later:
--------
// We only need to put each item in ONE list. For if your NPC
// matches this response, then it must match ALL criteria, thus it
// will have to look up itself in all the lists. I think the order
// is well optimized in making the lists as small as possible.
if(this.actor.index != -1) actorDial[this.actor][parent]++;
else if(cell != "") cellDial[cell][parent]++;
else if(this.Class != -1) classDial[this.Class][parent]++;
else if(this.npcFaction != -1)
factionDial[this.npcFaction][parent]++;
else if(this.race != -1) raceDial[this.race][parent]++;
else allDial[parent]++; // Lists dialogues that might
// apply to all npcs.
*/
// List of dialogue topics (and greetings, voices, etc.) that
// reference other objects. Eg. raceDial is indexed by the indices of
// all races referenced. The value of raceDial is a new AA, which is
// basically used as a map (the int value is just a count and isn't
// used for anything important.) The indices (or elements of the map)
// are the dialogues that reference the given race. I use an AA
// instead of a list or array, since each dialogue can be added lots
// of times.
/*
int allDial[Dialogue*];
int classDial[int][Dialogue*];
int factionDial[int][Dialogue*];
int actorDial[Item][Dialogue*];
// If I look up cells on cell load, I don't have to resolve these
// names into anything!
int cellDial[char[]][Dialogue*];
int raceDial[int][Dialogue*];
*/
}
#endif

282
components/esm/variant.cpp Normal file
View file

@ -0,0 +1,282 @@
#include "variant.hpp"
#include <cassert>
#include <stdexcept>
#include "esmreader.hpp"
#include "variantimp.hpp"
ESM::Variant::Variant() : mType (VT_None), mData (0) {}
ESM::Variant::~Variant()
{
delete mData;
}
ESM::Variant& ESM::Variant::operator= (const Variant& variant)
{
if (&variant!=this)
{
VariantDataBase *newData = variant.mData ? variant.mData->clone() : 0;
delete mData;
mType = variant.mType;
mData = newData;
}
return *this;
}
ESM::Variant::Variant (const Variant& variant)
: mType (variant.mType), mData (variant.mData ? variant.mData->clone() : 0)
{}
ESM::VarType ESM::Variant::getType() const
{
return mType;
}
std::string ESM::Variant::getString() const
{
if (!mData)
throw std::runtime_error ("can not convert empty variant to string");
return mData->getString();
}
int ESM::Variant::getInteger() const
{
if (!mData)
throw std::runtime_error ("can not convert empty variant to integer");
return mData->getInteger();
}
float ESM::Variant::getFloat() const
{
if (!mData)
throw std::runtime_error ("can not convert empty variant to float");
return mData->getFloat();
}
void ESM::Variant::read (ESMReader& esm, Format format)
{
// type
VarType type = VT_Unknown;
if (format==Format_Global)
{
std::string typeId = esm.getHNString ("FNAM");
if (typeId == "s")
type = VT_Short;
else if (typeId == "l")
type = VT_Long;
else if (typeId == "f")
type = VT_Float;
else
esm.fail ("illegal global variable type " + typeId);
}
else if (format==Format_Gmst)
{
if (!esm.hasMoreSubs())
{
type = VT_None;
}
else
{
esm.getSubName();
NAME name = esm.retSubName();
if (name=="STRV")
{
type = VT_String;
}
else if (name=="INTV")
{
type = VT_Int;
}
else if (name=="FLTV")
{
type = VT_Float;
}
else
esm.fail ("invalid subrecord: " + name.toString());
}
}
else // info
{
esm.getSubName();
NAME name = esm.retSubName();
if (name=="INTV")
{
type = VT_Int;
}
else if (name=="FLTV")
{
type = VT_Float;
}
else
esm.fail ("invalid subrecord: " + name.toString());
}
setType (type);
// data
if (mData)
mData->read (esm, format, mType);
}
void ESM::Variant::write (ESMWriter& esm, Format format) const
{
if (mType==VT_Unknown)
{
throw std::runtime_error ("can not serialise variant of unknown type");
}
else if (mType==VT_None)
{
if (format==Format_Global)
throw std::runtime_error ("can not serialise variant of type none to global format");
if (format==Format_Info)
throw std::runtime_error ("can not serialise variant of type none to info format");
// nothing to do here for GMST format
}
else
mData->write (esm, format, mType);
}
void ESM::Variant::write (std::ostream& stream) const
{
switch (mType)
{
case VT_Unknown:
stream << "variant unknown";
break;
case VT_None:
stream << "variant none";
break;
case VT_Short:
stream << "variant short: " << mData->getInteger();
break;
case VT_Int:
stream << "variant int: " << mData->getInteger();
break;
case VT_Long:
stream << "variant long: " << mData->getInteger();
break;
case VT_Float:
stream << "variant float: " << mData->getFloat();
break;
case VT_String:
stream << "variant string: \"" << mData->getString() << "\2";
break;
}
}
void ESM::Variant::setType (VarType type)
{
if (type!=mType)
{
VariantDataBase *newData = 0;
switch (type)
{
case VT_Unknown:
case VT_None:
break; // no data
case VT_Short:
case VT_Int:
case VT_Long:
newData = new VariantIntegerData (mData);
break;
case VT_Float:
newData = new VariantFloatData (mData);
break;
case VT_String:
newData = new VariantStringData (mData);
break;
}
delete mData;
mData = newData;
mType = type;
}
}
void ESM::Variant::setString (const std::string& value)
{
if (!mData)
throw std::runtime_error ("can not assign string to empty variant");
mData->setString (value);
}
void ESM::Variant::setInteger (int value)
{
if (!mData)
throw std::runtime_error ("can not assign integer to empty variant");
mData->setInteger (value);
}
void ESM::Variant::setFloat (float value)
{
if (!mData)
throw std::runtime_error ("can not assign float to empty variant");
mData->setFloat (value);
}
bool ESM::Variant::isEqual (const Variant& value) const
{
if (mType!=value.mType)
return false;
if (!mData)
return true;
assert (value.mData);
return mData->isEqual (*value.mData);
}
std::ostream& ESM::operator<< (std::ostream& stream, const Variant& value)
{
value.write (stream);
return stream;
}
bool ESM::operator== (const Variant& left, const Variant& right)
{
return left.isEqual (right);
}
bool ESM::operator!= (const Variant& left, const Variant& right)
{
return !(left==right);
}

View file

@ -0,0 +1,86 @@
#ifndef OPENMW_ESM_VARIANT_H
#define OPENMW_ESM_VARIANT_H
#include <string>
#include <iosfwd>
namespace ESM
{
class ESMReader;
class ESMWriter;
enum VarType
{
VT_Unknown,
VT_None,
VT_Short, // stored as a float, kinda
VT_Int,
VT_Long, // stored as a float
VT_Float,
VT_String
};
class VariantDataBase;
class Variant
{
VarType mType;
VariantDataBase *mData;
public:
enum Format
{
Format_Global,
Format_Gmst,
Format_Info
};
Variant();
~Variant();
Variant& operator= (const Variant& variant);
Variant (const Variant& variant);
VarType getType() const;
std::string getString() const;
///< Will throw an exception, if value can not be represented as a string.
int getInteger() const;
///< Will throw an exception, if value can not be represented as an integer (implicit
/// casting of float values is permitted).
float getFloat() const;
///< Will throw an exception, if value can not be represented as a float value.
void read (ESMReader& esm, Format format);
void write (ESMWriter& esm, Format format) const;
void write (std::ostream& stream) const;
///< Write in text format.
void setType (VarType type);
void setString (const std::string& value);
///< Will throw an exception, if type is not compatible with string.
void setInteger (int value);
///< Will throw an exception, if type is not compatible with integer.
void setFloat (float value);
///< Will throw an exception, if type is not compatible with float.
bool isEqual (const Variant& value) const;
};
std::ostream& operator<<(std::ostream& stream, const Variant& value);
bool operator== (const Variant& left, const Variant& right);
bool operator!= (const Variant& left, const Variant& right);
}
#endif

View file

@ -0,0 +1,280 @@
#include "variantimp.hpp"
#include <stdexcept>
#include "esmreader.hpp"
#include "esmwriter.hpp"
ESM::VariantDataBase::~VariantDataBase() {}
std::string ESM::VariantDataBase::getString (bool default_) const
{
if (default_)
return "";
throw std::runtime_error ("can not convert variant to string");
}
int ESM::VariantDataBase::getInteger (bool default_) const
{
if (default_)
return 0;
throw std::runtime_error ("can not convert variant to integer");
}
float ESM::VariantDataBase::getFloat (bool default_) const
{
if (default_)
return 0;
throw std::runtime_error ("can not convert variant to float");
}
void ESM::VariantDataBase::setString (const std::string& value)
{
throw std::runtime_error ("conversion of string to variant not possible");
}
void ESM::VariantDataBase::setInteger (int value)
{
throw std::runtime_error ("conversion of integer to variant not possible");
}
void ESM::VariantDataBase::setFloat (float value)
{
throw std::runtime_error ("conversion of float to variant not possible");
}
ESM::VariantStringData::VariantStringData (const VariantDataBase *data)
{
if (data)
mValue = data->getString (true);
}
ESM::VariantDataBase *ESM::VariantStringData::clone() const
{
return new VariantStringData (*this);
}
std::string ESM::VariantStringData::getString (bool default_) const
{
return mValue;
}
void ESM::VariantStringData::setString (const std::string& value)
{
mValue = value;
}
void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarType type)
{
if (type!=VT_String)
throw std::logic_error ("not a string type");
if (format==Variant::Format_Global)
esm.fail ("global variables of type string not supported");
if (format==Variant::Format_Info)
esm.fail ("info variables of type string not supported");
// GMST
mValue = esm.getHString();
}
void ESM::VariantStringData::write (ESMWriter& esm, Variant::Format format, VarType type) const
{
if (type!=VT_String)
throw std::logic_error ("not a string type");
if (format==Variant::Format_Global)
throw std::runtime_error ("global variables of type string not supported");
if (format==Variant::Format_Info)
throw std::runtime_error ("info variables of type string not supported");
// GMST
esm.writeHNString ("STRV", mValue);
}
bool ESM::VariantStringData::isEqual (const VariantDataBase& value) const
{
return dynamic_cast<const VariantStringData&> (value).mValue==mValue;
}
ESM::VariantIntegerData::VariantIntegerData (const VariantDataBase *data) : mValue (0)
{
if (data)
mValue = data->getInteger (true);
}
ESM::VariantDataBase *ESM::VariantIntegerData::clone() const
{
return new VariantIntegerData (*this);
}
int ESM::VariantIntegerData::getInteger (bool default_) const
{
return mValue;
}
float ESM::VariantIntegerData::getFloat (bool default_) const
{
return mValue;
}
void ESM::VariantIntegerData::setInteger (int value)
{
mValue = value;
}
void ESM::VariantIntegerData::setFloat (float value)
{
mValue = static_cast<int> (value);
}
void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarType type)
{
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
throw std::logic_error ("not an integer type");
if (format==Variant::Format_Global)
{
float value;
esm.getHNT (value, "FLTV");
if (type==VT_Short)
{
if (value!=value)
mValue = 0; // nan
else
mValue = static_cast<short> (value);
}
else if (type==VT_Long)
mValue = static_cast<int> (value);
else
esm.fail ("unsupported global variable integer type");
}
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
{
if (type!=VT_Int)
{
std::ostringstream stream;
stream
<< "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info")
<< " variable integer type";
esm.fail (stream.str());
}
esm.getHT (mValue);
}
}
void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, VarType type) const
{
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
throw std::logic_error ("not an integer type");
if (format==Variant::Format_Global)
{
if (type==VT_Short || type==VT_Long)
{
float value = mValue;
esm.writeHNString ("FNAM", type==VT_Short ? "s" : "l");
esm.writeHNT ("FLTV", value);
}
else
throw std::runtime_error ("unsupported global variable integer type");
}
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
{
if (type==VT_Int)
{
std::ostringstream stream;
stream
<< "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info")
<< " variable integer type";
throw std::runtime_error (stream.str());
}
esm.writeHNT ("INTV", mValue);
}
}
bool ESM::VariantIntegerData::isEqual (const VariantDataBase& value) const
{
return dynamic_cast<const VariantIntegerData&> (value).mValue==mValue;
}
ESM::VariantFloatData::VariantFloatData (const VariantDataBase *data) : mValue (0)
{
if (data)
mValue = data->getFloat (true);
}
ESM::VariantDataBase *ESM::VariantFloatData::clone() const
{
return new VariantFloatData (*this);
}
int ESM::VariantFloatData::getInteger (bool default_) const
{
return static_cast<int> (mValue);
}
float ESM::VariantFloatData::getFloat (bool default_) const
{
return mValue;
}
void ESM::VariantFloatData::setInteger (int value)
{
mValue = value;
}
void ESM::VariantFloatData::setFloat (float value)
{
mValue = value;
}
void ESM::VariantFloatData::read (ESMReader& esm, Variant::Format format, VarType type)
{
if (type!=VT_Float)
throw std::logic_error ("not a float type");
if (format==Variant::Format_Global)
{
esm.getHNT (mValue, "FLTV");
}
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
{
esm.getHT (mValue);
}
}
void ESM::VariantFloatData::write (ESMWriter& esm, Variant::Format format, VarType type) const
{
if (type!=VT_Float)
throw std::logic_error ("not a float type");
if (format==Variant::Format_Global)
{
esm.writeHNString ("FNAM", "f");
esm.writeHNT ("FLTV", mValue);
}
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
{
esm.writeHNT ("FLTV", mValue);
}
}
bool ESM::VariantFloatData::isEqual (const VariantDataBase& value) const
{
return dynamic_cast<const VariantFloatData&> (value).mValue==mValue;
}

View file

@ -0,0 +1,179 @@
#ifndef OPENMW_ESM_VARIANTIMP_H
#define OPENMW_ESM_VARIANTIMP_H
#include <string>
#include "variant.hpp"
namespace ESM
{
class VariantDataBase
{
public:
virtual ~VariantDataBase();
virtual VariantDataBase *clone() const = 0;
virtual std::string getString (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as a string.
///
/// \note Numeric values are not converted to strings.
///
/// \param default_ Return a default value instead of throwing an exception.
///
/// Default-implementation: throw an exception.
virtual int getInteger (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as an integer (implicit
/// casting of float values is permitted).
///
/// \param default_ Return a default value instead of throwing an exception.
///
/// Default-implementation: throw an exception.
virtual float getFloat (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as a float value.
///
/// \param default_ Return a default value instead of throwing an exception.
///
/// Default-implementation: throw an exception.
virtual void setString (const std::string& value);
///< Will throw an exception, if type is not compatible with string.
///
/// Default-implementation: throw an exception.
virtual void setInteger (int value);
///< Will throw an exception, if type is not compatible with integer.
///
/// Default-implementation: throw an exception.
virtual void setFloat (float value);
///< Will throw an exception, if type is not compatible with float.
///
/// Default-implementation: throw an exception.
virtual void read (ESMReader& esm, Variant::Format format, VarType type) = 0;
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const = 0;
///< If \a type is not supported by \a format, an exception is thrown.
virtual bool isEqual (const VariantDataBase& value) const = 0;
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
};
class VariantStringData : public VariantDataBase
{
std::string mValue;
public:
VariantStringData (const VariantDataBase *data = 0);
///< Calling the constructor with an incompatible data type will result in a silent
/// default initialisation.
virtual VariantDataBase *clone() const;
virtual std::string getString (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as a string.
///
/// \note Numeric values are not converted to strings.
///
/// \param default_ Return a default value instead of throwing an exception.
virtual void setString (const std::string& value);
///< Will throw an exception, if type is not compatible with string.
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
///< If \a type is not supported by \a format, an exception is thrown.
virtual bool isEqual (const VariantDataBase& value) const;
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
};
class VariantIntegerData : public VariantDataBase
{
int mValue;
public:
VariantIntegerData (const VariantDataBase *data = 0);
///< Calling the constructor with an incompatible data type will result in a silent
/// default initialisation.
virtual VariantDataBase *clone() const;
virtual int getInteger (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as an integer (implicit
/// casting of float values is permitted).
///
/// \param default_ Return a default value instead of throwing an exception.
virtual float getFloat (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as a float value.
///
/// \param default_ Return a default value instead of throwing an exception.
virtual void setInteger (int value);
///< Will throw an exception, if type is not compatible with integer.
virtual void setFloat (float value);
///< Will throw an exception, if type is not compatible with float.
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
///< If \a type is not supported by \a format, an exception is thrown.
virtual bool isEqual (const VariantDataBase& value) const;
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
};
class VariantFloatData : public VariantDataBase
{
float mValue;
public:
VariantFloatData (const VariantDataBase *data = 0);
///< Calling the constructor with an incompatible data type will result in a silent
/// default initialisation.
virtual VariantDataBase *clone() const;
virtual int getInteger (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as an integer (implicit
/// casting of float values is permitted).
///
/// \param default_ Return a default value instead of throwing an exception.
virtual float getFloat (bool default_ = false) const;
///< Will throw an exception, if value can not be represented as a float value.
///
/// \param default_ Return a default value instead of throwing an exception.
virtual void setInteger (int value);
///< Will throw an exception, if type is not compatible with integer.
virtual void setFloat (float value);
///< Will throw an exception, if type is not compatible with float.
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
///< If \a type is not supported by \a format, an exception is thrown.
virtual bool isEqual (const VariantDataBase& value) const;
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
};
}
#endif