Port window and input events to flecs
This commit is contained in:
@@ -17,7 +17,7 @@ void Flycam::keyboard_movement(entt::registry& registry)
|
||||
};
|
||||
|
||||
auto& movement_context = registry.ctx().emplace<KeyboardMovementContext>();
|
||||
auto const& key_state = registry.ctx().get<Input::State<Input::KeyCode>>();
|
||||
auto const& key_state = registry.ctx().get<Input::ButtonInput<Input::KeyCode>>();
|
||||
auto const& delta_time = registry.ctx().get<Time::Delta>();
|
||||
|
||||
auto camera_view =
|
||||
|
||||
@@ -1,38 +1,25 @@
|
||||
#include <input/input.h>
|
||||
#include <window/window.h>
|
||||
#include <flecs.h>
|
||||
#include <input/input.h>
|
||||
#include <iostream>
|
||||
#include <window/window.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
flecs::world world;
|
||||
|
||||
world.import<WindowModule>();
|
||||
spawn_window(world);
|
||||
auto window = world.singleton<Window>();
|
||||
|
||||
world.import <Window::WindowModule>();
|
||||
auto window = Window::spawn_window(world);
|
||||
auto glfw_window = window.get<std::shared_ptr<GLFWwindow>>();
|
||||
|
||||
window.observe<Input::KeyInput>([window](Input::KeyInput& key_input) {
|
||||
auto* key_state = window.get_mut<Input::State<Input::KeyCode>>();
|
||||
|
||||
if (key_input.action == static_cast<Input::Action>(GLFW_PRESS)) {
|
||||
key_state->press(key_input.key_code);
|
||||
} else if (key_input.action == static_cast<Input::Action>(GLFW_RELEASE)) {
|
||||
key_state->release(key_input.key_code);
|
||||
}
|
||||
});
|
||||
world.import <Input::InputModule>();
|
||||
|
||||
while (glfwWindowShouldClose(glfw_window->get()) == GLFW_FALSE) {
|
||||
glfwPollEvents();
|
||||
|
||||
// X just pressed
|
||||
auto* keycode= window.get<Input::State<Input::KeyCode>>();
|
||||
if (keycode->just_pressed(Input::KeyCode{GLFW_KEY_X}))
|
||||
std::cout << "X was just pressed!\n";
|
||||
world.progress();
|
||||
|
||||
Input::State<Input::KeyCode>::update_state(window);
|
||||
glfwSwapBuffers(glfw_window->get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,13 @@ auto Camera::front_vector(GlobalTransform const& transform) -> glm::vec3
|
||||
|
||||
void Camera::aspect_ratio_update(entt::registry& registry)
|
||||
{
|
||||
float aspect_ratio = registry.ctx().get<WindowDeprecated::Descriptor>().aspect_ratio;
|
||||
// float aspect_ratio = registry.ctx().get<WindowDeprecated::Descriptor>().aspect_ratio;
|
||||
|
||||
auto camera_view = registry.view<Camera>();
|
||||
// auto camera_view = registry.view<Camera>();
|
||||
|
||||
for (auto [entity, camera] : camera_view.each()) {
|
||||
// Orthographic projection currently unsupported
|
||||
auto& camera_perspective = std::get<Perspective>(camera.projection);
|
||||
camera_perspective.aspect_ratio = aspect_ratio;
|
||||
}
|
||||
// for (auto [entity, camera] : camera_view.each()) {
|
||||
// // Orthographic projection currently unsupported
|
||||
// auto& camera_perspective = std::get<Perspective>(camera.projection);
|
||||
// camera_perspective.aspect_ratio = aspect_ratio;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -4,36 +4,40 @@
|
||||
|
||||
namespace Input {
|
||||
|
||||
// void KeyListener::key_event(KeyInput const& key_input_event)
|
||||
// {
|
||||
// auto& key_state = registry.ctx().get<State<KeyCode>>();
|
||||
static void keyboard_input_observer(KeyboardInput const& keyboard_input);
|
||||
|
||||
// if (key_input_event.action == static_cast<Action>(GLFW_PRESS)) {
|
||||
// key_state.press(key_input_event.key_code);
|
||||
// } else if (key_input_event.action == static_cast<Action>(GLFW_RELEASE)) {
|
||||
// key_state.release(key_input_event.key_code);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void CursorListener::cursor_event(MouseMotion const& mouse_motion_event)
|
||||
// {
|
||||
// auto& mouse_motion = registry.ctx().get<MouseMotion>();
|
||||
// mouse_motion.delta += mouse_motion_event.delta;
|
||||
// }
|
||||
|
||||
void reset_mouse_motion(entt::registry& registry)
|
||||
InputModule::InputModule(flecs::world& world)
|
||||
{
|
||||
auto& mouse_motion = registry.ctx().get<MouseMotion>();
|
||||
mouse_motion = {};
|
||||
world.component<Input::KeyboardInput>();
|
||||
world.component<Input::MouseButtonInput>();
|
||||
world.component<Input::MouseMotion>();
|
||||
|
||||
world.system<ButtonInput<KeyCode>>("ClearButtonInput")
|
||||
.kind(flecs::PostUpdate)
|
||||
.each(ButtonInput<KeyCode>::clear_button_input);
|
||||
|
||||
world.observer<KeyboardInput>("KeyboardInputObserver")
|
||||
.event(flecs::OnSet)
|
||||
.each(keyboard_input_observer);
|
||||
}
|
||||
|
||||
template <typename T> void State<T>::update_state(flecs::entity window_entity)
|
||||
void keyboard_input_observer(KeyboardInput const& keyboard_input)
|
||||
{
|
||||
auto* state = window_entity.get_mut<State<T>>();
|
||||
state->just_pressed_keys.clear();
|
||||
state->just_released_keys.clear();
|
||||
auto* key_state = keyboard_input.window.get_mut<Input::ButtonInput<Input::KeyCode>>();
|
||||
|
||||
if (keyboard_input.action == static_cast<Input::Action>(GLFW_PRESS)) {
|
||||
key_state->press(keyboard_input.key_code);
|
||||
} else if (keyboard_input.action == static_cast<Input::Action>(GLFW_RELEASE)) {
|
||||
key_state->release(keyboard_input.key_code);
|
||||
}
|
||||
}
|
||||
|
||||
template class State<KeyCode>;
|
||||
template <typename T> void ButtonInput<T>::clear_button_input(ButtonInput<T>& state)
|
||||
{
|
||||
state.just_pressed_keys.clear();
|
||||
state.just_released_keys.clear();
|
||||
}
|
||||
|
||||
template class ButtonInput<KeyCode>;
|
||||
|
||||
} // namespace Input
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "entt/entity/fwd.hpp"
|
||||
#include <entt/entt.hpp>
|
||||
#include <flecs.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace Input {
|
||||
|
||||
struct InputModule
|
||||
{
|
||||
InputModule(flecs::world& world);
|
||||
};
|
||||
|
||||
enum class KeyCode : int
|
||||
{
|
||||
};
|
||||
@@ -17,10 +19,18 @@ enum class Action : int
|
||||
{
|
||||
};
|
||||
|
||||
struct KeyInput
|
||||
struct KeyboardInput
|
||||
{
|
||||
KeyCode key_code;
|
||||
Action action;
|
||||
flecs::entity window;
|
||||
};
|
||||
|
||||
struct MouseButtonInput
|
||||
{
|
||||
KeyCode key_code;
|
||||
Action action;
|
||||
flecs::entity window;
|
||||
};
|
||||
|
||||
struct MouseMotion
|
||||
@@ -28,16 +38,16 @@ struct MouseMotion
|
||||
glm::vec2 delta{};
|
||||
};
|
||||
|
||||
template <typename T> class State
|
||||
template <typename T> class ButtonInput
|
||||
{
|
||||
public:
|
||||
auto pressed(T input) const -> bool { return pressed_keys.contains(input); }
|
||||
auto just_pressed(T input) const -> bool { return just_pressed_keys.contains(input); }
|
||||
auto just_released(T input) const -> bool { return just_pressed_keys.contains(input); }
|
||||
|
||||
static void update_state(flecs::entity window_entity);
|
||||
static void clear_button_input(ButtonInput<T>& state);
|
||||
|
||||
// private:
|
||||
// private:
|
||||
void press(T input)
|
||||
{
|
||||
if (pressed_keys.insert(input).second) {
|
||||
@@ -55,23 +65,6 @@ public:
|
||||
std::set<T> pressed_keys;
|
||||
std::set<T> just_pressed_keys;
|
||||
std::set<T> just_released_keys;
|
||||
|
||||
friend class KeyListener;
|
||||
friend class CursorListener;
|
||||
};
|
||||
|
||||
// struct KeyListener
|
||||
// {
|
||||
// entt::registry& registry;
|
||||
// void key_event(KeyInput const& key_input_event);
|
||||
// };
|
||||
|
||||
// struct CursorListener
|
||||
// {
|
||||
// entt::registry& registry;
|
||||
// void cursor_event(MouseMotion const& mouse_motion_event);
|
||||
// };
|
||||
|
||||
void reset_mouse_motion(entt::registry& registry);
|
||||
|
||||
}; // namespace Input
|
||||
|
||||
@@ -5,14 +5,17 @@
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace Window {
|
||||
|
||||
static constexpr unsigned INIT_WINDOW_WIDTH = 1280;
|
||||
static constexpr unsigned INIT_WINDOW_HEIGHT = 720;
|
||||
static constexpr double MOUSE_SENSITIVITY = 0.15;
|
||||
|
||||
static void glfw_error_callback(int error, char const* description);
|
||||
static void framebuffer_size_callback(GLFWwindow* glfw_window, int width, int height);
|
||||
static void window_size_callback(GLFWwindow* glfw_window, int width, int height);
|
||||
static void key_callback(GLFWwindow* glfw_window, int key, int scancode, int action, int mods);
|
||||
static void mouse_cursor_callback(GLFWwindow* glfw_window, double xpos, double ypos);
|
||||
|
||||
@@ -21,9 +24,12 @@ WindowModule::WindowModule(flecs::world& world)
|
||||
glfwInit();
|
||||
world.component<Window>();
|
||||
world.component<std::shared_ptr<GLFWwindow>>();
|
||||
world.component<std::optional<CursorPosition>>();
|
||||
world.component<LogicalSize>();
|
||||
world.component<PhysicalSize>();
|
||||
}
|
||||
|
||||
void spawn_window(flecs::world& world)
|
||||
flecs::entity spawn_window(flecs::world& world)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
@@ -52,17 +58,26 @@ void spawn_window(flecs::world& world)
|
||||
glfwSetWindowUserPointer(glfw_window.get(), &world);
|
||||
glfwSetKeyCallback(glfw_window.get(), key_callback);
|
||||
glfwSetCursorPosCallback(glfw_window.get(), mouse_cursor_callback);
|
||||
glfwSetWindowSizeCallback(glfw_window.get(), window_size_callback);
|
||||
glfwSetFramebufferSizeCallback(glfw_window.get(), framebuffer_size_callback);
|
||||
|
||||
init_glad();
|
||||
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(glfw_window.get(), &width, &height);
|
||||
glViewport(0, 0, width, height);
|
||||
int window_width, window_height;
|
||||
glfwGetWindowSize(glfw_window.get(), &window_width, &window_height);
|
||||
|
||||
int framebuffer_width, framebuffer_height;
|
||||
glfwGetFramebufferSize(glfw_window.get(), &framebuffer_width, &framebuffer_height);
|
||||
glViewport(0, 0, framebuffer_width, framebuffer_height);
|
||||
|
||||
flecs::entity window = world.singleton<Window>();
|
||||
window.add<Input::State<Input::KeyCode>>();
|
||||
window.add<Input::ButtonInput<Input::KeyCode>>();
|
||||
window.add<std::optional<CursorPosition>>();
|
||||
window.set<std::shared_ptr<GLFWwindow>>(glfw_window);
|
||||
window.set<LogicalSize>({window_width, window_height});
|
||||
window.set<PhysicalSize>({framebuffer_width, framebuffer_height});
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void glfw_error_callback(int error, char const* description)
|
||||
@@ -70,13 +85,22 @@ static void glfw_error_callback(int error, char const* description)
|
||||
spdlog::warn("GLFW [{:d}]: {:s}\n", error, description);
|
||||
}
|
||||
|
||||
void window_size_callback(GLFWwindow* glfw_window, int width, int height)
|
||||
{
|
||||
auto* world = static_cast<flecs::world*>(glfwGetWindowUserPointer(glfw_window));
|
||||
flecs::entity window = world->singleton<Window>();
|
||||
|
||||
window.set<LogicalSize>({width, height});
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* glfw_window, int width, int height)
|
||||
{
|
||||
// auto& window = *static_cast<WindowDeprecated*>(glfwGetWindowUserPointer(glfw_window));
|
||||
// glViewport(0, 0, width, height);
|
||||
auto* world = static_cast<flecs::world*>(glfwGetWindowUserPointer(glfw_window));
|
||||
flecs::entity window = world->singleton<Window>();
|
||||
|
||||
// world->event<ResizeEvent>().emit();
|
||||
// window.event_dispatcher.enqueue<ResizeEvent>();
|
||||
window.set<PhysicalSize>({width, height});
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void key_callback(GLFWwindow* glfw_window,
|
||||
@@ -86,77 +110,56 @@ void key_callback(GLFWwindow* glfw_window,
|
||||
[[maybe_unused]] int mods)
|
||||
{
|
||||
auto* world = static_cast<flecs::world*>(glfwGetWindowUserPointer(glfw_window));
|
||||
flecs::entity window = world->component<Window>();
|
||||
flecs::entity window = world->singleton<Window>();
|
||||
|
||||
window.emit<Input::KeyInput>(Input::KeyInput{.key_code = static_cast<Input::KeyCode>(key),
|
||||
.action = static_cast<Input::Action>(action)});
|
||||
world->component<Input::KeyboardInput>().set<Input::KeyboardInput>(
|
||||
{.key_code = static_cast<Input::KeyCode>(key),
|
||||
.action = static_cast<Input::Action>(action),
|
||||
.window = window});
|
||||
}
|
||||
|
||||
void mouse_cursor_callback(GLFWwindow* glfw_window, double xpos, double ypos)
|
||||
{
|
||||
// auto* world = static_cast<flecs::world*>(glfwGetWindowUserPointer(glfw_window));
|
||||
auto* world = static_cast<flecs::world*>(glfwGetWindowUserPointer(glfw_window));
|
||||
flecs::entity window = world->singleton<Window>();
|
||||
|
||||
// glm::vec2 delta{xpos - window.last_cursor_pos.x, ypos - window.last_cursor_pos.y};
|
||||
auto cursor_position = window.get_mut<std::optional<CursorPosition>>();
|
||||
bool had_value = cursor_position->has_value();
|
||||
|
||||
// window.last_cursor_pos = {xpos, ypos};
|
||||
// delta *= MOUSE_SENSITIVITY;
|
||||
*cursor_position = {xpos, ypos};
|
||||
|
||||
// // Check if this is the first VALID mouse event after window being resized
|
||||
// if (window.first_mouse_input && (delta.x >= std::numeric_limits<double>::epsilon() ||
|
||||
// delta.y >= std::numeric_limits<double>::epsilon())) {
|
||||
// window.first_mouse_input = false;
|
||||
// return;
|
||||
// }
|
||||
// Prevent invalid delta events when the cursor position wasn't valid
|
||||
if (!had_value)
|
||||
return;
|
||||
|
||||
// TODO remove with flecs
|
||||
// window.event_dispatcher.enqueue<Input::MouseMotion>(Input::MouseMotion{.delta = delta});
|
||||
glm::vec2 delta{xpos - cursor_position->value().x, ypos - cursor_position->value().y};
|
||||
|
||||
delta *= MOUSE_SENSITIVITY;
|
||||
|
||||
world->component<Input::MouseMotion>().set<Input::MouseMotion>({delta});
|
||||
}
|
||||
|
||||
auto WindowDeprecated::logical_dimensions() const -> glm::u32vec2
|
||||
{
|
||||
int width{};
|
||||
int height{};
|
||||
glfwGetWindowSize(glfw_window.get(), &width, &height);
|
||||
return {width, height};
|
||||
}
|
||||
} // namespace Window
|
||||
|
||||
auto WindowDeprecated::physical_dimensions() const -> glm::u32vec2
|
||||
{
|
||||
int width{};
|
||||
int height{};
|
||||
glfwGetFramebufferSize(glfw_window.get(), &width, &height);
|
||||
return {width, height};
|
||||
}
|
||||
// void WindowDeprecated::mouse_catching(entt::registry& registry) const
|
||||
// {
|
||||
// auto& mouse_catched = registry.ctx().emplace<MouseCatched>(MouseCatched{.catched = false});
|
||||
// auto const& key_state = registry.ctx().get<Input::ButtonInput<Input::KeyCode>>();
|
||||
|
||||
void WindowDeprecated::mouse_catching(entt::registry& registry) const
|
||||
{
|
||||
auto& mouse_catched = registry.ctx().emplace<MouseCatched>(MouseCatched{.catched = false});
|
||||
auto const& key_state = registry.ctx().get<Input::State<Input::KeyCode>>();
|
||||
// if (key_state.just_pressed(Input::KeyCode{GLFW_KEY_LEFT_CONTROL})) {
|
||||
// mouse_catched.catched = !mouse_catched.catched;
|
||||
|
||||
if (key_state.just_pressed(Input::KeyCode{GLFW_KEY_LEFT_CONTROL})) {
|
||||
mouse_catched.catched = !mouse_catched.catched;
|
||||
// glfwSetInputMode(glfw_window.get(),
|
||||
// GLFW_CURSOR,
|
||||
// mouse_catched.catched ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
|
||||
// }
|
||||
// }
|
||||
|
||||
glfwSetInputMode(glfw_window.get(),
|
||||
GLFW_CURSOR,
|
||||
mouse_catched.catched ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
}
|
||||
// void WindowDeprecated::close_on_esc(entt::registry& registry) const
|
||||
// {
|
||||
// auto const& key_state = registry.ctx().get<Input::ButtonInput<Input::KeyCode>>();
|
||||
|
||||
void WindowDeprecated::close_on_esc(entt::registry& registry) const
|
||||
{
|
||||
auto const& key_state = registry.ctx().get<Input::State<Input::KeyCode>>();
|
||||
|
||||
if (key_state.just_pressed(Input::KeyCode{GLFW_KEY_ESCAPE})) {
|
||||
glfwSetWindowShouldClose(glfw_window.get(), GLFW_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowDeprecated::update_descriptor(entt::registry& registry) const
|
||||
{
|
||||
auto dimensions = logical_dimensions();
|
||||
|
||||
registry.ctx().erase<Descriptor>();
|
||||
registry.ctx().emplace<Descriptor>(Descriptor{
|
||||
.logical_dimensions = dimensions,
|
||||
.aspect_ratio = static_cast<float>(dimensions.x) / static_cast<float>(dimensions.y)});
|
||||
}
|
||||
// if (key_state.just_pressed(Input::KeyCode{GLFW_KEY_ESCAPE})) {
|
||||
// glfwSetWindowShouldClose(glfw_window.get(), GLFW_TRUE);
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -8,39 +8,46 @@
|
||||
|
||||
class GLFWwindow;
|
||||
|
||||
namespace Window {
|
||||
|
||||
void glfw_init();
|
||||
|
||||
struct Window{};
|
||||
struct Window
|
||||
{};
|
||||
|
||||
struct CursorPosition
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct LogicalSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PhysicalSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct WindowModule
|
||||
{
|
||||
WindowModule(flecs::world& world);
|
||||
};
|
||||
|
||||
void spawn_window(flecs::world& world);
|
||||
flecs::entity spawn_window(flecs::world& world);
|
||||
|
||||
} // namespace Window
|
||||
|
||||
class WindowDeprecated
|
||||
{
|
||||
public:
|
||||
struct MouseCatched
|
||||
{
|
||||
bool catched = true;
|
||||
};
|
||||
|
||||
struct Descriptor
|
||||
{
|
||||
glm::u32vec2 logical_dimensions;
|
||||
float aspect_ratio{};
|
||||
};
|
||||
|
||||
struct ResizeEvent
|
||||
{};
|
||||
|
||||
[[nodiscard]] auto handle() -> GLFWwindow& { return *glfw_window; }
|
||||
[[nodiscard]] auto physical_dimensions() const -> glm::u32vec2;
|
||||
[[nodiscard]] auto logical_dimensions() const -> glm::u32vec2;
|
||||
|
||||
void update_descriptor(entt::registry& registry) const;
|
||||
void mouse_catching(entt::registry& registry) const;
|
||||
void close_on_esc(entt::registry& registry) const;
|
||||
|
||||
@@ -51,7 +58,4 @@ private:
|
||||
flecs::entity window_entity;
|
||||
|
||||
std::shared_ptr<GLFWwindow> glfw_window;
|
||||
|
||||
glm::vec2 last_cursor_pos{};
|
||||
bool first_mouse_input = true;
|
||||
};
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
"fx-gltf",
|
||||
"flecs"
|
||||
],
|
||||
"builtin-baseline": "bc994510d2eb11aac7b43b03f67a7751d5bfe0e4"
|
||||
"builtin-baseline": "ce613c41372b23b1f51333815feb3edd87ef8a8b"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user