Compare commits

..

11 Commits

Author SHA1 Message Date
NaifBanana
684d09a09e Made buildable now 2026-06-08 03:37:18 -05:00
NaifBanana
f26a43e893 Large OpenGL Object handling overhaul 2026-06-08 03:20:51 -05:00
NaifBanana
8b0c08931c Formatting tweaks 2026-05-18 01:35:28 -05:00
NaifBanana
091867e77d Got logging and errors basically all working the way I want 2026-05-18 01:35:28 -05:00
NaifBanana
32ca555c49 Error logging almost working! 2026-05-18 01:35:28 -05:00
NaifBanana
01ddba733d Added type traits and string utils 2026-05-18 01:35:28 -05:00
NaifBanana
0b5189dd2c nb::Error objects now working 2026-05-18 01:35:28 -05:00
NaifBanana
18de24649a I mean it compiled 2026-05-18 01:35:28 -05:00
NaifBanana
0ab3f7e808 Man im so tired This is wrong but I can taste it, im close 2026-05-18 01:35:28 -05:00
NaifBanana
31ea554cd1 Added more Util tests and str-wstr related changes to util functions 2026-05-18 01:35:27 -05:00
NaifBanana
450c793d71 Made errors mostly work as hoped 2026-05-18 01:35:27 -05:00
15 changed files with 177 additions and 227 deletions

View File

@ -6,11 +6,9 @@
#include <memory>
#include <string>
#include <type_traits>
#include <unordered_map>
#include "Logger.hpp"
#include "StringUtils.hpp"
#include "TypeTraits.hpp"
#include <unordered_map>
#include "StringUtils.hpp"
namespace nb {
@ -275,38 +273,8 @@ public:
static const std::string type;
static const ErrorCodeMap ErrorMessages;
};
} // namespace nb
#ifdef _NB_AUTOLOG
#ifdef _NB_CODE_ERROR_LOCATIONS
#ifndef LOG
#define LOG(args...) nb::logger.log(args, __FILE__, __LINE__)
#endif // LOG
#ifndef WARN
#define WARN(args...) nb::logger.warn(args, __FILE__, __LINE__)
#endif // WARN
#ifndef ERROR
#define ERROR(args...) nb::logger.error(args, __FILE__, __LINE__)
#endif // ERROR
#else
#ifndef LOG
#define LOG(args...) nb::logger.log(args)
#endif // LOG
#ifndef WARN
#define WARN(args...) nb::logger.warn(args)
#endif // WARN
#ifndef ERROR
#define ERROR(args...) nb::logger.error(args)
#endif // ERROR
#endif // _NB_CODE_ERROR_LOCATIONS
#endif // _NB_AUTOLOG
#ifndef THROW
#ifdef _NB_AUTOLOG
#define THROW(args...) ERROR(args); throw args
#else
#define THROW(args...) throw args
#endif // _NB_CODE_ERROR_LOCATIONS
#endif // THROW
#endif // _NB_ERROR

View File

@ -9,15 +9,13 @@
#include <vector>
#include "DataSink.hpp"
#include "Errors.hpp"
#include "Processes.hpp"
#include "ThreadSafeQueue.hpp"
#include "TypeTraits.hpp"
namespace nb {
template <typename T>
class ErrorBase;
typedef std::chrono::time_point<
std::chrono::system_clock,
std::chrono::nanoseconds
@ -133,10 +131,7 @@ public:
U val,
std::string file="",
unsigned int line=0
) {
static_cast<LoggerType*>(this)->log(val, 0xFF, file, line);
static_cast<LoggerType*>(this)->flush();
}
) { static_cast<LoggerType*>(this)->log(val, 0xFF, file, line); }
protected:
std::vector<std::ostream*> _ostream;
@ -172,6 +167,103 @@ extern DefaultDebugLogger logger;
// Taking Charge of Adult ADHD by Russell Barkley
/* template <typename T=NoneType>
struct NB_DEFAULT_LOGGER_THROW;
template<>
struct NB_DEFAULT_LOGGER_THROW<NoneType> {
template <typename T>
NB_DEFAULT_LOGGER_THROW(T arg) {
#ifdef _NB_AUTOLOG
logger.error(arg);
#endif // _NB_AUTLOG
throw arg;
}
};
template <typename T>
struct NB_DEFAULT_LOGGER_THROW {
template <typename... Args>
NB_DEFAULT_LOGGER_THROW(Args&&... args) {
std::shared_ptr<T> error_ptr;
#ifdef _NB_AUTOLOG
#ifdef _NB_CODE_ERROR_LOCATIONS
error_ptr = std::make_shared<T>(args..., __LINE__, __FILE__);
#else
error_ptr = std::make_shared<T>(args...);
#endif // _NB_CODE_ERROR_LOCATIONS
logger.error(*error_ptr);
#endif // _NB_AUTLOG
throw *error_ptr;
}
}; */
/* template <typename Arg1=NoneType, typename...Args>
void NB_DEFAULT_LOGGER_THROW(Args&& ... args) {
std::shared_ptr<Arg1> error_ptr;
#ifdef _NB_AUTOLOG
#ifdef _NB_CODE_ERROR_LOCATIONS
error_ptr = std::make_shared<Arg1>(args..., __LINE__, __FILE__);
#else
error_ptr = std::make_shared<Arg1>(args...);
#endif // _NB_CODE_ERROR_LOCATIONS
logger.error(*error_ptr);
#endif // _NB_AUTLOG
throw *error_ptr;
}
template <typename Arg>
void NB_DEFAULT_LOGGER_THROW<NoneType>(const Arg& arg) {
#ifdef _NB_AUTOLOG
logger.error(arg);
#endif // _NB_AUTLOG
throw arg;
} */
template <typename T>
void NB_DEFAULT_LOGGER_THROW(const T& err, std::string file="", unsigned int line = 0) {
#ifdef _NB_AUTOLOG
if (file.empty()) {
logger.error(err);
} else {
logger.error(err, file, line);
}
#endif // _NB_AUTLOG
throw err;
}
} // namespace nb
#ifdef _NB_AUTOLOG
#ifdef _NB_CODE_ERROR_LOCATIONS
#ifndef LOG
#define LOG(args...) nb::logger.log(args, __FILE__, __LINE__)
#endif // LOG
#ifndef WARN
#define WARN(args...) nb::logger.warn(args, __FILE__, __LINE__)
#endif // WARN
#ifndef ERROR
#define ERROR(args...) nb::logger.error(args, __FILE__, __LINE__)
#endif // ERROR
#else
#ifndef LOG
#define LOG(args...) nb::logger.log(args)
#endif // LOG
#ifndef WARN
#define WARN(args...) nb::logger.warn(args)
#endif // WARN
#ifndef ERROR
#define ERROR(args...) nb::logger.error(args)
#endif // ERROR
#endif // _NB_CODE_ERROR_LOCATIONS
#endif // _NB_AUTOLOG
#ifndef THROW
#ifdef _NB_AUTOLOG
#define THROW(args...) ERROR(args); throw args
#else
#define THROW(args...) throw args
#endif // _NB_CODE_ERROR_LOCATIONS
#endif // THROW
#endif // _NB_LOGGER

View File

@ -7,8 +7,6 @@
namespace nb {
uint64_t GetPID();
uint64_t getTID();
} // namespace nb

View File

@ -1,6 +1,6 @@
#pragma once
#ifndef _NB_STRING_UTILS
#define _NB_STRING_UTILS
#ifndef _NB_CORE_TYPES
#define _NB_CORE_TYPES
#include <iostream>
#include <string>
@ -76,4 +76,4 @@ std::string indent_strblock(
);
} // namespace nb
#endif // _NB_STRING_UTILS
#endif // _NB_CORE_TYPES

View File

@ -2,79 +2,23 @@
#ifndef _NB_CORE_TYPES
#define _NB_CORE_TYPES
#include <mutex>
#include <vector>
#include "Errors.hpp"
namespace nb {
using ByteVector = std::vector<uint8_t>;
/* template<typename T>
T swap_endian(const T& val) {
T ret;
const int size = sizeof(T);
auto retLoc = static_cast<void*>(&ret);
auto valLoc = static_cast<const void*>(&val);
class ObjectManagerError : public Error<ObjectManagerError> {
using Base = Error<ObjectManagerError>;
public:
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, NO_MANAGER, MANAGER_MISMATCH, LOCK_OVERFLOW, BAD_THREAD
};
static const std::string type;
static const ErrorCodeMap ErrorMessages;
};
template <typename T>
class ThreadsafeObjectLock;
template <typename T>
class ThreadsafeObject {
using Codes = ObjectManagerError::Codes;
public:
ThreadsafeObject(T&& obj)
: _obj(std::make_shared<T>(obj)) {}
ThreadsafeObjectLock<T> lock() {
return ThreadsafeObjectLock<T>(this);
for (int i = 0; i < size; ++i) {
memcpy(retLoc+i, valLoc+(size-i-1), 1);
}
return ret;
} */
friend ThreadsafeObjectLock<T>;
protected:
std::shared_ptr<T> _obj;
mutable std::recursive_mutex _mutex;
};
template <typename T>
class ThreadsafeObjectLock {
public:
ThreadsafeObjectLock(const ThreadsafeObjectLock&) = delete;
ThreadsafeObjectLock operator=(const ThreadsafeObjectLock&) = delete;
~ThreadsafeObjectLock() {
_manager->_mutex.unlock();
}
T* operator->() {
return _manager->_obj.get();
}
friend ThreadsafeObject<T>;
protected:
ThreadsafeObjectLock(
ThreadsafeObject<T>* const manager_
) : _manager(manager_) {
if (!_manager) {
using Codes = ObjectManagerError::Codes;
THROW(ObjectManagerError(Codes::NO_MANAGER));
}
_manager->_mutex.lock();
}
ThreadsafeObject<T>* const _manager;
};
// using ByteVector = std::vector<uint8_t>;
} // namespace nb
#endif // _NB_CORE_TYPES

View File

@ -33,6 +33,8 @@ static bool RUN_LOGGER(nb::DefaultDebugLogger& log) {
return log.run();
}
static const bool LOGGER_RUNNING = RUN_LOGGER(logger);
} // namespace nb

View File

@ -15,14 +15,7 @@ uint64_t GetPID() {
return GetCurrentProcessId();
}
#endif // _NB_TARGET_WINDOWS
#ifdef _NB_TARGET_LINUX
#endif // _NB_TARGET_LINUX
#ifdef _NB_TARGET_WINDOWS
uint64_t GetTID() {
return GetCurrentThreadId();
}
#endif // _NB_TARGET_WINDOWS
#ifdef _NB_TARGET_LINUX
#endif // _NB_TARGET_LINUX

View File

@ -1,27 +1 @@
#include "Utils.hpp"
namespace nb {
using ObjectManagerCodes = ObjectManagerError::Codes;
const std::string ObjectManagerError::type = "nb::ObjectManagerError";
const ErrorCodeMap ObjectManagerError::ErrorMessages({
{ObjectManagerCodes::UNDEFINED, "Error"},
{
ObjectManagerCodes::NO_MANAGER,
"Attempting to create object lock without lock manager"
},
{
ObjectManagerCodes::MANAGER_MISMATCH,
"Attempting to delete object lock from mismatched lock manager"
},
{
ObjectManagerCodes::LOCK_OVERFLOW,
"Too many object locks allocated"
},
{
ObjectManagerCodes::BAD_THREAD,
"Attempting operation from a bad thread"
}
});
}; // namespace nb

View File

@ -5,4 +5,30 @@
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
namespace NB {
static unsigned int __NB_GL_DEBUG_ERROR_CODE__;
static std::string formatDebugString(const std::string& msg, const std::string& file="", int line=-1) {
std::string ret = "";
if (file != "") {
ret += "In file " + file;
if (line >= 0) {
ret += " at line " + std::to_string(line);
}
ret += ":\n\t";
}
return ret + msg;
}
}
#define NB_GL_DEBUG_THROW(cmd, when) while(NB::__NB_GL_DEBUG_ERROR_CODE__=glGetError()){\
std::cout << "[GL ERROR]: " << NB::__NB_GL_DEBUG_ERROR_CODE__;\
std::cout << " " << when << " " << cmd << "\n";\
}
#define NB_GL_DEBUG(cmd) NB_GL_DEBUG_THROW(#cmd, "before"); cmd; NB_GL_DEBUG_THROW(#cmd, "after");
#endif

View File

@ -25,11 +25,7 @@ struct VertexAttribute {
VertexAttributeLayout layout;
};
struct VertexAttributePointer {
VertexAttribute attribute;
GLuint buffer;
GLuint index;
};
struct VertexAttributePointer;
static bool isIndexInVertexAttribute(int i, const VertexAttribute& va) {
if ((i -= va.layout.offset) < 0) { return false; }
@ -89,6 +85,12 @@ class VertexBuffer<true>
};
struct VertexAttributePointer {
VertexAttribute attribute;
VertexBuffer<false>* buffer;
GLuint index;
};
class VAO : public OpenGLObject {
using Base = OpenGLObject;
using Codes = VAOError::Codes;

View File

@ -9,7 +9,6 @@
#include <stdexcept>
#include <string>
#include <NBCore/Errors.hpp>
#include <NBCore/Utils.hpp>
namespace nb {
@ -19,32 +18,9 @@ public:
GLError(const std::string&);
};
class OpenGLError : public Error<OpenGLError> {
using Base = Error<OpenGLError>;
class WindowError : public std::runtime_error {
public:
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, INIT_FAILED, GLFW_INTIALIZED, GLAD_FAILED
};
static const std::string type;
static const ErrorCodeMap ErrorMessages;
};
class WindowError : public Error<WindowError> {
using Base = Error<WindowError>;
public:
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, INITIALIZED_WINDOW, NO_GLFW, INIT_FAILED
};
static const std::string type;
static const ErrorCodeMap ErrorMessages;
WindowError(const std::string&);
};
class Window {

View File

@ -38,7 +38,7 @@ VertexAttributePointerList VAO::attributes(const VertexAttributePointerList& att
_attrs = attrs_;
bind();
for (auto attr_ptr : attrs_) {
glBindBuffer(GL_ARRAY_BUFFER, attr_ptr.buffer);
attr_ptr.buffer->bind();
GLuint idx = attr_ptr.index;
glVertexAttribPointer(
idx,
@ -124,7 +124,7 @@ size_t VertexGroup::buffer(VertexBuffer<false>&& buf_) {
GLuint idx = attrs.size();
for (auto attr : buf_ptr->attributes) {
attrs.emplace_back(
VertexAttributePointer{attr, buf_ptr->id(),idx}
VertexAttributePointer{attr, buf_ptr,idx}
);
idx++;
}
@ -152,7 +152,7 @@ size_t VertexGroup::buffers(std::vector<VertexBuffer<false>>&& bufs_) {
for (auto buf : _vertex_data) {
for (auto attr : buf->attributes) {
attr_ptrs.emplace_back(
VertexAttributePointer{attr, buf->id(), idx}
VertexAttributePointer{attr, buf.get(), idx}
);
idx++;
}
@ -197,10 +197,10 @@ void VertexGroup::disableAttr(GLuint idx) {
}
void VertexGroup::disableBuffer(size_t idx) {
auto buf_idx = _vertex_data[idx]->id();
auto buf_ptr = _vertex_data[idx].get();
bind();
for (auto attr : _vao.attributes()) {
if (attr.buffer == buf_idx) {
if (attr.buffer == buf_ptr) {
_vao.disable(attr.index);
}
}
@ -208,10 +208,10 @@ void VertexGroup::disableBuffer(size_t idx) {
}
void VertexGroup::enableBuffer(size_t idx) {
auto buf_idx = _vertex_data[idx]->id();
auto buf_ptr = _vertex_data[idx].get();
bind();
for (auto attr : _vao.attributes()) {
if (attr.buffer == buf_idx) {
if (attr.buffer == buf_ptr) {
_vao.enable(attr.index);
}
}

View File

@ -16,26 +16,10 @@ static std::map<int, int> defailt_window_hints = {
#endif
};
using OpenGLErrorCodes = OpenGLError::Codes;
const std::string OpenGLError::type = "nb::OpenGLError";
const ErrorCodeMap OpenGLError::ErrorMessages = {
{OpenGLErrorCodes::UNDEFINED, "Error"},
{OpenGLErrorCodes::INIT_FAILED, "GLFW initialization failed"},
{OpenGLErrorCodes::GLFW_INTIALIZED, "GLFW has already been initialized"},
{OpenGLErrorCodes::GLAD_FAILED, "GLAD initialization failed"}
};
using WindowErrorCodes = WindowError::Codes;
const std::string WindowError::type = "nb::WindowError";
const ErrorCodeMap WindowError::ErrorMessages = {
{WindowErrorCodes::UNDEFINED, "Error"},
{WindowErrorCodes::INITIALIZED_WINDOW, "Window already initialized"},
{WindowErrorCodes::NO_GLFW, "GLFW has not been initialized"},
{WindowErrorCodes::INIT_FAILED, "Could not intialized window"}
};
GLError::GLError(const std::string& msg) : std::runtime_error(msg) {}
WindowError::WindowError(const std::string &msg) : std::runtime_error(msg) {}
int Window::getGLFWHint(int hint_key) {
if (GLFWHints.find(hint_key) == GLFWHints.end()) {
return 0;
@ -46,7 +30,7 @@ int Window::getGLFWHint(int hint_key) {
int Window::setGLFWHint(int hint_key, int hint_val) {
if (Window::_glfw_init) {
THROW(OpenGLError(OpenGLErrorCodes::GLFW_INTIALIZED));
throw GLError("Cannot set GLFW hint after window is initialized.");
} else {
GLFWHints[hint_key] = hint_val;
}
@ -76,7 +60,7 @@ Window::Window(const uint16_t x, const uint16_t y, const char* initName, GLFWmon
Window::_glfw_init = true;
} else {
if (Window::StrictInitialization) {
THROW(OpenGLError(OpenGLErrorCodes::INIT_FAILED));
throw GLError("Failed to load GLFW with glfwInit()="+std::to_string(glfwResponse)+".");
}
}
}
@ -119,7 +103,7 @@ int Window::getWindowHint(int hint_key) const {
int Window::setWindowHint(int hint_key, int hint_val) {
if (_init) {
THROW(WindowError(WindowErrorCodes::INITIALIZED_WINDOW));
throw WindowError("Cannot set window hint after window is initialized.");
} else {
windowHints[hint_key] = hint_val;
}
@ -128,7 +112,7 @@ int Window::setWindowHint(int hint_key, int hint_val) {
int Window::init() {
if (!_glfw_init) {
THROW(WindowError(WindowErrorCodes::NO_GLFW));
throw GLError("GLFW has not been initialized.");
}
for (const auto& hint : windowHints) {
glfwWindowHint(hint.first, hint.second);
@ -139,7 +123,7 @@ int Window::init() {
Window::WindowContexts.erase(window);
if (Window::WindowContexts.size()==0 && Window::_glfw_init) { glfwTerminate(); }
if (Window::StrictInitialization) {
THROW(WindowError(WindowErrorCodes::INIT_FAILED));
throw WindowError("Could not create window in glfwCreateWindow().");
}
}
glfwMakeContextCurrent(window);
@ -149,7 +133,10 @@ int Window::init() {
if (!gladResponse) {
Window::checkKillGLFW();
if (Window::StrictInitialization) {
THROW(OpenGLError(OpenGLErrorCodes::GLAD_FAILED));
throw GLError("Failed to load GLAD with \
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)="+\
std::to_string(gladResponse)+"."
);
}
}

View File

@ -9,8 +9,8 @@ if (NB_BUILD_TESTS)
target_link_libraries(TestWindow
NBCore
NBGraphics
# GTest::gtest_main
GTest::gtest_main
)
# gtest_discover_tests(TestWindow)
gtest_discover_tests(TestWindow)
endif()

View File

@ -1,18 +1,6 @@
#include "GLLoad.hpp"
// #define _NB_AUTOLOG
#include "VertexArray.hpp"
#include "Window.hpp"
#include <Buffers.hpp>
int main() {
nb::logger.log("Howdy!");
nb::Window window(200, 200, "Hello!");
window.setWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
window.setWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
window.init();
GLFWwindow* window_ptr = window.getWindow();
while(!glfwWindowShouldClose(window_ptr)) {}
return 0;
}