Compare commits

...

24 Commits

Author SHA1 Message Date
7fe522ffbe new minor change to test new https subdomain 2026-04-19 20:30:15 +02:00
4cd1528343 fix: getmouse pos uses the member vars correctly and removed const 2026-04-17 11:54:42 +02:00
31f57eddf7 fix: window remove flags function used | to remove flag instead of & 2026-04-17 11:40:56 +02:00
e9808fb47f fix: sdl render alpha was set 0 changed to 255 to be transparent 2026-04-17 11:39:48 +02:00
fa05feceb8 fixed: uninitalized m_Flags in window made the application window not appear 2026-04-16 15:42:08 +02:00
4b89548102 changed the type of the windowflags in windowdata struct and window create function argument 2026-04-16 13:48:34 +02:00
99d508c5ed added windowFlag to WindowData so client can specify the first window's flags when application is created 2026-04-15 10:35:22 +02:00
fb9e93d9cf changed m_Flags from pointer to stack var 2026-04-15 10:28:11 +02:00
e64fc16d6a removeflags function for window class 2026-04-15 10:19:24 +02:00
73db13dcc2 addflags function for windows 2026-04-15 10:16:05 +02:00
ec5d5af43e added member var for the window flags to the window class 2026-04-15 10:15:08 +02:00
ccbc79d496 fixed: the application crashes when the user used the x button or key combination to close the window
the crash occured because running state was set false but the
application loop was still running during that frame and rendered to the
now closed window, because the check only happened at the start of the
next frame
2026-04-14 18:03:36 +02:00
7ff93e58ea fixed: handling window creation failure correctly 2026-04-10 16:00:41 +02:00
e57149e9db removed not needed includes and added the include for the event 2026-04-10 15:49:09 +02:00
796769c6a4 window flag add and remove function definition 2026-04-10 15:48:43 +02:00
daefc73de7 window create now accepts flags as parameter 2026-04-10 15:48:11 +02:00
d28dbc1083 updated all submodules to newest version 2026-04-10 11:26:49 +02:00
7e5317fdc0 Revert "deleted getlayers function"
This reverts commit 0dbb8bc642.
2026-04-10 10:56:48 +02:00
0dbb8bc642 deleted getlayers function 2026-04-10 10:54:23 +02:00
96c19efaea changed default constructor and initialized vectors with size to avoid early copying 2026-04-10 10:54:14 +02:00
b964c2257b deleted commented out old code and todo comment 2026-04-10 10:53:22 +02:00
e46225eda9 added getlayerstack function to application 2026-04-10 10:52:26 +02:00
5dd3cc1b73 feat: queuing layer commands such as pop, push and transition at the end of each frame 2026-04-09 22:07:10 +02:00
b98f46f425 removed todo comment from window class 2026-04-09 22:04:31 +02:00
11 changed files with 200 additions and 41 deletions

View File

@@ -50,7 +50,11 @@ bool Application::Init() {
m_AppData.windowdata.eventCallback = [this](Event &event) { RaiseEvent(event); };
m_Window.push_back(std::make_shared<Window>(m_AppData.windowdata));
m_Window[0]->Create();
bool isSuccessful = m_Window[0]->Create({m_AppData.windowdata.windowFlags});
if (!isSuccessful) {
Shutdown();
return false;
}
m_Renderer = SDL_CreateRenderer(GetSDLWindow(), nullptr);
if (!m_Renderer) {
@@ -131,8 +135,11 @@ void Application::Run() {
}
}
// Rendering
if (!m_isRunning) {
break;
}
// Rendering
for (auto &layer : m_LayerStack) {
layer->OnRender();
}
@@ -140,7 +147,7 @@ void Application::Run() {
m_ImGui->Begin();
SDL_SetRenderScale(m_Renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
SDL_SetRenderDrawColor(m_Renderer, (Uint8)111, (Uint8)232, (Uint8)168, (Uint8)0);
SDL_SetRenderDrawColor(m_Renderer, (Uint8)111, (Uint8)232, (Uint8)168, (Uint8)255);
SDL_RenderClear(m_Renderer);
for (auto &layer : m_LayerStack) {
@@ -155,6 +162,9 @@ void Application::Run() {
}
SDL_RenderPresent(m_Renderer);
// handle layercommands here after each frame
m_LayerStack.ProcessCommands();
}
}

View File

@@ -84,6 +84,7 @@ public:
void SetRunningState(bool isRunning) { m_isRunning = isRunning; }
static Application &Get() { return *s_Instance; }
inline LayerStack &GetLayerStack() { return m_LayerStack; }
private:
bool m_isRunning;

View File

@@ -1,5 +1,6 @@
#include "Layer.h"
#include "Application.h"
#include "LayerStack.h"
#include <memory>
#include <string>
@@ -7,13 +8,13 @@ namespace SakuraVNE {
Layer::Layer(const std::string &name, bool isActive) : m_LayerName(name), m_isActive(isActive) {}
void Layer::QueueTransition(std::unique_ptr<Layer> toLayer) {
// TODO: redo this based on the event video
auto &layerStack = Application::Get().m_LayerStack;
for (auto &layer : layerStack) {
if (layer.get() == this) {
layer = std::move(toLayer);
return;
}
}
auto &layerStack = Application::Get().GetLayerStack();
LayerCommand command;
command.action = LayerAction::Transition;
command.targetLayer = this;
command.newLayer = std::move(toLayer);
layerStack.SubmitCommand(std::move(command));
}
} // namespace SakuraVNE

View File

@@ -4,13 +4,49 @@
#include <vector>
namespace SakuraVNE {
LayerStack::LayerStack() {
m_LayerStack.reserve(3);
m_CommandQueue.reserve(10);
}
LayerStack::~LayerStack() {
for (auto &layer : m_LayerStack) {
layer->OnDetach();
// delete layer;
}
}
void LayerStack::SubmitCommand(LayerCommand command) { m_CommandQueue.push_back(std::move(command)); }
void LayerStack::ProcessCommands() {
if (m_CommandQueue.empty()) {
return;
}
for (auto &command : m_CommandQueue) {
switch (command.action) {
case LayerAction::Pop:
PopLayer(command.targetLayer);
break;
case LayerAction::Push:
PushLayer(std::move(command.newLayer));
break;
case LayerAction::Transition:
auto it = std::find_if(m_LayerStack.begin(), m_LayerStack.end(), [&](const std::unique_ptr<Layer> &layer) { return layer.get() == command.targetLayer; });
if (it != m_LayerStack.end()) {
(*it)->OnDetach();
command.newLayer->OnAttach();
*it = std::move(command.newLayer);
}
break;
}
}
m_CommandQueue.clear();
}
void LayerStack::PushLayer(std::unique_ptr<Layer> layer) {
m_LayerStack.emplace(m_LayerStack.begin() + m_LayerIndex, std::move(layer));
m_LayerIndex++;

View File

@@ -6,9 +6,17 @@
#include <vector>
namespace SakuraVNE {
enum class LayerAction { Push, Pop, Transition };
struct LayerCommand {
LayerAction action;
Layer *targetLayer;
std::unique_ptr<Layer> newLayer;
};
class LayerStack {
public:
LayerStack() = default;
LayerStack();
~LayerStack();
void PushLayer(std::unique_ptr<Layer> layer);
@@ -26,11 +34,15 @@ public:
std::vector<std::unique_ptr<Layer>>::const_reverse_iterator rbegin() const { return m_LayerStack.rbegin(); }
std::vector<std::unique_ptr<Layer>>::const_reverse_iterator rend() const { return m_LayerStack.rend(); }
void SubmitCommand(LayerCommand command);
void ProcessCommands();
#ifdef DEBUG
// this is only used for the tests for now, so it will be taken out of the release build
inline const std::vector<std::unique_ptr<Layer>> &GetLayers() const { return m_LayerStack; }
#endif
private:
std::vector<LayerCommand> m_CommandQueue;
std::vector<std::unique_ptr<Layer>> m_LayerStack;
unsigned int m_LayerIndex = 0;
};

View File

@@ -1,27 +1,24 @@
#include "Window.h"
#include "Application.h"
#include "InputEvents.h"
#include "Log.h"
#include "SDL3/SDL_events.h"
#include "SDL3/SDL_mouse.h"
#include "SDL3/SDL_video.h"
#include "WindowEvents.h"
#include <span>
namespace SakuraVNE {
Window::Window(const WindowData &data) : m_Data(data) {}
Window::Window(const WindowData &data) : m_Data(data), m_Flags(0) {}
Window::~Window() { Destroy(); }
void Window::Create() {
// TODO: maybe get an unknow amount of parameters / an array of window flags? or just provide a seperate function for it
SDL_WindowFlags windowFlags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY);
m_Handle = SDL_CreateWindow(m_Data.title.c_str(), m_Data.width, m_Data.height, windowFlags);
bool Window::Create(const SDL_WindowFlags flags) {
m_Flags |= flags;
m_Handle = SDL_CreateWindow(m_Data.title.c_str(), m_Data.width, m_Data.height, m_Flags);
if (!m_Handle) {
LOG_ERROR("SDL window could not be created! {0}", SDL_GetError());
// FIX: there has to be a better way to shutdown this cannot be correct, because i just quit the sdl stuff but the init continues
Application::Get().Shutdown();
return;
return false;
} else {
LOG_INFO("SDl window created");
}
@@ -35,11 +32,9 @@ void Window::Create() {
} else {
LOG_WARN("SDL window position not set. Will not attempt to set window position.");
}
}
// TODO: add the window callbacks here as seperate functions because sdl functions that way
// each of them will get a function which will receive a window event filled in with the window's data (id (i guess))
// and then they will dispatch it to the event system using the same raise event
return true;
}
void Window::ProcessEvent(const SDL_Event &event) {
switch (event.type) {
@@ -94,6 +89,106 @@ void Window::ProcessEvent(const SDL_Event &event) {
}
}
void Window::AddFlags(std::span<const SDL_WindowFlags> flags) {
for (auto &flag : flags) {
switch (flag) {
case SDL_WINDOW_FULLSCREEN:
SDL_SetWindowFullscreen(m_Handle, true);
break;
case SDL_WINDOW_HIDDEN:
SDL_ShowWindow(m_Handle);
break;
case SDL_WINDOW_BORDERLESS:
SDL_SetWindowBordered(m_Handle, false);
break;
case SDL_WINDOW_RESIZABLE:
SDL_SetWindowResizable(m_Handle, true);
break;
case SDL_WINDOW_MINIMIZED:
SDL_MinimizeWindow(m_Handle);
break;
case SDL_WINDOW_MAXIMIZED:
SDL_MaximizeWindow(m_Handle);
break;
case SDL_WINDOW_MOUSE_GRABBED:
SDL_SetWindowMouseGrab(m_Handle, true);
break;
case SDL_WINDOW_MOUSE_CAPTURE:
SDL_SetWindowMouseGrab(m_Handle, true);
break;
case SDL_WINDOW_MOUSE_RELATIVE_MODE:
SDL_SetWindowRelativeMouseMode(m_Handle, true);
break;
case SDL_WINDOW_MODAL:
SDL_SetWindowModal(m_Handle, true);
break;
case SDL_WINDOW_ALWAYS_ON_TOP:
SDL_SetWindowAlwaysOnTop(m_Handle, true);
break;
case SDL_WINDOW_KEYBOARD_GRABBED:
SDL_SetWindowKeyboardGrab(m_Handle, true);
break;
case SDL_WINDOW_NOT_FOCUSABLE:
SDL_SetWindowFocusable(m_Handle, false);
break;
default:
LOG_WARN("You can only use this when creating a window or the flag is readonly");
break;
}
m_Flags |= flag;
}
}
void Window::RemoveFlags(std::span<const SDL_WindowFlags> flags) {
for (auto &flag : flags) {
switch (flag) {
case SDL_WINDOW_FULLSCREEN:
SDL_SetWindowFullscreen(m_Handle, false);
break;
case SDL_WINDOW_HIDDEN:
SDL_HideWindow(m_Handle);
break;
case SDL_WINDOW_BORDERLESS:
SDL_SetWindowBordered(m_Handle, true);
break;
case SDL_WINDOW_RESIZABLE:
SDL_SetWindowResizable(m_Handle, false);
break;
case SDL_WINDOW_MINIMIZED:
case SDL_WINDOW_MAXIMIZED:
SDL_RestoreWindow(m_Handle);
break;
case SDL_WINDOW_MOUSE_GRABBED:
SDL_SetWindowMouseGrab(m_Handle, false);
break;
case SDL_WINDOW_MOUSE_CAPTURE:
SDL_SetWindowMouseGrab(m_Handle, false);
break;
case SDL_WINDOW_MOUSE_RELATIVE_MODE:
SDL_SetWindowRelativeMouseMode(m_Handle, false);
break;
case SDL_WINDOW_MODAL:
SDL_SetWindowModal(m_Handle, false);
break;
case SDL_WINDOW_ALWAYS_ON_TOP:
SDL_SetWindowAlwaysOnTop(m_Handle, false);
break;
case SDL_WINDOW_KEYBOARD_GRABBED:
SDL_SetWindowKeyboardGrab(m_Handle, false);
break;
case SDL_WINDOW_NOT_FOCUSABLE:
SDL_SetWindowFocusable(m_Handle, true);
break;
default:
LOG_WARN("You can only use this when creating a window or the flag is readonly");
break;
}
m_Flags &= flag;
}
}
void Window::Resize() {
SDL_GetWindowSize(m_Handle, &m_Data.width, &m_Data.height);
SDL_SetWindowSize(m_Handle, m_Data.width, m_Data.height);
@@ -114,13 +209,13 @@ void Window::RaiseEvent(Event &event) {
// TODO: this need testing because i am really not sure this is correct
// should this be static or go somewhere else | probably in application?
auto Window::GetMousePos() const {
auto Window::GetMousePos() {
struct result {
float *x;
float *y;
float x;
float y;
};
SDL_GetMouseState(m_MouseXPos, m_MouseYPos);
SDL_GetMouseState(&m_MouseXPos, &m_MouseYPos);
return result{m_MouseXPos, m_MouseYPos};
}

View File

@@ -1,14 +1,15 @@
#pragma once
#include "Event.h"
#include "SDL3/SDL_events.h"
#include "SDL3/SDL_video.h"
#include "imgui_impl_sdl3.h"
#include <cstdint>
#include <functional>
#include <span>
#include <string>
namespace SakuraVNE {
struct WindowData {
SDL_WindowFlags windowFlags = 0;
std::string title = "Window Title";
int width = 1280;
int height = 720;
@@ -26,25 +27,28 @@ public:
Window(const WindowData &data = WindowData());
~Window();
void Create();
bool Create(const SDL_WindowFlags flags = 0);
void Destroy();
void Update();
void AddFlags(std::span<const SDL_WindowFlags> flags = {});
void RemoveFlags(std::span<const SDL_WindowFlags> flags = {});
void Resize();
void ProcessEvent(const SDL_Event &event);
void RaiseEvent(Event &event);
bool ShouldClose() const;
auto GetMousePos() const;
auto GetMousePos();
SDL_Window *GetHandle() const { return m_Handle; }
private:
WindowData m_Data;
SDL_Window *m_Handle = nullptr;
float *m_MouseXPos = nullptr;
float *m_MouseYPos = nullptr;
SDL_WindowFlags m_Flags;
float m_MouseXPos;
float m_MouseYPos;
};
} // namespace SakuraVNE