#ifndef DEFS_H #define DEFS_H /*************************************************************************/ /* defs.h */ /*************************************************************************/ /* This file is part of: */ /* PANDEMONIUM ENGINE */ /* https://pandemoniumengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2022 Pandemonium Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ enum Error { OK, FAILED, ///< Generic fail error ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable ERR_UNCONFIGURED, ///< The object being used hasnt been properly set up yet ERR_UNAUTHORIZED, ///< Missing credentials for requested resource ERR_PARAMETER_RANGE_ERROR, ///< Parameter given out of range (5) ERR_OUT_OF_MEMORY, ///< Out of memory ERR_FILE_NOT_FOUND, ERR_FILE_BAD_DRIVE, ERR_FILE_BAD_PATH, ERR_FILE_NO_PERMISSION, // (10) ERR_FILE_ALREADY_IN_USE, ERR_FILE_CANT_OPEN, ERR_FILE_CANT_WRITE, ERR_FILE_CANT_READ, ERR_FILE_UNRECOGNIZED, // (15) ERR_FILE_CORRUPT, ERR_FILE_MISSING_DEPENDENCIES, ERR_FILE_EOF, ERR_CANT_OPEN, ///< Can't open a resource/socket/file ERR_CANT_CREATE, // (20) ERR_QUERY_FAILED, ERR_ALREADY_IN_USE, ERR_LOCKED, ///< resource is locked ERR_TIMEOUT, ERR_CANT_CONNECT, // (25) ERR_CANT_RESOLVE, ERR_CONNECTION_ERROR, ERR_CANT_AQUIRE_RESOURCE, ERR_CANT_FORK, ERR_INVALID_DATA, ///< Data passed is invalid (30) ERR_INVALID_PARAMETER, ///< Parameter passed is invalid ERR_ALREADY_EXISTS, ///< When adding, item already exists ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist ERR_DATABASE_CANT_READ, ///< database is full ERR_DATABASE_CANT_WRITE, ///< database is full (35) ERR_COMPILATION_FAILED, ERR_METHOD_NOT_FOUND, ERR_LINK_FAILED, ERR_SCRIPT_FAILED, ERR_CYCLIC_LINK, // (40) ERR_INVALID_DECLARATION, ERR_DUPLICATE_SYMBOL, ERR_PARSE_ERROR, ERR_BUSY, ERR_SKIP, // (45) ERR_HELP, ///< user requested help!! ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior. ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames }; #include // alloca() is non-standard. When using MSVC, it's in malloc.h. #if defined(__linux__) || defined(__APPLE__) #include #else #include #endif typedef float real_t; // This epsilon should match the one used by Pandemonium for consistency. // Using `f` when `real_t` is float. #define CMP_EPSILON 0.00001f #define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON) #define Math_PI 3.1415926535897932384626433833 #define Math_TAU 6.2831853071795864769252867666 #define Math_INF INFINITY #define Math_NAN NAN #define _PLANE_EQ_DOT_EPSILON 0.999 #define _PLANE_EQ_D_EPSILON 0.0001 #ifdef __GNUC__ #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else #define likely(x) x #define unlikely(x) x #endif #include "typedefs.h" // Don't use this directly; instead, use any of the CRASH_* macros #ifdef _MSC_VER #define GENERATE_TRAP \ __debugbreak(); \ /* Avoid warning about control paths */ \ for (;;) { \ } #else #define GENERATE_TRAP __builtin_trap(); #endif // ERR/WARN macros #ifndef WARN_PRINT #define WARN_PRINT(msg) Pandemonium::print_warning(msg, __func__, __FILE__, __LINE__) #endif #ifndef WARN_PRINTS #define WARN_PRINTS(msg) WARN_PRINT((msg).utf8().get_data()) #endif #ifndef ERR_PRINT #define ERR_PRINT(msg) Pandemonium::print_error(msg, __func__, __FILE__, __LINE__) #endif #ifndef ERR_PRINTS #define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data()) #endif #ifndef FATAL_PRINT #define FATAL_PRINT(msg) ERR_PRINT(String("FATAL: ") + (msg)) #endif #ifndef ERR_MSG_INDEX #define ERR_MSG_INDEX(index, size) (String("Index ") + #index + "=" + String::num_int64(index) + " out of size (" + #size + "=" + String::num_int64(size) + ")") #endif #ifndef ERR_MSG_INDEX_MSG #define ERR_MSG_INDEX_MSG(index, size, msg) (String("Index ") + #index + "=" + String::num_int64(index) + " out of size (" + #size + "=" + String::num_int64(size) + ")" + #msg) #endif #ifndef ERR_MSG_NULL #define ERR_MSG_NULL(param) (String("Parameter '") + #param + "' is null.") #endif #ifndef ERR_MSG_NULL_MSG #define ERR_MSG_NULL_MSG(param, msg) (String("Parameter '") + #param + "' is null." + #msg) #endif #ifndef ERR_MSG_COND #define ERR_MSG_COND(cond) (String("Condition '") + #cond + "' is true.") #endif #ifndef ERR_MSG_COND_MSG #define ERR_MSG_COND_MSG(cond, msg) (String("Condition '") + #cond + "' is true." + #msg) #endif #ifndef ERR_FAIL_INDEX #define ERR_FAIL_INDEX(index, size) \ do { \ if (unlikely((index) < 0 || (index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX(index, size)); \ return; \ } \ } while (0) #endif #ifndef ERR_FAIL_INDEX_MSG #define ERR_FAIL_INDEX_MSG(index, size, m_msg) \ do { \ if (unlikely((index) < 0 || (index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX_MSG(index, size, m_msg)); \ return; \ } \ } while (0) #endif #ifndef ERR_FAIL_INDEX_V #define ERR_FAIL_INDEX_V(index, size, ret) \ do { \ if (unlikely((index) < 0 || (index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX(index, size)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_INDEX_V_MSG #define ERR_FAIL_INDEX_V_MSG(index, size, ret, m_msg) \ do { \ if (unlikely((index) < 0 || (index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX_MSG(index, size, m_msg)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_UNSIGNED_INDEX_V #define ERR_FAIL_UNSIGNED_INDEX_V(index, size, ret) \ do { \ if (unlikely((index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX(index, size)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_UNSIGNED_INDEX_V_MSG #define ERR_FAIL_UNSIGNED_INDEX_V_MSG(index, size, ret, m_msg) \ do { \ if (unlikely((index) >= (size))) { \ ERR_PRINT(ERR_MSG_INDEX_MSG(index, size, m_msg)); \ return ret; \ } \ } while (0) #endif #ifndef CRASH_BAD_INDEX #define CRASH_BAD_INDEX(index, size) \ do { \ if (unlikely((index) < 0 || (index) >= (size))) { \ FATAL_PRINT(ERR_MSG_INDEX(index, size)); \ GENERATE_TRAP; \ } \ } while (0) #endif #ifndef ERR_FAIL_NULL #define ERR_FAIL_NULL(param) \ do { \ if (unlikely(!param)) { \ ERR_PRINT(ERR_MSG_NULL(param)); \ return; \ } \ } while (0) #endif #ifndef ERR_FAIL_NULL_MSG #define ERR_FAIL_NULL_MSG(param, m_msg) \ do { \ if (unlikely(!param)) { \ ERR_PRINT(ERR_MSG_NULL_MSG(param, m_msg)); \ return; \ } \ } while (0) #endif #ifndef ERR_FAIL_NULL_V #define ERR_FAIL_NULL_V(param, ret) \ do { \ if (unlikely(!param)) { \ ERR_PRINT(ERR_MSG_NULL(param)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_NULL_V_MSG #define ERR_FAIL_NULL_V_MSG(param, ret, m_msg) \ do { \ if (unlikely(!param)) { \ ERR_PRINT(ERR_MSG_NULL_MSG(param, m_msg)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_COND #define ERR_FAIL_COND(cond) \ do { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND(cond)); \ return; \ } \ } while (0) #endif #ifndef ERR_FAIL_COND_MSG #define ERR_FAIL_COND_MSG(cond, m_msg) \ do { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND_MSG(cond, m_msg)); \ return; \ } \ } while (0) #endif #ifndef CRASH_COND #define CRASH_COND(cond) \ do { \ if (unlikely(cond)) { \ FATAL_PRINT(ERR_MSG_COND(cond)); \ GENERATE_TRAP; \ } \ } while (0) #endif #ifndef CRASH_COND_MSG #define CRASH_COND_MSG(cond, m_msg) \ do { \ if (unlikely(cond)) { \ FATAL_PRINT(ERR_MSG_COND_MSG(cond, m_msg)); \ GENERATE_TRAP; \ } \ } while (0) #endif #ifndef ERR_FAIL_COND_V #define ERR_FAIL_COND_V(cond, ret) \ do { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND(cond)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_FAIL_COND_V_MSG #define ERR_FAIL_COND_V_MSG(cond, ret, m_msg) \ do { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND_MSG(cond, m_msg)); \ return ret; \ } \ } while (0) #endif #ifndef ERR_CONTINUE #define ERR_CONTINUE(cond) \ { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND(cond)); \ continue; \ } \ } #endif #ifndef ERR_BREAK #define ERR_BREAK(cond) \ { \ if (unlikely(cond)) { \ ERR_PRINT(ERR_MSG_COND(cond)); \ break; \ } \ } #endif #ifndef ERR_FAIL #define ERR_FAIL() \ do { \ ERR_PRINT("Method/Function Failed."); \ return; \ } while (0) #endif #ifndef ERR_FAIL_V #define ERR_FAIL_V(ret) \ do { \ ERR_PRINT("Method/Function Failed."); \ return ret; \ } while (0) #endif #ifndef CRASH_NOW #define CRASH_NOW() \ do { \ FATAL_PRINT("Method/Function Failed."); \ GENERATE_TRAP; \ } while (0) #endif #endif // DEFS_H