From 8c581fbc14d785372189fe122145c89b11e5f476 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 15 Oct 2023 03:09:47 -0400 Subject: [PATCH] Application and layers refactoring --- Editor/Editor.cpp | 126 ++++----------------------- Editor/src/EditorApplication.cpp | 26 ++++++ Editor/src/EditorApplication.h | 24 +++++ Editor/src/EditorLayer.cpp | 73 ++++++++++++++++ Editor/src/EditorLayer.h | 23 +++++ Editor/src/Misc/GizmoDrawer.cpp | 14 +-- Editor/src/Misc/GizmoDrawer.h | 4 +- Editor/src/Windows/WelcomeWindow.cpp | 2 +- Nuake/Engine.h | 2 +- Nuake/src/Audio/AudioManager.cpp | 9 ++ Nuake/src/Core/Application.cpp | 58 ++++++++++++ Nuake/src/Core/Application.h | 89 +++++++++++++++++++ Nuake/src/Core/Core.h | 1 + Nuake/src/Core/EntryPoint.h | 44 ++++++++++ Nuake/src/Core/Event.h | 20 +++++ Nuake/src/Core/IApplicationModule.h | 20 +++++ Nuake/src/Core/Layer.h | 35 ++++++++ Nuake/src/Core/LayerStack.cpp | 40 +++++++++ Nuake/src/Core/LayerStack.h | 33 +++++++ 19 files changed, 524 insertions(+), 119 deletions(-) create mode 100644 Editor/src/EditorApplication.cpp create mode 100644 Editor/src/EditorApplication.h create mode 100644 Editor/src/EditorLayer.cpp create mode 100644 Editor/src/EditorLayer.h create mode 100644 Nuake/src/Core/Application.cpp create mode 100644 Nuake/src/Core/Application.h create mode 100644 Nuake/src/Core/EntryPoint.h create mode 100644 Nuake/src/Core/Event.h create mode 100644 Nuake/src/Core/IApplicationModule.h create mode 100644 Nuake/src/Core/Layer.h create mode 100644 Nuake/src/Core/LayerStack.cpp create mode 100644 Nuake/src/Core/LayerStack.h diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 167ec41c..fd39013b 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -33,7 +33,11 @@ #include #include "src/Misc/WindowTheming.h" +#include +#include + +#include "src/EditorApplication.h" struct LaunchSettings { @@ -109,123 +113,25 @@ LaunchSettings ParseLaunchSettings(const std::vector& arguments) return launchSettings; } -int ApplicationMain(int argc, char* argv[]) + +Nuake::Application* Nuake::CreateApplication(int argc, char** argv) { using namespace Nuake; - // Parse launch arguments const auto& arguments = ParseArguments(argc, argv); LaunchSettings launchSettings = ParseLaunchSettings(arguments); + ApplicationSpecification specification + { + .Name = "Editor", + .WindowWidth = 1600, + .WindowHeight = 900, + .VSync = true + }; + #ifdef NK_DEBUG - launchSettings.windowTitle += "(DEBUG BUILD)"; -#endif // NK_DEBUG - - // Initialize Engine & Window - Engine::Init(); - auto window = Engine::GetCurrentWindow(); - window->SetSize(launchSettings.resolution); - window->SetTitle(launchSettings.windowTitle); - - if (launchSettings.monitor >= 0) - { - window->SetMonitor(launchSettings.monitor); - } - WindowTheming::SetWindowDarkMode(window); - - Logger::Log("Creating editor ", "window", CRITICAL); - // Initialize Editor - Nuake::EditorInterface editor; - - Logger::Log("Created editor ", "window", CRITICAL); - // Load project in argument - if (!launchSettings.projectPath.empty()) - { - Logger::Log("Loading project", "window", CRITICAL); - editor.LoadProject(launchSettings.projectPath); - } - - // Start application main loop - GizmoDrawer gizmoDrawer = GizmoDrawer(&editor); - while (!window->ShouldClose()) - { - Nuake::Engine::Tick(); // Update - - Nuake::Engine::Draw(); // Render - - // Render editor - Nuake::Vector2 WindowSize = window->GetSize(); - glViewport(0, 0, WindowSize.x, WindowSize.y); - Nuake::Renderer2D::BeginDraw(WindowSize); - - auto sceneFramebuffer = window->GetFrameBuffer(); - - Ref currentScene = Nuake::Engine::GetCurrentScene(); - - // Draw gizmos - sceneFramebuffer->Bind(); - { - //glDepthMask(false); - - - Ref camera; - if (currentScene) - { - camera = currentScene->m_EditorCamera; - //currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_COLOR_ATTACHMENT3)->Unbind(); - //glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_COLOR_ATTACHMENT3)->GetID(), 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_DEPTH_ATTACHMENT)->GetID(), 0); - } - - if (currentScene && !Nuake::Engine::IsPlayMode()) - { - glEnable(GL_LINE_SMOOTH); - - if (editor.ShouldDrawAxis()) - { - //gizmoDrawer.DrawAxis(currentScene); - } - - if (editor.ShouldDrawCollision()) - { - gizmoDrawer.DrawGizmos(currentScene, false); - glDepthFunc(GL_GREATER); - - gizmoDrawer.DrawGizmos(currentScene, true); - glDepthFunc(GL_LESS); - } - } - //glDepthMask(true); - - } - sceneFramebuffer->Unbind(); - - // Update & Draw editor - editor.Draw(); - editor.Update(Nuake::Engine::GetTimestep()); - Nuake::Engine::EndDraw(); - } - - Nuake::Engine::Close(); - return 0; -} - - - -#ifdef NK_WIN -#ifdef NK_DIST -#include "windows.h" -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cdmline, int cmdshow) -{ - return ApplicationMain(__argc, __argv); -} -#endif + specification.Name += "(DEBUG BUILD)"; #endif - -int main(int argc, char* argv[]) -{ - return ApplicationMain(argc, argv); + return new EditorApplication(specification); } - - diff --git a/Editor/src/EditorApplication.cpp b/Editor/src/EditorApplication.cpp new file mode 100644 index 00000000..befff116 --- /dev/null +++ b/Editor/src/EditorApplication.cpp @@ -0,0 +1,26 @@ +#include "EditorApplication.h" + +#include "Engine.h" +#include "Windows/EditorInterface.h" +#include "Misc/GizmoDrawer.h" +#include "EditorLayer.h" + +#include + + +void EditorApplication::OnInit() +{ + using namespace Nuake; + + Engine::Init(); + m_Window = Engine::GetCurrentWindow(); + m_Window->SetSize({ m_Specification.WindowWidth, m_Specification.WindowHeight }); + m_Window->SetTitle(m_Specification.Name); + + PushLayer(CreateScope()); +} + +void EditorApplication::OnShutdown() +{ + Nuake::Engine::Close(); +} \ No newline at end of file diff --git a/Editor/src/EditorApplication.h b/Editor/src/EditorApplication.h new file mode 100644 index 00000000..19b05e7c --- /dev/null +++ b/Editor/src/EditorApplication.h @@ -0,0 +1,24 @@ +#pragma once +#include +#include + +#include "Windows/EditorInterface.h" +#include "Misc/GizmoDrawer.h" + + +class EditorApplication : public Nuake::Application +{ +public: + EditorApplication(const Nuake::ApplicationSpecification& specification) + : Application(specification), + m_Editor(nullptr) + { + } + + virtual void OnInit() override; + // virtual void OnUpdate() override; + virtual void OnShutdown() override; + +private: + Nuake::EditorInterface* m_Editor; +}; \ No newline at end of file diff --git a/Editor/src/EditorLayer.cpp b/Editor/src/EditorLayer.cpp new file mode 100644 index 00000000..2b8d8425 --- /dev/null +++ b/Editor/src/EditorLayer.cpp @@ -0,0 +1,73 @@ +#include "EditorLayer.h" + +#include "Windows/EditorInterface.h" +#include "Misc/GizmoDrawer.h" + +#include + + +void EditorLayer::OnAttach() +{ + m_EditorInterface = new Nuake::EditorInterface(); + m_GizmoDrawer = new GizmoDrawer(m_EditorInterface); +} + +void EditorLayer::OnUpdate() +{ + using namespace Nuake; + + Nuake::Engine::Tick(); + Nuake::Engine::Draw(); + + auto sceneFramebuffer = GetApplication().GetWindow()->GetFrameBuffer(); + + + // Draw gizmos + if (Ref currentScene = Nuake::Engine::GetCurrentScene(); currentScene) + { + sceneFramebuffer->Bind(); + { + Ref camera; + if (currentScene) + { + camera = currentScene->m_EditorCamera; + //currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_COLOR_ATTACHMENT3)->Unbind(); + //glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_COLOR_ATTACHMENT3)->GetID(), 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, currentScene->m_SceneRenderer->GetGBuffer().GetTexture(GL_DEPTH_ATTACHMENT)->GetID(), 0); + } + + if (currentScene && !Nuake::Engine::IsPlayMode()) + { + glEnable(GL_LINE_SMOOTH); + + if (m_EditorInterface->ShouldDrawAxis()) + { + m_GizmoDrawer->DrawAxis(currentScene, false); + glDepthFunc(GL_GREATER); + + m_GizmoDrawer->DrawAxis(currentScene, true); + glDepthFunc(GL_LESS); + } + + if (m_EditorInterface->ShouldDrawCollision()) + { + m_GizmoDrawer->DrawGizmos(currentScene, false); + glDepthFunc(GL_GREATER); + + m_GizmoDrawer->DrawGizmos(currentScene, true); + glDepthFunc(GL_LESS); + } + } + } + sceneFramebuffer->Unbind(); + } + + m_EditorInterface->Draw(); + m_EditorInterface->Update(Nuake::Engine::GetTimestep()); + Nuake::Engine::EndDraw(); +} + +void EditorLayer::OnDetach() +{ + delete m_EditorInterface; +} \ No newline at end of file diff --git a/Editor/src/EditorLayer.h b/Editor/src/EditorLayer.h new file mode 100644 index 00000000..d974946d --- /dev/null +++ b/Editor/src/EditorLayer.h @@ -0,0 +1,23 @@ +#pragma once +#include + +namespace Nuake { + + class EditorInterface; + +} + +class GizmoDrawer; + + +class EditorLayer : public Nuake::Layer +{ +public: + virtual void OnAttach() override; + virtual void OnUpdate() override; + virtual void OnDetach() override; + +private: + Nuake::EditorInterface* m_EditorInterface; + GizmoDrawer* m_GizmoDrawer; +}; \ No newline at end of file diff --git a/Editor/src/Misc/GizmoDrawer.cpp b/Editor/src/Misc/GizmoDrawer.cpp index f87e7145..e93b6f27 100644 --- a/Editor/src/Misc/GizmoDrawer.cpp +++ b/Editor/src/Misc/GizmoDrawer.cpp @@ -162,14 +162,9 @@ bool GizmoDrawer::IsEntityInSelection(Nuake::Entity entity) return false; } -void GizmoDrawer::DrawGizmos(Ref scene, bool occluded) +void GizmoDrawer::DrawAxis(Ref scene, bool occluded) { - using namespace Nuake; - //RenderCommand::Disable(RendererEnum::DEPTH_TEST); RenderCommand::Enable(RendererEnum::DEPTH_TEST); - // Draw Axis lignes. - //glDepthFunc(GL_ALWAYS); // Disable built-in depth testing - //glDepthMask(false); // Disable writing to the depth buffer { m_LineShader->Bind(); m_LineShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform()); @@ -178,6 +173,13 @@ void GizmoDrawer::DrawGizmos(Ref scene, bool occluded) m_AxisLineBuffer->Bind(); Nuake::RenderCommand::DrawLines(0, 6); } +} + +void GizmoDrawer::DrawGizmos(Ref scene, bool occluded) +{ + using namespace Nuake; + + RenderCommand::Enable(RendererEnum::DEPTH_TEST); glLineWidth(2.0f); auto boxColliderView = scene->m_Registry.view(); diff --git a/Editor/src/Misc/GizmoDrawer.h b/Editor/src/Misc/GizmoDrawer.h index 5d3f96b5..95d17db1 100644 --- a/Editor/src/Misc/GizmoDrawer.h +++ b/Editor/src/Misc/GizmoDrawer.h @@ -49,10 +49,12 @@ private: public: GizmoDrawer(EditorInterface* editor); + + GizmoDrawer() = default; ~GizmoDrawer() = default; void DrawGizmos(Ref scene, bool occluded); - + void DrawAxis(Ref scene, bool occlude); private: void GenerateSphereGizmo(); diff --git a/Editor/src/Windows/WelcomeWindow.cpp b/Editor/src/Windows/WelcomeWindow.cpp index 7c63226e..dccd1bd7 100644 --- a/Editor/src/Windows/WelcomeWindow.cpp +++ b/Editor/src/Windows/WelcomeWindow.cpp @@ -219,7 +219,7 @@ namespace Nuake { SaveRecentFile(); - queuedProjectPath = _Projects[SelectedProject].Path;; + queuedProjectPath = _Projects[SelectedProject].Path; } //ImGui::PopStyleColor(); diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 2335b1f5..73804048 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -29,7 +29,7 @@ namespace Nuake public: static void Init(); // Initialize the engine. - static void Tick(); // Updates everything, called everyframe. + static void Tick(); // Updates everything, called every frame. static void Close(); // Shutdown the engine. static void EnterPlayMode(); // Start the game diff --git a/Nuake/src/Audio/AudioManager.cpp b/Nuake/src/Audio/AudioManager.cpp index 7a48aae1..37cd287e 100644 --- a/Nuake/src/Audio/AudioManager.cpp +++ b/Nuake/src/Audio/AudioManager.cpp @@ -22,6 +22,8 @@ namespace Nuake { m_AudioThreadRunning = false; m_AudioThread.join(); + + m_Soloud->deinit(); } void AudioManager::Initialize() @@ -35,6 +37,13 @@ namespace Nuake { m_Soloud->init(SoLoud::Soloud::CLIP_ROUNDOFF, SoLoud::Soloud::ALSA); #endif + if (m_AudioThread.joinable()) + { + m_AudioThreadRunning = false; + m_AudioThread.join(); + } + + m_AudioThreadRunning = true; m_AudioThread = std::thread(&AudioManager::AudioThreadLoop, this); Logger::Log("Audio manager initialized", "audio", VERBOSE); diff --git a/Nuake/src/Core/Application.cpp b/Nuake/src/Core/Application.cpp new file mode 100644 index 00000000..aff46aeb --- /dev/null +++ b/Nuake/src/Core/Application.cpp @@ -0,0 +1,58 @@ +#include "Application.h" +#include "Layer.h" + +#include + +namespace Nuake { + + Application::Application(const ApplicationSpecification& appSpecification) + : m_Specification(appSpecification), + m_Running(true) + { + if (!appSpecification.Headless) + { + m_Window = Window::Get(); + } + } + + void Application::PushLayer(Scope layer) + { + layer->OnAttach(); + layer->SetApplicationOwner(this); + m_LayerStack.PushLayer(std::move(layer)); + } + + void Application::PushOverlay(Scope layer) + { + layer->OnAttach(); + layer->SetApplicationOwner(this); + m_LayerStack.PushOverlayLayer(std::move(layer)); + } + + void Application::Run() + { + while (m_Running) + { + for (auto& layer : m_LayerStack) + { + layer->OnUpdate(); + } + + if (!m_Specification.Headless) + { + for (auto& layer : m_LayerStack) + { + layer->OnDraw(); + } + } + } + } + + void Application::Exit() + { + for (auto& layer : m_LayerStack) + { + layer->OnDetach(); + } + } +} \ No newline at end of file diff --git a/Nuake/src/Core/Application.h b/Nuake/src/Core/Application.h new file mode 100644 index 00000000..20832369 --- /dev/null +++ b/Nuake/src/Core/Application.h @@ -0,0 +1,89 @@ +#pragma once +#include "IApplicationModule.h" +#include "Core.h" +#include "LayerStack.h" + +#include +#include +#include + + +namespace Nuake { + + struct ApplicationSpecification + { + std::string Name = "Application"; + uint32_t WindowWidth = 1280; + uint32_t WindowHeight = 720; + bool VSync = true; + std::string WorkingDirectory = ""; + bool Headless = false; + }; + + class Application + { + public: + Application(const ApplicationSpecification& appSpecification); + virtual ~Application() {}; + + void Run(); + void Exit(); + + virtual void OnInit() {}; + virtual void OnUpdate() {}; + virtual void OnShutdown() {}; + + virtual void OnEvent() {}; + + inline const std::string& GetName() const { return m_Specification.Name; } + + void PushLayer(Scope layer); + void PushOverlay(Scope layer); + + // Only accepts IApplicationModule type class + template + T& PushModule(Scope applicationModule) + { + static_assert(std::is_base_of::value, "Type must be derived from IApplicationModule"); + + auto* rawPtr = applicationModule.get(); // Get a raw pointer to the module. + m_ApplicationModules.push_back(std::move(applicationModule)); + return *dynamic_cast(rawPtr); + } + + // Only accepts IApplicationModule type class + template + T& GetModule() + { + static_assert(std::is_base_of::value, "Type must be derived from IApplicationModule"); + + auto resultFindIt = std::find_if( + m_ApplicationModules.begin(), + m_ApplicationModules.end(), + [](IApplicationModule& module) + { + return dynamic_cast(&module) != nullptr; + } + ); + + if (resultFindIt == m_ApplicationModules.end()) + { + throw std::runtime_error("Module not found."); + } + + return dynamic_cast(*resultFindIt); + } + + inline Ref GetWindow() const { return m_Window; } + protected: + ApplicationSpecification m_Specification; + std::vector> m_ApplicationModules; + LayerStack m_LayerStack; + bool m_Running; + Ref m_Window; + }; + + // Implemented by the client + Application* CreateApplication(int argc, char** argv); + +} \ No newline at end of file diff --git a/Nuake/src/Core/Core.h b/Nuake/src/Core/Core.h index 816c6a6d..1b32c8b4 100644 --- a/Nuake/src/Core/Core.h +++ b/Nuake/src/Core/Core.h @@ -5,6 +5,7 @@ #include #include #include +#include #define ASSERT(x) if (!(x)) assert(false) diff --git a/Nuake/src/Core/EntryPoint.h b/Nuake/src/Core/EntryPoint.h new file mode 100644 index 00000000..5423d8ca --- /dev/null +++ b/Nuake/src/Core/EntryPoint.h @@ -0,0 +1,44 @@ +#pragma once +#include "Application.h" + +bool g_ApplicationRunning = true; + +namespace Nuake { + + int Main(int argc, char** argv) + { + while (g_ApplicationRunning) + { + Application* app = CreateApplication(argc, argv); + app->OnInit(); + app->Run(); + app->Exit(); + delete app; + + g_ApplicationRunning = false; + } + + return 1; + } +} + +#ifdef NK_WIN +#ifdef NK_DIST +#include "windows.h" +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cdmline, int cmdshow) +{ + return ApplicationMain(__argc, __argv); +} +#else +#define REGULAR_MAIN +#endif +#else +#define REGULAR_MAIN +#endif + +#ifdef REGULAR_MAIN +int main(int argc, char** argv) +{ + return Nuake::Main(argc, argv); +} +#endif \ No newline at end of file diff --git a/Nuake/src/Core/Event.h b/Nuake/src/Core/Event.h new file mode 100644 index 00000000..30f23a61 --- /dev/null +++ b/Nuake/src/Core/Event.h @@ -0,0 +1,20 @@ +#pragma once +#include "Core.h" + + +namespace Nuake { + + enum class EventType + { + None = 0, + WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, + AppUpdate, AppRender, AppEvent, AppCloseEvent + }; + + class Event + { + virtual EventType GetEventType() const = 0; + virtual const std::string_view& GetName() const = 0; + + }; +} \ No newline at end of file diff --git a/Nuake/src/Core/IApplicationModule.h b/Nuake/src/Core/IApplicationModule.h new file mode 100644 index 00000000..4cf6a99e --- /dev/null +++ b/Nuake/src/Core/IApplicationModule.h @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace Nuake +{ + class IApplicationModule + { + private: + std::string m_Name; + + public: + IApplicationModule(const std::string& name) : m_Name(name) {} + virtual ~IApplicationModule() {} + + virtual void OnInit() = 0; + virtual void OnUpdate() = 0; + virtual void OnExit() = 0; + }; + +} \ No newline at end of file diff --git a/Nuake/src/Core/Layer.h b/Nuake/src/Core/Layer.h new file mode 100644 index 00000000..86ffd398 --- /dev/null +++ b/Nuake/src/Core/Layer.h @@ -0,0 +1,35 @@ +#pragma once +#include "Core.h" +#include "Application.h" + + +namespace Nuake { + + class Layer + { + public: + Layer(const std::string& name = "Layer") : m_Name(name) { }; + virtual ~Layer() = default; + + virtual void OnAttach() {}; + virtual void OnUpdate() {}; + virtual void OnDetach() {}; + + virtual void OnDraw() {}; + + // TODO: OnEvent + + inline const std::string& GetName() const { return m_Name; } + + // This is used for layer to have access to the + // application that owns them and their modules. + void SetApplicationOwner(Application* application) { m_Application = application; } + Application& GetApplication() { return *m_Application; } + + private: + std::string m_Name; + + protected: + Application* m_Application; + }; +} \ No newline at end of file diff --git a/Nuake/src/Core/LayerStack.cpp b/Nuake/src/Core/LayerStack.cpp new file mode 100644 index 00000000..af186599 --- /dev/null +++ b/Nuake/src/Core/LayerStack.cpp @@ -0,0 +1,40 @@ +#include "LayerStack.h" +#include "Layer.h" + +namespace Nuake { + + LayerStack::LayerStack() + { + m_LayerInsert = m_Layers.begin(); + } + + void LayerStack::PushLayer(Ref layer) + { + m_LayerInsert = m_Layers.emplace(m_LayerInsert, std::move(layer)); + } + + void LayerStack::PushOverlayLayer(Ref layer) + { + m_Layers.emplace_back(std::move(layer)); + } + + void LayerStack::PopLayer(Ref layer) + { + auto it = std::find(m_Layers.begin(), m_Layers.end(), layer); + if (it != m_Layers.end()) + { + m_Layers.erase(it); + m_LayerInsert--; + } + } + + void LayerStack::PopOverlayLayer(Ref layer) + { + auto it = std::find(m_Layers.begin(), m_Layers.end(), layer); + if (it != m_Layers.end()) + { + m_Layers.erase(it); + } + } + +} \ No newline at end of file diff --git a/Nuake/src/Core/LayerStack.h b/Nuake/src/Core/LayerStack.h new file mode 100644 index 00000000..73ae7e98 --- /dev/null +++ b/Nuake/src/Core/LayerStack.h @@ -0,0 +1,33 @@ +#pragma once +#include "Core.h" + + +#include + + +namespace Nuake { + + class Layer; + + + class LayerStack + { + public: + LayerStack(); + ~LayerStack() = default; + + void PushLayer(Ref layer); + void PopLayer(Ref layer); + + void PushOverlayLayer(Ref layer); + void PopOverlayLayer(Ref layer); + + std::vector>::iterator begin() { return m_Layers.begin(); } + std::vector>::iterator end() { return m_Layers.end(); } + + private: + std::vector> m_Layers; + std::vector>::iterator m_LayerInsert; + }; + +} \ No newline at end of file