Editor now uses separate stacks; 1 set of stacks when in play and another set of stacks otherwise.

CommandStack now uses SHDeque
This commit is contained in:
Sri Sham Haran 2022-11-12 18:22:45 +08:00
parent 3402992189
commit 78ca464c65
4 changed files with 141 additions and 22 deletions

View File

@ -10,63 +10,102 @@
namespace SHADE
{
SHCommandManager::CommandStack SHCommandManager::undoStack{};
SHCommandManager::CommandStack SHCommandManager::redoStack{};
SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize);
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
{
redoStack = CommandStack();
*pCurrRedoStack = CommandStack(defaultStackSize);
commandPtr->Execute();
if (overrideValue && !undoStack.empty())
if (overrideValue && !pCurrUndoStack->Empty())
{
undoStack.top()->Merge(commandPtr);
pCurrUndoStack->Top()->Merge(commandPtr);
}
else
{
undoStack.push(commandPtr);
pCurrUndoStack->Push(commandPtr);
}
}
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
{
undoStack.push(commandPtr);
pCurrUndoStack->Push(commandPtr);
}
void SHCommandManager::UndoCommand()
{
if (undoStack.empty())
if (pCurrUndoStack->Empty())
return;
undoStack.top()->Undo();
redoStack.push(undoStack.top());
undoStack.pop();
pCurrUndoStack->Top()->Undo();
pCurrRedoStack->Push(pCurrUndoStack->Top());
pCurrUndoStack->Pop();
}
void SHCommandManager::RedoCommand()
{
if (redoStack.empty())
if (pCurrRedoStack->Empty())
return;
redoStack.top()->Execute();
undoStack.push(redoStack.top());
redoStack.pop();
pCurrRedoStack->Top()->Execute();
pCurrUndoStack->Push(pCurrRedoStack->Top());
pCurrRedoStack->Pop();
}
std::size_t SHCommandManager::GetUndoStackSize()
{
return undoStack.size();
return pCurrUndoStack->Size();
}
std::size_t SHCommandManager::GetRedoStackSize()
{
return redoStack.size();
return pCurrRedoStack->Size();
}
void SHCommandManager::PopLatestCommandFromRedoStack()
{
redoStack.pop();
pCurrRedoStack->Pop();
}
void SHCommandManager::PopLatestCommandFromUndoStack()
{
undoStack.pop();
pCurrUndoStack->Pop();
}
void SHCommandManager::SwapStacks()
{
if (pCurrUndoStack == &undoStack)
{
pCurrUndoStack = &secondaryUndoStack;
}
else
{
secondaryUndoStack.Clear();
pCurrUndoStack = &undoStack;
}
if (pCurrRedoStack == &redoStack)
{
pCurrRedoStack = &secondaryRedoStack;
}
else
{
secondaryRedoStack.Clear();
pCurrRedoStack = &redoStack;
}
}
void SHCommandManager::ClearAll()
{
undoStack.Clear();
redoStack.Clear();
secondaryUndoStack.Clear();
secondaryRedoStack.Clear();
}
}//namespace SHADE

View File

@ -10,6 +10,7 @@
//#==============================================================#
#include "SHCommand.hpp"
#include "SH_API.h"
#include "Tools/SHDeque.h"
namespace SHADE
{
@ -22,7 +23,8 @@ namespace SHADE
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
template<typename T>
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
using CommandStack = std::stack<BaseCommandPtr>;
using CommandStack = SHDeque<BaseCommandPtr>;
using CommandStackPtr = CommandStack*;
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
static void RegisterCommand(BaseCommandPtr commandPtr);
@ -34,8 +36,17 @@ namespace SHADE
static void PopLatestCommandFromRedoStack();
static void PopLatestCommandFromUndoStack();
static void SwapStacks();
static void ClearAll();
static constexpr CommandStack::SizeType defaultStackSize = 100;
private:
static CommandStackPtr pCurrUndoStack;
static CommandStackPtr pCurrRedoStack;
static CommandStack undoStack;
static CommandStack secondaryUndoStack;
static CommandStack redoStack;
static CommandStack secondaryRedoStack;
};
}//namespace SHADE

View File

@ -228,7 +228,7 @@ namespace SHADE
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PLAY;
SHCommandManager::SwapStacks();
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
}
}
@ -253,7 +253,7 @@ namespace SHADE
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::STOP;
SHCommandManager::SwapStacks();
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
}

View File

@ -0,0 +1,69 @@
#pragma once
#pragma once
#include "SH_API.h"
#include <deque>
namespace SHADE
{
template<typename T>
class SH_API SHDeque
{
public:
using ValueType = T;
using Pointer = T*;
using ValueRef = T&;
using ValueConstRef = T const&;
using SizeType = uint32_t;
using ContainerType = std::deque<ValueType>;
using ContainerTypeConstRef = std::deque<ValueType>;
SHDeque(SizeType n) : max_size(n) {}
ContainerTypeConstRef const& GetDeque() const
{
return deque;
}
void Push(ValueConstRef obj)
{
if (deque.size() < max_size)
deque.push_front(std::move(obj));
else
{
deque.pop_back();
deque.push_front(std::move(obj));
}
}
bool Empty()
{
return deque.empty();
}
void Pop()
{
deque.pop_front();
}
ValueConstRef Top()
{
return deque.front();
}
SizeType Size() const noexcept
{
return deque.size();
}
void Clear()
{
deque.clear();
}
private:
int max_size;
ContainerType deque{};
};
}