WIP script object template serialization

This commit is contained in:
Aruki
2018-09-16 09:44:19 -07:00
parent 5182f436b8
commit 36926ca28e
14 changed files with 634 additions and 179 deletions

View File

@@ -8,20 +8,56 @@
struct SState
{
u32 ID;
union {
u32 ID;
CFourCC ID_4CC;
};
TString Name;
SState() {}
SState(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
SState()
{}
SState(u32 InID, const TString& kInName)
: ID(InID)
, Name(kInName)
{}
void Serialize(IArchive& Arc)
{
if (Arc.Game() <= ePrime)
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
else
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
Arc << SerialParameter("Name", Name, SH_Attribute);
}
};
struct SMessage
{
u32 ID;
union {
u32 ID;
CFourCC ID_4CC;
};
TString Name;
SMessage() {}
SMessage(u32 _ID, const TString& rkName) : ID(_ID), Name(rkName) {}
SMessage()
{}
SMessage(u32 InID, const TString& kInName)
: ID(InID)
, Name(kInName)
{}
void Serialize(IArchive& Arc)
{
if (Arc.Game() <= ePrime)
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
else
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
Arc << SerialParameter("Name", Name, SH_Attribute);
}
};
class CLink

View File

@@ -3,34 +3,81 @@
#include <Common/Log.h>
CMasterTemplate::CMasterTemplate()
: mVersion(0)
, mFullyLoaded(false)
: mFullyLoaded(false)
{
}
CMasterTemplate::~CMasterTemplate()
void CMasterTemplate::Serialize(IArchive& Arc)
{
for (auto it = mTemplates.begin(); it != mTemplates.end(); it++)
delete it->second;
Arc << SerialParameter("ScriptObjects", mScriptTemplates)
<< SerialParameter("Structs", mStructTemplates)
<< SerialParameter("Enums", mEnumTemplates)
<< SerialParameter("Flags", mFlagsTemplates)
<< SerialParameter("States", mStates)
<< SerialParameter("Messages", mMessages);
}
void CMasterTemplate::LoadSubTemplates()
{
//todo
}
void CMasterTemplate::SaveSubTemplates()
{
TString GameDir = "../templates_new/" + GetDirectory();
for (auto Iter = mScriptTemplates.begin(); Iter != mScriptTemplates.end(); Iter++)
{
SScriptTemplatePath& Path = Iter->second;
TString OutPath = GameDir + Path.Path;
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
CXMLWriter Writer(OutPath, "ScriptObject", 0, Game());
Path.pTemplate->Serialize(Writer);
}
for (auto Iter = mStructTemplates.begin(); Iter != mStructTemplates.end(); Iter++)
{
SPropertyTemplatePath& Path = Iter->second;
TString OutPath = GameDir + Path.Path;
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
CXMLWriter Writer(OutPath, "Struct", 0, Game());
Path.pTemplate->Serialize(Writer);
}
for (auto Iter = mEnumTemplates.begin(); Iter != mEnumTemplates.end(); Iter++)
{
SPropertyTemplatePath& Path = Iter->second;
TString OutPath = GameDir + Path.Path;
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
CXMLWriter Writer(OutPath, "Enum", 0, Game());
Path.pTemplate->Serialize(Writer);
}
for (auto Iter = mFlagsTemplates.begin(); Iter != mFlagsTemplates.end(); Iter++)
{
SPropertyTemplatePath& Path = Iter->second;
TString OutPath = GameDir + Path.Path;
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
CXMLWriter Writer(OutPath, "Flags", 0, Game());
Path.pTemplate->Serialize(Writer);
}
}
u32 CMasterTemplate::GameVersion(TString VersionName)
{
VersionName = VersionName.ToLower();
for (u32 iVer = 0; iVer < mGameVersions.size(); iVer++)
if (mGameVersions[iVer].ToLower() == VersionName)
return iVer;
return -1;
}
CScriptTemplate* CMasterTemplate::TemplateByID(u32 ObjectID)
{
auto it = mTemplates.find(ObjectID);
auto it = mScriptTemplates.find(ObjectID);
if (it != mTemplates.end())
return it->second;
if (it != mScriptTemplates.end())
return it->second.pTemplate.get();
else
return nullptr;
}
@@ -42,16 +89,16 @@ CScriptTemplate* CMasterTemplate::TemplateByID(const CFourCC& ObjectID)
CScriptTemplate* CMasterTemplate::TemplateByIndex(u32 Index)
{
auto it = mTemplates.begin();
return (std::next(it, Index))->second;
auto it = mScriptTemplates.begin();
return (std::next(it, Index))->second.pTemplate.get();
}
SState CMasterTemplate::StateByID(u32 StateID)
{
auto it = mStates.find(StateID);
auto Iter = mStates.find(StateID);
if (it != mStates.end())
return it->second;
if (Iter != mStates.end())
return SState(Iter->first, Iter->second);
else
return SState(-1, "Invalid");
}
@@ -63,16 +110,17 @@ SState CMasterTemplate::StateByID(const CFourCC& State)
SState CMasterTemplate::StateByIndex(u32 Index)
{
auto it = mStates.begin();
return (std::next(it, Index))->second;
auto Iter = mStates.begin();
Iter = std::next(Iter, Index);
return SState(Iter->first, Iter->second);
}
SMessage CMasterTemplate::MessageByID(u32 MessageID)
{
auto it = mMessages.find(MessageID);
auto Iter = mMessages.find(MessageID);
if (it != mMessages.end())
return it->second;
if (Iter != mMessages.end())
return SMessage(Iter->first, Iter->second);
else
return SMessage(-1, "Invalid");
}
@@ -84,18 +132,31 @@ SMessage CMasterTemplate::MessageByID(const CFourCC& MessageID)
SMessage CMasterTemplate::MessageByIndex(u32 Index)
{
auto it = mMessages.begin();
return (std::next(it, Index))->second;
auto Iter = mMessages.begin();
Iter = std::next(Iter, Index);
return SMessage(Iter->first, Iter->second);
}
CStructPropertyNew* CMasterTemplate::StructAtSource(const TString& rkSource)
CStructPropertyNew* CMasterTemplate::FindStructArchetype(const TString& kStructName) const
{
auto InfoIt = mStructTemplates.find(rkSource);
auto Iter = mStructTemplates.find(kStructName);
IPropertyNew* pProperty = (Iter != mStructTemplates.end()) ? Iter->second.pTemplate.get() : nullptr;
return TPropCast<CStructPropertyNew>(pProperty);
}
if (InfoIt != mStructTemplates.end())
return InfoIt->second;
CEnumProperty* CMasterTemplate::FindEnumArchetype(const TString& kEnumName) const
{
auto Iter = mEnumTemplates.find(kEnumName);
IPropertyNew* pProperty = (Iter != mEnumTemplates.end()) ? Iter->second.pTemplate.get() : nullptr;
return TPropCast<CEnumProperty>(pProperty);
}
else return nullptr;
CFlagsProperty* CMasterTemplate::FindFlagsArchetype(const TString& kFlagsName) const
{
auto Iter = mFlagsTemplates.find(kFlagsName);
IPropertyNew* pProperty = (Iter != mFlagsTemplates.end()) ? Iter->second.pTemplate.get() : nullptr;
return TPropCast<CFlagsProperty>(pProperty);
}
// ************ STATIC ************

View File

@@ -8,25 +8,113 @@
#include <Common/types.h>
#include <map>
/** Serialization aid
* Retro switched from using integers to fourCCs to represent IDs in several cases (states/messages, object IDs).
* This struct is functionally an integer but it serializes as an int for MP1 and a fourCC for MP2 and on.
*/
struct SObjId
{
union {
u32 ID;
CFourCC ID_4CC;
};
inline SObjId() {}
inline SObjId(u32 InID) : ID(InID) {}
inline SObjId(CFourCC InID) : ID_4CC(InID) {}
inline operator u32() const { return ID; }
inline operator CFourCC() const { return ID_4CC; }
void Serialize(IArchive& Arc)
{
if (Arc.Game() <= ePrime)
Arc.SerializePrimitive(ID, SH_HexDisplay);
else
Arc.SerializePrimitive(ID_4CC, 0);
}
};
class CMasterTemplate
{
friend class CTemplateLoader;
friend class CTemplateWriter;
/** Struct holding a reference to a script object template */
struct SScriptTemplatePath
{
/** Script object ID */
SObjId ID;
/** File path to the template file, relative to the game directory */
TString Path;
/** Template in memory */
std::shared_ptr<CScriptTemplate> pTemplate;
/** Constructor */
SScriptTemplatePath()
: ID(0)
{}
SScriptTemplatePath(u32 InID, const TString& kInPath, CScriptTemplate* pInTemplate)
: ID(InID)
, Path(kInPath)
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
{}
SScriptTemplatePath(const CFourCC& kInID, const TString& kInPath, CScriptTemplate* pInTemplate)
: ID(kInID)
, Path(kInPath)
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
{}
/** Serializer */
void Serialize(IArchive& Arc)
{
Arc << SerialParameter("ID", ID, SH_Attribute)
<< SerialParameter("Path", Path, SH_Attribute);
}
};
/** Struct holding a reference to a property template */
struct SPropertyTemplatePath
{
/** File path to the template file, relative to the game directory */
TString Path;
/** Template in memory */
std::shared_ptr<IPropertyNew> pTemplate;
/** Constructor */
SPropertyTemplatePath()
{}
SPropertyTemplatePath(const TString& kInPath, IPropertyNew* pInTemplate)
: Path(kInPath)
, pTemplate( std::shared_ptr<IPropertyNew>(pInTemplate) )
{}
/** Serializer */
void Serialize(IArchive& Arc)
{
Arc << SerialParameter("Path", Path, SH_Attribute);
}
};
EGame mGame;
TString mGameName;
TString mSourceFile;
u32 mVersion;
bool mFullyLoaded;
std::vector<TString> mGameVersions;
std::map<TString, CStructPropertyNew*> mStructTemplates;
std::map<TString, CEnumProperty*> mEnumTemplates;
std::map<TString, CFlagsProperty*> mFlagsTemplates;
/** Template arrays */
std::map<SObjId, SScriptTemplatePath> mScriptTemplates;
std::map<TString, SPropertyTemplatePath> mStructTemplates;
std::map<TString, SPropertyTemplatePath> mEnumTemplates;
std::map<TString, SPropertyTemplatePath> mFlagsTemplates;
std::map<u32, CScriptTemplate*> mTemplates;
std::map<u32, SState> mStates;
std::map<u32, SMessage> mMessages;
std::map<SObjId, TString> mStates;
std::map<SObjId, TString> mMessages;
struct SPropIDInfo
{
@@ -40,7 +128,9 @@ class CMasterTemplate
public:
CMasterTemplate();
~CMasterTemplate();
void Serialize(IArchive& Arc);
void LoadSubTemplates();
void SaveSubTemplates();
u32 GameVersion(TString VersionName);
CScriptTemplate* TemplateByID(u32 ObjectID);
CScriptTemplate* TemplateByID(const CFourCC& ObjectID);
@@ -51,13 +141,15 @@ public:
SMessage MessageByID(u32 MessageID);
SMessage MessageByID(const CFourCC& MessageID);
SMessage MessageByIndex(u32 Index);
CStructPropertyNew* StructAtSource(const TString& rkSource);
CStructPropertyNew* FindStructArchetype(const TString& kStructName) const;
CEnumProperty* FindEnumArchetype(const TString& kEnumName) const;
CFlagsProperty* FindFlagsArchetype(const TString& kFlagsName) const;
// Inline Accessors
inline EGame Game() const { return mGame; }
inline TString GameName() const { return mGameName; }
inline u32 NumGameVersions() const { return mGameVersions.empty() ? 1 : mGameVersions.size(); }
inline u32 NumScriptTemplates() const { return mTemplates.size(); }
inline u32 NumScriptTemplates() const { return mScriptTemplates.size(); }
inline u32 NumStates() const { return mStates.size(); }
inline u32 NumMessages() const { return mMessages.size(); }
inline bool IsLoadedSuccessfully() { return mFullyLoaded; }

View File

@@ -8,6 +8,7 @@
#include <iostream>
#include <string>
// Old constructor
CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
: mpMaster(pMaster)
, mpProperties(nullptr)
@@ -24,10 +25,58 @@ CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
{
}
// New constructor
CScriptTemplate::CScriptTemplate(CMasterTemplate* pInMaster, u32 InObjectID, const TString& kInFilePath)
: mRotationType(eRotationEnabled)
, mScaleType(eScaleEnabled)
, mPreviewScale(1.f)
, mVolumeShape(eNoShape)
, mVolumeScale(1.f)
, mSourceFile(kInFilePath)
, mObjectID(InObjectID)
, mpMaster(pInMaster)
, mpNameProperty(nullptr)
, mpPositionProperty(nullptr)
, mpRotationProperty(nullptr)
, mpScaleProperty(nullptr)
, mpActiveProperty(nullptr)
, mpLightParametersProperty(nullptr)
, mVisible(true)
{
}
CScriptTemplate::~CScriptTemplate()
{
}
void CScriptTemplate::Serialize(IArchive& Arc)
{
Arc << SerialParameter("Modules", mModules, SH_Optional)
<< SerialParameter("Properties", mpProperties);
if (Arc.ParamBegin("EditorProperties", 0))
{
Arc << SerialParameter("NameProperty", mNameIDString, SH_Optional)
<< SerialParameter("PositionProperty", mPositionIDString, SH_Optional)
<< SerialParameter("RotationProperty", mRotationIDString, SH_Optional)
<< SerialParameter("ScaleProperty", mScaleIDString, SH_Optional)
<< SerialParameter("ActiveProperty", mActiveIDString, SH_Optional)
<< SerialParameter("LightParametersProperty", mLightParametersIDString, SH_Optional);
Arc.ParamEnd();
}
Arc << SerialParameter("Assets", mAssets, SH_Optional)
<< SerialParameter("Attachments", mAttachments, SH_Optional)
<< SerialParameter("RotationType", mRotationType, SH_Optional, eRotationEnabled)
<< SerialParameter("ScaleType", mScaleType, SH_Optional, eScaleEnabled)
<< SerialParameter("PreviewScale", mPreviewScale, SH_Optional, 1.0f)
<< SerialParameter("VolumeShape", mVolumeShape, SH_Optional, eNoShape)
<< SerialParameter("VolumeScale", mVolumeScale, SH_Optional, 1.0f)
<< SerialParameter("VolumeConditionProperty", mVolumeConditionIDString, SH_Optional)
<< SerialParameter("VolumeConditions", mVolumeConditions, SH_Optional);
}
void CScriptTemplate::PostLoad()
{
if (!mNameIDString.IsEmpty()) mpNameProperty = TPropCast<CStringProperty>( mpProperties->ChildByIDString(mNameIDString) );

View File

@@ -26,6 +26,13 @@ struct SAttachment
TIDString AttachProperty; // Must point to a CMDL!
TString LocatorName;
EAttachType AttachType;
void Serialize(IArchive& Arc)
{
Arc << SerialParameter("AttachProperty", AttachProperty, SH_Attribute)
<< SerialParameter("LocatorName", LocatorName, SH_Attribute)
<< SerialParameter("AttachType", AttachType, SH_Attribute);
}
};
/*
@@ -52,41 +59,28 @@ public:
private:
struct SEditorAsset
{
enum {
enum EAssetType {
eModel, eAnimParams, eBillboard, eCollision
} AssetType;
enum {
enum EAssetSource {
eProperty, eFile
} AssetSource;
TIDString AssetLocation;
s32 ForceNodeIndex; // Force animsets to use specific node instead of one from property
void Serialize(IArchive& Arc)
{
Arc << SerialParameter("Type", AssetType, SH_Attribute)
<< SerialParameter("Source", AssetSource, SH_Attribute)
<< SerialParameter("Location", AssetLocation, SH_Attribute)
<< SerialParameter("ForceCharacterIndex", ForceNodeIndex, SH_Attribute | SH_Optional, (s32) -1);
}
};
CMasterTemplate* mpMaster;
std::unique_ptr<CStructPropertyNew> mpProperties;
std::list<CScriptObject*> mObjectList;
std::vector<TString> mModules;
TString mSourceFile;
u32 mObjectID;
bool mVisible;
// Editor Properties
TIDString mNameIDString;
TIDString mPositionIDString;
TIDString mRotationIDString;
TIDString mScaleIDString;
TIDString mActiveIDString;
TIDString mLightParametersIDString;
CStringProperty* mpNameProperty;
CVectorProperty* mpPositionProperty;
CVectorProperty* mpRotationProperty;
CVectorProperty* mpScaleProperty;
CBoolProperty* mpActiveProperty;
CStructPropertyNew* mpLightParametersProperty;
std::unique_ptr<CStructPropertyNew> mpProperties;
std::vector<SEditorAsset> mAssets;
std::vector<SAttachment> mAttachments;
@@ -99,15 +93,47 @@ private:
float mVolumeScale;
TIDString mVolumeConditionIDString;
TString mSourceFile;
u32 mObjectID;
// Editor Properties
TIDString mNameIDString;
TIDString mPositionIDString;
TIDString mRotationIDString;
TIDString mScaleIDString;
TIDString mActiveIDString;
TIDString mLightParametersIDString;
CMasterTemplate* mpMaster;
std::list<CScriptObject*> mObjectList;
CStringProperty* mpNameProperty;
CVectorProperty* mpPositionProperty;
CVectorProperty* mpRotationProperty;
CVectorProperty* mpScaleProperty;
CBoolProperty* mpActiveProperty;
CStructPropertyNew* mpLightParametersProperty;
struct SVolumeCondition {
int Value;
u32 Value;
EVolumeShape Shape;
float Scale;
void Serialize(IArchive& Arc)
{
Arc << SerialParameter("Value", Value)
<< SerialParameter("Shape", Shape)
<< SerialParameter("Scale", Scale, SH_Optional, 1.0f);
}
};
std::vector<SVolumeCondition> mVolumeConditions;
bool mVisible;
public:
// Old constructor
CScriptTemplate(CMasterTemplate *pMaster);
// New constructor
CScriptTemplate(CMasterTemplate* pMaster, u32 ObjectID, const TString& kFilePath);
~CScriptTemplate();
void Serialize(IArchive& rArc);
void PostLoad();
@@ -133,11 +159,11 @@ public:
const SAttachment& Attachment(u32 Index) const { return mAttachments[Index]; }
const std::vector<TString>& RequiredModules() const { return mModules; }
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 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; }

View File

@@ -93,14 +93,14 @@ void* IPropertyNew::GetChildDataPointer(void* pPropertyData) const
void IPropertyNew::Serialize(IArchive& rArc)
{
if (rArc.Game() <= ePrime)
if (rArc.Game() <= ePrime && !IsArchetype())
{
rArc << SerialParameter("Name", mName);
}
rArc << SerialParameter("ID", mID, SH_HexDisplay | SH_Optional, (u32) 0xFFFFFFFF)
rArc << SerialParameter("ID", mID, SH_HexDisplay | SH_Attribute | SH_Optional, (u32) 0xFFFFFFFF)
<< SerialParameter("Description", mDescription, SH_Optional)
<< SerialParameter("CookPref", mCookPreference, SH_Optional, ECookPreferenceNew::Default)
<< SerialParameter("CookPreference", mCookPreference, SH_Optional, ECookPreferenceNew::Default)
<< SerialParameter("MinVersion", mMinVersion, SH_Optional, 0.f)
<< SerialParameter("MaxVersion", mMaxVersion, SH_Optional, FLT_MAX);

View File

@@ -376,7 +376,7 @@ protected:
public:
virtual void Serialize(IArchive& rArc)
{
IPropertyNew::Serialize(rArc);
TTypedPropertyNew::Serialize(rArc);
// Determine if default value should be serialized as optional.
// All MP1 properties should be optional. For MP2 and on, we set optional
@@ -436,14 +436,14 @@ protected:
public:
virtual void Serialize(IArchive& rArc)
{
TTypedPropertyNew::Serialize(rArc);
TSerializeableTypedProperty::Serialize(rArc);
rArc << SerialParameter("Min", mMinValue, SH_Optional, (PropType) -1)
<< SerialParameter("Max", mMaxValue, SH_Optional, (PropType) -1);
}
virtual void InitFromArchetype(IPropertyNew* pOther)
{
TTypedPropertyNew::InitFromArchetype(pOther);
TSerializeableTypedProperty::InitFromArchetype(pOther);
TNumericalPropertyNew* pCastOther = static_cast<TNumericalPropertyNew*>(pOther);
mMinValue = pCastOther->mMinValue;
mMaxValue = pCastOther->mMaxValue;
@@ -451,7 +451,7 @@ public:
virtual void PropertyValueChanged(void* pPropertyData)
{
IPropertyNew::PropertyValueChanged(pPropertyData);
TSerializeableTypedProperty::PropertyValueChanged(pPropertyData);
if (mMinValue >= 0 && mMaxValue >= 0)
{

View File

@@ -122,16 +122,17 @@ typedef TEnumPropertyBase<EPropertyTypeNew::Enum> CEnumProperty;
template<>
inline CEnumProperty* TPropCast(IPropertyNew* pProperty)
{
EPropertyTypeNew InType = pProperty->Type();
if (pProperty)
{
EPropertyTypeNew InType = pProperty->Type();
if (InType == EPropertyTypeNew::Enum || InType == EPropertyTypeNew::Choice)
{
return static_cast<CEnumProperty*>(pProperty);
}
else
{
return nullptr;
if (InType == EPropertyTypeNew::Enum || InType == EPropertyTypeNew::Choice)
{
return static_cast<CEnumProperty*>(pProperty);
}
}
return nullptr;
}
template<>