Skip to content

Commit

Permalink
Interrupts for InputDevice and UI
Browse files Browse the repository at this point in the history
  • Loading branch information
capnkenny committed Feb 3, 2023
1 parent 5465f85 commit 27ff830
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 9 deletions.
1 change: 1 addition & 0 deletions include/NovelRT/Ecs/Configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace NovelRT::Ecs
target.RegisterSystem(std::make_shared<Ecs::Audio::AudioSystem>(_resourceManagementPluginProvider));

target.RegisterSystem(std::make_shared<NovelRT::Ecs::UI::UISystem>(_uiPluginProvider,
target.GetRegisteredIEcsSystemAs<NovelRT::Ecs::Input::InputSystem>(),
target.GetRegisteredIEcsSystemAs<NovelRT::Ecs::Graphics::DefaultRenderingSystem>()));
}

Expand Down
1 change: 1 addition & 0 deletions include/NovelRT/Ecs/Input/InputSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace NovelRT::Ecs::Input
void Update(Timing::Timestamp delta, Ecs::Catalogue catalogue) final;
void AddMapping(std::string name, std::string id);
void AddDefaultKBMMapping();
[[nodiscard]] std::shared_ptr<NovelRT::Input::IInputDevice> GetInputDevice();
[[nodiscard]] NovelRT::Atom GetMappingId(const std::string& mappingName) const;
};
}
Expand Down
1 change: 1 addition & 0 deletions include/NovelRT/Ecs/UI/UISystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace NovelRT::Ecs::UI

public:
UISystem(std::shared_ptr<NovelRT::PluginManagement::IUIPluginProvider> uiPluginProvider,
std::shared_ptr<NovelRT::Ecs::Input::InputSystem> inputSystem,
std::shared_ptr<NovelRT::Ecs::Graphics::DefaultRenderingSystem> renderingSystem);

void Update(Timing::Timestamp delta, Ecs::Catalogue catalogue) final;
Expand Down
31 changes: 31 additions & 0 deletions include/NovelRT/Input/Glfw/GlfwInputDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,44 @@ namespace NovelRT::Input::Glfw
[[nodiscard]] bool IsKeyPressed(const std::string& input) noexcept final;
[[nodiscard]] bool IsKeyHeld(const std::string& input) noexcept final;
[[nodiscard]] bool IsKeyReleased(const std::string& input) noexcept final;
[[nodiscard]] bool IsMouseKey(const std::string& key) noexcept final;
[[nodiscard]] KeyState GetKeyState(const std::string& key) noexcept final;
[[nodiscard]] InputAction& AddInputAction(const std::string& actionName,
const std::string& keyIdentifier) final;
[[nodiscard]] NovelKey& GetAvailableKey(const std::string& keyRequested) final;
[[nodiscard]] NovelRT::Maths::GeoVector2F GetMousePosition() noexcept final;
[[nodiscard]] gsl::span<InputAction> GetAllMappings() noexcept final;

[[nodiscard]] inline bool& MouseButtonInterrupt() final
{
return _mouseButtonInterrupt;
}

[[nodiscard]] inline const bool& MouseButtonInterrupt() const final
{
return _mouseButtonInterrupt;
}

[[nodiscard]] inline bool& MousePositionInterrupt() final
{
return _mousePositionInterrupt;
}

[[nodiscard]] inline const bool& MousePositionInterrupt() const final
{
return _mousePositionInterrupt;
}

[[nodiscard]] inline bool& KeyPressInterrupt() final
{
return _keyPressInterrupt;
}

[[nodiscard]] inline const bool& KeyPressInterrupt() const final
{
return _keyPressInterrupt;
}

~GlfwInputDevice() final;
};
}
Expand Down
15 changes: 15 additions & 0 deletions include/NovelRT/Input/IInputDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,28 @@ namespace NovelRT::Input
LoggingService _logger;
std::vector<InputAction> _mappedActions;
std::map<std::string, NovelKey> _availableKeys;
bool _mouseButtonInterrupt;
bool _keyPressInterrupt;
bool _mousePositionInterrupt;

public:
Utilities::Event<std::shared_ptr<IInputDevice>, float, float> MousePositionHandler;
Utilities::Event<std::shared_ptr<IInputDevice>, NovelKey, KeyState> MouseButtonHandler;
Utilities::Event<std::shared_ptr<IInputDevice>, NovelKey, KeyState> KeyPressHandler;
Utilities::Event<std::shared_ptr<IInputDevice>> UpdateHandler;

virtual void Initialise(void* window) = 0;
virtual void Update(Timing::Timestamp delta) = 0;
[[nodiscard]] virtual inline bool& MouseButtonInterrupt() = 0;
[[nodiscard]] virtual inline bool& MousePositionInterrupt() = 0;
[[nodiscard]] virtual inline bool& KeyPressInterrupt() = 0;
[[nodiscard]] virtual inline const bool& MouseButtonInterrupt() const = 0;
[[nodiscard]] virtual inline const bool& MousePositionInterrupt() const = 0;
[[nodiscard]] virtual inline const bool& KeyPressInterrupt() const = 0;
[[nodiscard]] virtual bool IsKeyPressed(const std::string& key) = 0;
[[nodiscard]] virtual bool IsKeyHeld(const std::string& key) = 0;
[[nodiscard]] virtual bool IsKeyReleased(const std::string& key) = 0;
[[nodiscard]] virtual bool IsMouseKey(const std::string& key) = 0;
[[nodiscard]] virtual KeyState GetKeyState(const std::string& key) = 0;
[[nodiscard]] virtual InputAction& AddInputAction(const std::string& actionName,
const std::string& keyIdentifier) = 0;
Expand Down
1 change: 1 addition & 0 deletions include/NovelRT/Input/Input.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "NovelRT/LoggingService.h"
#include "NovelRT/Maths/Maths.h"
#include "NovelRT/Timing/Timestamp.h"
#include "NovelRT/Utilities/Event.h"
#include <gsl/span>
#include <map>
#include <string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace NovelRT::UI::DearImGui::GlfwVulkan
NovelRT::Maths::GeoVector2F _windowSize;

void Render();
ImGuiKey GlfwVulkanUIProvider::GlfwToImGuiKey(int32_t key);

protected:
bool _isInitialised;
Expand All @@ -28,6 +29,7 @@ namespace NovelRT::UI::DearImGui::GlfwVulkan
~GlfwVulkanUIProvider() final;
void Initialise(std::shared_ptr<NovelRT::Graphics::GraphicsDevice> gfxDevice,
std::shared_ptr<NovelRT::Windowing::IWindowingDevice> windowingDevice,
std::shared_ptr<NovelRT::Input::IInputDevice> inputDevice,
std::shared_ptr<NovelRT::Graphics::GraphicsProvider> gfxProvider,
std::shared_ptr<NovelRT::Graphics::GraphicsPipeline> pipeline);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace NovelRT::UI::DearImGui::GlfwVulkan
#include "../../../Graphics/Graphics.h"
#include "../../../Graphics/Vulkan/Graphics.Vulkan.h"
#include "../../../Windowing/Glfw/Windowing.Glfw.h"
#include "../../../Input/Glfw/Input.Glfw.h"
#include "../../../PluginManagement/PluginManagement.h"
#include "../UI.DearImGui.h"
#include <imgui_impl_glfw.h>
Expand Down
3 changes: 2 additions & 1 deletion include/NovelRT/UI/IUIProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace NovelRT::UI

virtual void Initialise(std::shared_ptr<NovelRT::Graphics::GraphicsDevice> gfxDevice,
std::shared_ptr<NovelRT::Windowing::IWindowingDevice> windowingDevice,
std::shared_ptr<NovelRT::Input::IInputDevice> inputDevice,
std::shared_ptr<NovelRT::Graphics::GraphicsProvider> gfxProvider,
std::shared_ptr<NovelRT::Graphics::GraphicsPipeline> pipeline) = 0;
virtual ~IUIProvider() = default;
Expand All @@ -30,7 +31,7 @@ namespace NovelRT::UI

virtual std::shared_ptr<IUITextbox> CreateTextbox(const std::string& identifier, const std::string& text,
bool wordWrap, NovelRT::Maths::GeoVector2F position, NovelRT::Maths::GeoVector2F scale, float fontSize, NovelRT::Graphics::RGBAColour backgroundColour) = 0;

virtual std::shared_ptr<IUIButton> CreateButton(const std::string& identifier,
NovelRT::Maths::GeoVector2F position, NovelRT::Maths::GeoVector2F scale, NovelRT::Graphics::RGBAColour backgroundColour) = 0;

Expand Down
3 changes: 2 additions & 1 deletion include/NovelRT/UI/UI.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include "../Graphics/Graphics.h"
#include "../Windowing/Windowing.h"
#include "../Utilities/Event.h"
//#include "NovelRT/PluginManagement/PluginManagement.h"
#include "../Input/Input.h"

/**
* @brief The experimental UI plugin API.
*/
Expand Down
4 changes: 2 additions & 2 deletions samples/InputEcsSample/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int main()
.WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor<IResourceManagementPluginProvider>())
.WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor<IUIPluginProvider>())
.InitialiseAndRegisterComponents();

std::shared_ptr<NovelRT::Ecs::UI::UISystem> ui = scheduler.GetRegisteredIEcsSystemAs<NovelRT::Ecs::UI::UISystem>();
auto uiProvider = ui->GetProvider();
auto testButton = uiProvider->CreateButton("Hello Button", NovelRT::Maths::GeoVector2F::Zero(), NovelRT::Maths::GeoVector2F::Uniform(500.0f), NovelRT::Graphics::RGBAColour(255, 0, 0, 255));
Expand Down Expand Up @@ -139,7 +139,7 @@ int main()
}

if (events.TryGetComponent(mouseClick, input) &&
(input.state == KeyState::KeyDown || input.state == KeyState::KeyDownHeld))
input.state == KeyState::KeyDown)
{
logger.logInfo("Clicked at {}, {}", input.mousePositionX, input.mousePositionY);
}
Expand Down
23 changes: 20 additions & 3 deletions src/NovelRT/Ecs/Input/InputSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ namespace NovelRT::Ecs::Input
case NovelRT::Input::KeyState::KeyDown:
case NovelRT::Input::KeyState::KeyDownHeld:
{
if(_device->IsMouseKey(input.first))
{
if(_device->MouseButtonInterrupt()) break;
}
else
{
if(_device->KeyPressInterrupt()) break;
}

auto event = InputEventComponent{in.actionId, state, in.mousePositionX, in.mousePositionY};
inputs.PushComponentUpdateInstruction(in.actionId, event);
break;
Expand All @@ -48,9 +57,12 @@ namespace NovelRT::Ecs::Input
{
if (state != NovelRT::Input::KeyState::Idle)
{
auto mouse = _device->GetMousePosition();
in = InputEventComponent{input.second, state, mouse.x, mouse.y};
inputs.AddComponent(input.second, in);
if(!_device->MousePositionInterrupt())
{
auto mouse = _device->GetMousePosition();
in = InputEventComponent{input.second, state, mouse.x, mouse.y};
inputs.AddComponent(input.second, in);
}
}
}
}
Expand All @@ -77,6 +89,11 @@ namespace NovelRT::Ecs::Input
AddMapping("B", "L");
}

std::shared_ptr<NovelRT::Input::IInputDevice> InputSystem::GetInputDevice()
{
return _device;
}

NovelRT::Atom InputSystem::GetMappingId(const std::string& mappingName) const
{
return _inputMap.at(mappingName);
Expand Down
2 changes: 2 additions & 0 deletions src/NovelRT/Ecs/UI/UISystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
namespace NovelRT::Ecs::UI
{
UISystem::UISystem(std::shared_ptr<NovelRT::PluginManagement::IUIPluginProvider> uiPluginProvider,
std::shared_ptr<NovelRT::Ecs::Input::InputSystem> inputSystem,
std::shared_ptr<NovelRT::Ecs::Graphics::DefaultRenderingSystem> renderingSystem):
_uiProvider(std::move(uiPluginProvider->GetUIProvider()))
{
_uiProvider->Initialise(renderingSystem->GetCurrentGraphicsDevice(),
renderingSystem->GetCurrentWindowingPluginProvider()->GetWindowingDevice(),
inputSystem->GetInputDevice(),
renderingSystem->GetCurrentGraphicsProvider(),
renderingSystem->GetExistingDefaultPipelineInfo()->gpuPipeline.GetUnderlyingSharedPtr());

Expand Down
44 changes: 44 additions & 0 deletions src/NovelRT/Input/Glfw/GlfwInputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ namespace NovelRT::Input::Glfw
_availableKeys = std::map<std::string, NovelKey>();
_mappedActions = std::vector<InputAction>();
_window = reinterpret_cast<GLFWwindow*>(window);
MouseButtonHandler = Utilities::Event<std::shared_ptr<IInputDevice>, NovelKey, KeyState>();
MousePositionHandler = Utilities::Event<std::shared_ptr<IInputDevice>, float, float>();
KeyPressHandler = Utilities::Event<std::shared_ptr<IInputDevice>, NovelKey, KeyState>();
UpdateHandler = Utilities::Event<std::shared_ptr<IInputDevice>>();

// Map GLFW keys to NovelKeys
_availableKeys.emplace("LeftMouseButton", NovelKey("LeftMouseButton", GLFW_MOUSE_BUTTON_LEFT));
Expand Down Expand Up @@ -181,6 +185,11 @@ namespace NovelRT::Input::Glfw
_mousePos.x = static_cast<float>(x - (width / 2));
_mousePos.y = static_cast<float>(-y + (height / 2));

if (MousePositionHandler.getHandlerCount() > 0)
{
MousePositionHandler(this->shared_from_this(), (float)x, (float)y);
}

_previousStates = _mappedActions;

size_t count = _mappedActions.size();
Expand All @@ -196,13 +205,16 @@ namespace NovelRT::Input::Glfw
{
bool press = false;
bool release = false;
bool changed = false;
bool mouseButton = false;

if ((mapIterator->pairedKey.GetKeyName() == "LeftMouseButton") ||
(mapIterator->pairedKey.GetKeyName() == "RightMouseButton") ||
(mapIterator->pairedKey.GetKeyName() == "MiddleMouseButton"))
{
press = glfwGetMouseButton(_window, mapIterator->pairedKey.GetExternalKeyCode()) == GLFW_PRESS;
release = glfwGetMouseButton(_window, mapIterator->pairedKey.GetExternalKeyCode()) == GLFW_RELEASE;
mouseButton = true;
}
else
{
Expand All @@ -227,8 +239,24 @@ namespace NovelRT::Input::Glfw
{
mapIterator->state = KeyState::Idle;
}

if(mapIterator->state != stateIterator->state)
{
changed = true;
}

if(mouseButton && changed && MouseButtonHandler.getHandlerCount() > 0)
{
MouseButtonHandler(this->shared_from_this(), mapIterator->pairedKey, mapIterator->state);
}
else if(!mouseButton && changed && KeyPressHandler.getHandlerCount() > 0)
{
KeyPressHandler(this->shared_from_this(), mapIterator->pairedKey, mapIterator->state);
}
}
}

UpdateHandler(this->shared_from_this());
}

KeyState GlfwInputDevice::GetKeyState(const std::string& key) noexcept
Expand Down Expand Up @@ -288,6 +316,22 @@ namespace NovelRT::Input::Glfw
return false;
}

bool GlfwInputDevice::IsMouseKey(const std::string& input) noexcept
{
for (auto action : _mappedActions)
{
if (action.actionName == input)
{
return action.pairedKey.GetExternalKeyCode() == GLFW_MOUSE_BUTTON_LEFT ||
action.pairedKey.GetExternalKeyCode() == GLFW_MOUSE_BUTTON_MIDDLE ||
action.pairedKey.GetExternalKeyCode() == GLFW_MOUSE_BUTTON_RIGHT;
}
}

_logger.logWarning("Requested action is not mapped: {}", input);
return false;
}

InputAction& GlfwInputDevice::AddInputAction(const std::string& actionName, const std::string& keyIdentifier)
{
bool nameExists = false;
Expand Down
Loading

0 comments on commit 27ff830

Please sign in to comment.