Skip to content

Commit

Permalink
Fix undo/redo Prefab overrides properties UID + Undo/Redo destroy WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Benualdo committed Sep 30, 2024
1 parent a51b97e commit 1676ff3
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 63 deletions.
8 changes: 4 additions & 4 deletions Editor.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Root>
<Object class="EditorOptions">
<Property type="Uint32" name="m_uid" flags="Debug|Hexadecimal" value="3465924071"/>
<Property type="Uint32" name="m_originalUID" flags="Debug|Hexadecimal" value="0"/>
<Property type="String" name="m_name" flags="NotVisible" value="Editor Options"/>
<Property type="EnumFlagsU32" name="m_objectFlags" flags="Debug|Bitfield" value=""/>
<Property type="Uint32" name="m_uid" flags="" value="3465924071"/>
<Property type="Uint32" name="m_originalUID" flags="" value="0"/>
<Property type="EnumFlagsU32" name="m_objectFlags" flags="" value=""/>
<Property type="EnumU8" name="m_theme" value="VimontGames_Dark"/>
<Property type="EnumU8" name="m_gizmo.m_type" value="Translate"/>
<Property type="EnumU8" name="m_gizmo.m_space" value="World"/>
Expand All @@ -14,6 +14,6 @@
<Property type="Bool" name="m_gizmo.m_snapScale" flags="NotVisible" value="true"/>
<Property type="Float" name="m_gizmo.m_scaleSnap" flags="Optional" value="0.5"/>
<Property type="EnumFlagsU32" name="m_consoleOptions.m_levels" flags="Bitfield" value="Warning|Error"/>
<Property type="EnumFlagsU64" name="m_debugFlags" flags="Bitfield" value=""/>
<Property type="EnumFlagsU64" name="m_debugFlags" flags="Bitfield" value="Properties"/>
</Object>
</Root>
40 changes: 20 additions & 20 deletions data/Scenes/Aiguelongue.scene

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/core/IFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace vg::core
virtual UID RegisterUID (IObject * _object) = 0;
virtual void ReleaseUID (IObject * _object, UID & _uid) = 0;
virtual const UIDObjectHash & GetUIDObjects () const = 0;
virtual IObject * FindByUID (UID _uid) = 0;
virtual IObject * FindByUID (UID _uid) const = 0;
};
}

Expand Down
8 changes: 4 additions & 4 deletions src/core/Object/DynamicProperties/DynamicProperty.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace vg::core
{
super::registerProperties(_desc);
setPropertyFlag(DynamicProperty, m_name, PropertyFlags::NotVisible, true);
setPropertyFlag(DynamicProperty, m_uid, PropertyFlags::NotVisible, true);
//setPropertyFlag(DynamicProperty, m_uid, PropertyFlags::NotVisible, true);
setPropertyFlag(DynamicProperty, m_originalUID, PropertyFlags::NotVisible, true);
setPropertyFlag(DynamicProperty, m_objectFlags, PropertyFlags::NotVisible, true);

Expand All @@ -21,18 +21,18 @@ namespace vg::core
{
SetName(_name);
SetParent(_parent);
RegisterUID();
}

//--------------------------------------------------------------------------------------
DynamicProperty::~DynamicProperty()
{

}

//--------------------------------------------------------------------------------------
bool DynamicProperty::RegisterUID()
{
return false;
return super::RegisterUID();
}

}
6 changes: 3 additions & 3 deletions src/core/Object/Factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ namespace vg::core
}

//--------------------------------------------------------------------------------------
IObject * Factory::FindByUID(UID _uid)
IObject * Factory::FindByUID(UID _uid) const
{
lock_guard<mutex> lock(m_uidObjectHashMutex);

Expand Down Expand Up @@ -822,7 +822,7 @@ namespace vg::core
if (it != m_initValues.end())
{
io::Buffer * buffer = it->second;
bool result = serializeFromMemory(_object, *buffer);
bool result = serializeObjectFromMemory(_object, *buffer);
VG_SAFE_DELETE(it->second);
m_initValues.erase(it);
return result;
Expand All @@ -832,7 +832,7 @@ namespace vg::core
}

//--------------------------------------------------------------------------------------
bool Factory::serializeFromMemory(IObject * _object, io::Buffer & _buffer)
bool Factory::serializeObjectFromMemory(IObject * _object, io::Buffer & _buffer)
{
const char * className = _object->GetClassName();
const auto * classDesc = GetClassDescriptor(className);
Expand Down
6 changes: 3 additions & 3 deletions src/core/Object/Factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace vg::core
UID RegisterUID (IObject * _object) final override;
void ReleaseUID (IObject * _object, UID & _uid) final override;
const UIDObjectHash & GetUIDObjects () const final override;
IObject * FindByUID (UID _uid) final override;
IObject * FindByUID (UID _uid) const final override;

//protected:
bool SerializeFromXML (IObject * _object, const XMLElem * _xmlElem) const;
Expand All @@ -62,7 +62,7 @@ namespace vg::core
bool serializeObjectToMemory (const IObject * _object, io::Buffer & _buffer);
void serializePropertyToMemory (const IObject * _object, const IProperty * _prop, io::Buffer & _buffer);

bool serializeFromMemory (IObject * _object, io::Buffer & _buffer);
bool serializeObjectFromMemory (IObject * _object, io::Buffer & _buffer);
void serializePropertyFromMemory (IObject * _object, const IProperty * _prop, io::Buffer & _buffer);

void ReleaseAsync (core::IObject * _object);
Expand All @@ -84,6 +84,6 @@ namespace vg::core
u8 m_objectsToReleaseTableIndex = 0;
core::unordered_map<IObject *, io::Buffer*> m_initValues;
UIDObjectHash m_uidObjectHash;
mutex m_uidObjectHashMutex;
mutable mutex m_uidObjectHashMutex;
};
}
38 changes: 38 additions & 0 deletions src/core/UndoRedo/Entry/UndoRedoDestroyEntry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "core/IUndoRedo.h"
#include "core/File/Buffer.h"

namespace vg::core
{
class IObject;
class IProperty;
class IDynamicProperty;

//--------------------------------------------------------------------------------------
class UndoRedoDestroyEntry final : public UndoRedoEntry
{
using super = UndoRedoEntry;

public:
UndoRedoDestroyEntry(IObject * _object, IObject * _parent, uint _indexInParent);

void BeforeChange() final override;
void AfterChange() final override;

void Undo() final override;
void Redo() final override;

string GetEntryName() const final override;
string GetObjectName() const final override;
string GetDescription() const final override;

IObject * getParent() const;

private:
io::Buffer m_buffer;
string m_className;
UID m_parentUID;
uint m_indexInParent;
};
}
91 changes: 91 additions & 0 deletions src/core/UndoRedo/Entry/UndoRedoDestroyEntry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "UndoRedoDestroyEntry.h"
#include "core/Kernel.h"
#include "core/Object/Factory.h"
#include "core/IGameObject.h"
#include "core/string/string.h"

namespace vg::core
{
//--------------------------------------------------------------------------------------
UndoRedoDestroyEntry::UndoRedoDestroyEntry(IObject * _object, IObject * _parent, uint _indexInParent) :
UndoRedoEntry(_object)
{
m_className = _object->GetClassName();
m_parentUID = _parent->GetUID();
m_indexInParent = _indexInParent;
}

//--------------------------------------------------------------------------------------
void UndoRedoDestroyEntry::BeforeChange()
{
Factory * factory = (Factory *)Kernel::getFactory();
if (auto * object = GetObject())
{
m_buffer.resetWrite();
factory->serializeObjectToMemory(object, m_buffer);
}
}

//--------------------------------------------------------------------------------------
void UndoRedoDestroyEntry::AfterChange()
{

}

//--------------------------------------------------------------------------------------
string UndoRedoDestroyEntry::GetEntryName() const
{
return "Destroy";
}

//--------------------------------------------------------------------------------------
string UndoRedoDestroyEntry::GetObjectName() const
{
return super::GetObjectName();
}

//--------------------------------------------------------------------------------------
string UndoRedoDestroyEntry::GetDescription() const
{
return fmt::sprintf("(%s) \"%s\"", m_className, m_objectName);
}

//--------------------------------------------------------------------------------------
IObject * UndoRedoDestroyEntry::getParent() const
{
IFactory * factory = Kernel::getFactory();
return factory->FindByUID(m_parentUID);
}

//--------------------------------------------------------------------------------------
void UndoRedoDestroyEntry::Undo()
{
VG_INFO("[Undo/Redo] Undo Destroy Object %s (UID=0x%08X)", GetDescription().c_str(), m_objectUID);

Factory * factory = (Factory *)Kernel::getFactory();

if (IGameObject * parent = dynamic_cast<IGameObject*>(getParent()))
{
IGameObject * obj = (IGameObject*)factory->CreateObject(m_className.c_str(), m_objectName, parent);
m_buffer.resetRead();
factory->serializeObjectFromMemory(obj, m_buffer);
VG_ASSERT(m_objectUID == obj->GetUID());

parent->AddChild(obj);
//obj->OnLoad();
obj->Release();
}
}

//--------------------------------------------------------------------------------------
void UndoRedoDestroyEntry::Redo()
{
VG_INFO("[Undo/Redo] Redo Destroy Object \"%s\" (UID=0x%08X)", m_objectName.c_str(), m_objectUID);

if (auto * obj = dynamic_cast<IGameObject *>(GetObject()))
{
if (auto * parent = dynamic_cast<IGameObject *>(obj->GetParent()))
parent->RemoveChild(obj);
}
}
}
2 changes: 0 additions & 2 deletions src/core/UndoRedo/Entry/UndoRedoPropertyEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ namespace vg::core
class IProperty;
class IDynamicProperty;

//--------------------------------------------------------------------------------------
// TODO: do not store object raw pointers but safe GUID instead
//--------------------------------------------------------------------------------------
class UndoRedoPropertyEntry final : public UndoRedoEntry
{
Expand Down
1 change: 1 addition & 0 deletions src/core/UndoRedo/UndoRedo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "UndoRedoEntry.hpp"
#include "UndoRedoEntryGroup.hpp"
#include "Entry/UndoRedoPropertyEntry.hpp"
#include "Entry/UndoRedoDestroyEntry.hpp"

namespace vg::core
{
Expand Down
1 change: 1 addition & 0 deletions src/core/UndoRedo/UndoRedo.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "UndoRedo_consts.h"
#include "UndoRedoManager.h"
#include "Entry/UndoRedoPropertyEntry.h"
#include "Entry/UndoRedoDestroyEntry.h"

namespace vg::core
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/UndoRedo/UndoRedoEntry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace vg::core
{
if (nullptr != _object)
{
m_objectUID = _object->GetUID();
m_objectUID = _object->GetUID(false);
VG_ASSERT(m_objectUID);

m_objectName = _object->GetName();
Expand Down
2 changes: 2 additions & 0 deletions src/core/core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@
<ClInclude Include="Types\Enum.h" />
<ClInclude Include="Types\Types.h" />
<ClInclude Include="Types\Traits.h" />
<ClInclude Include="UndoRedo\Entry\UndoRedoDestroyEntry.h" />
<ClInclude Include="UndoRedo\Entry\UndoRedoDestroyEntry.hpp" />
<ClInclude Include="UndoRedo\Entry\UndoRedoPropertyEntry.h" />
<ClInclude Include="UndoRedo\Entry\UndoRedoPropertyEntry.hpp" />
<ClInclude Include="UndoRedo\UndoRedo.h" />
Expand Down
6 changes: 6 additions & 0 deletions src/core/core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,12 @@
<ClInclude Include="UndoRedo\UndoRedoEntryGroup.hpp">
<Filter>UndoRedo</Filter>
</ClInclude>
<ClInclude Include="UndoRedo\Entry\UndoRedoDestroyEntry.h">
<Filter>UndoRedo\Entry</Filter>
</ClInclude>
<ClInclude Include="UndoRedo\Entry\UndoRedoDestroyEntry.hpp">
<Filter>UndoRedo\Entry</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math\Math.cpp">
Expand Down
33 changes: 24 additions & 9 deletions src/editor/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "core/IGameObject.h"
#include "core/File/File.h"
#include "core/Timer/Timer.h"
#include "core/UndoRedo/UndoRedo.h"
#include "gfx/IViewGUI.h"
#include "renderer/IRenderer.h"
#include "renderer/IImGuiAdapter.h"
Expand Down Expand Up @@ -751,16 +752,30 @@ namespace vg::editor
void Editor::deleteGameObjects(core::vector<IGameObject *> & _gameObjects)
{
ImGui::OnMsgBoxClickedFunc deleteGameObject = [=]() mutable
{
auto * undoRedoManager = Kernel::getUndoRedoManager();

// Prepare undo/redo
UndoRedoTarget undoRedoTarget(this, nullptr);

auto * undoRedoGroup = new UndoRedoEntryGroup("Destroy");
for (uint i = 0; i < _gameObjects.size(); ++i)
undoRedoGroup->AddSubEntry(new UndoRedoDestroyEntry(_gameObjects[i], _gameObjects[i]->GetParent(), i));
undoRedoManager->BeforeChange(undoRedoGroup);

for (uint i = 0; i < _gameObjects.size(); ++i)
{
for (uint i = 0; i < _gameObjects.size(); ++i)
{
IGameObject * gameObjectToDelete = _gameObjects[i];
IGameObject * parentGameObject = dynamic_cast<IGameObject *>(gameObjectToDelete->GetParent());
if (nullptr != parentGameObject)
parentGameObject->RemoveChild(gameObjectToDelete);
}
return true;
};
IGameObject * gameObjectToDelete = _gameObjects[i];
IGameObject * parentGameObject = dynamic_cast<IGameObject *>(gameObjectToDelete->GetParent());
if (nullptr != parentGameObject)
parentGameObject->RemoveChild(gameObjectToDelete);
}

// Finalize Undo/Redo entry after editing
undoRedoManager->AfterChange();

return true;
};

string msg;
if (_gameObjects.size() > 1)
Expand Down
Loading

0 comments on commit 1676ff3

Please sign in to comment.