Removal of unused files from Code/Editor

XmlHistoryManager.cpp was being compiled but unused

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-08-05 12:43:46 -07:00
parent 9a82005cb8
commit d955189a31
14 changed files with 0 additions and 3032 deletions
-149
View File
@@ -1,149 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "SkeletonHierarchy.h"
using namespace Skeleton;
/*
CHierarchy
*/
CHierarchy::CHierarchy()
{
}
CHierarchy::~CHierarchy()
{
}
//
uint32 CHierarchy::AddNode(const char* name, const QuatT& pose, int32 parent)
{
int32 index = FindNodeIndexByName(name);
if (index < 0)
{
m_nodes.push_back(SNode());
index = int32(m_nodes.size() - 1);
}
m_nodes[index].name = name;
m_nodes[index].pose = pose;
m_nodes[index].parent = parent;
return uint32(index);
}
int32 CHierarchy::FindNodeIndexByName(const char* name) const
{
uint32 count = uint32(m_nodes.size());
for (uint32 i = 0; i < count; ++i)
{
if (::_stricmp(m_nodes[i].name, name))
{
continue;
}
return i;
}
return -1;
}
const CHierarchy::SNode* CHierarchy::FindNode(const char* name) const
{
int32 index = FindNodeIndexByName(name);
return index < 0 ? NULL : &m_nodes[index];
}
void CHierarchy::CreateFrom(IDefaultSkeleton* pIDefaultSkeleton)
{
const uint32 jointCount = pIDefaultSkeleton->GetJointCount();
m_nodes.clear();
m_nodes.reserve(jointCount);
for (uint32 i = 0; i < jointCount; ++i)
{
m_nodes.push_back(SNode());
m_nodes.back().name = pIDefaultSkeleton->GetJointNameByID(int32(i));
m_nodes.back().pose = pIDefaultSkeleton->GetDefaultAbsJointByID(int32(i));
m_nodes.back().parent = pIDefaultSkeleton->GetJointParentIDByID(int32(i));
}
ValidateReferences();
}
void CHierarchy::ValidateReferences()
{
uint32 nodeCount = m_nodes.size();
if (!nodeCount)
{
return;
}
for (uint32 i = 0; i < nodeCount; ++i)
{
if (m_nodes[i].parent < nodeCount)
{
continue;
}
m_nodes[i].parent = -1;
}
}
void CHierarchy::AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination)
{
uint32 count = uint32(m_nodes.size());
std::vector<QuatT> absolutes(count);
for (uint32 i = 0; i < count; ++i)
{
absolutes[i] = pSource[i];
}
for (uint32 i = 0; i < count; ++i)
{
int32 parent = m_nodes[i].parent;
if (parent < 0)
{
pDestination[i] = absolutes[i];
continue;
}
pDestination[i].t = (absolutes[i].t - absolutes[parent].t) * absolutes[parent].q;
pDestination[i].q = absolutes[parent].q.GetInverted() * absolutes[i].q;
}
}
bool CHierarchy::SerializeTo(XmlNodeRef& node)
{
XmlNodeRef hierarchy = node->newChild("Hierarchy");
uint32 nodeCount = uint32(m_nodes.size());
std::vector<IXmlNode*> nodes(nodeCount);
for (uint32 i = 0; i < nodeCount; ++i)
{
XmlNodeRef parent = hierarchy;
if (m_nodes[i].parent > -1)
{
parent = nodes[m_nodes[i].parent];
}
nodes[i] = parent->newChild("Node");
nodes[i]->setAttr("name", m_nodes[i].name);
}
return true;
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
#pragma once
namespace Skeleton {
class CHierarchy
: public _reference_target_t
{
public:
struct SNode
{
string name;
QuatT pose;
int32 parent;
/* TODO: Implement
uint32 childrenIndex;
uint32 childrenCount;
*/
};
public:
CHierarchy();
~CHierarchy();
public:
uint32 AddNode(const char* name, const QuatT& pose, int32 parent = -1);
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
int32 FindNodeIndexByName(const char* name) const;
const SNode* FindNode(const char* name) const;
void ClearNodes() { m_nodes.clear(); }
void CreateFrom(IDefaultSkeleton* rIDefaultSkeleton);
void ValidateReferences();
void AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination);
bool SerializeTo(XmlNodeRef& node);
private:
std::vector<SNode> m_nodes;
};
} // namespace Skeleton
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
-368
View File
@@ -1,368 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "SkeletonMapper.h"
using namespace Skeleton;
/*
CMapper
*/
CMapper::CMapper()
{
}
CMapper::~CMapper()
{
}
//
void CMapper::CreateFromHierarchy()
{
m_nodes.clear();
uint32 nodeCount = m_hierarchy.GetNodeCount();
m_nodes.resize(nodeCount);
}
//
uint32 CMapper::CreateLocation(const char* name)
{
int32 index = FindLocation(name);
if (index < 1)
{
CMapperLocation* pLocation = new CMapperLocation();
pLocation->SetName(name);
m_locations.push_back(pLocation);
}
return uint32(m_locations.size() - 1);
}
void CMapper::ClearLocations()
{
uint32 count = uint32(m_nodes.size());
for (uint32 i = 0; i < count; ++i)
{
m_nodes[i].position = NULL;
m_nodes[i].orientation = NULL;
}
m_locations.clear();
}
int32 CMapper::FindLocation(const char* name) const
{
uint32 count = uint32(m_locations.size());
for (uint32 i = 0; i < count; ++i)
{
if (::_stricmp(m_locations[i]->GetName(), name))
{
continue;
}
return int32(i);
}
return -1;
}
void CMapper::SetLocation(CMapperLocation& location)
{
int32 index = FindLocation(location.GetName());
if (index < 0)
{
m_locations.push_back(&location);
return;
}
m_locations[index] = &location;
}
//
bool CMapper::CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent)
{
if (NodeHasLocation(index))
{
const CHierarchy::SNode* pNode = m_hierarchy.GetNode(index);
uint32 nodeIndex = hierarchy.AddNode(pNode->name, pNode->pose, hierarchyParent);
hierarchyParent = uint32(nodeIndex);
}
std::vector<uint32> children;
GetChildrenIndices(index, children);
uint32 childCount = uint32(children.size());
for (uint32 i = 0; i < childCount; ++i)
{
CreateLocationsHierarchy(children[i], hierarchy, hierarchyParent);
}
return hierarchy.GetNodeCount() != 0;
}
bool CMapper::CreateLocationsHierarchy(CHierarchy& hierarchy)
{
hierarchy.ClearNodes();
if (!CreateLocationsHierarchy(0, hierarchy, -1))
{
return false;
}
hierarchy.ValidateReferences();
return true;
}
void CMapper::Map(QuatT* pResult)
{
uint32 outputCount = m_hierarchy.GetNodeCount();
std::vector<Quat> absolutes(outputCount);
for (uint32 i = 0; i < outputCount; ++i)
{
pResult[i].SetIdentity();
absolutes[i].SetIdentity();
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
if (!pNode)
{
continue;
}
CHierarchy::SNode* pParent = pNode->parent < 0 ?
NULL : m_hierarchy.GetNode(pNode->parent);
if (pParent)
{
pResult[i].t =
(pNode->pose.t - pParent->pose.t) * pParent->pose.q;
}
if (m_nodes[i].position)
{
pResult[i].t = m_nodes[i].position->Compute().t;
}
if (m_nodes[i].orientation)
{
absolutes[i] = m_nodes[i].orientation->Compute().q;
}
else if (pParent)
{
Quat relative = pParent->pose.q.GetInverted() * pNode->pose.q;
absolutes[i] = absolutes[pNode->parent] * relative;
}
}
for (uint32 i = 0; i < outputCount; ++i)
{
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
if (!pNode)
{
continue;
}
CHierarchy::SNode* pParent = pNode->parent < 0 ?
NULL : m_hierarchy.GetNode(pNode->parent);
if (!pParent)
{
pResult[i].q = absolutes[i];
continue;
}
pResult[i].q = absolutes[i];
if (!m_nodes[i].position)
{
pResult[i].t = pResult[pNode->parent].t +
pResult[i].t * absolutes[pNode->parent].GetInverted();
}
}
}
//
bool CMapper::NodeHasLocation(uint32 index)
{
if (CMapperOperator* pOperator = m_nodes[index].position)
{
if (pOperator->IsOfClass("Location"))
{
return true;
}
if (pOperator->HasLinksOfClass("Location"))
{
return true;
}
}
if (CMapperOperator* pOperator = m_nodes[index].orientation)
{
if (pOperator->IsOfClass("Location"))
{
return true;
}
if (pOperator->HasLinksOfClass("Location"))
{
return true;
}
}
return false;
}
void CMapper::GetChildrenIndices(uint32 parent, std::vector<uint32>& children)
{
uint32 nodeCount = m_hierarchy.GetNodeCount();
for (uint32 i = 0; i < nodeCount; ++i)
{
if (m_hierarchy.GetNode(i)->parent != parent)
{
continue;
}
children.push_back(i);
}
}
bool CMapper::ChildrenHaveLocation(uint32 index)
{
std::vector<uint32> children;
GetChildrenIndices(index, children);
uint32 childrenCount = uint32(children.size());
for (uint32 i = 0; i < childrenCount; ++i)
{
if (ChildrenHaveLocation(children[i]))
{
return true;
}
}
return false;
}
bool CMapper::NodeOrChildrenHaveLocation(uint32 index)
{
if (NodeHasLocation(index))
{
return true;
}
std::vector<uint32> children;
GetChildrenIndices(index, children);
uint32 childrenCount = uint32(children.size());
for (uint32 i = 0; i < childrenCount; ++i)
{
if (NodeOrChildrenHaveLocation(children[i]))
{
return true;
}
}
return false;
}
bool CMapper::SerializeTo(XmlNodeRef& node)
{
XmlNodeRef hierarchy = node->newChild("Hierarchy");
uint32 nodeCount = GetNodeCount();
std::vector<IXmlNode*> nodes(nodeCount);
for (uint32 i = 0; i < nodeCount; ++i)
{
if (!NodeOrChildrenHaveLocation(i))
{
continue;
}
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
if (!pNode)
{
return false;
}
XmlNodeRef xmlParent = hierarchy;
int32 parent = pNode->parent;
if (parent > -1)
{
xmlParent = nodes[parent];
}
nodes[i] = xmlParent->newChild("Node");
nodes[i]->setAttr("name", pNode->name);
if (CMapperOperator* pOperator = m_nodes[i].position)
{
XmlNodeRef position = nodes[i]->newChild("Position");
XmlNodeRef child = position->newChild("Operator");
if (!pOperator->SerializeWithLinksTo(child))
{
return false;
}
}
if (CMapperOperator* pOperator = m_nodes[i].orientation)
{
XmlNodeRef orientation = nodes[i]->newChild("Orientation");
XmlNodeRef child = orientation->newChild("Operator");
if (!pOperator->SerializeWithLinksTo(child))
{
return false;
}
}
}
return true;
}
bool CMapper::SerializeFrom(XmlNodeRef& node, int32 parent)
{
int childCount = uint32(node->getChildCount());
for (int i = 0; i < childCount; ++i)
{
XmlNodeRef child = node->getChild(i);
if (::_stricmp(child->getTag(), "Node"))
{
continue;
}
uint32 index = m_hierarchy.AddNode(child->getAttr("name"), QuatT(IDENTITY), parent);
if (!SerializeFrom(child, int32(index)))
{
return false;
}
}
return true;
}
bool CMapper::SerializeFrom(XmlNodeRef& node)
{
XmlNodeRef hierarchy = node->findChild("Hierarchy");
if (!hierarchy)
{
return false;
}
m_hierarchy.ClearNodes();
if (!SerializeFrom(hierarchy, -1))
{
return false;
}
m_nodes.resize(m_hierarchy.GetNodeCount());
return true;
}
-76
View File
@@ -1,76 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
#pragma once
#include "SkeletonHierarchy.h"
#include "SkeletonMapperOperator.h"
namespace Skeleton {
class CMapper
{
public:
struct SNode
{
_smart_ptr<CMapperOperator> position;
_smart_ptr<CMapperOperator> orientation;
};
public:
CMapper();
~CMapper();
public:
CHierarchy& GetHierarchy() { return m_hierarchy; }
void CreateFromHierarchy();
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
uint32 CreateLocation(const char* name);
void ClearLocations();
int32 FindLocation(const char* name) const;
uint32 GetLocationCount() const { return uint32(m_locations.size()); }
void SetLocation(CMapperLocation& location);
CMapperLocation* GetLocation(uint32 index) { return m_locations[index]; }
const CMapperLocation* GetLocation(uint32 index) const { return m_locations[index]; }
bool CreateLocationsHierarchy(CHierarchy& hierarchy);
void Map(QuatT* pResult);
bool SerializeTo(XmlNodeRef& node);
bool SerializeFrom(XmlNodeRef& node);
private:
bool NodeHasLocation(uint32 index);
bool ChildrenHaveLocation(uint32 index);
bool NodeOrChildrenHaveLocation(uint32 index);
bool SerializeFrom(XmlNodeRef& node, int32 parent);
bool CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent = -1);
// TEMP
void GetChildrenIndices(uint32 parent, std::vector<uint32>& children);
private:
CHierarchy m_hierarchy;
std::vector<_smart_ptr<CMapperLocation> > m_locations;
std::vector<SNode> m_nodes;
};
} // namespace Skeleton
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
@@ -1,284 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "SkeletonMapperOperator.h"
using namespace Skeleton;
/*
CMapperOperatorDesc
*/
std::vector<CMapperOperatorDesc*> CMapperOperatorDesc::s_descs;
//
CMapperOperatorDesc::CMapperOperatorDesc(const char* name)
{
s_descs.push_back(this);
}
/*
CMapperOperator
*/
CMapperOperator::CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount)
{
m_className = className;
m_position.resize(positionCount, NULL);
m_orientation.resize(orientationCount, NULL);
}
CMapperOperator::~CMapperOperator()
{
}
//
bool CMapperOperator::IsOfClass(const char* className)
{
if (::_stricmp(m_className, className))
{
return false;
}
return true;
}
uint32 CMapperOperator::HasLinksOfClass(const char* className)
{
uint32 count = 0;
uint32 positionCount = m_position.size();
for (uint32 i = 0; i < positionCount; ++i)
{
CMapperOperator* pOperator = m_position[i];
if (!pOperator)
{
continue;
}
if (pOperator->IsOfClass(className))
{
++count;
}
}
uint32 orientationCount = m_orientation.size();
for (uint32 i = 0; i < orientationCount; ++i)
{
CMapperOperator* pOperator = m_orientation[i];
if (!pOperator)
{
continue;
}
if (pOperator->IsOfClass(className))
{
++count;
}
}
return count;
}
//
bool CMapperOperator::SerializeTo(XmlNodeRef& node)
{
node->setAttr("class", m_className);
uint32 parameterCount = uint32(m_parameters.size());
for (uint32 i = 0; i < parameterCount; ++i)
{
m_parameters[i]->Serialize(node, false);
}
return true;
}
bool CMapperOperator::SerializeFrom(XmlNodeRef& node)
{
uint32 parameterCount = uint32(m_parameters.size());
for (uint32 i = 0; i < parameterCount; ++i)
{
m_parameters[i]->Serialize(node, true);
}
return true;
}
bool CMapperOperator::SerializeWithLinksTo(XmlNodeRef& node)
{
if (!SerializeTo(node))
{
return false;
}
uint32 positionCount = uint32(m_position.size());
for (uint32 i = 0; i < positionCount; ++i)
{
CMapperOperator* pOperator = m_position[i];
if (!pOperator)
{
continue;
}
XmlNodeRef position = node->newChild("Position");
position->setAttr("index", i);
XmlNodeRef child = position->newChild("Operator");
if (!pOperator->SerializeWithLinksTo(child))
{
return false;
}
}
uint32 orientationCount = uint32(m_orientation.size());
for (uint32 i = 0; i < orientationCount; ++i)
{
CMapperOperator* pOperator = m_orientation[i];
if (!pOperator)
{
continue;
}
XmlNodeRef orientation = node->newChild("Orientation");
orientation->setAttr("index", i);
XmlNodeRef child = orientation->newChild("Operator");
if (!pOperator->SerializeWithLinksTo(child))
{
return false;
}
}
return true;
}
bool CMapperOperator::SerializeWithLinksFrom(XmlNodeRef& node)
{
if (!SerializeFrom(node))
{
return false;
}
return true;
}
/*
CMapperOperator_Transform
*/
class CMapperOperator_Transform
: public CMapperOperator
{
public:
CMapperOperator_Transform()
: CMapperOperator("Transform", 1, 1)
{
m_pAngles = new CVariable<Vec3>();
m_pAngles->SetName("rotation");
m_pAngles->Set(Vec3(0.0f, 0.0f, 0.0f));
m_pAngles->SetLimits(-180.0f, 180.0f);
AddParameter(*m_pAngles);
m_pVector = new CVariable<Vec3>();
m_pVector->SetName("vector");
m_pVector->Set(Vec3(0.0f, 0.0f, 0.0f));
AddParameter(*m_pVector);
m_pScale = new CVariable<Vec3>();
m_pScale->SetName("scale");
m_pScale->Set(Vec3(1.0f, 1.0f, 1.0f));
AddParameter(*m_pScale);
}
// CMapperOperator
public:
virtual QuatT CMapperOperator_Transform::Compute()
{
QuatT result(IDENTITY);
m_pVector->Get(result.t);
Vec3 scale;
m_pScale->Get(scale);
Vec3 angles;
m_pAngles->Get(angles);
result.q = Quat::CreateRotationXYZ(
Ang3(DEG2RAD(angles.x), DEG2RAD(angles.y), DEG2RAD(angles.z)));
if (CMapperOperator* pOperator = GetPosition(0))
{
result.t = pOperator->Compute().t.CompMul(scale) + result.t;
}
if (CMapperOperator* pOperator = GetOrientation(0))
{
result.q = pOperator->Compute().q * result.q;
}
return result;
}
private:
CVariable<Vec3>* m_pVector;
CVariable<Vec3>* m_pAngles;
CVariable<Vec3>* m_pScale;
};
SkeletonMapperOperatorRegister(Transform, CMapperOperator_Transform)
class CMapperOperator_PositionsToOrientation
: public CMapperOperator
{
public:
CMapperOperator_PositionsToOrientation()
: CMapperOperator("PositionsToOrientation", 3, 0)
{
}
// CMapperOperator
public:
virtual QuatT Compute()
{
CMapperOperator* pOperator0 = GetPosition(0);
CMapperOperator* pOperator1 = GetPosition(1);
CMapperOperator* pOperator2 = GetPosition(2);
if (!pOperator0 || !pOperator1 || !pOperator2)
{
return QuatT(IDENTITY);
}
Vec3 p0 = pOperator0->Compute().t;
Vec3 p1 = pOperator1->Compute().t;
Vec3 p2 = pOperator2->Compute().t;
Vec3 m = (p1 + p2) * 0.5f;
Vec3 y = (m - p0).GetNormalized();
Vec3 z = (p1 - p2).GetNormalized();
Vec3 x = y % z;
z = x % y;
Matrix33 m33;
m33.SetFromVectors(x, y, z);
QuatT result(IDENTITY);
result.q = Quat(m33);
return result;
}
};
SkeletonMapperOperatorRegister(PositionsToOrientation, CMapperOperator_PositionsToOrientation)
@@ -1,164 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
#pragma once
#include "../Util/Variable.h"
#undef GetClassName
#define SkeletonMapperOperatorRegister(name, className) \
class CMapperOperatorDesc_##name \
: public CMapperOperatorDesc \
{ \
public: \
CMapperOperatorDesc_##name() \
: CMapperOperatorDesc(#name) { } \
protected: \
virtual const char* GetName() { return #name; } \
virtual CMapperOperator* Create() { return new className(); } \
} mapperOperatorDesc__##name;
namespace Skeleton {
class CMapperOperator;
class CMapperOperatorDesc
{
public:
static uint32 GetCount() { return uint32(s_descs.size()); }
static const char* GetName(uint32 index) { return s_descs[index]->GetName(); }
static CMapperOperator* Create(uint32 index) { return s_descs[index]->Create(); }
private:
static std::vector<CMapperOperatorDesc*> s_descs;
public:
CMapperOperatorDesc(const char* name);
protected:
virtual const char* GetName() = 0;
virtual CMapperOperator* Create() = 0;
};
class CMapperOperator
: public _reference_target_t
{
protected:
CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount);
~CMapperOperator();
public:
const char* GetClassName() { return m_className; }
uint32 GetPositionCount() const { return uint32(m_position.size()); }
void SetPosition(uint32 index, CMapperOperator* pOperator) { m_position[index] = pOperator; }
CMapperOperator* GetPosition(uint32 index) { return m_position[index]; }
uint32 GetOrientationCount() const { return uint32(m_orientation.size()); }
void SetOrientation(uint32 index, CMapperOperator* pOperator) { m_orientation[index] = pOperator; }
CMapperOperator* GetOrientation(uint32 index) { return m_orientation[index]; }
uint32 GetParameterCount() { return uint32(m_parameters.size()); }
IVariable* GetParameter(uint32 index) { return m_parameters[index]; }
bool IsOfClass(const char* className);
uint32 HasLinksOfClass(const char* className);
bool SerializeTo(XmlNodeRef& node);
bool SerializeFrom(XmlNodeRef& node);
bool SerializeWithLinksTo(XmlNodeRef& node);
bool SerializeWithLinksFrom(XmlNodeRef& node);
protected:
void AddParameter(IVariable& variable) { m_parameters.push_back(&variable); }
public:
virtual QuatT Compute() = 0;
private:
const char* m_className;
std::vector<_smart_ptr<CMapperOperator> > m_position;
std::vector<_smart_ptr<CMapperOperator> > m_orientation;
std::vector<IVariablePtr> m_parameters;
};
class CMapperLocation
: public CMapperOperator
{
public:
CMapperLocation()
: CMapperOperator("Location", 0, 0)
{
m_pName = new CVariable<CString>();
m_pName->SetName("name");
m_pName->SetFlags(m_pName->GetFlags() | IVariable::UI_INVISIBLE);
AddParameter(*m_pName);
m_pAxis = new CVariable<Vec3>();
m_pAxis->SetName("axis");
m_pAxis->SetLimits(-3.0f, +3.0f);
m_pAxis->Set(Vec3(1.0f, 2.0f, 3.0f));
AddParameter(*m_pAxis);
m_location = QuatT(IDENTITY);
}
public:
void SetName(const char* name) { m_pName->Set(name); }
CString GetName() const { CString s; m_pName->Get(s); return s; }
void SetLocation(const QuatT& location) { m_location = location; }
const QuatT& GetLocation() const { return m_location; }
// CMapperOperator
public:
virtual QuatT Compute()
{
Vec3 axis;
m_pAxis->Get(axis);
uint32 x = fabs_tpl(axis.x);
uint32 y = fabs_tpl(axis.y);
uint32 z = fabs_tpl(axis.z);
if (x < 1 || y < 1 || z < 1 ||
x > 3 || y > 3 || y > 3 ||
x == y || x == z || y == z)
{
return QuatT(IDENTITY);
}
Matrix33 matrix;
matrix.SetFromVectors(
m_location.q.GetColumn(x - 1) * f32(::sgn(axis.x)),
m_location.q.GetColumn(y - 1) * f32(::sgn(axis.y)),
m_location.q.GetColumn(z - 1) * f32(::sgn(axis.z)));
if (!matrix.IsOrthonormalRH(0.01f))
{
return QuatT(IDENTITY);
}
QuatT result = m_location;
result.q = Quat(matrix);
return result;
}
private:
CVariable<CString>* m_pName;
CVariable<Vec3>* m_pAxis;
QuatT m_location;
};
} // namespace Skeleton
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
-135
View File
@@ -1,135 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "ControlMRU.h"
IMPLEMENT_XTP_CONTROL(CControlMRU, CXTPControlRecentFileList)
bool CControlMRU::DoesFileExist(CString& sFileName)
{
return (_access(sFileName.GetBuffer(), 0) == 0);
}
void CControlMRU::OnCalcDynamicSize(DWORD dwMode)
{
CRecentFileList* pRecentFileList = GetRecentFileList();
if (!pRecentFileList)
{
return;
}
CString* pArrNames = pRecentFileList->m_arrNames;
assert(pArrNames != NULL);
if (!pArrNames)
{
return;
}
while (m_nIndex + 1 < m_pControls->GetCount())
{
CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
assert(pControl);
if (pControl->GetID() >= GetFirstMruID()
&& pControl->GetID() <= GetFirstMruID() + pRecentFileList->m_nSize)
{
m_pControls->Remove(pControl);
}
else
{
break;
}
}
if (m_pParent->IsCustomizeMode())
{
m_dwHideFlags = 0;
SetEnabled(TRUE);
return;
}
if (pArrNames[0].IsEmpty())
{
SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION)));
SetDescription("No recently opened files");
m_dwHideFlags = 0;
SetEnabled(FALSE);
return;
}
else
{
SetCaption(CString(MAKEINTRESOURCE(IDS_RECENTFILE_CAPTION)));
SetDescription("Open this document");
}
m_dwHideFlags |= xtpHideGeneric;
CString sCurDir = (Path::GetEditingGameDataFolder() + "\\").c_str();
int nCurDir = sCurDir.GetLength();
CString strName;
CString strTemp;
int iLastValidMRU = 0;
for (int iMRU = 0; iMRU < pRecentFileList->m_nSize; iMRU++)
{
if (!pRecentFileList->GetDisplayName(strName, iMRU, sCurDir.GetBuffer(), nCurDir))
{
break;
}
if (DoesFileExist(pArrNames[iMRU]))
{
CString sCurEntryDir = pArrNames[iMRU].Left(nCurDir);
if (sCurEntryDir.CompareNoCase(sCurDir) != 0)
{
//unavailable entry (wrong directory)
continue;
}
}
else
{
//invalid entry (not existing)
continue;
}
int nId = iMRU + GetFirstMruID();
CXTPControl* pControl = m_pControls->Add(xtpControlButton, nId, _T(""), m_nIndex + iLastValidMRU + 1, TRUE);
assert(pControl);
pControl->SetCaption(CXTPControlWindowList::ConstructCaption(strName, iLastValidMRU + 1));
pControl->SetFlags(xtpFlagManualUpdate);
pControl->SetBeginGroup(iLastValidMRU == 0 && m_nIndex != 0);
pControl->SetParameter(pArrNames[iMRU]);
CString sDescription = "Open file: " + pArrNames[iMRU];
pControl->SetDescription(sDescription);
if ((GetFlags() & xtpFlagWrapRow) && iMRU == 0)
{
pControl->SetFlags(pControl->GetFlags() | xtpFlagWrapRow);
}
++iLastValidMRU;
}
//if no entry was valid, treat as none would exist
if (iLastValidMRU == 0)
{
SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION)));
SetDescription("No recently opened files");
m_dwHideFlags = 0;
SetEnabled(FALSE);
}
}
-24
View File
@@ -1,24 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#ifndef CRYINCLUDE_EDITOR_CONTROLMRU_H
#define CRYINCLUDE_EDITOR_CONTROLMRU_H
class CControlMRU
: public CXTPControlRecentFileList
{
protected:
virtual void OnCalcDynamicSize(DWORD dwMode);
private:
DECLARE_XTP_CONTROL(CControlMRU)
bool DoesFileExist(CString& sFileName);
};
#endif // CRYINCLUDE_EDITOR_CONTROLMRU_H
-543
View File
@@ -1,543 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "ConsoleSCBMFC.h"
#include "PropertiesDialog.h"
#include "QtViewPaneManager.h"
#include "Core/QtEditorApplication.h"
#include <Controls/ui_ConsoleSCBMFC.h>
#include <QtUtil.h>
#include <QtUtilWin.h>
#include <QtCore/QStringList>
#include <QtCore/QScopedPointer>
#include <QtCore/QPoint>
#include <QtGui/QCursor>
#include <QtGui/QMouseEvent>
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QMenu>
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QVBoxLayout>
#include <vector>
#include <iostream>
namespace MFC
{
static CPropertiesDialog* gPropertiesDlg = nullptr;
static CString mfc_popup_helper(HWND hwnd, int x, int y);
static CConsoleSCB* s_consoleSCB = nullptr;
static QString RemoveColorCode(const QString& text, int& iColorCode)
{
QString cleanString;
cleanString.reserve(text.size());
const int textSize = text.size();
for (int i = 0; i < textSize; ++i)
{
QChar c = text.at(i);
bool isLast = i == textSize - 1;
if (c == '$' && !isLast && text.at(i + 1).isDigit())
{
if (iColorCode == 0)
{
iColorCode = text.at(i + 1).digitValue();
}
++i;
continue;
}
if (c == '\r' || c == '\n')
{
++i;
continue;
}
cleanString.append(c);
}
return cleanString;
}
ConsoleLineEdit::ConsoleLineEdit(QWidget* parent)
: QLineEdit(parent)
, m_historyIndex(0)
, m_bReusedHistory(false)
{
}
void ConsoleLineEdit::mousePressEvent(QMouseEvent* ev)
{
if (ev->type() == QEvent::MouseButtonPress && ev->button() & Qt::RightButton)
{
Q_EMIT variableEditorRequested();
}
QLineEdit::mousePressEvent(ev);
}
void ConsoleLineEdit::mouseDoubleClickEvent(QMouseEvent* ev)
{
Q_EMIT variableEditorRequested();
}
bool ConsoleLineEdit::event(QEvent* ev)
{
// Tab key doesn't go to keyPressEvent(), must be processed here
if (ev->type() != QEvent::KeyPress)
{
return QLineEdit::event(ev);
}
QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
if (ke->key() != Qt::Key_Tab)
{
return QLineEdit::event(ev);
}
QString inputStr = text();
QString newStr;
QStringList tokens = inputStr.split(" ");
inputStr = tokens.isEmpty() ? QString() : tokens.first();
IConsole* console = GetIEditor()->GetSystem()->GetIConsole();
const bool ctrlPressed = ke->modifiers() & Qt::ControlModifier;
CString cstring = QtUtil::ToCString(inputStr); // TODO: Use QString once the backend stops using QString
if (ctrlPressed)
{
newStr = QtUtil::ToString(console->AutoCompletePrev(cstring));
}
else
{
newStr = QtUtil::ToString(console->ProcessCompletion(cstring));
newStr = QtUtil::ToString(console->AutoComplete(cstring));
if (newStr.isEmpty())
{
newStr = QtUtil::ToQString(GetIEditor()->GetCommandManager()->AutoComplete(QtUtil::ToString(newStr)));
}
}
if (!newStr.isEmpty())
{
newStr += " ";
setText(newStr);
}
deselect();
return true;
}
void ConsoleLineEdit::keyPressEvent(QKeyEvent* ev)
{
IConsole* console = GetIEditor()->GetSystem()->GetIConsole();
auto commandManager = GetIEditor()->GetCommandManager();
console->ResetAutoCompletion();
switch (ev->key())
{
case Qt::Key_Enter:
case Qt::Key_Return:
{
QString str = text().trimmed();
if (!str.isEmpty())
{
if (commandManager->IsRegistered(QtUtil::ToCString(str)))
{
commandManager->Execute(QtUtil::ToString(str));
}
else
{
CLogFile::WriteLine(QtUtil::ToCString(str));
GetIEditor()->GetSystem()->GetIConsole()->ExecuteString(QtUtil::ToCString(str));
}
// If a history command was reused directly via up arrow enter, do not reset history index
if (m_history.size() > 0 && m_historyIndex < m_history.size() && m_history[m_historyIndex] == str)
{
m_bReusedHistory = true;
}
else
{
m_historyIndex = m_history.size();
}
// Do not add the same string if it is the top of the stack, but allow duplicate entries otherwise
if (m_history.isEmpty() || m_history.back() != str)
{
m_history.push_back(str);
if (!m_bReusedHistory)
{
m_historyIndex = m_history.size();
}
}
}
else
{
m_historyIndex = m_history.size();
}
setText(QString());
break;
}
case Qt::Key_AsciiTilde: // ~
case Qt::Key_Agrave: // `
// disable log.
GetIEditor()->ShowConsole(false);
setText(QString());
m_historyIndex = m_history.size();
break;
case Qt::Key_Escape:
setText(QString());
m_historyIndex = m_history.size();
break;
case Qt::Key_Up:
DisplayHistory(false /*bForward*/);
break;
case Qt::Key_Down:
DisplayHistory(true /*bForward*/);
break;
default:
QLineEdit::keyPressEvent(ev);
}
}
void ConsoleLineEdit::DisplayHistory(bool bForward)
{
if (m_history.isEmpty())
{
return;
}
// Immediately after reusing a history entry, ensure up arrow re-displays command just used
if (!m_bReusedHistory || bForward)
{
m_historyIndex = static_cast<unsigned int>(clamp_tpl(static_cast<int>(m_historyIndex) + (bForward ? 1 : -1), 0, m_history.size() - 1));
}
m_bReusedHistory = false;
setText(m_history[m_historyIndex]);
}
ConsoleTextEdit::ConsoleTextEdit(QWidget* parent)
: QTextEdit(parent)
{
}
Lines CConsoleSCB::s_pendingLines;
CConsoleSCB::CConsoleSCB(QWidget* parent)
: QWidget(parent)
, ui(new Ui::ConsoleMFC())
, m_richEditTextLength(0)
, m_backgroundTheme(gSettings.consoleBackgroundColorTheme)
{
m_lines = s_pendingLines;
s_pendingLines.clear();
s_consoleSCB = this;
ui->setupUi(this);
setMinimumHeight(120);
// Setup the color table for the default (light) theme
m_colorTable << QColor(0, 0, 0)
<< QColor(0, 0, 0)
<< QColor(0, 0, 200) // blue
<< QColor(0, 200, 0) // green
<< QColor(200, 0, 0) // red
<< QColor(0, 200, 200) // cyan
<< QColor(128, 112, 0) // yellow
<< QColor(200, 0, 200) // red+blue
<< QColor(0x000080ff)
<< QColor(0x008f8f8f);
OnStyleSettingsChanged();
connect(ui->button, &QPushButton::clicked, this, &CConsoleSCB::showVariableEditor);
connect(ui->lineEdit, &MFC::ConsoleLineEdit::variableEditorRequested, this, &MFC::CConsoleSCB::showVariableEditor);
connect(Editor::EditorQtApplication::instance(), &Editor::EditorQtApplication::skinChanged, this, &MFC::CConsoleSCB::OnStyleSettingsChanged);
if (GetIEditor()->IsInConsolewMode())
{
// Attach / register edit box
//CLogFile::AttachEditBox(m_edit.GetSafeHwnd()); // FIXME
}
}
CConsoleSCB::~CConsoleSCB()
{
s_consoleSCB = nullptr;
delete gPropertiesDlg;
gPropertiesDlg = nullptr;
CLogFile::AttachEditBox(nullptr);
}
void CConsoleSCB::RegisterViewClass()
{
QtViewOptions opts;
opts.preferedDockingArea = Qt::BottomDockWidgetArea;
opts.isDeletable = false;
opts.isStandard = true;
opts.showInMenu = true;
opts.builtInActionId = ID_VIEW_CONSOLEWINDOW;
opts.sendViewPaneNameBackToAmazonAnalyticsServers = true;
RegisterQtViewPane<CConsoleSCB>(GetIEditor(), LyViewPane::Console, LyViewPane::CategoryTools, opts);
}
void CConsoleSCB::OnStyleSettingsChanged()
{
ui->button->setIcon(QIcon(QString(":/controls/img/cvar_dark.bmp")));
// Set the debug/warning text colors appropriately for the background theme
// (e.g. not have black text on black background)
QColor textColor = Qt::black;
m_backgroundTheme = gSettings.consoleBackgroundColorTheme;
if (m_backgroundTheme == SEditorSettings::ConsoleColorTheme::Dark)
{
textColor = Qt::white;
}
m_colorTable[0] = textColor;
m_colorTable[1] = textColor;
QColor bgColor;
if (!GetIEditor()->IsInConsolewMode() && CConsoleSCB::GetCreatedInstance() && m_backgroundTheme == SEditorSettings::ConsoleColorTheme::Dark)
{
bgColor = Qt::black;
}
else
{
bgColor = Qt::white;
}
ui->textEdit->setStyleSheet(QString("QTextEdit{ background: %1 }").arg(bgColor.name(QColor::HexRgb)));
// Clear out the console text when we change our background color since
// some of the previous text colors may not be appropriate for the
// new background color
ui->textEdit->clear();
}
void CConsoleSCB::showVariableEditor()
{
const QPoint cursorPos = QCursor::pos();
CString str = mfc_popup_helper(0, cursorPos.x(), cursorPos.y());
if (!str.IsEmpty())
{
ui->lineEdit->setText(QtUtil::ToQString(str));
}
}
void CConsoleSCB::SetInputFocus()
{
ui->lineEdit->setFocus();
ui->lineEdit->setText(QString());
}
void CConsoleSCB::AddToConsole(const QString& text, bool bNewLine)
{
m_lines.push_back({ text, bNewLine });
FlushText();
}
void CConsoleSCB::FlushText()
{
if (m_lines.empty())
{
return;
}
// Store our current cursor in case we need to restore it, and check if
// the user has scrolled the text edit away from the bottom
const QTextCursor oldCursor = ui->textEdit->textCursor();
QScrollBar* scrollBar = ui->textEdit->verticalScrollBar();
const int oldScrollValue = scrollBar->value();
bool scrolledOffBottom = oldScrollValue != scrollBar->maximum();
ui->textEdit->moveCursor(QTextCursor::End);
QTextCursor textCursor = ui->textEdit->textCursor();
while (!m_lines.empty())
{
ConsoleLine line = m_lines.front();
m_lines.pop_front();
int iColor = 0;
QString text = MFC::RemoveColorCode(line.text, iColor);
if (iColor < 0 || iColor >= m_colorTable.size())
{
iColor = 0;
}
if (line.newLine)
{
text = QtUtil::trimRight(text);
text = "\r\n" + text;
}
QTextCharFormat format;
const QColor color(m_colorTable[iColor]);
format.setForeground(color);
if (iColor != 0)
{
format.setFontWeight(QFont::Bold);
}
textCursor.setCharFormat(format);
textCursor.insertText(text);
}
// If the user has selected some text in the text edit area or has scrolled
// away from the bottom, then restore the previous cursor and keep the scroll
// bar in the same location
if (oldCursor.hasSelection() || scrolledOffBottom)
{
ui->textEdit->setTextCursor(oldCursor);
scrollBar->setValue(oldScrollValue);
}
// Otherwise scroll to the bottom so the latest text can be seen
else
{
scrollBar->setValue(scrollBar->maximum());
}
}
QSize CConsoleSCB::minimumSizeHint() const
{
return QSize(-1, -1);
}
QSize CConsoleSCB::sizeHint() const
{
return QSize(100, 100);
}
/** static */
void CConsoleSCB::AddToPendingLines(const QString& text, bool bNewLine)
{
s_pendingLines.push_back({ text, bNewLine });
}
static CVarBlock* VarBlockFromConsoleVars()
{
IConsole* console = GetIEditor()->GetSystem()->GetIConsole();
std::vector<const char*> cmds;
cmds.resize(console->GetNumVars());
size_t cmdCount = console->GetSortedVars(&cmds[0], cmds.size());
CVarBlock* vb = new CVarBlock;
IVariable* pVariable = 0;
for (int i = 0; i < cmdCount; i++)
{
ICVar* pCVar = console->GetCVar(cmds[i]);
if (!pCVar)
{
continue;
}
int varType = pCVar->GetType();
switch (varType)
{
case CVAR_INT:
pVariable = new CVariable<int>();
pVariable->Set(pCVar->GetIVal());
break;
case CVAR_FLOAT:
pVariable = new CVariable<float>();
pVariable->Set(pCVar->GetFVal());
break;
case CVAR_STRING:
pVariable = new CVariable<CString>();
pVariable->Set(pCVar->GetString());
break;
default:
assert(0);
}
pVariable->SetDescription(pCVar->GetHelp());
pVariable->SetName(cmds[i]);
if (pVariable)
{
vb->AddVariable(pVariable);
}
}
return vb;
}
static void OnConsoleVariableUpdated(IVariable* pVar)
{
if (!pVar)
{
return;
}
CString varName = pVar->GetName();
ICVar* pCVar = GetIEditor()->GetSystem()->GetIConsole()->GetCVar(varName);
if (!pCVar)
{
return;
}
if (pVar->GetType() == IVariable::INT)
{
int val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::FLOAT)
{
float val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::STRING)
{
CString val;
pVar->Get(val);
pCVar->Set(val);
}
}
static CString mfc_popup_helper(HWND hwnd, int x, int y)
{
IConsole* console = GetIEditor()->GetSystem()->GetIConsole();
TSmartPtr<CVarBlock> vb = VarBlockFromConsoleVars();
XmlNodeRef node;
if (!gPropertiesDlg)
{
gPropertiesDlg = new CPropertiesDialog("Console Variables", node, AfxGetMainWnd(), true);
}
if (!gPropertiesDlg->m_hWnd)
{
gPropertiesDlg->Create(CPropertiesDialog::IDD, AfxGetMainWnd());
gPropertiesDlg->SetUpdateCallback(AZStd::bind(OnConsoleVariableUpdated, AZStd::placeholders::_1));
}
gPropertiesDlg->ShowWindow(SW_SHOW);
gPropertiesDlg->BringWindowToTop();
gPropertiesDlg->GetPropertyCtrl()->AddVarBlock(vb);
return "";
}
CConsoleSCB* CConsoleSCB::GetCreatedInstance()
{
return s_consoleSCB;
}
} // namespace MFC
#include <Controls/moc_ConsoleSCBMFC.cpp>
-73
View File
@@ -1,73 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H
#define CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H
#pragma once
// Helper class to handle Redo/Undo on set of Xml nodes
struct IXmlUndoEventHandler
{
virtual bool SaveToXml(XmlNodeRef& xmlNode) = 0;
virtual bool LoadFromXml(const XmlNodeRef& xmlNode) = 0;
virtual bool ReloadFromXml(const XmlNodeRef& xmlNode) = 0;
};
struct IXmlHistoryEventListener
{
enum EHistoryEventType
{
eHET_HistoryDeleted,
eHET_HistoryCleared,
eHET_HistorySaved,
eHET_VersionChanged,
eHET_VersionAdded,
eHET_HistoryInvalidate,
eHET_HistoryGroupChanged,
eHET_HistoryGroupAdded,
eHET_HistoryGroupRemoved,
};
virtual void OnEvent(EHistoryEventType event, void* pData = NULL) = 0;
};
struct IXmlHistoryView
{
virtual bool LoadXml(int typeId, const XmlNodeRef& xmlNode, IXmlUndoEventHandler*& pUndoEventHandler, uint32 userindex) = 0;
virtual void UnloadXml(int typeId) = 0;
};
struct IXmlHistoryManager
{
// Undo/Redo
virtual bool Undo() = 0;
virtual bool Redo() = 0;
virtual bool Goto(int historyNum) = 0;
virtual void RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc) = 0;
virtual void UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId = 0, bool destoryForever = false) = 0;
virtual void RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId) = 0;
virtual void RegisterEventListener(IXmlHistoryEventListener* pEventListener) = 0;
virtual void UnregisterEventListener(IXmlHistoryEventListener* pEventListener) = 0;
// History
virtual void ClearHistory(bool flagAsSaved = false) = 0;
virtual int GetVersionCount() const = 0;
virtual const AZStd::string& GetVersionDesc(int number) const = 0;
virtual int GetCurrentVersionNumber() const = 0;
// Views
virtual void RegisterView(IXmlHistoryView* pView) = 0;
virtual void UnregisterView(IXmlHistoryView* pView) = 0;
};
#endif // CRYINCLUDE_EDITOR_UTIL_IXMLHISTORYMANAGER_H
-62
View File
@@ -1,62 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
// Description : Utility class to help in STL algorithms on containers with
// CStrings when intending to use case insensitive searches or sorting for
// example.
#ifndef CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H
#define CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H
#pragma once
/*
Utility class to help in STL algorithms on containers with CStrings
when intending to use case insensitive searches or sorting for example.
e.g.
std::vector< CString > v;
...
std::sort( v.begin(), v.end(), CStringNoCasePredicate::LessThan() );
std::find_if( v.begin(), v.end(), CStringNoCasePredicate::Equal( stringImLookingFor ) );
*/
class CStringNoCasePredicate
{
public:
//////////////////////////////////////////////////////////////////////////
struct Equal
{
Equal(const QString& referenceString)
: m_referenceString(referenceString)
{
}
bool operator() (const QString& arg) const
{
return (m_referenceString.compare(arg, Qt::CaseInsensitive) == 0);
}
private:
const QString& m_referenceString;
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
struct LessThan
{
bool operator() (const QString& arg1, const QString& arg2) const
{
return (arg1.CompareNoCase(arg2) < 0);
}
};
//////////////////////////////////////////////////////////////////////////
};
#endif // CRYINCLUDE_EDITOR_UTIL_STRINGNOCASEPREDICATE_H
-875
View File
@@ -1,875 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "XmlHistoryManager.h"
////////////////////////////////////////////////////////////////////////////
SXmlHistory::SXmlHistory(CXmlHistoryManager* pManager, const XmlNodeRef& xmlBaseVersion, uint32 typeId)
: m_pManager(pManager)
, m_typeId(typeId)
, m_DeletedVersion(-1)
, m_SavedVersion(-1)
{
int newVersionNumber = m_pManager->GetCurrentVersionNumber() + (m_pManager->IsPreparedForNextVersion() ? 1 : 0);
m_xmlVersionList[ newVersionNumber ] = xmlBaseVersion;
}
////////////////////////////////////////////////////////////////////////////
void SXmlHistory::AddToHistory(const XmlNodeRef& newXmlVersion)
{
int newVersionNumber = m_pManager->IncrementVersion(this);
m_xmlVersionList[ newVersionNumber ] = newXmlVersion;
}
////////////////////////////////////////////////////////////////////////////
const XmlNodeRef& SXmlHistory::Undo(bool* bVersionExist)
{
m_pManager->Undo();
return GetCurrentVersion(bVersionExist);
}
////////////////////////////////////////////////////////////////////////////
const XmlNodeRef& SXmlHistory::Redo()
{
m_pManager->Redo();
return GetCurrentVersion();
}
////////////////////////////////////////////////////////////////////////////
const XmlNodeRef& SXmlHistory::GetCurrentVersion(bool* bVersionExist, int* iVersionNumber) const
{
int currentVersion = m_pManager->GetCurrentVersionNumber();
TXmlVersionMap::const_iterator it = m_xmlVersionList.begin();
TXmlVersionMap::const_iterator previt = m_xmlVersionList.begin();
while (it != m_xmlVersionList.end())
{
if (it->first > currentVersion)
{
break;
}
previt = it;
++it;
}
if (bVersionExist)
{
*bVersionExist = currentVersion >= m_xmlVersionList.begin()->first;
}
if (iVersionNumber)
{
*iVersionNumber = previt->first;
}
return previt->second;
}
////////////////////////////////////////////////////////////////////////////
bool SXmlHistory::IsModified() const
{
int currVersion;
GetCurrentVersion(NULL, &currVersion);
return m_SavedVersion != currVersion;
}
////////////////////////////////////////////////////////////////////////////
void SXmlHistory::FlagAsDeleted()
{
assert(m_pManager->IsPreparedForNextVersion());
m_DeletedVersion = m_pManager->GetCurrentVersionNumber() + 1;
m_SavedVersion = -1;
}
////////////////////////////////////////////////////////////////////////////
void SXmlHistory::FlagAsSaved()
{
if (Exist())
{
int currVersion;
GetCurrentVersion(NULL, &currVersion);
m_SavedVersion = currVersion;
}
}
////////////////////////////////////////////////////////////////////////////
bool SXmlHistory::Exist() const
{
// int currentVersion = m_pManager->GetCurrentVersionNumber();
// bool deleted = m_DeletedVersion != -1 && currentVersion >= m_DeletedVersion;
// bool exist = currentVersion >= m_xmlVersionList.begin()->first;
// return !deleted && exist;
int currentVersion = m_pManager->GetCurrentVersionNumber();
return currentVersion >= m_xmlVersionList.begin()->first && (m_DeletedVersion == -1 || currentVersion < m_DeletedVersion);
}
////////////////////////////////////////////////////////////////////////////
void SXmlHistory::ClearRedo()
{
int currentVersion = m_pManager->GetCurrentVersionNumber();
if (m_DeletedVersion > currentVersion + (m_pManager->IsPreparedForNextVersion() ? 1 : 0))
{
m_DeletedVersion = -1;
}
TXmlVersionMap::iterator it = m_xmlVersionList.begin();
for (; it != m_xmlVersionList.end(); ++it)
{
if (it->first > currentVersion)
{
break;
}
}
if (it != m_xmlVersionList.end())
{
++it;
while (it != m_xmlVersionList.end())
{
m_xmlVersionList.erase(it++);
}
}
}
////////////////////////////////////////////////////////////////////////////
void SXmlHistory::ClearHistory(bool flagAsSaved)
{
bool wasModified = !flagAsSaved && IsModified();
m_DeletedVersion = Exist() ? -1 : 0;
ClearRedo();
XmlNodeRef latest = m_xmlVersionList.rbegin()->second;
m_xmlVersionList.clear();
m_xmlVersionList[ 0 ] = latest;
m_SavedVersion = wasModified ? -1 : 0;
}
////////////////////////////////////////////////////////////////////////////
SXmlHistoryGroup::SXmlHistoryGroup(CXmlHistoryManager* pManager, uint32 typeId)
: m_pManager(pManager)
, m_typeId(typeId)
{
}
////////////////////////////////////////////////////////////////////////////
SXmlHistory* SXmlHistoryGroup::GetHistory(int index) const
{
THistoryList::const_iterator it = m_List.begin();
while (index > 0 && it != m_List.end())
{
++it;
if ((*it)->Exist())
{
--index;
}
}
return it != m_List.end() ? *it : NULL;
}
////////////////////////////////////////////////////////////////////////////
int SXmlHistoryGroup::GetHistoryCount() const
{
int count = 0;
for (THistoryList::const_iterator it = m_List.begin(); it != m_List.end(); ++it)
{
if ((*it)->Exist())
{
count++;
}
}
return count;
}
////////////////////////////////////////////////////////////////////////////
SXmlHistory* SXmlHistoryGroup::GetHistoryByTypeId(uint32 typeId, int index /*= 0*/) const
{
for (int i = 0; i < GetHistoryCount(); ++i)
{
SXmlHistory* pHistory = GetHistory(i);
if (pHistory->GetTypeId() == typeId)
{
index--;
}
if (index == -1)
{
return pHistory;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////
int SXmlHistoryGroup::GetHistoryCountByTypeId(uint32 typeId) const
{
int res = 0;
for (int i = 0; i < GetHistoryCount(); ++i)
{
if (GetHistory(i)->GetTypeId() == typeId)
{
res++;
}
}
return res;
}
////////////////////////////////////////////////////////////////////////////
int SXmlHistoryGroup::CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion)
{
if (m_pManager)
{
m_List.push_back(m_pManager->CreateXmlHistory(typeId, xmlBaseVersion));
return m_List.size() - 1;
}
return -1;
}
////////////////////////////////////////////////////////////////////////////
int SXmlHistoryGroup::GetHistoryIndex(const SXmlHistory* pHistory) const
{
int index = 0;
for (THistoryList::const_iterator it = m_List.begin(); it != m_List.end(); ++it)
{
if (*it == pHistory)
{
return index;
}
index++;
}
return -1;
}
////////////////////////////////////////////////////////////////////////////
CXmlHistoryManager::CXmlHistoryManager()
: m_CurrentVersion(0)
, m_LatestVersion(0)
, m_pExclusiveListener(NULL)
, m_RecordNextVersion(false)
, m_pExActiveGroup(NULL)
, m_bIsActiveGroupEx(false)
{
m_pNullGroup = new SXmlHistoryGroup(this, (uint32) - 1);
}
CXmlHistoryManager::~CXmlHistoryManager()
{
delete m_pNullGroup;
}
/////////////////////////////////////////////////////////////////////////////
bool CXmlHistoryManager::Undo()
{
if (m_CurrentVersion > 0)
{
int prevVersion = m_CurrentVersion;
const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup();
m_CurrentVersion--;
ReloadCurrentVersion(pPrevCurrGroup, prevVersion);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
bool CXmlHistoryManager::Redo()
{
if (m_CurrentVersion < m_LatestVersion)
{
int prevVersion = m_CurrentVersion;
const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup();
m_CurrentVersion++;
ReloadCurrentVersion(pPrevCurrGroup, prevVersion);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
bool CXmlHistoryManager::Goto(int historyNum)
{
if (historyNum >= 0 && historyNum <= m_LatestVersion)
{
int prevVersion = m_CurrentVersion;
const SXmlHistoryGroup* pPrevCurrGroup = GetActiveGroup();
m_CurrentVersion = historyNum;
ReloadCurrentVersion(pPrevCurrGroup, prevVersion);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc)
{
ClearRedo();
SXmlHistory* pChangedXml = m_UndoEventHandlerMap[ pEventHandler ].CurrentData;
assert(pChangedXml);
XmlNodeRef newData = gEnv->pSystem->CreateXmlNode();
#if !defined(NDEBUG)
bool bRes =
#endif
pEventHandler->SaveToXml(newData);
assert(bRes);
TXmlHistotyGroupPtrList activeGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups;
pChangedXml->AddToHistory(newData);
m_UndoEventHandlerMap[ pEventHandler ].HistoryData[ m_CurrentVersion ] = pChangedXml;
m_HistoryInfoMap[ m_CurrentVersion ].HistoryDescription = desc;
m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo = false;
m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups = activeGroups;
m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = false;
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionAdded);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId /*= 0*/, bool destoryForever /*= false*/)
{
if (destoryForever)
{
UnregisterUndoEventHandler(pEventHandler);
}
else
{
m_InvalidHandlerMap[typeId] = pEventHandler;
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId)
{
TInvalidUndoEventListener::iterator it = m_InvalidHandlerMap.find(typeId);
if (it != m_InvalidHandlerMap.end())
{
IXmlUndoEventHandler* pLastHandler = it->second;
TUndoEventHandlerMap::iterator lastit = m_UndoEventHandlerMap.find(pLastHandler);
if (lastit != m_UndoEventHandlerMap.end())
{
m_UndoEventHandlerMap[pEventHandler] = lastit->second;
m_UndoEventHandlerMap.erase(lastit);
}
m_InvalidHandlerMap.erase(it);
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RegisterEventListener(IXmlHistoryEventListener* pEventListener)
{
stl::push_back_unique(m_EventListener, pEventListener);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::UnregisterEventListener(IXmlHistoryEventListener* pEventListener)
{
m_EventListener.remove(pEventListener);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::PrepareForNextVersion()
{
assert(!m_RecordNextVersion);
m_RecordNextVersion = true;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RecordNextVersion(SXmlHistory* pHistory, XmlNodeRef newData, const char* undoDesc /*= NULL*/)
{
assert(m_RecordNextVersion);
RegisterUndoEventHandler(this, pHistory);
m_newHistoryData = newData;
RecordUndo(this, undoDesc ? undoDesc : "<UNDEFINED>");
m_RecordNextVersion = false;
m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = true;
UnregisterUndoEventHandler(this);
SetActiveGroupInt(GetActiveGroup());
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryInvalidate);
}
/////////////////////////////////////////////////////////////////////////////
bool CXmlHistoryManager::SaveToXml(XmlNodeRef& xmlNode)
{
assert(m_newHistoryData);
xmlNode = m_newHistoryData;
return true;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::ClearHistory(bool flagAsSaved)
{
TXmlHistotyGroupPtrList activeGropus = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups;
for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it)
{
it->ClearHistory(flagAsSaved);
}
SetActiveGroup(NULL);
m_CurrentVersion = 0;
m_LatestVersion = 0;
m_UndoEventHandlerMap.clear();
m_HistoryInfoMap.clear();
m_HistoryInfoMap[ 0 ].HistoryDescription = "New History";
m_HistoryInfoMap[ 0 ].ActiveGroups = activeGropus;
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryCleared);
}
/////////////////////////////////////////////////////////////////////////////
const AZStd::string& CXmlHistoryManager::GetVersionDesc(int number) const
{
THistoryInfoMap::const_iterator it = m_HistoryInfoMap.find(number);
if (it != m_HistoryInfoMap.end())
{
return it->second.HistoryDescription;
}
static AZStd::string undef("UNDEFINED");
return undef;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RegisterView(IXmlHistoryView* pView)
{
stl::push_back_unique(m_Views, pView);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::UnregisterView(IXmlHistoryView* pView)
{
m_Views.remove(pView);
}
/////////////////////////////////////////////////////////////////////////////
SXmlHistoryGroup* CXmlHistoryManager::CreateXmlGroup(uint32 typeId)
{
m_Groups.push_back(SXmlHistoryGroup(this, typeId));
return &(*m_Groups.rbegin());
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::AddXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc /*= NULL*/)
{
RecordUndoInternal(undoDesc ? undoDesc : "New XML Group added");
m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups.push_back(pGroup);
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupAdded, (void*)pGroup);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RemoveXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc /*= NULL*/)
{
bool unload = m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup == pGroup;
RecordUndoInternal(undoDesc ? undoDesc : "XML Group deleted");
TXmlHistotyGroupPtrList& list = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups;
stl::find_and_erase(list, pGroup);
if (unload)
{
SetActiveGroupInt(NULL);
}
m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup = m_pNullGroup;
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupRemoved, (void*)pGroup);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::SetActiveGroup(const SXmlHistoryGroup* pGroup, const char* displayName /*= NULL*/, const TGroupIndexMap& groupIndex /*= TGroupIndexMap()*/, bool setExternal /*= false*/)
{
TGroupIndexMap userIndex;
const SXmlHistoryGroup* pActiveGroup = GetActiveGroup(userIndex);
if (pGroup != pActiveGroup || userIndex != groupIndex || setExternal)
{
const bool isEx = m_CurrentVersion != m_LatestVersion || setExternal;
m_pExActiveGroup = const_cast<SXmlHistoryGroup*>(pGroup);
m_ExCurrentIndex = groupIndex;
m_bIsActiveGroupEx = true;
SetActiveGroupInt(pGroup, displayName, !isEx, groupIndex);
m_bIsActiveGroupEx = isEx;
}
}
void CXmlHistoryManager::SetActiveGroupInt(const SXmlHistoryGroup* pGroup, const char* displayName /*= NULL*/, bool bRecordNullUndo /*= false*/, const TGroupIndexMap& groupIndex /*= TGroupIndexMap()*/)
{
UnloadInt();
TEventHandlerList eventHandler;
AZStd::string undoDesc;
if (pGroup)
{
for (TViews::iterator it = m_Views.begin(); it != m_Views.end(); ++it)
{
IXmlHistoryView* pView = *it;
std::map<uint32, int> userIndexCount;
for (SXmlHistoryGroup::THistoryList::const_iterator history = pGroup->m_List.begin(); history != pGroup->m_List.end(); ++history)
{
std::map<uint32, int>::iterator it2 = userIndexCount.find((*history)->GetTypeId());
if (it2 == userIndexCount.end())
{
userIndexCount[ (*history)->GetTypeId() ] = 0;
}
uint32 userindex = userIndexCount[ (*history)->GetTypeId() ];
IXmlUndoEventHandler* pEventHandler = NULL;
TGroupIndexMap::const_iterator indexIter = groupIndex.find((*history)->GetTypeId());
if (indexIter == groupIndex.end() || indexIter->second == userindex)
{
if ((*history)->Exist())
{
if (pView->LoadXml((*history)->GetTypeId(), (*history)->GetCurrentVersion(), pEventHandler, userindex))
{
if (pEventHandler)
{
m_UndoHandlerViewMap[ pEventHandler ] = pView;
RegisterUndoEventHandler(pEventHandler, *history);
eventHandler.push_back(pEventHandler);
}
}
}
}
if ((*history)->Exist())
{
userIndexCount[ (*history)->GetTypeId() ]++;
}
}
}
undoDesc = AZStd::string::format("Changed View to \"%s\"", displayName ? displayName : "UNDEFINED");
}
else
{
undoDesc = "Unloaded Views";
for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it)
{
eventHandler.push_back(it->first);
}
pGroup = m_pNullGroup;
}
if (bRecordNullUndo)
{
RecordNullUndo(eventHandler, undoDesc.c_str());
m_HistoryInfoMap[ m_CurrentVersion ].CurrGroup = pGroup;
m_HistoryInfoMap[ m_CurrentVersion ].CurrUserIndex = groupIndex;
}
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupChanged);
}
/////////////////////////////////////////////////////////////////////////////
const SXmlHistoryGroup* CXmlHistoryManager::GetActiveGroup() const
{
TGroupIndexMap userIndex;
return GetActiveGroup(userIndex);
}
/////////////////////////////////////////////////////////////////////////////
const SXmlHistoryGroup* CXmlHistoryManager::GetActiveGroup(TGroupIndexMap& currUserIndex /*out*/) const
{
if (m_bIsActiveGroupEx)
{
currUserIndex = m_ExCurrentIndex;
return m_pExActiveGroup;
}
int currVersion = m_CurrentVersion;
do
{
THistoryInfoMap::const_iterator it = m_HistoryInfoMap.find(currVersion);
if (it != m_HistoryInfoMap.end())
{
const SXmlHistoryGroup* pGroup = it->second.CurrGroup;
if (it != m_HistoryInfoMap.end() && pGroup)
{
currUserIndex = it->second.CurrUserIndex;
return pGroup == m_pNullGroup ? NULL : pGroup;
}
}
currVersion--;
} while (currVersion >= 0);
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
SXmlHistory* CXmlHistoryManager::CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion)
{
m_XmlHistoryList.push_back(SXmlHistory(this, xmlBaseVersion, typeId));
return &(*m_XmlHistoryList.rbegin());
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::DeleteXmlHistory(const SXmlHistory* pXmlHistry)
{
for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it)
{
if (&(*it) == pXmlHistry)
{
m_XmlHistoryList.erase(it);
return;
}
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::UnloadInt()
{
for (TViews::iterator it = m_Views.begin(); it != m_Views.end(); ++it)
{
IXmlHistoryView* pView = *it;
pView->UnloadXml(-1);
}
}
/////////////////////////////////////////////////////////////////////////////
namespace
{
template< class T >
void ClearAfterVersion(T& container, int version)
{
auto foundit = container.end();
do
{
auto it = container.find(version);
if (it != container.end())
{
foundit = it;
break;
}
version--;
} while (version >= 0);
if (foundit != container.end())
{
for (auto it = ++foundit; it != container.end(); )
{
container.erase(it++);
}
}
}
}
void CXmlHistoryManager::ClearRedo()
{
ClearAfterVersion(m_HistoryInfoMap, m_CurrentVersion);
for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it)
{
ClearAfterVersion(it->second.HistoryData, m_CurrentVersion);
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::DeleteAll()
{
ClearHistory();
m_Groups.clear();
m_UndoEventHandlerMap.clear();
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryDeleted);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::FlagHistoryAsSaved()
{
for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it)
{
it->FlagAsSaved();
}
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistorySaved);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RecordNullUndo(const TEventHandlerList& eventHandler, const char* desc, bool isNull /*= true*/)
{
TXmlHistotyGroupPtrList activeGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups;
// if current version is already null undo, overwrite it instead of create a new version
if (m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo && isNull)
{
assert(m_CurrentVersion);
m_CurrentVersion--;
}
ClearRedo();
IncrementVersion();
for (TEventHandlerList::const_iterator it = eventHandler.begin(); it != eventHandler.end(); ++it)
{
SXmlHistory* pChangedXml = m_UndoEventHandlerMap[ *it ].CurrentData;
m_UndoEventHandlerMap[ *it ].HistoryData[ m_CurrentVersion ] = pChangedXml;
}
m_HistoryInfoMap[ m_CurrentVersion ].HistoryDescription = desc;
m_HistoryInfoMap[ m_CurrentVersion ].IsNullUndo = isNull;
m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups = activeGroups;
m_HistoryInfoMap[ m_CurrentVersion ].HistoryInvalidated = false;
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionAdded);
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::ReloadCurrentVersion(const SXmlHistoryGroup* pPrevGroup, int prevVersion)
{
m_bIsActiveGroupEx = false;
const SXmlHistoryGroup* pActiveGroup = GetActiveGroup();
bool bInvalidated = false;
int start = min(prevVersion, m_CurrentVersion);
int end = max(prevVersion, m_CurrentVersion);
for (int i = start; i <= end; ++i)
{
if (m_HistoryInfoMap[i].HistoryInvalidated)
{
bInvalidated = true;
break;
}
}
if (!bInvalidated && pPrevGroup == pActiveGroup)
{
for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it)
{
IXmlUndoEventHandler* pEventHandler = it->first;
if (!IsEventHandlerValid(pEventHandler))
{
assert(false);
continue;
}
SXmlHistory* pXmlHistory = GetLatestHistory(m_UndoEventHandlerMap[ pEventHandler ]); /*m_UndoEventHandlerMap[ pEventHandler ].HistoryData[ m_CurrentVersion ];*/
if (pXmlHistory)
{
if (pXmlHistory->Exist())
{
pEventHandler->ReloadFromXml(pXmlHistory->GetCurrentVersion());
}
}
}
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_VersionChanged);
}
else
{
SetActiveGroupInt(pActiveGroup);
}
if (bInvalidated)
{
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryInvalidate);
}
TXmlHistotyGroupPtrList oldActiveGroups = m_HistoryInfoMap[ prevVersion ].ActiveGroups;
TXmlHistotyGroupPtrList newActiveGroups = m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups;
RemoveListFromList(newActiveGroups, oldActiveGroups);
RemoveListFromList(oldActiveGroups, m_HistoryInfoMap[ m_CurrentVersion ].ActiveGroups);
for (TXmlHistotyGroupPtrList::iterator it = newActiveGroups.begin(); it != newActiveGroups.end(); ++it)
{
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupAdded, (void*) *it);
}
for (TXmlHistotyGroupPtrList::iterator it = oldActiveGroups.begin(); it != oldActiveGroups.end(); ++it)
{
NotifyUndoEventListener(IXmlHistoryEventListener::eHET_HistoryGroupRemoved, (void*) *it);
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RemoveListFromList(TXmlHistotyGroupPtrList& list, const TXmlHistotyGroupPtrList& removeList)
{
for (TXmlHistotyGroupPtrList::const_iterator rit = removeList.begin(); rit != removeList.end(); ++rit)
{
for (TXmlHistotyGroupPtrList::iterator it = list.begin(); it != list.end(); ++it)
{
if (*it == *rit)
{
list.erase(it);
break;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
SXmlHistory* CXmlHistoryManager::GetLatestHistory(SUndoEventHandlerData& eventHandlerData)
{
int currVersion = m_CurrentVersion;
do
{
THistoryVersionMap::iterator it = eventHandlerData.HistoryData.find(currVersion);
if (it != eventHandlerData.HistoryData.end())
{
return it->second;
}
currVersion--;
} while (currVersion >= 0);
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::NotifyUndoEventListener(IXmlHistoryEventListener::EHistoryEventType event, void* pData)
{
if (m_pExclusiveListener)
{
m_pExclusiveListener->OnEvent(event, pData);
}
else
{
for (TEventListener::iterator it = m_EventListener.begin(); it != m_EventListener.end(); ++it)
{
(*it)->OnEvent(event, pData);
}
}
}
/////////////////////////////////////////////////////////////////////////////
int CXmlHistoryManager::IncrementVersion([[maybe_unused]] SXmlHistory* pXmlHistry)
{
for (TXmlHistoryList::iterator it = m_XmlHistoryList.begin(); it != m_XmlHistoryList.end(); ++it)
{
it->ClearRedo();
}
return IncrementVersion();
}
/////////////////////////////////////////////////////////////////////////////
int CXmlHistoryManager::IncrementVersion()
{
m_CurrentVersion++;
m_LatestVersion = m_CurrentVersion;
return m_CurrentVersion;
}
////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RegisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler, SXmlHistory* pXmlData)
{
m_UndoEventHandlerMap[ pEventHandler ].CurrentData = pXmlData;
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::UnregisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler)
{
TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.find(pEventHandler);
if (it != m_UndoEventHandlerMap.end())
{
m_UndoEventHandlerMap.erase(it);
}
}
/////////////////////////////////////////////////////////////////////////////
void CXmlHistoryManager::RecordUndoInternal(const char* desc)
{
TEventHandlerList eventHandler;
for (TUndoEventHandlerMap::iterator it = m_UndoEventHandlerMap.begin(); it != m_UndoEventHandlerMap.end(); ++it)
{
eventHandler.push_back(it->first);
}
RecordNullUndo(eventHandler, desc, false);
}
/////////////////////////////////////////////////////////////////////////////
bool CXmlHistoryManager::IsEventHandlerValid(IXmlUndoEventHandler* pEventHandler)
{
for (TInvalidUndoEventListener::iterator it = m_InvalidHandlerMap.begin(); it != m_InvalidHandlerMap.end(); ++it)
{
if (it->second == pEventHandler)
{
return false;
}
}
return true;
}
-218
View File
@@ -1,218 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H
#define CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H
#pragma once
#include "IXmlHistoryManager.h"
class CXmlHistoryManager;
struct SXmlHistory
{
public:
SXmlHistory(CXmlHistoryManager* pManager, const XmlNodeRef& xmlBaseVersion, uint32 typeId);
void AddToHistory(const XmlNodeRef& newXmlVersion);
const XmlNodeRef& Undo(bool* bVersionExist = NULL);
const XmlNodeRef& Redo();
const XmlNodeRef& GetCurrentVersion(bool* bVersionExist = NULL, int* iVersionNumber = NULL) const;
bool IsModified() const;
uint32 GetTypeId() const {return m_typeId; }
void FlagAsDeleted();
void FlagAsSaved();
bool Exist() const;
private:
friend class CXmlHistoryManager;
void ClearRedo();
void ClearHistory(bool flagAsSaved);
private:
CXmlHistoryManager* m_pManager;
uint32 m_typeId;
int m_DeletedVersion;
int m_SavedVersion;
typedef std::map< int, XmlNodeRef > TXmlVersionMap;
TXmlVersionMap m_xmlVersionList;
};
struct SXmlHistoryGroup
{
SXmlHistoryGroup(CXmlHistoryManager* pManager, uint32 typeId);
SXmlHistory* GetHistory(int index) const;
int GetHistoryCount() const;
SXmlHistory* GetHistoryByTypeId(uint32 typeId, int index = 0) const;
int GetHistoryCountByTypeId(uint32 typeId) const;
int CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion);
uint32 GetTypeId() const {return m_typeId; }
int GetHistoryIndex(const SXmlHistory* pHistory) const;
private:
friend class CXmlHistoryManager;
CXmlHistoryManager* m_pManager;
uint32 m_typeId;
typedef std::list< SXmlHistory* > THistoryList;
THistoryList m_List;
};
typedef std::map<uint32, int> TGroupIndexMap;
class CXmlHistoryManager
: public IXmlHistoryManager
, public IXmlUndoEventHandler
{
public:
CXmlHistoryManager();
~CXmlHistoryManager();
// Undo/Redo
bool Undo();
bool Redo();
bool Goto(int historyNum);
void RecordUndo(IXmlUndoEventHandler* pEventHandler, const char* desc);
void UndoEventHandlerDestroyed(IXmlUndoEventHandler* pEventHandler, uint32 typeId = 0, bool destoryForever = false);
void RestoreUndoEventHandler(IXmlUndoEventHandler* pEventHandler, uint32 typeId);
void PrepareForNextVersion();
void RecordNextVersion(SXmlHistory* pHistory, XmlNodeRef newData, const char* undoDesc = NULL);
bool IsPreparedForNextVersion() const {return m_RecordNextVersion; }
void RegisterEventListener(IXmlHistoryEventListener* pEventListener);
void UnregisterEventListener(IXmlHistoryEventListener* pEventListener);
void SetExclusiveListener(IXmlHistoryEventListener* pEventListener) { m_pExclusiveListener = pEventListener; }
// History
void ClearHistory(bool flagAsSaved = false);
int GetVersionCount() const { return m_LatestVersion; }
const AZStd::string& GetVersionDesc(int number) const;
int GetCurrentVersionNumber() const { return m_CurrentVersion; }
// Views
void RegisterView(IXmlHistoryView* pView);
void UnregisterView(IXmlHistoryView* pView);
// Xml History Groups
SXmlHistoryGroup* CreateXmlGroup(uint32 typeId);
void SetActiveGroup(const SXmlHistoryGroup* pGroup, const char* displayName = NULL, const TGroupIndexMap& groupIndex = TGroupIndexMap(), bool setExternal = false);
const SXmlHistoryGroup* GetActiveGroup() const;
const SXmlHistoryGroup* GetActiveGroup(TGroupIndexMap& currUserIndex /*out*/) const;
void AddXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc = NULL);
void RemoveXmlGroup(const SXmlHistoryGroup* pGroup, const char* undoDesc = NULL);
void DeleteAll();
void FlagHistoryAsSaved();
virtual bool SaveToXml(XmlNodeRef& xmlNode);
virtual bool LoadFromXml([[maybe_unused]] const XmlNodeRef& xmlNode) { return false; };
virtual bool ReloadFromXml([[maybe_unused]] const XmlNodeRef& xmlNode) { return false; };
private:
typedef std::list< SXmlHistory > TXmlHistoryList;
TXmlHistoryList m_XmlHistoryList;
int m_CurrentVersion;
int m_LatestVersion;
SXmlHistoryGroup* m_pNullGroup; // hack for unload view ...
XmlNodeRef m_newHistoryData;
bool m_RecordNextVersion;
bool m_bIsActiveGroupEx;
SXmlHistoryGroup* m_pExActiveGroup;
TGroupIndexMap m_ExCurrentIndex;
typedef std::list< SXmlHistoryGroup > TXmlHistotyGroupList;
TXmlHistotyGroupList m_Groups;
// event listener
typedef std::list< IXmlHistoryEventListener* > TEventListener;
TEventListener m_EventListener;
IXmlHistoryEventListener* m_pExclusiveListener;
// views
typedef std::list< IXmlHistoryView* > TViews;
TViews m_Views;
typedef std::list< const SXmlHistoryGroup* > TXmlHistotyGroupPtrList;
// history
struct SHistoryInfo
{
SHistoryInfo()
: IsNullUndo(false)
, CurrGroup(NULL)
, HistoryInvalidated(false) {}
const SXmlHistoryGroup* CurrGroup;
TGroupIndexMap CurrUserIndex;
AZStd::string HistoryDescription;
bool IsNullUndo;
bool HistoryInvalidated;
TXmlHistotyGroupPtrList ActiveGroups;
};
typedef std::map< int, SHistoryInfo > THistoryInfoMap;
THistoryInfoMap m_HistoryInfoMap;
// undo event handler
typedef std::map< int, SXmlHistory* > THistoryVersionMap;
struct SUndoEventHandlerData
{
SUndoEventHandlerData()
: CurrentData(NULL) {}
SXmlHistory* CurrentData;
THistoryVersionMap HistoryData;
};
typedef std::map< IXmlUndoEventHandler*, SUndoEventHandlerData > TUndoEventHandlerMap;
TUndoEventHandlerMap m_UndoEventHandlerMap;
typedef std::map< IXmlUndoEventHandler*, IXmlHistoryView* > TUndoHandlerViewMap;
TUndoHandlerViewMap m_UndoHandlerViewMap;
typedef std::map< uint32, IXmlUndoEventHandler* > TInvalidUndoEventListener;
TInvalidUndoEventListener m_InvalidHandlerMap;
private:
friend struct SXmlHistory;
friend struct SXmlHistoryGroup;
int IncrementVersion(SXmlHistory* pXmlHistry);
int IncrementVersion();
SXmlHistory* CreateXmlHistory(uint32 typeId, const XmlNodeRef& xmlBaseVersion);
void DeleteXmlHistory(const SXmlHistory* pXmlHistry);
void RegisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler, SXmlHistory* pXmlData);
void UnregisterUndoEventHandler(IXmlUndoEventHandler* pEventHandler);
typedef std::list< IXmlUndoEventHandler* > TEventHandlerList;
void RecordNullUndo(const TEventHandlerList& eventHandler, const char* desc, bool isNull = true);
void ReloadCurrentVersion(const SXmlHistoryGroup* pPrevGroup, int prevVersion);
SXmlHistory* GetLatestHistory(SUndoEventHandlerData& eventHandlerData);
void NotifyUndoEventListener(IXmlHistoryEventListener::EHistoryEventType event, void* pData = NULL);
void SetActiveGroupInt(const SXmlHistoryGroup* pGroup, const char* displayName = NULL, bool bRecordNullUndo = false, const TGroupIndexMap& groupIndex = TGroupIndexMap());
void UnloadInt();
void ClearRedo();
void RecordUndoInternal(const char* desc);
void RemoveListFromList(TXmlHistotyGroupPtrList& list, const TXmlHistotyGroupPtrList& removeList);
bool IsEventHandlerValid(IXmlUndoEventHandler* pEventHandler);
};
#endif // CRYINCLUDE_EDITOR_UTIL_XMLHISTORYMANAGER_H
-4
View File
@@ -498,9 +498,7 @@ set(FILES
UndoViewPosition.h
UndoViewRotation.h
Util/GeometryUtil.h
Util/IXmlHistoryManager.h
Util/KDTree.h
Util/XmlHistoryManager.h
WipFeaturesDlg.h
WipFeaturesDlg.ui
WipFeaturesDlg.qrc
@@ -737,14 +735,12 @@ set(FILES
Util/PredefinedAspectRatios.h
Util/StringHelpers.cpp
Util/StringHelpers.h
Util/StringNoCasePredicate.h
Util/TRefCountBase.h
Util/Triangulate.cpp
Util/Triangulate.h
Util/Util.h
Util/XmlArchive.cpp
Util/XmlArchive.h
Util/XmlHistoryManager.cpp
Util/XmlTemplate.cpp
Util/XmlTemplate.h
Util/bitarray.h