docs: 更新 containers 和 threading 模块文档
- containers: 更新 string 类的多个方法文档 - threading: 更新 mutex 和 task-group 方法文档
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include "SelectionManager.h"
|
||||
#include "IProjectManager.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "IUndoManager.h"
|
||||
#include "UndoManager.h"
|
||||
#include "Managers/SceneManager.h"
|
||||
#include "Managers/ProjectManager.h"
|
||||
#include "EditorEvents.h"
|
||||
@@ -20,6 +22,7 @@ public:
|
||||
: m_eventBus(std::make_unique<EventBus>())
|
||||
, m_selectionManager(std::make_unique<SelectionManager>(*m_eventBus))
|
||||
, m_sceneManager(std::make_unique<SceneManager>(m_eventBus.get()))
|
||||
, m_undoManager(std::make_unique<UndoManager>(*m_sceneManager, *m_selectionManager))
|
||||
, m_projectManager(std::make_unique<ProjectManager>()) {
|
||||
|
||||
m_entityDeletedHandlerId = m_eventBus->Subscribe<EntityDeletedEvent>([this](const EntityDeletedEvent& event) {
|
||||
@@ -48,6 +51,10 @@ public:
|
||||
IProjectManager& GetProjectManager() override {
|
||||
return *m_projectManager;
|
||||
}
|
||||
|
||||
IUndoManager& GetUndoManager() override {
|
||||
return *m_undoManager;
|
||||
}
|
||||
|
||||
void SetProjectPath(const std::string& path) override {
|
||||
m_projectPath = path;
|
||||
@@ -61,6 +68,7 @@ private:
|
||||
std::unique_ptr<EventBus> m_eventBus;
|
||||
std::unique_ptr<SelectionManager> m_selectionManager;
|
||||
std::unique_ptr<SceneManager> m_sceneManager;
|
||||
std::unique_ptr<UndoManager> m_undoManager;
|
||||
std::unique_ptr<ProjectManager> m_projectManager;
|
||||
std::string m_projectPath;
|
||||
uint64_t m_entityDeletedHandlerId;
|
||||
|
||||
@@ -10,6 +10,7 @@ class EventBus;
|
||||
class ISelectionManager;
|
||||
class IProjectManager;
|
||||
class ISceneManager;
|
||||
class IUndoManager;
|
||||
|
||||
class IEditorContext {
|
||||
public:
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
virtual ISelectionManager& GetSelectionManager() = 0;
|
||||
virtual ISceneManager& GetSceneManager() = 0;
|
||||
virtual IProjectManager& GetProjectManager() = 0;
|
||||
virtual IUndoManager& GetUndoManager() = 0;
|
||||
|
||||
virtual void SetProjectPath(const std::string& path) = 0;
|
||||
virtual const std::string& GetProjectPath() const = 0;
|
||||
|
||||
40
editor/src/Core/IUndoManager.h
Normal file
40
editor/src/Core/IUndoManager.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceneSnapshot.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct UndoStateSnapshot {
|
||||
SceneSnapshot scene;
|
||||
std::vector<uint64_t> selectionIds;
|
||||
};
|
||||
|
||||
class IUndoManager {
|
||||
public:
|
||||
virtual ~IUndoManager() = default;
|
||||
|
||||
virtual void ClearHistory() = 0;
|
||||
virtual bool CanUndo() const = 0;
|
||||
virtual bool CanRedo() const = 0;
|
||||
virtual const std::string& GetUndoLabel() const = 0;
|
||||
virtual const std::string& GetRedoLabel() const = 0;
|
||||
|
||||
virtual void Undo() = 0;
|
||||
virtual void Redo() = 0;
|
||||
|
||||
virtual UndoStateSnapshot CaptureCurrentState() const = 0;
|
||||
virtual void PushCommand(const std::string& label, UndoStateSnapshot before, UndoStateSnapshot after) = 0;
|
||||
|
||||
virtual void BeginInteractiveChange(const std::string& label) = 0;
|
||||
virtual bool HasPendingInteractiveChange() const = 0;
|
||||
virtual void FinalizeInteractiveChange() = 0;
|
||||
virtual void CancelInteractiveChange() = 0;
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
16
editor/src/Core/SceneSnapshot.h
Normal file
16
editor/src/Core/SceneSnapshot.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct SceneSnapshot {
|
||||
bool hasScene = false;
|
||||
std::string sceneData;
|
||||
std::string scenePath;
|
||||
bool dirty = false;
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
165
editor/src/Core/UndoManager.cpp
Normal file
165
editor/src/Core/UndoManager.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "Core/UndoManager.h"
|
||||
|
||||
#include "Core/ISelectionManager.h"
|
||||
#include "Managers/SceneManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t kMaxUndoHistory = 128;
|
||||
|
||||
} // namespace
|
||||
|
||||
UndoManager::UndoManager(SceneManager& sceneManager, ISelectionManager& selectionManager)
|
||||
: m_sceneManager(sceneManager)
|
||||
, m_selectionManager(selectionManager) {}
|
||||
|
||||
void UndoManager::ClearHistory() {
|
||||
m_history.clear();
|
||||
m_nextIndex = 0;
|
||||
m_pendingInteractiveChange.reset();
|
||||
}
|
||||
|
||||
bool UndoManager::CanUndo() const {
|
||||
return m_nextIndex > 0;
|
||||
}
|
||||
|
||||
bool UndoManager::CanRedo() const {
|
||||
return m_nextIndex < m_history.size();
|
||||
}
|
||||
|
||||
const std::string& UndoManager::GetUndoLabel() const {
|
||||
return CanUndo() ? m_history[m_nextIndex - 1].label : m_emptyLabel;
|
||||
}
|
||||
|
||||
const std::string& UndoManager::GetRedoLabel() const {
|
||||
return CanRedo() ? m_history[m_nextIndex].label : m_emptyLabel;
|
||||
}
|
||||
|
||||
void UndoManager::Undo() {
|
||||
if (HasPendingInteractiveChange()) {
|
||||
FinalizeInteractiveChange();
|
||||
}
|
||||
|
||||
if (!CanUndo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
--m_nextIndex;
|
||||
ApplyState(m_history[m_nextIndex].before);
|
||||
}
|
||||
|
||||
void UndoManager::Redo() {
|
||||
if (HasPendingInteractiveChange()) {
|
||||
FinalizeInteractiveChange();
|
||||
}
|
||||
|
||||
if (!CanRedo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyState(m_history[m_nextIndex].after);
|
||||
++m_nextIndex;
|
||||
}
|
||||
|
||||
UndoStateSnapshot UndoManager::CaptureCurrentState() const {
|
||||
UndoStateSnapshot snapshot;
|
||||
snapshot.scene = m_sceneManager.CaptureSceneSnapshot();
|
||||
|
||||
if (!snapshot.scene.hasScene) {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
for (uint64_t entityId : m_selectionManager.GetSelectedEntities()) {
|
||||
if (m_sceneManager.GetEntity(entityId)) {
|
||||
snapshot.selectionIds.push_back(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
void UndoManager::PushCommand(const std::string& label, UndoStateSnapshot before, UndoStateSnapshot after) {
|
||||
if (AreStatesEqual(before, after)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_nextIndex < m_history.size()) {
|
||||
m_history.erase(m_history.begin() + static_cast<std::ptrdiff_t>(m_nextIndex), m_history.end());
|
||||
}
|
||||
|
||||
m_history.push_back(CommandEntry{ label, std::move(before), std::move(after) });
|
||||
if (m_history.size() > kMaxUndoHistory) {
|
||||
m_history.erase(m_history.begin());
|
||||
if (m_nextIndex > 0) {
|
||||
--m_nextIndex;
|
||||
}
|
||||
}
|
||||
|
||||
m_nextIndex = m_history.size();
|
||||
}
|
||||
|
||||
void UndoManager::BeginInteractiveChange(const std::string& label) {
|
||||
if (m_pendingInteractiveChange.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_pendingInteractiveChange = PendingInteractiveChange{ label, CaptureCurrentState() };
|
||||
}
|
||||
|
||||
bool UndoManager::HasPendingInteractiveChange() const {
|
||||
return m_pendingInteractiveChange.has_value();
|
||||
}
|
||||
|
||||
void UndoManager::FinalizeInteractiveChange() {
|
||||
if (!m_pendingInteractiveChange.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PushCommand(
|
||||
m_pendingInteractiveChange->label,
|
||||
std::move(m_pendingInteractiveChange->before),
|
||||
CaptureCurrentState());
|
||||
m_pendingInteractiveChange.reset();
|
||||
}
|
||||
|
||||
void UndoManager::CancelInteractiveChange() {
|
||||
m_pendingInteractiveChange.reset();
|
||||
}
|
||||
|
||||
bool UndoManager::ApplyState(const UndoStateSnapshot& state) {
|
||||
if (!m_sceneManager.RestoreSceneSnapshot(state.scene)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> validSelection;
|
||||
validSelection.reserve(state.selectionIds.size());
|
||||
for (uint64_t entityId : state.selectionIds) {
|
||||
if (m_sceneManager.GetEntity(entityId)) {
|
||||
validSelection.push_back(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
if (validSelection.empty()) {
|
||||
m_selectionManager.ClearSelection();
|
||||
} else {
|
||||
m_selectionManager.SetSelectedEntities(validSelection);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UndoManager::AreStatesEqual(const UndoStateSnapshot& lhs, const UndoStateSnapshot& rhs) {
|
||||
return lhs.scene.hasScene == rhs.scene.hasScene &&
|
||||
lhs.scene.scenePath == rhs.scene.scenePath &&
|
||||
lhs.scene.sceneData == rhs.scene.sceneData &&
|
||||
lhs.scene.dirty == rhs.scene.dirty &&
|
||||
lhs.selectionIds == rhs.selectionIds;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
60
editor/src/Core/UndoManager.h
Normal file
60
editor/src/Core/UndoManager.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "IUndoManager.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
class ISelectionManager;
|
||||
class SceneManager;
|
||||
|
||||
class UndoManager : public IUndoManager {
|
||||
public:
|
||||
UndoManager(SceneManager& sceneManager, ISelectionManager& selectionManager);
|
||||
|
||||
void ClearHistory() override;
|
||||
bool CanUndo() const override;
|
||||
bool CanRedo() const override;
|
||||
const std::string& GetUndoLabel() const override;
|
||||
const std::string& GetRedoLabel() const override;
|
||||
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
|
||||
UndoStateSnapshot CaptureCurrentState() const override;
|
||||
void PushCommand(const std::string& label, UndoStateSnapshot before, UndoStateSnapshot after) override;
|
||||
|
||||
void BeginInteractiveChange(const std::string& label) override;
|
||||
bool HasPendingInteractiveChange() const override;
|
||||
void FinalizeInteractiveChange() override;
|
||||
void CancelInteractiveChange() override;
|
||||
|
||||
private:
|
||||
struct CommandEntry {
|
||||
std::string label;
|
||||
UndoStateSnapshot before;
|
||||
UndoStateSnapshot after;
|
||||
};
|
||||
|
||||
struct PendingInteractiveChange {
|
||||
std::string label;
|
||||
UndoStateSnapshot before;
|
||||
};
|
||||
|
||||
bool ApplyState(const UndoStateSnapshot& state);
|
||||
static bool AreStatesEqual(const UndoStateSnapshot& lhs, const UndoStateSnapshot& rhs);
|
||||
|
||||
SceneManager& m_sceneManager;
|
||||
ISelectionManager& m_selectionManager;
|
||||
std::vector<CommandEntry> m_history;
|
||||
size_t m_nextIndex = 0;
|
||||
std::optional<PendingInteractiveChange> m_pendingInteractiveChange;
|
||||
std::string m_emptyLabel;
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user