1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

rwlib: Add option to abort/break on failed checks or at request

- RW_ABORT/RW_ASSERT/RW_BREAKPOINT are only defined in debug mode
- the callback is needed to unlock the mouse when entering
    the debugger
This commit is contained in:
Anonymous Maarten 2017-09-12 18:00:07 +02:00 committed by Daniel Evans
parent afe4928678
commit a1333360c5
5 changed files with 65 additions and 2 deletions

View File

@ -22,6 +22,8 @@ option(ENABLE_SCRIPT_DEBUG "Enable verbose script execution")
option(ENABLE_PROFILING "Enable detailed profiling metrics")
option(TESTS_NODATA "Build tests for no-data testing")
set(FAILED_CHECK_ACTION "IGNORE" CACHE STRING "What action to perform on a failed RW_CHECK (IGNORE, ABORT or BREAKPOINT) (only in debug mode)")
#
# Build configuration
#
@ -66,6 +68,16 @@ IF(${ENABLE_SCRIPT_DEBUG})
add_definitions(-DRW_SCRIPT_DEBUG)
ENDIF()
if(FAILED_CHECK_ACTION STREQUAL "IGNORE")
add_definitions(-DRW_FAILED_CHECK_ACTION=0)
elseif(FAILED_CHECK_ACTION STREQUAL "ABORT")
add_definitions(-DRW_FAILED_CHECK_ACTION=1)
elseif(FAILED_CHECK_ACTION STREQUAL "BREAKPOINT")
add_definitions(-DRW_FAILED_CHECK_ACTION=2)
else()
message(FATAL_ERROR "Illegal FAILED_CHECK_ACTION option.")
endif()
if(${RW_VERBOSE_DEBUG_MESSAGES})
add_definitions(-DRW_VERBOSE_DEBUG_MESSAGES=1)
else()

View File

@ -64,6 +64,9 @@ GameBase::GameBase(Logger &inlog, int argc, char *argv[]) : log(inlog) {
throw std::runtime_error("Failed to initialize SDL2!");
window.create(kWindowTitle + " [" + kBuildStr + "]", w, h, fullscreen);
SET_RW_ABORT_CB([this]() {window.showCursor();},
[this]() {window.hideCursor();});
}
GameBase::~GameBase() {

View File

@ -16,6 +16,7 @@ SET(RWLIB_SOURCES
"source/gl/TextureData.hpp"
"source/gl/TextureData.cpp"
"source/rw/abort.cpp"
"source/rw/types.hpp"
"source/rw/defines.hpp"

View File

@ -0,0 +1,5 @@
#include "rw/defines.hpp"
#if RW_DEBUG
std::function<void()> _rw_abort_cb[2] = {nullptr, nullptr};
#endif

View File

@ -1,17 +1,59 @@
#ifndef _LIBRW_DEFINES_HPP_
#define _LIBRW_DEFINES_HPP_
#if RW_DEBUG
#include <cstdlib>
#include <functional>
extern std::function<void()> _rw_abort_cb[2];
#define SET_RW_ABORT_CB(cb0, cb1) do { _rw_abort_cb[0] = cb0; _rw_abort_cb[1] = cb1;} while (0)
#define RW_ABORT() do { if(_rw_abort_cb[0]) _rw_abort_cb[0](); ::abort(); } while (0)
#define RW_ASSERT(cond) do { if (!(cond)) RW_ABORT();} while (0)
#if defined(RW_WINDOWS)
#include <Windows.h>
#define RW_BREAKPOINT() DebugBreak()
#else
#include <csignal>
#define RW_BREAKPOINT() do { if(_rw_abort_cb[0]) _rw_abort_cb[0](); ::raise(SIGTRAP); if(_rw_abort_cb[1]) _rw_abort_cb[1](); } while (0)
#endif
#define RW_FAILED_NO_ACTION 0
#define RW_FAILED_ABORT_OPTION 1
#define RW_FAILED_BREAKPOINT_OPTION 2
#if RW_FAILED_CHECK_ACTION == RW_FAILED_NO_ACTION
#define _RW_FAILED_CHECK_ACTION()
#elif RW_FAILED_CHECK_ACTION == RW_FAILED_ABORT_OPTION
#define _RW_FAILED_CHECK_ACTION() RW_ABORT()
#elif RW_FAILED_CHECK_ACTION == RW_FAILED_BREAKPOINT_OPTION
#define _RW_FAILED_CHECK_ACTION() RW_BREAKPOINT()
#endif
#else
#define SET_RW_ABORT_CB(cb0, cb1)
#define RW_ABORT()
#define RW_ASSERT(cond)
#define RW_BREAKPOINT()
#define _RW_FAILED_CHECK_ACTION()
#endif
#if RW_DEBUG && RW_VERBOSE_DEBUG_MESSAGES
#include <iostream>
#define RW_MESSAGE(msg) \
std::cout << __FILE__ << ":" << __LINE__ << ": " << msg << std::endl
#define RW_ERROR(msg) \
std::cerr << __FILE__ << ":" << __LINE__ << ": " << msg << std::endl
#define RW_CHECK(cond, msg) \
if (!(cond)) RW_ERROR(msg)
#else
#define RW_MESSAGE(msg)
#define RW_ERROR(msg)
#endif
#if RW_DEBUG
#define RW_CHECK(cond, msg) \
do { if (!(cond)) { RW_ERROR(msg); _RW_FAILED_CHECK_ACTION();}} while (0)
#else
#define RW_CHECK(cond, msg)
#endif