Fully implemented delete, added an easy-to-use ID lookup system for undo commands, fixed a bunch of crashes when undoing/redoing after creating/deleting an object

This commit is contained in:
parax0
2016-03-16 19:09:59 -06:00
parent 63812ae4b2
commit c4e05610f3
66 changed files with 992 additions and 569 deletions

View File

@@ -15,7 +15,7 @@ CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLa
, mIsCheckingNearVisibleActivation(false)
{
mpTemplate->AddObject(this);
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty(nullptr);
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty(this, nullptr);
}
CScriptObject::~CScriptObject()
@@ -80,14 +80,16 @@ void CScriptObject::SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex)
{
if (pLayer != mpLayer)
{
mpLayer->RemoveInstance(this);
if (mpLayer) mpLayer->RemoveInstance(this);
mpLayer = pLayer;
mpLayer->AddInstance(this, NewLayerIndex);
if (mpLayer) mpLayer->AddInstance(this, NewLayerIndex);
}
}
u32 CScriptObject::LayerIndex() const
{
if (!mpLayer) return -1;
for (u32 iInst = 0; iInst < mpLayer->NumInstances(); iInst++)
{
if (mpLayer->InstanceByIndex(iInst) == this)

View File

@@ -32,13 +32,44 @@ TString IProperty::Name() const
u32 IProperty::ID() const
{
return mpTemplate->PropertyID();
if (mpParent && mpParent->Type() == eArrayProperty)
return ArrayIndex();
else
return mpTemplate->PropertyID();
}
TIDString IProperty::IDString(bool FullPath) const
{
// todo: since this function just returns the template ID string, it doesn't correctly account for array properties;
return mpTemplate->IDString(FullPath);
TIDString Out;
if (ID() != 0xFFFFFFFF)
{
if (mpParent && FullPath)
{
Out = mpParent->IDString(true);
if (!Out.IsEmpty()) Out += ":";
}
Out += TString::HexString(ID(), true, true, 8);
}
return Out;
}
u32 IProperty::ArrayIndex() const
{
CArrayProperty *pArray = TPropCast<CArrayProperty>(mpParent);
if (pArray)
{
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
{
if (pArray->PropertyByIndex(iSub) == this)
return iSub;
}
}
return -1;
}
bool IProperty::ShouldCook()
@@ -74,7 +105,7 @@ void CPropertyStruct::Copy(const IProperty *pkProp)
mProperties.resize(pkSource->mProperties.size());
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
mProperties[iSub] = pkSource->mProperties[iSub]->Clone(this);
mProperties[iSub] = pkSource->mProperties[iSub]->Clone(Instance(), this);
}
bool CPropertyStruct::ShouldCook()
@@ -138,7 +169,7 @@ CPropertyStruct* CPropertyStruct::StructByIndex(u32 index) const
{
IProperty *pProp = PropertyByIndex(index);
if (pProp->Type() == eStructProperty)
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
@@ -148,7 +179,7 @@ CPropertyStruct* CPropertyStruct::StructByID(u32 ID) const
{
IProperty *pProp = PropertyByID(ID);
if (pProp->Type() == eStructProperty)
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
@@ -158,7 +189,7 @@ CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr) const
{
IProperty *pProp = PropertyByIDString(rkStr);
if (pProp->Type() == eStructProperty)
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
return static_cast<CPropertyStruct*>(pProp);
else
return nullptr;
@@ -186,7 +217,7 @@ void CArrayProperty::Resize(int Size)
if (Size > OldSize)
{
for (int iProp = OldSize; iProp < Size; iProp++)
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(Instance(), this);
}
}

View File

@@ -13,6 +13,7 @@
#include <Math/CVector3f.h>
#include <list>
class CScriptObject;
class CScriptTemplate;
class CStructTemplate;
class IPropertyTemplate;
@@ -28,11 +29,13 @@ class IProperty
protected:
class CPropertyStruct *mpParent;
CScriptObject *mpInstance;
IPropertyTemplate *mpTemplate;
public:
IProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
IProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: mpParent(pParent)
, mpInstance(pInstance)
, mpTemplate(pTemp)
{
}
@@ -42,12 +45,13 @@ public:
virtual TString ToString() const { return ""; }
virtual IPropertyValue* RawValue() { return nullptr; }
virtual void Copy(const IProperty *pkProp) = 0;
virtual IProperty* Clone(CPropertyStruct *pParent = 0) const = 0;
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent = 0) const = 0;
virtual bool Matches(const IProperty *pkProp) const = 0;
virtual bool ShouldCook(); // Can't be const because it calls MatchesDefault()
virtual bool MatchesDefault(); // Can't be const because RawValue() isn't const
inline CScriptObject* Instance() const { return mpInstance; }
inline CPropertyStruct* Parent() const { return mpParent; }
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
@@ -59,6 +63,7 @@ public:
TString Name() const;
u32 ID() const;
TIDString IDString(bool FullPath) const;
u32 ArrayIndex() const;
};
/*
@@ -70,11 +75,11 @@ class TTypedProperty : public IProperty
friend class CScriptLoader;
ValueClass mValue;
public:
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: IProperty(pTemp, pParent) {}
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: IProperty(pTemp, pInstance, pParent) {}
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent, ValueType v)
: IProperty(pTemp, pParent), mValue(v) {}
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v)
: IProperty(pTemp, pInstance, pParent), mValue(v) {}
~TTypedProperty() {}
virtual EPropertyType Type() const { return TypeEnum; }
@@ -89,11 +94,11 @@ public:
mValue.Set(pkCast->mValue.Get());
}
virtual TTypedProperty* Clone(CPropertyStruct *pParent) const
virtual TTypedProperty* Clone(class CScriptObject *pInstance, CPropertyStruct *pParent) const
{
if (!pParent) pParent = mpParent;
TTypedProperty *pOut = new TTypedProperty(mpTemplate, pParent);
TTypedProperty *pOut = new TTypedProperty(mpTemplate, pInstance, pParent);
pOut->Copy(this);
return pOut;
}
@@ -123,11 +128,11 @@ typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue>
* TStringProperty, TFileProperty, and TCharacterProperty get little subclasses in order to override some virtual functions.
*/
#define IMPLEMENT_PROPERTY_CTORS(ClassName, ValueType) \
ClassName(IPropertyTemplate *pTemp, CPropertyStruct *pParent) \
: TTypedProperty(pTemp, pParent) {} \
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent) \
: TTypedProperty(pTemp, pInstance, pParent) {} \
\
ClassName(IPropertyTemplate *pTemp, CPropertyStruct *pParent, ValueType v) \
: TTypedProperty(pTemp, pParent, v) {}
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v) \
: TTypedProperty(pTemp, pInstance, pParent, v) {}
class TStringProperty : public TTypedProperty<TString, eStringProperty, CStringValue>
{
@@ -169,8 +174,8 @@ class CPropertyStruct : public IProperty
protected:
std::vector<IProperty*> mProperties;
public:
CPropertyStruct(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: IProperty(pTemp, pParent) {}
CPropertyStruct(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: IProperty(pTemp, pInstance, pParent) {}
~CPropertyStruct()
{
@@ -183,10 +188,10 @@ public:
virtual void Copy(const IProperty *pkProp);
virtual IProperty* Clone(CPropertyStruct *pParent) const
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
{
if (!pParent) pParent = mpParent;
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pParent);
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pInstance, pParent);
pOut->Copy(this);
return pOut;
}
@@ -245,16 +250,16 @@ class CArrayProperty : public CPropertyStruct
friend class CScriptLoader;
public:
CArrayProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: CPropertyStruct(pTemp, pParent) {}
CArrayProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
: CPropertyStruct(pTemp, pInstance, pParent) {}
EPropertyType Type() const { return eArrayProperty; }
static inline EPropertyType StaticType() { return eArrayProperty; }
virtual IProperty* Clone(CPropertyStruct *pParent) const
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
{
if (!pParent) pParent = mpParent;
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pParent);
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pInstance, pParent);
pOut->Copy(this);
return pOut;
}

View File

@@ -64,7 +64,7 @@ public:
virtual EPropertyType Type() const = 0;
virtual bool CanHaveDefault() const = 0;
virtual bool IsNumerical() const = 0;
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent) = 0;
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent) = 0;
virtual IPropertyTemplate* Clone(CScriptTemplate *pScript, CStructTemplate *pParent = 0) const = 0;
virtual void Copy(const IPropertyTemplate *pkTemp)
@@ -164,10 +164,10 @@ public:
virtual bool CanHaveDefault() const { return CanHaveDefaultValue; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
TPropertyType *pOut = new TPropertyType(this, pParent, GetDefaultValue());
TPropertyType *pOut = new TPropertyType(this, pInstance, pParent, GetDefaultValue());
return pOut;
}
@@ -321,9 +321,9 @@ public:
TCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TCharacterProperty(this, pParent, CAnimationParameters(Game()));
return new TCharacterProperty(this, pInstance, pParent, CAnimationParameters(Game()));
}
};
@@ -339,9 +339,9 @@ public:
TStringTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TStringProperty(this, pParent);
return new TStringProperty(this, pInstance, pParent);
}
};
@@ -357,9 +357,9 @@ public:
TMayaSplineTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TMayaSplineProperty(this, pParent);
return new TMayaSplineProperty(this, pInstance, pParent);
}
};
@@ -382,9 +382,9 @@ public:
virtual bool CanHaveDefault() const { return false; }
virtual bool IsNumerical() const { return false; }
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new TFileProperty(this, pParent);
return new TFileProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(CFileTemplate)
@@ -451,9 +451,9 @@ public:
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
TEnumProperty *pEnum = new TEnumProperty(this, pParent);
TEnumProperty *pEnum = new TEnumProperty(this, pInstance, pParent);
pEnum->Set(GetDefaultValue());
return pEnum;
}
@@ -546,9 +546,9 @@ public:
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
TBitfieldProperty *pBitfield = new TBitfieldProperty(this, pParent);
TBitfieldProperty *pBitfield = new TBitfieldProperty(this, pInstance, pParent);
pBitfield->Set(GetDefaultValue());
return pBitfield;
}
@@ -611,13 +611,13 @@ public:
bool CanHaveDefault() const { return false; }
bool IsNumerical() const { return false; }
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
CPropertyStruct *pStruct = new CPropertyStruct(this, pParent);
CPropertyStruct *pStruct = new CPropertyStruct(this, pInstance, pParent);
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
{
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty(pStruct);
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty(pInstance, pStruct);
pStruct->AddSubProperty(pSubProp);
}
@@ -708,9 +708,9 @@ public:
EPropertyType Type() const { return eArrayProperty; }
IProperty* InstantiateProperty(CPropertyStruct *pParent)
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
{
return new CArrayProperty(this, pParent);
return new CArrayProperty(this, pInstance, pParent);
}
IMPLEMENT_TEMPLATE_CLONE(CArrayTemplate)
@@ -740,9 +740,9 @@ public:
TString ElementName() const { return mElementName; }
void SetElementName(const TString& rkName) { mElementName = rkName; }
CPropertyStruct* CreateSubStruct(CArrayProperty *pArray)
CPropertyStruct* CreateSubStruct(CScriptObject *pInstance, CArrayProperty *pArray)
{
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pArray);
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pInstance, pArray);
}
};