From edc0ef7203dd52421a5f877d9df68b7370c02048 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Fri, 16 Sep 2022 20:20:34 +0200 Subject: [PATCH] Everywhere: Update work in progress --- .clang-format | 6 +- assets/gfx/test-inverted.png | Bin 0 -> 5832 bytes assets/glsl/batch-font.frag | 1 + assets/glsl/batch-font.vert | 3 + script/lint-ci.sh | 16 +-- script/lint-clang-format.sh | 3 +- script/lint-shell-script.sh | 3 +- script/pre-commit.sh | 37 +++--- src/inferno/application.cpp | 24 +++- src/inferno/application.h | 43 ++++--- src/inferno/assert.h | 76 +++++++++++-- src/inferno/core.h | 5 +- src/inferno/event/event.h | 155 +++++++++++++------------- src/inferno/io/log.h | 3 + src/inferno/render/gltf.h | 19 ++++ src/inferno/scene/scene.cpp | 13 +++ src/inferno/scene/scene.h | 4 + src/inferno/script/cameracontroller.h | 1 + src/inferno/singleton.h | 6 +- 19 files changed, 284 insertions(+), 134 deletions(-) create mode 100644 assets/gfx/test-inverted.png diff --git a/.clang-format b/.clang-format index 5e21330..d3078a9 100644 --- a/.clang-format +++ b/.clang-format @@ -14,14 +14,17 @@ AlignTrailingComments: true AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: false +AllowShortLambdasOnASingleLine: All AlwaysBreakTemplateDeclarations: Yes +IndentPPDirectives: BeforeHash BraceWrapping: AfterEnum: false AfterFunction: true BeforeCatch: true BeforeElse: true + BeforeLambdaBody: false SplitEmptyRecord: false BreakBeforeBraces: Custom BreakInheritanceList: BeforeComma @@ -29,7 +32,8 @@ BreakInheritanceList: BeforeComma SpaceAfterTemplateKeyword: false SpaceInEmptyBlock: false NamespaceIndentation: None -Standard: c++11 +FixNamespaceComments: true +Standard: c++17 TabWidth: 4 UseTab: AlignWithSpaces ... diff --git a/assets/gfx/test-inverted.png b/assets/gfx/test-inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..a20fcd1b4b26a3f6a6806e565135825036bf4fec GIT binary patch literal 5832 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 M<{fRU=KaWj0= /dev/null 2>&1; then exit 1 fi -files=$(git ls-files -- '*.sh' ':!:inferno/vendor') +files="${1:-$(git --no-pager diff --cached --name-only)}" +files="$(echo "$files" | grep -E '\.sh$')" if [ -z "$files" ]; then echo "No .sh files to check." diff --git a/script/pre-commit.sh b/script/pre-commit.sh index 18e0b44..5b543bd 100755 --- a/script/pre-commit.sh +++ b/script/pre-commit.sh @@ -7,23 +7,24 @@ scriptName="$(basename "$0")" -help() { - b=$(tput bold) - u=$(tput smul) - nc=$(tput sgr0) +b="$(tput bold)" +u="$(tput smul)" +red="$(tput setf 4)" +n="$(tput sgr0)" +help() { cat << EOF -${b}NAME${nc} +${b}NAME${n} ${scriptName} - manage pre-commit hooks -${b}SYNOPSIS${nc} - ${b}${scriptName}${nc} ${u}COMMAND${nc} +${b}SYNOPSIS${n} + ${b}${scriptName}${n} ${u}COMMAND${n} -${b}COMMANDS${nc} - ${b}install${nc} +${b}COMMANDS${n} + ${b}install${n} Install all pre-commit hooks. - ${b}remove${nc} + ${b}remove${n} Remove all pre-commit hooks. EOF } @@ -31,8 +32,18 @@ EOF # Exit if no option is provided [ "$#" -eq 0 ] && help && exit 1 +if [ ! -d ".git" ]; then + echo "${b}${red}Error:${n} please run this script from the project root." >&2 + exit 1 +fi + +currentDir="$(pwd -P)" + +# Get the path from the project root to the script +subDir="$(dirname -- "$0")" + # Get the full path to this script while handling spaces and symlinks correctly -scriptPath="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" +scriptPath="$(cd -P -- "$subDir" && pwd -P)" cd "$scriptPath/.." || exit 1 hooks=" @@ -42,7 +53,7 @@ lint-ci.sh install() { echo "Installing pre-commit hooks" - preCommit=".git/hooks/pre-commit" + preCommit="$currentDir/.git/hooks/pre-commit" if ! test -f "$preCommit"; then touch "$preCommit" chmod +x "$preCommit" @@ -51,7 +62,7 @@ install() { for hook in $hooks; do sed -Ei "/$hook/d" "$preCommit" - sed -Ei "\$ a script/$hook" "$preCommit" + sed -Ei "\$ a $subDir/$hook" "$preCommit" done } diff --git a/src/inferno/application.cpp b/src/inferno/application.cpp index dd5bd1b..3caa73f 100644 --- a/src/inferno/application.cpp +++ b/src/inferno/application.cpp @@ -1,3 +1,5 @@ +#include "glm/gtc/type_ptr.hpp" // glm::make_mat4 + #include "inferno/application.h" #include "inferno/assert.h" #include "inferno/core.h" @@ -5,12 +7,14 @@ #include "inferno/event/event.h" #include "inferno/event/keyevent.h" #include "inferno/event/mouseevent.h" -#include "inferno/keycodes.h" +#include "inferno/io/gltffile.h" #include "inferno/io/input.h" #include "inferno/io/log.h" +#include "inferno/keycodes.h" #include "inferno/render/buffer.h" #include "inferno/render/context.h" #include "inferno/render/font.h" +#include "inferno/render/gltf.h" #include "inferno/render/renderer.h" #include "inferno/render/shader.h" #include "inferno/render/texture.h" @@ -18,6 +22,7 @@ #include "inferno/settings.h" #include "inferno/time.h" #include "inferno/window.h" +#include namespace Inferno { @@ -47,6 +52,20 @@ namespace Inferno { // Load assets m_font = FontManager::the().load("assets/fnt/dejavu-sans"); + + // auto bla = GlTFFile::read("assets/gltf/box.glb"); + // success() << "@" << bla.first.get() << "@"; + // auto bla2 = GlTFFile::read("assets/gltf/boxtextured.glb"); + // info() << "@" << bla2.first.get() << "@"; + // auto bla3 = GlTFFile::read("assets/gltf/guinea-pig-cage-fleece.glb"); + // warn() << "@" << bla3.first.get() << "@"; + + // Gltf model = Gltf("assets/gltf/box.glb"); + + // Gltf model = Gltf("assets/gltf/animatedmorphcube.glb"); + // Gltf model = Gltf("assets/gltf/reciprocatingsaw.glb"); + + Gltf model = Gltf("assets/gltf/triangle-without-indices.gltf"); } Application::~Application() @@ -138,7 +157,7 @@ namespace Inferno { RendererCharacter::the().beginScene(); m_scene->render(); - RendererCharacter::the().drawCharacter(character, f->texture()); + // RendererCharacter::the().drawCharacter(character, f->texture()); Renderer2D::the().endScene(); RendererCharacter::the().endScene(); @@ -167,6 +186,7 @@ namespace Inferno { (void)e; info() << "WindowCloseEvent triggered"; + infoln("{}Event triggered", e.toString()); m_window->setShouldClose(true); diff --git a/src/inferno/application.h b/src/inferno/application.h index 25606a4..6dfb234 100644 --- a/src/inferno/application.h +++ b/src/inferno/application.h @@ -53,37 +53,48 @@ namespace Inferno { #endif // APPLICATION_H // C++17 features used: -// - std::string:view, log.h -// - std::shared_ptr array management, renderer.h +// - std::string_view -> log.h +// - std::shared_ptr array management -> renderer.h +// - EnTT library +// - structured binding -> render.cpp, camera.cpp +// - std::optional -> textareasystem.cpp // OpenGL 4.5 features used: // - +// Cmake 3.16 features used: +// - Precompiled headers + // Gameplan -// v Entrypoint -// v Logging -// v Events -// v Window -// v Settings loader (json) -// v Input polling -// v OpenGL context // - GPUDriver (?) // v Renderer // v Buffers // ~ Shader // - Schene (camera, lights, environment) -// - Texture loading // - Model loading -// - Entity Component System // - Serialization // - Level format // - Tools (Tiled?) -// - Scripting (Lua) -// - Global object access can be done in 3 ways: -// - Singleton, static, extern +// - Global object access can be done in 4 ways: +// - Singleton, static class, extern, regular global // @Todo -// - Settings should contain all file paths (ex: shaders) // - RefPtr<> -// - Rename Application::get() to Application::the() for singleton +// - keycodes.h stringify helper in code.h (util/types.h, util/defines.h) +// https://github.com/SerenityOS/serenity/blob/master/Kernel/Assertions.h#L29 +// - Call delete on pointers that make the singletons, so valgrind will say "All heap blocks were freed -- no leaks are possible", in "HEAP SUMMARY" +// - TagComponent, string -> char[] +// - Move Gltf parsing and json helper to /parser directory + +// - Initialize primitive types, raw pointers are uninitialized, so need to be explicitly initialized to nullptr +// - Run clang-format on every file + +// profiling: 1:33:08 - JS bytecode VM part 7 +// $ valgrind --tool=callgrind +// $ kcachegrind callgrind.out. + +// GUI +// Framebuffer on entire screen, manage every individual pixel +// - classes: Window, Button, Label +// - event loop: select based diff --git a/src/inferno/assert.h b/src/inferno/assert.h index 1c76171..eb27b23 100644 --- a/src/inferno/assert.h +++ b/src/inferno/assert.h @@ -3,6 +3,10 @@ #include // raise #include // uint32_t +#include // fflush +#include // strlen +#include // ifstream +#include #include "inferno/core.h" #include "inferno/io/log.h" @@ -15,50 +19,98 @@ #ifdef NF_ENABLE_ASSERTS // Check if SIGTRAP is available #ifdef SIGTRAP - #define ABORT_SIGNAL SIGTRAP + #define ABORT_SIGNAL SIGTRAP // POSIX #else - #define ABORT_SIGNAL SIGABRT + #define ABORT_SIGNAL SIGABRT // C99 #endif // Non-standard function macro #ifdef GCC - #define FUNCTION_MACRO __PRETTY_FUNCTION__ + #define FUNCTION_MACRO __PRETTY_FUNCTION__ // GCC extension #elif MSVC #define FUNCTION_MACRO __FUNCSIG__ #else - #define FUNCTION_MACRO __func__ + #define FUNCTION_MACRO __func__ // C99 #endif // ##__VA_ARGS__ is a non-standard GCC extension, C++20 introduces __VA_OPT__ // https://stackoverflow.com/questions/52891546/what-does-va-args-mean - #define ASSERT(expr, ...) static_cast(expr) ? (void)0 : Inferno::__assert_fail(#expr, __FILE__, __LINE__, FUNCTION_MACRO, ##__VA_ARGS__) + #define ASSERT(expr, ...) (static_cast(expr) ? (void)0 : Inferno::__assert_fail(#expr, __FILE__, __LINE__, FUNCTION_MACRO, ##__VA_ARGS__)) #define ASSERT_NOT_REACHED() ASSERT(false) #else - #define ASSERT(expr, ...) + #define ASSERT(expr, ...) (static_cast(0)) #define ASSERT_NOT_REACHED() CRASH() #endif -#define CRASH() raise(SIGABRT) +#define CRASH() Inferno::__crash(); +// https://stackoverflow.com/questions/1440570/likely-unlikely-equivalent-for-msvc namespace Inferno { +inline void __crash() +{ + asm volatile("int $0x03"); +} + + // FIXME: Doesnt print to stderr #ifdef NF_ENABLE_ASSERTS template inline void __assert_fail(const char* assertion, const char* file, uint32_t line, const char* function, P&&... parameters) { - dangerln(false, "ASSERTION `{}' FAILED.", assertion); + (void)function; + + // Get the line that caused the error + std::ifstream source(file); + std::string content; + if (source.is_open()) { + for (uint32_t i = 0; std::getline(source, content); ++i) { + if (i == line - 1) { + break; + } + } + } + // Replace tab indentation with spaces + size_t tabs = content.find_first_not_of('\t'); + if (tabs > 0 && tabs < content.size()) { + content = std::string(tabs * 4, ' ') + content.substr(tabs); + } + // Find the assertion in the line + size_t column = content.find_first_of(assertion); + size_t assertionLength = strlen(assertion); + if (column == std::string::npos) { + column = content.find_first_not_of(' '); + assertionLength = content.length() - column; + } + + // Error message + dbgln(false, "\033[0;1m{}:{}:{}: ", file, line, column + 1); + dangerln(false, "error: "); + dbgln(false, "assertion failed"); if (sizeof...(P) > 0) { - dbg(false) << " "; - dbgln(Log::Danger, false, std::forward

(parameters)...); + dbgln(false, ": "); + dbgln(Log::None, false, std::forward

(parameters)...); } - danger() << "\n " << file << ":" << line << " in " << function; + // Code line + dbgln("\n {} | {}\033[31;1m{}\033[0m{}", line, + content.substr(0, column), // Whitespace at front + content.substr(column, assertionLength), // Error portion + content.substr(column + assertionLength)); // Rest of the line - raise(ABORT_SIGNAL); + // Arrow pointer + dbgln(" {} | {}\033[31;1m^{}\033[0m", + std::string(std::to_string(line).length(), ' '), // Line number spacing + std::string(column, ' '), // Content spacing + std::string(assertionLength - 1, '~')); // Arrow pointer + + fflush(stdout); // FIXME: stdout is buffered, strerr is not so wouldnt need this + CRASH(); } #endif } #endif // ASSERT_H + +// https://github.com/scottt/debugbreak diff --git a/src/inferno/core.h b/src/inferno/core.h index e3f7266..ac78e98 100644 --- a/src/inferno/core.h +++ b/src/inferno/core.h @@ -1,10 +1,13 @@ #ifndef CORE_H #define CORE_H -#include // std::bind +#include // std::bind, std::placeholders #define BIT(x) (1 << x) +// @Todo figure out lambda's and replace std::bind +// https://github.com/TheCherno/Hazel/pull/277 +// variadic args in lambdas were added in C++17 #define NF_BIND_EVENT(f) std::bind(&f, this, std::placeholders::_1) // Compiler diff --git a/src/inferno/event/event.h b/src/inferno/event/event.h index da76162..9af4a40 100644 --- a/src/inferno/event/event.h +++ b/src/inferno/event/event.h @@ -7,105 +7,108 @@ namespace Inferno { - enum class EventType { - None = 0, +enum class EventType { + None = 0, - WindowClose, - WindowResize, + WindowClose, + WindowResize, - KeyPress, - KeyRelease, - KeyRepeat, + KeyPress, + KeyRelease, + KeyRepeat, - MouseButtonPress, - MouseButtonRelease, - MousePosition, - MouseScroll, + MouseButtonPress, + MouseButtonRelease, + MousePosition, + MouseScroll, - JoystickConnected, - JoystickDisconnected, - }; + JoystickConnected, + JoystickDisconnected, +}; - enum EventCategory { - None = 0, - ApplicationEventCategory = BIT(0), +enum EventCategory { + None = 0, + ApplicationEventCategory = BIT(0), - InputEventCategory = BIT(1), + InputEventCategory = BIT(1), - KeyEventCategory = BIT(2), + KeyEventCategory = BIT(2), - MouseEventCategory = BIT(3), - MouseButtonEventCategory = BIT(4), + MouseEventCategory = BIT(3), + MouseButtonEventCategory = BIT(4), - JoystickEventCatergory = BIT(5), - }; + JoystickEventCatergory = BIT(5), +}; - class Event { - // EventDispatcher is allowed to access Event private/protected members - friend class EventDispatcher; +class Event { + // EventDispatcher is allowed to access Event private/protected members + friend class EventDispatcher; - public: - virtual ~Event() {} +public: + virtual ~Event() {} - virtual std::string toString() const { return getName(); } + virtual std::string toString() const { return getName(); } - inline bool inCategory(EventCategory category) - { - return getCategoryFlags() & category; - } + inline bool inCategory(EventCategory category) + { + return getCategoryFlags() & category; + } + + // ----------------------------------------- + + // Getter function templates + virtual char getCategoryFlags() const = 0; + virtual const char* getName() const = 0; + virtual EventType getType() const = 0; + +private: + bool handled = false; +}; + +class EventDispatcher { +public: + EventDispatcher(Event& e) + : m_event(e) + { + } -// ----------------------------------------- - - // Getter function templates - virtual char getCategoryFlags() const = 0; - virtual const char* getName() const = 0; - virtual EventType getType() const = 0; - - private: - bool handled = false; - }; - - class EventDispatcher { - public: - EventDispatcher(Event& e) : m_event(e) {} - - // Easily dispatch all type of Events, call with: - // dispatch(std::bind(&F, this, std::placeholders::_1)); - // T is the type of Event - // F is the function to call, signature: bool name(T& e); - template - bool dispatch(const F& function) - { - // If type is same as member variable type - if (T::getTypeStatic() == m_event.getType()) { - // Call the function - m_event.handled = function(static_cast(m_event)); - return true; - } - - return false; + // Easily dispatch all type of Events, call with: + // dispatch(std::bind(&F, this, std::placeholders::_1)); + // T is the type of Event + // F is the function to call, signature: bool name(T& e); + template + bool dispatch(const F& function) + { + // If type is same as member variable type + if (T::getTypeStatic() == m_event.getType()) { + // Call the function + m_event.handled = function(static_cast(m_event)); + return true; } - private: - Event& m_event; - }; + return false; + } + +private: + Event& m_event; +}; - // Add class type functions macro -#define EVENT_CLASS_TYPE(type) \ - virtual const char* getName() const override { return #type; } \ +// Add class type functions macro +#define EVENT_CLASS_TYPE(type) \ + virtual const char* getName() const override { return #type; } \ virtual EventType getType() const override { return getTypeStatic(); } \ static inline EventType getTypeStatic() { return EventType::type; } - // Add class catergory function macro +// Add class category function macro #define EVENT_CLASS_CATEGORY(category) \ virtual char getCategoryFlags() const override { return category; } - // Make Events easily printable - inline std::ostream& operator<<(std::ostream& os, const Event& e) - { - return os << e.toString(); - } - +// Make Events easily printable +inline std::ostream& operator<<(std::ostream& os, const Event& e) +{ + return os << e.toString(); } +} // namespace Inferno + #endif // EVENT_H diff --git a/src/inferno/io/log.h b/src/inferno/io/log.h index afaa36c..32269c4 100644 --- a/src/inferno/io/log.h +++ b/src/inferno/io/log.h @@ -152,6 +152,7 @@ namespace Inferno { // ----------------------------------------- + // clang-format off template void dbgln(const char* format, P&&... parameters) { dbgln(Log::None, true, format, std::forward

(parameters)...); } template void infoln(const char* format, P&&... parameters) { dbgln(Log::Info, true, format, std::forward

(parameters)...); } template void warnln(const char* format, P&&... parameters) { dbgln(Log::Warn, true, format, std::forward

(parameters)...); } @@ -193,6 +194,7 @@ namespace Inferno { template void dangerln(bool newline, const std::string_view& format, P&&... parameters) { dbgln(Log::Danger, newline, format.data(), std::forward

(parameters)...); } template void successln(bool newline, const std::string_view& format, P&&... parameters) { dbgln(Log::Success, newline, format.data(), std::forward

(parameters)...); } template void commentln(bool newline, const std::string_view& format, P&&... parameters) { dbgln(Log::Comment, newline, format.data(), std::forward

(parameters)...); } + // clang-format on // ----------------------------------------- @@ -214,6 +216,7 @@ namespace Inferno { } } } + // possible c++17 improvent https://riptutorial.com/cplusplus/example/3208/iterating-over-a-parameter-pack // ----------------------------------------- diff --git a/src/inferno/render/gltf.h b/src/inferno/render/gltf.h index 3101d13..32fcceb 100644 --- a/src/inferno/render/gltf.h +++ b/src/inferno/render/gltf.h @@ -10,6 +10,25 @@ #include "inferno/singleton.h" #include "inferno/util/json.h" +#define GLTF_TYPE_SCALAR 1 +#define GLTF_TYPE_VEC2 2 +#define GLTF_TYPE_VEC3 3 +#define GLTF_TYPE_VEC4 4 +#define GLTF_TYPE_MAT2 8 +#define GLTF_TYPE_MAT3 12 +#define GLTF_TYPE_MAT4 16 + +#define GLTF_COMPONENT_TYPE_BYTE 5120 +#define GLTF_COMPONENT_TYPE_UNSIGNED_BYTE 5121 +#define GLTF_COMPONENT_TYPE_SHORT 5122 +#define GLTF_COMPONENT_TYPE_UNSIGNED_SHORT 5123 +#define GLTF_COMPONENT_TYPE_INT 5124 +#define GLTF_COMPONENT_TYPE_UNSIGNED_INT 5125 +#define GLTF_COMPONENT_TYPE_FLOAT 5126 + +#define GLTF_TARGET_ARRAY_BUFFER 34962 +#define GLTF_TARGET_ELEMENT_ARRAY_BUFFER 34963 + namespace Inferno { namespace glTF { diff --git a/src/inferno/scene/scene.cpp b/src/inferno/scene/scene.cpp index d0c4798..27914ae 100644 --- a/src/inferno/scene/scene.cpp +++ b/src/inferno/scene/scene.cpp @@ -4,12 +4,14 @@ #include "inferno/component/nativescriptcomponent.h" #include "inferno/component/spritecomponent.h" #include "inferno/component/tagcomponent.h" +#include "inferno/component/textareacomponent.h" #include "inferno/scene/scene.h" #include "inferno/script/cameracontroller.h" #include "inferno/script/nativescript.h" #include "inferno/system/camerasystem.h" #include "inferno/system/rendersystem.h" #include "inferno/system/scriptsystem.h" +#include "inferno/system/textareasystem.h" #include "inferno/system/transformsystem.h" namespace Inferno { @@ -33,6 +35,9 @@ namespace Inferno { ScriptSystem::initialize(); ScriptSystem::the().setScene(this); + TextAreaSystem::initialize(); + TextAreaSystem::the().setScene(this); + // Load assets // --------------------------------- @@ -44,6 +49,9 @@ namespace Inferno { uint32_t camera = createEntity("Camera Entity"); auto& cameraTransform = getComponent(camera); + // cameraTransform.rotate.z = 0.0f; + // cameraTransform.translate.z = -1.0f; + // addComponent(camera, CameraType::Orthographic); cameraTransform.rotate.z = -1.0f; cameraTransform.translate.z = 1.0f; addComponent(camera, CameraType::Perspective); @@ -63,6 +71,10 @@ namespace Inferno { quad3Transform.translate.x = 2.2f; addComponent(quad3, glm::vec4 { 1.0f, 1.0f, 1.0f, 1.0f }, m_texture2); + uint32_t text = createEntity("Text"); + addComponent(text, "HelloWorld!", "assets/fnt/dejavu-sans", 0, 150, 3); + // addComponent(text, "@#$%^&*()qygij!", "assets/fnt/dejavu-sans-test", 0, 150, 3); + info() << "Scene initialized"; } @@ -77,6 +89,7 @@ namespace Inferno { void Scene::render() { RenderSystem::the().render(); + TextAreaSystem::the().render(); } void Scene::destroy() diff --git a/src/inferno/scene/scene.h b/src/inferno/scene/scene.h index e8e109e..d5befaf 100644 --- a/src/inferno/scene/scene.h +++ b/src/inferno/scene/scene.h @@ -82,3 +82,7 @@ namespace Inferno { } #endif // SCENE_H + +// @Todo +// - Convert registry to stack variable +// - Convert registry to scene pointer in systems diff --git a/src/inferno/script/cameracontroller.h b/src/inferno/script/cameracontroller.h index fec8806..390d2eb 100644 --- a/src/inferno/script/cameracontroller.h +++ b/src/inferno/script/cameracontroller.h @@ -1,6 +1,7 @@ #ifndef CAMERA_CONTROLLER_H #define CAMERA_CONTROLLER_H +#include "inferno/component/cameracomponent.h" #include "inferno/script/nativescript.h" #define TRANSLATE_SPEED 2.5f diff --git a/src/inferno/singleton.h b/src/inferno/singleton.h index 670b2c3..53d3fc5 100644 --- a/src/inferno/singleton.h +++ b/src/inferno/singleton.h @@ -13,20 +13,20 @@ namespace Inferno { public: static inline void initialize() { - ASSERT(!s_instance, "Singleton already exists!"); + ASSERT(!s_instance, "singleton already exists"); s_instance = new T { s {} }; } static inline void destroy() { - ASSERT(s_instance, "Singleton does not exist!"); + ASSERT(s_instance, "singleton does not exist"); delete s_instance; s_instance = nullptr; } static inline T& the() { - ASSERT(s_instance, "Singleton does not exist!"); + ASSERT(s_instance, "singleton does not exist"); return *s_instance; }