diff --git a/src/core/base/CMakeLists.txt b/src/core/base/CMakeLists.txt index 430da3eb..d6284c3a 100644 --- a/src/core/base/CMakeLists.txt +++ b/src/core/base/CMakeLists.txt @@ -35,6 +35,7 @@ target_sources(vbam-core-base version.cpp PUBLIC + check.h array.h file_util.h image_util.h diff --git a/src/core/base/check.h b/src/core/base/check.h new file mode 100644 index 00000000..4c44a94f --- /dev/null +++ b/src/core/base/check.h @@ -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_ diff --git a/src/core/gb/gb.cpp b/src/core/gb/gb.cpp index 01fb1266..bf1fa3cb 100644 --- a/src/core/gb/gb.cpp +++ b/src/core/gb/gb.cpp @@ -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, diff --git a/src/core/gb/gbCartData.cpp b/src/core/gb/gbCartData.cpp index ca04b2cc..1ed88e25 100644 --- a/src/core/gb/gbCartData.cpp +++ b/src/core/gb/gbCartData.cpp @@ -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; diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index d238f0b3..6fefd82c 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -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 */ diff --git a/src/wx/audio/audio.cpp b/src/wx/audio/audio.cpp index 208dad20..eb08b2bb 100644 --- a/src/wx/audio/audio.cpp +++ b/src/wx/audio/audio.cpp @@ -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; } } diff --git a/src/wx/audio/internal/faudio.cpp b/src/wx/audio/internal/faudio.cpp index e332495b..18aaed17 100644 --- a/src/wx/audio/internal/faudio.cpp +++ b/src/wx/audio/internal/faudio.cpp @@ -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 diff --git a/src/wx/audio/internal/openal.cpp b/src/wx/audio/internal/openal.cpp index deb84dc8..59e5f420 100644 --- a/src/wx/audio/internal/openal.cpp +++ b/src/wx/audio/internal/openal.cpp @@ -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; diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index fff56a2a..6bc7123f 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -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); diff --git a/src/wx/config/bindings.cpp b/src/wx/config/bindings.cpp index 35adb2bc..b11e8395 100644 --- a/src/wx/config/bindings.cpp +++ b/src/wx/config/bindings.cpp @@ -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()) { diff --git a/src/wx/config/cmdtab.cpp b/src/wx/config/cmdtab.cpp index b50f732b..2acab191 100644 --- a/src/wx/config/cmdtab.cpp +++ b/src/wx/config/cmdtab.cpp @@ -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; } diff --git a/src/wx/config/command.h b/src/wx/config/command.h index 118c3642..03792c5b 100644 --- a/src/wx/config/command.h +++ b/src/wx/config/command.h @@ -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; } }; diff --git a/src/wx/config/emulated-gamepad.cpp b/src/wx/config/emulated-gamepad.cpp index 1215a1f8..94dbc05f 100644 --- a/src/wx/config/emulated-gamepad.cpp +++ b/src/wx/config/emulated-gamepad.cpp @@ -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()) { diff --git a/src/wx/config/internal/option-internal.cpp b/src/wx/config/internal/option-internal.cpp index 8011ac9b..3609541a 100644 --- a/src/wx/config/internal/option-internal.cpp +++ b/src/wx/config/internal/option-internal.cpp @@ -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; } diff --git a/src/wx/config/option-observer.cpp b/src/wx/config/option-observer.cpp index cd802dfd..1cbce697 100644 --- a/src/wx/config/option-observer.cpp +++ b/src/wx/config/option-observer.cpp @@ -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; diff --git a/src/wx/config/option-test.cpp b/src/wx/config/option-test.cpp index 82a19e1c..0b9b0a2c 100644 --- a/src/wx/config/option-test.cpp +++ b/src/wx/config/option-test.cpp @@ -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) { diff --git a/src/wx/config/option.cpp b/src/wx/config/option.cpp index ab579b3e..bf11013d 100644 --- a/src/wx/config/option.cpp +++ b/src/wx/config/option.cpp @@ -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(); diff --git a/src/wx/config/user-input.cpp b/src/wx/config/user-input.cpp index a3401555..925578b4 100644 --- a/src/wx/config/user-input.cpp +++ b/src/wx/config/user-input.cpp @@ -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; } diff --git a/src/wx/config/user-input.h b/src/wx/config/user-input.h index 3a9c1b2e..b4b74a5e 100644 --- a/src/wx/config/user-input.h +++ b/src/wx/config/user-input.h @@ -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; } }; diff --git a/src/wx/dialogs/accel-config.cpp b/src/wx/dialogs/accel-config.cpp index b3b2e9f5..e2f8c3b1 100644 --- a/src/wx/dialogs/accel-config.cpp +++ b/src/wx/dialogs/accel-config.cpp @@ -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()); diff --git a/src/wx/dialogs/base-dialog.cpp b/src/wx/dialogs/base-dialog.cpp index 0817782b..e65aae32 100644 --- a/src/wx/dialogs/base-dialog.cpp +++ b/src/wx/dialogs/base-dialog.cpp @@ -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; } diff --git a/src/wx/dialogs/base-dialog.h b/src/wx/dialogs/base-dialog.h index 7ac7451d..238b3875 100644 --- a/src/wx/dialogs/base-dialog.h +++ b/src/wx/dialogs/base-dialog.h @@ -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; } diff --git a/src/wx/dialogs/directories-config.cpp b/src/wx/dialogs/directories-config.cpp index 5e58a322..9ce62728 100644 --- a/src/wx/dialogs/directories-config.cpp +++ b/src/wx/dialogs/directories-config.cpp @@ -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); } diff --git a/src/wx/dialogs/display-config.cpp b/src/wx/dialogs/display-config.cpp index 797b5fde..c8453b8c 100644 --- a/src/wx/dialogs/display-config.cpp +++ b/src/wx/dialogs/display-config.cpp @@ -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); } diff --git a/src/wx/dialogs/game-boy-config.cpp b/src/wx/dialogs/game-boy-config.cpp index 757fb694..2bf001a4 100644 --- a/src/wx/dialogs/game-boy-config.cpp +++ b/src/wx/dialogs/game-boy-config.cpp @@ -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); } diff --git a/src/wx/dialogs/gb-rom-info.cpp b/src/wx/dialogs/gb-rom-info.cpp index cc1dd450..b94b6aec 100644 --- a/src/wx/dialogs/gb-rom-info.cpp +++ b/src/wx/dialogs/gb-rom-info.cpp @@ -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); } diff --git a/src/wx/dialogs/joypad-config.cpp b/src/wx/dialogs/joypad-config.cpp index bd973aae..f1e1ea9e 100644 --- a/src/wx/dialogs/joypad-config.cpp +++ b/src/wx/dialogs/joypad-config.cpp @@ -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; diff --git a/src/wx/dialogs/sound-config.cpp b/src/wx/dialogs/sound-config.cpp index 181ec0b7..40c7b12a 100644 --- a/src/wx/dialogs/sound-config.cpp +++ b/src/wx/dialogs/sound-config.cpp @@ -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); } diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index 52affac5..69796888 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -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') { diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 71a3ee72..91cbff3f 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -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; } } diff --git a/src/wx/widgets/client-data.h b/src/wx/widgets/client-data.h index fe1eceed..ac4fe908 100644 --- a/src/wx/widgets/client-data.h +++ b/src/wx/widgets/client-data.h @@ -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(); } diff --git a/src/wx/widgets/group-check-box.cpp b/src/wx/widgets/group-check-box.cpp index 96aa2bea..0e623825 100644 --- a/src/wx/widgets/group-check-box.cpp +++ b/src/wx/widgets/group-check-box.cpp @@ -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. diff --git a/src/wx/widgets/keep-on-top-styler.cpp b/src/wx/widgets/keep-on-top-styler.cpp index ad3cb748..52d5699a 100644 --- a/src/wx/widgets/keep-on-top-styler.cpp +++ b/src/wx/widgets/keep-on-top-styler.cpp @@ -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); } diff --git a/src/wx/widgets/option-validator.cpp b/src/wx/widgets/option-validator.cpp index 489f668e..6d70d835 100644 --- a/src/wx/widgets/option-validator.cpp +++ b/src/wx/widgets/option-validator.cpp @@ -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()); } diff --git a/src/wx/widgets/render-plugin.cpp b/src/wx/widgets/render-plugin.cpp index 02889137..9c47b593 100644 --- a/src/wx/widgets/render-plugin.cpp +++ b/src/wx/widgets/render-plugin.cpp @@ -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; diff --git a/src/wx/widgets/sdl-poller.cpp b/src/wx/widgets/sdl-poller.cpp index e2734e5a..03efc566 100644 --- a/src/wx/widgets/sdl-poller.cpp +++ b/src/wx/widgets/sdl-poller.cpp @@ -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); diff --git a/src/wx/widgets/user-input-ctrl.cpp b/src/wx/widgets/user-input-ctrl.cpp index cad8f15c..c63b96b9 100644 --- a/src/wx/widgets/user-input-ctrl.cpp +++ b/src/wx/widgets/user-input-ctrl.cpp @@ -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(); } diff --git a/src/wx/widgets/user-input-event.cpp b/src/wx/widgets/user-input-event.cpp index a5a518e2..fba8f056 100644 --- a/src/wx/widgets/user-input-event.cpp +++ b/src/wx/widgets/user-input-event.cpp @@ -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; diff --git a/src/wx/widgets/utils.h b/src/wx/widgets/utils.h index a9285e69..ffc0298f 100644 --- a/src/wx/widgets/utils.h +++ b/src/wx/widgets/utils.h @@ -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; } diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index afbeeddd..9d700c94 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -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) {