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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,7 @@
#include <wx/msgdlg.h>
#include "components/filters_interframe/interframe.h"
#include "core/base/check.h"
#include "core/base/version.h"
#include "core/gb/gb.h"
#include "core/gb/gbCheats.h"
@ -32,7 +33,7 @@
void MainFrame::GetMenuOptionBool(const wxString& menuName, bool* field)
{
assert(field);
VBAM_CHECK(field);
*field = !*field;
int id = wxXmlResource::GetXRCID(menuName);
@ -48,7 +49,7 @@ void MainFrame::GetMenuOptionBool(const wxString& menuName, bool* field)
void MainFrame::GetMenuOptionConfig(const wxString& menu_name,
const config::OptionID& option_id) {
config::Option* option = config::Option::ByID(option_id);
assert(option);
VBAM_CHECK(option);
int id = wxXmlResource::GetXRCID(menu_name);
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);
break;
default:
assert(false);
VBAM_CHECK(false);
return;
}
break;
@ -73,7 +74,7 @@ void MainFrame::GetMenuOptionConfig(const wxString& menu_name,
void MainFrame::GetMenuOptionInt(const wxString& menuName, int* field, int mask)
{
assert(field);
VBAM_CHECK(field);
int value = mask;
bool is_checked = ((*field) & (mask)) != (value);
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) {
assert(input);
VBAM_CHECK(input);
auto iter = input_to_control_.find(input);
if (iter == input_to_control_.end()) {
@ -194,7 +194,7 @@ void Bindings::UnassignInput(const UserInput& input) {
// Otherwise, just remove it from the 2 maps.
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);
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);
assert(command_iter != control_to_inputs_.end());
VBAM_CHECK(command_iter != control_to_inputs_.end());
command_iter->second.erase(input);
if (command_iter->second.empty()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,18 +21,16 @@ TEST(OptionTest, Bool) {
EXPECT_TRUE(option->SetBool(false));
EXPECT_FALSE(option->GetBool());
#if !defined(NDEBUG)
EXPECT_DEATH(option->SetDouble(2.0), ".*");
EXPECT_DEATH(option->SetInt(2), ".*");
EXPECT_DEATH(option->SetUnsigned(2), ".*");
EXPECT_DEATH(option->SetString("foo"), ".*");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), ".*");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), ".*");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), ".*");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), ".*");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), ".*");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), ".*");
#endif // !defined(NDEBUG)
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\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
TEST(OptionTest, Double) {
@ -56,18 +54,205 @@ TEST(OptionTest, Double) {
EXPECT_FALSE(option->SetDouble(7.0));
EXPECT_DOUBLE_EQ(option->GetDouble(), 2.5);
#if !defined(NDEBUG)
EXPECT_DEATH(option->SetBool(true), ".*");
EXPECT_DEATH(option->SetInt(2), ".*");
EXPECT_DEATH(option->SetUnsigned(2), ".*");
EXPECT_DEATH(option->SetString("foo"), ".*");
EXPECT_DEATH(option->SetFilter(config::Filter::kNone), ".*");
EXPECT_DEATH(option->SetInterframe(config::Interframe::kNone), ".*");
EXPECT_DEATH(option->SetRenderMethod(config::RenderMethod::kSimple), ".*");
EXPECT_DEATH(option->SetAudioApi(config::AudioApi::kOpenAL), ".*");
EXPECT_DEATH(option->SetAudioRate(config::AudioRate::k11kHz), ".*");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), ".*");
#endif // !defined(NDEBUG)
EXPECT_DEATH(option->SetBool(true), "is_bool\\(\\)");
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\\(\\)");
EXPECT_DEATH(option->SetGbPalette({0, 1, 2, 3, 4, 5, 6, 7}), "is_gb_palette\\(\\)");
}
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) {
@ -110,6 +295,16 @@ TEST(Optiontest, GbPalette) {
EXPECT_FALSE(option->SetGbPaletteString(""));
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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -118,7 +118,7 @@ opts_t::opts_t()
void load_opts(bool first_time_launch) {
// just for sanity...
static bool did_init = false;
assert(!did_init);
VBAM_CHECK(!did_init);
did_init = true;
// 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()) {
switch (opt->type()) {
case config::Option::Type::kNone:
// This should never happen.
assert(false);
VBAM_NOTREACHED();
return;
case config::Option::Type::kBool:
if (val != '0' && val != '1') {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,11 @@
#include "wx/widgets/render-plugin.h"
#include "core/base/check.h"
namespace widgets {
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)) {
return nullptr;

View File

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

View File

@ -2,6 +2,7 @@
#include <wx/time.h>
#include "core/base/check.h"
#include "wx/config/user-input.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 {
assert(!is_multikey_);
VBAM_CHECK(!is_multikey_);
if (inputs_.empty()) {
return config::UserInput();
}

View File

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

View File

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

View File

@ -63,10 +63,10 @@ void ResetMenuItemAccelerator(wxMenuItem* menu_item) {
std::unordered_set<config::UserInput> user_inputs =
wxGetApp().bindings()->InputsForCommand(
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(user_input.ToLocalizedString());
break;
}
if (old_label != new_label) {