text: #include "rblpch.h"
  #include "Application.h"
  #include "Rebelle/Log.h"
  #include "Macros.h"
  #include "Renderer/Renderer.h"
  #include <glfw/glfw3.h>
  
  namespace Rebelle {
  	Application* Application::s_Instance = nullptr;
  
  	Application::Application() 
  	{
  		RBL_CORE_ASSERT(!s_Instance, "Application already exists");
  		s_Instance = this;
  
  		m_Window = std::unique_ptr<Window>(Window::Create());
  		m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
  		m_Window->SetVSync(true);
  		m_ImGuiLayer = new ImGuiLayer();
  		PushOverlay(m_ImGuiLayer);
  	}
  
  	Application::~Application()
  	{
  	}
  
  	void Application::Run()
  	{
  		while (m_Running) 
  		{
  			float time = (float) glfwGetTime(); //@todo move to Platform::GetTime
  			TimeStep timeStep = time - m_LastFrameTime;
  			m_LastFrameTime = time;
  
  			m_LayerStack.Update(timeStep);
  
  			m_ImGuiLayer->Begin();
  			for (Layer* layer : m_LayerStack)
  				layer->OnImGuiRender();
  			m_ImGuiLayer->End();
  			
  			m_Window->OnUpdate();
  		}
  	}
  
  	void Application::OnEvent(Event& e)
  	{
  		EventDispatcher dispatcher(e);
  
  		dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClosed));
  
  		for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();)
  		{
  			(*--it)->OnEvent(e);
  			if (e.Handled)
  			{
  				break;
  			}
  		}
  	}
  
  	bool Application::OnWindowClosed(WindowCloseEvent& e)
  	{
  		m_Running = false;
  		return true;
  	}
  
  	void Application::PushLayer(Layer* layer)
  	{
  		m_LayerStack.PushLayer(layer);
  		layer->OnAttach();
  	}
  
  	void Application::PushOverlay(Layer* layer)
  	{
  		m_LayerStack.PushOverlay(layer);
  		layer->OnAttach();
  	}
  }