All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m52s
252 lines
7.4 KiB
C++
252 lines
7.4 KiB
C++
#include <ReWindow/types/Window.h>
|
|
#include <ReWindow/InputService.h>
|
|
#include <ReWindow/Logger.h>
|
|
|
|
using namespace ReWindow;
|
|
|
|
RWindow::~RWindow() {
|
|
if (open)
|
|
DestroyOSWindowHandle();
|
|
}
|
|
|
|
std::pair<int, int> RWindow::GetCursorPosition() const {
|
|
return currentMouse.Position;
|
|
}
|
|
|
|
bool RWindow::IsAlive() const {
|
|
return (!closing) && open;
|
|
}
|
|
|
|
void RWindow::SetFullscreen(bool fs) {
|
|
if (fs)
|
|
Fullscreen();
|
|
else
|
|
RestoreFromFullscreen();
|
|
}
|
|
|
|
#pragma region Event Processors Implementation
|
|
void RWindow::processFocusIn() {
|
|
RWindowEvent event {};
|
|
OnFocusGain(event);
|
|
OnFocusGainEvent(event);
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processFocusOut() {
|
|
RWindowEvent event {};
|
|
OnFocusLost(event);
|
|
OnFocusLostEvent(event);
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processMousePress(const MouseButton& btn) {
|
|
currentMouse.Set(btn, true);
|
|
auto event = MouseButtonDownEvent(btn);
|
|
OnMouseButtonDown(event);
|
|
OnMouseButtonDownEvent(event);
|
|
InputService::OnMouseButtonEvent(MouseButtonEvent(btn, true));
|
|
InputService::OnMouseDown(event);
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processMouseMove(const std::pair<int, int>& last_pos, const std::pair<int, int>& new_pos) {
|
|
currentMouse.Position = new_pos;
|
|
auto event = MouseMoveEvent(new_pos);
|
|
OnMouseMove(event);
|
|
OnMouseMoveEvent(event);
|
|
InputService::OnMouseMove(event);
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processMouseRelease(const MouseButton& btn) {
|
|
currentMouse.Set(btn, false);
|
|
auto event = MouseButtonUpEvent(btn);
|
|
OnMouseButtonUp(event);
|
|
OnMouseButtonUpEvent(event);
|
|
InputService::OnMouseButtonEvent(MouseButtonEvent(btn, false));
|
|
InputService::OnMouseUp(event);
|
|
LogEvent(event);
|
|
|
|
}
|
|
|
|
void RWindow::processKeyRelease(Key key) {
|
|
currentKeyboard.PressedKeys[key] = false;
|
|
auto event = KeyUpEvent(key);
|
|
OnKeyUp(event);
|
|
OnKeyUpEvent(event);
|
|
InputService::OnKeyboardEvent(KeyboardEvent(key, KeyState::Released));
|
|
InputService::OnKeyEvent(KeyboardEvent(key, KeyState::Released));
|
|
InputService::OnKeyUp(event);
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processKeyPress(Key key) {
|
|
currentKeyboard.PressedKeys[key] = true;
|
|
auto event = KeyDownEvent(key);
|
|
OnKeyDown(event);
|
|
OnKeyDownEvent(event);
|
|
InputService::OnKeyDown(event);
|
|
InputService::OnKeyboardEvent(KeyboardEvent(key, KeyState::Pressed));
|
|
InputService::OnKeyEvent(KeyboardEvent(key, KeyState::Pressed));
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processOnClose() {
|
|
auto event = RWindowEvent();
|
|
OnClosing();
|
|
OnClosingEvent();
|
|
LogEvent(event);
|
|
}
|
|
|
|
void RWindow::processOnOpen() {
|
|
auto event = RWindowEvent();
|
|
OnOpen();
|
|
OnOpenEvent();
|
|
LogEvent(event);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
std::string RWindow::GetTitle() const { return this->title; }
|
|
|
|
int RWindow::GetWidth() const { return this->width; }
|
|
|
|
int RWindow::GetHeight() const { return this->height; }
|
|
|
|
bool RWindow::IsResizable() const { return resizable; }
|
|
|
|
bool RWindow::IsFullscreen() const { return fullscreen_mode; }
|
|
|
|
bool RWindow::IsFocused() const { return focused; }
|
|
|
|
bool RWindow::IsVsyncEnabled() const { return vsync; }
|
|
|
|
float RWindow::GetDeltaTime() const { return delta_time; }
|
|
|
|
float RWindow::GetRefreshRate() const { return refresh_rate; }
|
|
|
|
bool RWindow::SetCursorPosition(const int x, const int y) { return SetCursorPosition({x, y}); }
|
|
|
|
unsigned long long RWindow::GetRefreshCount() const { return refresh_count; }
|
|
|
|
void RWindow::SetSizeWithoutEvent(const std::pair<int, int>& size) {
|
|
width = size.first;
|
|
height = size.second;
|
|
}
|
|
|
|
bool RWindow::IsKeyDown(Key key) const {
|
|
if (currentKeyboard.PressedKeys.contains(key))
|
|
return currentKeyboard.PressedKeys.at(key);
|
|
|
|
return false; // NOTE: Key may not be mapped!!
|
|
}
|
|
|
|
bool RWindow::IsMouseButtonDown(const MouseButton& button) const {
|
|
// TODO: Implement MouseButton map
|
|
return currentMouse.IsDown(button);
|
|
}
|
|
|
|
|
|
void RWindow::ManagedRefresh() {
|
|
auto begin = GetTimestamp();
|
|
Refresh();
|
|
auto end = GetTimestamp();
|
|
|
|
float dt = ComputeElapsedFrameTimeSeconds(begin, end);
|
|
|
|
UpdateFrameTiming(dt);
|
|
}
|
|
|
|
void RWindow::Refresh() {
|
|
PollEvents();
|
|
OnRefresh(delta_time);
|
|
|
|
// Only call once and cache the result.
|
|
currentMouse.Position = GetAccurateCursorCoordinates();
|
|
|
|
if (currentMouse.Position != previousMouse.Position) {
|
|
processMouseMove(previousMouse.Position, currentMouse.Position);
|
|
previousMouse.Position = currentMouse.Position;
|
|
}
|
|
}
|
|
|
|
bool RWindow::GetCursorFocused() {
|
|
return cursor_focused;
|
|
}
|
|
|
|
float RWindow::ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) {
|
|
auto frame_time = end - start;
|
|
unsigned long int frame_time_us = std::chrono::duration_cast<std::chrono::microseconds>(frame_time).count();
|
|
float frame_time_s = frame_time_us / (1000.f * 1000.f);
|
|
return frame_time_s;
|
|
}
|
|
|
|
std::chrono::steady_clock::time_point RWindow::GetTimestamp() {
|
|
return std::chrono::steady_clock::now();
|
|
}
|
|
|
|
void RWindow::UpdateFrameTiming(float frame_time) {
|
|
delta_time = frame_time;
|
|
refresh_rate = 1.f / delta_time;
|
|
refresh_rate_prev_5 = refresh_rate_prev_4;
|
|
refresh_rate_prev_4 = refresh_rate_prev_3;
|
|
refresh_rate_prev_3 = refresh_rate_prev_2;
|
|
refresh_rate_prev_2 = refresh_rate_prev_1;
|
|
refresh_rate_prev_1 = refresh_rate;
|
|
avg_refresh_rate = (refresh_rate_prev_1 + refresh_rate_prev_2 + refresh_rate_prev_3 + refresh_rate_prev_4 + refresh_rate_prev_5) / 5.f;
|
|
refresh_count++;
|
|
}
|
|
|
|
|
|
void RWindow::processMouseWheel(int scrolls) {
|
|
currentMouse.Wheel += scrolls;
|
|
auto ev = MouseWheelEvent(scrolls);
|
|
OnMouseWheel(ev);
|
|
OnMouseWheelEvent(ev);
|
|
|
|
previousMouse.Wheel = currentMouse.Wheel;
|
|
}
|
|
|
|
void RWindow::Close() {
|
|
closing = true;
|
|
processOnClose();
|
|
}
|
|
|
|
void RWindow::ForceClose() {
|
|
Close();
|
|
DestroyOSWindowHandle();
|
|
}
|
|
|
|
bool MouseState::IsDown(const MouseButton& btn) const {
|
|
if (btn == MouseButtons::Left) return Buttons.LMB;
|
|
if (btn == MouseButtons::Right) return Buttons.RMB;
|
|
if (btn == MouseButtons::Middle) return Buttons.MMB;
|
|
if (btn == MouseButtons::Mouse4) return Buttons.SideButton1;
|
|
if (btn == MouseButtons::Mouse5) return Buttons.SideButton2;
|
|
//if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp;
|
|
//if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown;
|
|
|
|
return false; // Unknown button?
|
|
}
|
|
|
|
void MouseState::Set(const MouseButton& btn, bool state) {
|
|
if (btn == MouseButtons::Left) Buttons.LMB = state;
|
|
if (btn == MouseButtons::Right) Buttons.RMB = state;
|
|
if (btn == MouseButtons::Middle) Buttons.MMB = state;
|
|
if (btn == MouseButtons::Mouse4) Buttons.SideButton1 = state;
|
|
if (btn == MouseButtons::Mouse5) Buttons.SideButton2 = state;
|
|
//if (btn == MouseButtons::MWheelUp) Buttons.MWheelUp = state;
|
|
//if (btn == MouseButtons::MWheelDown) Buttons.MWheelDown = state;
|
|
}
|
|
|
|
bool &MouseState::operator [](const MouseButton& btn) {
|
|
if (btn == MouseButtons::Left) return Buttons.LMB;
|
|
if (btn == MouseButtons::Right) return Buttons.RMB;
|
|
if (btn == MouseButtons::Middle) return Buttons.MMB;
|
|
if (btn == MouseButtons::Mouse4) return Buttons.SideButton1;
|
|
if (btn == MouseButtons::Mouse5) return Buttons.SideButton2;
|
|
//if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp;
|
|
//if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown;
|
|
|
|
throw std::invalid_argument("Attempted to handle unmapped mouse button.");
|
|
} |