mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-14 23:56:23 +00:00
Massive overhaul of property system done over the last few months. There is unfinished/broken stuff still, but it compiles now.
This commit is contained in:
@@ -88,7 +88,7 @@ SMessage CMasterTemplate::MessageByIndex(u32 Index)
|
||||
return (std::next(it, Index))->second;
|
||||
}
|
||||
|
||||
CStructTemplate* CMasterTemplate::StructAtSource(const TString& rkSource)
|
||||
CStructPropertyNew* CMasterTemplate::StructAtSource(const TString& rkSource)
|
||||
{
|
||||
auto InfoIt = mStructTemplates.find(rkSource);
|
||||
|
||||
@@ -149,38 +149,44 @@ TString CMasterTemplate::PropertyName(u32 PropertyID)
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
u32 CMasterTemplate::CreatePropertyID(IPropertyTemplate *pTemp)
|
||||
// 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)
|
||||
{
|
||||
// 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).
|
||||
TString IDString = pTemp->IDString(false);
|
||||
TString Source;
|
||||
CStructTemplate *pStruct = pTemp->Parent();
|
||||
//
|
||||
// Note for properties that have accurate names we can apply a CRC32 to the name to generate a hash equivalent to what the hash would
|
||||
// have been if this were an MP2/3 property. In an ideal world where every property was named, this would be great. However, we have a
|
||||
// lot of properties that have generic names like "Unknown", and they should be tracked separately as they are in all likelihood
|
||||
// different properties. So for this reason, we only want to track sub-instances of one property under one ID.
|
||||
TString IDString = pProp->Archetype()->IDString(true);
|
||||
TString TemplateFile = pProp->GetTemplateFileName();
|
||||
|
||||
while (pStruct)
|
||||
{
|
||||
Source = pStruct->SourceFile();
|
||||
if (!Source.IsEmpty()) break;
|
||||
IDString.Prepend(pStruct->IDString(false) + ":");
|
||||
pStruct = pStruct->Parent();
|
||||
}
|
||||
|
||||
return IDString.Hash32() * Source.Hash32();
|
||||
CCRC32 Hash;
|
||||
Hash.Hash(*IDString);
|
||||
Hash.Hash(*TemplateFile);
|
||||
return Hash.Digest();
|
||||
}
|
||||
|
||||
void CMasterTemplate::AddProperty(IPropertyTemplate *pTemp, const TString& rkTemplateName /*= ""*/)
|
||||
void CMasterTemplate::AddProperty(IPropertyNew* pProp, const TString& rkTemplateName /*= ""*/)
|
||||
{
|
||||
u32 ID;
|
||||
|
||||
if (pTemp->Game() >= eEchoesDemo)
|
||||
ID = pTemp->PropertyID();
|
||||
if (pProp->Game() >= eEchoesDemo)
|
||||
ID = pProp->ID();
|
||||
|
||||
// Use a different ID for MP1
|
||||
else
|
||||
{
|
||||
// For MP1 we only really need to track properties that come from struct templates.
|
||||
if (!pTemp->IsFromStructTemplate()) return;
|
||||
else ID = CreatePropertyID(pTemp);
|
||||
IPropertyNew* pArchetype = pProp->Archetype();
|
||||
|
||||
if (!pArchetype ||
|
||||
pArchetype->ScriptTemplate() != nullptr ||
|
||||
pArchetype->RootParent()->Type() != EPropertyTypeNew::Struct)
|
||||
return;
|
||||
|
||||
ID = CreatePropertyID(pProp);
|
||||
}
|
||||
|
||||
auto it = smIDMap.find(ID);
|
||||
@@ -189,7 +195,7 @@ void CMasterTemplate::AddProperty(IPropertyTemplate *pTemp, const TString& rkTem
|
||||
if (it != smIDMap.end())
|
||||
{
|
||||
SPropIDInfo& rInfo = it->second;
|
||||
rInfo.PropertyList.push_back(pTemp);
|
||||
rInfo.PropertyList.push_back(pProp);
|
||||
|
||||
if (!rkTemplateName.IsEmpty())
|
||||
{
|
||||
@@ -214,15 +220,15 @@ void CMasterTemplate::AddProperty(IPropertyTemplate *pTemp, const TString& rkTem
|
||||
{
|
||||
SPropIDInfo Info;
|
||||
if (!rkTemplateName.IsEmpty()) Info.XMLList.push_back(rkTemplateName);
|
||||
Info.PropertyList.push_back(pTemp);
|
||||
Info.PropertyList.push_back(pProp);
|
||||
smIDMap[ID] = Info;
|
||||
}
|
||||
}
|
||||
|
||||
void CMasterTemplate::RenameProperty(IPropertyTemplate *pTemp, const TString& rkNewName)
|
||||
void CMasterTemplate::RenameProperty(IPropertyNew* pProp, const TString& rkNewName)
|
||||
{
|
||||
u32 ID = pTemp->PropertyID();
|
||||
if (ID <= 0xFF) ID = CreatePropertyID(pTemp);
|
||||
u32 ID = pProp->ID();
|
||||
if (ID <= 0xFF) ID = CreatePropertyID(pProp);
|
||||
RenameProperty(ID, rkNewName);
|
||||
}
|
||||
|
||||
@@ -245,10 +251,10 @@ void CMasterTemplate::RenameProperty(u32 ID, const TString& rkNewName)
|
||||
{
|
||||
const SPropIDInfo& rkInfo = InfoIt->second;
|
||||
|
||||
for (u32 iTemp = 0; iTemp < rkInfo.PropertyList.size(); iTemp++)
|
||||
for (u32 PropertyIdx = 0; PropertyIdx < rkInfo.PropertyList.size(); PropertyIdx++)
|
||||
{
|
||||
if (Original.IsEmpty() || rkInfo.PropertyList[iTemp]->Name() == Original)
|
||||
rkInfo.PropertyList[iTemp]->SetName(rkNewName);
|
||||
if (Original.IsEmpty() || rkInfo.PropertyList[PropertyIdx]->Name() == Original)
|
||||
rkInfo.PropertyList[PropertyIdx]->SetName(rkNewName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,10 +270,10 @@ void CMasterTemplate::XMLsUsingID(u32 ID, std::vector<TString>& rOutList)
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<IPropertyTemplate*>* CMasterTemplate::TemplatesWithMatchingID(IPropertyTemplate *pTemp)
|
||||
const std::vector<IPropertyNew*>* CMasterTemplate::TemplatesWithMatchingID(IPropertyNew* pProp)
|
||||
{
|
||||
u32 ID = pTemp->PropertyID();
|
||||
if (ID <= 0xFF) ID = CreatePropertyID(pTemp);
|
||||
u32 ID = pProp->ID();
|
||||
if (ID <= 0xFF) ID = CreatePropertyID(pProp);
|
||||
|
||||
auto InfoIt = smIDMap.find(ID);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "CLink.h"
|
||||
#include "CScriptTemplate.h"
|
||||
#include "Core/Resource/Script/Property/Properties.h"
|
||||
#include <Common/EGame.h>
|
||||
#include <Common/types.h>
|
||||
#include <map>
|
||||
@@ -19,7 +20,9 @@ class CMasterTemplate
|
||||
bool mFullyLoaded;
|
||||
|
||||
std::vector<TString> mGameVersions;
|
||||
std::map<TString, CStructTemplate*> mStructTemplates;
|
||||
std::map<TString, CStructPropertyNew*> mStructTemplates;
|
||||
std::map<TString, CEnumProperty*> mEnumTemplates;
|
||||
std::map<TString, CFlagsProperty*> mFlagsTemplates;
|
||||
|
||||
std::map<u32, CScriptTemplate*> mTemplates;
|
||||
std::map<u32, SState> mStates;
|
||||
@@ -28,7 +31,7 @@ class CMasterTemplate
|
||||
struct SPropIDInfo
|
||||
{
|
||||
std::vector<TString> XMLList; // List of script/struct templates that use this ID
|
||||
std::vector<IPropertyTemplate*> PropertyList; // List of all properties that use this ID
|
||||
std::vector<IPropertyNew*> PropertyList; // List of all properties that use this ID
|
||||
};
|
||||
static std::map<u32, SPropIDInfo> smIDMap;
|
||||
static std::map<EGame, CMasterTemplate*> smMasterMap;
|
||||
@@ -48,7 +51,7 @@ public:
|
||||
SMessage MessageByID(u32 MessageID);
|
||||
SMessage MessageByID(const CFourCC& MessageID);
|
||||
SMessage MessageByIndex(u32 Index);
|
||||
CStructTemplate* StructAtSource(const TString& rkSource);
|
||||
CStructPropertyNew* StructAtSource(const TString& rkSource);
|
||||
|
||||
// Inline Accessors
|
||||
inline EGame Game() const { return mGame; }
|
||||
@@ -66,12 +69,12 @@ public:
|
||||
static TString FindGameName(EGame Game);
|
||||
static EGame FindGameForName(const TString& rkName);
|
||||
static TString PropertyName(u32 PropertyID);
|
||||
static u32 CreatePropertyID(IPropertyTemplate *pTemp);
|
||||
static void AddProperty(IPropertyTemplate *pTemp, const TString& rkTemplateName = "");
|
||||
static void RenameProperty(IPropertyTemplate *pTemp, const TString& rkNewName);
|
||||
static u32 CreatePropertyID(IPropertyNew *pTemp);
|
||||
static void AddProperty(IPropertyNew *pTemp, const TString& rkTemplateName = "");
|
||||
static void RenameProperty(IPropertyNew *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<IPropertyTemplate*>* TemplatesWithMatchingID(IPropertyTemplate *pTemp);
|
||||
static const std::vector<IPropertyNew*>* TemplatesWithMatchingID(IPropertyNew *pTemp);
|
||||
};
|
||||
|
||||
#endif // CMASTERTEMPLATE_H
|
||||
|
||||
@@ -13,19 +13,29 @@ CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLa
|
||||
, mIsCheckingNearVisibleActivation(false)
|
||||
{
|
||||
mpTemplate->AddObject(this);
|
||||
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty(this, nullptr);
|
||||
|
||||
mpInstanceName = mpTemplate->FindInstanceName(mpProperties);
|
||||
mpPosition = mpTemplate->FindPosition(mpProperties);
|
||||
mpRotation = mpTemplate->FindRotation(mpProperties);
|
||||
mpScale = mpTemplate->FindScale(mpProperties);
|
||||
mpActive = mpTemplate->FindActive(mpProperties);
|
||||
mpLightParameters = mpTemplate->FindLightParameters(mpProperties);
|
||||
// Init properties
|
||||
CStructPropertyNew* pProperties = pTemplate->Properties();
|
||||
u32 PropertiesSize = pProperties->DataSize();
|
||||
mPropertyData.resize( PropertiesSize );
|
||||
pProperties->Construct( mPropertyData.data() );
|
||||
|
||||
mInstanceName = CStringRef(this, pTemplate->NameProperty());
|
||||
mPosition = CVectorRef(this, pTemplate->PositionProperty());
|
||||
mRotation = CVectorRef(this, pTemplate->RotationProperty());
|
||||
mScale = CVectorRef(this, pTemplate->ScaleProperty());
|
||||
mActive = CBoolRef(this, pTemplate->ActiveProperty());
|
||||
mLightParameters = CStructRef(this, pTemplate->LightParametersProperty());
|
||||
}
|
||||
|
||||
CScriptObject::~CScriptObject()
|
||||
{
|
||||
if (mpProperties) delete mpProperties;
|
||||
if (!mPropertyData.empty())
|
||||
{
|
||||
mpTemplate->Properties()->Destruct( mPropertyData.data() );
|
||||
mPropertyData.clear();
|
||||
}
|
||||
|
||||
mpTemplate->RemoveObject(this);
|
||||
|
||||
// Note: Incoming links will be deleted by the sender.
|
||||
@@ -34,6 +44,19 @@ CScriptObject::~CScriptObject()
|
||||
}
|
||||
|
||||
// ************ DATA MANIPULATION ************
|
||||
void CScriptObject::CopyProperties(CScriptObject* pObject)
|
||||
{
|
||||
ASSERT(pObject->Template() == Template());
|
||||
CSerialVersion Version(0, IArchive::skCurrentArchiveVersion, Template()->Game());
|
||||
|
||||
CVectorOutStream DataStream;
|
||||
CBasicBinaryWriter DataWriter(&DataStream, Version);
|
||||
Template()->Properties()->SerializeValue( pObject->PropertyData(), DataWriter );
|
||||
|
||||
CBasicBinaryReader DataReader(DataStream.Data(), DataStream.Size(), Version);
|
||||
Template()->Properties()->SerializeValue( PropertyData(), DataReader );
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateProperties()
|
||||
{
|
||||
EvaluateDisplayAsset();
|
||||
@@ -43,12 +66,12 @@ CScriptObject::~CScriptObject()
|
||||
|
||||
void CScriptObject::EvaluateDisplayAsset()
|
||||
{
|
||||
mpDisplayAsset = mpTemplate->FindDisplayAsset(mpProperties, mActiveCharIndex, mActiveAnimIndex, mHasInGameModel);
|
||||
mpDisplayAsset = mpTemplate->FindDisplayAsset(PropertyData(), mActiveCharIndex, mActiveAnimIndex, mHasInGameModel);
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateCollisionModel()
|
||||
{
|
||||
mpCollision = mpTemplate->FindCollision(mpProperties);
|
||||
mpCollision = mpTemplate->FindCollision(PropertyData());
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateVolume()
|
||||
@@ -57,15 +80,15 @@ void CScriptObject::EvaluateVolume()
|
||||
mVolumeScale = mpTemplate->VolumeScale(this);
|
||||
}
|
||||
|
||||
bool CScriptObject::IsEditorProperty(IProperty *pProp)
|
||||
bool CScriptObject::IsEditorProperty(IPropertyNew *pProp)
|
||||
{
|
||||
return ( (pProp == mpInstanceName) ||
|
||||
(pProp == mpPosition) ||
|
||||
(pProp == mpRotation) ||
|
||||
(pProp == mpScale) ||
|
||||
(pProp == mpActive) ||
|
||||
(pProp == mpLightParameters) ||
|
||||
(pProp->Parent() == mpLightParameters)
|
||||
return ( (pProp == mInstanceName.Property()) ||
|
||||
(pProp == mPosition.Property()) ||
|
||||
(pProp == mRotation.Property()) ||
|
||||
(pProp == mScale.Property()) ||
|
||||
(pProp == mActive.Property()) ||
|
||||
(pProp == mLightParameters.Property()) ||
|
||||
(pProp->Parent() == mLightParameters.Property())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#ifndef CSCRIPTOBJECT_H
|
||||
#define CSCRIPTOBJECT_H
|
||||
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyTemplate.h"
|
||||
#include "CScriptTemplate.h"
|
||||
#include "Core/Resource/Area/CGameArea.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/CCollisionMeshGroup.h"
|
||||
#include "Core/Resource/Script/Property/Properties.h"
|
||||
|
||||
class CScriptLayer;
|
||||
class CLink;
|
||||
@@ -30,14 +29,15 @@ class CScriptObject
|
||||
u32 mInstanceID;
|
||||
std::vector<CLink*> mOutLinks;
|
||||
std::vector<CLink*> mInLinks;
|
||||
CPropertyStruct *mpProperties;
|
||||
std::vector<char> mPropertyData;
|
||||
|
||||
CStringRef mInstanceName;
|
||||
CVectorRef mPosition;
|
||||
CVectorRef mRotation;
|
||||
CVectorRef mScale;
|
||||
CBoolRef mActive;
|
||||
CStructRef mLightParameters;
|
||||
|
||||
TStringProperty *mpInstanceName;
|
||||
TVector3Property *mpPosition;
|
||||
TVector3Property *mpRotation;
|
||||
TVector3Property *mpScale;
|
||||
TBoolProperty *mpActive;
|
||||
CPropertyStruct *mpLightParameters;
|
||||
TResPtr<CResource> mpDisplayAsset;
|
||||
TResPtr<CCollisionMeshGroup> mpCollision;
|
||||
u32 mActiveCharIndex;
|
||||
@@ -54,11 +54,12 @@ public:
|
||||
CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
|
||||
~CScriptObject();
|
||||
|
||||
void CopyProperties(CScriptObject* pObject);
|
||||
void EvaluateProperties();
|
||||
void EvaluateDisplayAsset();
|
||||
void EvaluateCollisionModel();
|
||||
void EvaluateVolume();
|
||||
bool IsEditorProperty(IProperty *pProp);
|
||||
bool IsEditorProperty(IPropertyNew *pProp);
|
||||
void SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex = -1);
|
||||
u32 LayerIndex() const;
|
||||
bool HasNearVisibleActivation() const;
|
||||
@@ -73,39 +74,37 @@ public:
|
||||
CGameArea* Area() const { return mpArea; }
|
||||
CScriptLayer* Layer() const { return mpLayer; }
|
||||
u32 Version() const { return mVersion; }
|
||||
CPropertyStruct* Properties() const { return mpProperties; }
|
||||
u32 NumProperties() const { return mpProperties->Count(); }
|
||||
IProperty* PropertyByIndex(u32 Index) const { return mpProperties->PropertyByIndex(Index); }
|
||||
IProperty* PropertyByIDString(const TIDString& rkStr) const { return mpProperties->PropertyByIDString(rkStr); }
|
||||
u32 ObjectTypeID() const { return mpTemplate->ObjectID(); }
|
||||
u32 InstanceID() const { return mInstanceID; }
|
||||
u32 NumLinks(ELinkType Type) const { return (Type == eIncoming ? mInLinks.size() : mOutLinks.size()); }
|
||||
CLink* Link(ELinkType Type, u32 Index) const { return (Type == eIncoming ? mInLinks[Index] : mOutLinks[Index]); }
|
||||
void* PropertyData() const { return (void*) mPropertyData.data(); }
|
||||
|
||||
CVector3f Position() const { return mpPosition ? mpPosition->Get() : CVector3f::skZero; }
|
||||
CVector3f Rotation() const { return mpRotation ? mpRotation->Get() : CVector3f::skZero; }
|
||||
CVector3f Scale() const { return mpScale ? mpScale->Get() : CVector3f::skOne; }
|
||||
TString InstanceName() const { return mpInstanceName ? mpInstanceName->Get() : ""; }
|
||||
bool IsActive() const { return mpActive ? mpActive->Get() : false; }
|
||||
CVector3f Position() const { return mPosition.IsValid() ? mPosition.Get() : CVector3f::skZero; }
|
||||
CVector3f Rotation() const { return mRotation.IsValid() ? mRotation.Get() : CVector3f::skZero; }
|
||||
CVector3f Scale() const { return mScale.IsValid() ? mScale.Get() : CVector3f::skOne; }
|
||||
TString InstanceName() const { return mInstanceName.IsValid() ? mInstanceName.Get() : ""; }
|
||||
bool IsActive() const { return mActive.IsValid() ? mActive.Get() : false; }
|
||||
bool HasInGameModel() const { return mHasInGameModel; }
|
||||
CPropertyStruct* LightParameters() const { return mpLightParameters; }
|
||||
CStructRef LightParameters() const { return mLightParameters; }
|
||||
CResource* DisplayAsset() const { return mpDisplayAsset; }
|
||||
u32 ActiveCharIndex() const { return mActiveCharIndex; }
|
||||
u32 ActiveAnimIndex() const { return mActiveAnimIndex; }
|
||||
CCollisionMeshGroup* Collision() const { return mpCollision; }
|
||||
EVolumeShape VolumeShape() const { return mVolumeShape; }
|
||||
float VolumeScale() const { return mVolumeScale; }
|
||||
void SetPosition(const CVector3f& rkNewPos) { if (mpPosition) mpPosition->Set(rkNewPos); }
|
||||
void SetRotation(const CVector3f& rkNewRot) { if (mpRotation) mpRotation->Set(rkNewRot); }
|
||||
void SetScale(const CVector3f& rkNewScale) { if (mpScale) mpScale->Set(rkNewScale); }
|
||||
void SetName(const TString& rkNewName) { if (mpInstanceName) mpInstanceName->Set(rkNewName); }
|
||||
void SetActive(bool Active) { if (mpActive) mpActive->Set(Active); }
|
||||
void SetPosition(const CVector3f& rkNewPos) { mPosition.Set(rkNewPos); }
|
||||
void SetRotation(const CVector3f& rkNewRot) { mRotation.Set(rkNewRot); }
|
||||
void SetScale(const CVector3f& rkNewScale) { mScale.Set(rkNewScale); }
|
||||
void SetName(const TString& rkNewName) { mInstanceName.Set(rkNewName); }
|
||||
void SetActive(bool Active) { mActive.Set(Active); }
|
||||
|
||||
TVector3Property* PositionProperty() const { return mpPosition; }
|
||||
TVector3Property* RotationProperty() const { return mpRotation; }
|
||||
TVector3Property* ScaleProperty() const { return mpScale; }
|
||||
TStringProperty* InstanceNameProperty() const { return mpInstanceName; }
|
||||
TBoolProperty* ActiveProperty() const { return mpActive; }
|
||||
bool HasPosition() const { return mPosition.IsValid(); }
|
||||
bool HasRotation() const { return mRotation.IsValid(); }
|
||||
bool HasScale() const { return mScale.IsValid(); }
|
||||
bool HasInstanceName() const { return mInstanceName.IsValid(); }
|
||||
bool HasActive() const { return mActive.IsValid(); }
|
||||
bool HasLightParameters() const { return mLightParameters.IsValid(); }
|
||||
};
|
||||
|
||||
#endif // CSCRIPTOBJECT_H
|
||||
|
||||
@@ -10,8 +10,14 @@
|
||||
|
||||
CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
|
||||
: mpMaster(pMaster)
|
||||
, mpBaseStruct(nullptr)
|
||||
, mpProperties(nullptr)
|
||||
, mVisible(true)
|
||||
, mpNameProperty(nullptr)
|
||||
, mpPositionProperty(nullptr)
|
||||
, mpRotationProperty(nullptr)
|
||||
, mpScaleProperty(nullptr)
|
||||
, mpActiveProperty(nullptr)
|
||||
, mpLightParametersProperty(nullptr)
|
||||
, mPreviewScale(1.f)
|
||||
, mVolumeShape(eNoShape)
|
||||
, mVolumeScale(1.f)
|
||||
@@ -20,7 +26,16 @@ CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
|
||||
|
||||
CScriptTemplate::~CScriptTemplate()
|
||||
{
|
||||
delete mpBaseStruct;
|
||||
}
|
||||
|
||||
void CScriptTemplate::PostLoad()
|
||||
{
|
||||
if (!mNameIDString.IsEmpty()) mpNameProperty = TPropCast<CStringProperty>( mpProperties->ChildByIDString(mNameIDString) );
|
||||
if (!mPositionIDString.IsEmpty()) mpPositionProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mPositionIDString) );
|
||||
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) );
|
||||
}
|
||||
|
||||
EGame CScriptTemplate::Game() const
|
||||
@@ -29,14 +44,14 @@ EGame CScriptTemplate::Game() const
|
||||
}
|
||||
|
||||
// ************ PROPERTY FETCHING ************
|
||||
template<typename PropType, EPropertyType PropEnum>
|
||||
PropType TFetchProperty(CPropertyStruct *pProperties, const TIDString& rkID)
|
||||
template<class PropType>
|
||||
PropType* TFetchProperty(CStructPropertyNew* pProperties, const TIDString& rkID)
|
||||
{
|
||||
if (rkID.IsEmpty()) return nullptr;
|
||||
IProperty *pProp = pProperties->PropertyByIDString(rkID);
|
||||
IPropertyNew *pProp = pProperties->ChildByIDString(rkID);
|
||||
|
||||
if (pProp && (pProp->Type() == PropEnum))
|
||||
return static_cast<PropType>(pProp);
|
||||
return static_cast<PropType*>(pProp)->ValuePtr();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@@ -80,39 +95,42 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
|
||||
// Private function
|
||||
if (mVolumeShape == eConditionalShape)
|
||||
{
|
||||
IProperty *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString);
|
||||
TIDString PropID = mVolumeConditionIDString;
|
||||
IPropertyNew* pProp = pObj->Template()->Properties()->ChildByIDString( PropID );
|
||||
|
||||
// Get value of the condition test property (only boolean, integral, and enum types supported)
|
||||
void* pData = pObj->PropertyData();
|
||||
int Val;
|
||||
|
||||
switch (pProp->Type())
|
||||
{
|
||||
case eBoolProperty:
|
||||
Val = (static_cast<TBoolProperty*>(pProp)->Get() ? 1 : 0);
|
||||
case EPropertyTypeNew::Bool:
|
||||
Val = TPropCast<CBoolProperty>(pProp)->Value(pData) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case eByteProperty:
|
||||
Val = (int) static_cast<TByteProperty*>(pProp)->Get();
|
||||
case EPropertyTypeNew::Byte:
|
||||
Val = (int) TPropCast<CByteProperty>(pProp)->Value(pData);
|
||||
break;
|
||||
|
||||
case eShortProperty:
|
||||
Val = (int) static_cast<TShortProperty*>(pProp)->Get();
|
||||
case EPropertyTypeNew::Short:
|
||||
Val = (int) TPropCast<CShortProperty>(pProp)->Value(pData);
|
||||
break;
|
||||
|
||||
case eLongProperty:
|
||||
Val = (int) static_cast<TLongProperty*>(pProp)->Get();
|
||||
case EPropertyTypeNew::Int:
|
||||
Val = TPropCast<CIntProperty>(pProp)->Value(pData);
|
||||
break;
|
||||
|
||||
case eEnumProperty:
|
||||
Val = (int) static_cast<TEnumProperty*>(pProp)->Get();
|
||||
case EPropertyTypeNew::Enum:
|
||||
case EPropertyTypeNew::Choice:
|
||||
Val = TPropCast<CEnumProperty>(pProp)->Value(pData);
|
||||
break;
|
||||
}
|
||||
|
||||
// Test and check whether any of the conditions are true
|
||||
for (u32 iCon = 0; iCon < mVolumeConditions.size(); iCon++)
|
||||
for (u32 LinkIdx = 0; LinkIdx < mVolumeConditions.size(); LinkIdx++)
|
||||
{
|
||||
if (mVolumeConditions[iCon].Value == Val)
|
||||
return iCon;
|
||||
if (mVolumeConditions[LinkIdx].Value == Val)
|
||||
return LinkIdx;
|
||||
}
|
||||
|
||||
if (LogErrors)
|
||||
@@ -122,37 +140,7 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
|
||||
return -1;
|
||||
}
|
||||
|
||||
TStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<TStringProperty*, eStringProperty>(pProperties, mNameIDString);
|
||||
}
|
||||
|
||||
TVector3Property* CScriptTemplate::FindPosition(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mPositionIDString);
|
||||
}
|
||||
|
||||
TVector3Property* CScriptTemplate::FindRotation(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mRotationIDString);
|
||||
}
|
||||
|
||||
TVector3Property* CScriptTemplate::FindScale(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mScaleIDString);
|
||||
}
|
||||
|
||||
TBoolProperty* CScriptTemplate::FindActive(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<TBoolProperty*, eBoolProperty>(pProperties, mActiveIDString);
|
||||
}
|
||||
|
||||
CPropertyStruct* CScriptTemplate::FindLightParameters(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CPropertyStruct*, eStructProperty>(pProperties, mLightParametersIDString);
|
||||
}
|
||||
|
||||
CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame)
|
||||
CResource* CScriptTemplate::FindDisplayAsset(void* pPropertyData, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame)
|
||||
{
|
||||
rOutCharIndex = -1;
|
||||
rOutAnimIndex = -1;
|
||||
@@ -170,25 +158,28 @@ CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32&
|
||||
// Property
|
||||
else
|
||||
{
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IPropertyNew* pProp = mpProperties->ChildByIDString(it->AssetLocation);
|
||||
|
||||
if (it->AssetType == SEditorAsset::eAnimParams && pProp->Type() == eCharacterProperty)
|
||||
if (it->AssetType == SEditorAsset::eAnimParams && pProp->Type() == EPropertyTypeNew::AnimationSet)
|
||||
{
|
||||
TCharacterProperty *pChar = static_cast<TCharacterProperty*>(pProp);
|
||||
pRes = pChar->Get().AnimSet();
|
||||
CAnimationSetProperty* pAnimSet = TPropCast<CAnimationSetProperty>(pProp);
|
||||
CAnimationParameters Params = pAnimSet->Value(pPropertyData);
|
||||
pRes = Params.AnimSet();
|
||||
|
||||
if (pRes)
|
||||
{
|
||||
u32 MaxNumChars = static_cast<CAnimSet*>(pRes)->NumCharacters();
|
||||
rOutCharIndex = (it->ForceNodeIndex >= 0 && it->ForceNodeIndex < (s32) MaxNumChars ? it->ForceNodeIndex : pChar->Get().CharacterIndex());
|
||||
rOutAnimIndex = pChar->Get().AnimIndex();
|
||||
rOutCharIndex = (it->ForceNodeIndex >= 0 && it->ForceNodeIndex < (s32) MaxNumChars ? it->ForceNodeIndex : Params.CharacterIndex());
|
||||
rOutAnimIndex = Params.AnimIndex();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
TAssetProperty *pAsset = static_cast<TAssetProperty*>(pProp);
|
||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(pAsset->Get());
|
||||
ASSERT(pProp->Type() == EPropertyTypeNew::Asset);
|
||||
CAssetProperty* pAsset = TPropCast<CAssetProperty>(pProp);
|
||||
CAssetID ID = pAsset->Value(pPropertyData);
|
||||
CResourceEntry *pEntry = gpResourceStore->FindEntry( ID );
|
||||
if (pEntry) pRes = pEntry->Load();
|
||||
}
|
||||
}
|
||||
@@ -205,7 +196,7 @@ CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32&
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties)
|
||||
CCollisionMeshGroup* CScriptTemplate::FindCollision(void* pPropertyData)
|
||||
{
|
||||
for (auto it = mAssets.begin(); it != mAssets.end(); it++)
|
||||
{
|
||||
@@ -219,12 +210,12 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties
|
||||
// Property
|
||||
else
|
||||
{
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IPropertyNew* pProp = mpProperties->ChildByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eAssetProperty)
|
||||
if (pProp->Type() == EPropertyTypeNew::Asset)
|
||||
{
|
||||
TAssetProperty *pAsset = static_cast<TAssetProperty*>(pProp);
|
||||
pRes = gpResourceStore->LoadResource( pAsset->Get(), eDynamicCollision );
|
||||
CAssetProperty* pAsset = TPropCast<CAssetProperty>(pProp);
|
||||
pRes = gpResourceStore->LoadResource( pAsset->Value(pPropertyData), eDynamicCollision );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef CSCRIPTTEMPLATE_H
|
||||
#define CSCRIPTTEMPLATE_H
|
||||
|
||||
#include "IPropertyTemplate.h"
|
||||
#include "IProperty.h"
|
||||
#include "Core/Resource/Script/Property/Properties.h"
|
||||
#include "EPropertyType.h"
|
||||
#include "EVolumeShape.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
@@ -12,6 +11,7 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
class CMasterTemplate;
|
||||
class CScriptObject;
|
||||
typedef TString TIDString;
|
||||
|
||||
@@ -64,10 +64,9 @@ private:
|
||||
s32 ForceNodeIndex; // Force animsets to use specific node instead of one from property
|
||||
};
|
||||
|
||||
CMasterTemplate *mpMaster;
|
||||
CStructTemplate *mpBaseStruct;
|
||||
CMasterTemplate* mpMaster;
|
||||
std::unique_ptr<CStructPropertyNew> mpProperties;
|
||||
std::list<CScriptObject*> mObjectList;
|
||||
TString mTemplateName;
|
||||
std::vector<TString> mModules;
|
||||
TString mSourceFile;
|
||||
u32 mObjectID;
|
||||
@@ -80,6 +79,14 @@ private:
|
||||
TIDString mScaleIDString;
|
||||
TIDString mActiveIDString;
|
||||
TIDString mLightParametersIDString;
|
||||
|
||||
CStringProperty* mpNameProperty;
|
||||
CVectorProperty* mpPositionProperty;
|
||||
CVectorProperty* mpRotationProperty;
|
||||
CVectorProperty* mpScaleProperty;
|
||||
CBoolProperty* mpActiveProperty;
|
||||
CStructPropertyNew* mpLightParametersProperty;
|
||||
|
||||
std::vector<SEditorAsset> mAssets;
|
||||
std::vector<SAttachment> mAttachments;
|
||||
|
||||
@@ -102,44 +109,38 @@ private:
|
||||
public:
|
||||
CScriptTemplate(CMasterTemplate *pMaster);
|
||||
~CScriptTemplate();
|
||||
void PostLoad();
|
||||
EGame Game() const;
|
||||
|
||||
// Property Fetching
|
||||
EVolumeShape VolumeShape(CScriptObject *pObj);
|
||||
float VolumeScale(CScriptObject *pObj);
|
||||
TStringProperty* FindInstanceName(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindPosition(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindRotation(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindScale(CPropertyStruct *pProperties);
|
||||
TBoolProperty* FindActive(CPropertyStruct *pProperties);
|
||||
CPropertyStruct* FindLightParameters(CPropertyStruct *pProperties);
|
||||
CResource* FindDisplayAsset(CPropertyStruct *pProperties, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame);
|
||||
CCollisionMeshGroup* FindCollision(CPropertyStruct *pProperties);
|
||||
CResource* FindDisplayAsset(void* pPropertyData, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame);
|
||||
CCollisionMeshGroup* FindCollision(void* pPropertyData);
|
||||
|
||||
// Accessors
|
||||
inline CMasterTemplate* MasterTemplate() const { return mpMaster; }
|
||||
inline TString Name() const { return mTemplateName; }
|
||||
inline TString Name() const { return mpProperties->Name(); }
|
||||
inline ERotationType RotationType() const { return mRotationType; }
|
||||
inline EScaleType ScaleType() const { return mScaleType; }
|
||||
inline float PreviewScale() const { return mPreviewScale; }
|
||||
inline u32 ObjectID() const { return mObjectID; }
|
||||
inline bool IsVisible() const { return mVisible; }
|
||||
inline TString SourceFile() const { return mSourceFile; }
|
||||
inline CStructTemplate* BaseStruct() const { return mpBaseStruct; }
|
||||
inline CStructPropertyNew* Properties() const { return mpProperties.get(); }
|
||||
inline u32 NumAttachments() const { return mAttachments.size(); }
|
||||
const SAttachment& Attachment(u32 Index) const { return mAttachments[Index]; }
|
||||
const std::vector<TString>& RequiredModules() const { return mModules; }
|
||||
|
||||
inline bool HasName() const { return !mNameIDString.IsEmpty(); }
|
||||
inline bool HasPosition() const { return !mPositionIDString.IsEmpty(); }
|
||||
inline bool HasRotation() const { return !mRotationIDString.IsEmpty(); }
|
||||
inline bool HasScale() const { return !mScaleIDString.IsEmpty(); }
|
||||
inline bool HasActive() const { return !mActiveIDString.IsEmpty(); }
|
||||
inline CStringProperty* NameProperty() const { return mpNameProperty; }
|
||||
inline CVectorProperty* PositionProperty() const { return mpPositionProperty; }
|
||||
inline CVectorProperty* RotationProperty() const { return mpRotationProperty; }
|
||||
inline CVectorProperty* ScaleProperty() const { return mpScaleProperty; }
|
||||
inline CBoolProperty* ActiveProperty() const { return mpActiveProperty; }
|
||||
inline CStructPropertyNew* LightParametersProperty() const { return mpLightParametersProperty; }
|
||||
|
||||
inline void SetVisible(bool Visible) { mVisible = Visible; }
|
||||
|
||||
inline void DebugPrintProperties() { mpBaseStruct->DebugPrintProperties(""); }
|
||||
|
||||
// Object Tracking
|
||||
u32 NumObjects() const;
|
||||
const std::list<CScriptObject*>& ObjectList() const;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef EPROPERTYTYPE
|
||||
#define EPROPERTYTYPE
|
||||
|
||||
#include "IPropertyNew.h"
|
||||
|
||||
#if 0
|
||||
#include <Common/TString.h>
|
||||
|
||||
enum EPropertyType
|
||||
@@ -24,11 +27,12 @@ enum EPropertyType
|
||||
eUnknownProperty,
|
||||
eInvalidProperty
|
||||
};
|
||||
#endif
|
||||
|
||||
// functions defined in IPropertyTemplate.cpp
|
||||
EPropertyType PropStringToPropEnum(TString Prop);
|
||||
TString PropEnumToPropString(EPropertyType Prop);
|
||||
const char* HashablePropTypeName(EPropertyType Prop);
|
||||
EPropertyTypeNew PropStringToPropEnum(TString Prop);
|
||||
TString PropEnumToPropString(EPropertyTypeNew Prop);
|
||||
const char* HashablePropTypeName(EPropertyTypeNew Prop);
|
||||
|
||||
#endif // EPROPERTYTYPE
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyTemplate.h"
|
||||
|
||||
#if 0
|
||||
// ************ IProperty ************
|
||||
bool IProperty::IsInArray() const
|
||||
{
|
||||
@@ -241,3 +242,4 @@ TString CArrayProperty::ElementName() const
|
||||
{
|
||||
return static_cast<CArrayTemplate*>(Template())->ElementName();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef IPROPERTY
|
||||
#define IPROPERTY
|
||||
|
||||
#if 0
|
||||
#include "EPropertyType.h"
|
||||
#include "IPropertyValue.h"
|
||||
#include "Core/Resource/CResource.h"
|
||||
@@ -297,6 +298,6 @@ PropertyClass* TPropCast(IProperty *pProp)
|
||||
{
|
||||
return (pProp && pProp->Type() == PropertyClass::StaticType() ? static_cast<PropertyClass*>(pProp) : nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // IPROPERTY
|
||||
|
||||
|
||||
364
src/Core/Resource/Script/IPropertyNew.cpp
Normal file
364
src/Core/Resource/Script/IPropertyNew.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
#include "IPropertyNew.h"
|
||||
#include "Property/CAssetProperty.h"
|
||||
#include "Property/CArrayProperty.h"
|
||||
#include "Property/CEnumProperty.h"
|
||||
#include "Property/CFlagsProperty.h"
|
||||
#include "Property/CPointerProperty.h"
|
||||
|
||||
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||
#include "Core/Resource/Script/CScriptTemplate.h"
|
||||
|
||||
/** IPropertyNew */
|
||||
IPropertyNew::IPropertyNew()
|
||||
: mpParent( nullptr )
|
||||
, mpPointerParent( nullptr )
|
||||
, mpArchetype( nullptr )
|
||||
, mOffset( -1 )
|
||||
, mID( -1 )
|
||||
, mCookPreference( ECookPreferenceNew::Default )
|
||||
, mMinVersion( 0.0f )
|
||||
, mMaxVersion( FLT_MAX )
|
||||
{}
|
||||
|
||||
void IPropertyNew::_CalcOffset()
|
||||
{
|
||||
// For standard properties, append to the end of the parent.
|
||||
bool IsRootArrayArchetype = (IsArrayArchetype() && TPropCast<CArrayProperty>(mpParent) != nullptr);
|
||||
|
||||
if (mpParent && !IsRootArrayArchetype)
|
||||
{
|
||||
// When we have a parent, our data is usually located inside the parent's property data. So we want to
|
||||
// position ourself at the end of the parent's existing children so we don't overlap any other properties.
|
||||
IPropertyNew* pLastChild = (mpParent->mChildren.empty() ? nullptr : mpParent->mChildren.back());
|
||||
|
||||
if (pLastChild)
|
||||
{
|
||||
mOffset = pLastChild->mOffset + pLastChild->DataSize();
|
||||
}
|
||||
else if (mpParent != mpPointerParent)
|
||||
{
|
||||
mOffset = mpParent->mOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
mOffset = 0;
|
||||
}
|
||||
|
||||
mOffset = ALIGN(mOffset, DataAlignment());
|
||||
}
|
||||
// Array archetypes are accessed differently because they have no way of knowing
|
||||
// which array index is meant to be accessed. So the offset is 0 and the caller
|
||||
// is responsible for passing in a pointer to the correct array item.
|
||||
else
|
||||
{
|
||||
mOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 IPropertyNew::_GetOffset() const
|
||||
{
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
void IPropertyNew::_ClearChildren()
|
||||
{
|
||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
delete mChildren[ChildIdx];
|
||||
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
IPropertyNew::~IPropertyNew()
|
||||
{
|
||||
// Remove from archetype
|
||||
if( mpArchetype != nullptr )
|
||||
{
|
||||
NBasics::VectorRemoveOne(mpArchetype->mSubInstances, this);
|
||||
}
|
||||
|
||||
// If this is an archetype, all our sub-instances should have destructed first.
|
||||
if( IsArchetype() )
|
||||
{
|
||||
ASSERT(mSubInstances.empty());
|
||||
}
|
||||
|
||||
// Delete children
|
||||
_ClearChildren();
|
||||
}
|
||||
|
||||
const char* IPropertyNew::HashableTypeName() const
|
||||
{
|
||||
return PropEnumToHashableTypeName( Type() );
|
||||
}
|
||||
|
||||
void* IPropertyNew::GetChildDataPointer(void* pPropertyData) const
|
||||
{
|
||||
return pPropertyData;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void IPropertyNew::Serialize(IArchive& rArc)
|
||||
{
|
||||
if (rArc.Game() <= ePrime)
|
||||
{
|
||||
rArc << SERIAL("Name", mName);
|
||||
}
|
||||
|
||||
rArc << SERIAL_HEX("ID", mID)
|
||||
<< SERIAL("Description", mDescription)
|
||||
<< SERIAL("CookPref", mCookPref)
|
||||
<< SERIAL("MinVersion", mMinVersion)
|
||||
<< SERIAL("MaxVersion", mMaxVersion);
|
||||
|
||||
// Children don't get serialized for most property types
|
||||
}
|
||||
#endif
|
||||
|
||||
void IPropertyNew::InitFromArchetype(IPropertyNew* pOther)
|
||||
{
|
||||
//@todo maybe somehow use Serialize for this instead?
|
||||
mpArchetype = pOther;
|
||||
mFlags = pOther->mFlags & ~EPropertyFlag::ArchetypeCopyFlags;
|
||||
mID = pOther->mID;
|
||||
mName = pOther->mName;
|
||||
mDescription = pOther->mDescription;
|
||||
mSuffix = pOther->mSuffix;
|
||||
mCookPreference = pOther->mCookPreference;
|
||||
mMinVersion = pOther->mMinVersion;
|
||||
mMaxVersion = pOther->mMaxVersion;
|
||||
|
||||
// Copy children
|
||||
_ClearChildren();
|
||||
|
||||
for (u32 ChildIdx = 0; ChildIdx < pOther->mChildren.size(); ChildIdx++)
|
||||
{
|
||||
CreateCopy( pOther->mChildren[ChildIdx], this );
|
||||
}
|
||||
}
|
||||
|
||||
TString IPropertyNew::GetTemplateFileName()
|
||||
{
|
||||
if (mpScriptTemplate)
|
||||
{
|
||||
return mpScriptTemplate->SourceFile();
|
||||
}
|
||||
else if (IsArchetype())
|
||||
{
|
||||
IPropertyNew* pRootParent = RootParent();
|
||||
ASSERT(pRootParent != this);
|
||||
return pRootParent->GetTemplateFileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mpArchetype->GetTemplateFileName();
|
||||
}
|
||||
}
|
||||
|
||||
void* IPropertyNew::RawValuePtr(void* pData) const
|
||||
{
|
||||
// For array archetypes, the caller needs to provide the pointer to the correct array item
|
||||
if (IsArrayArchetype())
|
||||
return pData;
|
||||
|
||||
void* pBasePtr = (mpPointerParent ? mpPointerParent->GetChildDataPointer(pData) : pData);
|
||||
return ((char*)pBasePtr + mOffset);
|
||||
}
|
||||
|
||||
IPropertyNew* IPropertyNew::ChildByID(u32 ID) const
|
||||
{
|
||||
for (u32 ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
if (mChildren[ChildIdx]->mID == ID)
|
||||
return mChildren[ChildIdx];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IPropertyNew* IPropertyNew::ChildByIDString(const TIDString& rkIdString)
|
||||
{
|
||||
// String must contain at least one ID!
|
||||
// some ID strings are formatted with 8 characters and some with 2 (plus the beginning "0x")
|
||||
ASSERT(rkIdString.Size() >= 4);
|
||||
|
||||
u32 IDEndPos = rkIdString.IndexOf(':');
|
||||
u32 NextChildID = -1;
|
||||
|
||||
if (IDEndPos == -1)
|
||||
NextChildID = rkIdString.ToInt32();
|
||||
else
|
||||
NextChildID = rkIdString.SubString(2, IDEndPos - 2).ToInt32();
|
||||
|
||||
if (NextChildID == 0xFFFFFFFF)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IPropertyNew* pNextChild = ChildByID(NextChildID);
|
||||
|
||||
// Check if we need to recurse
|
||||
if (IDEndPos != -1)
|
||||
{
|
||||
return pNextChild->ChildByIDString(rkIdString.ChopFront(IDEndPos + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return pNextChild;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPropertyNew::ShouldCook(void*pPropertyData) const
|
||||
{
|
||||
switch (mCookPreference)
|
||||
{
|
||||
case ECookPreferenceNew::Always:
|
||||
return true;
|
||||
|
||||
case ECookPreferenceNew::Never:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return (Game() < eReturns ? true : !MatchesDefault(pPropertyData));
|
||||
}
|
||||
}
|
||||
|
||||
void IPropertyNew::SetName(const TString& rkNewName)
|
||||
{
|
||||
mName = rkNewName;
|
||||
mFlags.ClearFlag(EPropertyFlag::HasCachedNameCheck);
|
||||
}
|
||||
|
||||
void IPropertyNew::SetDescription(const TString& rkNewDescription)
|
||||
{
|
||||
mDescription = rkNewDescription;
|
||||
}
|
||||
|
||||
void IPropertyNew::SetSuffix(const TString& rkNewSuffix)
|
||||
{
|
||||
mSuffix = rkNewSuffix;
|
||||
}
|
||||
|
||||
bool IPropertyNew::HasAccurateName()
|
||||
{
|
||||
if (!mFlags.HasFlag(EPropertyFlag::HasCachedNameCheck))
|
||||
{
|
||||
CCRC32 Hash;
|
||||
Hash.Hash(*mName);
|
||||
Hash.Hash(HashableTypeName());
|
||||
u32 GeneratedID = Hash.Digest();
|
||||
|
||||
if (GeneratedID == mID)
|
||||
mFlags.SetFlag( EPropertyFlag::HasCorrectPropertyName );
|
||||
else
|
||||
mFlags.ClearFlag( EPropertyFlag::HasCorrectPropertyName );
|
||||
|
||||
mFlags.SetFlag(EPropertyFlag::HasCachedNameCheck);
|
||||
}
|
||||
|
||||
return mFlags.HasFlag( EPropertyFlag::HasCorrectPropertyName );
|
||||
}
|
||||
|
||||
/** IPropertyNew Accessors */
|
||||
EGame IPropertyNew::Game() const
|
||||
{
|
||||
return mpMasterTemplate->Game();
|
||||
}
|
||||
|
||||
IPropertyNew* IPropertyNew::Create(EPropertyTypeNew Type,
|
||||
IPropertyNew* pParent,
|
||||
CMasterTemplate* pMaster,
|
||||
CScriptTemplate* pScript,
|
||||
bool CallPostInit /*= true*/)
|
||||
{
|
||||
IPropertyNew* pOut = nullptr;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case EPropertyTypeNew::Bool: pOut = new CBoolProperty; break;
|
||||
case EPropertyTypeNew::Byte: pOut = new CByteProperty; break;
|
||||
case EPropertyTypeNew::Short: pOut = new CShortProperty; break;
|
||||
case EPropertyTypeNew::Int: pOut = new CIntProperty; break;
|
||||
case EPropertyTypeNew::Float: pOut = new CFloatProperty; break;
|
||||
case EPropertyTypeNew::Choice: pOut = new CChoiceProperty; break;
|
||||
case EPropertyTypeNew::Enum: pOut = new CEnumProperty; break;
|
||||
case EPropertyTypeNew::Flags: pOut = new CFlagsProperty; break;
|
||||
case EPropertyTypeNew::String: pOut = new CStringProperty; break;
|
||||
case EPropertyTypeNew::Vector: pOut = new CVectorProperty; break;
|
||||
case EPropertyTypeNew::Color: pOut = new CColorProperty; break;
|
||||
case EPropertyTypeNew::Asset: pOut = new CAssetProperty; break;
|
||||
case EPropertyTypeNew::Sound: pOut = new CSoundProperty; break;
|
||||
case EPropertyTypeNew::Animation: pOut = new CAnimationProperty; break;
|
||||
case EPropertyTypeNew::AnimationSet: pOut = new CAnimationSetProperty; break;
|
||||
case EPropertyTypeNew::Sequence: pOut = new CSequenceProperty; break;
|
||||
case EPropertyTypeNew::Spline: pOut = new CSplineProperty; break;
|
||||
case EPropertyTypeNew::Guid: pOut = new CGuidProperty; break;
|
||||
case EPropertyTypeNew::Pointer: pOut = new CPointerProperty; break;
|
||||
case EPropertyTypeNew::Struct: pOut = new CStructPropertyNew; break;
|
||||
case EPropertyTypeNew::Array: pOut = new CArrayProperty; break;
|
||||
}
|
||||
|
||||
if (!pOut)
|
||||
{
|
||||
// this shouldn't be possible! unhandled type! someone fucked up!
|
||||
ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Set parent and offset
|
||||
pOut->mpParent = pParent;
|
||||
|
||||
if (pParent)
|
||||
{
|
||||
pOut->mFlags = pParent->mFlags & EPropertyFlag::InheritableFlags;
|
||||
|
||||
if (pParent->IsPointerType())
|
||||
{
|
||||
pOut->mpPointerParent = pParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOut->mpPointerParent = pParent->mpPointerParent;
|
||||
}
|
||||
}
|
||||
|
||||
// Set other metadata
|
||||
pOut->mpMasterTemplate = pMaster;
|
||||
pOut->mpScriptTemplate = pScript;
|
||||
pOut->_CalcOffset();
|
||||
|
||||
// Add to the parent's array. This needs to be done -after- we calculate offset, as adding a child to
|
||||
// the parent property will change the offset that gets calculated.
|
||||
if (pParent)
|
||||
{
|
||||
pParent->mChildren.push_back(pOut);
|
||||
}
|
||||
|
||||
if (CallPostInit)
|
||||
{
|
||||
pOut->PostInitialize();
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
IPropertyNew* IPropertyNew::CreateCopy(IPropertyNew* pArchetype,
|
||||
IPropertyNew* pParent,
|
||||
bool CallPostInit /*= true*/)
|
||||
{
|
||||
// Note this is mainly going to be used to create copies from struct/enum/flag archetype properties.
|
||||
// Properties that have archetypes will never be the root property of a script template, and there
|
||||
// is no case where we will be creating archetypes outside this context. As such, pParent should
|
||||
// always be valid.
|
||||
ASSERT(pParent != nullptr);
|
||||
|
||||
IPropertyNew* pOut = Create(pArchetype->Type(), pParent, pParent->mpMasterTemplate, pParent->mpScriptTemplate, false);
|
||||
pOut->InitFromArchetype(pArchetype);
|
||||
pArchetype->mSubInstances.push_back(pOut);
|
||||
|
||||
if (CallPostInit)
|
||||
{
|
||||
pOut->PostInitialize();
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
432
src/Core/Resource/Script/IPropertyNew.h
Normal file
432
src/Core/Resource/Script/IPropertyNew.h
Normal file
@@ -0,0 +1,432 @@
|
||||
#ifndef IPROPERTYNEW_H
|
||||
#define IPROPERTYNEW_H
|
||||
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
#include <Common/Common.h>
|
||||
#include <Math/CVector3f.h>
|
||||
#include <Math/MathUtil.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
/** Forward declares */
|
||||
class CMasterTemplate;
|
||||
class CScriptTemplate;
|
||||
class CStructPropertyNew;
|
||||
|
||||
/** Typedefs */
|
||||
typedef TString TIDString;
|
||||
|
||||
/** Property flags */
|
||||
enum class EPropertyFlag : u32
|
||||
{
|
||||
/** Property is an archetype (a template for other properties to copy from) */
|
||||
IsArchetype = 0x1,
|
||||
/** Property is an array archetype (a template for elements of an array property) */
|
||||
IsArrayArchetype = 0x2,
|
||||
/** This property and all its children are a single unit and do not have individual property IDs, sizes, etc. */
|
||||
IsAtomic = 0x4,
|
||||
/** We have cached whether the property name is correct */
|
||||
HasCachedNameCheck = 0x40000000,
|
||||
/** The name of the property is a match for the property ID hash */
|
||||
HasCorrectPropertyName = 0x80000000,
|
||||
|
||||
/** Flags that are left intact when copying from an archetype */
|
||||
ArchetypeCopyFlags = EPropertyFlag::IsAtomic,
|
||||
/** Flags that are inheritable from parent */
|
||||
InheritableFlags = EPropertyFlag::IsArchetype | EPropertyFlag::IsArrayArchetype | EPropertyFlag::IsAtomic,
|
||||
};
|
||||
DECLARE_FLAGS_ENUMCLASS(EPropertyFlag, FPropertyFlags)
|
||||
|
||||
/** Property type */
|
||||
enum class EPropertyTypeNew
|
||||
{
|
||||
Bool = FOURCC('BOOL'),
|
||||
Byte = FOURCC('BYTE'),
|
||||
Short = FOURCC('SHRT'),
|
||||
Int = FOURCC('INT '),
|
||||
Float = FOURCC('REAL'),
|
||||
Choice = FOURCC('CHOI'),
|
||||
Enum = FOURCC('ENUM'),
|
||||
Flags = FOURCC('FLAG'),
|
||||
String = FOURCC('STRG'),
|
||||
Vector = FOURCC('VECT'),
|
||||
Color = FOURCC('COLR'),
|
||||
Asset = FOURCC('ASST'),
|
||||
Sound = FOURCC('SOND'),
|
||||
Animation = FOURCC('ANIM'),
|
||||
AnimationSet = FOURCC('ANMS'),
|
||||
Sequence = FOURCC('SQNC'),
|
||||
Spline = FOURCC('SPLN'),
|
||||
Guid = FOURCC('GUID'),
|
||||
Pointer = FOURCC('PNTR'),
|
||||
Struct = FOURCC('STRC'),
|
||||
Array = FOURCC('ARRY'),
|
||||
Invalid = FOURCC('INVD')
|
||||
};
|
||||
inline void Serialize(IArchive& rArc, EPropertyTypeNew& rType)
|
||||
{
|
||||
rArc.SerializePrimitive( (CFourCC&) rType );
|
||||
}
|
||||
|
||||
inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case EPropertyTypeNew::Bool: return "bool";
|
||||
case EPropertyTypeNew::Int: return "int";
|
||||
case EPropertyTypeNew::Float: return "float";
|
||||
case EPropertyTypeNew::Choice: return "choice";
|
||||
case EPropertyTypeNew::Enum: return "enum";
|
||||
case EPropertyTypeNew::Flags: return "Flags";
|
||||
case EPropertyTypeNew::String: return "string";
|
||||
case EPropertyTypeNew::Vector: return "Vector";
|
||||
case EPropertyTypeNew::Color: return "Color";
|
||||
case EPropertyTypeNew::Asset: return "asset";
|
||||
case EPropertyTypeNew::Sound: return "sound";
|
||||
case EPropertyTypeNew::Spline: return "spline";
|
||||
case EPropertyTypeNew::Guid: return "guid";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
/** Enum that describes when/how properties should be cooked out */
|
||||
enum class ECookPreferenceNew
|
||||
{
|
||||
Default,
|
||||
Always,
|
||||
Never
|
||||
};
|
||||
inline void Serialize(IArchive& rArc, ECookPreferenceNew& rPref)
|
||||
{
|
||||
rArc.SerializePrimitive( (u32&) rPref );
|
||||
}
|
||||
|
||||
/** New property class */
|
||||
class IPropertyNew
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CPropertyFactory;
|
||||
|
||||
protected:
|
||||
/** Flags */
|
||||
FPropertyFlags mFlags;
|
||||
|
||||
/** Parent property */
|
||||
IPropertyNew* mpParent;
|
||||
|
||||
/** Pointer parent; if non-null, this parent needs to be dereferenced to access the correct
|
||||
* memory region that our property data is stored in */
|
||||
IPropertyNew* mpPointerParent;
|
||||
|
||||
/** Archetype property; source property that we copied metadata from */
|
||||
IPropertyNew* mpArchetype;
|
||||
|
||||
/** Sub-instances of archetype properties. For non-archetypes, will be empty. @todo better
|
||||
* method of storing this? maybe a linked list? */
|
||||
std::vector<IPropertyNew*> mSubInstances;
|
||||
|
||||
/** Child properties; these appear underneath this property on the UI */
|
||||
std::vector<IPropertyNew*> mChildren;
|
||||
|
||||
/** Master template for the game this property belongs to.
|
||||
* Cannot be derived from mpScriptTemplate because mpScriptTemplate is null sometimes */
|
||||
CMasterTemplate* mpMasterTemplate;
|
||||
|
||||
/** Script template that this property belongs to. Null for struct/enum/flag archetypes. */
|
||||
CScriptTemplate* mpScriptTemplate;
|
||||
|
||||
/** Offset of this property within the property block */
|
||||
u32 mOffset;
|
||||
|
||||
/** Property ID. This ID is used to uniquely identify this property within this struct. */
|
||||
u32 mID;
|
||||
|
||||
/** Property metadata */
|
||||
TString mName;
|
||||
TString mDescription;
|
||||
TString mSuffix;
|
||||
ECookPreferenceNew mCookPreference;
|
||||
|
||||
/** Min/max allowed version number. These numbers correspond to the game's internal build number.
|
||||
* This is not used yet but in the future it can be used to configure certain properties to only
|
||||
* show up when certain versions of the game are being edited. The default values allow the
|
||||
* property to show up in all versions. */
|
||||
float mMinVersion;
|
||||
float mMaxVersion;
|
||||
|
||||
/** Private constructor - use static methods to instantiate */
|
||||
IPropertyNew();
|
||||
void _CalcOffset();
|
||||
u32 _GetOffset() const;
|
||||
void _ClearChildren();
|
||||
|
||||
/** Called after property is created and fully initialized */
|
||||
virtual void PostInitialize() {}
|
||||
|
||||
public:
|
||||
virtual ~IPropertyNew();
|
||||
|
||||
/** Interface */
|
||||
virtual EPropertyTypeNew Type() const = 0;
|
||||
virtual u32 DataSize() const = 0;
|
||||
virtual u32 DataAlignment() const = 0;
|
||||
virtual void Construct(void* pData) const = 0;
|
||||
virtual void Destruct(void* pData) const = 0;
|
||||
virtual bool MatchesDefault(void* pData) const = 0;
|
||||
virtual void RevertToDefault(void* pData) const = 0;
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const = 0;
|
||||
|
||||
virtual void PropertyValueChanged(void* pPropertyData) {}
|
||||
virtual bool IsNumericalType() const { return false; }
|
||||
virtual bool IsPointerType() const { return false; }
|
||||
virtual TString ValueAsString(void* pData) const { return ""; }
|
||||
|
||||
virtual const char* HashableTypeName() const;
|
||||
virtual void* GetChildDataPointer(void* pPropertyData) const;
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc);
|
||||
#endif
|
||||
virtual void InitFromArchetype(IPropertyNew* pOther);
|
||||
virtual TString GetTemplateFileName();
|
||||
|
||||
/** Utility methods */
|
||||
void* RawValuePtr(void* pData) const;
|
||||
IPropertyNew* ChildByID(u32 ID) const;
|
||||
IPropertyNew* ChildByIDString(const TIDString& rkIdString);
|
||||
bool ShouldCook(void* pPropertyData) const;
|
||||
void SetName(const TString& rkNewName);
|
||||
void SetDescription(const TString& rkNewDescription);
|
||||
void SetSuffix(const TString& rkNewSuffix);
|
||||
bool HasAccurateName();
|
||||
|
||||
/** Accessors */
|
||||
EGame Game() const;
|
||||
inline ECookPreferenceNew CookPreference() const;
|
||||
inline u32 NumChildren() const;
|
||||
inline IPropertyNew* ChildByIndex(u32 ChildIndex) const;
|
||||
inline IPropertyNew* Parent() const;
|
||||
inline IPropertyNew* RootParent();
|
||||
inline IPropertyNew* Archetype() const;
|
||||
inline CScriptTemplate* ScriptTemplate() const;
|
||||
inline CMasterTemplate* MasterTemplate() const;
|
||||
inline TString Name() const;
|
||||
inline TString Description() const;
|
||||
inline TString Suffix() const;
|
||||
inline TIDString IDString(bool FullyQualified) const;
|
||||
inline u32 ID() const;
|
||||
|
||||
inline bool IsArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArchetype); }
|
||||
inline bool IsArrayArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArrayArchetype); }
|
||||
inline bool IsAtomic() const { return mFlags.HasFlag(EPropertyFlag::IsAtomic); }
|
||||
|
||||
/** Create */
|
||||
static IPropertyNew* Create(EPropertyTypeNew Type,
|
||||
IPropertyNew* pParent,
|
||||
CMasterTemplate* pMaster,
|
||||
CScriptTemplate* pScript,
|
||||
bool CallPostInit = true);
|
||||
|
||||
static IPropertyNew* CreateCopy(IPropertyNew* pArchetype,
|
||||
IPropertyNew* pParent,
|
||||
bool CallPostInit = true);
|
||||
};
|
||||
|
||||
inline ECookPreferenceNew IPropertyNew::CookPreference() const
|
||||
{
|
||||
return mCookPreference;
|
||||
}
|
||||
|
||||
inline u32 IPropertyNew::NumChildren() const
|
||||
{
|
||||
return mChildren.size();
|
||||
}
|
||||
|
||||
inline IPropertyNew* IPropertyNew::ChildByIndex(u32 ChildIndex) const
|
||||
{
|
||||
ASSERT(ChildIndex >= 0 && ChildIndex < mChildren.size());
|
||||
return mChildren[ChildIndex];
|
||||
}
|
||||
|
||||
inline IPropertyNew* IPropertyNew::Parent() const
|
||||
{
|
||||
return mpParent;
|
||||
}
|
||||
|
||||
inline IPropertyNew* IPropertyNew::RootParent()
|
||||
{
|
||||
IPropertyNew* pParent = Parent();
|
||||
IPropertyNew* pOut = this;
|
||||
|
||||
while (pParent)
|
||||
{
|
||||
pOut = pParent;
|
||||
pParent = pParent->Parent();
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
inline IPropertyNew* IPropertyNew::Archetype() const
|
||||
{
|
||||
return mpArchetype;
|
||||
}
|
||||
|
||||
inline CScriptTemplate* IPropertyNew::ScriptTemplate() const
|
||||
{
|
||||
return mpScriptTemplate;
|
||||
}
|
||||
|
||||
inline CMasterTemplate* IPropertyNew::MasterTemplate() const
|
||||
{
|
||||
return mpMasterTemplate;
|
||||
}
|
||||
|
||||
inline TString IPropertyNew::Name() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
inline TString IPropertyNew::Description() const
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
inline TString IPropertyNew::Suffix() const
|
||||
{
|
||||
return mSuffix;
|
||||
}
|
||||
|
||||
inline TString IPropertyNew::IDString(bool FullyQualified) const
|
||||
{
|
||||
if (FullyQualified && mpParent != nullptr)
|
||||
return mpParent->IDString(FullyQualified) + ":" + TString::HexString(mID);
|
||||
else
|
||||
return TString::HexString(mID);
|
||||
}
|
||||
|
||||
inline u32 IPropertyNew::ID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
template<typename PropType, EPropertyTypeNew PropEnum>
|
||||
class TTypedPropertyNew : public IPropertyNew
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
friend class CTemplateLoader;
|
||||
public:
|
||||
typedef PropType ValueType;
|
||||
|
||||
protected:
|
||||
PropType mDefaultValue;
|
||||
|
||||
TTypedPropertyNew()
|
||||
: IPropertyNew()
|
||||
{
|
||||
memset(&mDefaultValue, 0, sizeof(PropType));
|
||||
}
|
||||
|
||||
public:
|
||||
virtual EPropertyTypeNew Type() const { return PropEnum; }
|
||||
virtual u32 DataSize() const { return sizeof(PropType); }
|
||||
virtual u32 DataAlignment() const { return alignof(PropType); }
|
||||
virtual void Construct(void* pData) const { new(ValuePtr(pData)) PropType(mDefaultValue); }
|
||||
virtual void Destruct(void* pData) const { ValueRef(pData).~PropType(); }
|
||||
virtual bool MatchesDefault(void* pData) const { return ValueRef(pData) == mDefaultValue; }
|
||||
virtual void RevertToDefault(void* pData) const { ValueRef(pData) = mDefaultValue; }
|
||||
|
||||
virtual bool CanHaveDefault() const { return true; }
|
||||
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc)
|
||||
{
|
||||
IPropertyNew::Serialize(rArc);
|
||||
rArc << SERIAL("DefaultValue", mDefaultValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||
{
|
||||
IPropertyNew::InitFromArchetype(pOther);
|
||||
mDefaultValue = static_cast<TTypedPropertyNew*>(pOther)->mDefaultValue;
|
||||
}
|
||||
|
||||
inline PropType* ValuePtr(void* pData) const
|
||||
{
|
||||
return (PropType*) RawValuePtr(pData);
|
||||
}
|
||||
|
||||
inline PropType& ValueRef(void* pData) const
|
||||
{
|
||||
return *ValuePtr(pData);
|
||||
}
|
||||
|
||||
inline PropType Value(void* pData) const
|
||||
{
|
||||
return *ValuePtr(pData);
|
||||
}
|
||||
|
||||
inline static EPropertyTypeNew StaticType() { return PropEnum; }
|
||||
};
|
||||
|
||||
template<typename PropType, EPropertyTypeNew PropEnum>
|
||||
class TNumericalPropertyNew : public TTypedPropertyNew<PropType, PropEnum>
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
friend class CTemplateLoader;
|
||||
|
||||
protected:
|
||||
PropType mMinValue;
|
||||
PropType mMaxValue;
|
||||
|
||||
TNumericalPropertyNew()
|
||||
: TTypedPropertyNew()
|
||||
, mMinValue( -1 )
|
||||
, mMaxValue( -1 )
|
||||
{}
|
||||
|
||||
public:
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc)
|
||||
{
|
||||
TTypedPropertyNew::Serialize(rArc);
|
||||
rArc << SERIAL("Min", mMin)
|
||||
<< SERIAL("Max", mMax);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||
{
|
||||
TTypedPropertyNew::InitFromArchetype(pOther);
|
||||
TNumericalPropertyNew* pCastOther = static_cast<TNumericalPropertyNew*>(pOther);
|
||||
mMinValue = pCastOther->mMinValue;
|
||||
mMaxValue = pCastOther->mMaxValue;
|
||||
}
|
||||
|
||||
virtual void PropertyValueChanged(void* pPropertyData)
|
||||
{
|
||||
IPropertyNew::PropertyValueChanged(pPropertyData);
|
||||
|
||||
if (mMinValue >= 0 && mMaxValue >= 0)
|
||||
{
|
||||
PropType& rValue = ValueRef(pPropertyData);
|
||||
rValue = Math::Clamp(mMinValue, mMaxValue, rValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Property casting with dynamic type checking */
|
||||
template<class PropertyClass>
|
||||
inline PropertyClass* TPropCast(IPropertyNew* pProperty)
|
||||
{
|
||||
if (pProperty && pProperty->Type() == PropertyClass::StaticType())
|
||||
{
|
||||
return static_cast<PropertyClass*>(pProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IPROPERTYNEW_H
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <Common/Hash/CCRC32.h>
|
||||
#include <iostream>
|
||||
|
||||
#if 0
|
||||
// ************ IPropertyTemplate ************
|
||||
EGame IPropertyTemplate::Game() const
|
||||
{
|
||||
@@ -250,75 +251,73 @@ void CStructTemplate::DetermineVersionPropertyCounts()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ************ GLOBAL FUNCTIONS ************
|
||||
TString PropEnumToPropString(EPropertyType Prop)
|
||||
TString PropEnumToPropString(EPropertyTypeNew 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 eSoundProperty: return "sound";
|
||||
case eAssetProperty: return "asset";
|
||||
case eStructProperty: return "struct";
|
||||
case eArrayProperty: return "array";
|
||||
case eCharacterProperty: return "character";
|
||||
case eMayaSplineProperty: return "MayaSpline";
|
||||
case eUnknownProperty: return "unknown";
|
||||
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";
|
||||
|
||||
case eInvalidProperty:
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
EPropertyType PropStringToPropEnum(TString Prop)
|
||||
EPropertyTypeNew PropStringToPropEnum(TString Prop)
|
||||
{
|
||||
Prop = Prop.ToLower();
|
||||
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 == "sound") return eSoundProperty;
|
||||
if (Prop == "asset") return eAssetProperty;
|
||||
if (Prop == "struct") return eStructProperty;
|
||||
if (Prop == "array") return eArrayProperty;
|
||||
if (Prop == "character") return eCharacterProperty;
|
||||
if (Prop == "mayaspline") return eMayaSplineProperty;
|
||||
if (Prop == "unknown") return eUnknownProperty;
|
||||
return eInvalidProperty;
|
||||
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(EPropertyType Prop)
|
||||
const char* HashablePropTypeName(EPropertyTypeNew Prop)
|
||||
{
|
||||
// Variants that match Retro's internal type names for generating property IDs. case sensitive
|
||||
switch (Prop)
|
||||
{
|
||||
case eBoolProperty: return "bool";
|
||||
case eLongProperty: return "int";
|
||||
case eEnumProperty: return "enum";
|
||||
case eBitfieldProperty: return "Flags";
|
||||
case eFloatProperty: return "float";
|
||||
case eStringProperty: return "string";
|
||||
case eColorProperty: return "Color";
|
||||
case eVector3Property: return "Vector";
|
||||
case eSoundProperty: return "sound";
|
||||
case eAssetProperty: return "asset";
|
||||
case eMayaSplineProperty: return "spline";
|
||||
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:
|
||||
@@ -327,6 +326,7 @@ const char* HashablePropTypeName(EPropertyType Prop)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// ************ DEBUG ************
|
||||
void CStructTemplate::DebugPrintProperties(TString base)
|
||||
{
|
||||
@@ -343,3 +343,4 @@ void CStructTemplate::DebugPrintProperties(TString base)
|
||||
Log::Write(base + tmp->Name());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef IPROPERTYTEMPLATE
|
||||
#define IPROPERTYTEMPLATE
|
||||
|
||||
#if 0
|
||||
#include "EPropertyType.h"
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyValue.h"
|
||||
@@ -797,6 +798,7 @@ public:
|
||||
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pInstance, pArray);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // IPROPERTYTEMPLATE
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef IPROPERTYVALUE_H
|
||||
#define IPROPERTYVALUE_H
|
||||
|
||||
#if 0
|
||||
#include "EPropertyType.h"
|
||||
#include <Common/CAssetID.h>
|
||||
#include <Common/Log.h>
|
||||
@@ -386,5 +387,6 @@ public:
|
||||
return new CUnknownValue(mValue);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // IPROPERTYVALUE_H
|
||||
|
||||
27
src/Core/Resource/Script/Property/CAnimationProperty.h
Normal file
27
src/Core/Resource/Script/Property/CAnimationProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CANIMATIONPROPERTY_H
|
||||
#define CANIMATIONPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CAnimationProperty : public TTypedPropertyNew< int, EPropertyTypeNew::Animation >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CAnimationProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
||||
{
|
||||
rArc.SerializeHexPrimitive( (u32&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData) const
|
||||
{
|
||||
return TString::HexString( (u32) Value(pData) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CANIMATIONPROPERTY_H
|
||||
22
src/Core/Resource/Script/Property/CAnimationSetProperty.h
Normal file
22
src/Core/Resource/Script/Property/CAnimationSetProperty.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef CANIMATIONSETPROPERTY_H
|
||||
#define CANIMATIONSETPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CAnimationSetProperty : public TTypedPropertyNew< CAnimationParameters, EPropertyTypeNew::AnimationSet >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CAnimationSetProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Value(pData).Serialize(Arc);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CANIMATIONSETPROPERTY_H
|
||||
176
src/Core/Resource/Script/Property/CArrayProperty.h
Normal file
176
src/Core/Resource/Script/Property/CArrayProperty.h
Normal file
@@ -0,0 +1,176 @@
|
||||
#ifndef CARRAYPROPERTY_H
|
||||
#define CARRAYPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
struct SScriptArray
|
||||
{
|
||||
int Count;
|
||||
std::vector<char> Array;
|
||||
|
||||
SScriptArray()
|
||||
: Count(0)
|
||||
{}
|
||||
|
||||
inline bool operator==(const SScriptArray& rkOther) const
|
||||
{
|
||||
return( Count == rkOther.Count && Array == rkOther.Array );
|
||||
}
|
||||
};
|
||||
|
||||
/** 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<int, EPropertyTypeNew::Array>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
/** This class inherits from TTypedPropertyNew<int> in order to expose the array
|
||||
* count value. Outside users can edit this value and we respond by updating the
|
||||
* allocated space, handling destruction/construction, etc.
|
||||
*/
|
||||
IPropertyNew* mpItemArchetype;
|
||||
|
||||
/** Internal functions */
|
||||
SScriptArray& _GetInternalArray(void* pData) const
|
||||
{
|
||||
return *( (SScriptArray*) RawValuePtr(pData) );
|
||||
}
|
||||
|
||||
u32 _InternalArrayCount(void* pPropertyData) const
|
||||
{
|
||||
std::vector<char>& rArray = _GetInternalArray(pPropertyData).Array;
|
||||
return rArray.size() / ItemSize();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual u32 DataSize() const
|
||||
{
|
||||
return sizeof(SScriptArray);
|
||||
}
|
||||
|
||||
virtual u32 DataAlignment() const
|
||||
{
|
||||
return alignof(SScriptArray);
|
||||
}
|
||||
|
||||
virtual void Construct(void* pData) const
|
||||
{
|
||||
new(ValuePtr(pData)) SScriptArray;
|
||||
}
|
||||
|
||||
virtual void Destruct(void* pData) const
|
||||
{
|
||||
RevertToDefault(pData);
|
||||
TTypedPropertyNew::Destruct(pData);
|
||||
}
|
||||
|
||||
virtual bool MatchesDefault(void* pData) const
|
||||
{
|
||||
return ArrayCount(pData) == 0;
|
||||
}
|
||||
|
||||
virtual void RevertToDefault(void* pData) const
|
||||
{
|
||||
Resize(pData, 0);
|
||||
ValueRef(pData) = 0;
|
||||
}
|
||||
|
||||
virtual bool CanHaveDefault() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool IsPointerType() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void* GetChildDataPointer(void* pPropertyData) const
|
||||
{
|
||||
return _GetInternalArray(pPropertyData).Array.data();
|
||||
}
|
||||
|
||||
virtual void PropertyValueChanged(void* pPropertyData)
|
||||
{
|
||||
SScriptArray& rArray = _GetInternalArray(pPropertyData);
|
||||
rArray.Count = Math::Max(rArray.Count, 0);
|
||||
Resize(pPropertyData, rArray.Count);
|
||||
}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
u32 Count = ArrayCount(pData);
|
||||
Arc.SerializePrimitive(Count);
|
||||
|
||||
if (Arc.IsReader())
|
||||
Resize(pData, Count);
|
||||
|
||||
for (u32 ItemIdx = 0; ItemIdx < Count; ItemIdx++)
|
||||
{
|
||||
if (Arc.ParamBegin("ArrayElement"))
|
||||
{
|
||||
void* pItemData = ItemPointer(pData, ItemIdx);
|
||||
mpArchetype->SerializeValue(pItemData, Arc);
|
||||
Arc.ParamEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 ArrayCount(void* pPropertyData) const
|
||||
{
|
||||
return ValueRef(pPropertyData);
|
||||
}
|
||||
|
||||
void Resize(void* pPropertyData, u32 NewCount) const
|
||||
{
|
||||
u32 OldCount = _InternalArrayCount(pPropertyData);
|
||||
|
||||
if (OldCount != NewCount)
|
||||
{
|
||||
SScriptArray& rArray = _GetInternalArray(pPropertyData);
|
||||
|
||||
// Handle destruction of old elements
|
||||
if (OldCount > NewCount)
|
||||
{
|
||||
for (u32 ItemIdx = NewCount; ItemIdx < OldCount; ItemIdx++)
|
||||
{
|
||||
void* pItemPtr = ItemPointer(pPropertyData, ItemIdx);
|
||||
mpItemArchetype->Destruct(pItemPtr);
|
||||
}
|
||||
}
|
||||
|
||||
u32 NewSize = NewCount * ItemSize();
|
||||
rArray.Array.resize(NewSize);
|
||||
|
||||
// Handle construction of new elements
|
||||
if (NewCount > OldCount)
|
||||
{
|
||||
for (u32 ItemIdx = OldCount; ItemIdx < NewCount; ItemIdx++)
|
||||
{
|
||||
void* pItemPtr = ItemPointer(pPropertyData, ItemIdx);
|
||||
mpItemArchetype->Construct(pItemPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* ItemPointer(void* pPropertyData, u32 ItemIndex) const
|
||||
{
|
||||
ASSERT(ArrayCount(pPropertyData) > ItemIndex);
|
||||
std::vector<char>& rArray = _GetInternalArray(pPropertyData).Array;
|
||||
u32 MyItemSize = ItemSize();
|
||||
ASSERT(rArray.size() >= (MyItemSize * (ItemIndex+1)));
|
||||
return rArray.data() + (MyItemSize * ItemIndex);
|
||||
}
|
||||
|
||||
u32 ItemSize() const
|
||||
{
|
||||
u32 ItemAlign = mpItemArchetype->DataAlignment();
|
||||
u32 ItemSize = ALIGN(mpItemArchetype->DataSize(), ItemAlign);
|
||||
return ItemSize;
|
||||
}
|
||||
|
||||
/** Accessors */
|
||||
IPropertyNew* ArchetypeProperty() const { return mpArchetype; }
|
||||
};
|
||||
|
||||
#endif // CARRAYPROPERTY_H
|
||||
42
src/Core/Resource/Script/Property/CAssetProperty.h
Normal file
42
src/Core/Resource/Script/Property/CAssetProperty.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef CASSETPROPERTY_H
|
||||
#define CASSETPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
#include "Core/Resource/CResTypeFilter.h"
|
||||
|
||||
class CAssetProperty : public TTypedPropertyNew<CAssetID, EPropertyTypeNew::Asset>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
CResTypeFilter mTypeFilter;
|
||||
|
||||
public:
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc)
|
||||
{
|
||||
TTypedPropertyNew::Serialize(rArc);
|
||||
rArc << SERIAL("AcceptedTypes", mTypeFilter);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData) const
|
||||
{
|
||||
return Value(pData).ToString();
|
||||
}
|
||||
|
||||
void SetTypeFilter(const TStringList& rkExtensions)
|
||||
{
|
||||
mTypeFilter.SetAcceptedTypes(Game(), rkExtensions);
|
||||
}
|
||||
|
||||
const CResTypeFilter& GetTypeFilter() const
|
||||
{
|
||||
return mTypeFilter;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CASSETPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CBoolProperty.h
Normal file
27
src/Core/Resource/Script/Property/CBoolProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CBOOLPROPERTY_H
|
||||
#define CBOOLPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CBoolProperty : public TTypedPropertyNew< bool, EPropertyTypeNew::Bool >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CBoolProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return Value(pData) ? "true" : "false";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CBOOLPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CByteProperty.h
Normal file
27
src/Core/Resource/Script/Property/CByteProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CBYTEPROPERTY_H
|
||||
#define CBYTEPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CByteProperty : public TNumericalPropertyNew< char, EPropertyTypeNew::Byte >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CByteProperty()
|
||||
: TNumericalPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (u8&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CBYTEPROPERTY_H
|
||||
34
src/Core/Resource/Script/Property/CColorProperty.h
Normal file
34
src/Core/Resource/Script/Property/CColorProperty.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef CCOLORPROPERTY_H
|
||||
#define CCOLORPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CColorProperty : public TTypedPropertyNew< CColor, EPropertyTypeNew::Color >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CColorProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void PostInitialize()
|
||||
{
|
||||
IPropertyNew* pR = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
IPropertyNew* pG = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
IPropertyNew* pB = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
IPropertyNew* pA = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
pR->SetName("R");
|
||||
pG->SetName("G");
|
||||
pB->SetName("B");
|
||||
pA->SetName("A");
|
||||
}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Value(pData).Serialize(Arc);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CVECTORPROPERTY_H
|
||||
124
src/Core/Resource/Script/Property/CEnumProperty.h
Normal file
124
src/Core/Resource/Script/Property/CEnumProperty.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef CENUMPROPERTY_H
|
||||
#define CENUMPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
/** There are two types of enum properties: in the game data enum and choice.
|
||||
*
|
||||
* In the game, the difference is that choice properties are index-based, while
|
||||
* enum properties are stored as a hash of the name of the enum.
|
||||
*
|
||||
* In PWE, however, they are both implemented the same way under the hood.
|
||||
*/
|
||||
template<EPropertyTypeNew TypeEnum>
|
||||
class TEnumPropertyBase : public TTypedPropertyNew<int, TypeEnum>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
struct SEnumValue
|
||||
{
|
||||
TString Name;
|
||||
u32 ID;
|
||||
|
||||
SEnumValue(const TString& rkInName, u32 InID)
|
||||
: Name(rkInName), ID(InID) {}
|
||||
|
||||
inline bool operator==(const SEnumValue& rkOther) const
|
||||
{
|
||||
return( Name == rkOther.Name && ID == rkOther.ID );
|
||||
}
|
||||
};
|
||||
std::vector<SEnumValue> mValues;
|
||||
|
||||
/** XML template file that this enum originated from; for archetypes */
|
||||
TString mSourceFile;
|
||||
|
||||
public:
|
||||
virtual const char* GetHashableTypeName() const
|
||||
{
|
||||
if (TypeEnum == EPropertyTypeNew::Enum)
|
||||
return "enum";
|
||||
else
|
||||
return "choice";
|
||||
}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString GetTemplateFileName()
|
||||
{
|
||||
ASSERT(IsArchetype() || mpArchetype);
|
||||
return IsArchetype() ? mSourceFile : mpArchetype->GetTemplateFileName();
|
||||
}
|
||||
|
||||
inline u32 NumPossibleValues() const { return mValues.size(); }
|
||||
|
||||
u32 ValueIndex(u32 ID) const
|
||||
{
|
||||
for (u32 ValueIdx = 0; ValueIdx < mValues.size(); ValueIdx++)
|
||||
{
|
||||
if (mValues[ValueIdx].ID == ID)
|
||||
{
|
||||
return ValueIdx;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 ValueID(u32 Index) const
|
||||
{
|
||||
ASSERT(Index >= 0 && Index < mValues.size());
|
||||
return mValues[Index].ID;
|
||||
}
|
||||
|
||||
TString ValueName(u32 Index) const
|
||||
{
|
||||
ASSERT(Index >= 0 && Index < mValues.size());
|
||||
return mValues[Index].Name;
|
||||
}
|
||||
|
||||
bool HasValidValue(void* pPropertyData)
|
||||
{
|
||||
int ID = ValueRef(pPropertyData);
|
||||
u32 Index = ValueIndex(ID);
|
||||
return Index >= 0 && Index < mValues.size();
|
||||
}
|
||||
};
|
||||
|
||||
typedef TEnumPropertyBase<EPropertyTypeNew::Choice> CChoiceProperty;
|
||||
typedef TEnumPropertyBase<EPropertyTypeNew::Enum> CEnumProperty;
|
||||
|
||||
// Specialization of TPropCast to allow interchangeable casting, as both types are the same thing
|
||||
template<>
|
||||
inline CEnumProperty* TPropCast(IPropertyNew* pProperty)
|
||||
{
|
||||
EPropertyTypeNew InType = pProperty->Type();
|
||||
|
||||
if (InType == EPropertyTypeNew::Enum || InType == EPropertyTypeNew::Choice)
|
||||
{
|
||||
return static_cast<CEnumProperty*>(pProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline CChoiceProperty* TPropCast(IPropertyNew* pProperty)
|
||||
{
|
||||
if (pProperty)
|
||||
{
|
||||
EPropertyTypeNew InType = pProperty->Type();
|
||||
|
||||
if (InType == EPropertyTypeNew::Enum || InType == EPropertyTypeNew::Choice)
|
||||
{
|
||||
return static_cast<CChoiceProperty*>(pProperty);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // CENUMPROPERTY_H
|
||||
99
src/Core/Resource/Script/Property/CFlagsProperty.h
Normal file
99
src/Core/Resource/Script/Property/CFlagsProperty.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef CFLAGSPROPERTY_H
|
||||
#define CFLAGSPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CFlagsProperty : public TTypedPropertyNew<int, EPropertyTypeNew::Flags>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class IPropertyNew;
|
||||
|
||||
struct SBitFlag
|
||||
{
|
||||
TString Name;
|
||||
u32 Mask;
|
||||
|
||||
SBitFlag(const TString& rkInName, u32 InMask)
|
||||
: Name(rkInName), Mask(InMask)
|
||||
{}
|
||||
|
||||
bool operator==(const SBitFlag& rkOther) const
|
||||
{
|
||||
return( Name == rkOther.Name && Mask == rkOther.Mask );
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Serialize(IArchive& rArc)
|
||||
{
|
||||
rArc << SERIAL("FlagName", Name)
|
||||
<< SERIAL_HEX("FlagMask", Mask);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
std::vector<SBitFlag> mBitFlags;
|
||||
u32 mAllFlags;
|
||||
|
||||
/** XML template file that this enum originated from; for archetypes */
|
||||
TString mSourceFile;
|
||||
|
||||
CFlagsProperty()
|
||||
: TTypedPropertyNew()
|
||||
, mAllFlags(0)
|
||||
{}
|
||||
|
||||
public:
|
||||
inline u32 NumFlags() const
|
||||
{
|
||||
return mBitFlags.size();
|
||||
}
|
||||
|
||||
inline TString FlagName(u32 Idx) const
|
||||
{
|
||||
ASSERT(Idx >= 0 && Idx < mBitFlags.size());
|
||||
return mBitFlags[Idx].Name;
|
||||
}
|
||||
|
||||
inline u32 FlagMask(u32 Idx) const
|
||||
{
|
||||
ASSERT(Idx >= 0 && Idx < mBitFlags.size());
|
||||
return mBitFlags[Idx].Mask;
|
||||
}
|
||||
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc)
|
||||
{
|
||||
TTypedPropertyNew::Serialize(rArc);
|
||||
rArc << SERIAL_CONTAINER("Flags", mFlags, "Flag");
|
||||
|
||||
// Initialize the "all flags" cache
|
||||
if (rArc.IsReader())
|
||||
{
|
||||
mAllFlags = 0;
|
||||
for (u32 FlagIdx = 0; FlagIdx < mFlags.size(); FlagIdx++)
|
||||
mAllFlags |= mFlags[FlagIdx].Mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
||||
{
|
||||
rArc.SerializeHexPrimitive( (u32&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString GetTemplateFileName()
|
||||
{
|
||||
ASSERT(IsArchetype() || mpArchetype);
|
||||
return IsArchetype() ? mSourceFile : mpArchetype->GetTemplateFileName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether there are any unrecognized bits toggled on in the property value.
|
||||
* Returns the mask of any invalid bits. If all bits are valid, returns 0.
|
||||
*/
|
||||
u32 HasValidValue(void* pPropertyData)
|
||||
{
|
||||
return ValueRef(pPropertyData) & ~mAllFlags;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CFLAGSPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CFloatProperty.h
Normal file
27
src/Core/Resource/Script/Property/CFloatProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CFLOATPROPERTY_H
|
||||
#define CFLOATPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CFloatProperty : public TNumericalPropertyNew< float, EPropertyTypeNew::Float >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CFloatProperty()
|
||||
: TNumericalPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (float&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return TString::FromFloat( Value(pData) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CFLOATPROPERTY_H
|
||||
22
src/Core/Resource/Script/Property/CGuidProperty.h
Normal file
22
src/Core/Resource/Script/Property/CGuidProperty.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef CGUIDPROPERTY_H
|
||||
#define CGUIDPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CGuidProperty : public TTypedPropertyNew< std::vector<char>, EPropertyTypeNew::Guid >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CGuidProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializeBulkData( ValueRef(pData) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CSPLINEPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CIntProperty.h
Normal file
27
src/Core/Resource/Script/Property/CIntProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CINTPROPERTY_H
|
||||
#define CINTPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CIntProperty : public TNumericalPropertyNew< int, EPropertyTypeNew::Int >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CIntProperty()
|
||||
: TNumericalPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return TString::FromInt32( Value(pData), 0, 10 );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CINTPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CPointerProperty.h
Normal file
27
src/Core/Resource/Script/Property/CPointerProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CPOINTERPROPERTY_H
|
||||
#define CPOINTERPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CPointerProperty : public TTypedPropertyNew<void*, EPropertyTypeNew::Pointer>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
public:
|
||||
virtual bool IsPointerType() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void* GetChildDataPointer(void* pPropertyData) const
|
||||
{
|
||||
return ValueRef(pPropertyData);
|
||||
}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
||||
{
|
||||
// pointers are not serializable, this shouldn't happen
|
||||
ASSERT(false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CPOINTERPROPERTY_H
|
||||
19
src/Core/Resource/Script/Property/CSequenceProperty.h
Normal file
19
src/Core/Resource/Script/Property/CSequenceProperty.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef CSEQUENCEPROPERTY_H
|
||||
#define CSEQUENCEPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CSequenceProperty : public TTypedPropertyNew< int, EPropertyTypeNew::Sequence >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CSequenceProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // CSEQUENCEPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CShortProperty.h
Normal file
27
src/Core/Resource/Script/Property/CShortProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CSHORTPROPERTY_H
|
||||
#define CSHORTPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CShortProperty : public TNumericalPropertyNew< short, EPropertyTypeNew::Short >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CShortProperty()
|
||||
: TNumericalPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (u16&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CSHORTPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CSoundProperty.h
Normal file
27
src/Core/Resource/Script/Property/CSoundProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CSOUNDPROPERTY_H
|
||||
#define CSOUNDPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CSoundProperty : public TTypedPropertyNew< int, EPropertyTypeNew::Sound >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CSoundProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData)
|
||||
{
|
||||
return TString::FromInt32( Value(pData), 0, 10 );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CSOUNDPROPERTY_H
|
||||
22
src/Core/Resource/Script/Property/CSplineProperty.h
Normal file
22
src/Core/Resource/Script/Property/CSplineProperty.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef CSPLINEPROPERTY_H
|
||||
#define CSPLINEPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CSplineProperty : public TTypedPropertyNew< std::vector<char>, EPropertyTypeNew::Spline >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CSplineProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializeBulkData( ValueRef(pData) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CSPLINEPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/CStringProperty.h
Normal file
27
src/Core/Resource/Script/Property/CStringProperty.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CSTRINGPROPERTY_H
|
||||
#define CSTRINGPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CStringProperty : public TTypedPropertyNew< TString, EPropertyTypeNew::String >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CStringProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
Arc.SerializePrimitive( ValueRef(pData) );
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData) const
|
||||
{
|
||||
return Value(pData);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CSTRINGPROPERTY_H
|
||||
146
src/Core/Resource/Script/Property/CStructProperty.h
Normal file
146
src/Core/Resource/Script/Property/CStructProperty.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef CSTRUCTPROPERTY_H
|
||||
#define CSTRUCTPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CStructPropertyNew : public IPropertyNew
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
|
||||
public:
|
||||
// Must be a valid type for TPropertyRef
|
||||
typedef void* ValueType;
|
||||
|
||||
protected:
|
||||
/** For archetypes, the filename of the template XML file. */
|
||||
TString mTemplateFileName;
|
||||
|
||||
public:
|
||||
virtual EPropertyTypeNew Type() const
|
||||
{
|
||||
return EPropertyTypeNew::Struct;
|
||||
}
|
||||
|
||||
virtual u32 DataSize() const
|
||||
{
|
||||
if (!mChildren.empty())
|
||||
{
|
||||
IPropertyNew* pLastChild = mChildren.back();
|
||||
return _GetOffset() + pLastChild->DataSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual u32 DataAlignment() const
|
||||
{
|
||||
return (mChildren.empty() ? 1 : mChildren[0]->DataAlignment());
|
||||
}
|
||||
|
||||
virtual void Construct(void* pData) const
|
||||
{
|
||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
mChildren[ChildIdx]->Construct(pData);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Destruct(void* pData) const
|
||||
{
|
||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
mChildren[ChildIdx]->Destruct(pData);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool MatchesDefault(void* pData) const
|
||||
{
|
||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
if (!mChildren[ChildIdx]->MatchesDefault(pData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void RevertToDefault(void* pData) const
|
||||
{
|
||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
mChildren[ChildIdx]->RevertToDefault(pData);
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* HashableTypeName() const
|
||||
{
|
||||
ASSERT(IsArchetype() || mpArchetype != nullptr);
|
||||
|
||||
if (IsArchetype())
|
||||
return *mName;
|
||||
else
|
||||
return *mpArchetype->Name();
|
||||
}
|
||||
|
||||
#if 0
|
||||
virtual void Serialize(IArchive& rArc)
|
||||
{
|
||||
IPropertyNew::Serialize(rArc);
|
||||
|
||||
if (rArc.ParamBegin("SubProperties"))
|
||||
{
|
||||
u32 NumChildren;
|
||||
rArc.SerializeContainerSize(NumChildren, "Property");
|
||||
|
||||
if (rArc.IsReader())
|
||||
{
|
||||
mChildren.resize(NumChildren);
|
||||
}
|
||||
|
||||
for (u32 ChildIdx = 0; ChildIdx < NumChildren; ChildIdx++)
|
||||
{
|
||||
if (rArc.ParamBegin("Property"))
|
||||
{
|
||||
EPropertyTypeNew Type = (rArc.IsWriter() ? mChildren[ChildIdx]->Type() : EPropertyTypeNew::Invalid);
|
||||
rArc << SERIAL_AUTO(Type);
|
||||
|
||||
if (rArc.IsReader())
|
||||
{
|
||||
mChildren[ChildIdx] = Create(Type, this, mpMasterTemplate, mpScriptTemplate);
|
||||
}
|
||||
|
||||
mChildren[ChildIdx]->Serialize(rArc);
|
||||
rArc.ParamEnd();
|
||||
}
|
||||
}
|
||||
|
||||
rArc.ParamEnd();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
for (u32 ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||
{
|
||||
if (Arc.ParamBegin("Property"))
|
||||
{
|
||||
mChildren[ChildIdx]->SerializeValue(pData, Arc);
|
||||
Arc.ParamEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual TString GetTemplateFileName()
|
||||
{
|
||||
ASSERT(IsArchetype() || mpArchetype);
|
||||
return IsArchetype() ? mTemplateFileName : mpArchetype->GetTemplateFileName();
|
||||
}
|
||||
|
||||
inline static EPropertyTypeNew StaticType() { return EPropertyTypeNew::Struct; }
|
||||
};
|
||||
|
||||
#endif
|
||||
37
src/Core/Resource/Script/Property/CVectorProperty.h
Normal file
37
src/Core/Resource/Script/Property/CVectorProperty.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef CVECTORPROPERTY_H
|
||||
#define CVECTORPROPERTY_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
|
||||
class CVectorProperty : public TTypedPropertyNew< CVector3f, EPropertyTypeNew::Vector >
|
||||
{
|
||||
friend class IPropertyNew;
|
||||
|
||||
protected:
|
||||
CVectorProperty()
|
||||
: TTypedPropertyNew()
|
||||
{}
|
||||
|
||||
public:
|
||||
virtual void PostInitialize()
|
||||
{
|
||||
IPropertyNew* pX = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
IPropertyNew* pY = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
IPropertyNew* pZ = Create(EPropertyTypeNew::Float, this, mpMasterTemplate, mpScriptTemplate);
|
||||
pX->SetName("X");
|
||||
pY->SetName("Y");
|
||||
pZ->SetName("Z");
|
||||
}
|
||||
|
||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||
{
|
||||
ValueRef(pData).Serialize(Arc);
|
||||
}
|
||||
|
||||
virtual TString ValueAsString(void* pData) const
|
||||
{
|
||||
return Value(pData).ToString();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CVECTORPROPERTY_H
|
||||
27
src/Core/Resource/Script/Property/Properties.h
Normal file
27
src/Core/Resource/Script/Property/Properties.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef PROPERTIES_H
|
||||
#define PROPERTIES_H
|
||||
|
||||
#include "../IPropertyNew.h"
|
||||
#include "CAnimationProperty.h"
|
||||
#include "CAnimationSetProperty.h"
|
||||
#include "CArrayProperty.h"
|
||||
#include "CAssetProperty.h"
|
||||
#include "CBoolProperty.h"
|
||||
#include "CByteProperty.h"
|
||||
#include "CColorProperty.h"
|
||||
#include "CEnumProperty.h"
|
||||
#include "CFlagsProperty.h"
|
||||
#include "CFloatProperty.h"
|
||||
#include "CGuidProperty.h"
|
||||
#include "CIntProperty.h"
|
||||
#include "CPointerProperty.h"
|
||||
#include "CSequenceProperty.h"
|
||||
#include "CShortProperty.h"
|
||||
#include "CSoundProperty.h"
|
||||
#include "CSplineProperty.h"
|
||||
#include "CStringProperty.h"
|
||||
#include "CStructProperty.h"
|
||||
#include "CVectorProperty.h"
|
||||
#include "TPropertyRef.h"
|
||||
|
||||
#endif // PROPERTIES_H
|
||||
113
src/Core/Resource/Script/Property/TPropertyRef.h
Normal file
113
src/Core/Resource/Script/Property/TPropertyRef.h
Normal file
@@ -0,0 +1,113 @@
|
||||
#ifndef TPROPERTYREF_H
|
||||
#define TPROPERTYREF_H
|
||||
|
||||
#include "CAnimationProperty.h"
|
||||
#include "CAnimationSetProperty.h"
|
||||
#include "CArrayProperty.h"
|
||||
#include "CAssetProperty.h"
|
||||
#include "CBoolProperty.h"
|
||||
#include "CByteProperty.h"
|
||||
#include "CColorProperty.h"
|
||||
#include "CEnumProperty.h"
|
||||
#include "CFlagsProperty.h"
|
||||
#include "CFloatProperty.h"
|
||||
#include "CGuidProperty.h"
|
||||
#include "CIntProperty.h"
|
||||
#include "CPointerProperty.h"
|
||||
#include "CSequenceProperty.h"
|
||||
#include "CShortProperty.h"
|
||||
#include "CSoundProperty.h"
|
||||
#include "CSplineProperty.h"
|
||||
#include "CStringProperty.h"
|
||||
#include "CStructProperty.h"
|
||||
#include "CVectorProperty.h"
|
||||
|
||||
/** TPropertyRef: Embeds a reference to a property on a specific script object */
|
||||
template<class PropertyClass, typename ValueType = PropertyClass::ValueType>
|
||||
class TPropertyRef
|
||||
{
|
||||
/** Script object containing the property data being referenced */
|
||||
CScriptObject* mpObject;
|
||||
|
||||
/** Property being referenced */
|
||||
PropertyClass* mpProperty;
|
||||
|
||||
public:
|
||||
TPropertyRef()
|
||||
: mpObject(nullptr), mpProperty(nullptr)
|
||||
{}
|
||||
|
||||
TPropertyRef(CScriptObject* pInObject, IPropertyNew* pInProperty)
|
||||
: mpObject(pInObject), mpProperty( TPropCast<PropertyClass>(pInProperty) )
|
||||
{
|
||||
}
|
||||
|
||||
TPropertyRef(CScriptObject* pInObject, PropertyClass* pInProperty)
|
||||
: mpObject(pInObject), mpProperty(pInProperty)
|
||||
{
|
||||
}
|
||||
|
||||
/** Accessors */
|
||||
inline CScriptObject* Object() const { return mpObject; }
|
||||
inline PropertyClass* Property() const { return mpProperty; }
|
||||
inline ValueType Get() const { ASSERT(IsValid()); return *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )); }
|
||||
inline void Set(const ValueType& kIn) const { if (IsValid()) *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )) = kIn; }
|
||||
inline bool IsValid() const { return mpObject != nullptr && mpProperty != nullptr; }
|
||||
|
||||
/** Inline operators */
|
||||
inline operator ValueType() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
inline bool operator==(IPropertyNew* pProperty) const
|
||||
{
|
||||
return mpProperty == pProperty;
|
||||
}
|
||||
|
||||
friend bool operator==(IPropertyNew* pLeft, const TPropertyRef& kRight)
|
||||
{
|
||||
return pLeft == kRight.Property();
|
||||
}
|
||||
};
|
||||
|
||||
/** Convenience typedefs */
|
||||
typedef TPropertyRef<CBoolProperty> CBoolRef;
|
||||
typedef TPropertyRef<CByteProperty> CByteRef;
|
||||
typedef TPropertyRef<CShortProperty> CShortRef;
|
||||
typedef TPropertyRef<CIntProperty> CIntRef;
|
||||
typedef TPropertyRef<CFloatProperty> CFloatRef;
|
||||
typedef TPropertyRef<CFlagsProperty> CFlagsRef;
|
||||
typedef TPropertyRef<CStringProperty> CStringRef;
|
||||
typedef TPropertyRef<CVectorProperty> CVectorRef;
|
||||
typedef TPropertyRef<CColorProperty> CColorRef;
|
||||
typedef TPropertyRef<CAssetProperty> CAssetRef;
|
||||
typedef TPropertyRef<CSoundProperty> CSoundRef;
|
||||
typedef TPropertyRef<CAnimationProperty> CAnimationRef;
|
||||
typedef TPropertyRef<CAnimationSetProperty> CAnimationSetRef;
|
||||
typedef TPropertyRef<CSequenceProperty> CSequenceRef;
|
||||
typedef TPropertyRef<CSplineProperty> CSplineRef;
|
||||
typedef TPropertyRef<CGuidProperty> CGuidRef;
|
||||
typedef TPropertyRef<CPointerProperty> CPointerRef;
|
||||
typedef TPropertyRef<CStructPropertyNew> CStructRef;
|
||||
typedef TPropertyRef<CArrayProperty> CArrayRef;
|
||||
|
||||
/** Special version for enums */
|
||||
template<typename ValueType>
|
||||
class TEnumRef : public TPropertyRef<CEnumProperty, ValueType>
|
||||
{
|
||||
public:
|
||||
TEnumRef()
|
||||
: TPropertyRef()
|
||||
{}
|
||||
|
||||
TEnumRef(CScriptObject* pInObject, IPropertyNew* pInProperty)
|
||||
: TPropertyRef(pInObject, pInProperty)
|
||||
{}
|
||||
|
||||
TEnumRef(CScriptObject* pInObject, CEnumProperty* pInProperty)
|
||||
: TPropertyRef(pInObject, pInProperty)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // TPROPERTYREF_H
|
||||
39
src/Core/Resource/Script/TPropertyProxy.h
Normal file
39
src/Core/Resource/Script/TPropertyProxy.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user