Program Listing for File Exceptions.hpp

Return to documentation for file (engine/include/Cacao/Exceptions.hpp)

#pragma once

#include "DllHelper.hpp"
#include "Log.hpp"

#include <functional>
#include <string>
#include <sstream>

namespace Cacao {

    class CACAO_API Exception : public std::exception {
      public:
        const char* what() const noexcept final override {
            return msg.c_str();
        }

      protected:
        std::string msg;

        Exception() : msg("") {}
        virtual ~Exception() {}
    };

#define DEF_EXCEPTION(cls, tp)                                   \
    class CACAO_API cls##Exception : public Exception {          \
      public:                                                    \
        cls##Exception(std::string m) : Exception() {            \
            msg = makeMsg(m);                                    \
        }                                                        \
        ~cls##Exception() {}                                     \
        std::string makeMsg(const std::string& m) {              \
            std::stringstream ss;                                \
            ss << "(Cacao Engine " << tp << " Exception) " << m; \
            return ss.str();                                     \
        }                                                        \
    };

    DEF_EXCEPTION(External, "External")
    DEF_EXCEPTION(FileNotFound, "File Not Found")
    DEF_EXCEPTION(IO, "I/O")
    DEF_EXCEPTION(FileOpen, "File Open")
    DEF_EXCEPTION(InvalidYAML, "Invalid YAML")
    DEF_EXCEPTION(BadInitState, "Bad Initialization State")
    DEF_EXCEPTION(BadRealizeState, "Bad Realization State")
    DEF_EXCEPTION(BadState, "Bad State")
    DEF_EXCEPTION(BadThread, "Bad Thread")
    DEF_EXCEPTION(BadType, "Bad Type")
    DEF_EXCEPTION(BadValue, "Bad Value")
    DEF_EXCEPTION(NonexistentValue, "Nonexistent Value")
    DEF_EXCEPTION(ExistingValue, "Existing Value")
    DEF_EXCEPTION(Misc, "Miscellaneous")

#undef DEF_EXCEPTION


    template<typename E>
        requires std::is_base_of_v<Exception, E>
    CACAO_API void Check(bool condition, std::string message, std::function<void()> unwindFn = []() {}) {
        if(!condition) {
            unwindFn();
            E ex(message);
            Logger::Engine(Logger::Level::Error) << ex.what();
            throw ex;
        }
    }

    template<typename P, typename E>
        requires std::is_base_of_v<Exception, E>
    CACAO_API void Check(std::shared_ptr<P> ptr, std::string message, std::function<void()> unwindFn = []() {}) {
        Check<E>((bool)ptr, message, unwindFn);
    }
}