Skip to content

Commit

Permalink
feat: add logging console and refactor Application class
Browse files Browse the repository at this point in the history
  • Loading branch information
painfulexistence committed Dec 11, 2024
1 parent e467c11 commit aae5e81
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 102 deletions.
3 changes: 2 additions & 1 deletion AtmosphericEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ option(BUILD_SHARED_LIBS OFF)
find_package(Bullet CONFIG REQUIRED)

find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(lua REQUIRED)

add_subdirectory(external/entt)
Expand Down Expand Up @@ -62,5 +63,5 @@ target_include_directories(AtmosphericEngine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
target_precompile_headers(AtmosphericEngine PRIVATE pch.hpp)
target_link_libraries(AtmosphericEngine
PUBLIC
GLEW::GLEW glfw glm::glm fmt::fmt EnTT::EnTT BulletSoftBody BulletDynamics BulletCollision LinearMath ${LUA_LIBRARIES} sol2 raudio
GLEW::GLEW glfw glm::glm fmt::fmt spdlog::spdlog EnTT::EnTT BulletSoftBody BulletDynamics BulletCollision LinearMath ${LUA_LIBRARIES} sol2 raudio
)
78 changes: 27 additions & 51 deletions AtmosphericEngine/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@
#include "scene.hpp"
#include "impostor.hpp"

Application::Application()
Application::Application(AppConfig config) : _config(config)
{
Log("Launching...");
_window = std::make_shared<Window>();; // Multi-window not supported now
// setbuf(stdout, NULL); // Cancel output stream buffering so that output can be seen immediately

_window = std::make_shared<Window>(WindowProps {
.title = config.windowTitle,
.width = config.windowWidth,
.height = config.windowHeight
}); // Multi-window not supported now
_window->Init();
_window->InitImGui();
}

Application::~Application()
{
Log("Exiting...");
ENGINE_LOG("Exiting...");
_window->DeinitImGui();

for (const auto& go : _entities)
delete go;
}

void Application::Run()
{
Log("Initializing subsystems...");

console.Init(this);
input.Init(this);
audio.Init(this);
Expand All @@ -33,9 +37,9 @@ void Application::Run()
for (auto& subsystem : _subsystems) {
subsystem->Init(this);
}
this->_initialized = true;
ENGINE_LOG("Subsystems initialized.");

Log("Subsystems initialized.");
OnInit();

OnLoad();

Expand All @@ -48,31 +52,24 @@ void Application::Run()
std::thread fork(&Application::Update, this, currFrame);
Render(currFrame);
fork.join();
SyncTransformWithPhysics();
#endif
_clock++;
});
}

void Application::LoadScene(SceneDef& scene)
{
Log("Loading scene...");
void Application::LoadScene(SceneDef& scene) {
ENGINE_LOG("Loading scene...");

graphics.LoadTextures(scene.textures);
script.Print("Textures created.");
ENGINE_LOG("Textures created.");

graphics.LoadColorShader(ShaderProgram(scene.shaders["color"]));
graphics.LoadDebugShader(ShaderProgram(scene.shaders["debug_line"]));
graphics.LoadDepthShader(ShaderProgram(scene.shaders["depth"]));
graphics.LoadDepthCubemapShader(ShaderProgram(scene.shaders["depth_cubemap"]));
graphics.LoadTerrainShader(ShaderProgram(scene.shaders["terrain"]));
graphics.LoadPostProcessShader(ShaderProgram(scene.shaders["hdr"]));
script.Print("Shaders created.");
graphics.LoadShaders(scene.shaders);
ENGINE_LOG("Shaders created.");

for (const auto& mat : scene.materials) {
graphics.materials.push_back(new Material(mat));
}
script.Print("Materials created.");
ENGINE_LOG("Materials created.");

for (const auto& go : scene.gameObjects) {
auto entity = CreateGameObject(go.position, go.rotation, go.scale);
Expand All @@ -81,11 +78,10 @@ void Application::LoadScene(SceneDef& scene)
entity->AddCamera(go.camera.value());
}
if (go.light.has_value()) {
Log(fmt::format("Adding light to {}", go.name));
entity->AddLight(go.light.value());
}
}
script.Print("Game objects created.");
ENGINE_LOG("Game objects created.");

mainCamera = graphics.GetMainCamera();
mainLight = graphics.GetMainLight();
Expand Down Expand Up @@ -120,7 +116,7 @@ void Application::ReloadScene() {

void Application::Quit()
{
Log("Requested to quit.");
ENGINE_LOG("Requested to quit.");
_window->Close();
}

Expand All @@ -140,9 +136,9 @@ void Application::Update(const FrameData& props)
subsystem->Process(dt);
}

#if SHOW_PROCESS_COST
Log(fmt::format("Update costs {} ms", (GetWindowTime() - time) * 1000));
#endif
#if SHOW_PROCESS_COST
ENGINE_LOG(fmt::format("Update costs {} ms", (GetWindowTime() - time) * 1000));
#endif
}

void Application::Render(const FrameData& props)
Expand Down Expand Up @@ -305,6 +301,7 @@ void Application::Render(const FrameData& props)
if (_showEngineView) {
ImGui::Begin("Engine Subsystems");
{
console.DrawImGui(dt);
input.DrawImGui(dt);
audio.DrawImGui(dt);
graphics.DrawImGui(dt);
Expand All @@ -318,34 +315,13 @@ void Application::Render(const FrameData& props)

_window->EndImGuiFrame();

#if SHOW_RENDER_AND_DRAW_COST
Log(fmt::format("[Engine] Render & draw cost {} ms", (GetWindowTime() - time) * 1000));
#endif
#if SHOW_RENDER_AND_DRAW_COST
ENGINE_LOG(fmt::format("Render & draw cost {} ms", (GetWindowTime() - time) * 1000));
#endif
}

void Application::SyncTransformWithPhysics()
{
float time = GetWindowTime();

//ecs.SyncTransformWithPhysics();
for (auto go : _entities)
{
auto impostor = dynamic_cast<Impostor*>(go->GetComponent("Physics"));
if (impostor == nullptr)
continue;
go->SyncObjectTransform(impostor->GetWorldTransform());
}

#if SHOW_SYNC_COST
Log(fmt::format("Sync cost {} ms", (Time() - time) * 1000));
#endif
}

void Application::Log(std::string message)
{
#if RUNTIME_LOG_ON
fmt::print("[Engine] {}\n", message);
#endif
}

uint64_t Application::GetClock()
Expand Down
26 changes: 21 additions & 5 deletions AtmosphericEngine/application.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once
#include "config.hpp"
#include "globals.hpp"
#include "imgui.h"
#include "console.hpp"
#include "audio_manager.hpp"
#include "graphics_server.hpp"
#include "physics_server.hpp"
#include "console.hpp"
#include "input.hpp"
#include "script.hpp"

Expand All @@ -27,17 +28,31 @@ struct FrameData
float deltaTime;
};

struct AppConfig {
std::string windowTitle = INIT_SCREEN_TITLE;
int windowWidth = INIT_SCREEN_WIDTH;
int windowHeight = INIT_SCREEN_HEIGHT;
bool fullscreen = false;
bool vsync = true;
bool enable3D = true;
bool enableAudio = true;
bool enablePhysics = true;
float physicsTimeStep = 1.0f / 60.0f;
};

using EntityID = uint64_t;

class Application {
public:
Application();
Application(AppConfig config = {});
~Application();

void Run();

virtual void OnLoad() = 0;
virtual void OnInit() {} // Load resources
virtual void OnLoad() = 0; // Setup game objects (side effects)
virtual void OnUpdate(float dt, float time) = 0;
virtual void OnReload() {} // Reset game objects (side effects clean up and recreate)

uint64_t GetClock();

Expand Down Expand Up @@ -65,7 +80,6 @@ class Application {
void LoadScene(SceneDef& scene);
void ReloadScene();

void Log(std::string message);
void Quit();

std::shared_ptr<Window> GetWindow();
Expand All @@ -81,10 +95,12 @@ class Application {
GameObject* CreateGameObject(glm::vec3 position = glm::vec3(0.0f), glm::vec3 rotation = glm::vec3(0.0f), glm::vec3 scale = glm::vec3(1.0f));

private:
AppConfig _config;

std::shared_ptr<Window> _window = nullptr;
std::vector<std::shared_ptr<Server>> _subsystems;
bool _initialized = false;

std::shared_ptr<Window> _window = nullptr;
uint64_t _clock = 0;
uint16_t _sceneIndex = 0;
std::optional<SceneDef> _currentSceneDef = std::nullopt;
Expand Down
87 changes: 87 additions & 0 deletions AtmosphericEngine/console.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "console.hpp"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "script.hpp"

Console* Console::_instance = nullptr;

Expand All @@ -13,4 +16,88 @@ Console::Console()
Console::~Console()
{

}

void Console::Init(Application* app)
{
Server::Init(app);

auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto logger = std::make_shared<spdlog::logger>("console", console_sink);
spdlog::set_default_logger(logger);
}

void Console::Process(float dt)
{

}

void Console::DrawImGui(float dt)
{
if (ImGui::CollapsingHeader("Console", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Text("Log Level:");
if (ImGui::RadioButton("Info", spdlog::level::info == spdlog::default_logger()->level())) {
spdlog::default_logger()->set_level(spdlog::level::info);
}
ImGui::SameLine();
if (ImGui::RadioButton("Warn", spdlog::level::warn == spdlog::default_logger()->level())) {
spdlog::default_logger()->set_level(spdlog::level::warn);
}
ImGui::SameLine();
if (ImGui::RadioButton("Error", spdlog::level::err == spdlog::default_logger()->level())) {
spdlog::default_logger()->set_level(spdlog::level::err);
}

ImGui::Separator();

if (ImGui::BeginChild("Log", ImVec2(0, 300))) {
ImGui::Text("Log:");
ImGui::EndChild();
}

ImGui::Separator();

// TODO: command palette
static char command[256] = "";
if (ImGui::InputText("Command", command, IM_ARRAYSIZE(command), ImGuiInputTextFlags_EnterReturnsTrue)) {
ExecuteCommand(command);
command[0] = '\0';
}
}
}

void Console::Info(const std::string& message)
{
#if RUNTIME_LOG_ON
spdlog::info(message);
#endif
}

void Console::Warn(const std::string& message)
{
#if RUNTIME_LOG_ON
spdlog::warn(message);
#endif
}

void Console::Error(const std::string& message)
{
#if RUNTIME_LOG_ON
spdlog::error(message);
#endif
}

void Console::RegisterCommand(const std::string& cmd, std::function<void(const std::vector<std::string>&)> callback)
{
_commands[cmd] = callback;
}

void Console::ExecuteCommand(const std::string& cmd)
{
auto it = _commands.find(cmd);
if (it != _commands.end()) {
it->second({});
}

Script::Get()->Run(cmd);
}
31 changes: 28 additions & 3 deletions AtmosphericEngine/console.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#pragma once
#include "globals.hpp"
#include "config.hpp"
#include "server.hpp"

/// Logging system
struct LogEntry {
std::string message;
};

/// Logging and command palette system
class Console : public Server
{
private:
Expand All @@ -15,6 +20,26 @@ class Console : public Server
}

Console();

~Console();
};

void Init(Application* app) override;
void Process(float dt) override;
void DrawImGui(float dt) override;

void Info(const std::string& message);
void Warn(const std::string& message);
void Error(const std::string& message);

void RegisterCommand(const std::string& cmd, std::function<void(const std::vector<std::string>&)> callback);
void ExecuteCommand(const std::string& cmd);

private:
bool _showInfo = true;
bool _showWarn = true;
bool _showError = true;

std::unordered_map<std::string, std::function<void(const std::vector<std::string>&)>> _commands;
};

#define LOG(msg, ...) Console::Get()->Info(fmt::format(msg, ##__VA_ARGS__))
#define ENGINE_LOG(msg, ...) Console::Get()->Info("[Engine] " + fmt::format(msg, ##__VA_ARGS__))
Loading

0 comments on commit aae5e81

Please sign in to comment.