Files
ReWindow/src/platform/shared/Window.cpp
Redacted 99a5978448
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m52s
Fixed window sizing issue on Windows.
2025-07-12 18:48:31 -04:00

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.");
}