Commit add36593 authored by Johannes Braun's avatar Johannes Braun
Browse files

Added Dissolve Node button

parent 1b375f80
......@@ -193,6 +193,19 @@ void drawSceneWindow()
{
ImGui::OpenPopup("rn_curr_node");
}
if (ImGui::AntiFeatureButton("Dissolve", ImVec2(ImGui::GetContentRegionAvailWidth(), 32)) && selected_node)
{
auto parent = selected_node->parent();
while (selected_node->childCount() != 0)
{
for (auto&& child : selected_node->iterateChildren())
{
parent->attach(child->detachSelf());
}
}
selected_node->destroy();
ImGui::ClearSelectableTreeData();
}
if(ImGui::BeginPopup("del_curr_node"))
{
......@@ -202,6 +215,8 @@ void drawSceneWindow()
{
if(selected_node)
selected_node->destroy();
selected_node = nullptr;
ImGui::ClearSelectableTreeData();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
......
#include "component.h"
#include "scene_node.h"
namespace glare::core
{
SceneComponent::~SceneComponent()
{
}
void SceneComponent::onTransform()
{
}
void SceneComponent::onGui()
{
}
void SceneComponent::onUpdate()
{
}
void SceneComponent::onDraw(DrawMode mode)
{
}
std::shared_ptr<SceneNode> SceneComponent::owner() const
{
return m_owner.lock();
}
std::shared_ptr<SceneComponent> SceneComponent::detach()
{
return detachAs<SceneComponent>();
}
void SceneComponent::onDestroy()
{
// Detach the node and let it go out of scope.
detach();
}
uint64_t SceneComponent::id()
{
if (m_id == 0)
{
static uint64_t m_current_id = 1ui64;
m_id = m_current_id++;
}
return m_id;
}
const std::string& SceneComponent::typeName() const
{
return m_type_name;
}
}
\ No newline at end of file
......@@ -10,21 +10,21 @@ namespace glare::core
template <typename TNode, typename TComponent>
class ComponentContainer;
class SceneNode;
enum class DrawMode;
/**
* \brief Can be attached to a GraphNode to add functionality to it (decorator)
* \brief Can be attached to a SceneNode to add functionality to it (decorator)
*/
class SceneComponent : public std::enable_shared_from_this<SceneComponent>, public Entity
{
friend class ComponentContainer<SceneNode, SceneComponent>;
friend class GraphNode;
friend class SceneNode;
public:
SceneComponent(const std::string& type_name) : m_type_name(type_name) {}
virtual ~SceneComponent();
template <typename T>
std::shared_ptr<T> detachAs();
std::shared_ptr<SceneComponent> detach();
std::shared_ptr<SceneNode> owner() const;
uint64_t id();
const std::string& typeName() const;
......@@ -40,7 +40,7 @@ namespace glare::core
*/
virtual void onGui() override;
virtual void onUpdate() override;
virtual void onDestroy() override { detachAs<SceneComponent>(); };
virtual void onDestroy() override;
virtual void onStart() override {}
virtual void onEnd() override {}
virtual void onActivate() override {}
......@@ -50,36 +50,11 @@ namespace glare::core
virtual void onDraw(DrawMode mode = DrawMode::eShaded) override;
private:
std::string m_type_name;
const std::string m_type_name;
std::weak_ptr<SceneNode> m_owner;
uint64_t m_id = 0;
};
inline SceneComponent::~SceneComponent()
{
}
inline void SceneComponent::onTransform()
{
}
inline void SceneComponent::onGui()
{
}
inline void SceneComponent::onUpdate()
{
}
inline void SceneComponent::onDraw(DrawMode mode)
{
}
inline std::shared_ptr<SceneNode> SceneComponent::owner() const
{
return m_owner.lock();
}
template <typename T>
std::shared_ptr<T> SceneComponent::detachAs()
{
......@@ -87,21 +62,6 @@ namespace glare::core
m_owner.lock()->removeComponent(shared);
return shared;
}
inline uint64_t SceneComponent::id()
{
if (m_id == 0)
{
static uint64_t m_current_id = 1ui64;
m_id = m_current_id++;
}
return m_id;
}
inline const std::string& SceneComponent::typeName() const
{
return m_type_name;
}
}
#include "scene_node.h"
......
#ifndef INCLUDE_BASE_CONTAINER_H
#define INCLUDE_BASE_CONTAINER_H
#include <algorithm>
#include <functional>
#include <memory>
#include <map>
#include <util/vector.h>
namespace glare::core
{
template<typename TNode, typename TComponent>
class ComponentContainer : public std::enable_shared_from_this<TNode>
{
public:
virtual ~ComponentContainer() = default;
template<typename T>
void addComponent(std::shared_ptr<T> component);
template<typename T>
void removeComponent(std::shared_ptr<T> component);
void removeComponent(std::shared_ptr<TComponent> component);
template<typename TComponentDerived, typename... TArgs>
std::shared_ptr<TComponentDerived> makeComponent(TArgs... args);
template<typename T>
std::shared_ptr<T> getComponent() const;
template<typename T>
std::vector<std::shared_ptr<TComponent>> getComponents() const;
/**
* \brief Iterates through all components calling the loop function with each one.
* Iterator stability will be achieved by iterating via vector index instead of vector iterators.
* This will enable the component to remove/detach itself while being iterated over with minimal impact.
*/
void iterateComponentsStable(std::function<void(TComponent& component)> loop);
bool hasComponents() const;
protected:
std::map<std::string, std::vector<std::shared_ptr<TComponent>>> m_components;
};
template <typename TNode, typename TComponent>
void ComponentContainer<TNode, TComponent>::iterateComponentsStable(std::function<void(TComponent& component)> loop)
{
for (auto& it = m_components.begin(); it != m_components.end();)
{
auto&& list = (*it);
for (auto&& component : stable_vector_iterator<std::shared_ptr<TComponent>>(list.second))
if (component) loop(*component);
if (list.second.empty()) it = m_components.erase(it);
else ++it;
}
}
template <typename TNode, typename TComponent>
bool ComponentContainer<TNode, TComponent>::hasComponents() const
{
return !m_components.empty();
}
template <typename TNode, typename TComponent>
template <typename T>
void ComponentContainer<TNode, TComponent>::addComponent(std::shared_ptr<T> component)
{
component->m_owner = std::enable_shared_from_this<TNode>::shared_from_this();
if(component)
component->start();
m_components[typeid(T).name()].push_back(component);
}
template <typename TNode, typename TComponent>
template<typename T>
void ComponentContainer<TNode, TComponent>::removeComponent(std::shared_ptr<T> component)
{
if (m_components.size() != 0 && m_components.count(typeid(T).name()) != 0)
{
auto&& list = m_components[typeid(T).name()];
auto rm_it = std::remove_if(list.begin(), list.end(), [&component](std::shared_ptr<TComponent> current) {
return current.get() == component.get();
});
if (rm_it != list.end())
{
(*rm_it)->end();
list.erase(rm_it);
}
if (list.empty())
m_components.erase(typeid(T).name());
}
}
template <typename TNode, typename TComponent>
void ComponentContainer<TNode, TComponent>::removeComponent(std::shared_ptr<TComponent> component)
{
for (auto& it = m_components.begin(); it != m_components.end(); ++it)
{
auto&& list = (*it).second;
auto rm_it = std::remove_if(list.begin(), list.end(), [&component](std::shared_ptr<TComponent> current) {
return current.get() == component.get();
});
if(rm_it != list.end())
{
list.erase(rm_it);
break;
}
}
}
template <typename TNode, typename TComponent>
template <typename TComponentDerived, typename ... TArgs>
std::shared_ptr<TComponentDerived> ComponentContainer<TNode, TComponent>::makeComponent(TArgs ... args)
{
auto component = std::make_shared<TComponentDerived>(args...);
addComponent<TComponentDerived>(component);
return component;
}
template <typename TNode, typename TComponent>
template<typename T>
std::shared_ptr<T> ComponentContainer<TNode, TComponent>::getComponent() const
{
auto hc = typeid(T).name();
if (m_components.size() == 0 || m_components.count(hc) == 0)
{
return std::shared_ptr<T>(nullptr);
}
else
{
const auto& list = m_components.at(hc);
if (list.empty())
return std::shared_ptr<T>(nullptr);
return std::static_pointer_cast<T>(list[0]);
}
}
template <typename TNode, typename TComponent>
template<typename T>
std::vector<std::shared_ptr<TComponent>> ComponentContainer<TNode, TComponent>::getComponents() const
{
if (m_components.size() == 0 || m_components.count(typeid(T).name()) == 0)
{
return std::vector<std::shared_ptr<TComponent>>();
}
else
{
//const auto& components = m_components.at(typeid(T).name());
return m_components.at(typeid(T).name());
}
}
}
#endif //INCLUDE_BASE_CONTAINER_H
#ifndef INCLUDE_BASE_CONTAINER_H
#define INCLUDE_BASE_CONTAINER_H
#include <algorithm>
#include <functional>
#include <memory>
#include <map>
#include <util/vector.h>
namespace glare::core
{
template<typename TNode, typename TComponent>
class ComponentContainer : public std::enable_shared_from_this<TNode>
{
public:
virtual ~ComponentContainer() = default;
template<typename T>
void addComponent(std::shared_ptr<T> component);
template<typename T>
void removeComponent(std::shared_ptr<T> component);
void removeComponent(std::shared_ptr<TComponent> component);
template<typename TComponentDerived, typename... TArgs>
std::shared_ptr<TComponentDerived> makeComponent(TArgs... args);
template<typename T>
std::shared_ptr<T> getComponent() const;
template<typename T>
std::vector<std::shared_ptr<TComponent>> getComponents() const;
/**
* \brief Iterates through all components calling the loop function with each one.
* Iterator stability will be achieved by iterating via vector index instead of vector iterators.
* This will enable the component to remove/detach itself while being iterated over with minimal impact.
*/
void iterateComponentsStable(std::function<void(TComponent& component)> loop);
bool hasComponents() const;
protected:
std::map<std::string, std::vector<std::shared_ptr<TComponent>>> m_components;
};
template <typename TNode, typename TComponent>
void ComponentContainer<TNode, TComponent>::iterateComponentsStable(std::function<void(TComponent& component)> loop)
{
for (auto& it = m_components.begin(); it != m_components.end();)
{
auto&& list = (*it);
for (auto&& component : stable_vector_iterator<std::shared_ptr<TComponent>>(list.second))
if (component) loop(*component);
if (list.second.empty()) it = m_components.erase(it);
else ++it;
}
}
template <typename TNode, typename TComponent>
bool ComponentContainer<TNode, TComponent>::hasComponents() const
{
return !m_components.empty();
}
template <typename TNode, typename TComponent>
template <typename T>
void ComponentContainer<TNode, TComponent>::addComponent(std::shared_ptr<T> component)
{
component->m_owner = std::enable_shared_from_this<TNode>::shared_from_this();
if(component)
component->start();
m_components[typeid(T).name()].push_back(component);
}
template <typename TNode, typename TComponent>
template<typename T>
void ComponentContainer<TNode, TComponent>::removeComponent(std::shared_ptr<T> component)
{
if (m_components.size() != 0 && m_components.count(typeid(T).name()) != 0)
{
auto&& list = m_components[typeid(T).name()];
auto rm_it = std::remove_if(list.begin(), list.end(), [&component](std::shared_ptr<TComponent> current) {
return current.get() == component.get();
});
if (rm_it != list.end())
{
(*rm_it)->end();
list.erase(rm_it);
}
if (list.empty())
m_components.erase(typeid(T).name());
}
}
template <typename TNode, typename TComponent>
void ComponentContainer<TNode, TComponent>::removeComponent(std::shared_ptr<TComponent> component)
{
for (auto& it = m_components.begin(); it != m_components.end(); ++it)
{
auto&& list = (*it).second;
auto rm_it = std::remove_if(list.begin(), list.end(), [&component](std::shared_ptr<TComponent> current) {
return current.get() == component.get();
});
if(rm_it != list.end())
{
list.erase(rm_it);
break;
}
}
}
template <typename TNode, typename TComponent>
template <typename TComponentDerived, typename ... TArgs>
std::shared_ptr<TComponentDerived> ComponentContainer<TNode, TComponent>::makeComponent(TArgs ... args)
{
auto component = std::make_shared<TComponentDerived>(args...);
addComponent<TComponentDerived>(component);
return component;
}
template <typename TNode, typename TComponent>
template<typename T>
std::shared_ptr<T> ComponentContainer<TNode, TComponent>::getComponent() const
{
auto hc = typeid(T).name();
if (m_components.size() == 0 || m_components.count(hc) == 0)
{
return std::shared_ptr<T>(nullptr);
}
else
{
const auto& list = m_components.at(hc);
if (list.empty())
return std::shared_ptr<T>(nullptr);
return std::static_pointer_cast<T>(list[0]);
}
}
template <typename TNode, typename TComponent>
template<typename T>
std::vector<std::shared_ptr<TComponent>> ComponentContainer<TNode, TComponent>::getComponents() const
{
if (m_components.size() == 0 || m_components.count(typeid(T).name()) == 0)
{
return std::vector<std::shared_ptr<TComponent>>();
}
else
{
//const auto& components = m_components.at(typeid(T).name());
return m_components.at(typeid(T).name());
}
}
}
#endif //INCLUDE_BASE_CONTAINER_H
......@@ -50,8 +50,8 @@ namespace glare::core
void Entity::destroy()
{
onDestroy();
end();
onDestroy();
}
void Entity::notifyTransform()
......
......@@ -30,7 +30,7 @@ namespace glare::core
void SceneNode::onDestroy()
{
callAndTraverse(&Entity::destroy);
//callAndTraverse(&Entity::destroy);
detachSelf();
}
......
......@@ -4,7 +4,7 @@
#include <core/numeric/geometry.h>
#include "component.h"
#include "base_node.h"
#include "node.h"
#include "entity.h"
namespace glare::core
......
......@@ -297,6 +297,16 @@ namespace ImGui {
}
return nullptr;
}
inline void ClearSelectableTreeData(const char* tree_id)
{
auto hash = ImHash(tree_id, 0);
if (nodes_cached.count(hash) != 0)
{
nodes_cached[hash].selected_user_data = nullptr;
}
}
}
#endif __IMGUI_GLFW3_IMPL_H
\ No newline at end of file
......@@ -8,15 +8,19 @@ class stable_vector_iterator : public std::iterator<std::forward_iterator_tag, T
{
public:
explicit stable_vector_iterator(std::vector<T>& container)
: m_container(&container)
: m_container(&container), m_last_size(container.size())
{
if (m_container->empty())
{
m_index = 0;
m_last_size = 0;
}
}
stable_vector_iterator()
{
m_index = 0;
m_last_size = 0;
}
stable_vector_iterator begin() { return *this; }
......@@ -29,7 +33,9 @@ public:
stable_vector_iterator& operator++()
{
auto old = m_index;
++m_index;
if (m_index > m_container->size() || old == 0 || !static_cast<bool>(m_container != nullptr))
{
m_index = 0;
......@@ -55,6 +61,7 @@ public:
private:
size_t m_index = 1;
size_t m_last_size = 0;
std::vector<T>* m_container;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment