Implemented logging utilities

This commit is contained in:
Pablo Rodriguez
2025-07-28 08:29:53 -04:00
parent 9a38c557f0
commit 472d35497d
16 changed files with 138 additions and 26 deletions

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"C_Cpp.default.cppStandard": "c++20",
"cmake.debugConfig": {
"cwd": "${workspaceFolder}"
}
}

View File

@@ -2,9 +2,13 @@ cmake_minimum_required(VERSION 3.31)
project(Ugly) project(Ugly)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
find_package(GLEW REQUIRED) find_package(GLEW REQUIRED)
find_package(glfw3 CONFIG REQUIRED) find_package(glfw3 CONFIG REQUIRED)
find_package(glm CONFIG REQUIRED) find_package(glm CONFIG REQUIRED)
add_subdirectory(./source/app) add_subdirectory(./source/app)
add_subdirectory(./source/log)
add_subdirectory(./source/shader) add_subdirectory(./source/shader)

View File

@@ -13,5 +13,6 @@ target_link_libraries(${PROJECT_NAME}
GLEW::GLEW GLEW::GLEW
glfw glfw
glm::glm glm::glm
UglyLogLib
UglyShaderLib UglyShaderLib
) )

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -1,24 +1,31 @@
#include "App.hpp" #include "App.hpp"
#include <cstdlib>
#include <iostream> #include <iostream>
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "LogUtils.hpp"
#include "ShaderProgramBuilder.hpp" #include "ShaderProgramBuilder.hpp"
#include "TimestampLog.hpp"
int App::main(std::vector<std::string> &args) { int App::main(std::vector<std::string> &args) {
auto cerrLog = ugly::TimestampLog{std::cerr, "ugly::log"};
ugly::log = ugly::LogAlias{&cerrLog};
ugly::log("hello, world! app started.");
auto app = App{}; auto app = App{};
app.game_loop(); app.game_loop();
return EXIT_SUCCESS;
ugly::log("app quitting.");
return 0;
} }
void App::error_callback_s(int error, const char *description) void App::error_callback_s(int error, const char *description)
{ {
std::cerr << "[GLFW error]: " << description << '\n'; ugly::log("(glfw error): {}", description);
exit(EXIT_FAILURE);
} }
@@ -45,7 +52,7 @@ App::App():
glfwMakeContextCurrent(mpWindow); glfwMakeContextCurrent(mpWindow);
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK) { if(glewInit() != GLEW_OK) {
error_callback_s(GLFW_NO_ERROR, "glewInit() failed"); ugly::log("glewInit() failed!");
} }
float vertices[] = { float vertices[] = {

11
source/log/CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
project(UglyLogLib)
add_library(${PROJECT_NAME}
./src/globals.cpp
./src/TimestampLog.cpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC ./include
PRIVATE ./src
)

View File

@@ -0,0 +1,13 @@
#pragma once
#include <format>
#include <string_view>
namespace ugly {
class ILogFacility {
public:
virtual void vlog(std::string_view fmt, std::format_args args) = 0;
};
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "ILogFacility.hpp"
#include <format>
namespace ugly {
class LogAlias {
public:
ILogFacility *mpLog;
template<typename ...Args>
LogAlias &operator()(std::format_string<Args...> format, Args &&...args) {
if(mpLog) {
mpLog->vlog(format.get(), std::make_format_args(args...));
}
return *this;
}
};
extern LogAlias log;
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "ILogFacility.hpp"
#include <chrono>
#include <format>
#include <ostream>
#include <string_view>
#include <string>
namespace ugly {
class TimestampLog: virtual public ILogFacility {
private:
std::ostream &mrOutputStream;
std::string mDescription;
std::chrono::high_resolution_clock::time_point mStart;
public:
TimestampLog(std::ostream &os, std::string_view description);
void vlog(std::string_view fmt, std::format_args args) override;
};
}

View File

@@ -0,0 +1,18 @@
#include "TimestampLog.hpp"
#include <format>
#include <chrono>
ugly::TimestampLog::TimestampLog(std::ostream &os, std::string_view description):
mrOutputStream{os},
mDescription{description},
mStart{std::chrono::high_resolution_clock::now()} {}
void ugly::TimestampLog::vlog(std::string_view fmt, std::format_args args) {
auto now = std::chrono::high_resolution_clock::now();
auto timestamp = std::chrono::duration_cast<std::chrono::duration<float>>(now - mStart).count();
auto message = std::vformat(fmt, args);
mrOutputStream << std::format("[{:9.4f}] {}: {}\n", timestamp, mDescription, message);
}

View File

@@ -0,0 +1,3 @@
#include "LogUtils.hpp"
ugly::LogAlias ugly::log{nullptr};

View File

@@ -11,4 +11,5 @@ target_include_directories(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
GLEW::GLEW GLEW::GLEW
UglyLogLib
) )

View File

@@ -7,11 +7,8 @@
namespace ugly{ namespace ugly{
class ShaderProgramBuilder { class ShaderProgramBuilder {
public: private:
class Error: public std::runtime_error{ GLuint mProgram;
public:
using std::runtime_error::runtime_error;
};
public: public:
ShaderProgramBuilder(); ShaderProgramBuilder();
@@ -20,9 +17,6 @@ public:
ShaderProgramBuilder &attachFromMemory(GLenum type, const GLchar *string, GLint length = 0); ShaderProgramBuilder &attachFromMemory(GLenum type, const GLchar *string, GLint length = 0);
ShaderProgramBuilder &attachFromFile(GLenum type, const char *filename); ShaderProgramBuilder &attachFromFile(GLenum type, const char *filename);
GLuint link(); GLuint link();
private:
GLuint mProgram;
}; };
} }

View File

@@ -1,14 +1,14 @@
#include "ShaderProgramBuilder.hpp" #include "ShaderProgramBuilder.hpp"
#include <fstream> #include <fstream>
#include <iostream>
#include <sstream> #include <sstream>
#include <utility> #include <utility>
#include "LogUtils.hpp"
ugly::ShaderProgramBuilder::ShaderProgramBuilder(): ugly::ShaderProgramBuilder::ShaderProgramBuilder():
mProgram{glCreateProgram()} { mProgram{glCreateProgram()} {}
}
ugly::ShaderProgramBuilder::~ShaderProgramBuilder() { ugly::ShaderProgramBuilder::~ShaderProgramBuilder() {
@@ -20,7 +20,8 @@ ugly::ShaderProgramBuilder::~ShaderProgramBuilder() {
void ugly::ShaderProgramBuilder::reset() { void ugly::ShaderProgramBuilder::reset() {
using namespace std; using namespace std;
swap(*this, ShaderProgramBuilder{}); ShaderProgramBuilder b;
swap(*this, b);
} }
@@ -35,8 +36,7 @@ ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromMemory(GLenum
char buf[512]; char buf[512];
glGetShaderInfoLog(shader, 512, NULL, buf); glGetShaderInfoLog(shader, 512, NULL, buf);
glDeleteShader(shader); glDeleteShader(shader);
std::cerr << "Failed to compile shader:\n\t" << buf << '\n'; ugly::log("failed to compile shader:\n\t{}", buf);
throw Error{"shader failed to compile"};
} }
glAttachShader(mProgram, shader); glAttachShader(mProgram, shader);
@@ -48,8 +48,14 @@ ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromMemory(GLenum
ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromFile(GLenum type, const char *filename) { ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromFile(GLenum type, const char *filename) {
auto file = std::filebuf{}; auto file = std::filebuf{};
auto ss = std::ostringstream{}; auto ss = std::ostringstream{};
ss.exceptions(std::ios_base::badbit);
ss << file.open(filename, std::ios_base::in); ugly::log("loading shader from file {}", filename);
file.open(filename, std::ios_base::in);
if(!file.is_open()) {
ugly::log("couldn't open file {}", filename);
}
ss << &file;
return attachFromMemory(type, ss.str().c_str()); return attachFromMemory(type, ss.str().c_str());
} }
@@ -62,8 +68,7 @@ GLuint ugly::ShaderProgramBuilder::link() {
if(status != GL_TRUE) { if(status != GL_TRUE) {
char buf[512]; char buf[512];
glGetProgramInfoLog(mProgram, 512, NULL, buf); glGetProgramInfoLog(mProgram, 512, NULL, buf);
std::cerr << "Failed to link program:\n\t" << buf << '\n'; ugly::log("failed to link program:\n\t{}", buf);
throw Error{"program failed to link"};
} }
auto result = mProgram; auto result = mProgram;