Elevate Engine 1
Loading...
Searching...
No Matches
Application.cpp
Go to the documentation of this file.
1#include "eepch.h"
2
3#include <filesystem>
4
5#include "Application.h"
6
12
16
22
24
25#ifdef EE_PLATFORM_WEB
26 #include <emscripten.h>
27#endif
28
29namespace Elevate {
30
31#define BIND_EVENT_FN(x) std::bind(&Application::x, this, std::placeholders::_1)
32
33 Application* Application::s_Instance = nullptr;
34
36 {
37 EE_CORE_ASSERT(!s_Instance, "Application already exists!");
38 s_Instance = this;
39
40 EE_CORE_TRACE("Current working directory : {}", std::filesystem::current_path().string().c_str());
41
42 m_Window = std::unique_ptr<Window>(Window::Create());
43 m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
44
46
47 FrameBuffer.reset(Framebuffer::Create(m_Window->GetWidth(), m_Window->GetHeight()));
48 FrameBuffer->SetClearColor({ 0.8f, 0.4f, 0.7f, 1.0f }); // Pink / purple for debug purposes
49
50 #ifdef EE_EDITOR_BUILD
53 #else
55 #endif
56
57 m_ImGuiLayer = new ImGuiLayer();
58 PushOverlay(m_ImGuiLayer);
59 }
60
62 {
63 m_LayerStack.PushLayer(layer);
64 layer->OnAttach();
65 }
66
68 {
69 m_LayerStack.PushOverlay(overlay);
70 overlay->OnAttach();
71 }
72
73 // Event Dispatcher
75 {
76 EventDispatcher dispatcher(e);
77 dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose));
78 dispatcher.Dispatch<WindowResizeEvent>(BIND_EVENT_FN(OnWindowResize));
79 dispatcher.Dispatch<WindowFocusEvent>(BIND_EVENT_FN(OnWindowFocusEvent));
80
81 // Keyboard
82 dispatcher.Dispatch<KeyPressedEvent>(BIND_EVENT_FN(OnKeyPressedEvent));
83 dispatcher.Dispatch<KeyReleasedEvent>(BIND_EVENT_FN(OnKeyReleasedEvent));
84
85 // Mousse
86 dispatcher.Dispatch<MouseButtonPressedEvent>(BIND_EVENT_FN(OnMouseButtonPressedEvent));
87 dispatcher.Dispatch<MouseButtonReleasedEvent>(BIND_EVENT_FN(OnMouseButtonReleasedEvent));
88
89 for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();)
90 {
91 (*--it)->OnEvent(e);
92 if (e.Handled)
93 break;
94 }
95 }
96
97#ifdef EE_PLATFORM_WEB
98 // Intermediate function to call the main loop in web builds
99 void WebMainLoop(void* arg)
100 {
101 static_cast<Application*>(arg)->EngineFrame();
102 }
103#endif
104
105 void Application::Start(int argc, char** argv)
106 {
107 //Log::Init(); // todo remove or uncomment depending on if the workarround worked
108 EE_CORE_INFO("Initializing ElevateEngine...");
109 auto app = CreateApplication();
110 app->m_args = ApplicationArguments(argc, argv);
111 EE_CORE_TRACE("Application Initialized.");
112 app->Run();
113
114#ifndef EE_PLATFORM_WEB
115 delete app;
116#endif
117 }
118
120 {
122 }
123
124 void Application::EngineFrame() // Each frame
125 {
126 static float lastTime = 0.0f;
127
128#if !EE_ASSERTS_ENABLED
129 try
130 {
131#endif // #if EE_ASSERTS_ENABLED
132 // TIME UPDATE //////////////////
133 Time::currentTime_ = (float) m_Window->GetTime();
134 Time::deltaTime_ = Time::currentTime_ - lastTime;
135 lastTime = Time::currentTime_;
137
140
141 FrameBuffer->Bind(); // Rendering the screen in a single texture
142 FrameBuffer->Clear();
143
144 for (Layer* layer : m_LayerStack)
145 layer->OnUpdate();
146
147 // Draw Layers and Scenes
148 for (Layer* layer : m_LayerStack)
149 layer->OnRender();
150
153
154 FrameBuffer->Unbind(); // Back to normal
155
156 #ifndef EE_EDITOR_BUILD
157 FrameBuffer->BlitFramebufferToScreen(m_Window->GetWidth(), m_Window->GetHeight());
158 #endif
159
160 //imgui
161 m_ImGuiLayer->PreRender();
162 m_ImGuiLayer->Begin();
163
164 for (Layer* layer : m_LayerStack)
165 layer->OnImGuiRender();
166
167 m_ImGuiLayer->Render(); // render imgui
168 m_ImGuiLayer->End(); // finish the imgui rendering
169
170 Renderer::InvalidateStateCache(); // Clear the renderer state after ImGui rendering
171 Input::ManageMidStates(); // Manage Key/Button up and down state
172
174 // Poll events and swap buffers
175 m_Window->OnUpdate();
176
177#ifdef EE_PLATFORM_WEB
178 if (!m_Running)
179 {
180 emscripten_cancel_main_loop();
181 Exit();
182 }
183#endif
184
185#if !EE_ASSERTS_ENABLED
186 }
187 catch (const std::exception& exc)
188 {
189 EE_CORE_ERROR("{}", exc.what());
190 }
191#endif // #if EE_ASSERTS_ENABLED
192 }
193
195 {
196#ifdef EE_PLATFORM_WEB
197 emscripten_set_main_loop_arg(WebMainLoop, this, 0, true);
198#else
199 while (m_Running)
200 {
201 EngineFrame();
202 }
203 Exit();
204#endif
205 }
206
208 {
209 m_ImGuiLayer->Cleanup();
211 }
212
214 {
215 return s_Instance->m_state;
216 }
217
219 {
220 if (s_Instance->m_state != newState)
221 {
222 GameContextState oldState = s_Instance->m_state;
223 s_Instance->m_state = newState;
224
225 EE_CORE_INFO("GameContext state changed from {} to {}",
226 GetGameContextStateName(oldState),
227 GetGameContextStateName(newState));
228
229 s_Instance->OnStateChange(oldState, newState);
230 }
231 }
232
234 {
235 return s_Instance->m_args;
236 }
237
238#pragma region Events
240 {
241 GameContextEvent e(oldState, newState);
242 OnEvent(e);
243 }
244
245 bool Application::OnKeyPressedEvent(KeyPressedEvent& e)
246 {
248 return true;
249 }
250
251 bool Application::OnKeyReleasedEvent(KeyReleasedEvent& e)
252 {
254 return true;
255 }
256
257 bool Application::OnMouseButtonPressedEvent(MouseButtonPressedEvent& e)
258 {
260 return true;
261 }
262
263 bool Application::OnMouseButtonReleasedEvent(MouseButtonReleasedEvent& e)
264 {
266 return true;
267 }
268
269 bool Application::OnWindowClose(WindowCloseEvent& e)
270 {
271 m_Running = false;
272 return true;
273 }
274
275 bool Application::OnWindowResize(WindowResizeEvent& e)
276 {
277 Renderer::SetViewport(0, 0, e.GetWidth(), e.GetHeight());
278 return true;
279 }
280
281 bool Application::OnWindowFocusEvent(WindowFocusEvent& e)
282 {
284
285 if (e.GetFocusState())
286 {
287 // todo add a setting to check the type of suspend to impl.
289 }
290 else
291 {
293 }
294
295 return true;
296 }
297
298#pragma endregion
299}
#define BIND_EVENT_FN(x)
std::unique_ptr< Framebuffer > FrameBuffer
Definition Application.h:60
void PushLayer(Layer *layer)
static void SetGameState(GameContextState newState)
static const GameContextState & GetGameState()
void OnEvent(Event &e)
void PushOverlay(Layer *overlay)
void OnStateChange(GameContextState oldState, GameContextState newState)
static void Start(int argc, char **argv)
static ApplicationArguments GetArguments()
friend class Elevate::Editor::EditorLayer
Definition Application.h:43
bool Dispatch(EventFn< T > func)
Definition Event.h:67
bool Handled
Definition Event.h:41
static Framebuffer * Create(uint32_t width=1280, uint32_t height=720)
static void OnKeyPressedEvent(KeyPressedEvent &e)
Managed Callbacks // Could be used to simulate inputs to an app by sending events.
Definition Input.h:57
static void OnMouseButtonReleasedEvent(MouseButtonReleasedEvent &e)
Definition Input.h:70
static void OnKeyReleasedEvent(KeyReleasedEvent &e)
Definition Input.h:61
static void ManageMidStates()
Definition Input.h:52
static void ResetAllStates()
Definition Input.h:53
static void OnMouseButtonPressedEvent(MouseButtonPressedEvent &e)
Definition Input.h:66
std::vector< Layer * >::iterator begin()
Definition LayerStack.h:19
std::vector< Layer * >::iterator end()
Definition LayerStack.h:20
void PushOverlay(Layer *overlay)
void PushLayer(Layer *layer)
virtual void OnAttach()
Definition Layer.h:15
static void FlushBuffers()
Definition Renderer.cpp:63
static void SetViewport(int x, int y, int width, int height)
Definition Renderer.cpp:68
static void InvalidateStateCache()
Definition Renderer.cpp:174
static void DrawStack()
Definition Renderer.cpp:86
static void Terminate()
static void Suspend(bool renderAnyway=false, bool fadeOut=true)
static void Wakeup()
static void RenderAudio()
static void UpdateLoadingTextures()
static Window * Create(const WindowProps &props=WindowProps("app.config"))
Definition Window.cpp:77
const char * GetGameContextStateName(GameContextState state)
GameContextState
Definition GameContext.h:6
@ EditorMode
Definition GameContext.h:8
Application * CreateApplication()