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
|
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)
|
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||||
{
|
{
|
||||||
redoStack = CommandStack();
|
*pCurrRedoStack = CommandStack(defaultStackSize);
|
||||||
commandPtr->Execute();
|
commandPtr->Execute();
|
||||||
if (overrideValue && !undoStack.empty())
|
if (overrideValue && !pCurrUndoStack->Empty())
|
||||||
{
|
{
|
||||||
undoStack.top()->Merge(commandPtr);
|
pCurrUndoStack->Top()->Merge(commandPtr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
undoStack.push(commandPtr);
|
pCurrUndoStack->Push(commandPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
||||||
{
|
{
|
||||||
undoStack.push(commandPtr);
|
pCurrUndoStack->Push(commandPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::UndoCommand()
|
void SHCommandManager::UndoCommand()
|
||||||
{
|
{
|
||||||
if (undoStack.empty())
|
if (pCurrUndoStack->Empty())
|
||||||
return;
|
return;
|
||||||
undoStack.top()->Undo();
|
pCurrUndoStack->Top()->Undo();
|
||||||
redoStack.push(undoStack.top());
|
pCurrRedoStack->Push(pCurrUndoStack->Top());
|
||||||
undoStack.pop();
|
pCurrUndoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::RedoCommand()
|
void SHCommandManager::RedoCommand()
|
||||||
{
|
{
|
||||||
if (redoStack.empty())
|
if (pCurrRedoStack->Empty())
|
||||||
return;
|
return;
|
||||||
redoStack.top()->Execute();
|
pCurrRedoStack->Top()->Execute();
|
||||||
undoStack.push(redoStack.top());
|
pCurrUndoStack->Push(pCurrRedoStack->Top());
|
||||||
redoStack.pop();
|
pCurrRedoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t SHCommandManager::GetUndoStackSize()
|
std::size_t SHCommandManager::GetUndoStackSize()
|
||||||
{
|
{
|
||||||
return undoStack.size();
|
return pCurrUndoStack->Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t SHCommandManager::GetRedoStackSize()
|
std::size_t SHCommandManager::GetRedoStackSize()
|
||||||
{
|
{
|
||||||
return redoStack.size();
|
return pCurrRedoStack->Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||||
{
|
{
|
||||||
redoStack.pop();
|
pCurrRedoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
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
|
}//namespace SHADE
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHCommand.hpp"
|
#include "SHCommand.hpp"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "Tools/SHDeque.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -22,7 +23,8 @@ namespace SHADE
|
||||||
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using SHCommandPtr = std::shared_ptr<SHCommand<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 PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
static void RegisterCommand(BaseCommandPtr commandPtr);
|
static void RegisterCommand(BaseCommandPtr commandPtr);
|
||||||
|
@ -34,8 +36,17 @@ namespace SHADE
|
||||||
static void PopLatestCommandFromRedoStack();
|
static void PopLatestCommandFromRedoStack();
|
||||||
static void PopLatestCommandFromUndoStack();
|
static void PopLatestCommandFromUndoStack();
|
||||||
|
|
||||||
|
static void SwapStacks();
|
||||||
|
static void ClearAll();
|
||||||
|
|
||||||
|
static constexpr CommandStack::SizeType defaultStackSize = 100;
|
||||||
private:
|
private:
|
||||||
|
static CommandStackPtr pCurrUndoStack;
|
||||||
|
static CommandStackPtr pCurrRedoStack;
|
||||||
|
|
||||||
static CommandStack undoStack;
|
static CommandStack undoStack;
|
||||||
|
static CommandStack secondaryUndoStack;
|
||||||
static CommandStack redoStack;
|
static CommandStack redoStack;
|
||||||
|
static CommandStack secondaryRedoStack;
|
||||||
};
|
};
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -228,7 +228,7 @@ namespace SHADE
|
||||||
.previousState = editor->editorState
|
.previousState = editor->editorState
|
||||||
};
|
};
|
||||||
editor->editorState = SHEditor::State::PLAY;
|
editor->editorState = SHEditor::State::PLAY;
|
||||||
|
SHCommandManager::SwapStacks();
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ namespace SHADE
|
||||||
.previousState = editor->editorState
|
.previousState = editor->editorState
|
||||||
};
|
};
|
||||||
editor->editorState = SHEditor::State::STOP;
|
editor->editorState = SHEditor::State::STOP;
|
||||||
|
SHCommandManager::SwapStacks();
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
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