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_AppData.windowdata.eventCallback = [this](Event &event) { RaiseEvent(event); };
m_Window.push_back(std::make_shared<Window>(m_AppData.windowdata)); 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); m_Renderer = SDL_CreateRenderer(GetSDLWindow(), nullptr);
if (!m_Renderer) { if (!m_Renderer) {
@@ -131,8 +135,11 @@ void Application::Run() {
} }
} }
// Rendering if (!m_isRunning) {
break;
}
// Rendering
for (auto &layer : m_LayerStack) { for (auto &layer : m_LayerStack) {
layer->OnRender(); layer->OnRender();
} }
@@ -140,7 +147,7 @@ void Application::Run() {
m_ImGui->Begin(); m_ImGui->Begin();
SDL_SetRenderScale(m_Renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); 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); SDL_RenderClear(m_Renderer);
for (auto &layer : m_LayerStack) { for (auto &layer : m_LayerStack) {
@@ -155,6 +162,9 @@ void Application::Run() {
} }
SDL_RenderPresent(m_Renderer); 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; } void SetRunningState(bool isRunning) { m_isRunning = isRunning; }
static Application &Get() { return *s_Instance; } static Application &Get() { return *s_Instance; }
inline LayerStack &GetLayerStack() { return m_LayerStack; }
private: private:
bool m_isRunning; bool m_isRunning;

View File

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

View File

@@ -4,13 +4,49 @@
#include <vector> #include <vector>
namespace SakuraVNE { namespace SakuraVNE {
LayerStack::LayerStack() {
m_LayerStack.reserve(3);
m_CommandQueue.reserve(10);
}
LayerStack::~LayerStack() { LayerStack::~LayerStack() {
for (auto &layer : m_LayerStack) { for (auto &layer : m_LayerStack) {
layer->OnDetach(); 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) { void LayerStack::PushLayer(std::unique_ptr<Layer> layer) {
m_LayerStack.emplace(m_LayerStack.begin() + m_LayerIndex, std::move(layer)); m_LayerStack.emplace(m_LayerStack.begin() + m_LayerIndex, std::move(layer));
m_LayerIndex++; m_LayerIndex++;

View File

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

View File

@@ -1,27 +1,24 @@
#include "Window.h" #include "Window.h"
#include "Application.h"
#include "InputEvents.h" #include "InputEvents.h"
#include "Log.h" #include "Log.h"
#include "SDL3/SDL_events.h" #include "SDL3/SDL_events.h"
#include "SDL3/SDL_mouse.h" #include "SDL3/SDL_mouse.h"
#include "SDL3/SDL_video.h" #include "SDL3/SDL_video.h"
#include "WindowEvents.h" #include "WindowEvents.h"
#include <span>
namespace SakuraVNE { namespace SakuraVNE {
Window::Window(const WindowData &data) : m_Data(data) {} Window::Window(const WindowData &data) : m_Data(data), m_Flags(0) {}
Window::~Window() { Destroy(); } Window::~Window() { Destroy(); }
void Window::Create() { bool Window::Create(const SDL_WindowFlags flags) {
// TODO: maybe get an unknow amount of parameters / an array of window flags? or just provide a seperate function for it m_Flags |= flags;
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); m_Handle = SDL_CreateWindow(m_Data.title.c_str(), m_Data.width, m_Data.height, m_Flags);
if (!m_Handle) { if (!m_Handle) {
LOG_ERROR("SDL window could not be created! {0}", SDL_GetError()); 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 return false;
Application::Get().Shutdown();
return;
} else { } else {
LOG_INFO("SDl window created"); LOG_INFO("SDl window created");
} }
@@ -35,11 +32,9 @@ void Window::Create() {
} else { } else {
LOG_WARN("SDL window position not set. Will not attempt to set window position."); 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 return true;
// 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
void Window::ProcessEvent(const SDL_Event &event) { void Window::ProcessEvent(const SDL_Event &event) {
switch (event.type) { 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() { void Window::Resize() {
SDL_GetWindowSize(m_Handle, &m_Data.width, &m_Data.height); SDL_GetWindowSize(m_Handle, &m_Data.width, &m_Data.height);
SDL_SetWindowSize(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 // TODO: this need testing because i am really not sure this is correct
// should this be static or go somewhere else | probably in application? // should this be static or go somewhere else | probably in application?
auto Window::GetMousePos() const { auto Window::GetMousePos() {
struct result { struct result {
float *x; float x;
float *y; float y;
}; };
SDL_GetMouseState(m_MouseXPos, m_MouseYPos); SDL_GetMouseState(&m_MouseXPos, &m_MouseYPos);
return result{m_MouseXPos, m_MouseYPos}; return result{m_MouseXPos, m_MouseYPos};
} }

View File

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