Updated to Script Template V4

This commit is contained in:
parax0
2016-01-02 10:24:40 -07:00
parent 1c80970a04
commit 78400b7072
1501 changed files with 100753 additions and 115119 deletions

View File

@@ -20,6 +20,23 @@ EGame CMasterTemplate::GetGame()
return mGame;
}
u32 CMasterTemplate::NumGameVersions()
{
if (mGameVersions.empty()) return 1;
else return mGameVersions.size();
}
u32 CMasterTemplate::GetGameVersion(TString VersionName)
{
VersionName = VersionName.ToLower();
for (u32 iVer = 0; iVer < mGameVersions.size(); iVer++)
if (mGameVersions[iVer].ToLower() == VersionName)
return iVer;
return -1;
}
CScriptTemplate* CMasterTemplate::TemplateByID(u32 ObjectID)
{
auto it = mTemplates.find(ObjectID);
@@ -83,14 +100,14 @@ TString CMasterTemplate::MessageByIndex(u32 Index)
return (std::next(it, Index))->second;
}
CPropertyTemplate* CMasterTemplate::GetProperty(u32 PropertyID)
TString CMasterTemplate::PropertyName(u32 PropertyID)
{
auto it = mPropertyList.find(PropertyID);
auto it = mPropertyNames.find(PropertyID);
if (it != mPropertyList.end())
if (it != mPropertyNames.end())
return it->second;
else
return nullptr;
return "Unknown";
}
bool CMasterTemplate::HasPropertyList()

View File

@@ -2,7 +2,7 @@
#define CMASTERTEMPLATE_H
#include "CScriptTemplate.h"
#include "Core/Resource/EFormatVersion.h"
#include "Core/Resource/EGame.h"
#include <Common/types.h>
#include <map>
@@ -17,12 +17,13 @@ class CMasterTemplate
u32 mVersion;
bool mFullyLoaded;
std::vector<TString> mGameVersions;
std::map<u32, CScriptTemplate*> mTemplates;
std::map<u32, TString> mStates;
std::map<u32, TString> mMessages;
bool mHasPropList;
std::map<u32, CPropertyTemplate*> mPropertyList;
std::map<u32, TString> mPropertyNames;
static std::map<EGame, CMasterTemplate*> smMasterMap;
static u32 smGameListVersion;
@@ -31,6 +32,8 @@ public:
CMasterTemplate();
~CMasterTemplate();
EGame GetGame();
u32 NumGameVersions();
u32 GetGameVersion(TString VersionName);
u32 NumScriptTemplates();
u32 NumStates();
u32 NumMessages();
@@ -43,7 +46,7 @@ public:
TString MessageByID(u32 MessageID);
TString MessageByID(const CFourCC& MessageID);
TString MessageByIndex(u32 Index);
CPropertyTemplate* GetProperty(u32 PropertyID);
TString PropertyName(u32 PropertyID);
bool HasPropertyList();
bool IsLoadedSuccessfully();

View File

@@ -1,123 +0,0 @@
#include "CProperty.h"
// ************ CPropertyStruct ************
CPropertyStruct::~CPropertyStruct()
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
delete *it;
}
CPropertyBase* CPropertyStruct::PropertyByIndex(u32 index)
{
return mProperties[index];
}
CPropertyBase* CPropertyStruct::PropertyByID(u32 ID)
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
{
if ((*it)->ID() == ID)
return *it;
}
return nullptr;
}
CPropertyBase* CPropertyStruct::PropertyByIDString(const TIDString& str)
{
// Resolve namespace
u32 nsStart = str.IndexOf(":");
// String has namespace; the requested property is within a struct
if (nsStart != -1)
{
TString strStructID = str.Truncate(nsStart);
if (!strStructID.IsHexString()) return nullptr;
u32 structID = strStructID.ToInt32();
TString propName = str.ChopFront(nsStart + 1);
CPropertyStruct *pStruct = StructByID(structID);
if (!pStruct) return nullptr;
else return pStruct->PropertyByIDString(propName);
}
// No namespace; fetch the property from this struct
else
{
if (str.IsHexString())
return PropertyByID(str.ToInt32());
else
return nullptr;
}
}
CPropertyStruct* CPropertyStruct::StructByIndex(u32 index)
{
CPropertyBase *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByID(u32 ID)
{
CPropertyBase *pProp = PropertyByID(ID);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& str)
{
CPropertyBase *pProp = PropertyByIDString(str);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
// ************ STATIC ************
CPropertyStruct* CPropertyStruct::CopyFromTemplate(CStructTemplate *pTemp)
{
CPropertyStruct *pStruct = new CPropertyStruct();
pStruct->mpTemplate = pTemp;
pStruct->Reserve(pTemp->Count());
for (u32 iProp = 0; iProp < pTemp->Count(); iProp++)
{
CPropertyTemplate *pPropTemp = pTemp->PropertyByIndex(iProp);
CPropertyBase *pProp = nullptr;
switch (pPropTemp->Type())
{
case eBoolProperty: pProp = new CBoolProperty(false); break;
case eByteProperty: pProp = new CByteProperty(0); break;
case eShortProperty: pProp = new CShortProperty(0); break;
case eLongProperty: pProp = new CLongProperty(0); break;
case eEnumProperty: pProp = new CEnumProperty(0); break;
case eBitfieldProperty: pProp = new CBitfieldProperty(0); break;
case eFloatProperty: pProp = new CFloatProperty(0.f); break;
case eStringProperty: pProp = new CStringProperty(""); break;
case eVector3Property: pProp = new CVector3Property(CVector3f::skZero); break;
case eColorProperty: pProp = new CColorProperty(CColor::skBlack); break;
case eFileProperty: pProp = new CFileProperty(); break;
case eArrayProperty: pProp = new CArrayProperty(); break;
case eAnimParamsProperty: pProp = new CAnimParamsProperty(); break;
case eUnknownProperty: pProp = new CUnknownProperty(); break;
case eStructProperty: pProp = CPropertyStruct::CopyFromTemplate(static_cast<CStructTemplate*>(pPropTemp)); break;
}
if (pProp)
{
pProp->SetTemplate(pPropTemp);
pStruct->mProperties.push_back(pProp);
}
}
return pStruct;
}

View File

@@ -1,101 +0,0 @@
#ifndef CPROPERTY
#define CPROPERTY
/* This header file declares some classes used to track script object properties
* CPropertyBase, __CProperty (and typedefs), CPropertyStruct
* It's a bit hard to read, should be reorganized at some point */
#include "CPropertyTemplate.h"
#include "EPropertyType.h"
#include "Core/Resource/CResource.h"
#include "Core/Resource/TResPtr.h"
#include "Core/Resource/CAnimationParameters.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Math/CVector3f.h>
#include <list>
class CScriptTemplate;
typedef TString TIDString;
/*
* CPropertyBase is the base class, containing just some virtual function definitions
* Virtual destructor is mainly there to make cleanup easy; don't need to cast to delete
*/
class CPropertyBase
{
friend class CScriptLoader;
protected:
CPropertyTemplate *mpTemplate;
public:
virtual ~CPropertyBase() {}
inline virtual EPropertyType Type() = 0;
inline CPropertyTemplate *Template() { return mpTemplate; }
inline void SetTemplate(CPropertyTemplate *_tmp) { mpTemplate = _tmp; }
inline TString Name() { return mpTemplate->Name(); }
inline u32 ID() { return mpTemplate->PropertyID(); }
};
/*
* __CProperty is a template subclass for actual properties.
* Don't use this class directly. Typedefs are provided for every possible property type.
*/
template <typename t, EPropertyType type>
class __CProperty : public CPropertyBase
{
friend class CScriptLoader;
t mValue;
public:
__CProperty() {}
__CProperty(t v) { Set(v); }
~__CProperty() {}
inline EPropertyType Type() { return type; }
inline t Get() { return mValue; }
inline void Set(t v) { mValue = v; }
};
typedef __CProperty<bool, eBoolProperty> CBoolProperty;
typedef __CProperty<char, eByteProperty> CByteProperty;
typedef __CProperty<short, eShortProperty> CShortProperty;
typedef __CProperty<long, eLongProperty> CLongProperty;
typedef __CProperty<long, eEnumProperty> CEnumProperty;
typedef __CProperty<long, eBitfieldProperty> CBitfieldProperty;
typedef __CProperty<float, eFloatProperty> CFloatProperty;
typedef __CProperty<TString, eStringProperty> CStringProperty;
typedef __CProperty<CVector3f, eVector3Property> CVector3Property;
typedef __CProperty<CColor, eColorProperty> CColorProperty;
typedef __CProperty<TResPtr<CResource>, eFileProperty> CFileProperty;
typedef __CProperty<CAnimationParameters, eAnimParamsProperty> CAnimParamsProperty;
typedef __CProperty<std::vector<u8>, eArrayProperty> CArrayProperty;
typedef __CProperty<std::vector<u8>, eUnknownProperty> CUnknownProperty;
/*
* CPropertyStruct is for defining structs of properties.
*/
class CPropertyStruct : public CPropertyBase
{
friend class CScriptLoader;
std::vector<CPropertyBase*> mProperties;
public:
// Destructor simply iterates through the list and deletes them. Nothing complicated.
~CPropertyStruct();
// Inline
EPropertyType Type() { return eStructProperty; }
inline u32 Count() { return mProperties.size(); }
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
inline CPropertyBase* operator[](u32 index) { return mProperties[index]; }
// Functions
CPropertyBase* PropertyByIndex(u32 index);
CPropertyBase* PropertyByID(u32 ID);
CPropertyBase* PropertyByIDString(const TIDString& str);
CPropertyStruct* StructByIndex(u32 index);
CPropertyStruct* StructByID(u32 ID);
CPropertyStruct* StructByIDString(const TIDString& str);
// Static
static CPropertyStruct* CopyFromTemplate(CStructTemplate *pTemp);
};
#endif // CPROPERTY

View File

@@ -1,175 +0,0 @@
#include "CPropertyTemplate.h"
#include <iostream>
EPropertyType PropStringToPropEnum(const TString& prop)
{
if (prop == "bool") return eBoolProperty;
if (prop == "byte") return eByteProperty;
if (prop == "short") return eShortProperty;
if (prop == "long") return eLongProperty;
if (prop == "enum") return eEnumProperty;
if (prop == "bitfield") return eBitfieldProperty;
if (prop == "float") return eFloatProperty;
if (prop == "string") return eStringProperty;
if (prop == "color") return eColorProperty;
if (prop == "vector3f") return eVector3Property;
if (prop == "file") return eFileProperty;
if (prop == "struct") return eStructProperty;
if (prop == "array") return eArrayProperty;
if (prop == "animparams") return eAnimParamsProperty;
if (prop == "unknown") return eUnknownProperty;
return eInvalidProperty;
}
TString PropEnumToPropString(EPropertyType prop)
{
switch (prop)
{
case eBoolProperty: return "bool";
case eByteProperty: return "byte";
case eShortProperty: return "short";
case eLongProperty: return "long";
case eEnumProperty: return "enum";
case eBitfieldProperty: return "bitfield";
case eFloatProperty: return "float";
case eStringProperty: return "string";
case eColorProperty: return "color";
case eVector3Property: return "vector3f";
case eFileProperty: return "file";
case eStructProperty: return "struct";
case eArrayProperty: return "array";
case eAnimParamsProperty: return "animparams";
case eUnknownProperty: return "unknown";
case eInvalidProperty:
default:
return "invalid";
}
}
/*******************
* CStructTemplate *
*******************/
CStructTemplate::CStructTemplate() : CPropertyTemplate(-1)
{
mIsSingleProperty = false;
mPropType = eStructProperty;
}
CStructTemplate::~CStructTemplate()
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
delete *it;
}
// ************ GETTERS ************
EPropertyType CStructTemplate::Type() const
{
return eStructProperty;
}
bool CStructTemplate::IsSingleProperty() const
{
return mIsSingleProperty;
}
u32 CStructTemplate::Count() const
{
return mProperties.size();
}
CPropertyTemplate* CStructTemplate::PropertyByIndex(u32 index)
{
if (mProperties.size() > index)
return mProperties[index];
else
return nullptr;
}
CPropertyTemplate* CStructTemplate::PropertyByID(u32 ID)
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
{
if ((*it)->PropertyID() == ID)
return *it;
}
return nullptr;
}
CPropertyTemplate* CStructTemplate::PropertyByIDString(const TIDString& str)
{
// Resolve namespace
u32 nsStart = str.IndexOf(":");
u32 propStart = nsStart + 1;
// String has namespace; the requested property is within a struct
if (nsStart != -1)
{
TString strStructID = str.SubString(0, nsStart);
if (!strStructID.IsHexString()) return nullptr;
u32 structID = strStructID.ToInt32();
TString propName = str.SubString(propStart, str.Length() - propStart);
CStructTemplate *pStruct = StructByID(structID);
if (!pStruct) return nullptr;
else return pStruct->PropertyByIDString(propName);
}
// No namespace; fetch the property from this struct
else
{
// ID string lookup
if (str.IsHexString())
return PropertyByID(str.ToInt32());
else
return nullptr;
}
}
CStructTemplate* CStructTemplate::StructByIndex(u32 index)
{
CPropertyTemplate *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
CStructTemplate* CStructTemplate::StructByID(u32 ID)
{
CPropertyTemplate *pProp = PropertyByID(ID);
if (pProp && pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
CStructTemplate* CStructTemplate::StructByIDString(const TString& str)
{
CPropertyTemplate *pProp = PropertyByIDString(str);
if (pProp && pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
// ************ DEBUG ************
void CStructTemplate::DebugPrintProperties(TString base)
{
base = base + Name() + "::";
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
{
CPropertyTemplate *tmp = *it;
if (tmp->Type() == eStructProperty)
{
CStructTemplate *tmp2 = static_cast<CStructTemplate*>(tmp);
tmp2->DebugPrintProperties(base);
}
else
std::cout << base << tmp->Name() << "\n";
}
}

View File

@@ -1,219 +0,0 @@
#ifndef CPROPERTYTEMPLATE
#define CPROPERTYTEMPLATE
#include "EPropertyType.h"
#include <Common/TString.h>
#include <Common/types.h>
#include <vector>
typedef TString TIDString;
class CPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
protected:
EPropertyType mPropType;
TString mPropName;
u32 mPropID;
public:
CPropertyTemplate(u32 ID)
: mPropID(ID)
{
}
CPropertyTemplate(EPropertyType type, TString name, u32 ID)
: mPropType(type),
mPropName(name),
mPropID(ID)
{
}
virtual EPropertyType Type() const
{
return mPropType;
}
inline TString Name() const
{
return mPropName;
}
inline u32 PropertyID() const
{
return mPropID;
}
inline void SetName(const TString& Name)
{
mPropName = Name;
}
};
class CFileTemplate : public CPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
TStringList mAcceptedExtensions;
public:
CFileTemplate(u32 ID) : CPropertyTemplate(ID) { mPropType = eFileProperty; }
CFileTemplate(const TString& name, u32 ID, const TStringList& extensions)
: CPropertyTemplate(ID)
{
mPropType = eFileProperty;
mPropName = name;
mAcceptedExtensions = extensions;
}
EPropertyType Type() const
{
return eFileProperty;
}
const TStringList& Extensions() const
{
return mAcceptedExtensions;
}
};
class CEnumTemplate : public CPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SEnumerator
{
TString Name;
u32 ID;
SEnumerator(const TString& _name, u32 _ID)
: Name(_name), ID(_ID) {}
};
std::vector<SEnumerator> mEnumerators;
TString mSourceFile;
public:
CEnumTemplate(u32 ID)
: CPropertyTemplate(ID)
{
mPropType = eEnumProperty;
}
CEnumTemplate(const TString& name, u32 ID)
: CPropertyTemplate(eEnumProperty, name, ID)
{}
EPropertyType Type() const
{
return eEnumProperty;
}
u32 NumEnumerators()
{
return mEnumerators.size();
}
u32 EnumeratorIndex(u32 enumID)
{
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
{
if (mEnumerators[iEnum].ID == enumID)
return iEnum;
}
return -1;
}
u32 EnumeratorID(u32 enumIndex)
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].ID;
else return -1;
}
TString EnumeratorName(u32 enumIndex)
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].Name;
else return "INVALID ENUM INDEX";
}
};
class CBitfieldTemplate : public CPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SBitFlag
{
TString Name;
u32 Mask;
SBitFlag(const TString& _name, u32 _mask)
: Name(_name), Mask(_mask) {}
};
std::vector<SBitFlag> mBitFlags;
TString mSourceFile;
public:
CBitfieldTemplate(u32 ID)
: CPropertyTemplate(ID)
{
mPropType = eBitfieldProperty;
}
CBitfieldTemplate(const TString& name, u32 ID)
: CPropertyTemplate(eBitfieldProperty, name, ID)
{}
EPropertyType Type() const
{
return eBitfieldProperty;
}
u32 NumFlags()
{
return mBitFlags.size();
}
TString FlagName(u32 index)
{
return mBitFlags[index].Name;
}
u32 FlagMask(u32 index)
{
return mBitFlags[index].Mask;
}
};
class CStructTemplate : public CPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
bool mIsSingleProperty;
std::vector<CPropertyTemplate*> mProperties;
TString mSourceFile;
public:
CStructTemplate();
~CStructTemplate();
EPropertyType Type() const;
bool IsSingleProperty() const;
u32 Count() const;
CPropertyTemplate* PropertyByIndex(u32 index);
CPropertyTemplate* PropertyByID(u32 ID);
CPropertyTemplate* PropertyByIDString(const TIDString& str);
CStructTemplate* StructByIndex(u32 index);
CStructTemplate* StructByID(u32 ID);
CStructTemplate* StructByIDString(const TIDString& str);
void DebugPrintProperties(TString base);
};
#endif // CPROPERTYTEMPLATE

View File

@@ -3,16 +3,16 @@
#include "Core/Resource/CAnimSet.h"
CScriptObject::CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
: mpTemplate(pTemplate)
, mpArea(pArea)
, mpLayer(pLayer)
, mVersion(0)
, mpDisplayModel(nullptr)
, mpCollision(nullptr)
, mHasInGameModel(false)
{
mpTemplate = pTemplate;
mpArea = pArea;
mpLayer = pLayer;
mpProperties = nullptr;
mpTemplate->AddObject(this);
mpDisplayModel = nullptr;
mpBillboard = nullptr;
mpCollision = nullptr;
mHasInGameModel = false;
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty();
}
CScriptObject::~CScriptObject()
@@ -22,14 +22,7 @@ CScriptObject::~CScriptObject()
}
// ************ DATA MANIPULATION ************
void CScriptObject::CopyFromTemplate(CScriptTemplate *pTemp, u32 propCount)
{
CStructTemplate *pBaseStruct = pTemp->BaseStructByCount(propCount);
delete mpProperties;
mpProperties = CPropertyStruct::CopyFromTemplate(pBaseStruct);
}
void CScriptObject::EvaluateProperties()
void CScriptObject::EvaluateProperties()
{
mpInstanceName = mpTemplate->FindInstanceName(mpProperties);
mpPosition = mpTemplate->FindPosition(mpProperties);
@@ -61,12 +54,12 @@ void CScriptObject::EvaluateCollisionModel()
}
// ************ GETTERS ************
CPropertyBase* CScriptObject::PropertyByIndex(u32 index) const
IProperty* CScriptObject::PropertyByIndex(u32 index) const
{
return mpProperties->PropertyByIndex(index);
}
CPropertyBase* CScriptObject::PropertyByIDString(const TString& str) const
IProperty* CScriptObject::PropertyByIDString(const TString& str) const
{
return mpProperties->PropertyByIDString(str);
}
@@ -91,6 +84,11 @@ CScriptLayer* CScriptObject::Layer() const
return mpLayer;
}
u32 CScriptObject::Version() const
{
return mVersion;
}
CPropertyStruct* CScriptObject::Properties() const
{
return mpProperties;

View File

@@ -2,8 +2,8 @@
#define CSCRIPTOBJECT_H
#include "SConnection.h"
#include "CProperty.h"
#include "CPropertyTemplate.h"
#include "IProperty.h"
#include "IPropertyTemplate.h"
#include "CScriptTemplate.h"
#include "Core/Resource/Model/CModel.h"
#include "Core/Resource/CCollisionMeshGroup.h"
@@ -19,17 +19,18 @@ class CScriptObject
CScriptTemplate *mpTemplate;
TResPtr<CGameArea> mpArea;
CScriptLayer *mpLayer;
u32 mVersion;
u32 mInstanceID;
std::vector<SLink> mOutConnections;
std::vector<SLink> mInConnections;
CPropertyStruct *mpProperties;
CStringProperty *mpInstanceName;
CVector3Property *mpPosition;
CVector3Property *mpRotation;
CVector3Property *mpScale;
CBoolProperty *mpActive;
TStringProperty *mpInstanceName;
TVector3Property *mpPosition;
TVector3Property *mpRotation;
TVector3Property *mpScale;
TBoolProperty *mpActive;
CPropertyStruct *mpLightParameters;
TResPtr<CModel> mpDisplayModel;
TResPtr<CTexture> mpBillboard;
@@ -43,7 +44,6 @@ public:
CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
~CScriptObject();
void CopyFromTemplate(CScriptTemplate *pTemp, u32 propCount);
void EvaluateProperties();
void EvaluateDisplayModel();
void EvaluateBillboard();
@@ -53,10 +53,11 @@ public:
CMasterTemplate* MasterTemplate() const;
CGameArea* Area() const;
CScriptLayer* Layer() const;
u32 Version() const;
CPropertyStruct* Properties() const;
u32 NumProperties() const;
CPropertyBase* PropertyByIndex(u32 index) const;
CPropertyBase* PropertyByIDString(const TIDString& str) const;
IProperty* PropertyByIndex(u32 index) const;
IProperty* PropertyByIDString(const TIDString& str) const;
u32 ObjectTypeID() const;
u32 InstanceID() const;
u32 NumInLinks() const;

View File

@@ -9,18 +9,18 @@
#include <string>
CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
: mpMaster(pMaster)
, mpBaseStruct(nullptr)
, mVisible(true)
, mPreviewScale(1.f)
, mVolumeShape(eNoShape)
, mVolumeScale(1.f)
{
mpMaster = pMaster;
mVisible = true;
mPreviewScale = 1.f;
mVolumeScale = 1.f;
mVolumeShape = eNoShape;
}
CScriptTemplate::~CScriptTemplate()
{
for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++)
delete mPropertySets[iSet].pBaseStruct;
delete mpBaseStruct;
}
CMasterTemplate* CScriptTemplate::MasterTemplate()
@@ -33,41 +33,9 @@ EGame CScriptTemplate::Game()
return mpMaster->GetGame();
}
TString CScriptTemplate::TemplateName(s32 propCount) const
TString CScriptTemplate::TemplateName() const
{
// Return original name if there is only one property set
// or if caller doesn't want to distinguish between sets
if ((NumPropertySets() == 1) || (propCount == -1))
return mTemplateName;
// Otherwise we return the template name with the set name appended
for (auto it = mPropertySets.begin(); it != mPropertySets.end(); it++)
if (it->pBaseStruct->Count() == propCount)
return mTemplateName + " (" + it->SetName + ")";
return mTemplateName + " (Invalid)";
}
TString CScriptTemplate::PropertySetNameByCount(s32 propCount) const
{
for (auto it = mPropertySets.begin(); it != mPropertySets.end(); it++)
if (it->pBaseStruct->Count() == propCount)
return it->SetName;
return "";
}
TString CScriptTemplate::PropertySetNameByIndex(u32 index) const
{
if (index < NumPropertySets())
return mPropertySets[index].SetName;
else
return "";
}
u32 CScriptTemplate::NumPropertySets() const
{
return mPropertySets.size();
return mTemplateName;
}
CScriptTemplate::ERotationType CScriptTemplate::RotationType() const
@@ -100,10 +68,9 @@ bool CScriptTemplate::IsVisible() const
return mVisible;
}
void CScriptTemplate::DebugPrintProperties(int propCount)
void CScriptTemplate::DebugPrintProperties()
{
CStructTemplate *pTemp = BaseStructByCount(propCount);
if (pTemp) pTemp->DebugPrintProperties("");
mpBaseStruct->DebugPrintProperties("");
}
// ************ PROPERTY FETCHING ************
@@ -111,7 +78,7 @@ template<typename t, EPropertyType propType>
t TFetchProperty(CPropertyStruct *pProperties, const TIDString& ID)
{
if (ID.IsEmpty()) return nullptr;
CPropertyBase *pProp = pProperties->PropertyByIDString(ID);
IProperty *pProp = pProperties->PropertyByIDString(ID);
if (pProp && (pProp->Type() == propType))
return static_cast<t>(pProp);
@@ -119,23 +86,9 @@ t TFetchProperty(CPropertyStruct *pProperties, const TIDString& ID)
return nullptr;
}
CStructTemplate* CScriptTemplate::BaseStructByCount(s32 propCount)
CStructTemplate* CScriptTemplate::BaseStruct()
{
if (mPropertySets.size() == 1) return mPropertySets[0].pBaseStruct;
for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++)
if (mPropertySets[iSet].pBaseStruct->Count() == propCount)
return mPropertySets[iSet].pBaseStruct;
return nullptr;
}
CStructTemplate* CScriptTemplate::BaseStructByIndex(u32 index)
{
if (index < NumPropertySets())
return mPropertySets[index].pBaseStruct;
else
return nullptr;
return mpBaseStruct;
}
EVolumeShape CScriptTemplate::VolumeShape(CScriptObject *pObj)
@@ -177,32 +130,32 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
// Private function
if (mVolumeShape == eConditionalShape)
{
CPropertyBase *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString);
IProperty *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString);
// Get value of the condition test property (only boolean, integral, and enum types supported)
int v;
switch (pProp->Type())
{
case eBoolProperty:
v = (static_cast<CBoolProperty*>(pProp)->Get() ? 1 : 0);
v = (static_cast<TBoolProperty*>(pProp)->Get() ? 1 : 0);
break;
case eByteProperty:
v = (int) static_cast<CByteProperty*>(pProp)->Get();
v = (int) static_cast<TByteProperty*>(pProp)->Get();
break;
case eShortProperty:
v = (int) static_cast<CShortProperty*>(pProp)->Get();
v = (int) static_cast<TShortProperty*>(pProp)->Get();
break;
case eLongProperty:
v = (int) static_cast<CLongProperty*>(pProp)->Get();
v = (int) static_cast<TLongProperty*>(pProp)->Get();
break;
case eEnumProperty: {
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(pProp);
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(pProp);
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pEnumCast->Template());
int index = static_cast<CEnumProperty*>(pProp)->Get();
int index = static_cast<TEnumProperty*>(pProp)->Get();
v = pEnumTemp->EnumeratorID(index);
break;
}
@@ -222,29 +175,29 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
return -1;
}
CStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties)
TStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties)
{
return TFetchProperty<CStringProperty*, eStringProperty>(pProperties, mNameIDString);
return TFetchProperty<TStringProperty*, eStringProperty>(pProperties, mNameIDString);
}
CVector3Property* CScriptTemplate::FindPosition(CPropertyStruct *pProperties)
TVector3Property* CScriptTemplate::FindPosition(CPropertyStruct *pProperties)
{
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mPositionIDString);
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mPositionIDString);
}
CVector3Property* CScriptTemplate::FindRotation(CPropertyStruct *pProperties)
TVector3Property* CScriptTemplate::FindRotation(CPropertyStruct *pProperties)
{
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mRotationIDString);
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mRotationIDString);
}
CVector3Property* CScriptTemplate::FindScale(CPropertyStruct *pProperties)
TVector3Property* CScriptTemplate::FindScale(CPropertyStruct *pProperties)
{
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mScaleIDString);
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mScaleIDString);
}
CBoolProperty* CScriptTemplate::FindActive(CPropertyStruct *pProperties)
TBoolProperty* CScriptTemplate::FindActive(CPropertyStruct *pProperties)
{
return TFetchProperty<CBoolProperty*, eBoolProperty>(pProperties, mActiveIDString);
return TFetchProperty<TBoolProperty*, eBoolProperty>(pProperties, mActiveIDString);
}
CPropertyStruct* CScriptTemplate::FindLightParameters(CPropertyStruct *pProperties)
@@ -270,17 +223,17 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
// Property
else
{
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
if (pProp->Type() == eFileProperty)
{
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
pRes = pFile->Get();
}
else if (pProp->Type() == eAnimParamsProperty)
else if (pProp->Type() == eCharacterProperty)
{
CAnimParamsProperty *pParams = static_cast<CAnimParamsProperty*>(pProp);
TAnimParamsProperty *pParams = static_cast<TAnimParamsProperty*>(pProp);
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
}
}
@@ -310,11 +263,11 @@ CTexture* CScriptTemplate::FindBillboardTexture(CPropertyStruct *pProperties)
// Property
else
{
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
if (pProp->Type() == eFileProperty)
{
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
pRes = pFile->Get();
}
}
@@ -344,11 +297,11 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties
// Property
else
{
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
if (pProp->Type() == eFileProperty)
{
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
pRes = pFile->Get();
}
}
@@ -369,17 +322,17 @@ bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties)
if (it->AssetSource == SEditorAsset::eFile) continue;
CResource *pRes = nullptr;
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
if (pProp->Type() == eFileProperty)
{
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
pRes = pFile->Get();
}
else if (pProp->Type() == eAnimParamsProperty)
else if (pProp->Type() == eCharacterProperty)
{
CAnimParamsProperty *pParams = static_cast<CAnimParamsProperty*>(pProp);
TAnimParamsProperty *pParams = static_cast<TAnimParamsProperty*>(pProp);
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
}

View File

@@ -1,8 +1,8 @@
#ifndef CSCRIPTTEMPLATE_H
#define CSCRIPTTEMPLATE_H
#include "CPropertyTemplate.h"
#include "CProperty.h"
#include "IPropertyTemplate.h"
#include "IProperty.h"
#include "EPropertyType.h"
#include "EVolumeShape.h"
#include "Core/Resource/Model/CModel.h"
@@ -39,11 +39,6 @@ public:
};
private:
struct SPropertySet {
TString SetName;
CStructTemplate *pBaseStruct;
};
struct SEditorAsset
{
enum {
@@ -59,7 +54,7 @@ private:
};
CMasterTemplate *mpMaster;
std::vector<SPropertySet> mPropertySets;
CStructTemplate *mpBaseStruct;
std::list<CScriptObject*> mObjectList;
TString mTemplateName;
TString mSourceFile;
@@ -75,9 +70,9 @@ private:
TIDString mLightParametersIDString;
std::vector<SEditorAsset> mAssets;
float mPreviewScale;
ERotationType mRotationType;
EScaleType mScaleType;
float mPreviewScale;
// Preview Volume
EVolumeShape mVolumeShape;
@@ -97,9 +92,7 @@ public:
CMasterTemplate* MasterTemplate();
EGame Game();
TString TemplateName(s32 propCount = -1) const;
TString PropertySetNameByCount(s32 propCount) const;
TString PropertySetNameByIndex(u32 index) const;
TString TemplateName() const;
u32 NumPropertySets() const;
ERotationType RotationType() const;
EScaleType ScaleType() const;
@@ -107,18 +100,17 @@ public:
u32 ObjectID() const;
void SetVisible(bool visible);
bool IsVisible() const;
void DebugPrintProperties(int propCount = -1);
void DebugPrintProperties();
// Property Fetching
CStructTemplate* BaseStructByCount(s32 propCount);
CStructTemplate* BaseStructByIndex(u32 index);
CStructTemplate* BaseStruct();
EVolumeShape VolumeShape(CScriptObject *pObj);
float VolumeScale(CScriptObject *pObj);
CStringProperty* FindInstanceName(CPropertyStruct *pProperties);
CVector3Property* FindPosition(CPropertyStruct *pProperties);
CVector3Property* FindRotation(CPropertyStruct *pProperties);
CVector3Property* FindScale(CPropertyStruct *pProperties);
CBoolProperty* FindActive(CPropertyStruct *pProperties);
TStringProperty* FindInstanceName(CPropertyStruct *pProperties);
TVector3Property* FindPosition(CPropertyStruct *pProperties);
TVector3Property* FindRotation(CPropertyStruct *pProperties);
TVector3Property* FindScale(CPropertyStruct *pProperties);
TBoolProperty* FindActive(CPropertyStruct *pProperties);
CPropertyStruct* FindLightParameters(CPropertyStruct *pProperties);
CModel* FindDisplayModel(CPropertyStruct *pProperties);
CTexture* FindBillboardTexture(CPropertyStruct *pProperties);

View File

@@ -18,7 +18,7 @@ enum EPropertyType
eFileProperty,
eStructProperty,
eArrayProperty,
eAnimParamsProperty,
eCharacterProperty,
eUnknownProperty,
eInvalidProperty
};

View File

@@ -0,0 +1,126 @@
#include "IProperty.h"
#include "IPropertyTemplate.h"
// ************ IProperty ************
IPropertyTemplate* IProperty::Template()
{
return mpTemplate;
}
TString IProperty::Name()
{
return mpTemplate->Name();
}
u32 IProperty::ID()
{
return mpTemplate->PropertyID();
}
// ************ CPropertyStruct ************
CPropertyStruct::~CPropertyStruct()
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
delete *it;
}
IProperty* CPropertyStruct::PropertyByIndex(u32 index)
{
return mProperties[index];
}
IProperty* CPropertyStruct::PropertyByID(u32 ID)
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
{
if ((*it)->ID() == ID)
return *it;
}
return nullptr;
}
IProperty* CPropertyStruct::PropertyByIDString(const TIDString& rkStr)
{
// Resolve namespace
u32 NSStart = rkStr.IndexOf(":");
// String has namespace; the requested property is within a struct
if (NSStart != -1)
{
TString StrStructID = rkStr.Truncate(NSStart);
if (!StrStructID.IsHexString()) return nullptr;
u32 StructID = StrStructID.ToInt32();
TString PropName = rkStr.ChopFront(NSStart + 1);
CPropertyStruct *pStruct = StructByID(StructID);
if (!pStruct) return nullptr;
else return pStruct->PropertyByIDString(PropName);
}
// No namespace; fetch the property from this struct
else
{
if (rkStr.IsHexString())
return PropertyByID(rkStr.ToInt32());
else
return nullptr;
}
}
CPropertyStruct* CPropertyStruct::StructByIndex(u32 index)
{
IProperty *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByID(u32 ID)
{
IProperty *pProp = PropertyByID(ID);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr)
{
IProperty *pProp = PropertyByIDString(rkStr);
if (pProp->Type() == eStructProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
// ************ CArrayProperty ************
void CArrayProperty::Resize(u32 Size)
{
u32 OldSize = mSubStructs.size();
if (OldSize == Size) return;
if (Size < OldSize)
{
for (u32 i = mSubStructs.size() - 1; i >= Size; i--)
delete mSubStructs[i];
}
mSubStructs.resize(Size);
if (Size > OldSize)
{
for (u32 i = OldSize; i < Size; i++)
mSubStructs[i] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct();
}
}
CStructTemplate* CArrayProperty::SubStructTemplate()
{
// CArrayTemplate inherits from CStructTemplate. It defines the substruct structure.
return static_cast<CStructTemplate*>(Template());
}

View File

@@ -0,0 +1,129 @@
#ifndef IPROPERTY
#define IPROPERTY
/* This header file declares some classes used to track script object properties
* IProperty, TTypedProperty (and typedefs), CPropertyStruct, and CArrayProperty */
#include "EPropertyType.h"
#include "IPropertyValue.h"
#include "Core/Resource/CResource.h"
#include "Core/Resource/TResPtr.h"
#include "Core/Resource/CAnimationParameters.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Math/CVector3f.h>
#include <list>
class CScriptTemplate;
class CStructTemplate;
class IPropertyTemplate;
typedef TString TIDString;
/*
* IProperty is the base class, containing just some virtual function definitions
* Virtual destructor is mainly there to make cleanup easy; don't need to cast to delete
*/
class IProperty
{
friend class CScriptLoader;
protected:
IPropertyTemplate *mpTemplate;
public:
IProperty(IPropertyTemplate *pTemp) : mpTemplate(pTemp) {}
virtual ~IProperty() {}
virtual EPropertyType Type() = 0;
IPropertyTemplate* Template();
TString Name();
u32 ID();
};
/*
* __CProperty is a template subclass for actual properties.
*/
template <typename PropType, EPropertyType TypeEnum, class ValueClass>
class TTypedProperty : public IProperty
{
friend class CScriptLoader;
ValueClass mValue;
public:
TTypedProperty(IPropertyTemplate *pTemp)
: IProperty(pTemp) {}
TTypedProperty(IPropertyTemplate *pTemp, PropType v)
: IProperty(pTemp), mValue(v) {}
~TTypedProperty() {}
inline EPropertyType Type() { return TypeEnum; }
inline PropType Get() { return mValue.Get(); }
inline void Set(PropType v) { mValue.Set(v); }
};
typedef TTypedProperty<bool, eBoolProperty, CBoolValue> TBoolProperty;
typedef TTypedProperty<char, eByteProperty, CByteValue> TByteProperty;
typedef TTypedProperty<short, eShortProperty, CShortValue> TShortProperty;
typedef TTypedProperty<long, eLongProperty, CLongValue> TLongProperty;
typedef TTypedProperty<long, eEnumProperty, CLongValue> TEnumProperty;
typedef TTypedProperty<long, eBitfieldProperty, CLongValue> TBitfieldProperty;
typedef TTypedProperty<float, eFloatProperty, CFloatValue> TFloatProperty;
typedef TTypedProperty<TString, eStringProperty, CStringValue> TStringProperty;
typedef TTypedProperty<CVector3f, eVector3Property, CVector3Value> TVector3Property;
typedef TTypedProperty<CColor, eColorProperty, CColorValue> TColorProperty;
typedef TTypedProperty<TResPtr<CResource>, eFileProperty, CFileValue> TFileProperty;
typedef TTypedProperty<CAnimationParameters, eCharacterProperty, CCharacterValue> TAnimParamsProperty;
typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue> TUnknownProperty;
/*
* CPropertyStruct is for defining structs of properties.
*/
class CPropertyStruct : public IProperty
{
friend class CScriptLoader;
std::vector<IProperty*> mProperties;
public:
CPropertyStruct(IPropertyTemplate *pTemp)
: IProperty(pTemp) {}
~CPropertyStruct();
EPropertyType Type() { return eStructProperty; }
// Inline
inline u32 Count() { return mProperties.size(); }
inline void AddSubProperty(IProperty *pProp) { mProperties.push_back(pProp); }
inline IProperty* operator[](u32 index) { return mProperties[index]; }
// Functions
IProperty* PropertyByIndex(u32 index);
IProperty* PropertyByID(u32 ID);
IProperty* PropertyByIDString(const TIDString& rkStr);
CPropertyStruct* StructByIndex(u32 index);
CPropertyStruct* StructByID(u32 ID);
CPropertyStruct* StructByIDString(const TIDString& rkStr);
};
/*
* CArrayProperty stores a repeated property struct.
*/
class CArrayProperty : public IProperty
{
friend class CScriptLoader;
std::vector<CPropertyStruct*> mSubStructs;
public:
CArrayProperty(IPropertyTemplate *pTemp)
: IProperty(pTemp) {}
EPropertyType Type() { return eArrayProperty; }
// Inline
inline u32 Count() { return mSubStructs.size(); }
inline void Reserve(u32 amount) { mSubStructs.reserve(amount); }
inline CPropertyStruct* ElementByIndex(u32 index) { return mSubStructs[index]; }
inline CPropertyStruct* operator[](u32 index) { return ElementByIndex(index); }
// Functions
void Resize(u32 Size);
CStructTemplate* SubStructTemplate();
};
#endif // IPROPERTY

View File

@@ -0,0 +1,224 @@
#include "IPropertyTemplate.h"
#include <iostream>
// ************ IPropertyTemplate ************
bool IPropertyTemplate::IsInVersion(u32 Version) const
{
if (mAllowedVersions.empty())
return true;
for (u32 iVer = 0; iVer < mAllowedVersions.size(); iVer++)
if (mAllowedVersions[iVer] == Version)
return true;
return false;
}
TIDString IPropertyTemplate::IDString(bool FullPath) const
{
TIDString out;
if (mpParent && FullPath) out = mpParent->IDString(true) + ":";
out += TIDString::HexString(mID, true, true, 8);
return out;
}
CStructTemplate* IPropertyTemplate::RootStruct()
{
if (mpParent) return mpParent->RootStruct();
else if (Type() == eStructProperty) return static_cast<CStructTemplate*>(this);
else return nullptr;
}
// ************ CStructTemplate ************
bool CStructTemplate::IsSingleProperty() const
{
return mIsSingleProperty;
}
u32 CStructTemplate::Count() const
{
return mSubProperties.size();
}
u32 CStructTemplate::NumVersions()
{
return mVersionPropertyCounts.size();
}
u32 CStructTemplate::PropertyCountForVersion(u32 Version)
{
if (Version == -1) Version = 0;
return mVersionPropertyCounts[Version];
}
u32 CStructTemplate::VersionForPropertyCount(u32 PropCount)
{
for (u32 iVer = 0; iVer < NumVersions(); iVer++)
if (mVersionPropertyCounts[iVer] == PropCount)
return iVer;
return -1;
}
IPropertyTemplate* CStructTemplate::PropertyByIndex(u32 index)
{
if (mSubProperties.size() > index)
return mSubProperties[index];
else
return nullptr;
}
IPropertyTemplate* CStructTemplate::PropertyByID(u32 ID)
{
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
{
if ((*it)->PropertyID() == ID)
return *it;
}
return nullptr;
}
IPropertyTemplate* CStructTemplate::PropertyByIDString(const TIDString& str)
{
// Resolve namespace
u32 nsStart = str.IndexOf(":");
u32 propStart = nsStart + 1;
// String has namespace; the requested property is within a struct
if (nsStart != -1)
{
TString strStructID = str.SubString(0, nsStart);
if (!strStructID.IsHexString()) return nullptr;
u32 structID = strStructID.ToInt32();
TString propName = str.SubString(propStart, str.Length() - propStart);
CStructTemplate *pStruct = StructByID(structID);
if (!pStruct) return nullptr;
else return pStruct->PropertyByIDString(propName);
}
// No namespace; fetch the property from this struct
else
{
// ID string lookup
if (str.IsHexString())
return PropertyByID(str.ToInt32());
else
return nullptr;
}
}
CStructTemplate* CStructTemplate::StructByIndex(u32 index)
{
IPropertyTemplate *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
CStructTemplate* CStructTemplate::StructByID(u32 ID)
{
IPropertyTemplate *pProp = PropertyByID(ID);
if (pProp && pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
CStructTemplate* CStructTemplate::StructByIDString(const TString& str)
{
IPropertyTemplate *pProp = PropertyByIDString(str);
if (pProp && pProp->Type() == eStructProperty)
return static_cast<CStructTemplate*>(pProp);
else
return nullptr;
}
bool CStructTemplate::HasProperty(const TIDString& rkIdString)
{
IPropertyTemplate *pProperty = PropertyByIDString(rkIdString);
return (pProperty != nullptr);
}
void CStructTemplate::DetermineVersionPropertyCounts()
{
for (u32 iVer = 0; iVer < mVersionPropertyCounts.size(); iVer++)
{
mVersionPropertyCounts[iVer] = 0;
for (u32 iProp = 0; iProp < mSubProperties.size(); iProp++)
{
if (mSubProperties[iProp]->IsInVersion(iVer) && mSubProperties[iProp]->CookPreference() != eNeverCook)
mVersionPropertyCounts[iVer]++;
}
}
}
// ************ GLOBAL FUNCTIONS ************
TString PropEnumToPropString(EPropertyType prop)
{
switch (prop)
{
case eBoolProperty: return "bool";
case eByteProperty: return "byte";
case eShortProperty: return "short";
case eLongProperty: return "long";
case eEnumProperty: return "enum";
case eBitfieldProperty: return "bitfield";
case eFloatProperty: return "float";
case eStringProperty: return "string";
case eColorProperty: return "color";
case eVector3Property: return "vector3f";
case eFileProperty: return "file";
case eStructProperty: return "struct";
case eArrayProperty: return "array";
case eCharacterProperty: return "character";
case eUnknownProperty: return "unknown";
case eInvalidProperty:
default:
return "invalid";
}
}
EPropertyType PropStringToPropEnum(const TString& rkProp)
{
if (rkProp == "bool") return eBoolProperty;
if (rkProp == "byte") return eByteProperty;
if (rkProp == "short") return eShortProperty;
if (rkProp == "long") return eLongProperty;
if (rkProp == "enum") return eEnumProperty;
if (rkProp == "bitfield") return eBitfieldProperty;
if (rkProp == "float") return eFloatProperty;
if (rkProp == "string") return eStringProperty;
if (rkProp == "color") return eColorProperty;
if (rkProp == "vector3f") return eVector3Property;
if (rkProp == "file") return eFileProperty;
if (rkProp == "struct") return eStructProperty;
if (rkProp == "array") return eArrayProperty;
if (rkProp == "character") return eCharacterProperty;
if (rkProp == "unknown") return eUnknownProperty;
return eInvalidProperty;
}
// ************ DEBUG ************
void CStructTemplate::DebugPrintProperties(TString base)
{
base = base + Name() + "::";
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
{
IPropertyTemplate *tmp = *it;
if (tmp->Type() == eStructProperty)
{
CStructTemplate *tmp2 = static_cast<CStructTemplate*>(tmp);
tmp2->DebugPrintProperties(base);
}
else
std::cout << base << tmp->Name() << "\n";
}
}

View File

@@ -0,0 +1,517 @@
#ifndef IPROPERTYTEMPLATE
#define IPROPERTYTEMPLATE
#include "EPropertyType.h"
#include "IProperty.h"
#include "IPropertyValue.h"
#include "Core/Resource/CAnimationParameters.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Common/types.h>
#include <Math/CVector3f.h>
#include <vector>
typedef TString TIDString;
class CStructTemplate;
class IProperty;
enum ECookPreference
{
eNoCookPreference,
eAlwaysCook,
eNeverCook
};
// IPropertyTemplate - Base class. Contains basic info that every property has,
// plus virtual functions for determining more specific property type.
class IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
protected:
CStructTemplate *mpParent;
TString mName;
u32 mID;
ECookPreference mCookPreference;
std::vector<u32> mAllowedVersions;
public:
IPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
: mID(ID)
, mpParent(pParent)
, mName("Unknown")
, mCookPreference(eNoCookPreference)
{
}
IPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: mID(ID)
, mpParent(pParent)
, mName(rkName)
, mCookPreference(CookPreference)
{
}
virtual EPropertyType Type() const = 0;
virtual bool CanHaveDefault() const = 0;
virtual bool IsNumerical() const = 0;
virtual bool HasValidRange() const { return false; }
virtual TString DefaultToString() { return ""; }
virtual TString RangeToString() { return ""; }
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
if (rkParamName == "should_cook")
{
if (rkValue == "always")
mCookPreference = eAlwaysCook;
else if (rkValue == "never")
mCookPreference = eNeverCook;
else
mCookPreference = eNoCookPreference;
}
}
virtual IProperty* InstantiateProperty() = 0;
inline TString Name() const
{
return mName;
}
inline u32 PropertyID() const
{
return mID;
}
inline ECookPreference CookPreference() const
{
return mCookPreference;
}
inline void SetName(const TString& Name)
{
mName = Name;
}
inline CStructTemplate* Parent() const
{
return mpParent;
}
bool IsInVersion(u32 Version) const;
TIDString IDString(bool FullPath) const;
CStructTemplate* RootStruct();
};
// TTypedPropertyTemplate - Template property class that allows for tracking
// a default value. Typedefs are set up for a bunch of property types.
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
class TTypedPropertyTemplate : public IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
protected:
ValueClass mDefaultValue;
public:
TTypedPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pParent) {}
TTypedPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pParent) {}
virtual EPropertyType Type() const { return PropTypeEnum; }
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual TString DefaultToString()
{
return mDefaultValue.ToString();
}
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
IPropertyTemplate::SetParam(rkParamName, rkValue);
if (rkParamName == "default")
mDefaultValue.FromString(rkValue);
}
virtual IProperty* InstantiateProperty()
{
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
TPropertyType *pOut = new TPropertyType(this);
pOut->Set(GetDefaultValue());
return pOut;
}
inline PropType GetDefaultValue() const
{
return mDefaultValue.Get();
}
inline void SetDefaultValue(const PropType& rkIn)
{
mDefaultValue.Set(rkIn);
}
};
// TNumericalPropertyTemplate - Subclass of TTypedPropertyTemplate for numerical
// property types, and allows a min/max value to be tracked.
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
class TNumericalPropertyTemplate : public TTypedPropertyTemplate<PropType,PropTypeEnum,ValueClass>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
ValueClass mMin;
ValueClass mMax;
public:
TNumericalPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pParent)
{}
TNumericalPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pParent)
, mMin(0)
, mMax(0)
{}
virtual bool IsNumerical() const { return true; }
virtual bool HasValidRange() const
{
return (mMin != 0 || mMax != 0);
}
virtual TString RangeToString() const
{
return mMin.ToString() + "," + mMax.ToString();
}
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
TTypedPropertyTemplate<PropType,PropTypeEnum,ValueClass>::SetParam(rkParamName, rkValue);
if (rkParamName == "range")
{
TStringList Components = rkValue.Split(", ");
if (Components.size() == 2)
{
mMin.FromString(Components.front());
mMax.FromString(Components.back());
}
}
}
inline PropType GetMin()
{
return mMin.Get();
}
inline PropType GetMax()
{
return mMax.Get();
}
inline void SetRange(const PropType& rkMin, const PropType& rkMax)
{
mMin.Set(rkMin);
mMax.Set(rkMax);
}
};
// Typedefs for all property types that don't need further functionality.
typedef TTypedPropertyTemplate<bool, eBoolProperty, CBoolValue> TBoolTemplate;
typedef TNumericalPropertyTemplate<s8, eByteProperty, CByteValue> TByteTemplate;
typedef TNumericalPropertyTemplate<s16, eShortProperty, CShortValue> TShortTemplate;
typedef TNumericalPropertyTemplate<s32, eLongProperty, CLongValue> TLongTemplate;
typedef TNumericalPropertyTemplate<float, eFloatProperty, CFloatValue> TFloatTemplate;
typedef TTypedPropertyTemplate<TString, eStringProperty, CStringValue> TStringTemplate;
typedef TTypedPropertyTemplate<CVector3f, eVector3Property, CVector3Value> TVector3Template;
typedef TTypedPropertyTemplate<CColor, eColorProperty, CColorValue> TColorTemplate;
// CFileTemplate - Property template for files. Tracks a list of file types that
// the property is allowed to accept.
class CFileTemplate : public IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
TStringList mAcceptedExtensions;
public:
CFileTemplate(u32 ID, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pParent) {}
CFileTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pParent) {}
virtual EPropertyType Type() const { return eFileProperty; }
virtual bool CanHaveDefault() const { return false; }
virtual bool IsNumerical() const { return false; }
IProperty* InstantiateProperty()
{
return new TFileProperty(this);
}
void SetAllowedExtensions(const TStringList& rkExtensions)
{
mAcceptedExtensions = rkExtensions;
}
const TStringList& Extensions() const
{
return mAcceptedExtensions;
}
};
// CCharacterTemplate - Typed property that doesn't allow default values.
class CCharacterTemplate : public TTypedPropertyTemplate<CAnimationParameters,
eCharacterProperty,
CCharacterValue>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
CCharacterTemplate(u32 ID, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pParent) { }
CCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pParent) { }
virtual bool CanHaveDefault() const
{
return false;
}
};
// CEnumTemplate - Property template for enums. Tracks a list of possible values (enumerators).
class CEnumTemplate : public TLongTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SEnumerator
{
TString Name;
u32 ID;
SEnumerator(const TString& rkName, u32 _ID)
: Name(rkName), ID(_ID) {}
};
std::vector<SEnumerator> mEnumerators;
TString mSourceFile;
public:
CEnumTemplate(u32 ID, CStructTemplate *pParent = 0)
: TLongTemplate(ID, pParent)
{
mDefaultValue.SetHexStringOutput(true);
}
CEnumTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: TLongTemplate(ID, rkName, CookPreference, pParent)
{
mDefaultValue.SetHexStringOutput(true);
}
virtual EPropertyType Type() const { return eEnumProperty; }
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty()
{
TEnumProperty *pEnum = new TEnumProperty(this);
u32 Index = EnumeratorIndex(GetDefaultValue());
pEnum->Set(Index);
return pEnum;
}
u32 NumEnumerators()
{
return mEnumerators.size();
}
u32 EnumeratorIndex(u32 enumID)
{
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
{
if (mEnumerators[iEnum].ID == enumID)
return iEnum;
}
return -1;
}
u32 EnumeratorID(u32 enumIndex)
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].ID;
else return -1;
}
TString EnumeratorName(u32 enumIndex)
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].Name;
else return "INVALID ENUM INDEX";
}
};
// CBitfieldTemplate - Property template for bitfields, which can have multiple
// distinct boolean parameters packed into one property.
class CBitfieldTemplate : public TLongTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SBitFlag
{
TString Name;
u32 Mask;
SBitFlag(const TString& _name, u32 _mask)
: Name(_name), Mask(_mask) {}
};
std::vector<SBitFlag> mBitFlags;
TString mSourceFile;
public:
CBitfieldTemplate(u32 ID, CStructTemplate *pParent = 0)
: TLongTemplate(ID, pParent) {}
CBitfieldTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: TLongTemplate(ID, rkName, CookPreference, pParent) {}
virtual EPropertyType Type() const { return eBitfieldProperty; }
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty()
{
TBitfieldProperty *pBitfield = new TBitfieldProperty(this);
pBitfield->Set(GetDefaultValue());
return pBitfield;
}
u32 NumFlags()
{
return mBitFlags.size();
}
TString FlagName(u32 index)
{
return mBitFlags[index].Name;
}
u32 FlagMask(u32 index)
{
return mBitFlags[index].Mask;
}
};
// CStructTemplate - Defines structs composed of multiple sub-properties.
class CStructTemplate : public IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
protected:
std::vector<IPropertyTemplate*> mSubProperties;
std::vector<u32> mVersionPropertyCounts;
bool mIsSingleProperty;
TString mSourceFile;
void DetermineVersionPropertyCounts();
public:
CStructTemplate(u32 ID, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pParent)
, mIsSingleProperty(false) {}
CStructTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pParent)
, mIsSingleProperty(false) {}
~CStructTemplate()
{
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
delete *it;
}
EPropertyType Type() const { return eStructProperty; }
bool CanHaveDefault() const { return false; }
bool IsNumerical() const { return false; }
IProperty* InstantiateProperty()
{
CPropertyStruct *pStruct = new CPropertyStruct(this);
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
{
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty();
pStruct->AddSubProperty(pSubProp);
}
return pStruct;
}
bool IsSingleProperty() const;
u32 Count() const;
u32 NumVersions();
u32 PropertyCountForVersion(u32 Version);
u32 VersionForPropertyCount(u32 PropCount);
IPropertyTemplate* PropertyByIndex(u32 index);
IPropertyTemplate* PropertyByID(u32 ID);
IPropertyTemplate* PropertyByIDString(const TIDString& str);
CStructTemplate* StructByIndex(u32 index);
CStructTemplate* StructByID(u32 ID);
CStructTemplate* StructByIDString(const TIDString& str);
bool HasProperty(const TIDString& rkIdString);
void DebugPrintProperties(TString base);
};
// CArrayTemplate - Defines a repeating struct composed of multiple sub-properties.
// Similar to CStructTemplate, but with new implementations of Type() and InstantiateProperty().
class CArrayTemplate : public CStructTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
CArrayTemplate(u32 ID, CStructTemplate *pParent = 0)
: CStructTemplate(ID, pParent)
{
mIsSingleProperty = true;
}
CArrayTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
: CStructTemplate(ID, rkName, CookPreference, pParent)
{
mIsSingleProperty = true;
}
EPropertyType Type() const { return eArrayProperty; }
IProperty* InstantiateProperty()
{
return new CArrayProperty(this);
}
CPropertyStruct* CreateSubStruct()
{
return (CPropertyStruct*) CStructTemplate::InstantiateProperty();
}
};
#endif // IPROPERTYTEMPLATE

View File

@@ -0,0 +1,275 @@
#ifndef IPROPERTYVALUE_H
#define IPROPERTYVALUE_H
#include "EPropertyType.h"
#include "Core/Log.h"
#include "Core/Resource/CAnimationParameters.h"
#include "Core/Resource/CResource.h"
#include "Core/Resource/TResPtr.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Math/CVector3f.h>
class IPropertyValue
{
public:
virtual TString ToString() const = 0;
virtual void FromString(const TString& rkString) = 0;
};
template<typename PropType>
class TTypedPropertyValue : public IPropertyValue
{
protected:
PropType mValue;
public:
TTypedPropertyValue() {}
TTypedPropertyValue(PropType Val)
: mValue(Val) {}
PropType Get() const
{
return mValue;
}
void Set(const PropType& rkIn)
{
mValue = rkIn;
}
bool operator==(const TTypedPropertyValue& rkOther) const
{
return (mValue == rkOther.mValue);
}
bool operator==(const PropType& rkOther) const { return (mValue == rkOther); }
bool operator!=(const PropType& rkOther) const { return (mValue != rkOther); }
bool operator< (const PropType& rkOther) const { return (mValue < rkOther); }
bool operator<=(const PropType& rkOther) const { return (mValue <= rkOther); }
bool operator> (const PropType& rkOther) const { return (mValue > rkOther); }
bool operator>=(const PropType& rkOther) const { return (mValue >= rkOther); }
};
class CBoolValue : public TTypedPropertyValue<bool>
{
public:
CBoolValue() { mValue = false; }
CBoolValue(bool Val) { mValue = Val; }
TString ToString() const
{
return (!mValue ? "false" : "true");
}
void FromString(const TString& rkString)
{
mValue = (rkString == "true");
}
};
class CByteValue : public TTypedPropertyValue<s8>
{
public:
CByteValue() { mValue = 0; }
CByteValue(s8 Val) { mValue = Val; }
TString ToString() const
{
return TString::FromInt32(mValue, 0, 10);
}
void FromString(const TString& rkString)
{
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
mValue = (s8) rkString.ToInt32(base);
}
};
class CShortValue : public TTypedPropertyValue<s16>
{
public:
CShortValue() { mValue = 0; }
CShortValue(s16 Val) { mValue = Val; }
TString ToString() const
{
return TString::FromInt32((s32) mValue, 0, 10);
}
void FromString(const TString& rkString)
{
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
mValue = (s16) rkString.ToInt32(base);
}
};
class CLongValue : public TTypedPropertyValue<s32>
{
protected:
bool mShouldOutputHex;
public:
CLongValue() { mShouldOutputHex = false; mValue = 0; }
CLongValue(s32 Val) { mShouldOutputHex = false; mValue = Val; }
void SetHexStringOutput(bool enable)
{
mShouldOutputHex = enable;
}
TString ToString() const
{
if (mShouldOutputHex)
return TString::HexString((u32) mValue, true, true, 8);
else
return TString::FromInt32(mValue, 0, 10);
}
void FromString(const TString& rkString)
{
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
mValue = (s32) rkString.ToInt32(base);
}
};
class CFloatValue : public TTypedPropertyValue<float>
{
public:
CFloatValue() { mValue = 0.0f; }
CFloatValue(float Val) { mValue = Val; }
TString ToString() const
{
return TString::FromFloat(mValue);
}
void FromString(const TString& rkString)
{
mValue = rkString.ToFloat();
}
};
class CStringValue : public TTypedPropertyValue<TString>
{
public:
CStringValue() {}
CStringValue(const TString& rkVal) { mValue = rkVal; }
// These functions are extremely complicated, but try to follow along
TString ToString() const
{
return mValue;
}
void FromString(const TString& rkString)
{
mValue = rkString;
}
};
class CColorValue : public TTypedPropertyValue<CColor>
{
public:
CColorValue() {}
CColorValue(const CColor& rkVal) { mValue = rkVal; }
TString ToString() const
{
TString out;
out += TString::FromFloat(mValue.r) + ", ";
out += TString::FromFloat(mValue.g) + ", ";
out += TString::FromFloat(mValue.b) + ", ";
out += TString::FromFloat(mValue.a);
return out;
}
void FromString(const TString& rkString)
{
TStringList Components = rkString.Split(", ");
if (Components.size() < 3 || Components.size() > 4)
{
Log::Error("CColorValue::FromString was passed a string with an invalid number of components");
mValue = CColor::skTransparentBlack;
return;
}
float *pPtr = &mValue.r;
mValue.a = 1.0f;
for (auto it = Components.begin(); it != Components.end(); it++)
{
*pPtr = it->ToFloat();
pPtr++;
}
}
};
class CVector3Value : public TTypedPropertyValue<CVector3f>
{
public:
CVector3Value() {}
CVector3Value(const CVector3f& rkVal) { mValue = rkVal; }
TString ToString() const
{
TString out;
out += TString::FromFloat(mValue.x) + ", ";
out += TString::FromFloat(mValue.y) + ", ";
out += TString::FromFloat(mValue.z);
return out;
}
void FromString(const TString& rkString)
{
TStringList Components = rkString.Split(", ");
if (Components.size() != 3)
{
Log::Error("CVector3Value::FromString was passed a string with an invalid number of components");
mValue = CVector3f::skInfinite;
return;
}
float *pPtr = &mValue.x;
for (auto it = Components.begin(); it != Components.end(); it++)
{
*pPtr = it->ToFloat();
pPtr++;
}
}
};
class CCharacterValue : public TTypedPropertyValue<CAnimationParameters>
{
public:
CCharacterValue() {}
TString ToString() const { return ""; }
void FromString(const TString&) { }
};
class CFileValue : public TTypedPropertyValue<TResPtr<CResource>>
{
public:
CFileValue() {}
CFileValue(CResource *pRes) { mValue = pRes; }
TString ToString() const { return ""; }
void FromString(const TString&) { }
};
class CUnknownValue : public TTypedPropertyValue<std::vector<u8>>
{
public:
CUnknownValue();
TString ToString() const { return ""; }
void FromString(const TString&) {}
};
#endif // IPROPERTYVALUE_H