feat: update Filament to v1.56.4

This commit is contained in:
Nick Fisher
2025-01-07 08:27:19 +08:00
parent b1c0d4b2e8
commit 020bfbcbf6
60 changed files with 1772 additions and 21074 deletions

View File

@@ -17,14 +17,28 @@
#ifndef TNT_UTILS_PANIC_H
#define TNT_UTILS_PANIC_H
#ifdef FILAMENT_PANIC_USES_ABSL
# if FILAMENT_PANIC_USES_ABSL
# include "absl/log/log.h"
# define FILAMENT_CHECK_PRECONDITION CHECK
# define FILAMENT_CHECK_POSTCONDITION CHECK
# define FILAMENT_CHECK_ARITHMETIC CHECK
# endif
#endif
#include <utils/CallStack.h>
#include <utils/compiler.h>
#include <utils/sstream.h>
#include <string>
#include <string_view>
#ifdef __EXCEPTIONS
# define UTILS_EXCEPTIONS 1
#else
# ifdef UTILS_EXCEPTIONS
# error UTILS_EXCEPTIONS is already defined!
# endif
#endif
/**
@@ -250,42 +264,83 @@ namespace utils {
*/
class UTILS_PUBLIC Panic {
public:
using PanicHandlerCallback = void(*)(void* user, Panic const& panic);
/**
* Sets a user-defined handler for the Panic. If exceptions are enabled, the concrete Panic
* object will be thrown upon return; moreover it is acceptable to throw from the provided
* callback, but it is unsafe to throw the Panic object itself, since it's just an interface.
* It is also acceptable to abort from the callback. If exceptions are not enabled, std::abort()
* will be automatically called upon return.
*
* The PanicHandlerCallback can be called from any thread.
*
* Caveat: this API can misbehave if is used as a static library in multiple translation units,
* some of these translation units might not see the callback.
*
* @param handler pointer to the user defined handler for the Panic
* @param user user pointer given back to the callback
*/
static void setPanicHandler(PanicHandlerCallback handler, void* user) noexcept;
virtual ~Panic() noexcept;
/**
* @return a detailed description of the error
* @return a formatted and detailed description of the error including all available
* information.
* @see std::exception
*/
virtual const char* what() const noexcept = 0;
/**
* Get the function name where the panic was detected
* Get the type of the panic (e.g. "Precondition")
* @return a C string containing the type of panic
*/
virtual const char* getType() const noexcept = 0;
/**
* Get the reason string for the panic
* @return a C string containing the reason for the panic
*/
virtual const char* getReason() const noexcept = 0;
/**
* Get a version of the reason string that is guaranteed to be constructed from literal
* strings only; it will contain no runtime information.
*/
virtual const char* getReasonLiteral() const noexcept = 0;
/**
* Get the function name where the panic was detected. On debug build the fully qualified
* function name is returned; on release builds only the function name is.
* @return a C string containing the function name where the panic was detected
*/
virtual const char* getFunction() const noexcept = 0;
/**
* Get the file name where the panic was detected
* Get the file name where the panic was detected. Only available on debug builds.
* @return a C string containing the file name where the panic was detected
*/
virtual const char* getFile() const noexcept = 0;
/**
* Get the line number in the file where the panic was detected
* Get the line number in the file where the panic was detected. Only available on debug builds.
* @return an integer containing the line number in the file where the panic was detected
*/
virtual int getLine() const noexcept = 0;
/**
* Logs this exception to the system-log
*/
virtual void log() const noexcept = 0;
/**
* Get the CallStack when the panic was detected
* Get the CallStack when the panic was detected if available.
* @return the CallStack when the panic was detected
*/
virtual const CallStack& getCallStack() const noexcept = 0;
/**
* Logs this exception to the system-log
*/
virtual void log() const noexcept = 0;
};
// -----------------------------------------------------------------------------------------------
@@ -305,6 +360,9 @@ public:
const char* what() const noexcept override;
// Panic interface
const char* getType() const noexcept override;
const char* getReason() const noexcept override;
const char* getReasonLiteral() const noexcept override;
const char* getFunction() const noexcept override;
const char* getFile() const noexcept override;
int getLine() const noexcept override;
@@ -318,13 +376,14 @@ public:
* @param function the name of the function where the error was detected
* @param file the file where the above function in implemented
* @param line the line in the above file where the error was detected
* @param literal a literal version of the error message
* @param format printf style string describing the error
* @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC
* @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC
* @see setMode()
*/
static void panic(char const* function, char const* file, int line, const char* format, ...)
UTILS_NORETURN;
static void panic(char const* function, char const* file, int line, char const* literal,
const char* format, ...) UTILS_NORETURN;
/**
* Depending on the mode set, either throws an exception of type T with the given reason plus
@@ -333,43 +392,41 @@ public:
* @param function the name of the function where the error was detected
* @param file the file where the above function in implemented
* @param line the line in the above file where the error was detected
* @param s std::string describing the error
* @param literal a literal version of the error message
* @param reason std::string describing the error
* @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC
* @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC
* @see setMode()
*/
static inline void panic(char const* function, char const* file, int line, const std::string& s)
UTILS_NORETURN {
panic(function, file, line, s.c_str());
}
static inline void panic(
char const* function, char const* file, int line, char const* literal,
std::string reason) UTILS_NORETURN;
protected:
/**
* Creates a Panic.
* @param reason a description of the cause of the error
*/
explicit TPanic(std::string reason);
/**
* Creates a Panic with extra information about the error-site.
* @param function the name of the function where the error was detected
* @param file the file where the above function in implemented
* @param line the line in the above file where the error was detected
* @param literal a literal version of the error message
* @param reason a description of the cause of the error
*/
TPanic(char const* function, char const* file, int line, std::string reason);
TPanic(char const* function, char const* file, int line, char const* literal,
std::string reason);
~TPanic() override;
private:
void buildMessage();
CallStack m_callstack;
std::string m_reason;
char const* const m_function = nullptr;
char const* const m_file = nullptr;
const int m_line = -1;
mutable std::string m_msg;
char const* const mFile = nullptr; // file where the panic happened
char const* const mFunction = nullptr; // function where the panic happened
int const mLine = -1; // line where the panic happened
std::string mLiteral; // reason for the panic, built only from literals
std::string mReason; // reason for the panic
mutable std::string mWhat; // fully formatted reason
CallStack mCallstack;
};
namespace details {
@@ -391,6 +448,7 @@ class UTILS_PUBLIC PreconditionPanic : public TPanic<PreconditionPanic> {
// e.g.: invalid arguments
using TPanic<PreconditionPanic>::TPanic;
friend class TPanic<PreconditionPanic>;
constexpr static auto type = "Precondition";
};
/**
@@ -404,6 +462,7 @@ class UTILS_PUBLIC PostconditionPanic : public TPanic<PostconditionPanic> {
// e.g.: dead-lock would occur, arithmetic errors
using TPanic<PostconditionPanic>::TPanic;
friend class TPanic<PostconditionPanic>;
constexpr static auto type = "Postcondition";
};
/**
@@ -417,8 +476,74 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
// e.g.: underflow, overflow, internal computations errors
using TPanic<ArithmeticPanic>::TPanic;
friend class TPanic<ArithmeticPanic>;
constexpr static auto type = "Arithmetic";
};
namespace details {
struct Voidify final {
template<typename T>
void operator&&(const T&) const&& {}
};
class UTILS_PUBLIC PanicStream {
public:
PanicStream(
char const* function,
char const* file,
int line,
char const* message) noexcept;
~PanicStream();
PanicStream& operator<<(short value) noexcept;
PanicStream& operator<<(unsigned short value) noexcept;
PanicStream& operator<<(char value) noexcept;
PanicStream& operator<<(unsigned char value) noexcept;
PanicStream& operator<<(int value) noexcept;
PanicStream& operator<<(unsigned int value) noexcept;
PanicStream& operator<<(long value) noexcept;
PanicStream& operator<<(unsigned long value) noexcept;
PanicStream& operator<<(long long value) noexcept;
PanicStream& operator<<(unsigned long long value) noexcept;
PanicStream& operator<<(float value) noexcept;
PanicStream& operator<<(double value) noexcept;
PanicStream& operator<<(long double value) noexcept;
PanicStream& operator<<(bool value) noexcept;
PanicStream& operator<<(const void* value) noexcept;
PanicStream& operator<<(const char* string) noexcept;
PanicStream& operator<<(const unsigned char* string) noexcept;
PanicStream& operator<<(std::string const& s) noexcept;
PanicStream& operator<<(std::string_view const& s) noexcept;
protected:
io::sstream mStream;
char const* mFunction;
char const* mFile;
int mLine;
char const* mLiteral;
};
template<typename T>
class TPanicStream : public PanicStream {
public:
using PanicStream::PanicStream;
~TPanicStream() noexcept(false) UTILS_NORETURN {
T::panic(mFunction, mFile, mLine, mLiteral, mStream.c_str());
}
};
} // namespace details
// -----------------------------------------------------------------------------------------------
} // namespace utils
@@ -430,37 +555,70 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
# define PANIC_FUNCTION __func__
#endif
#define FILAMENT_CHECK_CONDITION_IMPL(cond) \
switch (0) \
case 0: \
default: \
UTILS_LIKELY(cond) ? (void)0 : ::utils::details::Voidify()&&
#define FILAMENT_PANIC_IMPL(message, TYPE) \
::utils::details::TPanicStream<::utils::TYPE>(PANIC_FUNCTION, PANIC_FILE(__FILE__), __LINE__, message)
#ifndef FILAMENT_CHECK_PRECONDITION
#define FILAMENT_CHECK_PRECONDITION(condition) \
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PreconditionPanic)
#endif
#ifndef FILAMENT_CHECK_POSTCONDITION
#define FILAMENT_CHECK_POSTCONDITION(condition) \
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PostconditionPanic)
#endif
#ifndef FILAMENT_CHECK_ARITHMETIC
#define FILAMENT_CHECK_ARITHMETIC(condition) \
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, ArithmeticPanic)
#endif
#define PANIC_PRECONDITION_IMPL(cond, format, ...) \
::utils::PreconditionPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
#define PANIC_POSTCONDITION_IMPL(cond, format, ...) \
::utils::PostconditionPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
#define PANIC_ARITHMETIC_IMPL(cond, format, ...) \
::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
#define PANIC_LOG_IMPL(cond, format, ...) \
::utils::details::panicLog(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
/**
* PANIC_PRECONDITION is a macro that reports a PreconditionPanic
* @param format printf-style string describing the error in more details
*/
#define PANIC_PRECONDITION(format, ...) \
::utils::PreconditionPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
#define PANIC_PRECONDITION(format, ...) PANIC_PRECONDITION_IMPL(format, format, ##__VA_ARGS__)
/**
* PANIC_POSTCONDITION is a macro that reports a PostconditionPanic
* @param format printf-style string describing the error in more details
*/
#define PANIC_POSTCONDITION(format, ...) \
::utils::PostconditionPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
#define PANIC_POSTCONDITION(format, ...) PANIC_POSTCONDITION_IMPL(format, format, ##__VA_ARGS__)
/**
* PANIC_ARITHMETIC is a macro that reports a ArithmeticPanic
* @param format printf-style string describing the error in more details
*/
#define PANIC_ARITHMETIC(format, ...) \
::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
#define PANIC_ARITHMETIC(format, ...) PANIC_ARITHMETIC_IMPL(format, format, ##__VA_ARGS__)
/**
* PANIC_LOG is a macro that logs a Panic, and continues as usual.
* @param format printf-style string describing the error in more details
*/
#define PANIC_LOG(format, ...) \
::utils::details::panicLog(PANIC_FUNCTION, \
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
#define PANIC_LOG(format, ...) PANIC_LOG_IMPL(format, format, ##__VA_ARGS__)
/**
* @ingroup errors
@@ -471,14 +629,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
* @param format printf-style string describing the error in more details
*/
#define ASSERT_PRECONDITION(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__) : (void)0)
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
#define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true)
#else
#define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
#endif
@@ -499,14 +657,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
* @endcode
*/
#define ASSERT_POSTCONDITION(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__) : (void)0)
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
#define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true)
#else
#define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
#endif
/**
@@ -527,14 +685,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
* @endcode
*/
#define ASSERT_ARITHMETIC(cond, format, ...) \
(!(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__) : (void)0)
(!(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
#define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__), false : true)
#else
#define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
#endif
/**
@@ -558,6 +716,7 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
* }
* @endcode
*/
#define ASSERT_DESTRUCTOR(cond, format, ...) (!(cond) ? PANIC_LOG(format, ##__VA_ARGS__) : (void)0)
#define ASSERT_DESTRUCTOR(cond, format, ...) \
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
#endif // TNT_UTILS_PANIC_H