ADD: Ui can now block inputs for tile highlight system
This commit is contained in:
parent
285af0ae47
commit
16b4747175
@ -215,6 +215,27 @@ add_executable(Dicewars_Siedler src/main.cpp
|
||||
src/engine/renderer/model/GuiTextureBuilder.h
|
||||
src/game/ui/components/UiBuildingMenuContainer.cpp
|
||||
src/game/ui/components/UiBuildingMenuContainer.h
|
||||
src/engine/core/inputsOutputs/stateControl/states/IState.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/states/IState.h
|
||||
src/engine/core/inputsOutputs/stateControl/InputUser.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/InputUser.h
|
||||
src/engine/core/inputsOutputs/inputs/Keyboard.cpp
|
||||
src/engine/core/inputsOutputs/inputs/Keyboard.h
|
||||
src/engine/core/inputsOutputs/inputs/Mouse.cpp
|
||||
src/engine/core/inputsOutputs/inputs/Mouse.h
|
||||
src/engine/core/inputsOutputs/inputs/MouseButton.h
|
||||
src/engine/core/inputsOutputs/stateControl/RegisteredUsers.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/RegisteredUsers.h
|
||||
src/engine/core/inputsOutputs/stateControl/StateManager.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/StateManager.h
|
||||
src/engine/core/inputsOutputs/stateControl/states/State.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/states/State.h
|
||||
src/engine/core/inputsOutputs/stateControl/states/EmptyState.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/states/EmptyState.h
|
||||
src/engine/core/inputsOutputs/stateControl/inputUser/GameInputUser.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/inputUser/GameInputUser.h
|
||||
src/engine/core/inputsOutputs/stateControl/StateRegistry.cpp
|
||||
src/engine/core/inputsOutputs/stateControl/StateRegistry.h
|
||||
)
|
||||
|
||||
target_compile_options(Dicewars_Siedler PRIVATE
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
#include "EngineTime.h"
|
||||
#include "../layer/Layer.h"
|
||||
#include "../platform/glfw/InputManager.h"
|
||||
#include "inputsOutputs/stateControl/StateRegistry.h"
|
||||
#include "inputsOutputs/stateControl/states/EmptyState.h"
|
||||
#include "inputsOutputs/stateControl/states/State.h"
|
||||
|
||||
Application* Application::instance = nullptr;
|
||||
|
||||
@ -16,7 +19,7 @@ void Application::updateTime() {
|
||||
EngineTime::totalTime += EngineTime::deltaTime;
|
||||
lastFrame = now;
|
||||
|
||||
printf("Frametime: %f\n", EngineTime::deltaTime);
|
||||
// printf("Frametime: %f\n", EngineTime::deltaTime);
|
||||
}
|
||||
|
||||
void Application::pushLayer(Layer* layer) {
|
||||
@ -35,6 +38,9 @@ Application::Application()
|
||||
window_props.VSync = true;
|
||||
|
||||
window.reset(Window::Create(window_props));
|
||||
keyboard = std::make_unique<Keyboard>(*window);
|
||||
mouse = std::make_unique<Mouse>(*window);
|
||||
stateManager = std::make_unique<StateManager>(StateRegistry::get().empty, StateRegistry::get().game);
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
@ -51,6 +57,10 @@ void Application::run() {
|
||||
}
|
||||
window->OnUpdate();
|
||||
InputManager::update();
|
||||
|
||||
mouse->update();
|
||||
keyboard->update();
|
||||
stateManager->updateState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
|
||||
#include "Window.h"
|
||||
#include "events/EventBus.h"
|
||||
#include "inputsOutputs/inputs/Keyboard.h"
|
||||
#include "inputsOutputs/inputs/Mouse.h"
|
||||
#include "inputsOutputs/stateControl/StateManager.h"
|
||||
#include "inputsOutputs/stateControl/states/State.h"
|
||||
|
||||
|
||||
class Layer;
|
||||
@ -25,6 +29,11 @@ public:
|
||||
static Application& getInstance();
|
||||
[[nodiscard]] Window& getWindow() const {return *window;}
|
||||
EventBus& getEventBus() {return eventBus;}
|
||||
std::unique_ptr<Keyboard> keyboard;
|
||||
std::unique_ptr<Mouse> mouse;
|
||||
std::unique_ptr<StateManager> stateManager;
|
||||
|
||||
std::shared_ptr<GameState> gameState;
|
||||
private:
|
||||
bool running = true;
|
||||
std::unique_ptr<Window> window;
|
||||
|
||||
@ -38,9 +38,9 @@ void UiButton::onCollectRenderData(UiRenderBundle &uiRenderBundle) {
|
||||
|
||||
VisualStyle UiButton::getVisualStyle() const {
|
||||
switch (state) {
|
||||
case UiState::PRESSED:
|
||||
case UiElementState::PRESSED:
|
||||
return {1.0f, glm::vec3(0.3, 0.6, 1.0), 0.15f};
|
||||
case UiState::HOVERED:
|
||||
case UiElementState::HOVERED:
|
||||
return {1.15f, glm::vec3(0.0f), 0.0f};
|
||||
default:
|
||||
return {};
|
||||
|
||||
@ -59,15 +59,15 @@ void UiComponent::onUpdate(float) {
|
||||
bool releasedFrame = InputManager::isMouseButtonReleased(GLFW_MOUSE_BUTTON_LEFT);
|
||||
|
||||
if (pressedThisFrame) {
|
||||
state = UiState::PRESSED;
|
||||
state = UiElementState::PRESSED;
|
||||
} else if (releasedFrame) {
|
||||
if (state == UiState::PRESSED && hoveredNow) {
|
||||
if (state == UiElementState::PRESSED && hoveredNow) {
|
||||
onClick();
|
||||
}
|
||||
state = hoveredNow ? UiState::HOVERED : UiState::NORMAL;
|
||||
state = hoveredNow ? UiElementState::HOVERED : UiElementState::NORMAL;
|
||||
} else {
|
||||
if (state != UiState::PRESSED)
|
||||
state = hoveredNow ? UiState::HOVERED : UiState::NORMAL;
|
||||
if (state != UiElementState::PRESSED)
|
||||
state = hoveredNow ? UiElementState::HOVERED : UiElementState::NORMAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include "UiRenderBundle.h"
|
||||
#include "../../../renderer/model/GUITexture.h"
|
||||
|
||||
enum class UiState {
|
||||
enum class UiElementState {
|
||||
NORMAL, HOVERED, PRESSED
|
||||
};
|
||||
|
||||
@ -38,13 +38,13 @@ public:
|
||||
uiPositioner.setLayout(style);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isHovered() const { return state == UiState::HOVERED; }
|
||||
[[nodiscard]] bool isHovered() const { return state == UiElementState::HOVERED; }
|
||||
virtual void onClick() {};
|
||||
|
||||
UiComponent* getChildAtIndex(size_t t) const;
|
||||
protected:
|
||||
bool visible = true;
|
||||
UiState state = UiState::NORMAL;
|
||||
UiElementState state = UiElementState::NORMAL;
|
||||
|
||||
virtual void onUpdate(float );
|
||||
virtual void onCollectRenderData(UiRenderBundle& uiRenderBundle) {}
|
||||
|
||||
68
src/engine/core/inputsOutputs/inputs/Keyboard.cpp
Normal file
68
src/engine/core/inputsOutputs/inputs/Keyboard.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "Keyboard.h"
|
||||
#include "../../Window.h"
|
||||
#include "../../Application.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
Keyboard::Keyboard(Window &window) {
|
||||
addKeyListener(window);
|
||||
addTextListener(window);
|
||||
}
|
||||
|
||||
void Keyboard::update() {
|
||||
keysPressedThisFrame.clear();
|
||||
keysReleasedThisFrame.clear();
|
||||
keysRepeatedThisFrame.clear();
|
||||
charsThisFrame.clear();
|
||||
}
|
||||
|
||||
bool Keyboard::isKeyDown(int key) {
|
||||
return keysDown.contains(key);
|
||||
}
|
||||
|
||||
const std::vector<int> & Keyboard::getCharsThisFrame() {
|
||||
return charsThisFrame;
|
||||
}
|
||||
|
||||
bool Keyboard::keyPressEvent(int key) {
|
||||
return keysPressedThisFrame.contains(key);
|
||||
}
|
||||
|
||||
bool Keyboard::keyPressEvent(int key, bool checkRepeats) {
|
||||
return keysPressedThisFrame.contains(key) || (checkRepeats && keysRepeatedThisFrame.contains(key));
|
||||
}
|
||||
|
||||
bool Keyboard::keyReleaseEvent(int key) {
|
||||
return keysReleasedThisFrame.contains(key);
|
||||
}
|
||||
|
||||
void Keyboard::addTextListener(Window &window) {
|
||||
glfwSetCharCallback(static_cast<GLFWwindow *>(window.GetNativeWindow()), [](GLFWwindow *window, const unsigned int key) {
|
||||
Application::getInstance().keyboard->charsThisFrame.push_back(static_cast<int>(key));
|
||||
});
|
||||
}
|
||||
|
||||
void Keyboard::addKeyListener(Window &window) {
|
||||
glfwSetKeyCallback(static_cast<GLFWwindow *>(window.GetNativeWindow()), [](GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||
if (action == GLFW_PRESS) {
|
||||
Application::getInstance().keyboard->reportKeyPress(key);
|
||||
} else if (action == GLFW_RELEASE) {
|
||||
Application::getInstance().keyboard->reportKeyRelease(key);
|
||||
} else if (action == GLFW_REPEAT) {
|
||||
Application::getInstance().keyboard->keysRepeatedThisFrame.insert(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Keyboard::reportKeyPress(int key) {
|
||||
keysDown.insert(key);
|
||||
keysPressedThisFrame.insert(key);
|
||||
}
|
||||
|
||||
void Keyboard::reportKeyRelease(int key) {
|
||||
keysDown.erase(key);
|
||||
keysReleasedThisFrame.insert(key);
|
||||
}
|
||||
38
src/engine/core/inputsOutputs/inputs/Keyboard.h
Normal file
38
src/engine/core/inputsOutputs/inputs/Keyboard.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_KEYBOARD_H
|
||||
#define DICEWARS_SIEDLER_KEYBOARD_H
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class Window;
|
||||
|
||||
class Keyboard {
|
||||
public:
|
||||
explicit Keyboard(Window& window);
|
||||
|
||||
void update();
|
||||
bool isKeyDown(int key);
|
||||
const std::vector<int>& getCharsThisFrame();
|
||||
bool keyPressEvent(int key);
|
||||
bool keyPressEvent(int key, bool checkRepeats);
|
||||
bool keyReleaseEvent(int key);
|
||||
private:
|
||||
std::unordered_set<int> keysPressedThisFrame;
|
||||
std::unordered_set<int> keysRepeatedThisFrame;
|
||||
std::unordered_set<int> keysReleasedThisFrame;
|
||||
std::unordered_set<int> keysDown;
|
||||
std::vector<int> charsThisFrame;
|
||||
|
||||
static void addTextListener(Window& window);
|
||||
|
||||
static void addKeyListener(Window& window);
|
||||
void reportKeyPress(int key);
|
||||
void reportKeyRelease(int key);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_KEYBOARD_H
|
||||
107
src/engine/core/inputsOutputs/inputs/Mouse.cpp
Normal file
107
src/engine/core/inputsOutputs/inputs/Mouse.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "Mouse.h"
|
||||
#include "../../Window.h"
|
||||
#include "../../Application.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
Mouse::Mouse(Window &window) {
|
||||
addMoveListener(window);
|
||||
addScrollListener(window);
|
||||
addClickListener(window);
|
||||
}
|
||||
|
||||
bool Mouse::isButtonDown(MouseButton button) {
|
||||
return buttonsDown.contains(MouseButtonToInt(button));
|
||||
}
|
||||
|
||||
bool Mouse::isClickEvent(MouseButton button) {
|
||||
return buttonsClickedThisFrame.contains(MouseButtonToInt(button));
|
||||
}
|
||||
|
||||
bool Mouse::isReleaseEvent(MouseButton button) {
|
||||
return buttonsReleasedThisFrame.contains(MouseButtonToInt(button));
|
||||
}
|
||||
|
||||
float Mouse::getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
float Mouse::getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
float Mouse::getDX() {
|
||||
return dx;
|
||||
}
|
||||
|
||||
float Mouse::getDY() {
|
||||
return dy;
|
||||
}
|
||||
|
||||
float Mouse::getScroll() {
|
||||
return scroll;
|
||||
}
|
||||
|
||||
void Mouse::update() {
|
||||
buttonsClickedThisFrame.clear();
|
||||
buttonsReleasedThisFrame.clear();
|
||||
updateDetlas();
|
||||
scroll = 0.0f;
|
||||
}
|
||||
|
||||
void Mouse::reportButtonClick(int button) {
|
||||
buttonsDown.insert(button);
|
||||
buttonsClickedThisFrame.insert(button);
|
||||
}
|
||||
|
||||
void Mouse::reportButtonRelease(int button) {
|
||||
buttonsDown.erase(button);
|
||||
buttonsReleasedThisFrame.insert(button);
|
||||
}
|
||||
|
||||
void Mouse::updateDetlas() {
|
||||
dx = x - lastX;
|
||||
dy = y - lastY;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
|
||||
void Mouse::addMoveListener(Window &window) {
|
||||
glfwSetCursorPosCallback(static_cast<GLFWwindow *>(window.GetNativeWindow()), [](GLFWwindow *window, double xpos, double ypos) {
|
||||
Application::getInstance().mouse->x = static_cast<float>(xpos / Application::getInstance().getWindow().GetWidth() );
|
||||
Application::getInstance().mouse->y = static_cast<float>(ypos / Application::getInstance().getWindow().GetHeight());
|
||||
});
|
||||
}
|
||||
|
||||
void Mouse::addScrollListener(Window &window) {
|
||||
glfwSetScrollCallback(static_cast<GLFWwindow *>(window.GetNativeWindow()), [](GLFWwindow *window, double xoff, double yoff) {
|
||||
Application::getInstance().mouse->scroll = static_cast<float>(yoff);
|
||||
});
|
||||
}
|
||||
|
||||
void Mouse::addClickListener(Window &window) {
|
||||
glfwSetMouseButtonCallback(static_cast<GLFWwindow *>(window.GetNativeWindow()), [](GLFWwindow *window, int button, int action, int mods) {
|
||||
if (action == GLFW_PRESS) {
|
||||
Application::getInstance().mouse->reportButtonClick(button);
|
||||
} else if (action == GLFW_RELEASE) {
|
||||
Application::getInstance().mouse->reportButtonRelease(button);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int Mouse::MouseButtonToInt(MouseButton button) {
|
||||
int glfwButton = 0;
|
||||
switch (button) {
|
||||
case MouseButton::LEFT: glfwButton = GLFW_MOUSE_BUTTON_LEFT; break;
|
||||
case MouseButton::RIGHT: glfwButton = GLFW_MOUSE_BUTTON_RIGHT; break;
|
||||
case MouseButton::MIDDLE: glfwButton = GLFW_MOUSE_BUTTON_MIDDLE; break;
|
||||
}
|
||||
return glfwButton;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
47
src/engine/core/inputsOutputs/inputs/Mouse.h
Normal file
47
src/engine/core/inputsOutputs/inputs/Mouse.h
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_MOUSE_H
|
||||
#define DICEWARS_SIEDLER_MOUSE_H
|
||||
#include <unordered_set>
|
||||
|
||||
#include "MouseButton.h"
|
||||
|
||||
class Window;
|
||||
|
||||
class Mouse {
|
||||
public:
|
||||
explicit Mouse(Window& window);
|
||||
bool isButtonDown(MouseButton button);
|
||||
bool isClickEvent(MouseButton button);
|
||||
bool isReleaseEvent(MouseButton button);
|
||||
float getX();
|
||||
float getY();
|
||||
float getDX();
|
||||
float getDY();
|
||||
float getScroll();
|
||||
void update();
|
||||
private:
|
||||
std::unordered_set<int> buttonsDown;
|
||||
std::unordered_set<int> buttonsClickedThisFrame;
|
||||
std::unordered_set<int> buttonsReleasedThisFrame;
|
||||
|
||||
float x, y;
|
||||
float dx, dy;
|
||||
float scroll;
|
||||
float lastX, lastY;
|
||||
|
||||
void reportButtonClick(int button);
|
||||
void reportButtonRelease(int button);
|
||||
void updateDetlas();
|
||||
|
||||
static void addMoveListener(Window& window);
|
||||
static void addScrollListener(Window& window);
|
||||
static void addClickListener(Window& window);
|
||||
|
||||
static int MouseButtonToInt(MouseButton button);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_MOUSE_H
|
||||
14
src/engine/core/inputsOutputs/inputs/MouseButton.h
Normal file
14
src/engine/core/inputsOutputs/inputs/MouseButton.h
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_MOUSEBUTTON_H
|
||||
#define DICEWARS_SIEDLER_MOUSEBUTTON_H
|
||||
|
||||
|
||||
enum class MouseButton {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
MIDDLE
|
||||
};
|
||||
#endif //DICEWARS_SIEDLER_MOUSEBUTTON_H
|
||||
5
src/engine/core/inputsOutputs/stateControl/InputUser.cpp
Normal file
5
src/engine/core/inputsOutputs/stateControl/InputUser.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "InputUser.h"
|
||||
29
src/engine/core/inputsOutputs/stateControl/InputUser.h
Normal file
29
src/engine/core/inputsOutputs/stateControl/InputUser.h
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_INPUTUSER_H
|
||||
#define DICEWARS_SIEDLER_INPUTUSER_H
|
||||
#include "../inputs/Keyboard.h"
|
||||
|
||||
|
||||
class Mouse;
|
||||
|
||||
class InputUser {
|
||||
protected:
|
||||
bool mouseEnabled = true;
|
||||
bool keyboardEnabled = true;
|
||||
public:
|
||||
virtual ~InputUser() = default;
|
||||
|
||||
void enableKeyboard(bool enable) {keyboardEnabled = enable;}
|
||||
void enableMouse(bool enable) {mouseEnabled = enable;}
|
||||
|
||||
bool isKeyboardEnabled() const {return keyboardEnabled;}
|
||||
bool isMouseEnabled() const {return mouseEnabled;}
|
||||
|
||||
bool isFullyEnabled() const {return keyboardEnabled && mouseEnabled;}
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_INPUTUSER_H
|
||||
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "RegisteredUsers.h"
|
||||
|
||||
void RegisteredUsers::registerMouseUser(IState *state, InputUser* user) {
|
||||
registerInputUser(state, user, registeredMouseUsers);
|
||||
}
|
||||
|
||||
void RegisteredUsers::registerKeyboardUser(IState *state, InputUser *user) {
|
||||
registerInputUser(state, user, registeredKeyboardUsers);
|
||||
}
|
||||
|
||||
void RegisteredUsers::registerUser(IState *state, InputUser *user) {
|
||||
registerInputUser(state, user, registeredKeyboardUsers);
|
||||
registerInputUser(state, user, registeredMouseUsers);
|
||||
}
|
||||
|
||||
void RegisteredUsers::initState(IState *state) {
|
||||
enableMouseUsers(state, true);
|
||||
enableKeyboardUsers(state, true);
|
||||
}
|
||||
|
||||
void RegisteredUsers::endState(IState *state) {
|
||||
enableMouseUsers(state, false);
|
||||
enableKeyboardUsers(state, false);
|
||||
}
|
||||
|
||||
void RegisteredUsers::registerInputUser(IState *state, InputUser* user,
|
||||
std::unordered_map<IState *, std::unordered_set<InputUser*>> ®isteredUsers) {
|
||||
|
||||
registeredUsers[state].insert(user);
|
||||
}
|
||||
|
||||
void RegisteredUsers::enableMouseUsers(IState *state, bool enable) {
|
||||
auto it = registeredMouseUsers.find(state);
|
||||
if (it == registeredMouseUsers.end())
|
||||
return;
|
||||
|
||||
for (InputUser *user : it->second) {
|
||||
user->enableMouse(enable);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisteredUsers::enableKeyboardUsers(IState *state, bool enable) {
|
||||
auto it = registeredKeyboardUsers.find(state);
|
||||
if (it == registeredKeyboardUsers.end())
|
||||
return;
|
||||
|
||||
for (InputUser *user : it->second) {
|
||||
user->enableKeyboard(enable);
|
||||
}
|
||||
}
|
||||
32
src/engine/core/inputsOutputs/stateControl/RegisteredUsers.h
Normal file
32
src/engine/core/inputsOutputs/stateControl/RegisteredUsers.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_REGISTEREDUSERS_H
|
||||
#define DICEWARS_SIEDLER_REGISTEREDUSERS_H
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "InputUser.h"
|
||||
#include "states/IState.h"
|
||||
|
||||
|
||||
class RegisteredUsers {
|
||||
public:
|
||||
void registerMouseUser(IState* state, InputUser* user);
|
||||
void registerKeyboardUser(IState* state, InputUser* user);
|
||||
void registerUser(IState* state, InputUser* user);
|
||||
void initState(IState* state);
|
||||
void endState(IState* state);
|
||||
private:
|
||||
std::unordered_map<IState*, std::unordered_set<InputUser*>> registeredMouseUsers;
|
||||
std::unordered_map<IState*, std::unordered_set<InputUser*>> registeredKeyboardUsers;
|
||||
|
||||
static void registerInputUser(IState* state, InputUser* user, std::unordered_map<IState*, std::unordered_set<InputUser*>>& registeredUsers);
|
||||
|
||||
void enableMouseUsers(IState* state, bool enable);
|
||||
void enableKeyboardUsers(IState* state, bool enable);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_REGISTEREDUSERS_H
|
||||
76
src/engine/core/inputsOutputs/stateControl/StateManager.cpp
Normal file
76
src/engine/core/inputsOutputs/stateControl/StateManager.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "StateManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
void StateManager::suggestState(std::shared_ptr<IState> state, bool waitForEndRequest) {
|
||||
QueuedState queuedState(state, waitForEndRequest);
|
||||
sortStateIntoQueue(queuedState);
|
||||
}
|
||||
|
||||
void StateManager::endState(std::shared_ptr<IState> state) {
|
||||
queuedStates.erase(std::remove_if(queuedStates.begin(), queuedStates.end(), [&](const QueuedState &queuedState) {
|
||||
return queuedState.state == state;
|
||||
}), queuedStates.end());
|
||||
}
|
||||
|
||||
void StateManager::updateState() {
|
||||
auto nextState = getNextState();
|
||||
cleanQueue();
|
||||
if (currentState == nextState) {
|
||||
return;
|
||||
}
|
||||
switchState(nextState);
|
||||
}
|
||||
|
||||
void StateManager::registerUser(InputUser *user, std::initializer_list<std::shared_ptr<IState>> states) {
|
||||
for (auto& state : states) {
|
||||
registeredUsers.registerUser(state.get(), user);
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::registerKeyboardUser(InputUser *user, std::initializer_list<std::shared_ptr<IState>> states) {
|
||||
for (auto& state : states) {
|
||||
registeredUsers.registerKeyboardUser(state.get(), user);
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::registerMouseUser(InputUser *user, std::initializer_list<std::shared_ptr<IState>> states) {
|
||||
for (auto& state : states) {
|
||||
registeredUsers.registerMouseUser(state.get(), user);
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::sortStateIntoQueue(const QueuedState &queued_state) {
|
||||
auto it = std::ranges::find_if(queuedStates,
|
||||
[&](const QueuedState &s) {
|
||||
return s.state->getPriority() > queued_state.state->getPriority();
|
||||
});
|
||||
|
||||
queuedStates.insert(it, queued_state);
|
||||
}
|
||||
|
||||
std::shared_ptr<IState> StateManager::getNextState() {
|
||||
if (queuedStates.empty()) {
|
||||
return defaultState;
|
||||
}
|
||||
return queuedStates.front().state;
|
||||
}
|
||||
|
||||
void StateManager::cleanQueue() {
|
||||
queuedStates.erase(
|
||||
std::remove_if(queuedStates.begin(), queuedStates.end(),
|
||||
[](const QueuedState& s) { return !s.waitForEndRequest; }),
|
||||
queuedStates.end()
|
||||
);
|
||||
}
|
||||
|
||||
void StateManager::switchState(std::shared_ptr<IState> newState) {
|
||||
registeredUsers.endState(currentState.get());
|
||||
currentState = std::move(newState);
|
||||
registeredUsers.initState(currentState.get());
|
||||
}
|
||||
47
src/engine/core/inputsOutputs/stateControl/StateManager.h
Normal file
47
src/engine/core/inputsOutputs/stateControl/StateManager.h
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_STATEMANAGER_H
|
||||
#define DICEWARS_SIEDLER_STATEMANAGER_H
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "states/IState.h"
|
||||
#include "RegisteredUsers.h"
|
||||
|
||||
|
||||
class StateManager {
|
||||
public:
|
||||
StateManager(std::shared_ptr<IState> defaultState, std::shared_ptr<IState> initialState) : defaultState(defaultState), currentState(initialState) {
|
||||
suggestState(initialState, true);
|
||||
};
|
||||
|
||||
void suggestState(std::shared_ptr<IState> state, bool waitForEndRequest);
|
||||
void endState(std::shared_ptr<IState> state);
|
||||
std::shared_ptr<IState> getCurrentState() const {return currentState;}
|
||||
void updateState();
|
||||
|
||||
void registerUser(InputUser* user, std::initializer_list<std::shared_ptr<IState>> states);
|
||||
void registerKeyboardUser(InputUser* user, std::initializer_list<std::shared_ptr<IState>> states);
|
||||
void registerMouseUser(InputUser* user, std::initializer_list<std::shared_ptr<IState>> states);
|
||||
private:
|
||||
struct QueuedState {
|
||||
std::shared_ptr<IState> state;
|
||||
bool waitForEndRequest;
|
||||
};
|
||||
|
||||
std::shared_ptr<IState> defaultState;
|
||||
std::shared_ptr<IState> currentState;
|
||||
|
||||
RegisteredUsers registeredUsers;
|
||||
std::vector<QueuedState> queuedStates;
|
||||
|
||||
void sortStateIntoQueue(const QueuedState& queued_state);
|
||||
std::shared_ptr<IState> getNextState();
|
||||
void cleanQueue();
|
||||
void switchState(std::shared_ptr<IState> newState);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_STATEMANAGER_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "StateRegistry.h"
|
||||
37
src/engine/core/inputsOutputs/stateControl/StateRegistry.h
Normal file
37
src/engine/core/inputsOutputs/stateControl/StateRegistry.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_STATEREGISTRY_H
|
||||
#define DICEWARS_SIEDLER_STATEREGISTRY_H
|
||||
#include <memory>
|
||||
|
||||
#include "states/EmptyState.h"
|
||||
#include "states/State.h"
|
||||
|
||||
|
||||
class StateRegistry {
|
||||
public:
|
||||
static StateRegistry& get() {
|
||||
static StateRegistry instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::shared_ptr<GameState> game;
|
||||
std::shared_ptr<EmptyState> empty;
|
||||
std::shared_ptr<UiState> uiState;
|
||||
|
||||
private:
|
||||
StateRegistry() {
|
||||
game = std::make_shared<GameState>();
|
||||
empty = std::make_shared<EmptyState>();
|
||||
uiState = std::make_shared<UiState>();
|
||||
}
|
||||
|
||||
// Keine Kopien erlaubt
|
||||
StateRegistry(const StateRegistry&) = delete;
|
||||
StateRegistry& operator=(const StateRegistry&) = delete;
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_STATEREGISTRY_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "GameInputUser.h"
|
||||
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_GAMEINPUTUSER_H
|
||||
#define DICEWARS_SIEDLER_GAMEINPUTUSER_H
|
||||
#include "../InputUser.h"
|
||||
#include "../../../Application.h"
|
||||
#include "../../../../../game/hexWorld/ecs/systems/TileHighlightSystem.h"
|
||||
|
||||
|
||||
class GameInputUser : public InputUser {
|
||||
public:
|
||||
GameInputUser(TileHighlightSystem& highlightSystem,
|
||||
EntityManager& em,
|
||||
MousePicker& picker,
|
||||
Camera& camera,
|
||||
GameMode& gameMode)
|
||||
: highlightSystem(highlightSystem),
|
||||
em(em),
|
||||
picker(picker),
|
||||
camera(camera),
|
||||
gameMode(gameMode) {}
|
||||
|
||||
void update() {
|
||||
if (!isMouseEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
highlightSystem.update(em, picker, camera, gameMode);
|
||||
}
|
||||
private:
|
||||
TileHighlightSystem& highlightSystem;
|
||||
EntityManager& em;
|
||||
MousePicker& picker;
|
||||
Camera& camera;
|
||||
GameMode& gameMode;
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_GAMEINPUTUSER_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "EmptyState.h"
|
||||
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_EMPTYSTATE_H
|
||||
#define DICEWARS_SIEDLER_EMPTYSTATE_H
|
||||
#include <limits>
|
||||
|
||||
#include "IState.h"
|
||||
|
||||
|
||||
class EmptyState : public IState{
|
||||
int getPriority() override { return std::numeric_limits<int>::max(); }
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_EMPTYSTATE_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "IState.h"
|
||||
17
src/engine/core/inputsOutputs/stateControl/states/IState.h
Normal file
17
src/engine/core/inputsOutputs/stateControl/states/IState.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_ISTATE_H
|
||||
#define DICEWARS_SIEDLER_ISTATE_H
|
||||
|
||||
|
||||
class IState {
|
||||
public:
|
||||
virtual ~IState() = default;
|
||||
|
||||
virtual int getPriority() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_ISTATE_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#include "State.h"
|
||||
26
src/engine/core/inputsOutputs/stateControl/states/State.h
Normal file
26
src/engine/core/inputsOutputs/stateControl/states/State.h
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by sebastian on 15.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_STATE_H
|
||||
#define DICEWARS_SIEDLER_STATE_H
|
||||
#include "IState.h"
|
||||
|
||||
|
||||
class GameState : public IState {
|
||||
public:
|
||||
int getPriority() override { return 10; }
|
||||
};
|
||||
|
||||
class UiState : public IState {
|
||||
public:
|
||||
int getPriority() override { return 5; }
|
||||
};
|
||||
|
||||
class ModalState : public IState {
|
||||
public:
|
||||
int getPriority() override { return 0; } // höchste Priorität
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_STATE_H
|
||||
@ -9,6 +9,7 @@
|
||||
#include "../engine/core/animations/AnimationSystem.h"
|
||||
#include "../engine/core/ECS/ModelStateComponent.h"
|
||||
#include "../engine/core/ECS/WorldSpriteComponent.h"
|
||||
#include "../engine/core/inputsOutputs/stateControl/StateRegistry.h"
|
||||
#include "../engine/platform/glfw/InputManager.h"
|
||||
#include "../engine/renderer/Renderer.h"
|
||||
#include "../engine/renderer/loader/OBJLoader.h"
|
||||
@ -66,6 +67,9 @@ void GameLayer::onAttach()
|
||||
events.subscribe<TurnChangedEvent>([this](const TurnChangedEvent& event) {
|
||||
ProducingSystem::onTurnEnded(*entityManager);
|
||||
});
|
||||
|
||||
gameInputUser = std::make_unique<GameInputUser>(*tileHighlightSystem, *entityManager, *mousePicker, *camera, *gameMode);
|
||||
Application::getInstance().stateManager->registerMouseUser(gameInputUser.get(), {StateRegistry::get().game});
|
||||
}
|
||||
|
||||
void GameLayer::onDetach()
|
||||
@ -100,7 +104,11 @@ void GameLayer::onUpdate()
|
||||
|
||||
AnimationSystem::update(*entityManager, EngineTime::totalTime);
|
||||
camera->move(moveDir, 0.5f);
|
||||
if (gameInputUser->isMouseEnabled()) {
|
||||
tileHighlightSystem->update(*entityManager, *mousePicker, *camera, *gameMode);
|
||||
} else {
|
||||
tileHighlightSystem->reset(*entityManager);
|
||||
}
|
||||
buildingPlacementSystem->update(*entityManager, *gameMode, 0, *turnState);
|
||||
CollectResourceSystem::update(*entityManager, *gameMode);
|
||||
RenderSystem::render(*entityManager, *renderer);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#ifndef DICEWARS_SIEDLER_GAMELAYER_H
|
||||
#define DICEWARS_SIEDLER_GAMELAYER_H
|
||||
#include "../engine/core/ECS/RenderSystem.h"
|
||||
#include "../engine/core/inputsOutputs/stateControl/inputUser/GameInputUser.h"
|
||||
#include "../engine/layer/Layer.h"
|
||||
#include "../engine/platform/glfw/MousePicker.h"
|
||||
#include "../engine/renderer/Renderer.h"
|
||||
@ -48,6 +49,8 @@ private:
|
||||
std::unique_ptr<TurnSystem> turnSystem = std::make_unique<TurnSystem>();
|
||||
std::unique_ptr<TurnState> turnState = std::make_unique<TurnState>();
|
||||
|
||||
std::unique_ptr<GameInputUser> gameInputUser;
|
||||
|
||||
EntityID testEntity;
|
||||
};
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "../engine/core/gui/uiComponent/UiButton.h"
|
||||
#include "../engine/core/gui/uiComponent/UiImage.h"
|
||||
#include "../engine/core/gui/uiComponent/UiText.h"
|
||||
#include "../engine/core/inputsOutputs/stateControl/StateRegistry.h"
|
||||
#include "../engine/renderer/loader/AssetManager.h"
|
||||
#include "../engine/renderer/loader/Loader.h"
|
||||
#include "../engine/renderer/model/GUITexture.h"
|
||||
@ -139,6 +140,11 @@ void UILayer::onUpdate() {
|
||||
auto renderTexts = renderBundle.getGUITexts();
|
||||
textRenderer->renderGuiTexts(renderTexts);
|
||||
|
||||
if (rootContainer->isMouseOver(Application::getInstance().mouse->getX(), Application::getInstance().mouse->getY())) {
|
||||
Application::getInstance().stateManager->suggestState(StateRegistry::get().uiState, false);
|
||||
} else {
|
||||
Application::getInstance().stateManager->suggestState(StateRegistry::get().game, false);
|
||||
}
|
||||
}
|
||||
|
||||
void UILayer::onDetach() {
|
||||
|
||||
@ -42,6 +42,15 @@ void TileHighlightSystem::update(EntityManager &entityManager, const MousePicker
|
||||
}
|
||||
}
|
||||
|
||||
void TileHighlightSystem::reset(EntityManager &entityManager) {
|
||||
for (EntityID entityID : entityManager.getAllEntities()) {
|
||||
auto tileRenderComponent = entityManager.getComponent<TileRenderComponent>(entityID);
|
||||
if (tileRenderComponent) {
|
||||
tileRenderComponent->isHighlighted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TileHighlightSystem::intersectTile(const glm::vec3 &rayOrigin, const glm::vec3 &rayDirection, glm::vec3 worldPos, float hexRadius, glm::vec3& intersectionPoint) {
|
||||
float t = -rayOrigin.y / rayDirection.y;
|
||||
if (t < 0) return false;
|
||||
|
||||
@ -13,6 +13,7 @@ class Camera;
|
||||
class TileHighlightSystem {
|
||||
public:
|
||||
void update(EntityManager &entityManager, const MousePicker &picker, const Camera &camera, GameMode& gameMode);
|
||||
void reset(EntityManager& entityManager);
|
||||
private:
|
||||
bool intersectTile(const glm::vec3 & rayOrigin, const glm::vec3 & rayDirection, glm::vec3 worldPos, float hexRadius, glm::vec3 &interectionPoint);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user