initial commit

This commit is contained in:
2025-05-01 23:03:47 +02:00
commit a23fbff52a
200 changed files with 434542 additions and 0 deletions

124
ScopEngine/Runtime/Sources/Core/Engine.cpp git.filemode.normal_file
View File

@@ -0,0 +1,124 @@
#include <Core/Engine.h>
#include <Renderer/RenderCore.h>
#include <SDL2/SDL.h>
#include <Core/Logs.h>
#include <Core/EventBus.h>
#include <csignal>
namespace Scop
{
namespace Internal
{
struct InterruptEvent : public EventBase
{
Event What() const override { return Event::QuitEventCode; }
};
struct SceneChangedEvent : public EventBase
{
Event What() const override { return Event::SceneHasChangedEventCode; }
};
}
void FatalErrorEventHandle()
{
std::abort();
}
void SignalHandler([[maybe_unused]] int sig)
{
EventBus::Send("__ScopEngine", Internal::InterruptEvent{});
}
ScopEngine* ScopEngine::s_instance = nullptr;
ScopEngine::ScopEngine(int ac, char** av, const std::string& title, std::uint32_t width, std::uint32_t height, std::filesystem::path assets_path)
: m_renderer(), m_window(title, width, height), m_assets_path(std::move(assets_path))
#ifdef DEBUG
,m_imgui(&m_renderer)
#endif
{
s_instance = this;
std::function<void(const EventBase&)> functor = [this](const EventBase& event)
{
if(event.What() == Event::FatalErrorEventCode)
FatalErrorEventHandle();
if(event.What() == Event::QuitEventCode)
this->Quit();
};
EventBus::RegisterListener({ functor, "__ScopEngine" });
m_cli.Feed(ac, av);
signal(SIGINT, SignalHandler);
SDL_SetHint("SDL_MOUSE_RELATIVE_MODE_WARP", "1");
SDL_SetHint("SDL_MOUSE_RELATIVE_MODE_CENTER", "1");
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0)
FatalError("SDL error: unable to init all subsystems : %", SDL_GetError());
p_renderer_core = std::make_unique<RenderCore>();
m_renderer.Init(&m_window);
m_scene_renderer.Init();
#ifdef DEBUG
m_imgui.Init(m_inputs);
#endif
}
ScopEngine& ScopEngine::Get() noexcept
{
Verify(s_instance != nullptr, "ScopEngine has not been instanciated");
return *s_instance;
}
void ScopEngine::Run()
{
Verify(p_current_scene, "no main scene registered");
float old_timestep = static_cast<float>(SDL_GetTicks64()) / 1000.0f;
p_current_scene->Init(&m_renderer);
while(m_running)
{
float current_timestep = (static_cast<float>(SDL_GetTicks64()) / 1000.0f) - old_timestep;
old_timestep = static_cast<float>(SDL_GetTicks64()) / 1000.0f;
m_inputs.Update();
m_window.FetchWindowInfos();
p_current_scene->Update(m_inputs, current_timestep, static_cast<float>(m_window.GetWidth()) / static_cast<float>(m_window.GetHeight()));
if(m_scene_changed)
{
RenderCore::Get().WaitDeviceIdle();
EventBus::SendBroadcast(Internal::SceneChangedEvent{});
m_scene_changed = false;
continue;
}
m_renderer.BeginFrame();
m_scene_renderer.Render(*p_current_scene, m_renderer);
#ifdef DEBUG
m_imgui.BeginFrame();
m_imgui.DisplayRenderStatistics();
m_imgui.EndFrame();
#endif
m_renderer.EndFrame();
if(m_running)
m_running = !m_inputs.HasRecievedCloseEvent();
}
}
ScopEngine::~ScopEngine()
{
RenderCore::Get().WaitDeviceIdle();
m_main_scene->Destroy();
m_window.Destroy();
#ifdef DEBUG
m_imgui.Destroy();
#endif
m_scene_renderer.Destroy();
m_renderer.Destroy();
p_renderer_core.reset();
SDL_Quit();
Message("Successfully executed !");
s_instance = nullptr;
}
}

24
ScopEngine/Runtime/Sources/Core/EventBus.cpp git.filemode.normal_file
View File

@@ -0,0 +1,24 @@
#include <Core/EventBus.h>
#include <Core/Logs.h>
namespace Scop
{
void EventBus::Send(const std::string& listener_name, const EventBase& event)
{
for(const EventListener& listener : s_listeners)
{
if(listener.GetName() == listener_name)
{
listener.Call(event);
return;
}
}
Warning("Event Bus : listener not found, '%'", listener_name);
}
void EventBus::SendBroadcast(const EventBase& event)
{
for(const EventListener& listener : s_listeners)
listener.Call(event);
}
}

View File

@@ -0,0 +1,8 @@
#include <Core/EventListener.h>
namespace Scop
{
EventListener::EventListener(std::function<void(const EventBase&)> functor, std::string name)
: m_listen_functor(std::move(functor)), m_name(std::move(name))
{}
}

66
ScopEngine/Runtime/Sources/Core/Logs.cpp git.filemode.normal_file
View File

@@ -0,0 +1,66 @@
#include <ctime>
#include <string>
#include <string_view>
#include <Core/Logs.h>
#include <Utils/Ansi.h>
#include <Core/EventBase.h>
#include <Core/EventBus.h>
namespace Scop
{
namespace Internal
{
struct FatalErrorEvent : public EventBase
{
Event What() const override { return Event::FatalErrorEventCode; }
};
}
void Logs::Report(LogType type, std::string message)
{
Report(type, 0, {}, {}, std::move(message));
}
void Logs::Report(LogType type, unsigned int line, std::string_view file, std::string_view function, std::string message)
{
using namespace std::literals;
#ifndef VOX_DEBUG
if(type == LogType::Debug && std::getenv("VOX_DEBUG_LOGS") == nullptr)
return;
#endif
std::string code_infos;
if((type == LogType::Error || type == LogType::FatalError) && !file.empty() && !function.empty())
{
code_infos += "{in file '"s;
code_infos += file;
code_infos += "', line "s + std::to_string(line) + ", in function '"s;
code_infos += function;
code_infos += "'} "s;
}
switch(type)
{
case LogType::Debug: std::cout << Ansi::blue << "[Scop Debug] "; break;
case LogType::Message: std::cout << Ansi::blue << "[Scop Message] "; break;
case LogType::Warning: std::cout << Ansi::magenta << "[Scop Warning] "; break;
case LogType::Error: std::cerr << Ansi::red << "[Scop Error] "; break;
case LogType::FatalError: std::cerr << Ansi::red << "[Scop Fatal Error] "; break;
default: break;
}
std::time_t now = time(0);
std::tm tstruct = *localtime(&now);
char buffer[80];
std::strftime(buffer, sizeof(buffer), "[%X] ", &tstruct);
std::cout << Ansi::yellow << buffer << Ansi::def << code_infos << message << std::endl;
if(type == LogType::FatalError)
{
std::cout << Ansi::bg_red << "Fatal Error: emergency exit" << Ansi::bg_def << std::endl;
EventBus::Send("__ScopEngine", Internal::FatalErrorEvent{});
}
}
}