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:
parent
3402992189
commit
78ca464c65
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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{};
|
||||
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue