2024-04-13 14:38:26 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../DefaultInclude.hpp"
|
2024-07-24 13:41:52 -04:00
|
|
|
#include <exception>
|
2024-04-13 14:38:26 -04:00
|
|
|
|
|
|
|
namespace geode {
|
|
|
|
class Mod;
|
2024-06-02 20:13:05 -04:00
|
|
|
Mod* getMod();
|
2024-04-13 14:38:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace geode::utils {
|
2024-04-14 10:57:15 -04:00
|
|
|
#ifdef GEODE_IS_WINDOWS
|
|
|
|
static constexpr size_t GEODE_TERMINATE_EXCEPTION_CODE = 0x4000;
|
|
|
|
static constexpr size_t GEODE_UNREACHABLE_EXCEPTION_CODE = 0x4001;
|
|
|
|
|
|
|
|
static constexpr bool isGeodeExceptionCode(size_t code) {
|
|
|
|
return GEODE_TERMINATE_EXCEPTION_CODE <= code && code <= GEODE_UNREACHABLE_EXCEPTION_CODE;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static constexpr size_t GEODE_TERMINATE_EXCEPTION_CODE = 0;
|
|
|
|
static constexpr size_t GEODE_UNREACHABLE_EXCEPTION_CODE = 0;
|
|
|
|
|
|
|
|
static constexpr bool isGeodeExceptionCode(size_t code) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-04-13 14:38:26 -04:00
|
|
|
namespace detail {
|
|
|
|
// This needs to do stuff with `Mod*` which is not included in the file
|
2024-06-02 20:08:32 -04:00
|
|
|
GEODE_DLL void logTerminationError(const char* reason, Mod* mod);
|
2024-04-13 14:38:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class = void>
|
|
|
|
[[noreturn]]
|
2024-04-14 11:04:01 -04:00
|
|
|
void terminate(std::string const& reason, Mod* mod = getMod(), size_t platformCode = GEODE_TERMINATE_EXCEPTION_CODE) {
|
2024-04-13 14:38:26 -04:00
|
|
|
// Add the error to the logfile
|
2024-06-02 20:08:32 -04:00
|
|
|
detail::logTerminationError(reason.c_str(), mod);
|
2024-04-13 14:38:26 -04:00
|
|
|
|
|
|
|
#ifdef GEODE_IS_WINDOWS
|
|
|
|
// If a debugger is attached, start debugging
|
|
|
|
if (IsDebuggerPresent()) {
|
|
|
|
OutputDebugStringA(reason.c_str());
|
|
|
|
DebugBreak();
|
|
|
|
}
|
2024-04-14 10:57:15 -04:00
|
|
|
// Otherwise terminate by raising an exception (which is caught by the crashlog handler)
|
2024-04-13 14:38:26 -04:00
|
|
|
else {
|
2024-04-14 10:57:15 -04:00
|
|
|
std::array<const void*, 2> errorList { static_cast<const void*>(reason.c_str()), mod };
|
|
|
|
RaiseException(
|
|
|
|
platformCode,
|
|
|
|
EXCEPTION_NONCONTINUABLE,
|
|
|
|
2, reinterpret_cast<ULONG_PTR*>(errorList.data())
|
|
|
|
);
|
2024-04-13 14:38:26 -04:00
|
|
|
}
|
|
|
|
#endif
|
2024-06-06 11:43:12 -04:00
|
|
|
|
|
|
|
std::terminate();
|
2024-04-13 14:38:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class = void>
|
|
|
|
[[noreturn]]
|
2024-04-14 11:04:01 -04:00
|
|
|
void unreachable(std::string const& reason = "Unspecified", Mod* mod = getMod()) {
|
|
|
|
terminate(reason, mod, GEODE_UNREACHABLE_EXCEPTION_CODE);
|
2024-04-13 14:38:26 -04:00
|
|
|
}
|
|
|
|
}
|