Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73064c7257 | |||
| fa78991795 |
@@ -65,6 +65,8 @@ public:
|
|||||||
iterator end() const;
|
iterator end() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
|
std::size_t MemoryUsage() const;
|
||||||
|
|
||||||
//Dumps information about what the pool memory looks like right now
|
//Dumps information about what the pool memory looks like right now
|
||||||
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
||||||
//Interpret the data in the memory as InterpretType.
|
//Interpret the data in the memory as InterpretType.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct EntityWrapper
|
|||||||
bool HasComponent(const std::string& componentType);
|
bool HasComponent(const std::string& componentType);
|
||||||
void AttachComponent(const char* componentName);
|
void AttachComponent(const char* componentName);
|
||||||
EntityWrapper Parent();
|
EntityWrapper Parent();
|
||||||
|
EntityWrapper BaseParent();
|
||||||
EntityWrapper FirstChildByName(const std::string& name);
|
EntityWrapper FirstChildByName(const std::string& name);
|
||||||
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
||||||
EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid);
|
EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid);
|
||||||
|
|||||||
@@ -194,6 +194,11 @@ public:
|
|||||||
return m_ExtraMemory.size();
|
return m_ExtraMemory.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t MemoryUsage() const
|
||||||
|
{
|
||||||
|
return size() * m_Stride;
|
||||||
|
}
|
||||||
|
|
||||||
//Dumps information about what the pool memory looks like right now
|
//Dumps information about what the pool memory looks like right now
|
||||||
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
||||||
//Interpret the data in the memory as InterpretType.
|
//Interpret the data in the memory as InterpretType.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
World(const World& other);
|
World(const World& other);
|
||||||
|
|
||||||
// Create empty entity
|
// Create empty entity
|
||||||
EntityID CreateEntity(EntityID parent = 0);
|
EntityID CreateEntity(EntityID parent = EntityID_Invalid);
|
||||||
// Delete entity and all components within
|
// Delete entity and all components within
|
||||||
void DeleteEntity(EntityID entity);
|
void DeleteEntity(EntityID entity);
|
||||||
// Check if an entity exists
|
// Check if an entity exists
|
||||||
@@ -50,6 +50,9 @@ public:
|
|||||||
// Get the textual name of an entity
|
// Get the textual name of an entity
|
||||||
std::string GetName(EntityID entity) const;
|
std::string GetName(EntityID entity) const;
|
||||||
|
|
||||||
|
// Get an approximate number for component pool memory usage
|
||||||
|
std::size_t MemoryUsage() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventBroker* m_EventBroker = nullptr;
|
EventBroker* m_EventBroker = nullptr;
|
||||||
EntityID m_CurrentEntityID = 0;
|
EntityID m_CurrentEntityID = 0;
|
||||||
|
|||||||
@@ -91,7 +91,13 @@ public:
|
|||||||
// Called when the user selects a widget space.
|
// Called when the user selects a widget space.
|
||||||
typedef std::function<void(WidgetSpace)> OnWidgetSpace_t;
|
typedef std::function<void(WidgetSpace)> OnWidgetSpace_t;
|
||||||
void SetWidgetSpaceCallback(OnWidgetSpace_t f) { m_OnWidgetSpace = f; }
|
void SetWidgetSpaceCallback(OnWidgetSpace_t f) { m_OnWidgetSpace = f; }
|
||||||
|
// Called when anything is modified making the world dirty
|
||||||
|
// @param EntityWrapper The entity that was changed and marked as dirty
|
||||||
|
typedef std::function<void(EntityWrapper)> OnDirty_t;
|
||||||
|
void SetDirtyCallback(OnDirty_t f) { m_OnDirty = f; }
|
||||||
|
// Called when the user wishes to undo
|
||||||
|
typedef std::function<void()> OnUndo_t;
|
||||||
|
void SetUndoCallback(OnUndo_t f) { m_OnUndo = f; }
|
||||||
private:
|
private:
|
||||||
World* m_World;
|
World* m_World;
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
@@ -132,6 +138,8 @@ private:
|
|||||||
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
||||||
OnWidgetSpace_t m_OnWidgetSpace = nullptr;
|
OnWidgetSpace_t m_OnWidgetSpace = nullptr;
|
||||||
OnEntityPaste_t m_OnEntityPaste = nullptr;
|
OnEntityPaste_t m_OnEntityPaste = nullptr;
|
||||||
|
OnDirty_t m_OnDirty = nullptr;
|
||||||
|
OnUndo_t m_OnUndo = nullptr;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
|
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ private:
|
|||||||
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
|
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
|
||||||
EditorGUI* m_EditorGUI;
|
EditorGUI* m_EditorGUI;
|
||||||
EditorStats* m_EditorStats;
|
EditorStats* m_EditorStats;
|
||||||
|
std::vector<World> m_UndoLevels;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
double m_LastTime = 0.f;
|
double m_LastTime = 0.f;
|
||||||
@@ -44,6 +45,7 @@ private:
|
|||||||
EditorGUI::WidgetSpace m_WidgetSpace = EditorGUI::WidgetSpace::Global;
|
EditorGUI::WidgetSpace m_WidgetSpace = EditorGUI::WidgetSpace::Global;
|
||||||
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
||||||
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||||
|
bool m_SaveUndoLevel = false; // Only save undo state once per update
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
||||||
@@ -60,6 +62,8 @@ private:
|
|||||||
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
|
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
|
||||||
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
|
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
|
||||||
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
|
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
|
||||||
|
void OnDirty(EntityWrapper entity);
|
||||||
|
void OnUndo();
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
||||||
|
|||||||
@@ -5,6 +5,20 @@
|
|||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ size_t ComponentPool::size() const
|
|||||||
return m_Pool.size();
|
return m_Pool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t ComponentPool::MemoryUsage() const
|
||||||
|
{
|
||||||
|
return m_Pool.MemoryUsage();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename InterpretType /*= char*/>
|
template <typename InterpretType /*= char*/>
|
||||||
void ComponentPool::Dump() const
|
void ComponentPool::Dump() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ EntityWrapper EntityWrapper::Parent()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityWrapper EntityWrapper::BaseParent()
|
||||||
|
{
|
||||||
|
EntityWrapper baseParent = Parent();
|
||||||
|
while (baseParent.Parent().Valid()) {
|
||||||
|
baseParent = baseParent.Parent();
|
||||||
|
}
|
||||||
|
return baseParent;
|
||||||
|
}
|
||||||
|
|
||||||
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
|
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
|
||||||
{
|
{
|
||||||
return firstChildByNameRecursive(name, this->ID);
|
return firstChildByNameRecursive(name, this->ID);
|
||||||
|
|||||||
@@ -151,6 +151,17 @@ std::string World::GetName(EntityID entity) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t World::MemoryUsage() const
|
||||||
|
{
|
||||||
|
std::size_t mem = 0;
|
||||||
|
|
||||||
|
for (auto& kv : m_ComponentPools) {
|
||||||
|
mem += kv.second->MemoryUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
EntityID World::generateEntityID()
|
EntityID World::generateEntityID()
|
||||||
{
|
{
|
||||||
// TODO: Make EntityID generation smarter
|
// TODO: Make EntityID generation smarter
|
||||||
|
|||||||
@@ -602,6 +602,15 @@ bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
|
|||||||
m_CopyTarget = m_CurrentSelection;
|
m_CopyTarget = m_CurrentSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.ModCtrl && e.KeyCode == GLFW_KEY_Z) {
|
||||||
|
if (m_OnUndo != nullptr) {
|
||||||
|
m_OnUndo();
|
||||||
|
if (!m_CurrentSelection.Valid()) {
|
||||||
|
SelectEntity(EntityWrapper::Invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (e.ModCtrl && e.KeyCode == GLFW_KEY_V) {
|
if (e.ModCtrl && e.KeyCode == GLFW_KEY_V) {
|
||||||
if (m_OnEntityPaste != nullptr) {
|
if (m_OnEntityPaste != nullptr) {
|
||||||
EntityWrapper copy = m_OnEntityPaste(m_CopyTarget, m_CurrentSelection);
|
EntityWrapper copy = m_OnEntityPaste(m_CopyTarget, m_CurrentSelection);
|
||||||
@@ -774,13 +783,13 @@ bool EditorGUI::compareCharArray(const char* c1, const char* c2)
|
|||||||
|
|
||||||
void EditorGUI::SetDirty(EntityWrapper entity)
|
void EditorGUI::SetDirty(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
EntityWrapper baseParent = entity;
|
EntityWrapper baseParent = entity.BaseParent();
|
||||||
while (baseParent.Parent().Valid()) {
|
|
||||||
baseParent = baseParent.Parent();
|
|
||||||
}
|
|
||||||
if (m_EntityFiles.find(baseParent) != m_EntityFiles.end()) {
|
if (m_EntityFiles.find(baseParent) != m_EntityFiles.end()) {
|
||||||
m_EntityFiles.at(baseParent).Dirty = true;
|
m_EntityFiles.at(baseParent).Dirty = true;
|
||||||
}
|
}
|
||||||
|
if (m_OnDirty != nullptr) {
|
||||||
|
m_OnDirty(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorGUI::entityImport(World* world)
|
void EditorGUI::entityImport(World* world)
|
||||||
@@ -830,6 +839,7 @@ void EditorGUI::entityCreate(World* world, EntityWrapper parent)
|
|||||||
parent.World = world;
|
parent.World = world;
|
||||||
}
|
}
|
||||||
EntityWrapper newEntity = m_OnEntityCreate(parent);
|
EntityWrapper newEntity = m_OnEntityCreate(parent);
|
||||||
|
SetDirty(newEntity);
|
||||||
SelectEntity(newEntity);
|
SelectEntity(newEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,9 +855,9 @@ void EditorGUI::entityDelete(EntityWrapper entity)
|
|||||||
if (boost::any_cast<EntityWrapper>(m_ModalData[modalName]) == entity) {
|
if (boost::any_cast<EntityWrapper>(m_ModalData[modalName]) == entity) {
|
||||||
EntityWrapper parent = entity.Parent();
|
EntityWrapper parent = entity.Parent();
|
||||||
if (m_OnEntityDelete != nullptr) {
|
if (m_OnEntityDelete != nullptr) {
|
||||||
SetDirty(entity);
|
|
||||||
m_OnEntityDelete(entity);
|
m_OnEntityDelete(entity);
|
||||||
m_EntityFiles.erase(entity);
|
m_EntityFiles.erase(entity);
|
||||||
|
SetDirty(parent);
|
||||||
}
|
}
|
||||||
if (!m_CurrentSelection.Valid()) {
|
if (!m_CurrentSelection.Valid()) {
|
||||||
SelectEntity(parent);
|
SelectEntity(parent);
|
||||||
@@ -864,8 +874,8 @@ void EditorGUI::entityChangeParent(EntityWrapper entity, EntityWrapper parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_OnEntityChangeParent != nullptr) {
|
if (m_OnEntityChangeParent != nullptr) {
|
||||||
SetDirty(entity);
|
|
||||||
m_OnEntityChangeParent(entity, parent);
|
m_OnEntityChangeParent(entity, parent);
|
||||||
|
SetDirty(entity);
|
||||||
LOG_DEBUG("Changed parent of %i to %i", entity.ID, parent.ID);
|
LOG_DEBUG("Changed parent of %i to %i", entity.ID, parent.ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
|
|||||||
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
||||||
m_EditorGUI->SetWidgetSpaceCallback(std::bind(&EditorSystem::OnWidgetSpace, this, std::placeholders::_1));
|
m_EditorGUI->SetWidgetSpaceCallback(std::bind(&EditorSystem::OnWidgetSpace, this, std::placeholders::_1));
|
||||||
|
m_EditorGUI->SetDirtyCallback(std::bind(&EditorSystem::OnDirty, this, std::placeholders::_1));
|
||||||
|
m_EditorGUI->SetUndoCallback(std::bind(&EditorSystem::OnUndo, this));
|
||||||
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
||||||
@@ -87,6 +89,11 @@ void EditorSystem::Update(double dt)
|
|||||||
glm::vec3& pos = cameraTransform["Position"];
|
glm::vec3& pos = cameraTransform["Position"];
|
||||||
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
|
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_SaveUndoLevel) {
|
||||||
|
m_UndoLevels.push_back(*m_World);
|
||||||
|
m_SaveUndoLevel = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorSystem::Enable()
|
void EditorSystem::Enable()
|
||||||
@@ -185,6 +192,19 @@ void EditorSystem::OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace)
|
|||||||
m_WidgetSpace = widgetSpace;
|
m_WidgetSpace = widgetSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnDirty(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
m_SaveUndoLevel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnUndo()
|
||||||
|
{
|
||||||
|
// The last "undo level" is always the most recent change
|
||||||
|
if (m_UndoLevels.size() >= 2) {
|
||||||
|
*m_World = m_UndoLevels.at(m_UndoLevels.size() - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|||||||
Reference in New Issue
Block a user