Fix IsMouseButtonDown infinite loop
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Has been cancelled
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Has been cancelled
This commit is contained in:
@@ -31,6 +31,264 @@ enum class RenderingAPI: uint8_t {
|
||||
VULKAN = 1,
|
||||
};
|
||||
|
||||
namespace ReWindow {
|
||||
class IRenderer {
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual void SwapBuffers();
|
||||
virtual std::string GetDriverVendor();
|
||||
virtual void SetVsync(bool enabled);
|
||||
virtual void SetViewportSize(int width, int height);
|
||||
virtual void MakeCurrent();
|
||||
};
|
||||
|
||||
class VulkanRenderBase : public IRenderer {};
|
||||
class GLRenderBase : public IRenderer {};
|
||||
class GLXRenderer : public GLRenderBase {};
|
||||
class WGLRenderer : public GLRenderBase {};
|
||||
|
||||
// TODO: Refactor RenderingAPI into a polymorphic class interface for greater reusability.
|
||||
|
||||
// This may be better split into multiple component classes.
|
||||
// RWindow is just way too big to be easily grokkable.
|
||||
// I will work on the Input Service system soon.
|
||||
// I want to figure out how to structure ReWindow
|
||||
// to be easily grokkable. It's not too complicated,
|
||||
// but it looks more complicated than it is and
|
||||
// I'm not a fan of that. - Maxine
|
||||
/// RWindow is a class implementation of a platform-independent window abstraction.
|
||||
/// This library also provides abstractions for user-input devices, and their interaction with the window.
|
||||
class RWindow {
|
||||
public:
|
||||
/// The default constructor does not set any members, and are left uninitialized.
|
||||
RWindow() = default;
|
||||
/// Constructs a window by explicitly setting the title, width, height, and optionally; rendering API, fullscreen, resizable, and vsync.
|
||||
/// @param wTitle The window title text.
|
||||
/// @param wWidth
|
||||
/// @param wHeight
|
||||
/// @param wRenderer
|
||||
/// @param wFullscreen
|
||||
/// @param wResizable
|
||||
/// @param wVsync
|
||||
explicit RWindow(const std::string& wTitle, int wWidth = 640, int wHeight = 480,
|
||||
RenderingAPI wRenderer = RenderingAPI::OPENGL,
|
||||
bool wFullscreen = false,
|
||||
bool wResizable = true,
|
||||
bool wVsync = false);
|
||||
/// The destructor deallocates and cleans up any memory used by the RWindow program.
|
||||
/// @note If the window handle is not already destroyed, it will be done here.
|
||||
~RWindow();
|
||||
|
||||
public:
|
||||
/// Bindables are provided for hooking into window instances conveniently, without the need to derive and override for simple use cases.
|
||||
Event<> OnOpenEvent;
|
||||
Event<> OnClosingEvent;
|
||||
Event<RWindowEvent> OnFocusLostEvent;
|
||||
Event<RWindowEvent> OnFocusGainEvent;
|
||||
Event<float> OnRefreshEvent;
|
||||
Event<WindowResizeRequestEvent> OnResizeRequestEvent;
|
||||
Event<InputServiceEvent> OnInputServiceEvent;
|
||||
|
||||
public:
|
||||
/// These methods can also be overridden in derived classes.
|
||||
virtual void OnOpen() {};
|
||||
virtual void OnClosing() {};
|
||||
virtual void OnFocusLost(const RWindowEvent& e) {};
|
||||
virtual void OnFocusGain(const RWindowEvent& e) {};
|
||||
virtual void OnRefresh(float elapsed) {};
|
||||
virtual void OnResizeSuccess() {};
|
||||
virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true; }
|
||||
|
||||
public:
|
||||
/// This function instructs the operating system to create the actual window, and give it to us to control.
|
||||
/// Calling this function, therefore, creates the real 'window' object on the operating system.
|
||||
void Open();
|
||||
/// Tells the window that we want to close, without directly forcing it to. This gives us time to finalize any work we are performing.
|
||||
[[nodiscard]] bool IsOpen() const { return open;}
|
||||
[[nodiscard]] bool IsClosing() const { return closing;}
|
||||
/// Cleans up and closes the window object.
|
||||
void Close();
|
||||
/// Closes the window immediately, potentially without allowing finalization to occur.
|
||||
void ForceClose();
|
||||
void ForceCloseAndTerminateProgram();
|
||||
void CloseAndReopenInPlace();
|
||||
|
||||
public:
|
||||
/// Returns whether the window currently has mouse and/or keyboard focus.
|
||||
[[nodiscard]] bool IsFocused() const;
|
||||
/// Returns whether the window is currently in Fullscreen.
|
||||
// TODO: Support Fullscreen, FullscreenWindowed, and Windowed?
|
||||
[[nodiscard]] bool IsFullscreen() const;
|
||||
/// Returns whether the window can be resized.
|
||||
[[nodiscard]] bool IsResizable() const;
|
||||
/// Returns whether V-Sync is enabled.
|
||||
[[nodiscard]] bool IsVsyncEnabled() const;
|
||||
/// Returns whether the window is considered to be alive. Once dead, any logic loop should be terminated, and the cleanup procedure should run.
|
||||
[[nodiscard]] bool IsAlive() const;
|
||||
|
||||
public:
|
||||
/// Sets which rendering API is to be used with this window.
|
||||
void SetRenderer(RenderingAPI api);
|
||||
/// Sets whether or not to make the window fullscreen.
|
||||
/// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given.
|
||||
void SetFullscreen(bool fs);
|
||||
/// Sets whether or not to make the window resizable.
|
||||
/// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given.
|
||||
void SetResizable(bool resizable);
|
||||
/// Sets whether or not to enable vertical synchronization.
|
||||
/// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given.
|
||||
void SetVsyncEnabled(bool vsync);
|
||||
/// Sets the title of this window.
|
||||
void SetTitle(const std::string& title);
|
||||
/// A special-case function to change our internal size variable, without triggering event updates.
|
||||
void SetSizeWithoutEvent(const Vector2& size); //AAAAAHHHHHHHHH WINDOZE MAKING THINGS DIFFICULT :/ - Redacted.
|
||||
void SetLastKnownWindowSize(const Vector2& size);
|
||||
/// Requests the operating system to change the window size.
|
||||
/// @param width
|
||||
/// @param height
|
||||
void SetSize(int width, int height);
|
||||
/// Requests the operating system to change the window size.
|
||||
/// @param size
|
||||
void SetSize(const Vector2& size);
|
||||
/// Requests the operating system to move the window to the specified coordinates on the display.
|
||||
/// @param x The horizontal screen position to place the window at.
|
||||
/// @param y The vertical screen position to place the window at.
|
||||
void SetPos(int x, int y);
|
||||
/// Requests the operating system to move the window to the specified coordinates on the display.
|
||||
/// @param pos A Vector2 representing the x,y coordinates of the desired window destination. Fractional values are ignored.
|
||||
void SetPos(const Vector2& pos);
|
||||
void SetCursorCustomIcon() const;
|
||||
void SetCursorLocked();
|
||||
void SetCursorCenter();
|
||||
/// Hides the cursor when it's inside of our window. Useful for 3D game camera.
|
||||
|
||||
void SetCursorVisible(bool cursor_enable);
|
||||
|
||||
public:
|
||||
[[nodiscard]] std::string GetTitle() const;
|
||||
/// Returns the horizontal length of this window, in pixels.
|
||||
[[nodiscard]] int GetWidth() const;
|
||||
/// Returns the vertical length of this window, in pixels.
|
||||
[[nodiscard]] int GetHeight() const;
|
||||
/// Returns the name of the developer of the user's graphics driver, if it can be determined.
|
||||
std::string getGraphicsDriverVendor();
|
||||
/// Returns the position of the window's top-left corner relative to the display
|
||||
Vector2 GetPos() const;
|
||||
/// Returns the known size of the window, in {x,y} pixel measurement.
|
||||
Vector2 GetSize() const;
|
||||
/// Returns the position of the "renderable area" of the window relative to it's top left corner.
|
||||
/// (used to account for the width or the border & title bar).
|
||||
Vector2 GetPositionOfRenderableArea() const;
|
||||
/// Returns the current time, represented as a high-resolution std::chrono alias.
|
||||
static std::chrono::steady_clock::time_point GetTimestamp();
|
||||
/// Returns the amount of time, in seconds, between the current and last frame.
|
||||
/// Technically, no, it returns the elapsed time of the frame, start to finish.
|
||||
[[nodiscard]] float GetDeltaTime() const;
|
||||
/// Returns the approximate frames-per-second using delta time.
|
||||
[[nodiscard]] float GetRefreshRate() const;
|
||||
/// Returns the number of frames ran since the windows' creation.
|
||||
[[nodiscard]] float GetRefreshCounter() const;
|
||||
bool GetCursorVisible();
|
||||
|
||||
public:
|
||||
/// Tells the underlying window manager to destroy this window and drop the handle.
|
||||
/// The window, in theory, can not be re-opened after this.
|
||||
void DestroyOSWindowHandle();
|
||||
|
||||
public:
|
||||
/// Reads events from the operating system, and processes them accordingly.
|
||||
/// TODO: Move out of public API, consumers should call Refresh or ideally an update() call.
|
||||
void PollEvents();
|
||||
/// Updates internal window state, similar to ManagedRefresh, but without accounting for any timekeeping. This is left up to the user.
|
||||
void Refresh();
|
||||
/// Updates the window and handles timing internally.
|
||||
void ManagedRefresh();
|
||||
/// Updates internals to account for the latest calculated frame time.
|
||||
void UpdateFrameTiming(float frame_time);
|
||||
|
||||
public:
|
||||
/// Pull the window to the top, such that it is displayed on top of everything else.
|
||||
/// NOTE: The implementation is defined per-OS, and thus there is no guarantee of it always working.
|
||||
void Raise() const;
|
||||
/// Push the window Lower, such that it is effectively hidden behind other windows.
|
||||
/// NOTE: The implementation is defined per-OS, and thus there is no guarantee of it always working.
|
||||
void Lower() const;
|
||||
/// Requests the operating system to make the window fullscreen. Saves the previous window size as well.
|
||||
void Fullscreen();
|
||||
/// Requests the operating system to take the window out of fullscreen mode. Previously saved window size is restored, if possible.
|
||||
void RestoreFromFullscreen();
|
||||
void RestoreCursorFromLastCenter();
|
||||
|
||||
public:
|
||||
/// Calls OpenGL's SwapBuffers routine.
|
||||
/// NOTE: This is only used when the underlying rendering API is set to OpenGL.
|
||||
static void GLSwapBuffers();
|
||||
|
||||
public:
|
||||
/// Computes elapsed time from a start-point and end-point.
|
||||
float ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end);
|
||||
|
||||
public:
|
||||
/// Executes event handlers for keyboard rele;ase events.
|
||||
void processKeyRelease (Key key);
|
||||
/// Executes event handlers for keyboard press events.
|
||||
void processKeyPress (Key key);
|
||||
/// Executes event handlers for window close events.
|
||||
/// @note This will be invoked **before** the window-close procedure begins.
|
||||
void processOnClose();
|
||||
/// Executes event handlers for window open events.
|
||||
/// @note This will be invoked **after** the window-open procedure completes.
|
||||
void processOnOpen();
|
||||
/// Executes event handlers for window focus events.
|
||||
void processFocusIn();
|
||||
/// Executes event handlers for window unfocus events.
|
||||
void processFocusOut();
|
||||
|
||||
/// Executes event handlers for input events
|
||||
/// @note currently not implemented. Will be part of the interface to the Input Service
|
||||
void processOnInput();
|
||||
|
||||
protected:
|
||||
void LogEvent(const RWindowEvent& e) { eventLog.push_back(e);}
|
||||
RWindowEvent GetLastEvent() const {
|
||||
return eventLog.back();
|
||||
}
|
||||
std::vector<RWindowEvent> eventLog; // history of all logged window events.
|
||||
std::queue<RWindowEvent> eventQueue; //
|
||||
|
||||
protected:
|
||||
int width = 1280;
|
||||
int height = 720;
|
||||
|
||||
protected:
|
||||
bool open = false; // Is the underlying OS-Window-Handle actually open.
|
||||
bool resizable = true;
|
||||
bool fullscreen_mode = false;
|
||||
bool focused = true;
|
||||
bool vsync = false;
|
||||
bool cursor_visible = true;
|
||||
bool closing = false;
|
||||
|
||||
protected:
|
||||
float delta_time = 0.f;
|
||||
float refresh_rate = 0.f;
|
||||
unsigned int refresh_count = 0;
|
||||
// TODO: Implement ringbuffer / circular vector class of some sort.
|
||||
float refresh_rate_prev_1 = 0.f;
|
||||
float refresh_rate_prev_2 = 0.f;
|
||||
float refresh_rate_prev_3 = 0.f;
|
||||
float refresh_rate_prev_4 = 0.f;
|
||||
float refresh_rate_prev_5 = 0.f;
|
||||
float avg_refresh_rate = 0.0f;
|
||||
|
||||
protected:
|
||||
std::string title = "Redacted Window";
|
||||
|
||||
protected:
|
||||
RenderingAPI renderer = RenderingAPI::OPENGL;
|
||||
};
|
||||
}
|
||||
|
||||
namespace ReWindow
|
||||
{
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
|
Reference in New Issue
Block a user