Property cleanup

This commit is contained in:
Aruki
2018-09-22 13:36:50 -06:00
parent e68b961a8c
commit 31dac74a64
97 changed files with 287 additions and 3319 deletions

View File

@@ -150,7 +150,7 @@ SMessage CMasterTemplate::MessageByIndex(u32 Index)
return SMessage(Iter->first, Iter->second);
}
IPropertyNew* CMasterTemplate::FindPropertyArchetype(const TString& kTypeName)
IProperty* CMasterTemplate::FindPropertyArchetype(const TString& kTypeName)
{
auto Iter = mPropertyTemplates.find(kTypeName);
@@ -232,7 +232,7 @@ TString CMasterTemplate::PropertyName(u32 PropertyID)
}
// Removing these functions for now. I'm not sure of the best way to go about implementing them under the new system yet.
u32 CMasterTemplate::CreatePropertyID(IPropertyNew* pProp)
u32 CMasterTemplate::CreatePropertyID(IProperty* pProp)
{
// MP1 properties don't have IDs so we can use this function to create one to track instances of a particular property.
// To ensure the IDs are unique we'll create a hash using two things: the struct source file and the ID string (relative to the struct).
@@ -250,7 +250,7 @@ u32 CMasterTemplate::CreatePropertyID(IPropertyNew* pProp)
return Hash.Digest();
}
void CMasterTemplate::AddProperty(IPropertyNew* pProp, const TString& rkTemplateName /*= ""*/)
void CMasterTemplate::AddProperty(IProperty* pProp, const TString& rkTemplateName /*= ""*/)
{
u32 ID;
@@ -261,11 +261,11 @@ void CMasterTemplate::AddProperty(IPropertyNew* pProp, const TString& rkTemplate
else
{
// For MP1 we only really need to track properties that come from struct templates.
IPropertyNew* pArchetype = pProp->Archetype();
IProperty* pArchetype = pProp->Archetype();
if (!pArchetype ||
pArchetype->ScriptTemplate() != nullptr ||
pArchetype->RootParent()->Type() != EPropertyTypeNew::Struct)
pArchetype->RootParent()->Type() != EPropertyType::Struct)
return;
ID = CreatePropertyID(pProp);
@@ -307,7 +307,7 @@ void CMasterTemplate::AddProperty(IPropertyNew* pProp, const TString& rkTemplate
}
}
void CMasterTemplate::RenameProperty(IPropertyNew* pProp, const TString& rkNewName)
void CMasterTemplate::RenameProperty(IProperty* pProp, const TString& rkNewName)
{
u32 ID = pProp->ID();
if (ID <= 0xFF) ID = CreatePropertyID(pProp);
@@ -352,7 +352,7 @@ void CMasterTemplate::XMLsUsingID(u32 ID, std::vector<TString>& rOutList)
}
}
const std::vector<IPropertyNew*>* CMasterTemplate::TemplatesWithMatchingID(IPropertyNew* pProp)
const std::vector<IProperty*>* CMasterTemplate::TemplatesWithMatchingID(IProperty* pProp)
{
u32 ID = pProp->ID();
if (ID <= 0xFF) ID = CreatePropertyID(pProp);

View File

@@ -84,15 +84,15 @@ class CMasterTemplate
TString Path;
/** Template in memory */
std::shared_ptr<IPropertyNew> pTemplate;
std::shared_ptr<IProperty> pTemplate;
/** Constructor */
SPropertyTemplatePath()
{}
SPropertyTemplatePath(const TString& kInPath, IPropertyNew* pInTemplate)
SPropertyTemplatePath(const TString& kInPath, IProperty* pInTemplate)
: Path(kInPath)
, pTemplate( std::shared_ptr<IPropertyNew>(pInTemplate) )
, pTemplate( std::shared_ptr<IProperty>(pInTemplate) )
{}
/** Serializer */
@@ -117,7 +117,7 @@ class CMasterTemplate
struct SPropIDInfo
{
std::vector<TString> XMLList; // List of script/struct templates that use this ID
std::vector<IPropertyNew*> PropertyList; // List of all properties that use this ID
std::vector<IProperty*> PropertyList; // List of all properties that use this ID
};
static std::map<u32, SPropIDInfo> smIDMap;
static std::map<EGame, CMasterTemplate*> smMasterMap;
@@ -142,7 +142,7 @@ public:
SMessage MessageByID(u32 MessageID);
SMessage MessageByID(const CFourCC& MessageID);
SMessage MessageByIndex(u32 Index);
IPropertyNew* FindPropertyArchetype(const TString& kTypeName);
IProperty* FindPropertyArchetype(const TString& kTypeName);
TString GetGameDirectory(bool Absolute = false) const;
// Inline Accessors
@@ -159,12 +159,12 @@ public:
static TString FindGameName(EGame Game);
static EGame FindGameForName(const TString& rkName);
static TString PropertyName(u32 PropertyID);
static u32 CreatePropertyID(IPropertyNew *pTemp);
static void AddProperty(IPropertyNew *pTemp, const TString& rkTemplateName = "");
static void RenameProperty(IPropertyNew *pTemp, const TString& rkNewName);
static u32 CreatePropertyID(IProperty *pTemp);
static void AddProperty(IProperty *pTemp, const TString& rkTemplateName = "");
static void RenameProperty(IProperty *pTemp, const TString& rkNewName);
static void RenameProperty(u32 ID, const TString& rkNewName);
static void XMLsUsingID(u32 ID, std::vector<TString>& rOutList);
static const std::vector<IPropertyNew*>* TemplatesWithMatchingID(IPropertyNew *pTemp);
static const std::vector<IProperty*>* TemplatesWithMatchingID(IProperty *pTemp);
};
#endif // CMASTERTEMPLATE_H

View File

@@ -15,7 +15,7 @@ CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLa
mpTemplate->AddObject(this);
// Init properties
CStructPropertyNew* pProperties = pTemplate->Properties();
CStructProperty* pProperties = pTemplate->Properties();
u32 PropertiesSize = pProperties->DataSize();
mPropertyData.resize( PropertiesSize );
@@ -82,7 +82,7 @@ void CScriptObject::EvaluateVolume()
mVolumeScale = mpTemplate->VolumeScale(this);
}
bool CScriptObject::IsEditorProperty(IPropertyNew *pProp)
bool CScriptObject::IsEditorProperty(IProperty *pProp)
{
return ( (pProp == mInstanceName.Property()) ||
(pProp == mPosition.Property()) ||

View File

@@ -59,7 +59,7 @@ public:
void EvaluateDisplayAsset();
void EvaluateCollisionModel();
void EvaluateVolume();
bool IsEditorProperty(IPropertyNew *pProp);
bool IsEditorProperty(IProperty *pProp);
void SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex = -1);
u32 LayerIndex() const;
bool HasNearVisibleActivation() const;

View File

@@ -86,7 +86,7 @@ void CScriptTemplate::PostLoad()
if (!mRotationIDString.IsEmpty()) mpRotationProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mRotationIDString) );
if (!mScaleIDString.IsEmpty()) mpScaleProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mScaleIDString) );
if (!mActiveIDString.IsEmpty()) mpActiveProperty = TPropCast<CBoolProperty>( mpProperties->ChildByIDString(mActiveIDString) );
if (!mLightParametersIDString.IsEmpty()) mpLightParametersProperty = TPropCast<CStructPropertyNew>( mpProperties->ChildByIDString(mLightParametersIDString) );
if (!mLightParametersIDString.IsEmpty()) mpLightParametersProperty = TPropCast<CStructProperty>( mpProperties->ChildByIDString(mLightParametersIDString) );
}
EGame CScriptTemplate::Game() const
@@ -96,10 +96,10 @@ EGame CScriptTemplate::Game() const
// ************ PROPERTY FETCHING ************
template<class PropType>
PropType* TFetchProperty(CStructPropertyNew* pProperties, const TIDString& rkID)
PropType* TFetchProperty(CStructProperty* pProperties, const TIDString& rkID)
{
if (rkID.IsEmpty()) return nullptr;
IPropertyNew *pProp = pProperties->ChildByIDString(rkID);
IProperty *pProp = pProperties->ChildByIDString(rkID);
if (pProp && (pProp->Type() == PropEnum))
return static_cast<PropType*>(pProp)->ValuePtr();
@@ -147,7 +147,7 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
if (mVolumeShape == eConditionalShape)
{
TIDString PropID = mVolumeConditionIDString;
IPropertyNew* pProp = pObj->Template()->Properties()->ChildByIDString( PropID );
IProperty* pProp = pObj->Template()->Properties()->ChildByIDString( PropID );
// Get value of the condition test property (only boolean, integral, and enum types supported)
void* pData = pObj->PropertyData();
@@ -155,24 +155,24 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
switch (pProp->Type())
{
case EPropertyTypeNew::Bool:
case EPropertyType::Bool:
Val = TPropCast<CBoolProperty>(pProp)->Value(pData) ? 1 : 0;
break;
case EPropertyTypeNew::Byte:
case EPropertyType::Byte:
Val = (int) TPropCast<CByteProperty>(pProp)->Value(pData);
break;
case EPropertyTypeNew::Short:
case EPropertyType::Short:
Val = (int) TPropCast<CShortProperty>(pProp)->Value(pData);
break;
case EPropertyTypeNew::Int:
case EPropertyType::Int:
Val = TPropCast<CIntProperty>(pProp)->Value(pData);
break;
case EPropertyTypeNew::Enum:
case EPropertyTypeNew::Choice:
case EPropertyType::Enum:
case EPropertyType::Choice:
Val = TPropCast<CEnumProperty>(pProp)->Value(pData);
break;
}
@@ -209,9 +209,9 @@ CResource* CScriptTemplate::FindDisplayAsset(void* pPropertyData, u32& rOutCharI
// Property
else
{
IPropertyNew* pProp = mpProperties->ChildByIDString(it->AssetLocation);
IProperty* pProp = mpProperties->ChildByIDString(it->AssetLocation);
if (it->AssetType == SEditorAsset::eAnimParams && pProp->Type() == EPropertyTypeNew::AnimationSet)
if (it->AssetType == SEditorAsset::eAnimParams && pProp->Type() == EPropertyType::AnimationSet)
{
CAnimationSetProperty* pAnimSet = TPropCast<CAnimationSetProperty>(pProp);
CAnimationParameters Params = pAnimSet->Value(pPropertyData);
@@ -227,7 +227,7 @@ CResource* CScriptTemplate::FindDisplayAsset(void* pPropertyData, u32& rOutCharI
else
{
ASSERT(pProp->Type() == EPropertyTypeNew::Asset);
ASSERT(pProp->Type() == EPropertyType::Asset);
CAssetProperty* pAsset = TPropCast<CAssetProperty>(pProp);
CAssetID ID = pAsset->Value(pPropertyData);
CResourceEntry *pEntry = gpResourceStore->FindEntry( ID );
@@ -261,9 +261,9 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(void* pPropertyData)
// Property
else
{
IPropertyNew* pProp = mpProperties->ChildByIDString(it->AssetLocation);
IProperty* pProp = mpProperties->ChildByIDString(it->AssetLocation);
if (pProp->Type() == EPropertyTypeNew::Asset)
if (pProp->Type() == EPropertyType::Asset)
{
CAssetProperty* pAsset = TPropCast<CAssetProperty>(pProp);
pRes = gpResourceStore->LoadResource( pAsset->Value(pPropertyData), eDynamicCollision );

View File

@@ -2,7 +2,6 @@
#define CSCRIPTTEMPLATE_H
#include "Core/Resource/Script/Property/Properties.h"
#include "EPropertyType.h"
#include "EVolumeShape.h"
#include "Core/Resource/Model/CModel.h"
#include "Core/Resource/CCollisionMeshGroup.h"

View File

@@ -1,38 +0,0 @@
#ifndef EPROPERTYTYPE
#define EPROPERTYTYPE
#include "IPropertyNew.h"
#if 0
#include <Common/TString.h>
enum EPropertyType
{
eBoolProperty,
eByteProperty,
eShortProperty,
eLongProperty,
eEnumProperty,
eBitfieldProperty,
eFloatProperty,
eStringProperty,
eVector3Property,
eColorProperty,
eSoundProperty,
eAssetProperty,
eStructProperty,
eArrayProperty,
eCharacterProperty,
eMayaSplineProperty,
eUnknownProperty,
eInvalidProperty
};
#endif
// functions defined in IPropertyTemplate.cpp
EPropertyTypeNew PropStringToPropEnum(TString Prop);
TString PropEnumToPropString(EPropertyTypeNew Prop);
const char* HashablePropTypeName(EPropertyTypeNew Prop);
#endif // EPROPERTYTYPE

View File

@@ -1,245 +0,0 @@
#include "IProperty.h"
#include "IPropertyTemplate.h"
#if 0
// ************ IProperty ************
bool IProperty::IsInArray() const
{
CPropertyStruct *pParent = mpParent;
while (pParent)
{
if (pParent->Type() == eArrayProperty) return true;
pParent = pParent->Parent();
}
return false;
}
CPropertyStruct* IProperty::RootStruct()
{
return (mpParent ? mpParent->RootStruct() : Type() == eStructProperty ? static_cast<CPropertyStruct*>(this) : nullptr);
}
IPropertyTemplate* IProperty::Template() const
{
return mpTemplate;
}
TString IProperty::Name() const
{
return mpTemplate->Name();
}
u32 IProperty::ID() const
{
if (mpParent && mpParent->Type() == eArrayProperty)
return ArrayIndex();
else
return mpTemplate->PropertyID();
}
TIDString IProperty::IDString(bool FullPath) const
{
TIDString Out;
if (ID() != 0xFFFFFFFF)
{
if (mpParent && FullPath)
{
Out = mpParent->IDString(true);
if (!Out.IsEmpty()) Out += ":";
}
Out += TString::HexString(ID());
}
return Out;
}
u32 IProperty::ArrayIndex() const
{
CArrayProperty *pArray = TPropCast<CArrayProperty>(mpParent);
if (pArray)
{
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
{
if (pArray->PropertyByIndex(iSub) == this)
return iSub;
}
}
return -1;
}
bool IProperty::ShouldCook()
{
if (mpTemplate->CookPreference() == eNeverCook) return false;
else if (mpTemplate->CookPreference() == eAlwaysCook) return true;
else
{
if (mpTemplate->Game() == eReturns)
return !MatchesDefault();
else
return true;
}
}
bool IProperty::MatchesDefault()
{
const IPropertyValue *pkValue = RawValue();
const IPropertyValue *pkDefault = mpTemplate->RawDefaultValue();
if (!pkValue || !pkDefault) return false;
else return pkValue->Matches(pkDefault);
}
// ************ TAssetProperty ************
TAssetProperty::TAssetProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: TTypedProperty(pTemp, pInstance, pParent, CAssetID::InvalidID( pTemp->Game() ))
{
}
// ************ CPropertyStruct ************
void CPropertyStruct::Copy(const IProperty *pkProp)
{
const CPropertyStruct *pkSource = static_cast<const CPropertyStruct*>(pkProp);
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
mProperties[iSub]->Copy(pkSource->mProperties[iSub]);
}
bool CPropertyStruct::ShouldCook()
{
if (mpTemplate->CookPreference() == eNeverCook) return false;
for (u32 iProp = 0; iProp < mProperties.size(); iProp++)
{
if (mProperties[iProp]->ShouldCook())
return true;
}
return false;
}
IProperty* CPropertyStruct::PropertyByIndex(u32 index) const
{
return mProperties[index];
}
IProperty* CPropertyStruct::PropertyByID(u32 ID) const
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
{
if ((*it)->ID() == ID)
return *it;
}
return nullptr;
}
IProperty* CPropertyStruct::PropertyByIDString(const TIDString& rkStr) const
{
// 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) const
{
IProperty *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByID(u32 ID) const
{
IProperty *pProp = PropertyByID(ID);
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr) const
{
IProperty *pProp = PropertyByIDString(rkStr);
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
}
// ************ CArrayProperty ************
void CArrayProperty::Copy(const IProperty *pkProp)
{
const CArrayProperty *pkSource = static_cast<const CArrayProperty*>(pkProp);
Resize(pkSource->Count());
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
mProperties[iSub]->Copy(pkSource->mProperties[iSub]);
}
bool CArrayProperty::ShouldCook()
{
return (mpTemplate->CookPreference() == eNeverCook ? false : true);
}
void CArrayProperty::Resize(int Size)
{
int OldSize = mProperties.size();
if (OldSize == Size) return;
if (Size < OldSize)
{
for (int iProp = mProperties.size() - 1; iProp >= Size; iProp--)
delete mProperties[iProp];
}
mProperties.resize(Size);
if (Size > OldSize)
{
for (int iProp = OldSize; iProp < Size; iProp++)
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(Instance(), this);
}
}
CStructTemplate* CArrayProperty::SubStructTemplate() const
{
// CArrayTemplate inherits from CStructTemplate. The template defines the substruct structure.
return static_cast<CStructTemplate*>(Template());
}
TString CArrayProperty::ElementName() const
{
return static_cast<CArrayTemplate*>(Template())->ElementName();
}
#endif

View File

@@ -1,303 +0,0 @@
#ifndef IPROPERTY
#define IPROPERTY
#if 0
#include "EPropertyType.h"
#include "IPropertyValue.h"
#include "Core/Resource/CResource.h"
#include "Core/Resource/TResPtr.h"
#include "Core/Resource/Animation/CAnimationParameters.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Math/CVector3f.h>
#include <list>
class CScriptObject;
class CScriptTemplate;
class CStructTemplate;
class IPropertyTemplate;
typedef TString TIDString;
/*
* IProperty is the base class, containing just some virtual function definitions
*/
class IProperty
{
protected:
class CPropertyStruct *mpParent;
CScriptObject *mpInstance;
IPropertyTemplate *mpTemplate;
public:
IProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: mpParent(pParent)
, mpInstance(pInstance)
, mpTemplate(pTemp)
{
}
virtual ~IProperty() {}
virtual EPropertyType Type() const = 0;
virtual TString ToString() const { return ""; }
virtual IPropertyValue* RawValue() { return nullptr; }
virtual void Copy(const IProperty *pkProp) = 0;
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent = 0) const = 0;
virtual bool Matches(const IProperty *pkProp) const = 0;
virtual bool ShouldCook(); // Can't be const because it calls MatchesDefault()
virtual bool MatchesDefault(); // Can't be const because RawValue() isn't const
inline CScriptObject* Instance() const { return mpInstance; }
inline CPropertyStruct* Parent() const { return mpParent; }
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
bool IsInArray() const;
CPropertyStruct* RootStruct();
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
IPropertyTemplate* Template() const;
TString Name() const;
u32 ID() const;
TIDString IDString(bool FullPath) const;
u32 ArrayIndex() const;
};
/*
* TTypedProperty is a template subclass for actual properties.
*/
#define IMPLEMENT_PROPERTY_CLONE(ClassName) \
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const \
{ \
if (!pParent) pParent = mpParent; \
ClassName *pOut = new ClassName(mpTemplate, pInstance, pParent); \
pOut->Copy(this); \
return pOut; \
}
template <typename ValueType, EPropertyType TypeEnum, class ValueClass>
class TTypedProperty : public IProperty
{
ValueClass mValue;
public:
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: IProperty(pTemp, pInstance, pParent) {}
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v)
: IProperty(pTemp, pInstance, pParent), mValue(v) {}
~TTypedProperty() {}
virtual EPropertyType Type() const { return TypeEnum; }
static inline EPropertyType StaticType() { return TypeEnum; }
virtual TString ToString() const { return mValue.ToString(); }
virtual IPropertyValue* RawValue() { return &mValue; }
virtual void Copy(const IProperty *pkProp)
{
const TTypedProperty *pkCast = static_cast<const TTypedProperty*>(pkProp);
mValue.Set(pkCast->mValue.Get());
}
IMPLEMENT_PROPERTY_CLONE(TTypedProperty)
virtual bool Matches(const IProperty *pkProp) const
{
const TTypedProperty *pkTyped = static_cast<const TTypedProperty*>(pkProp);
return ( (Type() == pkTyped->Type()) &&
mValue.Matches(&pkTyped->mValue) );
}
inline ValueType Get() const { return mValue.Get(); }
inline void Set(ValueType 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, CHexLongValue> TBitfieldProperty;
typedef TTypedProperty<float, eFloatProperty, CFloatValue> TFloatProperty;
typedef TTypedProperty<CVector3f, eVector3Property, CVector3Value> TVector3Property;
typedef TTypedProperty<CColor, eColorProperty, CColorValue> TColorProperty;
typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue> TUnknownProperty;
/*
* TStringProperty, TSoundProperty, TAssetProperty, and TCharacterProperty get little subclasses in order to override some virtual functions.
*/
#define IMPLEMENT_PROPERTY_CTORS(ClassName, ValueType) \
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent) \
: TTypedProperty(pTemp, pInstance, pParent) {} \
\
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v) \
: TTypedProperty(pTemp, pInstance, pParent, v) {}
class TStringProperty : public TTypedProperty<TString, eStringProperty, CStringValue>
{
public:
IMPLEMENT_PROPERTY_CTORS(TStringProperty, TString)
IMPLEMENT_PROPERTY_CLONE(TStringProperty)
virtual bool MatchesDefault() { return Get().IsEmpty(); }
virtual bool ShouldCook() { return true; }
};
class TSoundProperty : public TTypedProperty<u32, eSoundProperty, CSoundValue>
{
public:
IMPLEMENT_PROPERTY_CTORS(TSoundProperty, u32)
IMPLEMENT_PROPERTY_CLONE(TSoundProperty)
virtual bool MatchesDefault() { return Get() == 0xFFFFFFFF; }
};
class TAssetProperty : public TTypedProperty<CAssetID, eAssetProperty, CAssetValue>
{
public:
TAssetProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent); // Can't be in the header because needs to check the template to set the correct ID length
TAssetProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, CAssetID v)
: TTypedProperty(pTemp, pInstance, pParent, v) {}
IMPLEMENT_PROPERTY_CLONE(TAssetProperty)
virtual bool MatchesDefault() { return !Get().IsValid(); }
virtual bool ShouldCook() { return true; }
};
class TCharacterProperty : public TTypedProperty<CAnimationParameters, eCharacterProperty, CCharacterValue>
{
public:
IMPLEMENT_PROPERTY_CTORS(TCharacterProperty, CAnimationParameters)
IMPLEMENT_PROPERTY_CLONE(TCharacterProperty)
virtual bool MatchesDefault() { return Get().AnimSet() == nullptr; }
virtual bool ShouldCook() { return true; }
};
class TMayaSplineProperty : public TTypedProperty<std::vector<u8>, eMayaSplineProperty, CMayaSplineValue>
{
public:
IMPLEMENT_PROPERTY_CTORS(TMayaSplineProperty, std::vector<u8>)
IMPLEMENT_PROPERTY_CLONE(TMayaSplineProperty)
virtual bool MatchesDefault() { return Get().empty(); }
};
/*
* CPropertyStruct is for defining structs of properties.
*/
class CPropertyStruct : public IProperty
{
friend class CScriptLoader;
protected:
std::vector<IProperty*> mProperties;
public:
CPropertyStruct(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: IProperty(pTemp, pInstance, pParent) {}
~CPropertyStruct()
{
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
delete *it;
}
EPropertyType Type() const { return eStructProperty; }
static inline EPropertyType StaticType() { return eStructProperty; }
virtual void Copy(const IProperty *pkProp);
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
{
if (!pParent) pParent = mpParent;
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pInstance, pParent);
pOut->Copy(this);
return pOut;
}
virtual bool Matches(const IProperty *pkProp) const
{
const CPropertyStruct *pkStruct = static_cast<const CPropertyStruct*>(pkProp);
if ( (Type() == pkStruct->Type()) &&
(mProperties.size() == pkStruct->mProperties.size()) )
{
for (u32 iProp = 0; iProp < mProperties.size(); iProp++)
{
if (!mProperties[iProp]->Matches(pkStruct->mProperties[iProp]))
return false;
}
return true;
}
return false;
}
virtual bool MatchesDefault()
{
for (u32 iProp = 0; iProp < mProperties.size(); iProp++)
{
if (!mProperties[iProp]->MatchesDefault())
return false;
}
return true;
}
virtual bool ShouldCook();
// Inline
inline u32 Count() const { 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) const;
IProperty* PropertyByID(u32 ID) const;
IProperty* PropertyByIDString(const TIDString& rkStr) const;
CPropertyStruct* StructByIndex(u32 index) const;
CPropertyStruct* StructByID(u32 ID) const;
CPropertyStruct* StructByIDString(const TIDString& rkStr) const;
};
/*
* CArrayProperty stores a repeated property struct.
*/
class CArrayProperty : public CPropertyStruct
{
friend class CScriptLoader;
public:
CArrayProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: CPropertyStruct(pTemp, pInstance, pParent) {}
EPropertyType Type() const { return eArrayProperty; }
static inline EPropertyType StaticType() { return eArrayProperty; }
virtual void Copy(const IProperty *pkProp);
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
{
if (!pParent) pParent = mpParent;
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pInstance, pParent);
pOut->Copy(this);
return pOut;
}
virtual bool MatchesDefault() { return mProperties.empty(); }
virtual bool ShouldCook();
// Inline
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
// Functions
void Resize(int Size);
CStructTemplate* SubStructTemplate() const;
TString ElementName() const;
};
/*
* Function for casting properties. Returns null if the property is not actually the requested type.
*/
template <class PropertyClass>
PropertyClass* TPropCast(IProperty *pProp)
{
return (pProp && pProp->Type() == PropertyClass::StaticType() ? static_cast<PropertyClass*>(pProp) : nullptr);
}
#endif
#endif // IPROPERTY

View File

@@ -1,346 +0,0 @@
#include "IPropertyTemplate.h"
#include "CMasterTemplate.h"
#include <Common/Hash/CCRC32.h>
#include <iostream>
#if 0
// ************ IPropertyTemplate ************
EGame IPropertyTemplate::Game() const
{
return (mpMasterTemplate ? mpMasterTemplate->Game() : eUnknownGame);
}
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;
}
TString IPropertyTemplate::FullName() const
{
return mpParent ? mpParent->FullName() + "::" + Name() : Name();
}
TIDString IPropertyTemplate::IDString(bool FullPath) const
{
if (mID != 0xFFFFFFFF)
{
TIDString Out;
if (mpParent && FullPath)
{
Out = mpParent->IDString(true);
if (!Out.IsEmpty()) Out += ":";
}
Out += TIDString::HexString(mID);
return Out;
}
else return "";
}
bool IPropertyTemplate::IsDescendantOf(const CStructTemplate *pStruct) const
{
CStructTemplate *pParent = mpParent;
while (pParent)
{
if (pParent == pStruct) return true;
pParent = pParent->Parent();
}
return false;
}
bool IPropertyTemplate::IsFromStructTemplate() const
{
const CStructTemplate *pParent = Parent();
while (pParent)
{
if (!pParent->SourceFile().IsEmpty()) return true;
pParent = pParent->Parent();
}
return false;
}
bool IPropertyTemplate::IsNameCorrect() const
{
// Check whether the property name is correct... i.e., if we hash it, does it match the property ID?
// Only valid for Prime 2 and up, since Prime 1 doesn't have real property IDs, so we can't validate names
if (Game() >= eEchoesDemo)
{
// Don't hash for single-property structs
if ( (!Parent() || !Parent()->IsSingleProperty()) &&
// Don't hash for the three properties in EditorProperties that have fourCC property IDs
mID != FOURCC('INAM') &&
mID != FOURCC('XFRM') &&
mID != FOURCC('ACTV') )
{
// Only re-hash if we need to. Save the result (output won't change if function is called multiple times)
if (!mHasCachedNameCheck)
{
// The property ID is just a CRC32 of the property name + the type
CCRC32 Hash;
Hash.Hash(*mName);
Hash.Hash(GetTypeNameString());
mCachedNameIsCorrect = Hash.Digest() == mID;
mHasCachedNameCheck = true;
}
return mCachedNameIsCorrect;
}
}
return true;
}
TString IPropertyTemplate::FindStructSource() const
{
const CStructTemplate *pkStruct = mpParent;
while (pkStruct)
{
if (!pkStruct->SourceFile().IsEmpty()) return pkStruct->SourceFile();
pkStruct = pkStruct->Parent();
}
return "";
}
CStructTemplate* IPropertyTemplate::RootStruct()
{
if (mpParent) return mpParent->RootStruct();
else if (Type() == eStructProperty) return static_cast<CStructTemplate*>(this);
else return nullptr;
}
// ************ CStructTemplate ************
void CStructTemplate::CopyStructData(const CStructTemplate *pkStruct)
{
mVersionPropertyCounts = pkStruct->mVersionPropertyCounts;
mIsSingleProperty = pkStruct->mIsSingleProperty;
mSourceFile = pkStruct->mSourceFile;
mTypeName = pkStruct->mTypeName;
mSubProperties.resize(pkStruct->mSubProperties.size());
for (u32 iSub = 0; iSub < pkStruct->mSubProperties.size(); iSub++)
{
mSubProperties[iSub] = pkStruct->mSubProperties[iSub]->Clone(mpScriptTemplate, this);
CMasterTemplate::AddProperty(mSubProperties[iSub]);
}
}
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]++;
}
}
}
#endif
// ************ GLOBAL FUNCTIONS ************
TString PropEnumToPropString(EPropertyTypeNew Prop)
{
switch (Prop)
{
case EPropertyTypeNew::Bool: return "bool";
case EPropertyTypeNew::Byte: return "byte";
case EPropertyTypeNew::Short: return "short";
case EPropertyTypeNew::Int: return "long";
case EPropertyTypeNew::Enum: return "enum";
case EPropertyTypeNew::Flags: return "bitfield";
case EPropertyTypeNew::Float: return "float";
case EPropertyTypeNew::String: return "string";
case EPropertyTypeNew::Color: return "color";
case EPropertyTypeNew::Vector: return "vector3f";
case EPropertyTypeNew::Sound: return "sound";
case EPropertyTypeNew::Asset: return "asset";
case EPropertyTypeNew::Struct: return "struct";
case EPropertyTypeNew::Array: return "array";
case EPropertyTypeNew::AnimationSet: return "character";
case EPropertyTypeNew::Spline: return "MayaSpline";
default:
return "invalid";
}
}
EPropertyTypeNew PropStringToPropEnum(TString Prop)
{
Prop = Prop.ToLower();
if (Prop == "bool") return EPropertyTypeNew::Bool;
if (Prop == "byte") return EPropertyTypeNew::Byte;
if (Prop == "short") return EPropertyTypeNew::Short;
if (Prop == "long") return EPropertyTypeNew::Int;
if (Prop == "enum") return EPropertyTypeNew::Enum;
if (Prop == "bitfield") return EPropertyTypeNew::Flags;
if (Prop == "float") return EPropertyTypeNew::Float;
if (Prop == "string") return EPropertyTypeNew::String;
if (Prop == "color") return EPropertyTypeNew::Color;
if (Prop == "vector3f") return EPropertyTypeNew::Vector;
if (Prop == "sound") return EPropertyTypeNew::Sound;
if (Prop == "asset") return EPropertyTypeNew::Asset;
if (Prop == "struct") return EPropertyTypeNew::Struct;
if (Prop == "array") return EPropertyTypeNew::Array;
if (Prop == "character") return EPropertyTypeNew::AnimationSet;
if (Prop == "mayaspline") return EPropertyTypeNew::Spline;
return EPropertyTypeNew::Invalid;
}
const char* HashablePropTypeName(EPropertyTypeNew Prop)
{
// Variants that match Retro's internal type names for generating property IDs. case sensitive
switch (Prop)
{
case EPropertyTypeNew::Bool: return "bool";
case EPropertyTypeNew::Int: return "int";
case EPropertyTypeNew::Enum: return "enum";
case EPropertyTypeNew::Flags: return "Flags";
case EPropertyTypeNew::Float: return "float";
case EPropertyTypeNew::String: return "string";
case EPropertyTypeNew::Color: return "Color";
case EPropertyTypeNew::Vector: return "Vector";
case EPropertyTypeNew::Sound: return "sound";
case EPropertyTypeNew::Asset: return "asset";
case EPropertyTypeNew::Spline: return "spline";
// All other types are either invalid or need a custom reimplementation because they can return multiple strings (like struct)
default:
ASSERT(false);
return nullptr;
}
}
#if 0
// ************ 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
Log::Write(base + tmp->Name());
}
}
#endif

View File

@@ -1,804 +0,0 @@
#ifndef IPROPERTYTEMPLATE
#define IPROPERTYTEMPLATE
#if 0
#include "EPropertyType.h"
#include "IProperty.h"
#include "IPropertyValue.h"
#include "Core/Resource/CResTypeFilter.h"
#include "Core/Resource/Animation/CAnimationParameters.h"
#include <Common/CColor.h>
#include <Common/TString.h>
#include <Common/types.h>
#include <Math/CVector3f.h>
#include <vector>
typedef TString TIDString;
class CMasterTemplate;
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;
CScriptTemplate *mpScriptTemplate;
CMasterTemplate *mpMasterTemplate;
TString mName;
TString mDescription;
u32 mID;
ECookPreference mCookPreference;
std::vector<u32> mAllowedVersions;
mutable bool mHasCachedNameCheck;
mutable bool mCachedNameIsCorrect;
public:
IPropertyTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: mID(ID)
, mpParent(pParent)
, mpScriptTemplate(pScript)
, mpMasterTemplate(pMaster)
, mName("UNSET PROPERTY NAME")
, mCookPreference(eNoCookPreference)
, mHasCachedNameCheck(false)
, mCachedNameIsCorrect(false)
{
}
IPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: mID(ID)
, mpParent(pParent)
, mpScriptTemplate(pScript)
, mpMasterTemplate(pMaster)
, mName(rkName)
, mCookPreference(CookPreference)
, mHasCachedNameCheck(false)
, mCachedNameIsCorrect(false)
{
}
virtual EPropertyType Type() const = 0;
virtual bool CanHaveDefault() const = 0;
virtual bool IsNumerical() const = 0;
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent) = 0;
virtual IPropertyTemplate* Clone(CScriptTemplate *pScript, CStructTemplate *pParent = 0) const = 0;
virtual void Copy(const IPropertyTemplate *pkTemp)
{
mName = pkTemp->mName;
mDescription = pkTemp->mDescription;
mID = pkTemp->mID;
mCookPreference = pkTemp->mCookPreference;
mAllowedVersions = pkTemp->mAllowedVersions;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
return ( (pkTemp != nullptr) &&
(mName == pkTemp->mName) &&
(mDescription == pkTemp->mDescription) &&
(mID == pkTemp->mID) &&
(mCookPreference == pkTemp->mCookPreference) &&
(mAllowedVersions == pkTemp->mAllowedVersions) &&
(Type() == pkTemp->Type()) );
}
virtual TString DefaultToString() const { return ""; }
virtual const IPropertyValue* RawDefaultValue() const { return nullptr; }
virtual bool HasValidRange() const { return false; }
virtual TString RangeToString() const { return ""; }
virtual TString Suffix() const { return ""; }
virtual const char* GetTypeNameString() const { return HashablePropTypeName(Type()); }
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
if (rkParamName == "cook_pref")
{
TString lValue = rkValue.ToLower();
if (lValue == "always")
mCookPreference = eAlwaysCook;
else if (lValue == "never")
mCookPreference = eNeverCook;
else
mCookPreference = eNoCookPreference;
}
else if (rkParamName == "description")
mDescription = rkValue;
}
EGame Game() const;
bool IsInVersion(u32 Version) const;
TString FullName() const;
TIDString IDString(bool FullPath) const;
bool IsDescendantOf(const CStructTemplate *pStruct) const;
bool IsFromStructTemplate() const;
bool IsNameCorrect() const;
TString FindStructSource() const;
CStructTemplate* RootStruct();
// Inline Accessors
inline TString Name() const { return mName; }
inline TString Description() const { return mDescription; }
inline u32 PropertyID() const { return mID; }
inline ECookPreference CookPreference() const { return mCookPreference; }
inline CStructTemplate* Parent() const { return mpParent; }
inline CScriptTemplate* ScriptTemplate() const { return mpScriptTemplate; }
inline CMasterTemplate* MasterTemplate() const { return mpMasterTemplate; }
inline void SetName(const TString& rkName) { mName = rkName; mHasCachedNameCheck = false; }
inline void SetDescription(const TString& rkDesc) { mDescription = rkDesc; }
};
// Macro for defining reimplementations of IPropertyTemplate::Clone(), which are usually identical to each other aside from the class being instantiated
#define IMPLEMENT_TEMPLATE_CLONE(ClassName) \
virtual IPropertyTemplate* Clone(CScriptTemplate *pScript, CStructTemplate *pParent = 0) const \
{ \
if (!pParent) pParent = mpParent; \
if (!pScript) pScript = mpScriptTemplate; \
ClassName *pTemp = new ClassName(mID, pScript, mpMasterTemplate, pParent); \
pTemp->Copy(this); \
return pTemp; \
}
// 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, bool CanHaveDefaultValue>
class TTypedPropertyTemplate : public IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
protected:
ValueClass mDefaultValue;
public:
TTypedPropertyTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pScript, pMaster, pParent) {}
TTypedPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
virtual EPropertyType Type() const { return PropTypeEnum; }
virtual bool CanHaveDefault() const { return CanHaveDefaultValue; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
TPropertyType *pOut = new TPropertyType(this, pInstance, pParent, GetDefaultValue());
return pOut;
}
IMPLEMENT_TEMPLATE_CLONE(TTypedPropertyTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
IPropertyTemplate::Copy(pkTemp);
mDefaultValue.Copy(&static_cast<const TTypedPropertyTemplate*>(pkTemp)->mDefaultValue);
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const TTypedPropertyTemplate *pkTyped = static_cast<const TTypedPropertyTemplate*>(pkTemp);
return ( (IPropertyTemplate::Matches(pkTemp)) &&
(mDefaultValue.Matches(&pkTyped->mDefaultValue)) );
}
virtual TString DefaultToString() const
{
return mDefaultValue.ToString();
}
virtual const IPropertyValue* RawDefaultValue() const
{
return &mDefaultValue;
}
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
IPropertyTemplate::SetParam(rkParamName, rkValue);
if (rkParamName == "default")
mDefaultValue.FromString(rkValue.ToLower());
}
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 and a suffix to be tracked.
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
class TNumericalPropertyTemplate : public TTypedPropertyTemplate<PropType,PropTypeEnum,ValueClass,true>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
ValueClass mMin;
ValueClass mMax;
TString mSuffix;
public:
TNumericalPropertyTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent)
{}
TNumericalPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent)
, mMin(0)
, mMax(0)
{}
virtual bool IsNumerical() const { return true; }
virtual bool HasValidRange() const { return (mMin != 0 || mMax != 0); }
IMPLEMENT_TEMPLATE_CLONE(TNumericalPropertyTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
TTypedPropertyTemplate::Copy(pkTemp);
const TNumericalPropertyTemplate *pkNumerical = static_cast<const TNumericalPropertyTemplate*>(pkTemp);
mMin.Copy(&pkNumerical->mMin);
mMax.Copy(&pkNumerical->mMax);
mSuffix = pkNumerical->mSuffix;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const TNumericalPropertyTemplate *pkNumerical = static_cast<const TNumericalPropertyTemplate*>(pkTemp);
return ( (TTypedPropertyTemplate::Matches(pkTemp)) &&
(mMin.Matches(&pkNumerical->mMin)) &&
(mMax.Matches(&pkNumerical->mMax)) &&
(mSuffix == pkNumerical->mSuffix) );
}
virtual TString RangeToString() const
{
return mMin.ToString() + "," + mMax.ToString();
}
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
TTypedPropertyTemplate::SetParam(rkParamName, rkValue);
if (rkParamName == "range")
{
TStringList Components = rkValue.ToLower().Split(", ");
if (Components.size() == 2)
{
mMin.FromString(Components.front());
mMax.FromString(Components.back());
}
}
else if (rkParamName == "suffix")
{
mSuffix = rkValue;
}
}
virtual TString Suffix() const { return mSuffix; }
inline PropType GetMin() const { return mMin.Get(); }
inline PropType GetMax() const { return mMax.Get(); }
inline void SetRange(const PropType& rkMin, const PropType& rkMax)
{
mMin.Set(rkMin);
mMax.Set(rkMax);
}
inline void SetSuffix(const TString& rkSuffix)
{
mSuffix = rkSuffix;
}
};
// Typedefs for all property types that don't need further functionality.
typedef TTypedPropertyTemplate<bool, eBoolProperty, CBoolValue, true> 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<CVector3f, eVector3Property, CVector3Value, true> TVector3Template;
typedef TTypedPropertyTemplate<CColor, eColorProperty, CColorValue, true> TColorTemplate;
// TCharacterTemplate, TSoundTemplate, TStringTemplate, and TMayaSplineTemplate get their own subclasses so they can reimplement a couple functions
class TCharacterTemplate : public TTypedPropertyTemplate<CAnimationParameters, eCharacterProperty, CCharacterValue, false>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
TCharacterTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent) {}
TCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TCharacterProperty(this, pInstance, pParent, CAnimationParameters(Game()));
}
const char* GetTypeNameString() const
{
return (Game() < eCorruptionProto ? "AnimationSet" : "CharacterAnimationSet");
}
IMPLEMENT_TEMPLATE_CLONE(TCharacterTemplate)
};
class TSoundTemplate : public TTypedPropertyTemplate<u32, eSoundProperty, CSoundValue, false>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
TSoundTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent) {}
TSoundTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TSoundProperty(this, pInstance, pParent, -1);
}
IMPLEMENT_TEMPLATE_CLONE(TSoundTemplate)
};
class TStringTemplate : public TTypedPropertyTemplate<TString, eStringProperty, CStringValue, false>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
TStringTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent) {}
TStringTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TStringProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(TStringTemplate)
};
class TMayaSplineTemplate : public TTypedPropertyTemplate<std::vector<u8>, eMayaSplineProperty, CMayaSplineValue, false>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
public:
TMayaSplineTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent) {}
TMayaSplineTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TMayaSplineProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(TMayaSplineTemplate)
};
// CAssetTemplate - Property template for assets. Tracks a list of resource types that
// the property is allowed to accept.
class CAssetTemplate : public IPropertyTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
CResTypeFilter mTypeFilter;
public:
CAssetTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pScript, pMaster, pParent) {}
CAssetTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
virtual EPropertyType Type() const { return eAssetProperty; }
virtual bool CanHaveDefault() const { return false; }
virtual bool IsNumerical() const { return false; }
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TAssetProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(CAssetTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
IPropertyTemplate::Copy(pkTemp);
mTypeFilter = static_cast<const CAssetTemplate*>(pkTemp)->mTypeFilter;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CAssetTemplate *pkAsset = static_cast<const CAssetTemplate*>(pkTemp);
return ( (IPropertyTemplate::Matches(pkTemp)) &&
(mTypeFilter == pkAsset->mTypeFilter) );
}
void SetTypeFilter(const TStringList& rkExtensions) { mTypeFilter.SetAcceptedTypes(Game(), rkExtensions); }
const CResTypeFilter& TypeFilter() const { return mTypeFilter; }
};
// CEnumTemplate - Property template for enums. Tracks a list of possible values (enumerators).
class CEnumTemplate : public TTypedPropertyTemplate<s32, eEnumProperty, CHexLongValue, true>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SEnumerator
{
TString Name;
u32 ID;
SEnumerator(const TString& rkName, u32 _ID)
: Name(rkName), ID(_ID) {}
bool operator==(const SEnumerator& rkOther) const
{
return ( (Name == rkOther.Name) && (ID == rkOther.ID) );
}
};
std::vector<SEnumerator> mEnumerators;
TString mSourceFile;
bool mUsesHashes;
public:
CEnumTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent)
, mUsesHashes(false)
{
}
CEnumTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent)
, mUsesHashes(false)
{
}
virtual EPropertyType Type() const { return eEnumProperty; }
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
TEnumProperty *pEnum = new TEnumProperty(this, pInstance, pParent);
pEnum->Set(GetDefaultValue());
return pEnum;
}
IMPLEMENT_TEMPLATE_CLONE(CEnumTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
TTypedPropertyTemplate::Copy(pkTemp);
const CEnumTemplate *pkEnum = static_cast<const CEnumTemplate*>(pkTemp);
mEnumerators = pkEnum->mEnumerators;
mSourceFile = pkEnum->mSourceFile;
mUsesHashes = pkEnum->mUsesHashes;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CEnumTemplate *pkEnum = static_cast<const CEnumTemplate*>(pkTemp);
return ( (TTypedPropertyTemplate::Matches(pkTemp)) &&
(mEnumerators == pkEnum->mEnumerators) &&
(mSourceFile == pkEnum->mSourceFile) &&
(mUsesHashes == pkEnum->mUsesHashes) );
}
virtual const char* GetTypeNameString() const
{
return (mUsesHashes ? "enum" : "choice");
}
inline TString SourceFile() const { return mSourceFile; }
inline u32 NumEnumerators() const { return mEnumerators.size(); }
u32 EnumeratorIndex(u32 enumID) const
{
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
{
if (mEnumerators[iEnum].ID == enumID)
return iEnum;
}
return -1;
}
u32 EnumeratorID(u32 enumIndex) const
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].ID;
else return -1;
}
TString EnumeratorName(u32 enumIndex) const
{
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 TTypedPropertyTemplate<u32, eBitfieldProperty, CHexLongValue, true>
{
friend class CTemplateLoader;
friend class CTemplateWriter;
struct SBitFlag
{
TString Name;
u32 Mask;
SBitFlag(const TString& _name, u32 _mask)
: Name(_name), Mask(_mask) {}
bool operator==(const SBitFlag& rkOther) const
{
return ( (Name == rkOther.Name) && (Mask == rkOther.Mask) );
}
};
std::vector<SBitFlag> mBitFlags;
TString mSourceFile;
public:
CBitfieldTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, pScript, pMaster, pParent)
{
}
CBitfieldTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent)
{
}
virtual EPropertyType Type() const { return eBitfieldProperty; }
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
TBitfieldProperty *pBitfield = new TBitfieldProperty(this, pInstance, pParent);
pBitfield->Set(GetDefaultValue());
return pBitfield;
}
IMPLEMENT_TEMPLATE_CLONE(CBitfieldTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
TTypedPropertyTemplate::Copy(pkTemp);
const CBitfieldTemplate *pkBitfield = static_cast<const CBitfieldTemplate*>(pkTemp);
mBitFlags = pkBitfield->mBitFlags;
mSourceFile = pkBitfield->mSourceFile;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CBitfieldTemplate *pkBitfield = static_cast<const CBitfieldTemplate*>(pkTemp);
return ( (TTypedPropertyTemplate::Matches(pkTemp)) &&
(mBitFlags == pkBitfield->mBitFlags) &&
(mSourceFile == pkBitfield->mSourceFile) );
}
inline TString SourceFile() const { return mSourceFile; }
inline u32 NumFlags() const { return mBitFlags.size(); }
inline TString FlagName(u32 index) const { return mBitFlags[index].Name; }
inline u32 FlagMask(u32 index) const { 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;
TString mTypeName;
void DetermineVersionPropertyCounts();
public:
CStructTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, pScript, pMaster, pParent)
, mIsSingleProperty(false) {}
CStructTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: IPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, 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(CScriptObject *pInstance, CPropertyStruct *pParent)
{
CPropertyStruct *pStruct = new CPropertyStruct(this, pInstance, pParent);
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
{
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty(pInstance, pStruct);
pStruct->AddSubProperty(pSubProp);
}
return pStruct;
}
IMPLEMENT_TEMPLATE_CLONE(CStructTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
IPropertyTemplate::Copy(pkTemp);
const CStructTemplate *pkStruct = static_cast<const CStructTemplate*>(pkTemp);
CopyStructData(pkStruct);
}
void CopyStructData(const CStructTemplate *pkStruct);
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CStructTemplate *pkStruct = static_cast<const CStructTemplate*>(pkTemp);
if ( (IPropertyTemplate::Matches(pkTemp)) &&
(mVersionPropertyCounts == pkStruct->mVersionPropertyCounts) &&
(mIsSingleProperty == pkStruct->mIsSingleProperty) &&
(mSourceFile == pkStruct->mSourceFile) &&
(mTypeName == pkStruct->mTypeName) )
{
return StructDataMatches(pkStruct);
}
return false;
}
const char* GetTypeNameString() const
{
// hack - currently templates embedded within another XML can't have a type name
return mTypeName.IsEmpty() ? *mName : *mTypeName;
}
bool StructDataMatches(const CStructTemplate *pkStruct) const
{
if ( (mIsSingleProperty == pkStruct->mIsSingleProperty) &&
(mSubProperties.size() == pkStruct->mSubProperties.size()) )
{
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
{
if (!mSubProperties[iSub]->Matches(pkStruct->mSubProperties[iSub]))
return false;
}
return true;
}
return false;
}
inline TString SourceFile() const { return mSourceFile; }
inline bool IsSingleProperty() const { return mIsSingleProperty; }
inline u32 Count() const { return mSubProperties.size(); }
inline u32 NumVersions() const { return mVersionPropertyCounts.size(); }
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;
TString mElementName;
public:
CArrayTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: CStructTemplate(ID, pScript, pMaster, pParent)
{
mIsSingleProperty = true;
}
CArrayTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: CStructTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent)
{
mIsSingleProperty = true;
}
EPropertyType Type() const { return eArrayProperty; }
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new CArrayProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(CArrayTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
CStructTemplate::Copy(pkTemp);
mElementName = static_cast<const CArrayTemplate*>(pkTemp)->mElementName;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CArrayTemplate *pkArray = static_cast<const CArrayTemplate*>(pkTemp);
return ( (mElementName == pkArray->mElementName) &
(CStructTemplate::Matches(pkTemp)) );
}
void SetParam(const TString& rkParamName, const TString& rkValue)
{
if (rkParamName == "element_name")
mElementName = rkValue;
else
CStructTemplate::SetParam(rkParamName, rkValue);
}
TString ElementName() const { return mElementName; }
void SetElementName(const TString& rkName) { mElementName = rkName; }
CPropertyStruct* CreateSubStruct(CScriptObject *pInstance, CArrayProperty *pArray)
{
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pInstance, pArray);
}
};
#endif
#endif // IPROPERTYTEMPLATE

View File

@@ -1,392 +0,0 @@
#ifndef IPROPERTYVALUE_H
#define IPROPERTYVALUE_H
#if 0
#include "EPropertyType.h"
#include <Common/CAssetID.h>
#include <Common/Log.h>
#include "Core/Resource/Animation/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;
virtual IPropertyValue* Clone() const = 0;
virtual void Copy(const IPropertyValue *pkValue) = 0;
virtual bool Matches(const IPropertyValue *pkValue) const = 0;
};
template<typename PropType>
class TTypedPropertyValue : public IPropertyValue
{
protected:
PropType mValue;
public:
TTypedPropertyValue() {}
TTypedPropertyValue(PropType rkVal)
: mValue(rkVal) {}
virtual void Copy(const IPropertyValue *pkValue)
{
const TTypedPropertyValue *pkOther = static_cast<const TTypedPropertyValue*>(pkValue);
mValue = pkOther->mValue;
}
virtual bool Matches(const IPropertyValue *pkValue) const
{
const TTypedPropertyValue *pkOther = static_cast<const TTypedPropertyValue*>(pkValue);
return ((pkValue != nullptr) && (mValue == pkOther->mValue));
}
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");
}
IPropertyValue* Clone() const
{
return new CBoolValue(mValue);
}
};
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);
}
IPropertyValue* Clone() const
{
return new CByteValue(mValue);
}
};
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);
}
IPropertyValue* Clone() const
{
return new CShortValue(mValue);
}
};
class CLongValue : public TTypedPropertyValue<s32>
{
public:
CLongValue() { mValue = 0; }
CLongValue(s32 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 = (s32) rkString.ToInt32(base);
}
IPropertyValue* Clone() const
{
return new CLongValue(mValue);
}
};
class CHexLongValue : public TTypedPropertyValue<u32>
{
public:
CHexLongValue() { mValue = 0; }
CHexLongValue(u32 Val) { mValue = Val; }
TString ToString() const
{
return TString::HexString(mValue, 8);
}
void FromString(const TString& rkString)
{
u32 Base = (rkString.StartsWith("0x") ? 16 : 10);
mValue = (s32) rkString.ToInt32(Base);
}
IPropertyValue* Clone() const
{
return new CHexLongValue(mValue);
}
};
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();
}
IPropertyValue* Clone() const
{
return new CFloatValue(mValue);
}
};
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;
}
IPropertyValue* Clone() const
{
return new CStringValue(mValue);
}
};
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++;
}
}
IPropertyValue* Clone() const
{
return new CColorValue(mValue);
}
};
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++;
}
}
IPropertyValue* Clone() const
{
return new CVector3Value(mValue);
}
};
class CCharacterValue : public TTypedPropertyValue<CAnimationParameters>
{
public:
CCharacterValue() {}
CCharacterValue(const CAnimationParameters& rkParams) { mValue = rkParams; }
TString ToString() const { return ""; }
void FromString(const TString&) { }
IPropertyValue* Clone() const
{
return new CCharacterValue(mValue);
}
};
class CMayaSplineValue : public TTypedPropertyValue<std::vector<u8>>
{
public:
CMayaSplineValue() {}
CMayaSplineValue(const std::vector<u8>& rkData) { mValue = rkData; }
TString ToString() const { return "[MayaSpline]"; }
void FromString(const TString&) {}
IPropertyValue* Clone() const
{
return new CMayaSplineValue(mValue);
}
};
class CSoundValue : public TTypedPropertyValue<u32>
{
public:
CSoundValue() {}
CSoundValue(u32 SoundID) { mValue = SoundID; }
TString ToString() const { return TString::FromInt32(mValue, 0, 10); }
void FromString(const TString& rkString) { mValue = rkString.ToInt32(10); }
IPropertyValue* Clone() const
{
return new CSoundValue(mValue);
}
};
class CAssetValue : public TTypedPropertyValue<CAssetID>
{
public:
CAssetValue() {}
CAssetValue(const CAssetID& rkID) { mValue = rkID; }
TString ToString() const { return ""; }
void FromString(const TString&) {}
IPropertyValue* Clone() const
{
return new CAssetValue(mValue);
}
};
class CUnknownValue : public TTypedPropertyValue<std::vector<u8>>
{
public:
CUnknownValue();
CUnknownValue(const std::vector<u8>& rkVec) { mValue = rkVec; }
TString ToString() const { return ""; }
void FromString(const TString&) {}
IPropertyValue* Clone() const
{
return new CUnknownValue(mValue);
}
};
#endif
#endif // IPROPERTYVALUE_H

View File

@@ -1,11 +1,11 @@
#ifndef CANIMATIONPROPERTY_H
#define CANIMATIONPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CAnimationProperty : public TSerializeableTypedProperty< u32, EPropertyTypeNew::Animation >
class CAnimationProperty : public TSerializeableTypedProperty< u32, EPropertyType::Animation >
{
friend class IPropertyNew;
friend class IProperty;
protected:
CAnimationProperty(EGame Game)

View File

@@ -1,11 +1,11 @@
#ifndef CANIMATIONSETPROPERTY_H
#define CANIMATIONSETPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CAnimationSetProperty : public TSerializeableTypedProperty< CAnimationParameters, EPropertyTypeNew::AnimationSet >
class CAnimationSetProperty : public TSerializeableTypedProperty< CAnimationParameters, EPropertyType::AnimationSet >
{
friend class IPropertyNew;
friend class IProperty;
protected:
CAnimationSetProperty(EGame Game)

View File

@@ -1,7 +1,7 @@
#ifndef CARRAYPROPERTY_H
#define CARRAYPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
struct SScriptArray
{
@@ -20,9 +20,9 @@ struct SScriptArray
/** You probably shouldn't use this on intrinsic classes; script only */
/** @todo proper support of default values for arrays (this would be used for prefabs) */
class CArrayProperty : public TTypedPropertyNew<u32, EPropertyTypeNew::Array>
class CArrayProperty : public TTypedProperty<u32, EPropertyType::Array>
{
friend class IPropertyNew;
friend class IProperty;
friend class CTemplateLoader;
/** This class inherits from TTypedPropertyNew<int> in order to expose the array
@@ -30,7 +30,7 @@ class CArrayProperty : public TTypedPropertyNew<u32, EPropertyTypeNew::Array>
* value and we respond by updating the allocated space, handling item destruction
* and construction, etc.
*/
IPropertyNew* mpItemArchetype;
IProperty* mpItemArchetype;
/** Internal functions */
SScriptArray& _GetInternalArray(void* pData) const
@@ -46,7 +46,7 @@ class CArrayProperty : public TTypedPropertyNew<u32, EPropertyTypeNew::Array>
protected:
CArrayProperty(EGame Game)
: TTypedPropertyNew(Game)
: TTypedProperty(Game)
, mpItemArchetype(nullptr)
{}
@@ -69,7 +69,7 @@ public:
virtual void Destruct(void* pData) const
{
RevertToDefault(pData);
TTypedPropertyNew::Destruct(pData);
TTypedProperty::Destruct(pData);
}
virtual bool MatchesDefault(void* pData) const
@@ -107,7 +107,7 @@ public:
virtual void Serialize(IArchive& rArc)
{
TTypedPropertyNew::Serialize(rArc);
TTypedProperty::Serialize(rArc);
rArc << SerialParameter("ItemArchetype", mpItemArchetype);
if (rArc.IsReader())
@@ -135,16 +135,16 @@ public:
}
}
virtual void InitFromArchetype(IPropertyNew* pOther)
virtual void InitFromArchetype(IProperty* pOther)
{
TTypedPropertyNew::InitFromArchetype(pOther);
TTypedProperty::InitFromArchetype(pOther);
CArrayProperty* pOtherArray = static_cast<CArrayProperty*>(pOther);
mpItemArchetype = IPropertyNew::CreateCopy(pOtherArray->mpItemArchetype);
mpItemArchetype = IProperty::CreateCopy(pOtherArray->mpItemArchetype);
}
virtual void PostInitialize()
{
TTypedPropertyNew::PostInitialize();
TTypedProperty::PostInitialize();
mpItemArchetype->Initialize(this, mpScriptTemplate, 0);
}
@@ -204,7 +204,7 @@ public:
}
/** Accessors */
IPropertyNew* ItemArchetype() const { return mpItemArchetype; }
IProperty* ItemArchetype() const { return mpItemArchetype; }
};
#endif // CARRAYPROPERTY_H

View File

@@ -1,13 +1,13 @@
#ifndef CASSETPROPERTY_H
#define CASSETPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
#include "Core/Resource/CResTypeFilter.h"
class CAssetProperty : public TSerializeableTypedProperty<CAssetID, EPropertyTypeNew::Asset>
class CAssetProperty : public TSerializeableTypedProperty<CAssetID, EPropertyType::Asset>
{
friend class CTemplateLoader;
friend class IPropertyNew;
friend class IProperty;
CResTypeFilter mTypeFilter;
@@ -33,9 +33,9 @@ public:
mTypeFilter != pArchetype->mTypeFilter;
}
virtual void InitFromArchetype(IPropertyNew* pOther)
virtual void InitFromArchetype(IProperty* pOther)
{
TTypedPropertyNew::InitFromArchetype(pOther);
TTypedProperty::InitFromArchetype(pOther);
mTypeFilter = static_cast<CAssetProperty*>(pOther)->mTypeFilter;
}

View File

@@ -1,11 +1,11 @@
#ifndef CBOOLPROPERTY_H
#define CBOOLPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CBoolProperty : public TSerializeableTypedProperty< bool, EPropertyTypeNew::Bool >
class CBoolProperty : public TSerializeableTypedProperty< bool, EPropertyType::Bool >
{
friend class IPropertyNew;
friend class IProperty;
protected:
CBoolProperty(EGame Game)

View File

@@ -1,7 +1,7 @@
#ifndef CBYTEPROPERTY_H
#define CBYTEPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CByteProperty : public TNumericalPropertyNew< s8, EPropertyTypeNew::Byte >
{

View File

@@ -1,7 +1,7 @@
#ifndef CCOLORPROPERTY_H
#define CCOLORPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
#include "CFloatProperty.h"
class CColorProperty : public TSerializeableTypedProperty< CColor, EPropertyTypeNew::Color >

View File

@@ -1,7 +1,7 @@
#ifndef CENUMPROPERTY_H
#define CENUMPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
/** There are two types of enum properties in the game data: enum and choice.
*

View File

@@ -29,7 +29,7 @@ void CFlagsProperty::SerializeValue(void* pData, IArchive& rArc) const
rArc.SerializePrimitive( (u32&) ValueRef(pData), SH_HexDisplay );
}
void CFlagsProperty::InitFromArchetype(IPropertyNew* pOther)
void CFlagsProperty::InitFromArchetype(IProperty* pOther)
{
TSerializeableTypedProperty::InitFromArchetype(pOther);
CFlagsProperty* pOtherFlags = static_cast<CFlagsProperty*>(pOther);

View File

@@ -1,7 +1,7 @@
#ifndef CFLAGSPROPERTY_H
#define CFLAGSPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CFlagsProperty : public TSerializeableTypedProperty<u32, EPropertyTypeNew::Flags>
{

View File

@@ -1,7 +1,7 @@
#ifndef CFLOATPROPERTY_H
#define CFLOATPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CFloatProperty : public TNumericalPropertyNew< float, EPropertyTypeNew::Float >
{

View File

@@ -1,7 +1,7 @@
#ifndef CGUIDPROPERTY_H
#define CGUIDPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CGuidProperty : public TTypedPropertyNew< std::vector<char>, EPropertyTypeNew::Guid >
{

View File

@@ -1,7 +1,7 @@
#ifndef CINTPROPERTY_H
#define CINTPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CIntProperty : public TNumericalPropertyNew< s32, EPropertyTypeNew::Int >
{

View File

@@ -1,7 +1,7 @@
#ifndef CPOINTERPROPERTY_H
#define CPOINTERPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CPointerProperty : public TTypedPropertyNew<void*, EPropertyTypeNew::Pointer>
{

View File

@@ -1,7 +1,7 @@
#ifndef CSEQUENCEPROPERTY_H
#define CSEQUENCEPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CSequenceProperty : public TTypedPropertyNew< s32, EPropertyTypeNew::Sequence >
{

View File

@@ -1,7 +1,7 @@
#ifndef CSHORTPROPERTY_H
#define CSHORTPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CShortProperty : public TNumericalPropertyNew< s16, EPropertyTypeNew::Short >
{

View File

@@ -1,7 +1,7 @@
#ifndef CSOUNDPROPERTY_H
#define CSOUNDPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CSoundProperty : public TSerializeableTypedProperty< s32, EPropertyTypeNew::Sound >
{

View File

@@ -1,7 +1,7 @@
#ifndef CSPLINEPROPERTY_H
#define CSPLINEPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CSplineProperty : public TTypedPropertyNew< std::vector<char>, EPropertyTypeNew::Spline >
{

View File

@@ -1,7 +1,7 @@
#ifndef CSTRINGPROPERTY_H
#define CSTRINGPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CStringProperty : public TSerializeableTypedProperty< TString, EPropertyTypeNew::String >
{

View File

@@ -1,16 +1,16 @@
#include "CStructProperty.h"
#include "Core/Resource/Script/CMasterTemplate.h"
EPropertyTypeNew CStructPropertyNew::Type() const
EPropertyType CStructProperty::Type() const
{
return EPropertyTypeNew::Struct;
return EPropertyType::Struct;
}
u32 CStructPropertyNew::DataSize() const
u32 CStructProperty::DataSize() const
{
if (!mChildren.empty())
{
IPropertyNew* pLastChild = mChildren.back();
IProperty* pLastChild = mChildren.back();
return (pLastChild->Offset() - Offset()) + pLastChild->DataSize();
}
else
@@ -19,13 +19,13 @@ u32 CStructPropertyNew::DataSize() const
}
}
u32 CStructPropertyNew::DataAlignment() const
u32 CStructProperty::DataAlignment() const
{
// Structs are aligned to the first child property.
return (mChildren.empty() ? 1 : mChildren[0]->DataAlignment());
}
void CStructPropertyNew::Construct(void* pData) const
void CStructProperty::Construct(void* pData) const
{
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -33,7 +33,7 @@ void CStructPropertyNew::Construct(void* pData) const
}
}
void CStructPropertyNew::Destruct(void* pData) const
void CStructProperty::Destruct(void* pData) const
{
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -41,7 +41,7 @@ void CStructPropertyNew::Destruct(void* pData) const
}
}
bool CStructPropertyNew::MatchesDefault(void* pData) const
bool CStructProperty::MatchesDefault(void* pData) const
{
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -53,7 +53,7 @@ bool CStructPropertyNew::MatchesDefault(void* pData) const
return true;
}
void CStructPropertyNew::RevertToDefault(void* pData) const
void CStructProperty::RevertToDefault(void* pData) const
{
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -61,14 +61,14 @@ void CStructPropertyNew::RevertToDefault(void* pData) const
}
}
const char* CStructPropertyNew::HashableTypeName() const
const char* CStructProperty::HashableTypeName() const
{
return mpArchetype ? mpArchetype->HashableTypeName() : *mName;
}
void CStructPropertyNew::Serialize(IArchive& rArc)
void CStructProperty::Serialize(IArchive& rArc)
{
IPropertyNew::Serialize(rArc);
IProperty::Serialize(rArc);
// Serialize atomic flag
bool Atomic = IsAtomic();
@@ -85,7 +85,7 @@ void CStructPropertyNew::Serialize(IArchive& rArc)
// Serialize archetype
if (mpArchetype)
{
CStructPropertyNew* pArchetype = static_cast<CStructPropertyNew*>(mpArchetype);
CStructProperty* pArchetype = static_cast<CStructProperty*>(mpArchetype);
ASSERT(pArchetype != nullptr);
if (rArc.IsReader())
@@ -103,13 +103,13 @@ void CStructPropertyNew::Serialize(IArchive& rArc)
// Serialize type and ID, then look up the matching property and serialize it.
// We don't really need the type, but it's a good sanity check, and it's also good practice
// to guarantee that parameters are read in order, as some serializers are order-dependent.
EPropertyTypeNew ChildType;
EPropertyType ChildType;
u32 ChildID;
rArc << SerialParameter("Type", ChildType, SH_Attribute)
<< SerialParameter("ID", ChildID, SH_Attribute | SH_HexDisplay );
IPropertyNew* pChild = ChildByID(ChildID);
IProperty* pChild = ChildByID(ChildID);
ASSERT(pChild != nullptr && pChild->Type() == ChildType);
pChild->Serialize(rArc);
@@ -123,7 +123,7 @@ void CStructPropertyNew::Serialize(IArchive& rArc)
else
{
// Check if any properties need to override parameters from their archetype.
std::vector<IPropertyNew*> PropertiesToSerialize;
std::vector<IProperty*> PropertiesToSerialize;
for (u32 ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -147,7 +147,7 @@ void CStructPropertyNew::Serialize(IArchive& rArc)
}
}
void CStructPropertyNew::SerializeValue(void* pData, IArchive& Arc) const
void CStructProperty::SerializeValue(void* pData, IArchive& Arc) const
{
for (u32 ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
{
@@ -159,9 +159,9 @@ void CStructPropertyNew::SerializeValue(void* pData, IArchive& Arc) const
}
}
void CStructPropertyNew::InitFromArchetype(IPropertyNew* pOther)
void CStructProperty::InitFromArchetype(IProperty* pOther)
{
IPropertyNew::InitFromArchetype(pOther);
IProperty::InitFromArchetype(pOther);
// Copy children
_ClearChildren();
@@ -169,14 +169,14 @@ void CStructPropertyNew::InitFromArchetype(IPropertyNew* pOther)
for (u32 ChildIdx = 0; ChildIdx < pOther->NumChildren(); ChildIdx++)
{
IPropertyNew* pChild = CreateCopy( pOther->ChildByIndex(ChildIdx) );
IProperty* pChild = CreateCopy( pOther->ChildByIndex(ChildIdx) );
mChildren.push_back( pChild );
}
}
bool CStructPropertyNew::ShouldSerialize() const
bool CStructProperty::ShouldSerialize() const
{
if (IPropertyNew::ShouldSerialize())
if (IProperty::ShouldSerialize())
return true;
for (u32 ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
@@ -188,7 +188,7 @@ bool CStructPropertyNew::ShouldSerialize() const
return false;
}
TString CStructPropertyNew::GetTemplateFileName()
TString CStructProperty::GetTemplateFileName()
{
ASSERT(IsArchetype() || mpArchetype);
return IsArchetype() ? mTemplateFileName : mpArchetype->GetTemplateFileName();

View File

@@ -1,7 +1,7 @@
#ifndef CSTRUCTPROPERTY_H
#define CSTRUCTPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CStructPropertyNew : public IPropertyNew
{

View File

@@ -1,7 +1,7 @@
#ifndef CVECTORPROPERTY_H
#define CVECTORPROPERTY_H
#include "../IPropertyNew.h"
#include "IProperty.h"
class CVectorProperty : public TSerializeableTypedProperty< CVector3f, EPropertyTypeNew::Vector >
{

View File

@@ -1,9 +1,9 @@
#include "IPropertyNew.h"
#include "Property/CAssetProperty.h"
#include "Property/CArrayProperty.h"
#include "Property/CEnumProperty.h"
#include "Property/CFlagsProperty.h"
#include "Property/CPointerProperty.h"
#include "IProperty.h"
#include "CAssetProperty.h"
#include "CArrayProperty.h"
#include "CEnumProperty.h"
#include "CFlagsProperty.h"
#include "CPointerProperty.h"
#include "Core/Resource/Script/CMasterTemplate.h"
#include "Core/Resource/Script/CScriptTemplate.h"

View File

@@ -87,7 +87,7 @@ inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type)
case EPropertyTypeNew::Spline: return "spline";
case EPropertyTypeNew::Guid: return "guid";
// unknown hashable types - used in hashes but these names are inaccurate
case EPropertyTypeNew::Animation: return "animation"; // hashable but real name unknown
case EPropertyTypeNew::Animation: return "animation";
case EPropertyTypeNew::Sequence: return "sequence";
// non hashable types - not used in ID hashes but still displayed on the UI
case EPropertyTypeNew::Byte: return "byte";

View File

@@ -1,7 +1,7 @@
#ifndef PROPERTIES_H
#define PROPERTIES_H
#include "../IPropertyNew.h"
#include "IProperty.h"
#include "CAnimationProperty.h"
#include "CAnimationSetProperty.h"
#include "CArrayProperty.h"

View File

@@ -1,39 +0,0 @@
#ifndef TPROPERTYPROXY_H
#define TPROPERTYPROXY_H
#include <type_traits>
/**
* Lightweight proxy class representing a property instance. Easy to read/modify
* specific properties and efficient to pass around.
*/
template<class PropertyClass>
class TPropertyProxy
{
typedef PropertyClass::ValueType ValueType;
/** Property data buffer */
void* mpDataPtr;
/** Source property */
PropertyClass* mpProperty;
public:
TPropertyProxy()
: mpDataPtr(nullptr)
, mpProperty(nullptr)
{}
TPropertyProxy(void* pDataPtr, PropertyClass* pProperty)
: mpDataPtr(pDataPtr)
, mpProperty(pProperty)
{}
/** Returns whether this proxy points to a valid property instance */
bool IsValid() const
{
return mpDataPtr != nullptr && mpProperty != nullptr;
}
};
#endif // TPROPERTYPROXY_H