Drag and drop prefab into scene tree. Play pause snapshot system

This commit is contained in:
antopilo
2021-09-08 21:28:53 -04:00
parent b403082ca2
commit 33b3962e51
9 changed files with 107 additions and 56 deletions

View File

@@ -70,8 +70,7 @@ int main()
//newEditor.Update(0.f);
if (Nuake::Input::IsKeyPressed(GLFW_KEY_F8))
Nuake::Engine::ExitPlayMode();
Nuake::Vector2 WindowSize = Nuake::Engine::GetCurrentWindow()->GetSize();
glViewport(0, 0, WindowSize.x, WindowSize.y);

View File

@@ -34,6 +34,7 @@
#include <src/Rendering/Shaders/ShaderManager.h>
#include "src/Rendering/Renderer.h"
#include <src/Scene/Components/InterfaceComponent.h>
#include "src/Core/Input.h"
namespace Nuake {
Ref<UI::UserInterface> userInterface;
@@ -270,6 +271,7 @@ namespace Nuake {
parent.Children.push_back(payload_entity);
}
}
ImGui::EndDragDropTarget();
}
if (ImGui::IsItemClicked())
@@ -386,53 +388,66 @@ namespace Nuake {
ImGui::EndChild();
ImGui::Separator();
// Draw a tree of entities.
std::vector<Entity> entities = scene->GetAllEntities();
for (Entity e : entities)
if (ImGui::BeginChild("Scene tree", ImGui::GetContentRegionAvail(), true))
{
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
std::string name = e.GetComponent<NameComponent>().Name;
// If selected add selected flag.
if (m_SelectedEntity == e)
base_flags |= ImGuiTreeNodeFlags_Selected;
// Write in normal font.
ImGui::PushFont(normalFont);
// Small icons + name.
std::string label = ICON_FA_CIRCLE + std::string(" ") + name;
// Draw all entity without parents.
if (!e.GetComponent<ParentComponent>().HasParent)
std::vector<Entity> entities = scene->GetAllEntities();
for (Entity e : entities)
{
// Recursively draw childrens.
DrawEntityTree(e);
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
std::string name = e.GetComponent<NameComponent>().Name;
// If selected add selected flag.
if (m_SelectedEntity == e)
base_flags |= ImGuiTreeNodeFlags_Selected;
// Write in normal font.
ImGui::PushFont(normalFont);
// Small icons + name.
std::string label = ICON_FA_CIRCLE + std::string(" ") + name;
// Draw all entity without parents.
if (!e.GetComponent<ParentComponent>().HasParent)
{
// Recursively draw childrens.
DrawEntityTree(e);
}
// Pop font.
ImGui::PopFont();
// Right click menu
//if (ImGui::BeginPopupContextItem())
// ImGui::EndPopup();
}
ImGui::EndChild();
}
if (ImGui::BeginDragDropTarget()) // Drag n drop new prefab file into scene tree
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Prefab"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
std::string relPath = FileSystem::AbsoluteToRelative(fullPath);
// Pop font.
ImGui::PopFont();
// Right click menu
//if (ImGui::BeginPopupContextItem())
// ImGui::EndPopup();
Entity newEntity = Engine::GetCurrentScene()->CreateEntity("New prefab Entity");
PrefabComponent& prefabComponent = newEntity.AddComponent<PrefabComponent>();
prefabComponent.PrefabInstance = Prefab::New(relPath);
}
ImGui::EndDragDropTarget();
}
// Delete entity
// Deleted entity queue
if (QueueDeletion.GetHandle() != -1)
{
Engine::GetCurrentScene()->DestroyEntity(QueueDeletion);
if (m_SelectedEntity == QueueDeletion)
{
m_IsEntitySelected = false;
}
QueueDeletion = Entity{ (entt::entity)-1, scene.get() };
//ImGui::TreePop();
}
}
ImGui::End();
}
@@ -1389,6 +1404,7 @@ namespace Nuake {
}
json SceneSnapshot;
void EditorInterface::Draw()
{
Init();
@@ -1595,9 +1611,19 @@ namespace Nuake {
float needed = half - used;
ImGui::Dummy(ImVec2(needed, 10));
ImGui::SameLine();
if (ImGui::Button(ICON_FA_PLAY)) Engine::EnterPlayMode();
if (ImGui::Button(ICON_FA_PLAY))
{
SceneSnapshot = Engine::GetCurrentScene()->Serialize();
Engine::EnterPlayMode();
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_STOP)) Engine::ExitPlayMode();
if (ImGui::Button(ICON_FA_STOP) || Input::IsKeyPressed(297))
{
Engine::ExitPlayMode();
Engine::GetCurrentScene()->Deserialize(SceneSnapshot.dump());
m_IsEntitySelected = false;
}
}
ImGui::End();
}

View File

@@ -123,6 +123,8 @@ namespace Nuake {
dragType = "_Model";
else if (file->Type == ".interface")
dragType = "_Interface";
else if (file->Type == ".prefab")
dragType = "_Prefab";
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
ImGui::Text(file->name.c_str());

View File

@@ -11,6 +11,17 @@ namespace Nuake {
return prefab;
}
Ref<Prefab> Prefab::New(const std::string& path)
{
Ref<Prefab> newPrefab = CreateRef<Prefab>();
newPrefab->Path = path;
std::string prefabTextContent = FileSystem::ReadFile(path);
newPrefab->Deserialize(prefabTextContent);
return newPrefab;
}
void Prefab::EntityWalker(Entity entity)
{
entity.GetComponent<NameComponent>().IsPrefab = true;

View File

@@ -1,8 +1,11 @@
#pragma once
#include "src/Scene/Entities/Entity.h"
#include "src/Scene/Components/ParentComponent.h"
#include "src/Resource/Serializable.h"
#include "Engine.h"
#include <string>
#include <vector>
#include <src/Scene/Entities/Entity.h>
#include "src/Resource/Serializable.h"
namespace Nuake {
class Prefab : ISerializable
{
@@ -12,6 +15,8 @@ namespace Nuake {
static Ref<Prefab> CreatePrefabFromEntity(Entity entity);
static Ref<Prefab> New(const std::string& path);
Prefab()
{
Path = "";
@@ -47,7 +52,25 @@ namespace Nuake {
{
BEGIN_DESERIALIZE();
Path = j["Path"];
if (j.contains("Entities"))
{
for (json e : j["Entities"])
{
Entity entity = Entity { Engine::GetCurrentScene()->m_Registry.create(), Engine::GetCurrentScene().get() };
entity.Deserialize(e.dump());
this->AddEntity(entity);
}
for (auto& e : Entities)
{
auto parentC = e.GetComponent<ParentComponent>();
if (!parentC.HasParent)
continue;
auto parent = Engine::GetCurrentScene()->GetEntityByID(parentC.ParentID);
parent.AddChild(e);
}
}
return true;
}

View File

@@ -45,10 +45,10 @@ namespace Nuake
BEGIN_DESERIALIZE();
this->HasParent = j["HasParent"];
if (HasParent)
{
this->ParentID = j["ParentID"];
//this->Parent = Entity{ j["Parent"], Engine::GetCurrentScene().get() };
//this->Parent = Entity{ j["Parent"], Engine::GetCurrentScene().get() };
}
return true;
}
};

View File

@@ -748,6 +748,8 @@ namespace Nuake {
if (!j.contains("Name"))
return false;
m_Registry.clear();
Name = j["Name"];
m_Environement = CreateRef<Environment>();
@@ -785,14 +787,4 @@ namespace Nuake {
return true;
}
void Scene::Snapshot()
{
}
void Scene::LoadSnapshot()
{
}
}

View File

@@ -1,6 +1,6 @@
#include "InterfaceParser.h"
#include "Styling/Stylesheet.h"
#include "src/Core/String.h"
namespace Nuake
{
Ref<Canvas> InterfaceParser::Root = CreateRef<Canvas>();
@@ -59,7 +59,7 @@ namespace Nuake
{
std::string name = a.name();
if (name == "groups")
for (auto& g : split(a.value(), ' '))
for (auto& g : String::Split(a.value(), ' '))
node->AddGroup(g);
if (name == "id")
@@ -106,7 +106,7 @@ namespace Nuake
{
std::string name = a.name();
if (name == "groups")
for (auto& g : split(a.value(), ' '))
for (auto& g : String::Split(a.value(), ' '))
node->AddGroup(g);
if (name == "id")
@@ -201,7 +201,7 @@ namespace Nuake
std::regex regex("[0-9]+[^ ]+");
std::smatch match_value;
std::vector<std::string> splits = split(value, ' ');
std::vector<std::string> splits = String::Split(value, ' ');
for (int i = 0; i < splits.size(); i++)
{
if (!std::regex_search(value.begin(), value.end(), match_value, regex))
@@ -224,7 +224,7 @@ namespace Nuake
{
std::string name = a.name();
if (name == "groups")
for (auto& g : split(a.value(), ' '))
for (auto& g : String::Split(a.value(), ' '))
node->AddGroup(g);
if (name == "id")
node->ID = a.value();

View File

@@ -25,8 +25,6 @@ namespace Nuake
static Ref<Canvas> CreateCanvas(const pugi::xml_node& xml_node);
static Ref<TextNode> CreateTextNode(const pugi::xml_node& xml_node);
static std::vector<std::string> split(std::string const& str, const char delim);
static Layout::LayoutUnit GetUnit(const std::string& value);
static Layout::LayoutVec4 GetVec4Unit(const std::string& value);
static Color GetColor(const std::string& value);