Dispatcher & Layers
This commit is contained in:
parent
ac1c0adedf
commit
b6464c714c
15 changed files with 229 additions and 19 deletions
|
@ -6,4 +6,6 @@
|
||||||
#error "Unsupported platform: UNIX"
|
#error "Unsupported platform: UNIX"
|
||||||
#else
|
#else
|
||||||
#error "Unsupported platform: Unknown"
|
#error "Unsupported platform: Unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "Core/Logger.h"
|
|
@ -3,13 +3,21 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
|
#include "Events/MouseEvents.h"
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
{
|
{
|
||||||
Logger::Initialize();
|
Logger::Initialize();
|
||||||
|
|
||||||
m_Window = std::unique_ptr<Window>(Window::Create({ "Title", 800u, 600u, false }));
|
m_Window = std::unique_ptr<Window>(Window::Create({ "Title", 800u, 600u, false }, std::bind(&Application::OnEvent, this , std::placeholders::_1)));
|
||||||
|
|
||||||
|
TestLayer* layer = new TestLayer("Test Layer");
|
||||||
|
m_LayerStack.PushLayer(layer);
|
||||||
|
|
||||||
LT_ENGINE_INFO("Initialized Logger");
|
LT_ENGINE_INFO("Initialized Logger");
|
||||||
}
|
}
|
||||||
|
@ -23,4 +31,9 @@ namespace Light {
|
||||||
while (true) { m_Window->OnUpdate(); }
|
while (true) { m_Window->OnUpdate(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::OnEvent(Event& event)
|
||||||
|
{
|
||||||
|
m_Dispatcher.Dispatch(event, m_LayerStack.begin(), m_LayerStack.end());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
|
#include "Events/Event.h"
|
||||||
|
#include "Events/Dispatcher.h"
|
||||||
|
|
||||||
|
#include "Layer/LayerStack.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
@ -12,11 +17,13 @@ namespace Light {
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Window> m_Window = nullptr;
|
std::unique_ptr<Window> m_Window = nullptr;
|
||||||
|
LayerStack m_LayerStack;
|
||||||
|
Dispatcher m_Dispatcher;
|
||||||
public:
|
public:
|
||||||
virtual ~Application();
|
virtual ~Application();
|
||||||
|
|
||||||
void GameLoop();
|
void GameLoop();
|
||||||
|
void OnEvent(Event& event);
|
||||||
|
|
||||||
// To be defined in client project
|
// To be defined in client project
|
||||||
friend Application* CreateApplication();
|
friend Application* CreateApplication();
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
|
#include "Events/Event.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
@ -25,7 +27,7 @@ namespace Light {
|
||||||
|
|
||||||
virtual inline void* GetNativeHandle() = 0;
|
virtual inline void* GetNativeHandle() = 0;
|
||||||
|
|
||||||
static Window* Create(const WindowProperties& properties);
|
static Window* Create(const WindowProperties& properties, std::function<void(Event&)> callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
42
Engine/src/Engine/Events/Dispatcher.h
Normal file
42
Engine/src/Engine/Events/Dispatcher.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Base.h"
|
||||||
|
|
||||||
|
#include "Event.h"
|
||||||
|
|
||||||
|
#include "Layer/Layer.h"
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
class Dispatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Dispatch(Event& event, std::vector<Layer*>::iterator begin, std::vector<Layer*>::iterator end)
|
||||||
|
{
|
||||||
|
switch (event.GetEventType())
|
||||||
|
{
|
||||||
|
case EventType::MouseMoved:
|
||||||
|
for (auto it = begin; it != end; it++)
|
||||||
|
if ((*it)->OnMouseMoved((MouseMovedEvent&)event)) return;
|
||||||
|
return;
|
||||||
|
case EventType::ButtonPressed:
|
||||||
|
for (auto it = begin; it != end; it++)
|
||||||
|
if ((*it)->OnButtonPressed((ButtonPressedEvent&)event)) return;
|
||||||
|
return;
|
||||||
|
case EventType::ButtonReleased:
|
||||||
|
for (auto it = begin; it != end; it++)
|
||||||
|
if ((*it)->OnButtonReleased((ButtonReleasedEvent&)event)) return;
|
||||||
|
return;
|
||||||
|
case EventType::KeyPressed:
|
||||||
|
for (auto it = begin; it != end; it++)
|
||||||
|
if ((*it)->OnKeyPressed((KeyPressedEvent&)event)) return;
|
||||||
|
return;
|
||||||
|
case EventType::KeyReleased:
|
||||||
|
for (auto it = begin; it != end; it++)
|
||||||
|
if ((*it)->OnKeyReleased((KeyReleasedEvent&)event)) return;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -4,9 +4,11 @@
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
enum EventType
|
enum class EventType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
|
@ -18,19 +20,14 @@ namespace Light {
|
||||||
WindowMoved, WindowResized, WindowClosed,
|
WindowMoved, WindowResized, WindowClosed,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EVENT_TYPE(x) virtual EventType GetType() override { return x; }
|
#define EVENT_TYPE(type) EventType GetEventType() const override { return EventType::##type; }
|
||||||
|
|
||||||
class Event
|
class Event
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
bool b_Handled;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual EventType GetType() = 0;
|
virtual EventType GetEventType() const = 0;
|
||||||
virtual std::string GetInfoLog() const = 0;
|
virtual std::string GetInfoLog() const = 0;
|
||||||
|
|
||||||
inline bool IsHandled() const { return b_Handled; }
|
|
||||||
|
|
||||||
friend std::ostream & operator<<(std::ostream & os, const Event& e)
|
friend std::ostream & operator<<(std::ostream & os, const Event& e)
|
||||||
{
|
{
|
||||||
return os << e.GetInfoLog();
|
return os << e.GetInfoLog();
|
||||||
|
|
3
Engine/src/Engine/Events/Events.cpp
Normal file
3
Engine/src/Engine/Events/Events.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "Event.h"
|
||||||
|
#include "KeyboardEvents.h"
|
||||||
|
#include "MouseEvents.h"
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Events/Event.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ namespace Light {
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "KeyPressed: " << m_Key;
|
ss << "KeyPressed: " << m_Key;
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
||||||
EVENT_TYPE(KeyPressed)
|
EVENT_TYPE(KeyPressed)
|
||||||
};
|
};
|
||||||
|
@ -40,6 +41,7 @@ namespace Light {
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "KeyReleased: " << m_Key;
|
ss << "KeyReleased: " << m_Key;
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
||||||
EVENT_TYPE(KeyReleased)
|
EVENT_TYPE(KeyReleased)
|
||||||
};
|
};
|
|
@ -63,7 +63,8 @@ namespace Light {
|
||||||
ss << "ButtonReleased: " << m_Button;
|
ss << "ButtonReleased: " << m_Button;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
EVENT_TYPE(ButtonReleased)
|
|
||||||
|
EVENT_TYPE(ButtonReleased);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
47
Engine/src/Engine/Layer/Layer.h
Normal file
47
Engine/src/Engine/Layer/Layer.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Base.h"
|
||||||
|
|
||||||
|
#include "Events/MouseEvents.h"
|
||||||
|
#include "Events/KeyboardEvents.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
class Layer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string m_Name;
|
||||||
|
public:
|
||||||
|
Layer(const std::string& name): m_Name(name) {}
|
||||||
|
virtual ~Layer() = default;
|
||||||
|
|
||||||
|
inline const std::string& GetName() const { return m_Name; }
|
||||||
|
|
||||||
|
// Mouse events
|
||||||
|
virtual bool OnMouseMoved(const MouseMovedEvent& event) { return false; }
|
||||||
|
virtual bool OnButtonPressed(const ButtonPressedEvent& event) { return false; }
|
||||||
|
virtual bool OnButtonReleased(const ButtonReleasedEvent& event) { return false; }
|
||||||
|
|
||||||
|
// Keyboard events
|
||||||
|
virtual bool OnKeyPressed(const KeyPressedEvent& event) { return false; }
|
||||||
|
virtual bool OnKeyReleased(const KeyReleasedEvent& event) { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestLayer : public Layer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestLayer(const std::string& name): Layer(name) {}
|
||||||
|
|
||||||
|
// Mouse events
|
||||||
|
virtual bool OnMouseMoved(const MouseMovedEvent& event) { LT_ENGINE_TRACE("{}", event.GetInfoLog()); return false; }
|
||||||
|
virtual bool OnButtonPressed(const ButtonPressedEvent& event) { LT_ENGINE_TRACE(event.GetInfoLog()); return false; }
|
||||||
|
virtual bool OnButtonReleased(const ButtonReleasedEvent& event) { LT_ENGINE_TRACE(event.GetInfoLog()); return false; }
|
||||||
|
|
||||||
|
// Keyboard events
|
||||||
|
virtual bool OnKeyPressed(const KeyPressedEvent& event) { LT_ENGINE_TRACE(event.GetInfoLog()); return false; }
|
||||||
|
virtual bool OnKeyReleased(const KeyReleasedEvent& event) { LT_ENGINE_TRACE(event.GetInfoLog()); return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
23
Engine/src/Engine/Layer/LayerStack.cpp
Normal file
23
Engine/src/Engine/Layer/LayerStack.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "LayerStack.h"
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
LayerStack::~LayerStack()
|
||||||
|
{
|
||||||
|
for (Layer* layer : m_Layers)
|
||||||
|
delete layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerStack::PushLayer(Layer* layer)
|
||||||
|
{
|
||||||
|
m_Layers.push_back(layer);
|
||||||
|
LT_ENGINE_TRACE("LayerStack::PushLayer: Attached [{}]", layer->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerStack::PopLayer(Layer* layer)
|
||||||
|
{
|
||||||
|
m_Layers.erase(std::find(m_Layers.begin(), m_Layers.end(), layer));
|
||||||
|
LT_ENGINE_TRACE("LayerStack::PushLayer: Detatched[{}]", layer->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
26
Engine/src/Engine/Layer/LayerStack.h
Normal file
26
Engine/src/Engine/Layer/LayerStack.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Base.h"
|
||||||
|
|
||||||
|
#include "Layer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
class LayerStack
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<Layer*> m_Layers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~LayerStack();
|
||||||
|
|
||||||
|
void PushLayer(Layer* layer);
|
||||||
|
void PopLayer(Layer* layer);
|
||||||
|
|
||||||
|
std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }
|
||||||
|
std::vector<Layer*>::iterator end() { return m_Layers.end(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,20 +1,26 @@
|
||||||
#include "wWindow.h"
|
#include "wWindow.h"
|
||||||
|
|
||||||
|
#include "Events/KeyboardEvents.h"
|
||||||
|
#include "Events/MouseEvents.h"
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
Window* Window::Create(const WindowProperties& properties)
|
Window* Window::Create(const WindowProperties& properties, std::function<void(Event&)> callback)
|
||||||
{
|
{
|
||||||
return new wWindow(properties);
|
return new wWindow(properties, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
wWindow::wWindow(const WindowProperties& properties)
|
wWindow::wWindow(const WindowProperties& properties, std::function<void(Event&)> callback)
|
||||||
: m_Properties(properties)
|
: m_Properties(properties), m_EventCallback(callback)
|
||||||
{
|
{
|
||||||
if (!glfwInit()) __debugbreak();
|
if (!glfwInit()) __debugbreak();
|
||||||
|
|
||||||
m_Handle = glfwCreateWindow(properties.width, properties.height, properties.title.c_str(), nullptr, nullptr);
|
m_Handle = glfwCreateWindow(properties.width, properties.height, properties.title.c_str(), nullptr, nullptr);
|
||||||
|
|
||||||
glfwMakeContextCurrent(m_Handle);
|
glfwMakeContextCurrent(m_Handle);
|
||||||
|
glfwSetWindowUserPointer(m_Handle, &m_EventCallback);
|
||||||
|
|
||||||
|
BindGlfwEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
wWindow::~wWindow()
|
wWindow::~wWindow()
|
||||||
|
@ -38,4 +44,33 @@ namespace Light {
|
||||||
return m_Properties.height;
|
return m_Properties.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wWindow::BindGlfwEvents()
|
||||||
|
{
|
||||||
|
glfwSetCursorPosCallback(m_Handle, [](GLFWwindow* window, double xpos, double ypos)
|
||||||
|
{
|
||||||
|
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
|
||||||
|
callback(MouseMovedEvent(xpos, ypos));
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetMouseButtonCallback(m_Handle, [](GLFWwindow* window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
|
||||||
|
|
||||||
|
if (action == GLFW_PRESS)
|
||||||
|
callback(ButtonPressedEvent(button));
|
||||||
|
else
|
||||||
|
callback(ButtonReleasedEvent(button));
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetKeyCallback(m_Handle, [](GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
|
||||||
|
|
||||||
|
if (action == GLFW_PRESS)
|
||||||
|
callback(KeyPressedEvent(key));
|
||||||
|
else
|
||||||
|
callback(KeyReleasedEvent(key));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "Core/Window.h"
|
#include "Core/Window.h"
|
||||||
|
|
||||||
|
#include "Events/Event.h"
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -15,8 +17,10 @@ namespace Light {
|
||||||
private:
|
private:
|
||||||
GLFWwindow* m_Handle = nullptr;
|
GLFWwindow* m_Handle = nullptr;
|
||||||
WindowProperties m_Properties;
|
WindowProperties m_Properties;
|
||||||
|
|
||||||
|
std::function<void(Event&)> m_EventCallback;
|
||||||
public:
|
public:
|
||||||
wWindow(const WindowProperties& properties);
|
wWindow(const WindowProperties& properties, std::function<void(Event&)> callback);
|
||||||
|
|
||||||
~wWindow();
|
~wWindow();
|
||||||
|
|
||||||
|
@ -26,6 +30,8 @@ namespace Light {
|
||||||
virtual unsigned int GetHeight() override;
|
virtual unsigned int GetHeight() override;
|
||||||
|
|
||||||
virtual inline void* GetNativeHandle() override { return m_Handle; }
|
virtual inline void* GetNativeHandle() override { return m_Handle; }
|
||||||
|
private:
|
||||||
|
void BindGlfwEvents();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Engine/Events/Event.h"
|
||||||
|
#include "Engine/Events/KeyboardEvents.h"
|
||||||
|
#include "Engine/Events/MouseEvents.h"
|
||||||
|
|
||||||
#include "Engine/Core/Application.h"
|
#include "Engine/Core/Application.h"
|
||||||
#include "Engine/Core/Logger.h"
|
#include "Engine/Core/Logger.h"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue