Compare commits

...

2 Commits

Author SHA1 Message Date
Jace 73064c7257 Broken undo 2016-02-26 13:12:49 +01:00
Jace fa78991795 World::MemoryUsage returns approximate value of component pool memory usage 2016-02-26 12:53:33 +01:00
12 changed files with 101 additions and 9 deletions
+2
View File
@@ -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.
+1
View File
@@ -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);
+5
View File
@@ -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.
+4 -1
View File
@@ -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;
+9 -1
View File
@@ -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;
+4
View File
@@ -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;
+14
View File
@@ -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>
+5
View File
@@ -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
{ {
+9
View File
@@ -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);
+11
View File
@@ -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
+16 -6
View File
@@ -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);
} }
} }
+20
View File
@@ -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();