added UniversalId class
parent
019146756f
commit
4c0dcd46a1
@ -0,0 +1,161 @@
|
||||
|
||||
#include "universalid.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct TypeData
|
||||
{
|
||||
CSMWorld::UniversalId::Class mClass;
|
||||
CSMWorld::UniversalId::Type mType;
|
||||
const char *mName;
|
||||
};
|
||||
|
||||
static const TypeData sNoArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
||||
static const TypeData sIdArg[] =
|
||||
{
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
||||
static const TypeData sIndexArg[] =
|
||||
{
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::UniversalId (Type type) : mArgumentType (ArgumentType_None), mType (type), mIndex (0)
|
||||
{
|
||||
for (int i=0; sNoArg[i].mName; ++i)
|
||||
if (type==sNoArg[i].mType)
|
||||
{
|
||||
mClass = sNoArg[i].mClass;
|
||||
return;
|
||||
}
|
||||
|
||||
throw std::logic_error ("invalid argument-less UniversalId type");
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::UniversalId (Type type, const std::string& id)
|
||||
: mArgumentType (ArgumentType_Id), mType (type), mId (id), mIndex (0)
|
||||
{
|
||||
for (int i=0; sIdArg[i].mName; ++i)
|
||||
if (type==sIdArg[i].mType)
|
||||
{
|
||||
mClass = sIdArg[i].mClass;
|
||||
return;
|
||||
}
|
||||
|
||||
throw std::logic_error ("invalid ID argument UniversalId type");
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::UniversalId (Type type, int index)
|
||||
: mArgumentType (ArgumentType_Index), mType (type), mIndex (index)
|
||||
{
|
||||
for (int i=0; sIndexArg[i].mName; ++i)
|
||||
if (type==sIndexArg[i].mType)
|
||||
{
|
||||
mClass = sIndexArg[i].mClass;
|
||||
return;
|
||||
}
|
||||
|
||||
throw std::logic_error ("invalid index argument UniversalId type");
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::Class CSMWorld::UniversalId::getClass() const
|
||||
{
|
||||
return mClass;
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::ArgumentType CSMWorld::UniversalId::getArgumentType() const
|
||||
{
|
||||
return mArgumentType;
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
const std::string& CSMWorld::UniversalId::getId() const
|
||||
{
|
||||
if (mArgumentType!=ArgumentType_Id)
|
||||
throw std::logic_error ("invalid access to ID of non-ID UniversalId");
|
||||
|
||||
return mId;
|
||||
}
|
||||
|
||||
int CSMWorld::UniversalId::getIndex() const
|
||||
{
|
||||
if (mArgumentType!=ArgumentType_Index)
|
||||
throw std::logic_error ("invalid access to index of non-index UniversalId");
|
||||
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
bool CSMWorld::UniversalId::isEqual (const UniversalId& universalId) const
|
||||
{
|
||||
if (mClass!=universalId.mClass || mArgumentType!=universalId.mArgumentType || mType!=universalId.mType)
|
||||
return false;
|
||||
|
||||
switch (mArgumentType)
|
||||
{
|
||||
case ArgumentType_Id: return mId==universalId.mId;
|
||||
case ArgumentType_Index: return mIndex==universalId.mIndex;
|
||||
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CSMWorld::UniversalId::getTypeName() const
|
||||
{
|
||||
const TypeData *typeData = mArgumentType==ArgumentType_None ? sNoArg :
|
||||
(mArgumentType==ArgumentType_Id ? sIdArg : sIndexArg);
|
||||
|
||||
for (int i=0; typeData[i].mName; ++i)
|
||||
if (typeData[i].mType==mType)
|
||||
return typeData[i].mName;
|
||||
|
||||
throw std::logic_error ("failed to retrieve UniversalId type name");
|
||||
}
|
||||
|
||||
std::string CSMWorld::UniversalId::toString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << getTypeName();
|
||||
|
||||
switch (mArgumentType)
|
||||
{
|
||||
case ArgumentType_None: break;
|
||||
case ArgumentType_Id: stream << " " << mId;
|
||||
case ArgumentType_Index: stream << " " << mIndex;
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
|
||||
{
|
||||
return left.isEqual (right);
|
||||
}
|
||||
|
||||
bool operator!= (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
|
||||
{
|
||||
return !left.isEqual (right);
|
||||
}
|
||||
|
||||
std::ostream& operator< (std::ostream& stream, const CSMWorld::UniversalId& universalId)
|
||||
{
|
||||
return stream << universalId.toString();
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
#ifndef CSM_WOLRD_UNIVERSALID_H
|
||||
#define CSM_WOLRD_UNIVERSALID_H
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class UniversalId
|
||||
{
|
||||
public:
|
||||
|
||||
enum Class
|
||||
{
|
||||
Class_None = 0,
|
||||
Class_Record,
|
||||
Class_SubRecord,
|
||||
Class_RecordList,
|
||||
Class_Collection, // multiple types of records combined
|
||||
Class_Transient, // not part of the world data or the project data
|
||||
Class_NonRecord // record like data that is not part of the world
|
||||
};
|
||||
|
||||
enum ArgumentType
|
||||
{
|
||||
ArgumentType_None,
|
||||
ArgumentType_Id,
|
||||
ArgumentType_Index
|
||||
};
|
||||
|
||||
enum Type
|
||||
{
|
||||
Type_None
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Class mClass;
|
||||
ArgumentType mArgumentType;
|
||||
Type mType;
|
||||
std::string mId;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
UniversalId (Type type = Type_None);
|
||||
///< Using a type for a non-argument-less UniversalId will throw an exception.
|
||||
|
||||
UniversalId (Type type, const std::string& id);
|
||||
///< Using a type for a non-ID-argument UniversalId will throw an exception.
|
||||
|
||||
UniversalId (Type type, int index);
|
||||
///< Using a type for a non-index-argument UniversalId will throw an exception.
|
||||
|
||||
Class getClass() const;
|
||||
|
||||
ArgumentType getArgumentType() const;
|
||||
|
||||
Type getType() const;
|
||||
|
||||
const std::string& getId() const;
|
||||
///< Calling this function for a non-ID type will throw an exception.
|
||||
|
||||
int getIndex() const;
|
||||
///< Calling this function for a non-index type will throw an exception.
|
||||
|
||||
bool isEqual (const UniversalId& universalId) const;
|
||||
|
||||
std::string getTypeName() const;
|
||||
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
bool operator== (const UniversalId& left, const UniversalId& right);
|
||||
bool operator!= (const UniversalId& left, const UniversalId& right);
|
||||
|
||||
std::ostream& operator< (std::ostream& stream, const UniversalId& universalId);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue