[Test] Change assert to custom CHECK macros

This changes the way we handle asserts to use a set of custom macros.
This greatly speeds up crashing, especially on Windows, and provides
assertions in release mode too.
This commit is contained in:
Fabrice de Gans 2024-05-10 16:43:06 -07:00 committed by Rafael Kitover
parent 09433875bc
commit f646c3848c
40 changed files with 587 additions and 325 deletions

View File

@ -35,6 +35,7 @@ target_sources(vbam-core-base
version.cpp version.cpp
PUBLIC PUBLIC
check.h
array.h array.h
file_util.h file_util.h
image_util.h image_util.h

62
src/core/base/check.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef VBAM_CORE_BASE_CHECK_H_
#define VBAM_CORE_BASE_CHECK_H_
// This header defines a number of macros for checking conditions and crashing
// the program if they are not met.
// * VBAM_CHECK(condition) - crashes the program if the condition is not met.
// * VBAM_NOTREACHED() - crashes the program if this line of code is reached.
// In release builds, this macro also tells the compiler that this code path
// is unreachable, which can help the compiler generate better code.
// * VBAM_STRINGIFY(x) - converts the argument to a string literal.
// While a number of other macros are defined in this file, they are not
// intended for general use and should be avoided.
#if defined(__GNUC__) || defined(__clang__)
// GCC/Clang.
#define VBAM_IMMEDIATE_CRASH_DETAIL() __builtin_trap()
#define VBAM_INTRINSIC_UNREACHABLE_DETAIL() __builtin_unreachable()
#elif defined(_MSC_VER) // defined(__GNUC__) || defined(__clang__)
// MSVC.
#define VBAM_IMMEDIATE_CRASH_DETAIL() __debugbreak()
#define VBAM_INTRINSIC_UNREACHABLE_DETAIL() __assume(0)
#else // defined(__GNUC__) || defined(__clang__)
#error "Unsupported compiler"
#endif // defined(__GNUC__) || defined(__clang__)
#define VBAM_STRINGIFY_DETAIL(x) #x
#define VBAM_STRINGIFY(x) VBAM_STRINGIFY_DETAIL(x)
#define VBAM_REQUIRE_SEMICOLON_DETAIL() \
static_assert(true, "Require a semicolon after macros invocation.")
#define VBAM_CHECK(condition) \
if (!(condition)) { \
fputs("CHECK failed at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) ": " #condition "\n", stderr); \
VBAM_IMMEDIATE_CRASH_DETAIL(); \
} \
VBAM_REQUIRE_SEMICOLON_DETAIL()
#define VBAM_NOTREACHED_MESSAGE_DETAIL() \
fputs("NOTREACHED code reached at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) "\n", stderr)
#if defined(DEBUG)
#define VBAM_NOTREACHED() \
VBAM_NOTREACHED_MESSAGE_DETAIL(); \
VBAM_IMMEDIATE_CRASH_DETAIL()
#else // defined(DEBUG)
#define VBAM_NOTREACHED() \
VBAM_NOTREACHED_MESSAGE_DETAIL(); \
VBAM_INTRINSIC_UNREACHABLE_DETAIL()
#endif // defined(DEBUG)
#endif // VBAM_CORE_BASE_CHECK_H_

View File

@ -1,13 +1,13 @@
#include "core/gb/gb.h" #include "core/gb/gb.h"
#include <array> #include <array>
#include <cassert>
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include "core/base/check.h"
#include "core/base/file_util.h" #include "core/base/file_util.h"
#include "core/base/message.h" #include "core/base/message.h"
#include "core/base/sizes.h" #include "core/base/sizes.h"
@ -291,8 +291,7 @@ bool gbInitializeRom(size_t romSize) {
switch (g_gbCartData.validity()) { switch (g_gbCartData.validity()) {
case gbCartData::Validity::kValid: case gbCartData::Validity::kValid:
case gbCartData::Validity::kUninitialized: case gbCartData::Validity::kUninitialized:
// Unreachable. VBAM_NOTREACHED();
assert(false);
break; break;
case gbCartData::Validity::kSizeTooSmall: case gbCartData::Validity::kSizeTooSmall:
systemMessage(MSG_UNSUPPORTED_ROM_SIZE, systemMessage(MSG_UNSUPPORTED_ROM_SIZE,

View File

@ -2,8 +2,8 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cassert>
#include "core/base/check.h"
#include "core/base/sizes.h" #include "core/base/sizes.h"
namespace { namespace {
@ -62,7 +62,7 @@ char byte_to_char(uint8_t byte) {
} else if (byte < 16) { } else if (byte < 16) {
return 'A' + (byte - 10); return 'A' + (byte - 10);
} else { } else {
assert(false); VBAM_NOTREACHED();
return '\0'; return '\0';
} }
} }
@ -98,7 +98,7 @@ bool is_valid_manufacturer_code(const std::string& manufacturer_code) {
constexpr size_t kHeaderGlobalChecksumAdress = 0x14e; constexpr size_t kHeaderGlobalChecksumAdress = 0x14e;
uint16_t get_rom_checksum(const uint8_t* romData, size_t romDataSize) { uint16_t get_rom_checksum(const uint8_t* romData, size_t romDataSize) {
assert(romData); VBAM_CHECK(romData);
uint16_t checksum = 0; uint16_t checksum = 0;
for (size_t i = 0; i < romDataSize; i++) { for (size_t i = 0; i < romDataSize; i++) {
@ -160,7 +160,7 @@ constexpr size_t kHeaderChecksumEndAdress = 0x14c;
} // namespace } // namespace
gbCartData::gbCartData(const uint8_t* romData, size_t romDataSize) { gbCartData::gbCartData(const uint8_t* romData, size_t romDataSize) {
assert(romData); VBAM_CHECK(romData);
if (romDataSize < sizeof(gbRomHeader)) { if (romDataSize < sizeof(gbRomHeader)) {
validity_ = Validity::kSizeTooSmall; validity_ = Validity::kSizeTooSmall;

View File

@ -1,4 +1,3 @@
#include <cassert>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
@ -12,6 +11,7 @@
#include "components/filters_agb/filters_agb.h" #include "components/filters_agb/filters_agb.h"
#include "components/filters_interframe/interframe.h" #include "components/filters_interframe/interframe.h"
#include "core/base/check.h"
#include "core/base/system.h" #include "core/base/system.h"
#include "core/base/file_util.h" #include "core/base/file_util.h"
#include "core/base/sizes.h" #include "core/base/sizes.h"
@ -177,8 +177,7 @@ static void* gb_rtcdata_prt(void)
case gbCartData::MapperType::kGameGenie: case gbCartData::MapperType::kGameGenie:
case gbCartData::MapperType::kGameShark: case gbCartData::MapperType::kGameShark:
case gbCartData::MapperType::kUnknown: case gbCartData::MapperType::kUnknown:
// Unreachable. VBAM_NOTREACHED();
assert(false);
return nullptr; return nullptr;
} }
return nullptr; return nullptr;
@ -205,8 +204,7 @@ static size_t gb_rtcdata_size(void)
case gbCartData::MapperType::kGameGenie: case gbCartData::MapperType::kGameGenie:
case gbCartData::MapperType::kGameShark: case gbCartData::MapperType::kGameShark:
case gbCartData::MapperType::kUnknown: case gbCartData::MapperType::kUnknown:
// Unreachable. VBAM_NOTREACHED();
assert(false);
break; break;
} }
return 0; return 0;
@ -272,8 +270,7 @@ static void gbInitRTC(void)
case gbCartData::MapperType::kGameGenie: case gbCartData::MapperType::kGameGenie:
case gbCartData::MapperType::kGameShark: case gbCartData::MapperType::kGameShark:
case gbCartData::MapperType::kUnknown: case gbCartData::MapperType::kUnknown:
// Unreachable. VBAM_NOTREACHED();
assert(false);
break; break;
} }
} }
@ -1456,8 +1453,7 @@ void retro_run(void)
case gbCartData::MapperType::kGameGenie: case gbCartData::MapperType::kGameGenie:
case gbCartData::MapperType::kGameShark: case gbCartData::MapperType::kGameShark:
case gbCartData::MapperType::kUnknown: case gbCartData::MapperType::kUnknown:
// Unreachable. VBAM_NOTREACHED();
assert(false);
break; break;
} }
/* Initialize RTC using local time if needed */ /* Initialize RTC using local time if needed */

View File

@ -1,12 +1,12 @@
#include "wx/audio/audio.h" #include "wx/audio/audio.h"
#include "core/base/check.h"
#include "wx/audio/internal/openal.h" #include "wx/audio/internal/openal.h"
#if defined(__WXMSW__) #if defined(__WXMSW__)
#include "wx/audio/internal/dsound.h" #include "wx/audio/internal/dsound.h"
#endif #endif
#if defined(VBAM_ENABLE_FAUDIO) #if defined(VBAM_ENABLE_FAUDIO)
#include "wx/audio/internal/faudio.h" #include "wx/audio/internal/faudio.h"
#endif #endif
@ -39,8 +39,7 @@ std::vector<AudioDevice> EnumerateAudioDevices(const config::AudioApi& audio_api
case config::AudioApi::kLast: case config::AudioApi::kLast:
default: default:
// This should never happen. VBAM_NOTREACHED();
assert(false);
return {}; return {};
} }
} }
@ -67,8 +66,7 @@ std::unique_ptr<SoundDriver> CreateSoundDriver(const config::AudioApi& api) {
case config::AudioApi::kLast: case config::AudioApi::kLast:
default: default:
// This should never happen. VBAM_NOTREACHED();
assert(false);
return nullptr; return nullptr;
} }
} }

View File

@ -5,8 +5,6 @@
#include "wx/audio/internal/faudio.h" #include "wx/audio/internal/faudio.h"
#include <cassert>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -18,6 +16,7 @@
#include <wx/log.h> #include <wx/log.h>
#include <wx/translation.h> #include <wx/translation.h>
#include "core/base/check.h"
#include "core/base/system.h" #include "core/base/system.h"
#include "core/gba/gbaGlobals.h" #include "core/gba/gbaGlobals.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
@ -176,7 +175,7 @@ void FAudio_Output::close() {
if (sVoice) { if (sVoice) {
if (playing) { if (playing) {
assert(FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW) == 0); VBAM_CHECK(FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW) == 0);
} }
FAudioVoice_DestroyVoice(sVoice); FAudioVoice_DestroyVoice(sVoice);
@ -259,7 +258,7 @@ bool FAudio_Output::init(long sampleRate) {
if (OPTION(kSoundUpmix)) { if (OPTION(kSoundUpmix)) {
// set up stereo upmixing // set up stereo upmixing
FAudioDeviceDetails dd{}; FAudioDeviceDetails dd{};
assert(FAudio_GetDeviceDetails(faud, 0, &dd) == 0); VBAM_CHECK(FAudio_GetDeviceDetails(faud, 0, &dd) == 0);
std::vector<float> matrix(sizeof(float) * 2 * dd.OutputFormat.Format.nChannels); std::vector<float> matrix(sizeof(float) * 2 * dd.OutputFormat.Format.nChannels);
bool matrixAvailable = true; bool matrixAvailable = true;
@ -353,12 +352,12 @@ bool FAudio_Output::init(long sampleRate) {
if (matrixAvailable) { if (matrixAvailable) {
hr = FAudioVoice_SetOutputMatrix(sVoice, nullptr, 2, dd.OutputFormat.Format.nChannels, hr = FAudioVoice_SetOutputMatrix(sVoice, nullptr, 2, dd.OutputFormat.Format.nChannels,
matrix.data(), FAUDIO_DEFAULT_CHANNELS); matrix.data(), FAUDIO_DEFAULT_CHANNELS);
assert(hr == 0); VBAM_CHECK(hr == 0);
} }
} }
hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW); hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); VBAM_CHECK(hr == 0);
playing = true; playing = true;
currentBuffer = 0; currentBuffer = 0;
device_changed = false; device_changed = false;
@ -380,7 +379,7 @@ void FAudio_Output::write(uint16_t* finalWave, int) {
} }
FAudioSourceVoice_GetState(sVoice, &vState, flags); FAudioSourceVoice_GetState(sVoice, &vState, flags);
assert(vState.BuffersQueued <= buffer_count_); VBAM_CHECK(vState.BuffersQueued <= buffer_count_);
if (vState.BuffersQueued < buffer_count_) { if (vState.BuffersQueued < buffer_count_) {
if (vState.BuffersQueued == 0) { if (vState.BuffersQueued == 0) {
@ -414,7 +413,7 @@ void FAudio_Output::write(uint16_t* finalWave, int) {
currentBuffer++; currentBuffer++;
currentBuffer %= (buffer_count_ + 1); // + 1 because we need one temporary buffer currentBuffer %= (buffer_count_ + 1); // + 1 because we need one temporary buffer
[[maybe_unused]] uint32_t hr = FAudioSourceVoice_SubmitSourceBuffer(sVoice, &buf, nullptr); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_SubmitSourceBuffer(sVoice, &buf, nullptr);
assert(hr == 0); VBAM_CHECK(hr == 0);
} }
void FAudio_Output::pause() { void FAudio_Output::pause() {
@ -423,7 +422,7 @@ void FAudio_Output::pause() {
if (playing) { if (playing) {
[[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); VBAM_CHECK(hr == 0);
playing = false; playing = false;
} }
} }
@ -434,7 +433,7 @@ void FAudio_Output::resume() {
if (!playing) { if (!playing) {
[[maybe_unused]] int32_t hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] int32_t hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); VBAM_CHECK(hr == 0);
playing = true; playing = true;
} }
} }
@ -445,7 +444,7 @@ void FAudio_Output::reset() {
if (playing) { if (playing) {
[[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); VBAM_CHECK(hr == 0);
} }
FAudioSourceVoice_FlushSourceBuffers(sVoice); FAudioSourceVoice_FlushSourceBuffers(sVoice);
@ -462,7 +461,7 @@ void FAudio_Output::setThrottle(unsigned short throttle_) {
[[maybe_unused]] uint32_t hr = [[maybe_unused]] uint32_t hr =
FAudioSourceVoice_SetFrequencyRatio(sVoice, (float)throttle_ / 100.0f, FAUDIO_COMMIT_NOW); FAudioSourceVoice_SetFrequencyRatio(sVoice, (float)throttle_ / 100.0f, FAUDIO_COMMIT_NOW);
assert(hr == 0); VBAM_CHECK(hr == 0);
} }
} // namespace } // namespace

View File

@ -30,13 +30,12 @@ typedef ALCboolean(ALC_APIENTRY* LPALCISEXTENSIONPRESENT)(ALCdevice* device,
typedef const ALCchar*(ALC_APIENTRY* LPALCGETSTRING)(ALCdevice* device, ALCenum param); typedef const ALCchar*(ALC_APIENTRY* LPALCGETSTRING)(ALCdevice* device, ALCenum param);
#endif #endif
#include <cassert>
#include <wx/arrstr.h> #include <wx/arrstr.h>
#include <wx/log.h> #include <wx/log.h>
#include <wx/translation.h> #include <wx/translation.h>
#include <wx/utils.h> #include <wx/utils.h>
#include "core/base/check.h"
#include "core/gba/gbaGlobals.h" #include "core/gba/gbaGlobals.h"
#include "core/gba/gbaSound.h" #include "core/gba/gbaSound.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
@ -47,7 +46,7 @@ namespace internal {
namespace { namespace {
// Debug // Debug
#define ASSERT_SUCCESS assert(AL_NO_ERROR == alGetError()) #define ASSERT_SUCCESS VBAM_CHECK(AL_NO_ERROR == alGetError())
#ifndef LOGALL #ifndef LOGALL
// replace logging functions with comments // replace logging functions with comments
@ -171,7 +170,7 @@ void OpenAL::debugState() {
bool OpenAL::init(long sampleRate) { bool OpenAL::init(long sampleRate) {
winlog("OpenAL::init\n"); winlog("OpenAL::init\n");
assert(initialized == false); VBAM_CHECK(initialized == false);
const wxString& audio_device = OPTION(kSoundAudioDevice); const wxString& audio_device = OPTION(kSoundAudioDevice);
if (!audio_device.empty()) { if (!audio_device.empty()) {
@ -191,9 +190,9 @@ bool OpenAL::init(long sampleRate) {
} }
context = alcCreateContext(device, nullptr); context = alcCreateContext(device, nullptr);
assert(context != nullptr); VBAM_CHECK(context != nullptr);
ALCboolean retVal = alcMakeContextCurrent(context); ALCboolean retVal = alcMakeContextCurrent(context);
assert(ALC_TRUE == retVal); VBAM_CHECK(ALC_TRUE == retVal);
alGenBuffers(OPTION(kSoundBuffers), buffer); alGenBuffers(OPTION(kSoundBuffers), buffer);
ASSERT_SUCCESS; ASSERT_SUCCESS;
alGenSources(1, &source); alGenSources(1, &source);
@ -338,7 +337,7 @@ void OpenAL::write(uint16_t* finalWave, int length) {
return; return;
} }
assert(nBuffersProcessed > 0); VBAM_CHECK(nBuffersProcessed > 0);
// unqueue buffer // unqueue buffer
tempBuffer = 0; tempBuffer = 0;

View File

@ -11,6 +11,7 @@
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include "components/filters_interframe/interframe.h" #include "components/filters_interframe/interframe.h"
#include "core/base/check.h"
#include "core/base/version.h" #include "core/base/version.h"
#include "core/gb/gb.h" #include "core/gb/gb.h"
#include "core/gb/gbCheats.h" #include "core/gb/gbCheats.h"
@ -32,7 +33,7 @@
void MainFrame::GetMenuOptionBool(const wxString& menuName, bool* field) void MainFrame::GetMenuOptionBool(const wxString& menuName, bool* field)
{ {
assert(field); VBAM_CHECK(field);
*field = !*field; *field = !*field;
int id = wxXmlResource::GetXRCID(menuName); int id = wxXmlResource::GetXRCID(menuName);
@ -48,7 +49,7 @@ void MainFrame::GetMenuOptionBool(const wxString& menuName, bool* field)
void MainFrame::GetMenuOptionConfig(const wxString& menu_name, void MainFrame::GetMenuOptionConfig(const wxString& menu_name,
const config::OptionID& option_id) { const config::OptionID& option_id) {
config::Option* option = config::Option::ByID(option_id); config::Option* option = config::Option::ByID(option_id);
assert(option); VBAM_CHECK(option);
int id = wxXmlResource::GetXRCID(menu_name); int id = wxXmlResource::GetXRCID(menu_name);
for (size_t i = 0; i < checkable_mi.size(); i++) { for (size_t i = 0; i < checkable_mi.size(); i++) {
@ -64,7 +65,7 @@ void MainFrame::GetMenuOptionConfig(const wxString& menu_name,
option->SetInt(is_checked); option->SetInt(is_checked);
break; break;
default: default:
assert(false); VBAM_CHECK(false);
return; return;
} }
break; break;
@ -73,7 +74,7 @@ void MainFrame::GetMenuOptionConfig(const wxString& menu_name,
void MainFrame::GetMenuOptionInt(const wxString& menuName, int* field, int mask) void MainFrame::GetMenuOptionInt(const wxString& menuName, int* field, int mask)
{ {
assert(field); VBAM_CHECK(field);
int value = mask; int value = mask;
bool is_checked = ((*field) & (mask)) != (value); bool is_checked = ((*field) & (mask)) != (value);
int id = wxXmlResource::GetXRCID(menuName); int id = wxXmlResource::GetXRCID(menuName);

View File

@ -176,7 +176,7 @@ void Bindings::AssignInputsToCommand(const std::unordered_set<UserInput>& inputs
} }
void Bindings::UnassignInput(const UserInput& input) { void Bindings::UnassignInput(const UserInput& input) {
assert(input); VBAM_CHECK(input);
auto iter = input_to_control_.find(input); auto iter = input_to_control_.find(input);
if (iter == input_to_control_.end()) { if (iter == input_to_control_.end()) {
@ -194,7 +194,7 @@ void Bindings::UnassignInput(const UserInput& input) {
// Otherwise, just remove it from the 2 maps. // Otherwise, just remove it from the 2 maps.
auto command_iter = control_to_inputs_.find(iter->second); auto command_iter = control_to_inputs_.find(iter->second);
assert(command_iter != control_to_inputs_.end()); VBAM_CHECK(command_iter != control_to_inputs_.end());
command_iter->second.erase(input); command_iter->second.erase(input);
if (command_iter->second.empty()) { if (command_iter->second.empty()) {
@ -238,7 +238,7 @@ void Bindings::UnassignDefaultBinding(const UserInput& input) {
} }
auto command_iter = control_to_inputs_.find(input_iter->second); auto command_iter = control_to_inputs_.find(input_iter->second);
assert(command_iter != control_to_inputs_.end()); VBAM_CHECK(command_iter != control_to_inputs_.end());
command_iter->second.erase(input); command_iter->second.erase(input);
if (command_iter->second.empty()) { if (command_iter->second.empty()) {

View File

@ -4,6 +4,8 @@
#include <wx/wxcrt.h> #include <wx/wxcrt.h>
#include "core/base/check.h"
// Initializer for struct cmditem // Initializer for struct cmditem
cmditem new_cmditem(const wxString cmd, cmditem new_cmditem(const wxString cmd,
const wxString name, const wxString name,
@ -22,7 +24,7 @@ namespace config {
} }
// Command not found. This should never happen. // Command not found. This should never happen.
assert(false); VBAM_NOTREACHED();
return wxEmptyString; return wxEmptyString;
} }
@ -34,7 +36,7 @@ namespace config {
} }
// Command not found. This should never happen. // Command not found. This should never happen.
assert(false); VBAM_NOTREACHED();
return wxEmptyString; return wxEmptyString;
} }

View File

@ -2,7 +2,6 @@
#define VBAM_WX_CONFIG_COMMAND_H_ #define VBAM_WX_CONFIG_COMMAND_H_
#include <array> #include <array>
#include <cassert>
#include <functional> #include <functional>
#include <optional.hpp> #include <optional.hpp>
@ -10,6 +9,8 @@
#include <wx/string.h> #include <wx/string.h>
#include "core/base/check.h"
namespace config { namespace config {
// clang-format off // clang-format off
@ -56,7 +57,7 @@ static constexpr size_t kNbJoypads = 4;
// Represents an emulated joypad. The internal index is zero-based. // Represents an emulated joypad. The internal index is zero-based.
class GameJoy { class GameJoy {
public: public:
constexpr explicit GameJoy(size_t index) : index_(index) { assert(index < kNbJoypads); } constexpr explicit GameJoy(size_t index) : index_(index) { VBAM_CHECK(index < kNbJoypads); }
// The underlying zero-based index for this emulated joypad. // The underlying zero-based index for this emulated joypad.
constexpr size_t index() const { return index_; } constexpr size_t index() const { return index_; }
@ -179,12 +180,12 @@ public:
bool is_shortcut() const { return tag() == Tag::kShortcut; } bool is_shortcut() const { return tag() == Tag::kShortcut; }
const GameCommand& game() const { const GameCommand& game() const {
assert(is_game()); VBAM_CHECK(is_game());
return nonstd::get<GameCommand>(control_); return nonstd::get<GameCommand>(control_);
} }
const ShortcutCommand& shortcut() const { const ShortcutCommand& shortcut() const {
assert(is_shortcut()); VBAM_CHECK(is_shortcut());
return nonstd::get<ShortcutCommand>(control_); return nonstd::get<ShortcutCommand>(control_);
} }
@ -201,8 +202,7 @@ public:
return shortcut() < other.shortcut(); return shortcut() < other.shortcut();
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return false; return false;
} else { } else {
return tag_ < other.tag_; return tag_ < other.tag_;
@ -260,8 +260,7 @@ struct std::hash<config::Command> {
return std::hash<config::ShortcutCommand>{}(control.shortcut()); return std::hash<config::ShortcutCommand>{}(control.shortcut());
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return 0; return 0;
} }
}; };

View File

@ -1,5 +1,7 @@
#include "wx/config/emulated-gamepad.h" #include "wx/config/emulated-gamepad.h"
#include "core/base/check.h"
namespace config { namespace config {
namespace { namespace {
@ -62,7 +64,7 @@ EmulatedGamepad::EmulatedGamepad(const BindingsProvider bindings_provider)
: joypads_({0, 0, 0, 0}), bindings_provider_(bindings_provider) {} : joypads_({0, 0, 0, 0}), bindings_provider_(bindings_provider) {}
bool EmulatedGamepad::OnInputPressed(const config::UserInput& user_input) { bool EmulatedGamepad::OnInputPressed(const config::UserInput& user_input) {
assert(user_input); VBAM_CHECK(user_input);
const auto command = bindings_provider_()->CommandForInput(user_input); const auto command = bindings_provider_()->CommandForInput(user_input);
if (!command || !command->is_game()) { if (!command || !command->is_game()) {
@ -85,7 +87,7 @@ bool EmulatedGamepad::OnInputPressed(const config::UserInput& user_input) {
} }
bool EmulatedGamepad::OnInputReleased(const config::UserInput& user_input) { bool EmulatedGamepad::OnInputReleased(const config::UserInput& user_input) {
assert(user_input); VBAM_CHECK(user_input);
const auto command = bindings_provider_()->CommandForInput(user_input); const auto command = bindings_provider_()->CommandForInput(user_input);
if (!command || !command->is_game()) { if (!command || !command->is_game()) {

View File

@ -11,6 +11,7 @@
#include <wx/log.h> #include <wx/log.h>
#include <wx/translation.h> #include <wx/translation.h>
#include "core/base/check.h"
#include "core/base/system.h" #include "core/base/system.h"
#include "core/gb/gbGlobals.h" #include "core/gb/gbGlobals.h"
#include "core/gba/gbaSound.h" #include "core/gba/gbaSound.h"
@ -580,14 +581,14 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
}; };
nonstd::optional<OptionID> StringToOptionId(const wxString& input) { nonstd::optional<OptionID> StringToOptionId(const wxString& input) {
static std::map<wxString, OptionID> kStringToOptionId; static const std::map<wxString, OptionID> kStringToOptionId([] {
if (kStringToOptionId.empty()) { std::map<wxString, OptionID> string_to_option_id;
for (size_t i = 0; i < kNbOptions; i++) { for (size_t i = 0; i < kNbOptions; i++) {
kStringToOptionId.emplace(kAllOptionsData[i].config_name, string_to_option_id.emplace(kAllOptionsData[i].config_name, static_cast<OptionID>(i));
static_cast<OptionID>(i));
}
assert(kStringToOptionId.size() == kNbOptions);
} }
VBAM_CHECK(string_to_option_id.size() == kNbOptions);
return string_to_option_id;
}());
const auto iter = kStringToOptionId.find(input); const auto iter = kStringToOptionId.find(input);
if (iter == kStringToOptionId.end()) { if (iter == kStringToOptionId.end()) {
@ -598,42 +599,43 @@ nonstd::optional<OptionID> StringToOptionId(const wxString& input) {
wxString FilterToString(const Filter& value) { wxString FilterToString(const Filter& value) {
const size_t size_value = static_cast<size_t>(value); const size_t size_value = static_cast<size_t>(value);
assert(size_value < kNbFilters); VBAM_CHECK(size_value < kNbFilters);
return kFilterStrings[size_value]; return kFilterStrings[size_value];
} }
wxString InterframeToString(const Interframe& value) { wxString InterframeToString(const Interframe& value) {
const size_t size_value = static_cast<size_t>(value); const size_t size_value = static_cast<size_t>(value);
assert(size_value < kNbInterframes); VBAM_CHECK(size_value < kNbInterframes);
return kInterframeStrings[size_value]; return kInterframeStrings[size_value];
} }
wxString RenderMethodToString(const RenderMethod& value) { wxString RenderMethodToString(const RenderMethod& value) {
const size_t size_value = static_cast<size_t>(value); const size_t size_value = static_cast<size_t>(value);
assert(size_value < kNbRenderMethods); VBAM_CHECK(size_value < kNbRenderMethods);
return kRenderMethodStrings[size_value]; return kRenderMethodStrings[size_value];
} }
wxString AudioApiToString(const AudioApi& value) { wxString AudioApiToString(const AudioApi& value) {
const size_t size_value = static_cast<size_t>(value); const size_t size_value = static_cast<size_t>(value);
assert(size_value < kNbAudioApis); VBAM_CHECK(size_value < kNbAudioApis);
return kAudioApiStrings[size_value]; return kAudioApiStrings[size_value];
} }
wxString AudioRateToString(const AudioRate& value) { wxString AudioRateToString(const AudioRate& value) {
const size_t size_value = static_cast<size_t>(value); const size_t size_value = static_cast<size_t>(value);
assert(size_value < kNbSoundRate); VBAM_CHECK(size_value < kNbSoundRate);
return kAudioRateStrings[size_value]; return kAudioRateStrings[size_value];
} }
Filter StringToFilter(const wxString& config_name, const wxString& input) { Filter StringToFilter(const wxString& config_name, const wxString& input) {
static std::map<wxString, Filter> kStringToFilter; static const std::map<wxString, Filter> kStringToFilter([] {
if (kStringToFilter.empty()) { std::map<wxString, Filter> string_to_filter;
for (size_t i = 0; i < kNbFilters; i++) { for (size_t i = 0; i < kNbFilters; i++) {
kStringToFilter.emplace(kFilterStrings[i], static_cast<Filter>(i)); string_to_filter.emplace(kFilterStrings[i], static_cast<Filter>(i));
}
assert(kStringToFilter.size() == kNbFilters);
} }
VBAM_CHECK(string_to_filter.size() == kNbFilters);
return string_to_filter;
}());
const auto iter = kStringToFilter.find(input); const auto iter = kStringToFilter.find(input);
if (iter == kStringToFilter.end()) { if (iter == kStringToFilter.end()) {
@ -646,14 +648,14 @@ Filter StringToFilter(const wxString& config_name, const wxString& input) {
} }
Interframe StringToInterframe(const wxString& config_name, const wxString& input) { Interframe StringToInterframe(const wxString& config_name, const wxString& input) {
static std::map<wxString, Interframe> kStringToInterframe; static const std::map<wxString, Interframe> kStringToInterframe([] {
if (kStringToInterframe.empty()) { std::map<wxString, Interframe> string_to_interframe;
for (size_t i = 0; i < kNbInterframes; i++) { for (size_t i = 0; i < kNbInterframes; i++) {
kStringToInterframe.emplace(kInterframeStrings[i], string_to_interframe.emplace(kInterframeStrings[i], static_cast<Interframe>(i));
static_cast<Interframe>(i));
}
assert(kStringToInterframe.size() == kNbInterframes);
} }
VBAM_CHECK(string_to_interframe.size() == kNbInterframes);
return string_to_interframe;
}());
const auto iter = kStringToInterframe.find(input); const auto iter = kStringToInterframe.find(input);
if (iter == kStringToInterframe.end()) { if (iter == kStringToInterframe.end()) {
@ -667,14 +669,14 @@ Interframe StringToInterframe(const wxString& config_name, const wxString& input
RenderMethod StringToRenderMethod(const wxString& config_name, RenderMethod StringToRenderMethod(const wxString& config_name,
const wxString& input) { const wxString& input) {
static std::map<wxString, RenderMethod> kStringToRenderMethod; static const std::map<wxString, RenderMethod> kStringToRenderMethod([] {
if (kStringToRenderMethod.empty()) { std::map<wxString, RenderMethod> string_to_render_method;
for (size_t i = 0; i < kNbRenderMethods; i++) { for (size_t i = 0; i < kNbRenderMethods; i++) {
kStringToRenderMethod.emplace(kRenderMethodStrings[i], string_to_render_method.emplace(kRenderMethodStrings[i], static_cast<RenderMethod>(i));
static_cast<RenderMethod>(i));
}
assert(kStringToRenderMethod.size() == kNbRenderMethods);
} }
VBAM_CHECK(string_to_render_method.size() == kNbRenderMethods);
return string_to_render_method;
}());
const auto iter = kStringToRenderMethod.find(input); const auto iter = kStringToRenderMethod.find(input);
if (iter == kStringToRenderMethod.end()) { if (iter == kStringToRenderMethod.end()) {
@ -687,14 +689,14 @@ RenderMethod StringToRenderMethod(const wxString& config_name,
} }
AudioApi StringToAudioApi(const wxString& config_name, const wxString& input) { AudioApi StringToAudioApi(const wxString& config_name, const wxString& input) {
static std::map<wxString, AudioApi> kStringToAudioApi; static const std::map<wxString, AudioApi> kStringToAudioApi([] {
if (kStringToAudioApi.empty()) { std::map<wxString, AudioApi> string_to_audio_api;
for (size_t i = 0; i < kNbAudioApis; i++) { for (size_t i = 0; i < kNbAudioApis; i++) {
kStringToAudioApi.emplace(kAudioApiStrings[i], string_to_audio_api.emplace(kAudioApiStrings[i], static_cast<AudioApi>(i));
static_cast<AudioApi>(i));
}
assert(kStringToAudioApi.size() == kNbAudioApis);
} }
VBAM_CHECK(string_to_audio_api.size() == kNbAudioApis);
return string_to_audio_api;
}());
const auto iter = kStringToAudioApi.find(input); const auto iter = kStringToAudioApi.find(input);
if (iter == kStringToAudioApi.end()) { if (iter == kStringToAudioApi.end()) {
@ -707,13 +709,14 @@ AudioApi StringToAudioApi(const wxString& config_name, const wxString& input) {
} }
AudioRate StringToSoundQuality(const wxString& config_name, const wxString& input) { AudioRate StringToSoundQuality(const wxString& config_name, const wxString& input) {
static std::map<wxString, AudioRate> kStringToSoundQuality; static const std::map<wxString, AudioRate> kStringToSoundQuality([] {
if (kStringToSoundQuality.empty()) { std::map<wxString, AudioRate> string_to_sound_quality;
for (size_t i = 0; i < kNbSoundRate; i++) { for (size_t i = 0; i < kNbSoundRate; i++) {
kStringToSoundQuality.emplace(kAudioRateStrings[i], static_cast<AudioRate>(i)); string_to_sound_quality.emplace(kAudioRateStrings[i], static_cast<AudioRate>(i));
}
assert(kStringToSoundQuality.size() == kNbSoundRate);
} }
VBAM_CHECK(string_to_sound_quality.size() == kNbSoundRate);
return string_to_sound_quality;
}());
const auto iter = kStringToSoundQuality.find(input); const auto iter = kStringToSoundQuality.find(input);
if (iter == kStringToSoundQuality.end()) { if (iter == kStringToSoundQuality.end()) {
@ -727,28 +730,23 @@ AudioRate StringToSoundQuality(const wxString& config_name, const wxString& inpu
wxString AllEnumValuesForType(Option::Type type) { wxString AllEnumValuesForType(Option::Type type) {
switch (type) { switch (type) {
case Option::Type::kFilter: { case Option::Type::kFilter: {
static const wxString kAllFilterValues = static const wxString kAllFilterValues(AllEnumValuesForArray(kFilterStrings));
AllEnumValuesForArray(kFilterStrings);
return kAllFilterValues; return kAllFilterValues;
} }
case Option::Type::kInterframe: { case Option::Type::kInterframe: {
static const wxString kAllInterframeValues = static const wxString kAllInterframeValues(AllEnumValuesForArray(kInterframeStrings));
AllEnumValuesForArray(kInterframeStrings);
return kAllInterframeValues; return kAllInterframeValues;
} }
case Option::Type::kRenderMethod: { case Option::Type::kRenderMethod: {
static const wxString kAllRenderValues = static const wxString kAllRenderValues(AllEnumValuesForArray(kRenderMethodStrings));
AllEnumValuesForArray(kRenderMethodStrings);
return kAllRenderValues; return kAllRenderValues;
} }
case Option::Type::kAudioApi: { case Option::Type::kAudioApi: {
static const wxString kAllAudioApiValues = static const wxString kAllAudioApiValues(AllEnumValuesForArray(kAudioApiStrings));
AllEnumValuesForArray(kAudioApiStrings);
return kAllAudioApiValues; return kAllAudioApiValues;
} }
case Option::Type::kAudioRate: { case Option::Type::kAudioRate: {
static const wxString kAllSoundQualityValues = static const wxString kAllSoundQualityValues(AllEnumValuesForArray(kAudioRateStrings));
AllEnumValuesForArray(kAudioRateStrings);
return kAllSoundQualityValues; return kAllSoundQualityValues;
} }
@ -761,10 +759,10 @@ wxString AllEnumValuesForType(Option::Type type) {
case Option::Type::kUnsigned: case Option::Type::kUnsigned:
case Option::Type::kString: case Option::Type::kString:
case Option::Type::kGbPalette: case Option::Type::kGbPalette:
assert(false); VBAM_NOTREACHED();
return wxEmptyString; return wxEmptyString;
} }
assert(false); VBAM_NOTREACHED();
return wxEmptyString; return wxEmptyString;
} }
@ -790,10 +788,10 @@ size_t MaxForType(Option::Type type) {
case Option::Type::kUnsigned: case Option::Type::kUnsigned:
case Option::Type::kString: case Option::Type::kString:
case Option::Type::kGbPalette: case Option::Type::kGbPalette:
assert(false); VBAM_NOTREACHED();
return 0; return 0;
} }
assert(false); VBAM_NOTREACHED();
return 0; return 0;
} }

View File

@ -1,5 +1,6 @@
#include "wx/config/option-observer.h" #include "wx/config/option-observer.h"
#include "core/base/check.h"
#include "wx/config/option.h" #include "wx/config/option.h"
namespace config { namespace config {
@ -10,7 +11,7 @@ public:
CallbackOptionObserver(const OptionID& option_id, CallbackOptionObserver(const OptionID& option_id,
std::function<void(Option*)> callback) std::function<void(Option*)> callback)
: Option::Observer(option_id), callback_(std::move(callback)) { : Option::Observer(option_id), callback_(std::move(callback)) {
assert(callback_); VBAM_CHECK(callback_);
} }
~CallbackOptionObserver() override = default; ~CallbackOptionObserver() override = default;

View File

@ -21,18 +21,16 @@ TEST(OptionTest, Bool) {
EXPECT_TRUE(option->SetBool(false)); EXPECT_TRUE(option->SetBool(false));
EXPECT_FALSE(option->GetBool()); EXPECT_FALSE(option->GetBool());
#if !defined(NDEBUG) EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), ".*"); EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetInt(2), ".*"); EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), ".*"); EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetString("foo"), ".*"); EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), ".*"); EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), ".*"); EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), ".*"); EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), ".*"); EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), ".*"); EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), ".*");
#endif // !defined(NDEBUG)
} }
TEST(OptionTest, Double) { TEST(OptionTest, Double) {
@ -56,18 +54,205 @@ TEST(OptionTest, Double) {
EXPECT_FALSE(option->SetDouble(7.0)); EXPECT_FALSE(option->SetDouble(7.0));
EXPECT_DOUBLE_EQ(option->GetDouble(), 2.5); EXPECT_DOUBLE_EQ(option->GetDouble(), 2.5);
#if !defined(NDEBUG) EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetBool(true), ".*"); EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetInt(2), ".*"); EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), ".*"); EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetString("foo"), ".*"); EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), ".*"); EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), ".*"); EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), ".*"); EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), ".*"); EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), ".*"); EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), ".*"); }
#endif // !defined(NDEBUG)
TEST(OptionTest, Int) {
config::Option* option = config::Option::ByID(config::OptionID::kSoundBuffers);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "Sound/Buffers");
EXPECT_EQ(option->id(), config::OptionID::kSoundBuffers);
EXPECT_EQ(option->type(), config::Option::Type::kInt);
EXPECT_TRUE(option->is_int());
EXPECT_TRUE(option->SetInt(8));
EXPECT_EQ(option->GetInt(), 8);
// Need to disable logging to test for errors.
const wxLogNull disable_logging;
// Test out of bounds values.
EXPECT_FALSE(option->SetInt(-1));
EXPECT_FALSE(option->SetInt(42));
EXPECT_EQ(option->GetInt(), 8);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, Unsigned) {
config::Option* option = config::Option::ByID(config::OptionID::kGeomWindowHeight);
ASSERT_TRUE(option);
EXPECT_EQ(option->config_name(), "geometry/windowHeight");
EXPECT_EQ(option->id(), config::OptionID::kGeomWindowHeight);
EXPECT_EQ(option->type(), config::Option::Type::kUnsigned);
EXPECT_TRUE(option->is_unsigned());
EXPECT_TRUE(option->SetUnsigned(100));
EXPECT_EQ(option->GetUnsigned(), 100);
// Need to disable logging to test for errors.
const wxLogNull disable_logging;
// Test out of bounds values.
EXPECT_FALSE(option->SetUnsigned(100000));
EXPECT_EQ(option->GetUnsigned(), 100);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, String) {
config::Option* option = config::Option::ByID(config::OptionID::kGenStateDir);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "General/StateDir");
EXPECT_EQ(option->id(), config::OptionID::kGenStateDir);
EXPECT_EQ(option->type(), config::Option::Type::kString);
EXPECT_TRUE(option->is_string());
EXPECT_TRUE(option->SetString("/path/to/sthg"));
EXPECT_EQ(option->GetString(), "/path/to/sthg");
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, Filter) {
config::Option* option = config::Option::ByID(config::OptionID::kDispFilter);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "Display/Filter");
EXPECT_EQ(option->id(), config::OptionID::kDispFilter);
EXPECT_EQ(option->type(), config::Option::Type::kFilter);
EXPECT_TRUE(option->is_filter());
EXPECT_TRUE(option->SetFilter(config::Filter::kNone));
EXPECT_EQ(option->GetFilter(), config::Filter::kNone);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, Interframe) {
config::Option* option = config::Option::ByID(config::OptionID::kDispIFB);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "Display/IFB");
EXPECT_EQ(option->id(), config::OptionID::kDispIFB);
EXPECT_EQ(option->type(), config::Option::Type::kInterframe);
EXPECT_TRUE(option->is_interframe());
EXPECT_TRUE(option->SetInterframe(config::Interframe::kNone));
EXPECT_EQ(option->GetInterframe(), config::Interframe::kNone);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, AudioApi) {
config::Option* option = config::Option::ByID(config::OptionID::kSoundAudioAPI);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "Sound/AudioAPI");
EXPECT_EQ(option->id(), config::OptionID::kSoundAudioAPI);
EXPECT_EQ(option->type(), config::Option::Type::kAudioApi);
EXPECT_TRUE(option->is_audio_api());
EXPECT_TRUE(option->SetAudioApi(config::AudioApi::kOpenAL));
EXPECT_EQ(option->GetAudioApi(), config::AudioApi::kOpenAL);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, AudioRate) {
config::Option* option = config::Option::ByID(config::OptionID::kSoundAudioRate);
ASSERT_TRUE(option);
EXPECT_TRUE(option->command().empty());
EXPECT_EQ(option->config_name(), "Sound/Quality");
EXPECT_EQ(option->id(), config::OptionID::kSoundAudioRate);
EXPECT_EQ(option->type(), config::Option::Type::kAudioRate);
EXPECT_TRUE(option->is_audio_rate());
EXPECT_TRUE(option->SetAudioRate(config::AudioRate::k11kHz));
EXPECT_EQ(option->GetAudioRate(), config::AudioRate::k11kHz);
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
} }
TEST(OptionTest, Enum) { TEST(OptionTest, Enum) {
@ -110,6 +295,16 @@ TEST(Optiontest, GbPalette) {
EXPECT_FALSE(option->SetGbPaletteString("")); EXPECT_FALSE(option->SetGbPaletteString(""));
EXPECT_FALSE(option->SetGbPaletteString("0000,0001,0002,0003,0004,0005,0006,000Q")); EXPECT_FALSE(option->SetGbPaletteString("0000,0001,0002,0003,0004,0005,0006,000Q"));
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
EXPECT_DEATH(option->SetDouble(2.0), "is_double\\(\\)");
EXPECT_DEATH(option->SetInt(2), "is_int\\(\\)");
EXPECT_DEATH(option->SetUnsigned(2), "is_unsigned\\(\\)");
EXPECT_DEATH(option->SetString("foo"), "is_string\\(\\)");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), "is_filter\\(\\)");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), "is_interframe\\(\\)");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), "is_render_method\\(\\)");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), "is_audio_api\\(\\)");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), "is_audio_rate\\(\\)");
} }
TEST(OptionObserverTest, Basic) { TEST(OptionObserverTest, Basic) {

View File

@ -11,6 +11,7 @@
#include "wx/config/internal/option-internal.h" #include "wx/config/internal/option-internal.h"
#undef VBAM_OPTION_INTERNAL_INCLUDE #undef VBAM_OPTION_INTERNAL_INCLUDE
#include "core/base/check.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
namespace config { namespace config {
@ -26,14 +27,14 @@ Option* Option::ByName(const wxString& config_name) {
// static // static
Option* Option::ByID(OptionID id) { Option* Option::ByID(OptionID id) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
return &All()[static_cast<size_t>(id)]; return &All()[static_cast<size_t>(id)];
} }
Option::~Option() = default; Option::~Option() = default;
Option::Observer::Observer(OptionID option_id) : option_(Option::ByID(option_id)) { Option::Observer::Observer(OptionID option_id) : option_(Option::ByID(option_id)) {
assert(option_); VBAM_CHECK(option_);
option_->AddObserver(this); option_->AddObserver(this);
} }
Option::Observer::~Observer() { Option::Observer::~Observer() {
@ -49,8 +50,8 @@ Option::Option(OptionID id)
value_(), value_(),
min_(), min_(),
max_() { max_() {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_none()); VBAM_CHECK(is_none());
} }
Option::Option(OptionID id, bool* option) Option::Option(OptionID id, bool* option)
@ -62,8 +63,8 @@ Option::Option(OptionID id, bool* option)
value_(option), value_(option),
min_(), min_(),
max_() { max_() {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_bool()); VBAM_CHECK(is_bool());
} }
Option::Option(OptionID id, double* option, double min, double max) Option::Option(OptionID id, double* option, double min, double max)
@ -75,8 +76,8 @@ Option::Option(OptionID id, double* option, double min, double max)
value_(option), value_(option),
min_(min), min_(min),
max_(max) { max_(max) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_double()); VBAM_CHECK(is_double());
// Validate the initial value. // Validate the initial value.
SetDouble(*option); SetDouble(*option);
@ -91,8 +92,8 @@ Option::Option(OptionID id, int32_t* option, int32_t min, int32_t max)
value_(option), value_(option),
min_(min), min_(min),
max_(max) { max_(max) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_int()); VBAM_CHECK(is_int());
// Validate the initial value. // Validate the initial value.
SetInt(*option); SetInt(*option);
@ -107,8 +108,8 @@ Option::Option(OptionID id, uint32_t* option, uint32_t min, uint32_t max)
value_(option), value_(option),
min_(min), min_(min),
max_(max) { max_(max) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_unsigned()); VBAM_CHECK(is_unsigned());
// Validate the initial value. // Validate the initial value.
SetUnsigned(*option); SetUnsigned(*option);
@ -123,8 +124,8 @@ Option::Option(OptionID id, wxString* option)
value_(option), value_(option),
min_(), min_(),
max_() { max_() {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_string()); VBAM_CHECK(is_string());
} }
Option::Option(OptionID id, Filter* option) Option::Option(OptionID id, Filter* option)
@ -136,8 +137,8 @@ Option::Option(OptionID id, Filter* option)
value_(option), value_(option),
min_(), min_(),
max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) { max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_filter()); VBAM_CHECK(is_filter());
} }
Option::Option(OptionID id, Interframe* option) Option::Option(OptionID id, Interframe* option)
@ -149,8 +150,8 @@ Option::Option(OptionID id, Interframe* option)
value_(option), value_(option),
min_(), min_(),
max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) { max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_interframe()); VBAM_CHECK(is_interframe());
} }
Option::Option(OptionID id, RenderMethod* option) Option::Option(OptionID id, RenderMethod* option)
@ -162,8 +163,8 @@ Option::Option(OptionID id, RenderMethod* option)
value_(option), value_(option),
min_(), min_(),
max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) { max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_render_method()); VBAM_CHECK(is_render_method());
} }
Option::Option(OptionID id, AudioApi* option) Option::Option(OptionID id, AudioApi* option)
@ -175,8 +176,8 @@ Option::Option(OptionID id, AudioApi* option)
value_(option), value_(option),
min_(), min_(),
max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) { max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_audio_api()); VBAM_CHECK(is_audio_api());
} }
Option::Option(OptionID id, AudioRate* option) Option::Option(OptionID id, AudioRate* option)
@ -188,8 +189,8 @@ Option::Option(OptionID id, AudioRate* option)
value_(option), value_(option),
min_(), min_(),
max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) { max_(nonstd::in_place_type<size_t>, internal::MaxForType(type_)) {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_audio_rate()); VBAM_CHECK(is_audio_rate());
} }
Option::Option(OptionID id, uint16_t* option) Option::Option(OptionID id, uint16_t* option)
@ -201,57 +202,57 @@ Option::Option(OptionID id, uint16_t* option)
value_(option), value_(option),
min_(), min_(),
max_() { max_() {
assert(id != OptionID::Last); VBAM_CHECK(id != OptionID::Last);
assert(is_gb_palette()); VBAM_CHECK(is_gb_palette());
} }
bool Option::GetBool() const { bool Option::GetBool() const {
assert(is_bool()); VBAM_CHECK(is_bool());
return *(nonstd::get<bool*>(value_)); return *(nonstd::get<bool*>(value_));
} }
double Option::GetDouble() const { double Option::GetDouble() const {
assert(is_double()); VBAM_CHECK(is_double());
return *(nonstd::get<double*>(value_)); return *(nonstd::get<double*>(value_));
} }
int32_t Option::GetInt() const { int32_t Option::GetInt() const {
assert(is_int()); VBAM_CHECK(is_int());
return *(nonstd::get<int32_t*>(value_)); return *(nonstd::get<int32_t*>(value_));
} }
uint32_t Option::GetUnsigned() const { uint32_t Option::GetUnsigned() const {
assert(is_unsigned()); VBAM_CHECK(is_unsigned());
return *(nonstd::get<uint32_t*>(value_)); return *(nonstd::get<uint32_t*>(value_));
} }
const wxString& Option::GetString() const { const wxString& Option::GetString() const {
assert(is_string()); VBAM_CHECK(is_string());
return *(nonstd::get<wxString*>(value_)); return *(nonstd::get<wxString*>(value_));
} }
Filter Option::GetFilter() const { Filter Option::GetFilter() const {
assert(is_filter()); VBAM_CHECK(is_filter());
return *(nonstd::get<Filter*>(value_)); return *(nonstd::get<Filter*>(value_));
} }
Interframe Option::GetInterframe() const { Interframe Option::GetInterframe() const {
assert(is_interframe()); VBAM_CHECK(is_interframe());
return *(nonstd::get<Interframe*>(value_)); return *(nonstd::get<Interframe*>(value_));
} }
RenderMethod Option::GetRenderMethod() const { RenderMethod Option::GetRenderMethod() const {
assert(is_render_method()); VBAM_CHECK(is_render_method());
return *(nonstd::get<RenderMethod*>(value_)); return *(nonstd::get<RenderMethod*>(value_));
} }
AudioApi Option::GetAudioApi() const { AudioApi Option::GetAudioApi() const {
assert(is_audio_api()); VBAM_CHECK(is_audio_api());
return *(nonstd::get<AudioApi*>(value_)); return *(nonstd::get<AudioApi*>(value_));
} }
AudioRate Option::GetAudioRate() const { AudioRate Option::GetAudioRate() const {
assert(is_audio_rate()); VBAM_CHECK(is_audio_rate());
return *(nonstd::get<AudioRate*>(value_)); return *(nonstd::get<AudioRate*>(value_));
} }
@ -277,15 +278,15 @@ wxString Option::GetEnumString() const {
case Option::Type::kUnsigned: case Option::Type::kUnsigned:
case Option::Type::kString: case Option::Type::kString:
case Option::Type::kGbPalette: case Option::Type::kGbPalette:
assert(false); VBAM_CHECK(false);
return wxEmptyString; return wxEmptyString;
} }
assert(false); VBAM_NOTREACHED();
return wxEmptyString; return wxEmptyString;
} }
std::array<uint16_t, 8> Option::GetGbPalette() const { std::array<uint16_t, 8> Option::GetGbPalette() const {
assert(is_gb_palette()); VBAM_CHECK(is_gb_palette());
const uint16_t* raw_palette = (nonstd::get<uint16_t*>(value_)); const uint16_t* raw_palette = (nonstd::get<uint16_t*>(value_));
std::array<uint16_t, 8> palette; std::array<uint16_t, 8> palette;
@ -294,7 +295,7 @@ std::array<uint16_t, 8> Option::GetGbPalette() const {
} }
wxString Option::GetGbPaletteString() const { wxString Option::GetGbPaletteString() const {
assert(is_gb_palette()); VBAM_CHECK(is_gb_palette());
wxString palette_string; wxString palette_string;
uint16_t const* value = nonstd::get<uint16_t*>(value_); uint16_t const* value = nonstd::get<uint16_t*>(value_);
@ -304,7 +305,7 @@ wxString Option::GetGbPaletteString() const {
} }
bool Option::SetBool(bool value) { bool Option::SetBool(bool value) {
assert(is_bool()); VBAM_CHECK(is_bool());
bool old_value = GetBool(); bool old_value = GetBool();
*nonstd::get<bool*>(value_) = value; *nonstd::get<bool*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -314,7 +315,7 @@ bool Option::SetBool(bool value) {
} }
bool Option::SetDouble(double value) { bool Option::SetDouble(double value) {
assert(is_double()); VBAM_CHECK(is_double());
double old_value = GetDouble(); double old_value = GetDouble();
if (value < nonstd::get<double>(min_) || value > nonstd::get<double>(max_)) { if (value < nonstd::get<double>(min_) || value > nonstd::get<double>(max_)) {
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), value, wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), value,
@ -329,7 +330,7 @@ bool Option::SetDouble(double value) {
} }
bool Option::SetInt(int32_t value) { bool Option::SetInt(int32_t value) {
assert(is_int()); VBAM_CHECK(is_int());
int old_value = GetInt(); int old_value = GetInt();
if (value < nonstd::get<int32_t>(min_) || value > nonstd::get<int32_t>(max_)) { if (value < nonstd::get<int32_t>(min_) || value > nonstd::get<int32_t>(max_)) {
wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), value, wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), value,
@ -344,7 +345,7 @@ bool Option::SetInt(int32_t value) {
} }
bool Option::SetUnsigned(uint32_t value) { bool Option::SetUnsigned(uint32_t value) {
assert(is_unsigned()); VBAM_CHECK(is_unsigned());
uint32_t old_value = GetUnsigned(); uint32_t old_value = GetUnsigned();
if (value < nonstd::get<uint32_t>(min_) || value > nonstd::get<uint32_t>(max_)) { if (value < nonstd::get<uint32_t>(min_) || value > nonstd::get<uint32_t>(max_)) {
wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), value, wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), value,
@ -359,7 +360,7 @@ bool Option::SetUnsigned(uint32_t value) {
} }
bool Option::SetString(const wxString& value) { bool Option::SetString(const wxString& value) {
assert(is_string()); VBAM_CHECK(is_string());
const wxString old_value = GetString(); const wxString old_value = GetString();
*nonstd::get<wxString*>(value_) = value; *nonstd::get<wxString*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -369,8 +370,8 @@ bool Option::SetString(const wxString& value) {
} }
bool Option::SetFilter(const Filter& value) { bool Option::SetFilter(const Filter& value) {
assert(is_filter()); VBAM_CHECK(is_filter());
assert(value < Filter::kLast); VBAM_CHECK(value < Filter::kLast);
const Filter old_value = GetFilter(); const Filter old_value = GetFilter();
*nonstd::get<Filter*>(value_) = value; *nonstd::get<Filter*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -380,8 +381,8 @@ bool Option::SetFilter(const Filter& value) {
} }
bool Option::SetInterframe(const Interframe& value) { bool Option::SetInterframe(const Interframe& value) {
assert(is_interframe()); VBAM_CHECK(is_interframe());
assert(value < Interframe::kLast); VBAM_CHECK(value < Interframe::kLast);
const Interframe old_value = GetInterframe(); const Interframe old_value = GetInterframe();
*nonstd::get<Interframe*>(value_) = value; *nonstd::get<Interframe*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -391,8 +392,8 @@ bool Option::SetInterframe(const Interframe& value) {
} }
bool Option::SetRenderMethod(const RenderMethod& value) { bool Option::SetRenderMethod(const RenderMethod& value) {
assert(is_render_method()); VBAM_CHECK(is_render_method());
assert(value < RenderMethod::kLast); VBAM_CHECK(value < RenderMethod::kLast);
const RenderMethod old_value = GetRenderMethod(); const RenderMethod old_value = GetRenderMethod();
*nonstd::get<RenderMethod*>(value_) = value; *nonstd::get<RenderMethod*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -402,8 +403,8 @@ bool Option::SetRenderMethod(const RenderMethod& value) {
} }
bool Option::SetAudioApi(const AudioApi& value) { bool Option::SetAudioApi(const AudioApi& value) {
assert(is_audio_api()); VBAM_CHECK(is_audio_api());
assert(value < AudioApi::kLast); VBAM_CHECK(value < AudioApi::kLast);
const AudioApi old_value = GetAudioApi(); const AudioApi old_value = GetAudioApi();
*nonstd::get<AudioApi*>(value_) = value; *nonstd::get<AudioApi*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -413,8 +414,8 @@ bool Option::SetAudioApi(const AudioApi& value) {
} }
bool Option::SetAudioRate(const AudioRate& value) { bool Option::SetAudioRate(const AudioRate& value) {
assert(is_audio_rate()); VBAM_CHECK(is_audio_rate());
assert(value < AudioRate::kLast); VBAM_CHECK(value < AudioRate::kLast);
const AudioRate old_value = GetAudioRate(); const AudioRate old_value = GetAudioRate();
*nonstd::get<AudioRate*>(value_) = value; *nonstd::get<AudioRate*>(value_) = value;
if (old_value != value) { if (old_value != value) {
@ -445,15 +446,15 @@ bool Option::SetEnumString(const wxString& value) {
case Option::Type::kUnsigned: case Option::Type::kUnsigned:
case Option::Type::kString: case Option::Type::kString:
case Option::Type::kGbPalette: case Option::Type::kGbPalette:
assert(false); VBAM_CHECK(false);
return false; return false;
} }
assert(false); VBAM_NOTREACHED();
return false; return false;
} }
bool Option::SetGbPalette(const std::array<uint16_t, 8>& value) { bool Option::SetGbPalette(const std::array<uint16_t, 8>& value) {
assert(is_gb_palette()); VBAM_CHECK(is_gb_palette());
uint16_t* dest = nonstd::get<uint16_t*>(value_); uint16_t* dest = nonstd::get<uint16_t*>(value_);
@ -471,7 +472,7 @@ bool Option::SetGbPalette(const std::array<uint16_t, 8>& value) {
} }
bool Option::SetGbPaletteString(const wxString& value) { bool Option::SetGbPaletteString(const wxString& value) {
assert(is_gb_palette()); VBAM_CHECK(is_gb_palette());
// 8 values of 4 chars and 7 commas. // 8 values of 4 chars and 7 commas.
static constexpr size_t kPaletteStringSize = 8 * 4 + 7; static constexpr size_t kPaletteStringSize = 8 * 4 + 7;
@ -497,50 +498,50 @@ bool Option::SetGbPaletteString(const wxString& value) {
} }
double Option::GetDoubleMin() const { double Option::GetDoubleMin() const {
assert(is_double()); VBAM_CHECK(is_double());
return nonstd::get<double>(min_); return nonstd::get<double>(min_);
} }
double Option::GetDoubleMax() const { double Option::GetDoubleMax() const {
assert(is_double()); VBAM_CHECK(is_double());
return nonstd::get<double>(max_); return nonstd::get<double>(max_);
} }
int32_t Option::GetIntMin() const { int32_t Option::GetIntMin() const {
assert(is_int()); VBAM_CHECK(is_int());
return nonstd::get<int32_t>(min_); return nonstd::get<int32_t>(min_);
} }
int32_t Option::GetIntMax() const { int32_t Option::GetIntMax() const {
assert(is_int()); VBAM_CHECK(is_int());
return nonstd::get<int32_t>(max_); return nonstd::get<int32_t>(max_);
} }
uint32_t Option::GetUnsignedMin() const { uint32_t Option::GetUnsignedMin() const {
assert(is_unsigned()); VBAM_CHECK(is_unsigned());
return nonstd::get<uint32_t>(min_); return nonstd::get<uint32_t>(min_);
} }
uint32_t Option::GetUnsignedMax() const { uint32_t Option::GetUnsignedMax() const {
assert(is_unsigned()); VBAM_CHECK(is_unsigned());
return nonstd::get<uint32_t>(max_); return nonstd::get<uint32_t>(max_);
} }
size_t Option::GetEnumMax() const { size_t Option::GetEnumMax() const {
assert(is_filter() || is_interframe() || is_render_method() || is_audio_api() || VBAM_CHECK(is_filter() || is_interframe() || is_render_method() || is_audio_api() ||
is_audio_rate()); is_audio_rate());
return nonstd::get<size_t>(max_); return nonstd::get<size_t>(max_);
} }
void Option::NextFilter() { void Option::NextFilter() {
assert(is_filter()); VBAM_CHECK(is_filter());
const int old_value = static_cast<int>(GetFilter()); const int old_value = static_cast<int>(GetFilter());
const int new_value = (old_value + 1) % kNbFilters; const int new_value = (old_value + 1) % kNbFilters;
SetFilter(static_cast<Filter>(new_value)); SetFilter(static_cast<Filter>(new_value));
} }
void Option::NextInterframe() { void Option::NextInterframe() {
assert(is_interframe()); VBAM_CHECK(is_interframe());
const int old_value = static_cast<int>(GetInterframe()); const int old_value = static_cast<int>(GetInterframe());
const int new_value = (old_value + 1) % kNbInterframes; const int new_value = (old_value + 1) % kNbInterframes;
SetInterframe(static_cast<Interframe>(new_value)); SetInterframe(static_cast<Interframe>(new_value));
@ -588,19 +589,19 @@ wxString Option::ToHelperString() const {
} }
void Option::AddObserver(Observer* observer) { void Option::AddObserver(Observer* observer) {
assert(observer); VBAM_CHECK(observer);
[[maybe_unused]] const auto pair = observers_.emplace(observer); [[maybe_unused]] const auto pair = observers_.emplace(observer);
assert(pair.second); VBAM_CHECK(pair.second);
} }
void Option::RemoveObserver(Observer* observer) { void Option::RemoveObserver(Observer* observer) {
assert(observer); VBAM_CHECK(observer);
[[maybe_unused]] const size_t removed = observers_.erase(observer); [[maybe_unused]] const size_t removed = observers_.erase(observer);
assert(removed == 1u); VBAM_CHECK(removed == 1u);
} }
void Option::CallObservers() { void Option::CallObservers() {
assert(!calling_observers_); VBAM_CHECK(!calling_observers_);
calling_observers_ = true; calling_observers_ = true;
for (const auto observer : observers_) { for (const auto observer : observers_) {
observer->OnValueChanged(); observer->OnValueChanged();

View File

@ -257,8 +257,7 @@ wxString JoyInput::ToConfigString() const {
return wxString::Format("%s-Hat%dE", joy_string, control_index_); return wxString::Format("%s-Hat%dE", joy_string, control_index_);
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return wxEmptyString; return wxEmptyString;
} }
@ -281,8 +280,7 @@ wxString JoyInput::ToLocalizedString() const {
return wxString::Format(_("%s: Hat %d East"), joy_string, control_index_); return wxString::Format(_("%s: Hat %d East"), joy_string, control_index_);
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return wxEmptyString; return wxEmptyString;
} }
@ -368,8 +366,7 @@ wxString UserInput::ToConfigString() const {
return joy_input().ToConfigString(); return joy_input().ToConfigString();
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return wxEmptyString; return wxEmptyString;
} }
@ -383,8 +380,7 @@ wxString UserInput::ToLocalizedString() const {
return joy_input().ToLocalizedString(); return joy_input().ToLocalizedString();
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return wxEmptyString; return wxEmptyString;
} }

View File

@ -1,7 +1,6 @@
#ifndef VBAM_WX_CONFIG_USER_INPUT_H_ #ifndef VBAM_WX_CONFIG_USER_INPUT_H_
#define VBAM_WX_CONFIG_USER_INPUT_H_ #define VBAM_WX_CONFIG_USER_INPUT_H_
#include <cassert>
#include <cstdint> #include <cstdint>
#include <unordered_set> #include <unordered_set>
@ -9,6 +8,8 @@
#include <wx/string.h> #include <wx/string.h>
#include "core/base/check.h"
namespace config { namespace config {
// Abstract representation of a keyboard input. This class is used to represent // Abstract representation of a keyboard input. This class is used to represent
@ -160,12 +161,12 @@ public:
Device device() const { return device_; } Device device() const { return device_; }
const KeyboardInput& keyboard_input() const { const KeyboardInput& keyboard_input() const {
assert(is_keyboard()); VBAM_CHECK(is_keyboard());
return nonstd::get<KeyboardInput>(input_); return nonstd::get<KeyboardInput>(input_);
}; };
const JoyInput& joy_input() const { const JoyInput& joy_input() const {
assert(is_joystick()); VBAM_CHECK(is_joystick());
return nonstd::get<JoyInput>(input_); return nonstd::get<JoyInput>(input_);
}; };
@ -247,8 +248,7 @@ struct std::hash<config::UserInput> {
std::hash<config::KeyboardInput>{}(user_input.keyboard_input()); std::hash<config::KeyboardInput>{}(user_input.keyboard_input());
} }
// Unreachable. VBAM_NOTREACHED();
assert(false);
return 0; return 0;
} }
}; };

View File

@ -6,6 +6,7 @@
#include <wx/menu.h> #include <wx/menu.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include "core/base/check.h"
#include "wx/config/bindings.h" #include "wx/config/bindings.h"
#include "wx/config/cmdtab.h" #include "wx/config/cmdtab.h"
#include "wx/config/command.h" #include "wx/config/command.h"
@ -112,9 +113,9 @@ AccelConfig* AccelConfig::NewInstance(wxWindow* parent,
wxMenuBar* menu, wxMenuBar* menu,
wxMenu* recents, wxMenu* recents,
const config::BindingsProvider bindings_provider) { const config::BindingsProvider bindings_provider) {
assert(parent); VBAM_CHECK(parent);
assert(menu); VBAM_CHECK(menu);
assert(recents); VBAM_CHECK(recents);
return new AccelConfig(parent, menu, recents, bindings_provider); return new AccelConfig(parent, menu, recents, bindings_provider);
} }
@ -123,7 +124,7 @@ AccelConfig::AccelConfig(wxWindow* parent,
wxMenu* recents, wxMenu* recents,
const config::BindingsProvider bindings_provider) const config::BindingsProvider bindings_provider)
: BaseDialog(parent, "AccelConfig"), bindings_provider_(bindings_provider) { : BaseDialog(parent, "AccelConfig"), bindings_provider_(bindings_provider) {
assert(menu); VBAM_CHECK(menu);
// Loads the various dialog elements. // Loads the various dialog elements.
tree_ = GetValidatedChild<wxTreeCtrl>("Commands"); tree_ = GetValidatedChild<wxTreeCtrl>("Commands");
@ -157,7 +158,7 @@ AccelConfig::AccelConfig(wxWindow* parent,
for (const auto& iter : command_to_item_id_) { for (const auto& iter : command_to_item_id_) {
const CommandTreeItemData* item_data = const CommandTreeItemData* item_data =
static_cast<const CommandTreeItemData*>(tree_->GetItemData(iter.second)); static_cast<const CommandTreeItemData*>(tree_->GetItemData(iter.second));
assert(item_data); VBAM_CHECK(item_data);
currently_assigned_label_->GetTextExtent(item_data->assigned_string(), &w, &h); currently_assigned_label_->GetTextExtent(item_data->assigned_string(), &w, &h);
size.SetWidth(std::max(w, size.GetWidth())); size.SetWidth(std::max(w, size.GetWidth()));
@ -277,10 +278,10 @@ void AccelConfig::OnAssignBinding(wxCommandEvent&) {
break; break;
case config::Command::Tag::kShortcut: case config::Command::Tag::kShortcut:
const auto iter = command_to_item_id_.find(old_command->shortcut()); const auto iter = command_to_item_id_.find(old_command->shortcut());
assert(iter != command_to_item_id_.end()); VBAM_CHECK(iter != command_to_item_id_.end());
const CommandTreeItemData* old_command_item_data = const CommandTreeItemData* old_command_item_data =
static_cast<const CommandTreeItemData*>(tree_->GetItemData(iter->second)); static_cast<const CommandTreeItemData*>(tree_->GetItemData(iter->second));
assert(old_command_item_data); VBAM_CHECK(old_command_item_data);
old_command_name = old_command_item_data->message_string(); old_command_name = old_command_item_data->message_string();
break; break;
} }
@ -318,7 +319,7 @@ void AccelConfig::OnKeyInput(wxCommandEvent&) {
break; break;
case config::Command::Tag::kShortcut: case config::Command::Tag::kShortcut:
const auto iter = command_to_item_id_.find(command->shortcut()); const auto iter = command_to_item_id_.find(command->shortcut());
assert(iter != command_to_item_id_.end()); VBAM_CHECK(iter != command_to_item_id_.end());
currently_assigned_label_->SetLabel( currently_assigned_label_->SetLabel(
static_cast<CommandTreeItemData*>(tree_->GetItemData(iter->second)) static_cast<CommandTreeItemData*>(tree_->GetItemData(iter->second))
->assigned_string()); ->assigned_string());

View File

@ -1,11 +1,10 @@
#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/base-dialog.h"
#include <cassert>
#include <wx/persist.h> #include <wx/persist.h>
#include <wx/persist/toplevel.h> #include <wx/persist/toplevel.h>
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include "core/base/check.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
#include "wx/widgets/utils.h" #include "wx/widgets/utils.h"
@ -73,7 +72,7 @@ private:
// static // static
wxDialog* BaseDialog::LoadDialog(wxWindow* parent, const wxString& xrc_file) { wxDialog* BaseDialog::LoadDialog(wxWindow* parent, const wxString& xrc_file) {
assert(parent); VBAM_CHECK(parent);
return new BaseDialog(parent, xrc_file); return new BaseDialog(parent, xrc_file);
} }
@ -85,8 +84,7 @@ BaseDialog::BaseDialog(wxWindow* parent, const wxString& xrc_file)
this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
#endif #endif
[[maybe_unused]] const bool success = wxXmlResource::Get()->LoadDialog(this, parent, xrc_file); VBAM_CHECK(wxXmlResource::Get()->LoadDialog(this, parent, xrc_file));
assert(success);
// Bind the event handler. // Bind the event handler.
this->Bind(wxEVT_SHOW, &BaseDialog::OnBaseDialogShow, this); this->Bind(wxEVT_SHOW, &BaseDialog::OnBaseDialogShow, this);
@ -96,7 +94,7 @@ BaseDialog::BaseDialog(wxWindow* parent, const wxString& xrc_file)
wxWindow* BaseDialog::GetValidatedChild(const wxString& name) const { wxWindow* BaseDialog::GetValidatedChild(const wxString& name) const {
wxWindow* window = this->FindWindow(name); wxWindow* window = this->FindWindow(name);
assert(window); VBAM_CHECK(window);
return window; return window;
} }

View File

@ -6,6 +6,8 @@
#include "wx/widgets/keep-on-top-styler.h" #include "wx/widgets/keep-on-top-styler.h"
#include "core/base/check.h"
namespace dialogs { namespace dialogs {
class BaseDialog : public wxDialog { class BaseDialog : public wxDialog {
@ -23,7 +25,7 @@ protected:
template <class T> template <class T>
T* GetValidatedChild(const wxString& name) const { T* GetValidatedChild(const wxString& name) const {
T* child = wxDynamicCast(this->GetValidatedChild(name), T); T* child = wxDynamicCast(this->GetValidatedChild(name), T);
assert(child); VBAM_CHECK(child);
return child; return child;
} }

View File

@ -2,6 +2,7 @@
#include <wx/filepicker.h> #include <wx/filepicker.h>
#include "core/base/check.h"
#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/base-dialog.h"
#include "wx/widgets/option-validator.h" #include "wx/widgets/option-validator.h"
@ -14,7 +15,7 @@ class DirectoryStringValidator final : public widgets::OptionValidator {
public: public:
DirectoryStringValidator(config::OptionID option_id) DirectoryStringValidator(config::OptionID option_id)
: widgets::OptionValidator(option_id) { : widgets::OptionValidator(option_id) {
assert(option()->is_string()); VBAM_CHECK(option()->is_string());
} }
~DirectoryStringValidator() final = default; ~DirectoryStringValidator() final = default;
@ -29,7 +30,7 @@ private:
bool WriteToWindow() final { bool WriteToWindow() final {
wxDirPickerCtrl* dir_picker = wxDirPickerCtrl* dir_picker =
wxDynamicCast(GetWindow(), wxDirPickerCtrl); wxDynamicCast(GetWindow(), wxDirPickerCtrl);
assert(dir_picker); VBAM_CHECK(dir_picker);
dir_picker->SetPath(option()->GetString()); dir_picker->SetPath(option()->GetString());
return true; return true;
} }
@ -37,7 +38,7 @@ private:
bool WriteToOption() final { bool WriteToOption() final {
const wxDirPickerCtrl* dir_picker = const wxDirPickerCtrl* dir_picker =
wxDynamicCast(GetWindow(), wxDirPickerCtrl); wxDynamicCast(GetWindow(), wxDirPickerCtrl);
assert(dir_picker); VBAM_CHECK(dir_picker);
return option()->SetString(dir_picker->GetPath()); return option()->SetString(dir_picker->GetPath());
} }
}; };
@ -52,7 +53,7 @@ void SetUpDirPicker(wxDirPickerCtrl* dir_picker,
// static // static
DirectoriesConfig* DirectoriesConfig::NewInstance(wxWindow* parent) { DirectoriesConfig* DirectoriesConfig::NewInstance(wxWindow* parent) {
assert(parent); VBAM_CHECK(parent);
return new DirectoriesConfig(parent); return new DirectoriesConfig(parent);
} }

View File

@ -146,7 +146,7 @@ public:
explicit RenderValidator(config::RenderMethod render_method) explicit RenderValidator(config::RenderMethod render_method)
: OptionValidator(config::OptionID::kDispRenderMethod), : OptionValidator(config::OptionID::kDispRenderMethod),
render_method_(render_method) { render_method_(render_method) {
assert(render_method != config::RenderMethod::kLast); VBAM_CHECK(render_method != config::RenderMethod::kLast);
} }
~RenderValidator() override = default; ~RenderValidator() override = default;
@ -189,7 +189,7 @@ private:
bool WriteToWindow() override { bool WriteToWindow() override {
wxChoice* plugin_selector = wxDynamicCast(GetWindow(), wxChoice); wxChoice* plugin_selector = wxDynamicCast(GetWindow(), wxChoice);
assert(plugin_selector); VBAM_CHECK(plugin_selector);
const wxString selected_plugin = option()->GetString(); const wxString selected_plugin = option()->GetString();
for (size_t i = 0; i < plugin_selector->GetCount(); i++) { for (size_t i = 0; i < plugin_selector->GetCount(); i++) {
const wxString& plugin_data = const wxString& plugin_data =
@ -206,7 +206,7 @@ private:
bool WriteToOption() override { bool WriteToOption() override {
wxChoice* plugin_selector = wxDynamicCast(GetWindow(), wxChoice); wxChoice* plugin_selector = wxDynamicCast(GetWindow(), wxChoice);
assert(plugin_selector); VBAM_CHECK(plugin_selector);
const wxString& selected_window_plugin = const wxString& selected_window_plugin =
dynamic_cast<wxStringClientData*>( dynamic_cast<wxStringClientData*>(
plugin_selector->GetClientObject( plugin_selector->GetClientObject(
@ -220,7 +220,7 @@ private:
// static // static
DisplayConfig* DisplayConfig::NewInstance(wxWindow* parent) { DisplayConfig* DisplayConfig::NewInstance(wxWindow* parent) {
assert(parent); VBAM_CHECK(parent);
return new DisplayConfig(parent); return new DisplayConfig(parent);
} }

View File

@ -13,6 +13,7 @@
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include "core/base/check.h"
#include "wx/config/option-observer.h" #include "wx/config/option-observer.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/base-dialog.h"
@ -90,8 +91,8 @@ public:
PaletteValidator(GBPalettePanelData* palette_data) PaletteValidator(GBPalettePanelData* palette_data)
: widgets::OptionValidator(palette_data->option_id_), : widgets::OptionValidator(palette_data->option_id_),
palette_data_(palette_data) { palette_data_(palette_data) {
assert(option()->is_gb_palette()); VBAM_CHECK(option()->is_gb_palette());
assert(palette_data); VBAM_CHECK(palette_data);
} }
~PaletteValidator() final = default; ~PaletteValidator() final = default;
@ -122,8 +123,8 @@ class BIOSPickerValidator final : public widgets::OptionValidator {
public: public:
BIOSPickerValidator(config::OptionID option_id, wxStaticText* label) BIOSPickerValidator(config::OptionID option_id, wxStaticText* label)
: widgets::OptionValidator(option_id), label_(label) { : widgets::OptionValidator(option_id), label_(label) {
assert(label_); VBAM_CHECK(label_);
assert(option()->is_string()); VBAM_CHECK(option()->is_string());
} }
~BIOSPickerValidator() final = default; ~BIOSPickerValidator() final = default;
@ -143,7 +144,7 @@ private:
} else { } else {
wxFilePickerCtrl* file_picker = wxFilePickerCtrl* file_picker =
wxDynamicCast(GetWindow(), wxFilePickerCtrl); wxDynamicCast(GetWindow(), wxFilePickerCtrl);
assert(file_picker); VBAM_CHECK(file_picker);
file_picker->SetPath(selection); file_picker->SetPath(selection);
label_->SetLabel(selection); label_->SetLabel(selection);
} }
@ -154,7 +155,7 @@ private:
bool WriteToOption() final { bool WriteToOption() final {
const wxFilePickerCtrl* file_picker = const wxFilePickerCtrl* file_picker =
wxDynamicCast(GetWindow(), wxFilePickerCtrl); wxDynamicCast(GetWindow(), wxFilePickerCtrl);
assert(file_picker); VBAM_CHECK(file_picker);
return option()->SetString(file_picker->GetPath()); return option()->SetString(file_picker->GetPath());
} }
@ -175,7 +176,7 @@ private:
bool TransferFromWindow() final { bool TransferFromWindow() final {
const wxChoice* borders_selector = wxDynamicCast(GetWindow(), wxChoice); const wxChoice* borders_selector = wxDynamicCast(GetWindow(), wxChoice);
assert(borders_selector); VBAM_CHECK(borders_selector);
switch (borders_selector->GetSelection()) { switch (borders_selector->GetSelection()) {
case 0: case 0:
OPTION(kPrefBorderOn) = false; OPTION(kPrefBorderOn) = false;
@ -199,7 +200,7 @@ private:
bool TransferToWindow() final { bool TransferToWindow() final {
wxChoice* borders_selector = wxDynamicCast(GetWindow(), wxChoice); wxChoice* borders_selector = wxDynamicCast(GetWindow(), wxChoice);
assert(borders_selector); VBAM_CHECK(borders_selector);
if (!OPTION(kPrefBorderOn) && !OPTION(kPrefBorderAutomatic)) { if (!OPTION(kPrefBorderOn) && !OPTION(kPrefBorderAutomatic)) {
borders_selector->SetSelection(0); borders_selector->SetSelection(0);
@ -225,8 +226,8 @@ GBPalettePanelData::GBPalettePanelData(wxPanel* panel, size_t palette_id)
default_selector_(widgets::GetValidatedChild<wxChoice>(panel, "DefaultPalette")), default_selector_(widgets::GetValidatedChild<wxChoice>(panel, "DefaultPalette")),
option_id_(static_cast<config::OptionID>(static_cast<size_t>(config::OptionID::kGBPalette0) + option_id_(static_cast<config::OptionID>(static_cast<size_t>(config::OptionID::kGBPalette0) +
palette_id)) { palette_id)) {
assert(panel); VBAM_CHECK(panel);
assert(palette_id < kNbPalettes); VBAM_CHECK(palette_id < kNbPalettes);
default_selector_->Bind( default_selector_->Bind(
wxEVT_CHOICE, &GBPalettePanelData::OnDefaultPaletteSelected, this); wxEVT_CHOICE, &GBPalettePanelData::OnDefaultPaletteSelected, this);
@ -274,7 +275,7 @@ void GBPalettePanelData::UpdateColourPickers() {
void GBPalettePanelData::OnColourChanged(size_t colour_index, void GBPalettePanelData::OnColourChanged(size_t colour_index,
wxColourPickerEvent& event) { wxColourPickerEvent& event) {
assert(colour_index < palette_.size()); VBAM_CHECK(colour_index < palette_.size());
// Update the colour value. // Update the colour value.
const wxColour colour = event.GetColour(); const wxColour colour = event.GetColour();
@ -313,7 +314,7 @@ void GBPalettePanelData::OnPaletteReset(wxCommandEvent& event) {
// static // static
GameBoyConfig* GameBoyConfig::NewInstance(wxWindow* parent) { GameBoyConfig* GameBoyConfig::NewInstance(wxWindow* parent) {
assert(parent); VBAM_CHECK(parent);
return new GameBoyConfig(parent); return new GameBoyConfig(parent);
} }

View File

@ -3,6 +3,7 @@
#include <wx/control.h> #include <wx/control.h>
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include "core/base/check.h"
#include "core/base/sizes.h" #include "core/base/sizes.h"
#include "core/gb/gb.h" #include "core/gb/gb.h"
#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/base-dialog.h"
@ -92,11 +93,11 @@ wxString GetCartCGBFlag() {
return wxString::Format(_("%02X (Supported)"), g_gbCartData.cgb_flag()); return wxString::Format(_("%02X (Supported)"), g_gbCartData.cgb_flag());
case gbCartData::CGBSupport::kRequired: case gbCartData::CGBSupport::kRequired:
return wxString::Format(_("%02X (Required)"), g_gbCartData.cgb_flag()); return wxString::Format(_("%02X (Required)"), g_gbCartData.cgb_flag());
default:
// Unreachable.
assert(false);
return "";
} }
VBAM_NOTREACHED();
return "";
} }
// Returns a localized string indicating the ROM size of the loaded GB/GBC cartridge. // Returns a localized string indicating the ROM size of the loaded GB/GBC cartridge.
@ -156,18 +157,17 @@ wxString GetCartDestinationCode() {
return wxString::Format(_("%02X (World)"), g_gbCartData.destination_code_flag()); return wxString::Format(_("%02X (World)"), g_gbCartData.destination_code_flag());
case gbCartData::DestinationCode::kUnknown: case gbCartData::DestinationCode::kUnknown:
return wxString::Format(_("%02X (Unknown)"), g_gbCartData.destination_code_flag()); return wxString::Format(_("%02X (Unknown)"), g_gbCartData.destination_code_flag());
default:
// Unreachable.
assert(false);
return "";
} }
VBAM_NOTREACHED();
return "";
} }
} // namespace } // namespace
// static // static
GbRomInfo* GbRomInfo::NewInstance(wxWindow* parent) { GbRomInfo* GbRomInfo::NewInstance(wxWindow* parent) {
assert(parent); VBAM_CHECK(parent);
return new GbRomInfo(parent); return new GbRomInfo(parent);
} }

View File

@ -2,6 +2,7 @@
#include <wx/checkbox.h> #include <wx/checkbox.h>
#include "core/base/check.h"
#include "wx/config/command.h" #include "wx/config/command.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/base-dialog.h"
@ -40,7 +41,7 @@ protected:
UserInputCtrlValidator::UserInputCtrlValidator(const config::GameCommand game_control, UserInputCtrlValidator::UserInputCtrlValidator(const config::GameCommand game_control,
config::BindingsProvider const bindings_provider) config::BindingsProvider const bindings_provider)
: wxValidator(), game_control_(game_control), bindings_provider(bindings_provider) { : wxValidator(), game_control_(game_control), bindings_provider(bindings_provider) {
assert(bindings_provider); VBAM_CHECK(bindings_provider);
} }
wxObject* UserInputCtrlValidator::Clone() const { wxObject* UserInputCtrlValidator::Clone() const {
@ -49,7 +50,7 @@ wxObject* UserInputCtrlValidator::Clone() const {
bool UserInputCtrlValidator::TransferToWindow() { bool UserInputCtrlValidator::TransferToWindow() {
widgets::UserInputCtrl* control = wxDynamicCast(GetWindow(), widgets::UserInputCtrl); widgets::UserInputCtrl* control = wxDynamicCast(GetWindow(), widgets::UserInputCtrl);
assert(control); VBAM_CHECK(control);
control->SetInputs(bindings_provider()->InputsForCommand(config::Command(game_control_))); control->SetInputs(bindings_provider()->InputsForCommand(config::Command(game_control_)));
return true; return true;
@ -57,7 +58,7 @@ bool UserInputCtrlValidator::TransferToWindow() {
bool UserInputCtrlValidator::TransferFromWindow() { bool UserInputCtrlValidator::TransferFromWindow() {
widgets::UserInputCtrl* control = wxDynamicCast(GetWindow(), widgets::UserInputCtrl); widgets::UserInputCtrl* control = wxDynamicCast(GetWindow(), widgets::UserInputCtrl);
assert(control); VBAM_CHECK(control);
bindings_provider()->ClearCommandAssignments(config::Command(game_control_)); bindings_provider()->ClearCommandAssignments(config::Command(game_control_));
for (const auto& input : control->inputs()) { for (const auto& input : control->inputs()) {
@ -72,8 +73,8 @@ bool UserInputCtrlValidator::TransferFromWindow() {
// static // static
JoypadConfig* JoypadConfig::NewInstance(wxWindow* parent, JoypadConfig* JoypadConfig::NewInstance(wxWindow* parent,
const config::BindingsProvider bindings_provider) { const config::BindingsProvider bindings_provider) {
assert(parent); VBAM_CHECK(parent);
assert(bindings_provider); VBAM_CHECK(bindings_provider);
return new JoypadConfig(parent, bindings_provider); return new JoypadConfig(parent, bindings_provider);
} }
@ -110,7 +111,7 @@ JoypadConfig::JoypadConfig(wxWindow* parent, const config::BindingsProvider bind
if (current_parent == prev_parent) { if (current_parent == prev_parent) {
// The first control will be skipped here, but that's fine since // The first control will be skipped here, but that's fine since
// we don't care where it fits in the tab order. // we don't care where it fits in the tab order.
assert(prev); VBAM_CHECK(prev);
game_key_control->MoveAfterInTabOrder(prev); game_key_control->MoveAfterInTabOrder(prev);
} }
prev = game_key_control; prev = game_key_control;

View File

@ -12,6 +12,7 @@
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include <functional> #include <functional>
#include "core/base/check.h"
#include "wx/audio/audio.h" #include "wx/audio/audio.h"
#include "wx/config/option-id.h" #include "wx/config/option-id.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
@ -37,14 +38,14 @@ private:
bool WriteToWindow() override { bool WriteToWindow() override {
wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
choice->SetSelection(static_cast<int>(option()->GetAudioRate())); choice->SetSelection(static_cast<int>(option()->GetAudioRate()));
return true; return true;
} }
bool WriteToOption() override { bool WriteToOption() override {
const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
const int selection = choice->GetSelection(); const int selection = choice->GetSelection();
if (selection == wxNOT_FOUND) { if (selection == wxNOT_FOUND) {
return false; return false;
@ -63,7 +64,7 @@ class AudioApiValidator : public widgets::OptionValidator {
public: public:
explicit AudioApiValidator(config::AudioApi audio_api) explicit AudioApiValidator(config::AudioApi audio_api)
: OptionValidator(config::OptionID::kSoundAudioAPI), audio_api_(audio_api) { : OptionValidator(config::OptionID::kSoundAudioAPI), audio_api_(audio_api) {
assert(audio_api < config::AudioApi::kLast); VBAM_CHECK(audio_api < config::AudioApi::kLast);
} }
~AudioApiValidator() override = default; ~AudioApiValidator() override = default;
@ -103,7 +104,7 @@ private:
bool WriteToWindow() override { bool WriteToWindow() override {
wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
const wxString& device_id = option()->GetString(); const wxString& device_id = option()->GetString();
for (size_t i = 0; i < choice->GetCount(); i++) { for (size_t i = 0; i < choice->GetCount(); i++) {
@ -121,7 +122,7 @@ private:
bool WriteToOption() override { bool WriteToOption() override {
const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
const int selection = choice->GetSelection(); const int selection = choice->GetSelection();
if (selection == wxNOT_FOUND) { if (selection == wxNOT_FOUND) {
return option()->SetString(wxEmptyString); return option()->SetString(wxEmptyString);
@ -136,7 +137,7 @@ private:
// static // static
SoundConfig* SoundConfig::NewInstance(wxWindow* parent) { SoundConfig* SoundConfig::NewInstance(wxWindow* parent) {
assert(parent); VBAM_CHECK(parent);
return new SoundConfig(parent); return new SoundConfig(parent);
} }

View File

@ -118,7 +118,7 @@ opts_t::opts_t()
void load_opts(bool first_time_launch) { void load_opts(bool first_time_launch) {
// just for sanity... // just for sanity...
static bool did_init = false; static bool did_init = false;
assert(!did_init); VBAM_CHECK(!did_init);
did_init = true; did_init = true;
// enumvals should not be translated, since they would cause config file // enumvals should not be translated, since they would cause config file
@ -447,8 +447,7 @@ void opt_set(const wxString& name, const wxString& val) {
if (opt && !opt->is_none()) { if (opt && !opt->is_none()) {
switch (opt->type()) { switch (opt->type()) {
case config::Option::Type::kNone: case config::Option::Type::kNone:
// This should never happen. VBAM_NOTREACHED();
assert(false);
return; return;
case config::Option::Type::kBool: case config::Option::Type::kBool:
if (val != '0' && val != '1') { if (val != '0' && val != '1') {

View File

@ -25,6 +25,7 @@
#include "components/filters/filters.h" #include "components/filters/filters.h"
#include "components/filters_agb/filters_agb.h" #include "components/filters_agb/filters_agb.h"
#include "components/filters_interframe/interframe.h" #include "components/filters_interframe/interframe.h"
#include "core/base/check.h"
#include "core/base/file_util.h" #include "core/base/file_util.h"
#include "core/base/patch.h" #include "core/base/patch.h"
#include "core/base/system.h" #include "core/base/system.h"
@ -89,10 +90,10 @@ double GetFilterScale() {
return 6.0; return 6.0;
case config::Filter::kPlugin: case config::Filter::kPlugin:
case config::Filter::kLast: case config::Filter::kLast:
assert(false); VBAM_NOTREACHED();
return 1.0; return 1.0;
} }
assert(false); VBAM_NOTREACHED();
return 1.0; return 1.0;
} }
@ -111,10 +112,10 @@ long GetSampleRate() {
return 11025; return 11025;
break; break;
case config::AudioRate::kLast: case config::AudioRate::kLast:
assert(false); VBAM_NOTREACHED();
return 44100; return 44100;
} }
assert(false); VBAM_NOTREACHED();
return 44100; return 44100;
} }
@ -1169,7 +1170,7 @@ void GameArea::OnIdle(wxIdleEvent& event)
break; break;
#endif #endif
case config::RenderMethod::kLast: case config::RenderMethod::kLast:
assert(false); VBAM_NOTREACHED();
return; return;
} }
@ -1615,7 +1616,7 @@ private:
break; break;
case config::Interframe::kLast: case config::Interframe::kLast:
assert(false); VBAM_NOTREACHED();
break; break;
} }
} }
@ -1758,7 +1759,7 @@ private:
case config::Filter::kNone: case config::Filter::kNone:
case config::Filter::kLast: case config::Filter::kLast:
assert(false); VBAM_NOTREACHED();
break; break;
} }
} }

View File

@ -1,12 +1,12 @@
#ifndef VBAM_WX_WIDGETS_CLIENT_DATA_H_ #ifndef VBAM_WX_WIDGETS_CLIENT_DATA_H_
#define VBAM_WX_WIDGETS_CLIENT_DATA_H_ #define VBAM_WX_WIDGETS_CLIENT_DATA_H_
#include <cassert>
#include <wx/clntdata.h> #include <wx/clntdata.h>
#include <wx/ctrlsub.h> #include <wx/ctrlsub.h>
#include <wx/window.h> #include <wx/window.h>
#include "core/base/check.h"
namespace widgets { namespace widgets {
// A simple wxClientData subclass that holds a single piece of data. // A simple wxClientData subclass that holds a single piece of data.
@ -16,14 +16,14 @@ public:
// Returns the data stored in the ClientData object. // Returns the data stored in the ClientData object.
static const T& From(wxWindow* window) { static const T& From(wxWindow* window) {
wxClientData* data = window->GetClientObject(); wxClientData* data = window->GetClientObject();
assert(data); VBAM_CHECK(data);
return static_cast<ClientData<T>*>(data)->data(); return static_cast<ClientData<T>*>(data)->data();
} }
// Returns the data stored in the ClientData object for a container. // Returns the data stored in the ClientData object for a container.
static const T& From(wxItemContainer* container, size_t index) { static const T& From(wxItemContainer* container, size_t index) {
wxClientData* data = container->GetClientObject(index); wxClientData* data = container->GetClientObject(index);
assert(data); VBAM_CHECK(data);
return static_cast<ClientData<T>*>(data)->data(); return static_cast<ClientData<T>*>(data)->data();
} }

View File

@ -1,5 +1,7 @@
#include "wx/widgets/group-check-box.h" #include "wx/widgets/group-check-box.h"
#include "core/base/check.h"
namespace widgets { namespace widgets {
namespace { namespace {
@ -8,7 +10,7 @@ wxWindow* FindTopLevelWindow(wxWindow* window) {
while (window != nullptr && !window->IsTopLevel()) { while (window != nullptr && !window->IsTopLevel()) {
window = window->GetParent(); window = window->GetParent();
} }
assert(window); VBAM_CHECK(window);
return window; return window;
} }
@ -77,7 +79,7 @@ bool GroupCheckBox::Create(wxWindow* parent,
} }
void GroupCheckBox::AddToGroup() { void GroupCheckBox::AddToGroup() {
assert(next_ == this); VBAM_CHECK(next_ == this);
if (GetName().IsEmpty()) { if (GetName().IsEmpty()) {
// No name means a singleton. // No name means a singleton.

View File

@ -2,6 +2,7 @@
#include <wx/toplevel.h> #include <wx/toplevel.h>
#include "core/base/check.h"
#include "wx/config/option.h" #include "wx/config/option.h"
namespace widgets { namespace widgets {
@ -12,7 +13,7 @@ KeepOnTopStyler::KeepOnTopStyler(wxTopLevelWindow* window)
std::bind(&KeepOnTopStyler::OnKeepOnTopChanged, std::bind(&KeepOnTopStyler::OnKeepOnTopChanged,
this, this,
std::placeholders::_1)) { std::placeholders::_1)) {
assert(window_); VBAM_CHECK(window_);
window_->Bind(wxEVT_SHOW, &KeepOnTopStyler::OnShow, this); window_->Bind(wxEVT_SHOW, &KeepOnTopStyler::OnShow, this);
} }

View File

@ -6,6 +6,8 @@
#include <wx/slider.h> #include <wx/slider.h>
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include "core/base/check.h"
namespace widgets { namespace widgets {
OptionValidator::OptionValidator(config::OptionID option_id) OptionValidator::OptionValidator(config::OptionID option_id)
@ -27,21 +29,21 @@ bool OptionValidator::TransferToWindow() {
void OptionValidator::SetWindow(wxWindow* window) { void OptionValidator::SetWindow(wxWindow* window) {
wxValidator::SetWindow(window); wxValidator::SetWindow(window);
[[maybe_unused]] const bool write_success = WriteToWindow(); [[maybe_unused]] const bool write_success = WriteToWindow();
assert(write_success); VBAM_CHECK(write_success);
} }
#endif #endif
void OptionValidator::OnValueChanged() { void OptionValidator::OnValueChanged() {
[[maybe_unused]] const bool write_success = WriteToWindow(); [[maybe_unused]] const bool write_success = WriteToWindow();
assert(write_success); VBAM_CHECK(write_success);
} }
OptionSelectedValidator::OptionSelectedValidator(config::OptionID option_id, OptionSelectedValidator::OptionSelectedValidator(config::OptionID option_id,
uint32_t value) uint32_t value)
: OptionValidator(option_id), value_(value) { : OptionValidator(option_id), value_(value) {
assert(option()->is_unsigned()); VBAM_CHECK(option()->is_unsigned());
assert(value_ >= option()->GetUnsignedMin()); VBAM_CHECK(value_ >= option()->GetUnsignedMin());
assert(value_ <= option()->GetUnsignedMax()); VBAM_CHECK(value_ <= option()->GetUnsignedMax());
} }
wxObject* OptionSelectedValidator::Clone() const { wxObject* OptionSelectedValidator::Clone() const {
@ -65,7 +67,7 @@ bool OptionSelectedValidator::WriteToWindow() {
return true; return true;
} }
assert(false); VBAM_NOTREACHED();
return false; return false;
} }
@ -87,13 +89,13 @@ bool OptionSelectedValidator::WriteToOption() {
return true; return true;
} }
assert(false); VBAM_NOTREACHED();
return false; return false;
} }
OptionIntValidator::OptionIntValidator(config::OptionID option_id) OptionIntValidator::OptionIntValidator(config::OptionID option_id)
: OptionValidator(option_id) { : OptionValidator(option_id) {
assert(option()->is_int()); VBAM_CHECK(option()->is_int());
} }
wxObject* OptionIntValidator::Clone() const { wxObject* OptionIntValidator::Clone() const {
@ -117,7 +119,7 @@ bool OptionIntValidator::WriteToWindow() {
return true; return true;
} }
assert(false); VBAM_NOTREACHED();
return false; return false;
} }
@ -132,13 +134,13 @@ bool OptionIntValidator::WriteToOption() {
return option()->SetInt(slider->GetValue()); return option()->SetInt(slider->GetValue());
} }
assert(false); VBAM_NOTREACHED();
return false; return false;
} }
OptionChoiceValidator::OptionChoiceValidator(config::OptionID option_id) OptionChoiceValidator::OptionChoiceValidator(config::OptionID option_id)
: OptionValidator(option_id) { : OptionValidator(option_id) {
assert(option()->is_unsigned()); VBAM_CHECK(option()->is_unsigned());
} }
wxObject* OptionChoiceValidator::Clone() const { wxObject* OptionChoiceValidator::Clone() const {
@ -151,20 +153,20 @@ bool OptionChoiceValidator::IsWindowValueValid() {
bool OptionChoiceValidator::WriteToWindow() { bool OptionChoiceValidator::WriteToWindow() {
wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
choice->SetSelection(option()->GetUnsigned()); choice->SetSelection(option()->GetUnsigned());
return true; return true;
} }
bool OptionChoiceValidator::WriteToOption() { bool OptionChoiceValidator::WriteToOption() {
const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice); const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
assert(choice); VBAM_CHECK(choice);
return option()->SetUnsigned(choice->GetSelection()); return option()->SetUnsigned(choice->GetSelection());
} }
OptionBoolValidator::OptionBoolValidator(config::OptionID option_id) OptionBoolValidator::OptionBoolValidator(config::OptionID option_id)
: OptionValidator(option_id) { : OptionValidator(option_id) {
assert(option()->is_bool()); VBAM_CHECK(option()->is_bool());
} }
wxObject* OptionBoolValidator::Clone() const { wxObject* OptionBoolValidator::Clone() const {
@ -177,14 +179,14 @@ bool OptionBoolValidator::IsWindowValueValid() {
bool OptionBoolValidator::WriteToWindow() { bool OptionBoolValidator::WriteToWindow() {
wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox); wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
assert(checkbox); VBAM_CHECK(checkbox);
checkbox->SetValue(option()->GetBool()); checkbox->SetValue(option()->GetBool());
return true; return true;
} }
bool OptionBoolValidator::WriteToOption() { bool OptionBoolValidator::WriteToOption() {
const wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox); const wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
assert(checkbox); VBAM_CHECK(checkbox);
return option()->SetBool(checkbox->GetValue()); return option()->SetBool(checkbox->GetValue());
} }

View File

@ -1,9 +1,11 @@
#include "wx/widgets/render-plugin.h" #include "wx/widgets/render-plugin.h"
#include "core/base/check.h"
namespace widgets { namespace widgets {
RENDER_PLUGIN_INFO* MaybeLoadFilterPlugin(const wxString& path, wxDynamicLibrary* filter_plugin) { RENDER_PLUGIN_INFO* MaybeLoadFilterPlugin(const wxString& path, wxDynamicLibrary* filter_plugin) {
assert(filter_plugin); VBAM_CHECK(filter_plugin);
if (!filter_plugin->Load(path, wxDL_VERBATIM | wxDL_NOW | wxDL_QUIET)) { if (!filter_plugin->Load(path, wxDL_VERBATIM | wxDL_NOW | wxDL_QUIET)) {
return nullptr; return nullptr;

View File

@ -1,6 +1,5 @@
#include "wx/widgets/sdl-poller.h" #include "wx/widgets/sdl-poller.h"
#include <cassert>
#include <map> #include <map>
#include <wx/timer.h> #include <wx/timer.h>
@ -8,6 +7,7 @@
#include <SDL.h> #include <SDL.h>
#include "core/base/check.h"
#include "wx/config/option-id.h" #include "wx/config/option-id.h"
#include "wx/config/option-observer.h" #include "wx/config/option-observer.h"
#include "wx/config/option-proxy.h" #include "wx/config/option-proxy.h"
@ -38,7 +38,7 @@ config::JoyControl AxisStatusToJoyControl(const JoyAxisStatus& status) {
case JoyAxisStatus::Neutral: case JoyAxisStatus::Neutral:
default: default:
// This should never happen. // This should never happen.
assert(false); VBAM_NOTREACHED();
return config::JoyControl::AxisPlus; return config::JoyControl::AxisPlus;
} }
} }
@ -55,7 +55,7 @@ config::JoyControl HatStatusToJoyControl(const uint8_t status) {
return config::JoyControl::HatEast; return config::JoyControl::HatEast;
default: default:
// This should never happen. // This should never happen.
assert(false); VBAM_NOTREACHED();
return config::JoyControl::HatNorth; return config::JoyControl::HatNorth;
} }
} }
@ -306,7 +306,7 @@ SdlPoller::SdlPoller(EventHandlerProvider* const handler_provider)
game_controller_enabled_observer_( game_controller_enabled_observer_(
config::OptionID::kSDLGameControllerMode, config::OptionID::kSDLGameControllerMode,
[this](config::Option* option) { ReconnectControllers(option->GetBool()); }) { [this](config::Option* option) { ReconnectControllers(option->GetBool()); }) {
assert(handler_provider); VBAM_CHECK(handler_provider);
wxTimer::Start(50); wxTimer::Start(50);
SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS); SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS);

View File

@ -2,6 +2,7 @@
#include <wx/time.h> #include <wx/time.h>
#include "core/base/check.h"
#include "wx/config/user-input.h" #include "wx/config/user-input.h"
#include "wx/widgets/user-input-event.h" #include "wx/widgets/user-input-event.h"
@ -50,7 +51,7 @@ void UserInputCtrl::SetInputs(const std::unordered_set<config::UserInput>& input
} }
config::UserInput UserInputCtrl::SingleInput() const { config::UserInput UserInputCtrl::SingleInput() const {
assert(!is_multikey_); VBAM_CHECK(!is_multikey_);
if (inputs_.empty()) { if (inputs_.empty()) {
return config::UserInput(); return config::UserInput();
} }

View File

@ -153,7 +153,7 @@ wxEvent* UserInputEvent::Clone() const {
KeyboardInputSender::KeyboardInputSender(EventHandlerProvider* const handler_provider) KeyboardInputSender::KeyboardInputSender(EventHandlerProvider* const handler_provider)
: handler_provider_(handler_provider) { : handler_provider_(handler_provider) {
assert(handler_provider_); VBAM_CHECK(handler_provider_);
} }
KeyboardInputSender::~KeyboardInputSender() = default; KeyboardInputSender::~KeyboardInputSender() = default;

View File

@ -1,11 +1,11 @@
#ifndef VBAM_WX_WIDGETS_UTILS_H_ #ifndef VBAM_WX_WIDGETS_UTILS_H_
#define VBAM_WX_WIDGETS_UTILS_H_ #define VBAM_WX_WIDGETS_UTILS_H_
#include <cassert>
#include <wx/window.h> #include <wx/window.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include "core/base/check.h"
// This file contains a collection of various utility functions for wxWidgets. // This file contains a collection of various utility functions for wxWidgets.
namespace widgets { namespace widgets {
@ -18,14 +18,14 @@ wxRect GetDisplayRect();
inline wxWindow* GetValidatedChild(const wxWindow* parent, inline wxWindow* GetValidatedChild(const wxWindow* parent,
const wxString& name) { const wxString& name) {
wxWindow* window = parent->FindWindow(name); wxWindow* window = parent->FindWindow(name);
assert(window); VBAM_CHECK(window);
return window; return window;
} }
template <class T> template <class T>
T* GetValidatedChild(const wxWindow* parent, const wxString& name) { T* GetValidatedChild(const wxWindow* parent, const wxString& name) {
T* child = wxDynamicCast(GetValidatedChild(parent, name), T); T* child = wxDynamicCast(GetValidatedChild(parent, name), T);
assert(child); VBAM_CHECK(child);
return child; return child;
} }

View File

@ -63,10 +63,10 @@ void ResetMenuItemAccelerator(wxMenuItem* menu_item) {
std::unordered_set<config::UserInput> user_inputs = std::unordered_set<config::UserInput> user_inputs =
wxGetApp().bindings()->InputsForCommand( wxGetApp().bindings()->InputsForCommand(
config::ShortcutCommand(menu_item->GetId())); config::ShortcutCommand(menu_item->GetId()));
for (const config::UserInput& user_input : user_inputs) { if (!user_inputs.empty()) {
const config::UserInput& user_input = *user_inputs.begin();
new_label.append('\t'); new_label.append('\t');
new_label.append(user_input.ToLocalizedString()); new_label.append(user_input.ToLocalizedString());
break;
} }
if (old_label != new_label) { if (old_label != new_label) {