From 43f5c8e2d025762a1e988a590de51dbee2171f7d Mon Sep 17 00:00:00 2001 From: Robert Broglia Date: Mon, 21 Aug 2023 03:54:56 -0400 Subject: [PATCH] Misc tweaks * Imagine: Merge bitset.hh into bit.hh * Imagine: Add utility functions for bit set classes * Imagine: Convert all bit set enums into classes with bit fields for easier usage * Imagine: Allow null BufferDeleter * EmuFramework: Store recent content items as separate entries in config file * EmuFramework: Add option to set max recent content items --- 2600.emu/src/main/input.cc | 4 +- 2600.emu/src/stella/emucore/Serializer.cxx | 2 +- C64.emu/src/main/VicePlugin.cc | 2 +- C64.emu/src/main/input.cc | 2 +- C64.emu/src/main/sysfile.cc | 4 +- EmuFramework/build.mk | 3 +- EmuFramework/include/emuframework/EmuApp.hh | 22 +-- EmuFramework/include/emuframework/EmuAudio.hh | 16 +- .../include/emuframework/EmuSystem.hh | 21 +-- .../include/emuframework/GUIOptionView.hh | 3 +- .../include/emuframework/RecentContent.hh | 67 ++++++++ .../include/emuframework/inputDefs.hh | 2 - EmuFramework/src/AutosaveManager.cc | 2 +- EmuFramework/src/ConfigFile.cc | 10 +- EmuFramework/src/EmuApp.cc | 41 ++--- EmuFramework/src/EmuAudio.cc | 12 +- EmuFramework/src/EmuOptions.cc | 61 -------- EmuFramework/src/EmuOptions.hh | 3 +- EmuFramework/src/EmuSystem.cc | 4 +- EmuFramework/src/InputDeviceData.cc | 7 +- EmuFramework/src/RecentContent.cc | 143 ++++++++++++++++++ EmuFramework/src/gui/AutosaveSlotView.cc | 2 +- EmuFramework/src/gui/BundledGamesView.cc | 2 +- EmuFramework/src/gui/EmuViewController.cc | 1 - EmuFramework/src/gui/GUIOptionView.cc | 16 ++ EmuFramework/src/gui/MainMenuView.cc | 8 +- ...RecentGameView.cc => RecentContentView.cc} | 21 +-- ...RecentGameView.hh => RecentContentView.hh} | 10 +- EmuFramework/src/pathUtils.cc | 2 +- .../src/shared/mednafen-emuex/MDFNFILE.cc | 4 +- .../src/shared/mednafen-emuex/StreamImpl.cc | 12 +- EmuFramework/src/vcontrols/VController.cc | 6 +- GBA.emu/src/main/input.cc | 4 +- GBA.emu/src/vbam/gba/GBA.cpp | 4 +- GBC.emu/src/main/Cheats.cc | 4 +- GBC.emu/src/main/Cheats.hh | 2 +- GBC.emu/src/main/Main.cc | 2 +- GBC.emu/src/main/input.cc | 2 +- MD.emu/src/main/Cheats.cc | 4 +- MD.emu/src/main/Cheats.hh | 2 +- MD.emu/src/main/Main.cc | 4 +- MD.emu/src/main/input.cc | 2 +- MD.emu/src/scd/scd.cc | 2 +- MSX.emu/src/main/RomLoader.cc | 10 +- MSX.emu/src/main/input.cc | 2 +- MSX.emu/src/main/ziphelper.cc | 2 +- NEO.emu/src/main/EmuMenuViews.cc | 4 +- NEO.emu/src/main/input.cc | 4 +- NEO.emu/src/main/unzip.cc | 4 +- NES.emu/src/main/Main.cc | 2 +- NES.emu/src/main/input.cc | 2 +- PCE.emu/src/main/input.cc | 2 +- Snes9x/src/main/S9XApi.cc | 4 +- Snes9x/src/main/input.cc | 6 +- Snes9x/src/snes9x/bml.cpp | 2 +- Swan.emu/src/main/input.cc | 6 +- .../imagine/base/ApplicationContext.hh | 34 ++--- imagine/include/imagine/base/BaseWindow.hh | 2 +- imagine/include/imagine/base/Window.hh | 2 +- .../base/android/AndroidApplication.hh | 8 +- imagine/include/imagine/base/baseDefs.hh | 20 +-- imagine/include/imagine/base/sharedLibrary.hh | 10 +- imagine/include/imagine/fs/FSDefs.hh | 12 +- imagine/include/imagine/fs/FSUtils.hh | 2 +- imagine/include/imagine/fs/PosixFS.hh | 2 +- imagine/include/imagine/gfx/Program.hh | 1 - imagine/include/imagine/gfx/Vertex.hh | 42 ++--- .../imagine/gfx/opengl/GLRendererCommands.hh | 4 +- imagine/include/imagine/input/Device.hh | 2 +- imagine/include/imagine/io/AAssetIO.hh | 2 +- imagine/include/imagine/io/FileIO.hh | 6 +- imagine/include/imagine/io/IOUtils.hh | 10 +- imagine/include/imagine/io/PosixFileIO.hh | 12 +- imagine/include/imagine/io/PosixIO.hh | 13 +- imagine/include/imagine/io/ioDefs.hh | 33 ++-- imagine/include/imagine/pixmap/PixelDesc.hh | 2 +- imagine/include/imagine/util/bit.hh | 77 ++++++++++ imagine/include/imagine/util/bitset.hh | 75 --------- imagine/include/imagine/util/enum.hh | 9 -- imagine/include/imagine/util/memory/Buffer.hh | 4 +- imagine/include/imagine/util/rectangle2.h | 1 + imagine/src/audio/android/aaudio.cc | 2 +- imagine/src/base/android/AndroidWindow.cc | 4 +- imagine/src/base/android/Application.cc | 33 ++-- .../src/base/android/ApplicationContext.cc | 8 +- imagine/src/base/common/ApplicationContext.cc | 32 ++-- imagine/src/base/common/Base.cc | 4 +- imagine/src/base/common/Window.cc | 10 +- imagine/src/base/iphone/IOSWindow.mm | 2 +- imagine/src/base/iphone/iphone.mm | 4 +- imagine/src/base/x11/xdnd.cc | 2 +- imagine/src/bluetooth/IControlPad.cc | 2 +- imagine/src/bluetooth/PS3Controller.cc | 2 +- imagine/src/bluetooth/Wiimote.cc | 2 +- imagine/src/data-type/image/LibPNG.cc | 4 +- imagine/src/fs/FS.cc | 2 +- imagine/src/fs/PosixFS.cc | 4 +- imagine/src/gfx/common/GlyphTextureSet.cc | 2 +- imagine/src/gfx/opengl/Renderer.cc | 2 +- imagine/src/gfx/opengl/RendererCommands.cc | 6 +- imagine/src/gfx/opengl/RendererTask.cc | 2 +- imagine/src/input/evdev/evdev.cc | 2 +- imagine/src/io/AAssetIO.cc | 6 +- imagine/src/io/IO.cc | 11 +- imagine/src/io/IOUtils.hh | 2 +- imagine/src/io/PosixFileIO.cc | 22 +-- imagine/src/io/PosixIO.cc | 32 ++-- 107 files changed, 655 insertions(+), 531 deletions(-) create mode 100644 EmuFramework/include/emuframework/RecentContent.hh create mode 100644 EmuFramework/src/RecentContent.cc rename EmuFramework/src/gui/{RecentGameView.cc => RecentContentView.cc} (73%) rename EmuFramework/src/gui/{RecentGameView.hh => RecentContentView.hh} (76%) delete mode 100755 imagine/include/imagine/util/bitset.hh diff --git a/2600.emu/src/main/input.cc b/2600.emu/src/main/input.cc index fa5edd7f6..88f73edd1 100644 --- a/2600.emu/src/main/input.cc +++ b/2600.emu/src/main/input.cc @@ -531,10 +531,10 @@ SystemInputDeviceDesc A2600System::inputDeviceDesc(int idx) const { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, InputComponentDesc{"Joystick Buttons", triggerKeyInfo, InputComponent::button, RB2DO}, - InputComponentDesc{"Keyboard Buttons", kbKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig | InputComponentFlagsMask::rowSize3}, + InputComponentDesc{"Keyboard Buttons", kbKeyInfo, InputComponent::button, RB2DO, {.altConfig = true, .rowSize = 3}}, InputComponentDesc{"Select", {&consoleKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Reset", {&consoleKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Console Buttons", consoleKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Console Buttons", consoleKeyInfo, InputComponent::button, RB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc jsDesc{"Joystick", jsComponents}; diff --git a/2600.emu/src/stella/emucore/Serializer.cxx b/2600.emu/src/stella/emucore/Serializer.cxx index a200ae2da..7cc6c7930 100644 --- a/2600.emu/src/stella/emucore/Serializer.cxx +++ b/2600.emu/src/stella/emucore/Serializer.cxx @@ -48,7 +48,7 @@ Serializer::Serializer(const string& filename, Mode m) ios_base::openmode stream_mode = ios::in | ios::out | ios::binary; if(m == Mode::ReadWriteTrunc) stream_mode |= ios::trunc; - auto str = make_unique(EmuEx::gAppContext().openFileUri(filename, IG::OpenFlagsMask::New), stream_mode); + auto str = make_unique(EmuEx::gAppContext().openFileUri(filename, IG::OpenFlags::newFile()), stream_mode); if(str && str->is_open()) { myStream = std::move(str); diff --git a/C64.emu/src/main/VicePlugin.cc b/C64.emu/src/main/VicePlugin.cc index fb648d3c3..b02203ac3 100644 --- a/C64.emu/src/main/VicePlugin.cc +++ b/C64.emu/src/main/VicePlugin.cc @@ -695,7 +695,7 @@ VicePlugin loadVicePlugin(ViceSystem system, const char *libBasePath) }; auto libPath = makePluginLibPath(libName[std::to_underlying(system)], libBasePath); logMsg("loading VICE plugin:%s", libPath.data()); - auto lib = IG::openSharedLibrary(libPath.data(), IG::RESOLVE_ALL_SYMBOLS_FLAG); + auto lib = IG::openSharedLibrary(libPath.data(), {.resolveAllSymbols = true}); if(!lib) { return {}; diff --git a/C64.emu/src/main/input.cc b/C64.emu/src/main/input.cc index 95564484c..61d48a939 100644 --- a/C64.emu/src/main/input.cc +++ b/C64.emu/src/main/input.cc @@ -768,7 +768,7 @@ SystemInputDeviceDesc C64System::inputDeviceDesc(int idx) const { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, InputComponentDesc{"Joystick Button", triggerKeyInfo, InputComponent::button, RB2DO}, - InputComponentDesc{"F1 & Keyboard Toggle", shortcutKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::rowSize1}, + InputComponentDesc{"F1 & Keyboard Toggle", shortcutKeyInfo, InputComponent::button, RB2DO, {.rowSize = 1}}, }; static constexpr SystemInputDeviceDesc jsDesc{"Joystick", jsComponents}; diff --git a/C64.emu/src/main/sysfile.cc b/C64.emu/src/main/sysfile.cc index c7f3cfea9..d1cd4a717 100644 --- a/C64.emu/src/main/sysfile.cc +++ b/C64.emu/src/main/sysfile.cc @@ -110,7 +110,7 @@ static ArchiveIO archiveIOForSysFile(IG::CStringView archivePath, std::string_vi static AssetIO assetIOForSysFile(IG::ApplicationContext ctx, std::string_view sysFileName, std::string_view subPath, char **complete_path_return) { auto fullPath = FS::pathString(subPath, sysFileName); - auto file = ctx.openAsset(fullPath, IOAccessHint::All, OpenFlagsMask::Test); + auto file = ctx.openAsset(fullPath, IOAccessHint::All, {.test = true}); if(!file) return {}; if(complete_path_return) @@ -309,7 +309,7 @@ CLINK int sysfile_load(const char *name, const char *subPath, uint8_t *dest, int } else { - auto file = appContext.openFileUri(FS::uriString(basePath, subPath, name), IOAccessHint::All, OpenFlagsMask::Test); + auto file = appContext.openFileUri(FS::uriString(basePath, subPath, name), IOAccessHint::All, {.test = true}); if(!file) continue; //logMsg("loading system file: %s", complete_path); diff --git a/EmuFramework/build.mk b/EmuFramework/build.mk index 71027dfb2..3aea3f623 100644 --- a/EmuFramework/build.mk +++ b/EmuFramework/build.mk @@ -17,6 +17,7 @@ InputDeviceData.cc \ KeyConfig.cc \ OutputTimingManager.cc \ pathUtils.cc \ +RecentContent.cc \ ToggleInput.cc \ TurboInput.cc \ VideoImageEffect.cc \ @@ -39,7 +40,7 @@ gui/LoadProgressView.cc \ gui/MainMenuView.cc \ gui/PlaceVControlsView.cc \ gui/PlaceVideoView.cc \ -gui/RecentGameView.cc \ +gui/RecentContentView.cc \ gui/StateSlotView.cc \ gui/SystemActionsView.cc \ gui/SystemOptionView.cc \ diff --git a/EmuFramework/include/emuframework/EmuApp.hh b/EmuFramework/include/emuframework/EmuApp.hh index 64bf8896d..e88df8d04 100644 --- a/EmuFramework/include/emuframework/EmuApp.hh +++ b/EmuFramework/include/emuframework/EmuApp.hh @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -64,17 +64,6 @@ namespace EmuEx struct MainWindowData; class EmuMainMenuView; -struct RecentContentInfo -{ - FS::PathString path{}; - FS::FileString name{}; - - constexpr bool operator ==(RecentContentInfo const& rhs) const - { - return path == rhs.path; - } -}; - enum class Tristate : uint8_t { OFF, IN_EMU, ON @@ -148,8 +137,6 @@ class EmuApp : public IG::Application public: using CreateSystemCompleteDelegate = DelegateFunc; using NavView = BasicNavView; - static constexpr int MAX_RECENT = 10; - using RecentContentList = StaticArrayList; enum class ViewID { @@ -265,11 +252,6 @@ public: BluetoothAdapter *bluetoothAdapter(); void closeBluetoothConnections(); ViewAttachParams attachParams(); - void addRecentContent(std::string_view path, std::string_view name); - void addCurrentContentToRecent(); - RecentContentList &recentContent() { return recentContentList; }; - void writeRecentContent(FileIO &); - bool readRecentContent(IG::ApplicationContext, MapIO &, size_t readSize_); auto &customKeyConfigList() { return inputManager.customKeyConfigs; }; auto &savedInputDeviceList() { return inputManager.savedInputDevs; }; IG::Viewport makeViewport(const Window &win) const; @@ -531,8 +513,8 @@ protected: [[no_unique_address]] PerformanceHintSession perfHintSession; BluetoothAdapter *bta{}; IG_UseMemberIf(MOGA_INPUT, std::unique_ptr, mogaManagerPtr); - RecentContentList recentContentList; public: + RecentContent recentContent; std::string userScreenshotPath; protected: IG_UseMemberIf(Config::cpuAffinity, CPUMask, cpuAffinityMask){}; diff --git a/EmuFramework/include/emuframework/EmuAudio.hh b/EmuFramework/include/emuframework/EmuAudio.hh index 6e3263237..9935c71e5 100644 --- a/EmuFramework/include/emuframework/EmuAudio.hh +++ b/EmuFramework/include/emuframework/EmuAudio.hh @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include @@ -35,14 +33,16 @@ namespace EmuEx using namespace IG; -enum class AudioFlagsMask: uint8_t +struct AudioFlags { - enabled = bit(0), - enabledDuringAltSpeed = bit(1), - defaultMask = enabled | enabledDuringAltSpeed, + uint8_t + enabled{}, + enabledDuringAltSpeed{}; + + constexpr bool operator ==(AudioFlags const &) const = default; }; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(AudioFlagsMask); +constexpr AudioFlags defaultAudioFlags{.enabled = 1, .enabledDuringAltSpeed = 1}; class EmuAudio { @@ -95,7 +95,7 @@ protected: float currentVolume{1.}; std::atomic audioWriteState{AudioWriteState::BUFFER}; int8_t channels{2}; - AudioFlagsMask flagsMask{AudioFlagsMask::defaultMask}; + AudioFlags flags{defaultAudioFlags}; IG_UseMemberIf(IG::Audio::Config::MULTIPLE_SYSTEM_APIS, IG::Audio::Api, audioAPI){}; bool addSoundBuffersOnUnderrun{}; public: diff --git a/EmuFramework/include/emuframework/EmuSystem.hh b/EmuFramework/include/emuframework/EmuSystem.hh index 5a1bc1d4f..82aa57fb4 100755 --- a/EmuFramework/include/emuframework/EmuSystem.hh +++ b/EmuFramework/include/emuframework/EmuSystem.hh @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include #include @@ -101,28 +99,21 @@ enum class InputComponent : uint8_t ui, dPad, button, trigger }; -enum class InputComponentFlagsMask: uint8_t +struct InputComponentFlags { - altConfig = bit(0), - rowSizeBit1 = bit(1), - rowSizeBit2 = bit(2), - rowSizeBits = rowSizeBit1 | rowSizeBit2, - rowSizeAuto = 0, - rowSize1 = rowSizeBit1, - rowSize2 = rowSizeBit2, - rowSize3 = rowSizeBit1 | rowSizeBit2, - staggeredLayout = bit(3), + uint8_t + altConfig:1{}, + rowSize:2{}, + staggeredLayout:1{}; }; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(InputComponentFlagsMask); - struct InputComponentDesc { const char *name{}; std::span keyCodes{}; InputComponent type{}; _2DOrigin layoutOrigin{}; - InputComponentFlagsMask flags{}; + InputComponentFlags flags{}; }; struct SystemInputDeviceDesc diff --git a/EmuFramework/include/emuframework/GUIOptionView.hh b/EmuFramework/include/emuframework/GUIOptionView.hh index 974d4ace3..3f6f5bd32 100644 --- a/EmuFramework/include/emuframework/GUIOptionView.hh +++ b/EmuFramework/include/emuframework/GUIOptionView.hh @@ -49,6 +49,7 @@ protected: BoolMenuItem showBundledGames; BoolMenuItem showBluetoothScan; BoolMenuItem showHiddenFiles; + DualTextMenuItem maxRecentContent; TextHeadingMenuItem orientationHeading; TextMenuItem menuOrientationItem[5]; MultiChoiceMenuItem menuOrientation; @@ -57,7 +58,7 @@ protected: IG_UseMemberIf(Config::TRANSLUCENT_SYSTEM_UI, BoolMenuItem, layoutBehindSystemUI); IG_UseMemberIf(Config::freeformWindows, TextMenuItem, setWindowSize); IG_UseMemberIf(Config::freeformWindows, TextMenuItem, toggleFullScreen); - StaticArrayList item; + StaticArrayList item; }; } diff --git a/EmuFramework/include/emuframework/RecentContent.hh b/EmuFramework/include/emuframework/RecentContent.hh new file mode 100644 index 000000000..850556b11 --- /dev/null +++ b/EmuFramework/include/emuframework/RecentContent.hh @@ -0,0 +1,67 @@ +#pragma once + +/* This file is part of EmuFramework. + + Imagine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Imagine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with EmuFramework. If not, see */ + +#include +#include +#include + +namespace IG +{ +class ApplicationContext; +class FileIO; +class MapIO; +} + +namespace EmuEx +{ + +class EmuSystem; + +using namespace IG; + +struct RecentContentInfo +{ + FS::PathString path; + FS::FileString name; + + constexpr bool operator==(RecentContentInfo const& rhs) const + { + return path == rhs.path; + } +}; + +class RecentContent +{ +public: + void add(std::string_view path, std::string_view name); + void add(const EmuSystem &); + size_t size() const { return recentContentList.size(); } + auto begin() const { return recentContentList.begin(); } + auto end() const { return recentContentList.end(); } + void clear() { recentContentList.clear(); } + void writeConfig(FileIO &) const; + bool readConfig(MapIO &, unsigned key, size_t size, const EmuSystem &); + bool readLegacyConfig(MapIO &, const EmuSystem &); + +private: + std::vector recentContentList; +public: + static constexpr uint8_t defaultMaxRecentContent{20}; + uint8_t maxRecentContent{defaultMaxRecentContent}; +}; + +} diff --git a/EmuFramework/include/emuframework/inputDefs.hh b/EmuFramework/include/emuframework/inputDefs.hh index 88c577683..96a878a9f 100644 --- a/EmuFramework/include/emuframework/inputDefs.hh +++ b/EmuFramework/include/emuframework/inputDefs.hh @@ -16,8 +16,6 @@ along with EmuFramework. If not, see */ #include -#include -#include #include #include #include diff --git a/EmuFramework/src/AutosaveManager.cc b/EmuFramework/src/AutosaveManager.cc index 32bbd8011..3f720311c 100644 --- a/EmuFramework/src/AutosaveManager.cc +++ b/EmuFramework/src/AutosaveManager.cc @@ -124,7 +124,7 @@ bool AutosaveManager::deleteSlot(std::string_view name) { ctx.removeFileUri(e.path()); return true; - }, FS::DirOpenFlagsMask::Test)) + }, {.test = true})) { return false; } diff --git a/EmuFramework/src/ConfigFile.cc b/EmuFramework/src/ConfigFile.cc index 6dcd12589..a80ed6ec4 100644 --- a/EmuFramework/src/ConfigFile.cc +++ b/EmuFramework/src/ConfigFile.cc @@ -95,7 +95,7 @@ void EmuApp::saveConfigFile(FileIO &io) std::apply([&](auto &...opt){ (writeOptionValue(io, opt), ...); }, cfgFileOptions); - writeRecentContent(io); + recentContent.writeConfig(io); writeOptionValueIfNotDefault(io, CFGKEY_GAME_ORIENTATION, optionEmuOrientation, Orientations{}); writeOptionValueIfNotDefault(io, CFGKEY_MENU_ORIENTATION, optionMenuOrientation, Orientations{}); writeOptionValue(io, CFGKEY_BACK_NAVIGATION, viewManager.needsBackControlOption()); @@ -193,7 +193,7 @@ EmuApp::ConfigParams EmuApp::loadConfigFile(IG::ApplicationContext ctx) #endif ConfigParams appConfig{}; Gfx::DrawableConfig pendingWindowDrawableConf{}; - readConfigKeys(FileUtils::bufferFromPath(configFilePath, OpenFlagsMask::Test), + readConfigKeys(FileUtils::bufferFromPath(configFilePath, {.test = true}), [&](auto key, auto size, auto &io) -> bool { switch(key) @@ -208,6 +208,8 @@ EmuApp::ConfigParams EmuApp::loadConfigFile(IG::ApplicationContext ctx) return true; if(emuAudio.readConfig(io, key, size)) return true; + if(recentContent.readConfig(io, key, size, system())) + return true; logMsg("skipping key %u", (unsigned)key); return false; } @@ -233,7 +235,7 @@ EmuApp::ConfigParams EmuApp::loadConfigFile(IG::ApplicationContext ctx) case CFGKEY_VIDEO_IMAGE_BUFFERS: return optionVideoImageBuffers.readFromIO(io, size); case CFGKEY_OVERLAY_EFFECT: return optionOverlayEffect.readFromIO(io, size); case CFGKEY_OVERLAY_EFFECT_LEVEL: return optionOverlayEffectLevel.readFromIO(io, size); - case CFGKEY_RECENT_GAMES: return readRecentContent(ctx, io, size); + case CFGKEY_RECENT_CONTENT: return recentContent.readLegacyConfig(io, system()); case CFGKEY_SWAPPED_GAMEPAD_CONFIM: setSwappedConfirmKeys(readOptionValue(io, size)); return true; @@ -317,7 +319,7 @@ void EmuApp::saveConfigFile(IG::ApplicationContext ctx) auto configFilePath = FS::pathString(ctx.supportPath(), "config"); try { - FileIO file{configFilePath, OpenFlagsMask::New}; + FileIO file{configFilePath, OpenFlags::newFile()}; saveConfigFile(file); } catch(...) diff --git a/EmuFramework/src/EmuApp.cc b/EmuFramework/src/EmuApp.cc index ad5e7ee61..b7a0088d7 100644 --- a/EmuFramework/src/EmuApp.cc +++ b/EmuFramework/src/EmuApp.cc @@ -276,13 +276,13 @@ void EmuApp::closeSystemWithoutSave() void EmuApp::applyOSNavStyle(IG::ApplicationContext ctx, bool inGame) { - auto flags = IG::SYS_UI_STYLE_NO_FLAGS; + SystemUIStyleFlags flags; if((int)optionLowProfileOSNav > (inGame ? 0 : 1)) - flags |= IG::SYS_UI_STYLE_DIM_NAV; + flags.dimNavigation = true; if((int)optionHideOSNav > (inGame ? 0 : 1)) - flags |= IG::SYS_UI_STYLE_HIDE_NAV; + flags.hideNavigation = true; if((int)optionHideStatusBar > (inGame ? 0 : 1)) - flags |= IG::SYS_UI_STYLE_HIDE_STATUS; + flags.hideStatus = true; ctx.setSysUIStyle(flags); } @@ -856,7 +856,7 @@ void EmuApp::onSelectFileFromPicker(IO io, CStringView path, std::string_view di createSystemWithMedia(std::move(io), path, displayName, e, params, attachParams, [this](const Input::Event &e) { - addCurrentContentToRecent(); + recentContent.add(system()); launchSystem(e); }); } @@ -1420,7 +1420,7 @@ void EmuApp::saveSessionOptions() try { auto ctx = appContext(); - auto configFile = ctx.openFileUri(configFilePath, OpenFlagsMask::New); + auto configFile = ctx.openFileUri(configFilePath, OpenFlags::newFile()); writeConfigHeader(configFile); system().writeConfig(ConfigType::SESSION, configFile); system().resetSessionOptionsSet(); @@ -1446,7 +1446,7 @@ void EmuApp::loadSessionOptions() { if(!system().resetSessionOptions(*this)) return; - if(readConfigKeys(FileUtils::bufferFromUri(appContext(), sessionConfigPath(), OpenFlagsMask::Test), + if(readConfigKeys(FileUtils::bufferFromUri(appContext(), sessionConfigPath(), {.test = true}), [this](uint16_t key, uint16_t size, auto &io) { switch(key) @@ -1470,7 +1470,7 @@ void EmuApp::loadSystemOptions() auto configName = system().configName(); if(configName.empty()) return; - readConfigKeys(FileUtils::bufferFromPath(FS::pathString(appContext().supportPath(), configName), OpenFlagsMask::Test), + readConfigKeys(FileUtils::bufferFromPath(FS::pathString(appContext().supportPath(), configName), {.test = true}), [this](uint16_t key, uint16_t size, auto &io) { if(!system().readConfig(ConfigType::CORE, io, key, size)) @@ -1488,7 +1488,7 @@ void EmuApp::saveSystemOptions() try { auto configFilePath = FS::pathString(appContext().supportPath(), configName); - auto configFile = FileIO{configFilePath, OpenFlagsMask::New}; + auto configFile = FileIO{configFilePath, OpenFlags::newFile()}; saveSystemOptions(configFile); if(configFile.size() == 1) { @@ -1601,29 +1601,6 @@ ViewAttachParams EmuApp::attachParams() return viewController().inputView.attachParams(); } -void EmuApp::addRecentContent(std::string_view fullPath, std::string_view name) -{ - if(fullPath.empty()) - return; - log.info("adding {} @ {} to recent list, current size:{}", name, fullPath, recentContentList.size()); - RecentContentInfo recent{FS::PathString{fullPath}, FS::FileString{name}}; - IG::eraseFirst(recentContentList, recent); // remove existing entry so it's added to the front - if(recentContentList.isFull()) // list full - recentContentList.pop_back(); - recentContentList.insert(recentContentList.begin(), recent); - - /*log.info("list contents:"); - for(auto &e : recentContentList) - { - log.info("path: {} name: {}", e.path, e.name); - }*/ -} - -void EmuApp::addCurrentContentToRecent() -{ - addRecentContent(system().contentLocation(), system().contentDisplayName()); -} - bool EmuApp::setFontSize(int size) { if(!optionFontSize.isValidVal(size)) diff --git a/EmuFramework/src/EmuAudio.cc b/EmuFramework/src/EmuAudio.cc index af8bc6f7a..f42efe1d4 100644 --- a/EmuFramework/src/EmuAudio.cc +++ b/EmuFramework/src/EmuAudio.cc @@ -402,12 +402,12 @@ void EmuAudio::setOutputAPI(IG::Audio::Api api) bool EmuAudio::isEnabled() const { - return to_underlying(flagsMask & AudioFlagsMask::enabled); + return flags.enabled; } void EmuAudio::setEnabled(bool on) { - flagsMask = setOrClearBits(flagsMask, AudioFlagsMask::enabled, on); + flags.enabled = on; if(on) open(); else @@ -416,12 +416,12 @@ void EmuAudio::setEnabled(bool on) bool EmuAudio::isEnabledDuringAltSpeed() const { - return to_underlying(flagsMask & AudioFlagsMask::enabledDuringAltSpeed); + return flags.enabledDuringAltSpeed; } void EmuAudio::setEnabledDuringAltSpeed(bool on) { - flagsMask = IG::setOrClearBits(flagsMask, AudioFlagsMask::enabledDuringAltSpeed, on); + flags.enabledDuringAltSpeed = on; updateAddBuffersOnUnderrun(); } @@ -445,7 +445,7 @@ constexpr bool isValidSoundRate(int rate) void EmuAudio::writeConfig(FileIO &io) const { - writeOptionValueIfNotDefault(io, CFGKEY_SOUND, flagsMask, AudioFlagsMask::defaultMask); + writeOptionValueIfNotDefault(io, CFGKEY_SOUND, flags, defaultAudioFlags); if(!EmuSystem::forcedSoundRate) writeOptionValueIfNotDefault(io, CFGKEY_SOUND_RATE, rate_, defaultRate); writeOptionValueIfNotDefault(io, CFGKEY_SOUND_BUFFERS, soundBuffers, defaultSoundBuffers); @@ -459,7 +459,7 @@ bool EmuAudio::readConfig(MapIO &io, unsigned key, size_t size) { switch(key) { - case CFGKEY_SOUND: return readOptionValue(io, size, flagsMask); + case CFGKEY_SOUND: return readOptionValue(io, size, flags); case CFGKEY_SOUND_RATE: return EmuSystem::forcedSoundRate ? false : readOptionValue(io, size, rate_, isValidSoundRate); case CFGKEY_SOUND_BUFFERS: return readOptionValue(io, size, soundBuffers, optionIsValidWithMinMax<1, 7, int8_t>); case CFGKEY_SOUND_VOLUME: return readOptionValue(io, size, [&](auto v){ setMaxVolume(v); }, isValidVolumeSetting); diff --git a/EmuFramework/src/EmuOptions.cc b/EmuFramework/src/EmuOptions.cc index 0805db53e..6c95b7ad8 100644 --- a/EmuFramework/src/EmuOptions.cc +++ b/EmuFramework/src/EmuOptions.cc @@ -101,67 +101,6 @@ IG::FontSettings EmuApp::fontSettings(Window &win) const return {win.heightScaledMMInPixels(size)}; } -void EmuApp::writeRecentContent(FileIO &io) -{ - size_t strSizes = 0; - for(const auto &e : recentContentList) - { - strSizes += 2; - strSizes += e.path.size(); - } - log.info("writing recent list"); - writeOptionValueHeader(io, CFGKEY_RECENT_GAMES, strSizes); - for(const auto &e : recentContentList) - { - auto len = e.path.size(); - io.put(uint16_t(len)); - io.write(e.path.data(), len); - } -} - -bool EmuApp::readRecentContent(IG::ApplicationContext ctx, MapIO &io, size_t readSize_) -{ - auto readSize = readSize_; - while(readSize && !recentContentList.isFull()) - { - if(readSize < 2) - { - log.info("expected string length but only {} bytes left", readSize); - return false; - } - - auto len = io.get(); - readSize -= 2; - - if(len > readSize) - { - log.info("string length {} longer than {} bytes left", len, readSize); - return false; - } - - FS::PathString path{}; - auto bytesRead = io.readSized(path, len); - if(bytesRead == -1) - { - log.error("error reading string option"); - return false; - } - if(!bytesRead) - continue; // don't add empty paths - readSize -= len; - auto displayName = system().contentDisplayNameForPath(path); - if(displayName.empty()) - { - log.info("skipping missing recent content:{}", path); - continue; - } - RecentContentInfo info{path, displayName}; - const auto &added = recentContentList.emplace_back(info); - log.info("added game to recent list:{}, name:{}", added.path, added.name); - } - return true; -} - void EmuApp::setFrameInterval(int val) { log.info("set frame interval:{}", val); diff --git a/EmuFramework/src/EmuOptions.hh b/EmuFramework/src/EmuOptions.hh index 146d10916..9b26414cc 100644 --- a/EmuFramework/src/EmuOptions.hh +++ b/EmuFramework/src/EmuOptions.hh @@ -31,7 +31,7 @@ enum { CFGKEY_SOUND = 0, CFGKEY_TOUCH_CONTROL_DISPLAY = 1, CFGKEY_SWAPPED_GAMEPAD_CONFIM = 20, CFGKEY_TOUCH_CONTROL_DPAD_DEADZONE = 21, CFGKEY_TOUCH_CONTROL_CENTER_BTN_POS = 22, CFGKEY_TOUCH_CONTROL_TRIGGER_BTN_POS = 23, CFGKEY_TOUCH_CONTROL_MENU_POS = 24, CFGKEY_TOUCH_CONTROL_FF_POS = 25, - CFGKEY_RECENT_GAMES = 26, CFGKEY_GL_SYNC_HACK = 27, CFGKEY_PAUSE_UNFOCUSED = 28, + CFGKEY_RECENT_CONTENT = 26, CFGKEY_GL_SYNC_HACK = 27, CFGKEY_PAUSE_UNFOCUSED = 28, CFGKEY_IMAGE_ZOOM = 29, CFGKEY_TOUCH_CONTROL_IMG_PIXELS = 30, CFGKEY_SOUND_RATE = 31, CFGKEY_NOTIFICATION_ICON = 32, CFGKEY_ICADE = 33, CFGKEY_TITLE_BAR = 34, CFGKEY_BACK_NAVIGATION = 35, CFGKEY_SYSTEM_ACTIONS_IS_DEFAULT_MENU = 36, @@ -76,6 +76,7 @@ enum { CFGKEY_SOUND = 0, CFGKEY_TOUCH_CONTROL_DISPLAY = 1, CFGKEY_RENDERER_PRESENT_MODE = 110, CFGKEY_BLANK_FRAME_INSERTION = 111, CFGKEY_VCONTROLLER_DEVICE_BUTTONS_V2 = 112, CFGKEY_VCONTROLLER_UI_BUTTONS_V2 = 113, CFGKEY_INPUT_KEY_CONFIGS_V2 = 114, CFGKEY_VCONTROLLER_HIGHLIGHT_PUSHED_BUTTONS = 115, + CFGKEY_RECENT_CONTENT_V2 = 116, CFGKEY_MAX_RECENT_CONTENT = 117, // 256+ is reserved }; diff --git a/EmuFramework/src/EmuSystem.cc b/EmuFramework/src/EmuSystem.cc index 1012c5c86..1843b7cb4 100644 --- a/EmuFramework/src/EmuSystem.cc +++ b/EmuFramework/src/EmuSystem.cc @@ -509,14 +509,14 @@ FileIO EmuSystem::staticBackupMemoryFile(CStringView uri, size_t size, uint8_t i { if(!size) [[unlikely]] return {}; - auto file = appContext().openFileUri(uri, IOAccessHint::Normal, OpenFlagsMask::CreateRW | OpenFlagsMask::Test); + auto file = appContext().openFileUri(uri, IOAccessHint::Normal, OpenFlags::testCreateFile()); if(!file) [[unlikely]] return {}; auto fileSize = file.size(); if(fileSize != size) file.truncate(size); // size is static so try to use a mapped file for writing - bool isMapped = file.tryMap(IOAccessHint::Normal, OpenFlagsMask::CreateRW); + bool isMapped = file.tryMap(IOAccessHint::Normal, OpenFlags::createFile()); if(initValue && fileSize < size) { if(isMapped) diff --git a/EmuFramework/src/InputDeviceData.cc b/EmuFramework/src/InputDeviceData.cc index 529f58f22..65d687958 100644 --- a/EmuFramework/src/InputDeviceData.cc +++ b/EmuFramework/src/InputDeviceData.cc @@ -74,18 +74,17 @@ void InputDeviceData::buildKeyMap(const InputManager &mgr, const Input::Device & } else { - logMsg("mapping key %s to %s (%u)", d.keyName(mapKeys[0]), mgr.toString(key).data(), key.codes[0]); assert(mapKeys[0] < totalKeys); actionTable[mapKeys[0]].tryPushBack(key); } } /*for(auto [group, i] : std::views::zip(actionTable, iotaCount(actionTable.size()))) { - for(auto code : group) + for(auto key : group) { - if(!code) + if(!key) break; - logMsg("key %s (%u) mapped as %s", mgr.keyCodeToString(code).data(), code, d.keyName(i)); + logMsg("mapped key %s to %s (%u)", d.keyName(i), mgr.toString(key).data(), key.codes[0]); } }*/ } diff --git a/EmuFramework/src/RecentContent.cc b/EmuFramework/src/RecentContent.cc new file mode 100644 index 000000000..ccc6d16c8 --- /dev/null +++ b/EmuFramework/src/RecentContent.cc @@ -0,0 +1,143 @@ +/* This file is part of EmuFramework. + + Imagine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Imagine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with EmuFramework. If not, see */ + +#include "EmuOptions.hh" +#include +#include +#include +#include +#include +#include +#include + +namespace EmuEx +{ + +constexpr SystemLogger log{"RecentContent"}; + +void RecentContent::add(std::string_view fullPath, std::string_view name) +{ + if(fullPath.empty()) + return; + log.info("adding {} @ {} to recent list, current size:{}", name, fullPath, recentContentList.size()); + RecentContentInfo recent{FS::PathString{fullPath}, FS::FileString{name}}; + eraseFirst(recentContentList, recent); // remove existing entry so it's added to the front + recentContentList.insert(recentContentList.begin(), recent); + if(recentContentList.size() > maxRecentContent) + recentContentList.resize(maxRecentContent); + + /*log.info("list contents:"); + for(auto &e : recentContentList) + { + log.info("path: {} name: {}", e.path, e.name); + }*/ +} + +void RecentContent::add(const EmuSystem &system) +{ + add(system.contentLocation(), system.contentDisplayName()); +} + +void RecentContent::writeConfig(FileIO &io) const +{ + writeOptionValueIfNotDefault(io, CFGKEY_MAX_RECENT_CONTENT, maxRecentContent, defaultMaxRecentContent); + log.info("writing recent content list"); + for(const auto &e : recentContentList) + { + auto size = 2 + e.path.size(); + writeOptionValueHeader(io, CFGKEY_RECENT_CONTENT_V2, size); + io.put(uint16_t(e.path.size())); + io.write(e.path.data(), e.path.size()); + } +} + +bool RecentContent::readConfig(MapIO &io, unsigned key, size_t size, const EmuSystem &system) +{ + if(key == CFGKEY_MAX_RECENT_CONTENT) + { + readOptionValue(io, size, maxRecentContent); + return true; + } + else if(key == CFGKEY_RECENT_CONTENT_V2) + { + auto len = io.get(); + FS::PathString path; + auto bytesRead = io.readSized(path, len); + if(bytesRead == -1) + { + log.error("error reading string option"); + return true; + } + if(!bytesRead) + return true; // don't add empty paths + auto displayName = system.contentDisplayNameForPath(path); + if(displayName.empty()) + { + log.info("skipping missing recent content:{}", path); + return true; + } + RecentContentInfo info{path, displayName}; + const auto &added = recentContentList.emplace_back(info); + log.info("added game to recent list:{}, name:{}", added.path, added.name); + return true; + } + return false; +} + +bool RecentContent::readLegacyConfig(MapIO &io, const EmuSystem &system) +{ + log.info("reading legacy config"); + auto readSize = io.size(); + while(readSize) + { + if(readSize < 2) + { + log.info("expected string length but only {} bytes left", readSize); + return false; + } + + auto len = io.get(); + readSize -= 2; + + if(len > readSize) + { + log.info("string length {} longer than {} bytes left", len, readSize); + return false; + } + + FS::PathString path; + auto bytesRead = io.readSized(path, len); + if(bytesRead == -1) + { + log.error("error reading string option"); + return false; + } + if(!bytesRead) + continue; // don't add empty paths + readSize -= len; + auto displayName = system.contentDisplayNameForPath(path); + if(displayName.empty()) + { + log.info("skipping missing recent content:{}", path); + continue; + } + RecentContentInfo info{path, displayName}; + const auto &added = recentContentList.emplace_back(info); + log.info("added game to recent list:{}, name:{}", added.path, added.name); + } + return true; +} + +} diff --git a/EmuFramework/src/gui/AutosaveSlotView.cc b/EmuFramework/src/gui/AutosaveSlotView.cc index 84eeedaa1..4e0d0bf8c 100644 --- a/EmuFramework/src/gui/AutosaveSlotView.cc +++ b/EmuFramework/src/gui/AutosaveSlotView.cc @@ -220,7 +220,7 @@ void AutosaveSlotView::refreshSlots() if(app().autosaveManager().slotName() == e.name()) item.setHighlighted(true); return true; - }, FS::DirOpenFlagsMask::Test); + }, {.test = true}); noSaveSlot = { "No Save", diff --git a/EmuFramework/src/gui/BundledGamesView.cc b/EmuFramework/src/gui/BundledGamesView.cc index cb7bb0c80..03b28170d 100644 --- a/EmuFramework/src/gui/BundledGamesView.cc +++ b/EmuFramework/src/gui/BundledGamesView.cc @@ -37,7 +37,7 @@ BundledGamesView::BundledGamesView(ViewAttachParams attach): [this](const Input::Event &e) { auto &info = system().bundledGameInfo(0); - auto file = appContext().openAsset(info.assetName, IOAccessHint::All, OpenFlagsMask::Test); + auto file = appContext().openAsset(info.assetName, IOAccessHint::All, {.test = true}); if(!file) { logErr("error opening bundled game asset: %s", info.assetName); diff --git a/EmuFramework/src/gui/EmuViewController.cc b/EmuFramework/src/gui/EmuViewController.cc index de656d95f..1629574d4 100644 --- a/EmuFramework/src/gui/EmuViewController.cc +++ b/EmuFramework/src/gui/EmuViewController.cc @@ -25,7 +25,6 @@ #include #include "../EmuOptions.hh" #include "../WindowData.hh" -#include "../configFile.hh" #include #include #include diff --git a/EmuFramework/src/gui/GUIOptionView.cc b/EmuFramework/src/gui/GUIOptionView.cc index 44b4bac01..b650aca4e 100644 --- a/EmuFramework/src/gui/GUIOptionView.cc +++ b/EmuFramework/src/gui/GUIOptionView.cc @@ -211,6 +211,21 @@ GUIOptionView::GUIOptionView(ViewAttachParams attach, bool customMenu): app().showHiddenFilesInPicker = item.flipBoolValue(*this); } }, + maxRecentContent + { + "Max Recent Content Items", std::to_string(app().recentContent.maxRecentContent), &defaultFace(), + [this](const Input::Event &e) + { + app().pushAndShowNewCollectValueRangeInputView(attachParams(), e, + "Input 1 to 100", std::to_string(app().recentContent.maxRecentContent), + [this](EmuApp &app, auto val) + { + app.recentContent.maxRecentContent = val; + maxRecentContent.set2ndName(std::to_string(val)); + return true; + }); + } + }, orientationHeading { "Orientation", &defaultBoldFace() @@ -336,6 +351,7 @@ void GUIOptionView::loadStockItems() if(used(showBluetoothScan)) item.emplace_back(&showBluetoothScan); item.emplace_back(&showHiddenFiles); + item.emplace_back(&maxRecentContent); item.emplace_back(&orientationHeading); item.emplace_back(&emuOrientation); item.emplace_back(&menuOrientation); diff --git a/EmuFramework/src/gui/MainMenuView.cc b/EmuFramework/src/gui/MainMenuView.cc index c5d4d34b9..a46fa3f6d 100644 --- a/EmuFramework/src/gui/MainMenuView.cc +++ b/EmuFramework/src/gui/MainMenuView.cc @@ -22,7 +22,7 @@ #include #include #include -#include "RecentGameView.hh" +#include "RecentContentView.hh" #include "../EmuOptions.hh" #include #include @@ -86,9 +86,9 @@ MainMenuView::MainMenuView(ViewAttachParams attach, bool customMenu): "Recent Content", &defaultFace(), [this](const Input::Event &e) { - if(app().recentContent().size()) + if(app().recentContent.size()) { - pushAndShow(makeView(app().recentContent()), e); + pushAndShow(makeView(app().recentContent), e); } } }, @@ -295,7 +295,7 @@ void MainMenuView::onShow() { TableView::onShow(); logMsg("refreshing main menu state"); - recentGames.setActive(app().recentContent().size()); + recentGames.setActive(app().recentContent.size()); systemActions.setActive(system().hasContent()); bluetoothDisconnect.setActive(Bluetooth::devsConnected(appContext())); } diff --git a/EmuFramework/src/gui/RecentGameView.cc b/EmuFramework/src/gui/RecentContentView.cc similarity index 73% rename from EmuFramework/src/gui/RecentGameView.cc rename to EmuFramework/src/gui/RecentContentView.cc index cd5244211..b9faf424a 100644 --- a/EmuFramework/src/gui/RecentGameView.cc +++ b/EmuFramework/src/gui/RecentContentView.cc @@ -13,7 +13,8 @@ You should have received a copy of the GNU General Public License along with EmuFramework. If not, see */ -#include "RecentGameView.hh" +#include "RecentContentView.hh" +#include #include #include #include @@ -21,18 +22,18 @@ namespace EmuEx { -RecentGameView::RecentGameView(ViewAttachParams attach, EmuApp::RecentContentList &list): +RecentContentView::RecentContentView(ViewAttachParams attach, RecentContent &recentContent_): TableView { "Recent Content", attach, [this](const TableView &) { - return 1 + recentGame.size(); + return 1 + recentItems.size(); }, [this](const TableView &, size_t idx) -> MenuItem& { - return idx < recentGame.size() ? recentGame[idx] : clear; + return idx < recentItems.size() ? recentItems[idx] : clear; } }, clear @@ -45,18 +46,18 @@ RecentGameView::RecentGameView(ViewAttachParams attach, EmuApp::RecentContentLis { .onYes = [this] { - this->list.clear(); + recentItems.clear(); dismiss(); } }), e); } }, - list{list} + recentContent{recentContent_} { - recentGame.reserve(list.size()); - for(auto &entry : list) + recentItems.reserve(recentContent_.size()); + for(auto &entry : recentContent_) { - auto &recentItem = recentGame.emplace_back(entry.name, &defaultFace(), + auto &recentItem = recentItems.emplace_back(entry.name, &defaultFace(), [this, &entry](const Input::Event &e) { app().createSystemWithMedia({}, entry.path, appContext().fileUriDisplayName(entry.path), e, {}, attachParams(), @@ -66,7 +67,7 @@ RecentGameView::RecentGameView(ViewAttachParams attach, EmuApp::RecentContentLis }); }); } - clear.setActive(list.size()); + clear.setActive(recentContent_.size()); } } diff --git a/EmuFramework/src/gui/RecentGameView.hh b/EmuFramework/src/gui/RecentContentView.hh similarity index 76% rename from EmuFramework/src/gui/RecentGameView.hh rename to EmuFramework/src/gui/RecentContentView.hh index 70d8e5efe..6b6554f73 100644 --- a/EmuFramework/src/gui/RecentGameView.hh +++ b/EmuFramework/src/gui/RecentContentView.hh @@ -16,7 +16,7 @@ along with EmuFramework. If not, see */ #include -#include +#include #include #include #include @@ -24,15 +24,15 @@ namespace EmuEx { -class RecentGameView : public TableView, public EmuAppHelper +class RecentContentView : public TableView, public EmuAppHelper { public: - RecentGameView(ViewAttachParams attach, EmuApp::RecentContentList &list); + RecentContentView(ViewAttachParams attach, RecentContent &); private: - std::vector recentGame{}; + std::vector recentItems{}; TextMenuItem clear{}; - EmuApp::RecentContentList &list; + RecentContent &recentContent; }; } diff --git a/EmuFramework/src/pathUtils.cc b/EmuFramework/src/pathUtils.cc index 168518399..88a17e355 100644 --- a/EmuFramework/src/pathUtils.cc +++ b/EmuFramework/src/pathUtils.cc @@ -93,7 +93,7 @@ bool hasWriteAccessToDir(CStringView path) if(IG::isUri(path)) return true; auto testFilePath = FS::pathString(path, ".safe-to-delete-me"); - PosixIO testFile{testFilePath, OpenFlagsMask::New | OpenFlagsMask::Test}; + PosixIO testFile{testFilePath, OpenFlags::testNewFile()}; auto removeTestFile = IG::scopeGuard([&]() { if(testFile) FS::remove(testFilePath); }); return (bool)testFile; } diff --git a/EmuFramework/src/shared/mednafen-emuex/MDFNFILE.cc b/EmuFramework/src/shared/mednafen-emuex/MDFNFILE.cc index 965158d71..5e3f3807a 100644 --- a/EmuFramework/src/shared/mednafen-emuex/MDFNFILE.cc +++ b/EmuFramework/src/shared/mednafen-emuex/MDFNFILE.cc @@ -87,8 +87,8 @@ MDFNFILE::MDFNFILE(VirtualFS* vfs, std::unique_ptr str): extern int openFdHelper(const char *file, int oflag, mode_t mode) { - auto openFlags = (oflag & O_CREAT) ? IG::OpenFlagsMask::New : IG::OpenFlagsMask{}; - return EmuEx::gAppContext().openFileUriFd(file, openFlags | IG::OpenFlagsMask::Test).release(); + auto openFlags = (oflag & O_CREAT) ? IG::OpenFlags::newFile() : IG::OpenFlags{}; + return EmuEx::gAppContext().openFileUriFd(file, openFlags | IG::OpenFlags{.test = true}).release(); } extern FILE *fopenHelper(const char* filename, const char* mode) diff --git a/EmuFramework/src/shared/mednafen-emuex/StreamImpl.cc b/EmuFramework/src/shared/mednafen-emuex/StreamImpl.cc index 71d1d4676..75c6cf17d 100644 --- a/EmuFramework/src/shared/mednafen-emuex/StreamImpl.cc +++ b/EmuFramework/src/shared/mednafen-emuex/StreamImpl.cc @@ -29,7 +29,7 @@ IG::ApplicationContext gAppContext(); namespace Mednafen { -static std::pair modeToAttribs(uint32 mode) +static std::pair modeToAttribs(uint32 mode) { using namespace IG; switch(mode) @@ -38,19 +38,19 @@ static std::pair modeToAttribs(uint32 mode) throw MDFN_Error(0, _("Unknown FileStream mode.")); case FileStream::MODE_READ: - return {OpenFlagsMask::Read, Stream::ATTRIBUTE_READABLE}; + return {{.read = true}, Stream::ATTRIBUTE_READABLE}; case FileStream::MODE_READ_WRITE: - return {OpenFlagsMask::CreateRW, Stream::ATTRIBUTE_READABLE | Stream::ATTRIBUTE_WRITEABLE}; + return {OpenFlags::createFile(), Stream::ATTRIBUTE_READABLE | Stream::ATTRIBUTE_WRITEABLE}; case FileStream::MODE_WRITE: - return {OpenFlagsMask::New, Stream::ATTRIBUTE_WRITEABLE}; + return {OpenFlags::newFile(), Stream::ATTRIBUTE_WRITEABLE}; case FileStream::MODE_WRITE_INPLACE: - return {OpenFlagsMask::Write | OpenFlagsMask::Create, Stream::ATTRIBUTE_WRITEABLE}; + return {{.write = true, .create = true}, Stream::ATTRIBUTE_WRITEABLE}; case FileStream::MODE_WRITE_SAFE: - return {OpenFlagsMask::Write, Stream::ATTRIBUTE_WRITEABLE}; + return {{.write = true}, Stream::ATTRIBUTE_WRITEABLE}; } } diff --git a/EmuFramework/src/vcontrols/VController.cc b/EmuFramework/src/vcontrols/VController.cc index 2c1c2cc0f..359180c7b 100644 --- a/EmuFramework/src/vcontrols/VController.cc +++ b/EmuFramework/src/vcontrols/VController.cc @@ -852,7 +852,7 @@ std::vector VController::defaultEmulatedDeviceGroups() const std::vector gpElements; for(const auto &c : system().inputDeviceDesc(0).components) { - if(!to_underlying(c.flags & InputComponentFlagsMask::altConfig)) + if(!c.flags.altConfig) add(gpElements, c); } if(hasWindow()) @@ -943,7 +943,7 @@ bool VController::gamepadIsActive() const static int8_t rowSize(InputComponentDesc c) { - auto size = to_underlying(c.flags & InputComponentFlagsMask::rowSizeBits) >> 1; + auto size = c.flags.rowSize; if(size) return size; else @@ -967,7 +967,7 @@ VControllerElement &VController::add(std::vector &elems, Inp auto &e = elems.emplace_back(std::in_place_type, c.keyCodes, c.layoutOrigin, rowSize(c)); auto &grp = *e.buttonGroup(); updateEnabledButtons(grp); - if(to_underlying(c.flags & InputComponentFlagsMask::staggeredLayout)) + if(c.flags.staggeredLayout) grp.setStaggerType(5); return e; } diff --git a/GBA.emu/src/main/input.cc b/GBA.emu/src/main/input.cc index b95bb6e55..e7d47c6cd 100644 --- a/GBA.emu/src/main/input.cc +++ b/GBA.emu/src/main/input.cc @@ -253,12 +253,12 @@ SystemInputDeviceDesc GbaSystem::inputDeviceDesc(int idx) const { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO}, - InputComponentDesc{"Face Buttons + Inline L/R", faceLRKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Face Buttons + Inline L/R", faceLRKeyInfo, InputComponent::button, RB2DO, {.altConfig = true}}, InputComponentDesc{"L", lKeyInfo, InputComponent::trigger, LB2DO}, InputComponentDesc{"R", rKeyInfo, InputComponent::trigger, RB2DO}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/GBA.emu/src/vbam/gba/GBA.cpp b/GBA.emu/src/vbam/gba/GBA.cpp index 7fdf6f858..ee5c9ef3a 100644 --- a/GBA.emu/src/vbam/gba/GBA.cpp +++ b/GBA.emu/src/vbam/gba/GBA.cpp @@ -861,7 +861,7 @@ static bool CPUWriteState(GBASys &gba, gzFile gzFile) bool CPUWriteState(IG::ApplicationContext ctx, GBASys &gba, const char* file) { - gzFile gzFile = utilGzOpen(ctx.openFileUriFd(file, IG::OpenFlagsMask::New | IG::OpenFlagsMask::Test).release(), "wb"); + gzFile gzFile = utilGzOpen(ctx.openFileUriFd(file, IG::OpenFlags::testNewFile()).release(), "wb"); if (gzFile == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file); @@ -1364,7 +1364,7 @@ bool CPUImportEepromFile(GBASys &gba, const char* fileName) bool CPUReadBatteryFile(IG::ApplicationContext ctx, GBASys &gba, const char* fileName) { - auto buff = IG::FileUtils::rwBufferFromUri(ctx, fileName, IG::OpenFlagsMask::Test, saveMemorySize(), 0xFF); + auto buff = IG::FileUtils::rwBufferFromUri(ctx, fileName, {.test = true}, saveMemorySize(), 0xFF); if(!buff) return false; saveMemoryIsMappedFile = buff.isMappedFile(); diff --git a/GBC.emu/src/main/Cheats.cc b/GBC.emu/src/main/Cheats.cc index 5a3af6f92..dc3a39608 100644 --- a/GBC.emu/src/main/Cheats.cc +++ b/GBC.emu/src/main/Cheats.cc @@ -83,7 +83,7 @@ void writeCheatFile(EmuSystem &sys_) return; } - auto file = ctx.openFileUri(path, OpenFlagsMask::New | OpenFlagsMask::Test); + auto file = ctx.openFileUri(path, OpenFlags::testNewFile()); if(!file) { logMsg("error creating cheats file %s", path.data()); @@ -108,7 +108,7 @@ void readCheatFile(EmuSystem &sys_) { auto &sys = static_cast(sys_); auto path = sys.userFilePath(sys.cheatsDir, ".gbcht"); - auto file = sys.appContext().openFileUri(path, IOAccessHint::All, OpenFlagsMask::Test); + auto file = sys.appContext().openFileUri(path, IOAccessHint::All, {.test = true}); if(!file) { return; diff --git a/GBC.emu/src/main/Cheats.hh b/GBC.emu/src/main/Cheats.hh index 6cce191d4..d27a4d058 100644 --- a/GBC.emu/src/main/Cheats.hh +++ b/GBC.emu/src/main/Cheats.hh @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with GBC.emu. If not, see */ -#include +#include #include #include #include diff --git a/GBC.emu/src/main/Main.cc b/GBC.emu/src/main/Main.cc index 58daa9715..546ef6d90 100755 --- a/GBC.emu/src/main/Main.cc +++ b/GBC.emu/src/main/Main.cc @@ -89,7 +89,7 @@ FS::FileString GbcSystem::stateFilename(int slot, std::string_view name) const void GbcSystem::saveState(IG::CStringView path) { - OFStream stream{appContext().openFileUri(path, OpenFlagsMask::New)}; + OFStream stream{appContext().openFileUri(path, OpenFlags::newFile())}; if(!gbEmu.saveState(frameBuffer, gambatte::lcd_hres, stream)) throwFileWriteError(); } diff --git a/GBC.emu/src/main/input.cc b/GBC.emu/src/main/input.cc index 0b5cdffed..4649d6451 100644 --- a/GBC.emu/src/main/input.cc +++ b/GBC.emu/src/main/input.cc @@ -192,7 +192,7 @@ SystemInputDeviceDesc GbcSystem::inputDeviceDesc(int idx) const InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/MD.emu/src/main/Cheats.cc b/MD.emu/src/main/Cheats.cc index 9cc01e123..0ec57f02e 100644 --- a/MD.emu/src/main/Cheats.cc +++ b/MD.emu/src/main/Cheats.cc @@ -402,7 +402,7 @@ void writeCheatFile(EmuSystem &sys_) return; } - auto file = ctx.openFileUri(path, OpenFlagsMask::New | OpenFlagsMask::Test); + auto file = ctx.openFileUri(path, OpenFlags::testNewFile()); if(!file) { logMsg("error creating cheats file %s", path.data()); @@ -431,7 +431,7 @@ void readCheatFile(EmuSystem &sys_) { auto &sys = static_cast(sys_); auto path = sys.userFilePath(sys.cheatsDir, ".pat"); - auto file = sys.appContext().openFileUri(path, IOAccessHint::All, OpenFlagsMask::Test); + auto file = sys.appContext().openFileUri(path, IOAccessHint::All, {.test = true}); if(!file) { return; diff --git a/MD.emu/src/main/Cheats.hh b/MD.emu/src/main/Cheats.hh index 2aa1c3fa4..9cd098107 100644 --- a/MD.emu/src/main/Cheats.hh +++ b/MD.emu/src/main/Cheats.hh @@ -16,7 +16,7 @@ along with MD.emu. If not, see */ #include -#include +#include #include #include diff --git a/MD.emu/src/main/Main.cc b/MD.emu/src/main/Main.cc index 325ac6fd3..12d52670f 100755 --- a/MD.emu/src/main/Main.cc +++ b/MD.emu/src/main/Main.cc @@ -176,7 +176,7 @@ void MdSystem::loadBackupMemory(EmuApp &app) if(sCD.isActive) { auto saveStr = bramSaveFilename(app); - auto bramFile = appContext().openFileUri(saveStr, IOAccessHint::All, OpenFlagsMask::Test); + auto bramFile = appContext().openFileUri(saveStr, IOAccessHint::All, {.test = true}); if(!bramFile) { logMsg("no BRAM on disk, formatting"); @@ -230,7 +230,7 @@ void MdSystem::onFlushBackupMemory(EmuApp &app, BackupMemoryDirtyFlags) { logMsg("saving BRAM"); auto saveStr = bramSaveFilename(app); - auto bramFile = appContext().openFileUri(saveStr, OpenFlagsMask::New | OpenFlagsMask::Test); + auto bramFile = appContext().openFileUri(saveStr, OpenFlags::testNewFile()); if(!bramFile) logMsg("error creating bram file"); else diff --git a/MD.emu/src/main/input.cc b/MD.emu/src/main/input.cc index c31e26a62..64311749e 100644 --- a/MD.emu/src/main/input.cc +++ b/MD.emu/src/main/input.cc @@ -406,7 +406,7 @@ SystemInputDeviceDesc MdSystem::inputDeviceDesc(int idx) const InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO}, InputComponentDesc{"Mode", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Mode/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Mode/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/MD.emu/src/scd/scd.cc b/MD.emu/src/scd/scd.cc index 13aadf14a..53adfdafc 100644 --- a/MD.emu/src/scd/scd.cc +++ b/MD.emu/src/scd/scd.cc @@ -30,7 +30,7 @@ void scd_interruptSubCpu(unsigned irq) void dumpPRG(const char *n) { - auto f = IG::FileIO{n, IG::OpenFlagsMask::New | IG::OpenFlagsMask::Test}; + auto f = IG::FileIO{n, IG::OpenFlags::testNewFile()}; f.write(sCD.prg.b, sizeof(sCD.prg.b)); } diff --git a/MSX.emu/src/main/RomLoader.cc b/MSX.emu/src/main/RomLoader.cc index 55766431d..bbb040293 100755 --- a/MSX.emu/src/main/RomLoader.cc +++ b/MSX.emu/src/main/RomLoader.cc @@ -62,7 +62,7 @@ UInt8 *romLoad(const char *filename, const char *filenameInArchive, int *size) auto appCtx = sys.appContext(); if(filename[0] == '/' || IG::isUri(filename)) // try to load absolute path directly { - auto file = appCtx.openFileUri(filename, IOAccessHint::All, OpenFlagsMask::Test); + auto file = appCtx.openFileUri(filename, IOAccessHint::All, {.test = true}); if(file) { return fileToMallocBuffer(file, size); @@ -72,7 +72,7 @@ UInt8 *romLoad(const char *filename, const char *filenameInArchive, int *size) } // relative path, try firmware directory { - auto file = appCtx.openFileUri(FS::uriString(machineBasePath(sys), filename), IOAccessHint::All, OpenFlagsMask::Test); + auto file = appCtx.openFileUri(FS::uriString(machineBasePath(sys), filename), IOAccessHint::All, {.test = true}); if(file) { return fileToMallocBuffer(file, size); @@ -80,7 +80,7 @@ UInt8 *romLoad(const char *filename, const char *filenameInArchive, int *size) } // fallback to app assets { - auto file = appCtx.openAsset(filename, IOAccessHint::All, OpenFlagsMask::Test); + auto file = appCtx.openAsset(filename, IOAccessHint::All, {.test = true}); if(file) { return fileToMallocBuffer(file, size); @@ -96,12 +96,12 @@ CLINK FILE *openMachineIni(const char *path, const char *mode) auto &sys = static_cast(gSystem()); auto appCtx = sys.appContext(); auto filePathInFirmwarePath = FS::uriString(machineBasePath(sys), path); - auto file = appCtx.openFileUri(filePathInFirmwarePath, IOAccessHint::All, OpenFlagsMask::Test); + auto file = appCtx.openFileUri(filePathInFirmwarePath, IOAccessHint::All, {.test = true}); if(file) { return file.toFileStream(mode); } - auto assetFile = appCtx.openAsset(path, IOAccessHint::All, OpenFlagsMask::Test); + auto assetFile = appCtx.openAsset(path, IOAccessHint::All, {.test = true}); if(assetFile) { return assetFile.toFileStream(mode); diff --git a/MSX.emu/src/main/input.cc b/MSX.emu/src/main/input.cc index b98bf604f..b6763cd58 100644 --- a/MSX.emu/src/main/input.cc +++ b/MSX.emu/src/main/input.cc @@ -550,7 +550,7 @@ SystemInputDeviceDesc MsxSystem::inputDeviceDesc(int idx) const { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, InputComponentDesc{"Joystick Buttons", faceKeyInfo, InputComponent::button, RB2DO}, - InputComponentDesc{"Space & Keyboard Toggle", shortcutKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::rowSize1}, + InputComponentDesc{"Space & Keyboard Toggle", shortcutKeyInfo, InputComponent::button, RB2DO, {.rowSize = 1}}, }; static constexpr SystemInputDeviceDesc jsDesc{"Joystick", jsComponents}; diff --git a/MSX.emu/src/main/ziphelper.cc b/MSX.emu/src/main/ziphelper.cc index 8772b413f..29ab1f797 100644 --- a/MSX.emu/src/main/ziphelper.cc +++ b/MSX.emu/src/main/ziphelper.cc @@ -104,7 +104,7 @@ bool zipStartWrite(const char *fileName) assert(!writeArch); writeArch = archive_write_new(); archive_write_set_format_zip(writeArch); - int fd = EmuEx::gAppContext().openFileUriFd(fileName, OpenFlagsMask::New | OpenFlagsMask::Test).release(); + int fd = EmuEx::gAppContext().openFileUriFd(fileName, IG::OpenFlags::testNewFile()).release(); if(archive_write_open_fd(writeArch, fd) != ARCHIVE_OK) { archive_write_free(writeArch); diff --git a/NEO.emu/src/main/EmuMenuViews.cc b/NEO.emu/src/main/EmuMenuViews.cc index 836ee84a2..9d5fe2e0d 100644 --- a/NEO.emu/src/main/EmuMenuViews.cc +++ b/NEO.emu/src/main/EmuMenuViews.cc @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "MainApp.hh" #include @@ -488,7 +488,7 @@ class GameListView : public TableView, public MainAppHelper app().createSystemWithMedia({}, gamePath, appContext().fileUriDisplayName(gamePath), e, {}, attachParams(), [this](Input::Event e) { - app().addCurrentContentToRecent(); + app().recentContent.add(system()); app().launchSystem(e); }); } diff --git a/NEO.emu/src/main/input.cc b/NEO.emu/src/main/input.cc index f98b24599..0721fb290 100644 --- a/NEO.emu/src/main/input.cc +++ b/NEO.emu/src/main/input.cc @@ -262,10 +262,10 @@ SystemInputDeviceDesc NeoSystem::inputDeviceDesc(int idx) const static constexpr std::array gamepadComponents { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, - InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::staggeredLayout}, + InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, {.staggeredLayout = true}}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/NEO.emu/src/main/unzip.cc b/NEO.emu/src/main/unzip.cc index 76908abfe..af42da7d8 100644 --- a/NEO.emu/src/main/unzip.cc +++ b/NEO.emu/src/main/unzip.cc @@ -142,6 +142,6 @@ struct PKZIP *open_rom_zip(void *contextPtr, char *romPath, char *name) gzFile gzopenHelper(void *contextPtr, const char *filename, const char *mode) { auto &ctx = *((IG::ApplicationContext*)contextPtr); - auto openFlags = std::string_view{mode}.contains('w') ? IG::OpenFlagsMask::New : IG::OpenFlagsMask{}; - return gzdopen(ctx.openFileUriFd(filename, openFlags | IG::OpenFlagsMask::Test).release(), mode); + auto openFlags = std::string_view{mode}.contains('w') ? OpenFlags::newFile() : OpenFlags{}; + return gzdopen(ctx.openFileUriFd(filename, openFlags | OpenFlags{.test = true}).release(), mode); } diff --git a/NES.emu/src/main/Main.cc b/NES.emu/src/main/Main.cc index 3fc78a5dd..6dab90aca 100755 --- a/NES.emu/src/main/Main.cc +++ b/NES.emu/src/main/Main.cc @@ -210,7 +210,7 @@ void NesSystem::setDefaultPalette(IG::ApplicationContext ctx, IG::CStringView pa } else { - IO io = ctx.openFileUri(palPath, IO::AccessHint::All, OpenFlagsMask::Test); + IO io = ctx.openFileUri(palPath, IO::AccessHint::All, {.test = true}); if(!io) return; setDefaultPalette(io); diff --git a/NES.emu/src/main/input.cc b/NES.emu/src/main/input.cc index c86b40e6b..f997534d4 100644 --- a/NES.emu/src/main/input.cc +++ b/NES.emu/src/main/input.cc @@ -295,7 +295,7 @@ SystemInputDeviceDesc NesSystem::inputDeviceDesc(int idx) const InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/PCE.emu/src/main/input.cc b/PCE.emu/src/main/input.cc index 446429720..8b3d1bae3 100644 --- a/PCE.emu/src/main/input.cc +++ b/PCE.emu/src/main/input.cc @@ -246,7 +246,7 @@ SystemInputDeviceDesc PceSystem::inputDeviceDesc(int idx) const InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Run", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Run", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Run", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/Snes9x/src/main/S9XApi.cc b/Snes9x/src/main/S9XApi.cc index a5fd6a2f9..56fb7cb4e 100755 --- a/Snes9x/src/main/S9XApi.cc +++ b/Snes9x/src/main/S9XApi.cc @@ -381,8 +381,8 @@ void removeFileHelper(const char* filename) gzFile gzopenHelper(const char *filename, const char *mode) { - auto openFlags = std::string_view{mode}.contains('w') ? IG::OpenFlagsMask::New : IG::OpenFlagsMask{}; - return gzdopen(gAppContext().openFileUriFd(filename, openFlags | IG::OpenFlagsMask::Test).release(), mode); + auto openFlags = std::string_view{mode}.contains('w') ? OpenFlags::newFile() : OpenFlags{}; + return gzdopen(gAppContext().openFileUriFd(filename, openFlags | OpenFlags{.test = true}).release(), mode); } // from screenshot.h diff --git a/Snes9x/src/main/input.cc b/Snes9x/src/main/input.cc index e6ba1d3be..9fb4cbc9e 100644 --- a/Snes9x/src/main/input.cc +++ b/Snes9x/src/main/input.cc @@ -591,13 +591,13 @@ SystemInputDeviceDesc Snes9xSystem::inputDeviceDesc(int idx) const static constexpr std::array gamepadComponents { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, - InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::staggeredLayout}, - InputComponentDesc{"Face Buttons + Inline L/R", faceLRKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig | InputComponentFlagsMask::staggeredLayout}, + InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, {.staggeredLayout = true}}, + InputComponentDesc{"Face Buttons + Inline L/R", faceLRKeyInfo, InputComponent::button, RB2DO, {.altConfig = true, .staggeredLayout = true}}, InputComponentDesc{"L", lKeyInfo, InputComponent::trigger, LB2DO}, InputComponentDesc{"R", rKeyInfo, InputComponent::trigger, RB2DO}, InputComponentDesc{"Select", {¢erKeyInfo[0], 1}, InputComponent::button, LB2DO}, InputComponentDesc{"Start", {¢erKeyInfo[1], 1}, InputComponent::button, RB2DO}, - InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, InputComponentFlagsMask::altConfig}, + InputComponentDesc{"Select/Start", centerKeyInfo, InputComponent::button, CB2DO, {.altConfig = true}}, }; static constexpr SystemInputDeviceDesc gamepadDesc{"Gamepad", gamepadComponents}; diff --git a/Snes9x/src/snes9x/bml.cpp b/Snes9x/src/snes9x/bml.cpp index 32ab68bbe..0a2f4e6c5 100644 --- a/Snes9x/src/snes9x/bml.cpp +++ b/Snes9x/src/snes9x/bml.cpp @@ -289,7 +289,7 @@ IG::ApplicationContext gAppContext(); bool bml_node::parse_file(std::string filename) { - IG::IFStream file(EmuEx::gAppContext().openFileUri(filename, IG::OpenFlagsMask::Test), std::ios_base::binary); + IG::IFStream file(EmuEx::gAppContext().openFileUri(filename, {.test = true}), std::ios_base::binary); if (!file) return false; diff --git a/Swan.emu/src/main/input.cc b/Swan.emu/src/main/input.cc index d850eea1e..c7c16acb8 100644 --- a/Swan.emu/src/main/input.cc +++ b/Swan.emu/src/main/input.cc @@ -344,9 +344,9 @@ SystemInputDeviceDesc WsSystem::inputDeviceDesc(int idx) const static constexpr std::array gamepadComponents { InputComponentDesc{"D-Pad", dpadKeyInfo, InputComponent::dPad, LB2DO}, - InputComponentDesc{"Face Buttons + Opposite D-Pad Buttons", faceButtonCombinedCodes, InputComponent::button, RB2DO, InputComponentFlagsMask::rowSize2}, - InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig}, - InputComponentDesc{"Opposite D-Pad Buttons", oppositeDPadKeyInfo, InputComponent::button, RB2DO, InputComponentFlagsMask::altConfig | InputComponentFlagsMask::staggeredLayout}, + InputComponentDesc{"Face Buttons + Opposite D-Pad Buttons", faceButtonCombinedCodes, InputComponent::button, RB2DO, {.rowSize = 2}}, + InputComponentDesc{"Face Buttons", faceKeyInfo, InputComponent::button, RB2DO, {.altConfig = true}}, + InputComponentDesc{"Opposite D-Pad Buttons", oppositeDPadKeyInfo, InputComponent::button, RB2DO, {.altConfig = true, .staggeredLayout = true}}, InputComponentDesc{"Start", centerKeyInfo, InputComponent::button, RB2DO}, }; diff --git a/imagine/include/imagine/base/ApplicationContext.hh b/imagine/include/imagine/base/ApplicationContext.hh index 5032190f5..247417e31 100755 --- a/imagine/include/imagine/base/ApplicationContext.hh +++ b/imagine/include/imagine/base/ApplicationContext.hh @@ -27,9 +27,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -46,13 +46,8 @@ class Device; namespace IG::FS { -class PathString; -class FileString; -struct PathLocation; -struct RootPathInfo; class AssetDirectoryIterator; class directory_entry; -enum class DirOpenFlagsMask: uint8_t; } namespace IG @@ -69,11 +64,16 @@ enum class Permission COARSE_LOCATION }; -static constexpr uint32_t - SYS_UI_STYLE_NO_FLAGS = 0, - SYS_UI_STYLE_DIM_NAV = bit(0), - SYS_UI_STYLE_HIDE_NAV = bit(1), - SYS_UI_STYLE_HIDE_STATUS = bit(2); +struct SystemUIStyleFlags +{ + uint8_t + dimNavigation:1{}, + hideNavigation:1{}, + hideStatus:1{}; + + constexpr bool operator ==(SystemUIStyleFlags const &) const = default; +}; + class ApplicationContext : public ApplicationContextImpl { @@ -166,7 +166,7 @@ public: FS::PathLocation sharedStoragePathLocation() const; std::vector rootFileLocations() const; FS::RootPathInfo rootPathInfo(std::string_view path) const; - AssetIO openAsset(CStringView name, IOAccessHint access, OpenFlagsMask oFlags = {}, const char *appName = applicationName) const; + AssetIO openAsset(CStringView name, IOAccessHint access, OpenFlags oFlags = {}, const char *appName = applicationName) const; FS::AssetDirectoryIterator openAssetDirectory(CStringView path, const char *appName = applicationName); // path/file access using OS-specific URIs such as those in the Android Storage Access Framework, @@ -176,9 +176,9 @@ public: bool hasSystemDocumentPicker() const; bool showSystemDocumentPicker(SystemDocumentPickerDelegate); bool showSystemCreateDocumentPicker(SystemDocumentPickerDelegate); - FileIO openFileUri(CStringView uri, IOAccessHint, OpenFlagsMask oFlags = {}) const; - FileIO openFileUri(CStringView uri, OpenFlagsMask oFlags = {}) const; - UniqueFileDescriptor openFileUriFd(CStringView uri, OpenFlagsMask oFlags = {}) const; + FileIO openFileUri(CStringView uri, IOAccessHint, OpenFlags oFlags = {}) const; + FileIO openFileUri(CStringView uri, OpenFlags oFlags = {}) const; + UniqueFileDescriptor openFileUriFd(CStringView uri, OpenFlags oFlags = {}) const; bool fileUriExists(CStringView uri) const; WallClockTimePoint fileUriLastWriteTime(CStringView uri) const; std::string fileUriFormatLastWriteTimeLocal(CStringView uri) const; @@ -187,10 +187,10 @@ public: bool renameFileUri(CStringView oldUri, CStringView newUri) const; bool createDirectoryUri(CStringView uri) const; bool removeDirectoryUri(CStringView uri) const; - bool forEachInDirectoryUri(CStringView uri, DirectoryEntryDelegate, FS::DirOpenFlagsMask flags = {}) const; + bool forEachInDirectoryUri(CStringView uri, DirectoryEntryDelegate, FS::DirOpenFlags flags = {}) const; // OS UI management (status & navigation bar) - void setSysUIStyle(uint32_t flags); + void setSysUIStyle(SystemUIStyleFlags); bool hasTranslucentSysUI() const; bool hasHardwareNavButtons() const; void setSystemOrientation(Rotation); diff --git a/imagine/include/imagine/base/BaseWindow.hh b/imagine/include/imagine/base/BaseWindow.hh index 5a94671d3..2becb0d93 100644 --- a/imagine/include/imagine/base/BaseWindow.hh +++ b/imagine/include/imagine/base/BaseWindow.hh @@ -66,7 +66,7 @@ protected: DrawPhase drawPhase{DrawPhase::READY}; int8_t drawEventPriority_{}; // all windows need an initial onSurfaceChange call - uint8_t surfaceChangeFlags{SurfaceChange::SURFACE_RESIZED | SurfaceChange::CONTENT_RECT_RESIZED}; + WindowSurfaceChangeFlags surfaceChangeFlags{.surfaceResized = true, .contentRectResized = true}; IG_UseMemberIfOrConstant(!Config::SYSTEM_ROTATES_WINDOWS, Rotation, Rotation::UP, softOrientation_){Rotation::UP}; F2Size smmPixelScaler() const; diff --git a/imagine/include/imagine/base/Window.hh b/imagine/include/imagine/base/Window.hh index 08428eafa..4402b193d 100644 --- a/imagine/include/imagine/base/Window.hh +++ b/imagine/include/imagine/base/Window.hh @@ -151,7 +151,7 @@ public: void dispatchSurfaceCreated(); void dispatchSurfaceChanged(); void dispatchSurfaceDestroyed(); - void signalSurfaceChanged(uint8_t surfaceChangeFlags); + void signalSurfaceChanged(WindowSurfaceChangeFlags); private: F2Size pixelSizeAsMM(WSize size); diff --git a/imagine/include/imagine/base/android/AndroidApplication.hh b/imagine/include/imagine/base/android/AndroidApplication.hh index ee34f5edc..6b307dad5 100644 --- a/imagine/include/imagine/base/android/AndroidApplication.hh +++ b/imagine/include/imagine/base/android/AndroidApplication.hh @@ -40,7 +40,7 @@ namespace IG::FS { class PathString; class FileString; -enum class DirOpenFlagsMask: uint8_t; +struct DirOpenFlags; } namespace IG @@ -78,7 +78,7 @@ public: bool systemAnimatesWindowRotation() const; void setIdleDisplayPowerSave(JNIEnv *, jobject baseActivity, bool on); void endIdleByUserActivity(ApplicationContext); - void setSysUIStyle(JNIEnv *, jobject baseActivity, int32_t androidSDK, uint32_t flags); + void setSysUIStyle(JNIEnv *, jobject baseActivity, int32_t androidSDK, SystemUIStyleFlags); bool hasDisplayCutout() const { return deviceFlags & DISPLAY_CUTOUT_BIT; } bool hasFocus() const; void addNotification(JNIEnv *, jobject baseActivity, const char *onShow, const char *title, const char *message); @@ -89,7 +89,7 @@ public: bool createDocumentIntent(JNIEnv *, jobject baseActivity, SystemDocumentPickerDelegate); FrameTimer makeFrameTimer(Screen &); bool requestPermission(ApplicationContext, Permission); - UniqueFileDescriptor openFileUriFd(JNIEnv *, jobject baseActivity, CStringView uri, OpenFlagsMask oFlags = {}) const; + UniqueFileDescriptor openFileUriFd(JNIEnv *, jobject baseActivity, CStringView uri, OpenFlags oFlags = {}) const; bool fileUriExists(JNIEnv *, jobject baseActivity, CStringView uri) const; WallClockTimePoint fileUriLastWriteTime(JNIEnv *, jobject baseActivity, CStringView uri) const; std::string fileUriFormatLastWriteTimeLocal(JNIEnv *, jobject baseActivity, CStringView uri) const; @@ -98,7 +98,7 @@ public: bool renameFileUri(JNIEnv *, jobject baseActivity, CStringView oldUri, CStringView newUri) const; bool createDirectoryUri(JNIEnv *, jobject baseActivity, CStringView uri) const; bool forEachInDirectoryUri(JNIEnv *, jobject baseActivity, CStringView uri, DirectoryEntryDelegate, - FS::DirOpenFlagsMask) const; + FS::DirOpenFlags) const; std::string formatDateAndTime(JNIEnv *, jclass baseActivityClass, WallClockTimePoint timeSinceEpoch); // Input system functions diff --git a/imagine/include/imagine/base/baseDefs.hh b/imagine/include/imagine/base/baseDefs.hh index ed869db7e..028cc4541 100644 --- a/imagine/include/imagine/base/baseDefs.hh +++ b/imagine/include/imagine/base/baseDefs.hh @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -196,6 +195,15 @@ static constexpr int APP_ON_RESUME_PRIORITY = 0; // Window/Screen helper classes +struct WindowSurfaceChangeFlags +{ + using BitSetClassInt = uint8_t; + + BitSetClassInt + surfaceResized:1{}, + contentRectResized:1{}; +}; + struct WindowSurfaceChange { enum class Action : uint8_t @@ -203,18 +211,12 @@ struct WindowSurfaceChange CREATED, CHANGED, DESTROYED }; - static constexpr uint8_t SURFACE_RESIZED = bit(0), - CONTENT_RECT_RESIZED = bit(1), - RESIZE_BITS = SURFACE_RESIZED | CONTENT_RECT_RESIZED; - Action action{}; - uint8_t flags{}; + WindowSurfaceChangeFlags flags{}; - constexpr WindowSurfaceChange(Action action, uint8_t flags = 0): + constexpr WindowSurfaceChange(Action action, WindowSurfaceChangeFlags flags = {}): action{action}, flags{flags} {} constexpr bool resized() const { return action == Action::CHANGED; } - constexpr bool surfaceResized() const { return flags & SURFACE_RESIZED; } - constexpr bool contentRectResized() const { return flags & CONTENT_RECT_RESIZED; } }; struct WindowDrawParams diff --git a/imagine/include/imagine/base/sharedLibrary.hh b/imagine/include/imagine/base/sharedLibrary.hh index 59fb1837b..c4d32d76f 100644 --- a/imagine/include/imagine/base/sharedLibrary.hh +++ b/imagine/include/imagine/base/sharedLibrary.hh @@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License along with Imagine. If not, see */ -#include #include #include @@ -23,9 +22,14 @@ namespace IG { using SharedLibraryRef = void*; -static constexpr unsigned RESOLVE_ALL_SYMBOLS_FLAG = bit(0); -SharedLibraryRef openSharedLibrary(const char *name, unsigned flags = 0); +struct OpenSharedLibraryFlags +{ + uint8_t + resolveAllSymbols:1{}; +}; + +SharedLibraryRef openSharedLibrary(const char *name, OpenSharedLibraryFlags flags = {}); void closeSharedLibrary(SharedLibraryRef lib); void *loadSymbol(SharedLibraryRef lib, const char *name); const char *lastOpenSharedLibraryError(); diff --git a/imagine/include/imagine/fs/FSDefs.hh b/imagine/include/imagine/fs/FSDefs.hh index 57ada3f79..24bdbe484 100644 --- a/imagine/include/imagine/fs/FSDefs.hh +++ b/imagine/include/imagine/fs/FSDefs.hh @@ -17,10 +17,7 @@ #include #include -#include #include -#include -#include #include #include #include @@ -133,13 +130,14 @@ protected: file_type type_ = file_type::none; }; -enum class DirOpenFlagsMask: uint8_t +struct DirOpenFlags { + uint8_t // return from constructor without throwing exception if opening fails - Test = bit(0), -}; + test:1{}; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(DirOpenFlagsMask); + constexpr bool operator ==(DirOpenFlags const &) const = default; +}; class directory_entry; class AssetDirectoryIterator; diff --git a/imagine/include/imagine/fs/FSUtils.hh b/imagine/include/imagine/fs/FSUtils.hh index 1099c42e4..e8841c9d2 100644 --- a/imagine/include/imagine/fs/FSUtils.hh +++ b/imagine/include/imagine/fs/FSUtils.hh @@ -38,7 +38,7 @@ inline PathString createDirectoryUriSegments(ApplicationContext ctx, Convertible } size_t directoryItems(CStringView path); -bool forEachInDirectory(CStringView path, DirectoryEntryDelegate del, DirOpenFlagsMask flags = {}); +bool forEachInDirectory(CStringView path, DirectoryEntryDelegate del, DirOpenFlags flags = {}); std::string formatLastWriteTimeLocal(ApplicationContext, CStringView path); } diff --git a/imagine/include/imagine/fs/PosixFS.hh b/imagine/include/imagine/fs/PosixFS.hh index 2ee13c127..dfb9878e3 100644 --- a/imagine/include/imagine/fs/PosixFS.hh +++ b/imagine/include/imagine/fs/PosixFS.hh @@ -54,7 +54,7 @@ protected: class DirectoryStream { public: - DirectoryStream(CStringView path, DirOpenFlagsMask flags = {}); + DirectoryStream(CStringView path, DirOpenFlags flags = {}); bool readNextDir(); bool hasEntry() const; directory_entry &entry() { return entry_; } diff --git a/imagine/include/imagine/gfx/Program.hh b/imagine/include/imagine/gfx/Program.hh index 82a7ab06f..fc48376b0 100644 --- a/imagine/include/imagine/gfx/Program.hh +++ b/imagine/include/imagine/gfx/Program.hh @@ -16,7 +16,6 @@ along with Imagine. If not, see */ #include -#include #include #include diff --git a/imagine/include/imagine/gfx/Vertex.hh b/imagine/include/imagine/gfx/Vertex.hh index f50a24f2d..134047919 100644 --- a/imagine/include/imagine/gfx/Vertex.hh +++ b/imagine/include/imagine/gfx/Vertex.hh @@ -18,6 +18,7 @@ #include #include #include +#include namespace IG::Gfx { @@ -36,43 +37,44 @@ concept VertexLayout = requires T::pos; }; -enum class VertexLayoutAttribMask : uint8_t +struct VertexLayoutFlags { - Position = bit(0), - TextureCoordinate = bit(1), - Color = bit(2), -}; + using BitSetClassInt = uint8_t; + + BitSetClassInt + position:1{}, + textureCoordinate:1{}, + color:1{}; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(VertexLayoutAttribMask); + constexpr bool operator==(VertexLayoutFlags const&) const = default; +}; template -constexpr VertexLayoutAttribMask vertexLayoutEnableMask() +constexpr VertexLayoutFlags vertexLayoutEnableMask() { - using enum VertexLayoutAttribMask; if constexpr(requires {V::pos; V::texCoord; V::color;}) - return Position | TextureCoordinate | Color; + return {.position = true, .textureCoordinate = true, .color = true}; else if constexpr(requires {V::pos; V::color;}) - return Position | Color; + return {.position = true, .color = true}; else if constexpr(requires {V::pos; V::texCoord;}) - return Position | TextureCoordinate; + return {.position = true, .textureCoordinate = true}; else - return Position; + return {.position = true}; } template -constexpr VertexLayoutAttribMask vertexLayoutIntNormalizeMask() +constexpr VertexLayoutFlags vertexLayoutIntNormalizeMask() { - using enum VertexLayoutAttribMask; if constexpr(requires {V::intNormalizeMask;}) return V::intNormalizeMask; else - return TextureCoordinate | Color; + return {.textureCoordinate = true, .color = true}; } template -constexpr bool shouldNormalize(AttribType type, VertexLayoutAttribMask attribMask) +constexpr bool shouldNormalize(AttribType type, VertexLayoutFlags attribMask) { - return type != AttribType::Float && to_underlying(vertexLayoutIntNormalizeMask() & attribMask); + return type != AttribType::Float && asInt(vertexLayoutIntNormalizeMask() & attribMask); } template @@ -80,7 +82,7 @@ constexpr AttribDesc posAttribDesc() { using T = decltype(V::pos.x); auto type = attribType; - return {offsetof(V, pos), sizeof(V::pos) / sizeof(T), type, shouldNormalize(type, VertexLayoutAttribMask::Position)}; + return {offsetof(V, pos), sizeof(V::pos) / sizeof(T), type, shouldNormalize(type, {.position = true})}; } template @@ -90,7 +92,7 @@ constexpr AttribDesc colorAttribDesc() { using T = decltype(V::color.r); auto type = attribType; - return {offsetof(V, color), sizeof(V::color) / sizeof(T), type, shouldNormalize(type, VertexLayoutAttribMask::Color)}; + return {offsetof(V, color), sizeof(V::color) / sizeof(T), type, shouldNormalize(type, {.color = true})}; } else { @@ -105,7 +107,7 @@ constexpr AttribDesc texCoordAttribDesc() { using T = decltype(V::texCoord.x); auto type = attribType; - return {offsetof(V, texCoord), sizeof(V::texCoord) / sizeof(T), type, shouldNormalize(type, VertexLayoutAttribMask::TextureCoordinate)}; + return {offsetof(V, texCoord), sizeof(V::texCoord) / sizeof(T), type, shouldNormalize(type, {.textureCoordinate = true})}; } else { diff --git a/imagine/include/imagine/gfx/opengl/GLRendererCommands.hh b/imagine/include/imagine/gfx/opengl/GLRendererCommands.hh index 8685eb93f..0c45aa7d2 100644 --- a/imagine/include/imagine/gfx/opengl/GLRendererCommands.hh +++ b/imagine/include/imagine/gfx/opengl/GLRendererCommands.hh @@ -55,7 +55,7 @@ public: #endif void setupVertexArrayPointers(const char *v, int stride, AttribDesc textureAttrib, AttribDesc colorAttrib, AttribDesc posAttrib); - void setupShaderVertexArrayPointers(const char *v, int stride, VertexLayoutAttribMask enableMask, + void setupShaderVertexArrayPointers(const char *v, int stride, VertexLayoutFlags enabledLayout, AttribDesc textureAttrib, AttribDesc colorAttrib, AttribDesc posAttrib); protected: @@ -110,7 +110,7 @@ protected: GLuint currSamplerName{}; #ifdef CONFIG_GFX_OPENGL_SHADER_PIPELINE NativeProgram currProgram{}; - VertexLayoutAttribMask currentVertexLayoutEnableMask{}; + VertexLayoutFlags currentEnabledVertexLayout{}; #endif GLStateCache glState{}; Color4F vColor{}; // color when using shader pipeline diff --git a/imagine/include/imagine/input/Device.hh b/imagine/include/imagine/input/Device.hh index c2c1216e7..d08bc5068 100644 --- a/imagine/include/imagine/input/Device.hh +++ b/imagine/include/imagine/input/Device.hh @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/imagine/include/imagine/io/AAssetIO.hh b/imagine/include/imagine/io/AAssetIO.hh index 92744af44..a9f5b1c04 100644 --- a/imagine/include/imagine/io/AAssetIO.hh +++ b/imagine/include/imagine/io/AAssetIO.hh @@ -45,7 +45,7 @@ public: using IOUtilsBase::toFileStream; constexpr AAssetIO() = default; - AAssetIO(ApplicationContext, CStringView name, AccessHint, OpenFlagsMask oFlags = {}); + AAssetIO(ApplicationContext, CStringView name, AccessHint, OpenFlags oFlags = {}); ssize_t read(void *buff, size_t bytes, std::optional offset = {}); ssize_t write(const void *buff, size_t bytes, std::optional offset = {}); std::span map(); diff --git a/imagine/include/imagine/io/FileIO.hh b/imagine/include/imagine/io/FileIO.hh index 57a529fc4..486cd3a10 100644 --- a/imagine/include/imagine/io/FileIO.hh +++ b/imagine/include/imagine/io/FileIO.hh @@ -67,9 +67,9 @@ ssize_t readFromUri(ApplicationContext, CStringView uri, std::span readFromUriWithArchiveScan(ApplicationContext, CStringView uri, std::span dest, bool(*nameMatchFunc)(std::string_view), IOAccessHint accessHint = IOAccessHint::All); -IOBuffer bufferFromPath(CStringView path, OpenFlagsMask oFlags = {}, size_t sizeLimit = defaultBufferReadSizeLimit); -IOBuffer bufferFromUri(ApplicationContext, CStringView uri, OpenFlagsMask oFlags = {}, size_t sizeLimit = defaultBufferReadSizeLimit); -IOBuffer rwBufferFromUri(ApplicationContext, CStringView uri, OpenFlagsMask extraOFlags, size_t size, uint8_t initValue = 0); +IOBuffer bufferFromPath(CStringView path, OpenFlags oFlags = {}, size_t sizeLimit = defaultBufferReadSizeLimit); +IOBuffer bufferFromUri(ApplicationContext, CStringView uri, OpenFlags oFlags = {}, size_t sizeLimit = defaultBufferReadSizeLimit); +IOBuffer rwBufferFromUri(ApplicationContext, CStringView uri, OpenFlags extraOFlags, size_t size, uint8_t initValue = 0); FILE *fopenUri(ApplicationContext, CStringView path, CStringView mode); } diff --git a/imagine/include/imagine/io/IOUtils.hh b/imagine/include/imagine/io/IOUtils.hh index 44ea93fd5..562341f04 100644 --- a/imagine/include/imagine/io/IOUtils.hh +++ b/imagine/include/imagine/io/IOUtils.hh @@ -32,14 +32,16 @@ class IOBuffer : public ByteBuffer { public: using ByteBuffer::ByteBuffer; - using Flags = uint8_t; - static constexpr Flags MAPPED_FILE_BIT = bit(0); + struct Flags + { + uint8_t mappedFile:1{}; + }; - constexpr IOBuffer(std::span span, Flags flags, DeleterFunc deleter = [](const uint8_t*, size_t){}): + constexpr IOBuffer(std::span span, Flags flags, DeleterFunc deleter = {}): ByteBuffer{span, deleter}, flags{flags} {} - constexpr bool isMappedFile() const { return flags & MAPPED_FILE_BIT; } + constexpr bool isMappedFile() const { return flags.mappedFile; } protected: Flags flags{}; diff --git a/imagine/include/imagine/io/PosixFileIO.hh b/imagine/include/imagine/io/PosixFileIO.hh index b57b107af..fe017fb9a 100644 --- a/imagine/include/imagine/io/PosixFileIO.hh +++ b/imagine/include/imagine/io/PosixFileIO.hh @@ -40,10 +40,10 @@ public: using IOUtilsBase::toFileStream; constexpr PosixFileIO() = default; - PosixFileIO(UniqueFileDescriptor fd, AccessHint access, OpenFlagsMask); - PosixFileIO(UniqueFileDescriptor fd, OpenFlagsMask); - PosixFileIO(CStringView path, AccessHint access, OpenFlagsMask oFlags = {}); - PosixFileIO(CStringView path, OpenFlagsMask oFlags = {}); + PosixFileIO(UniqueFileDescriptor fd, AccessHint access, OpenFlags); + PosixFileIO(UniqueFileDescriptor fd, OpenFlags); + PosixFileIO(CStringView path, AccessHint access, OpenFlags oFlags = {}); + PosixFileIO(CStringView path, OpenFlags oFlags = {}); ssize_t read(void *buff, size_t bytes, std::optional offset = {}); ssize_t write(const void *buff, size_t bytes, std::optional offset = {}); std::span map(); @@ -57,12 +57,12 @@ public: IOBuffer releaseBuffer(); UniqueFileDescriptor releaseFd(); operator IO(); - bool tryMap(AccessHint access, OpenFlagsMask); + bool tryMap(AccessHint access, OpenFlags); private: std::variant ioImpl{}; - void initMmap(AccessHint access, OpenFlagsMask openFlags); + void initMmap(AccessHint access, OpenFlags openFlags); }; } diff --git a/imagine/include/imagine/io/PosixIO.hh b/imagine/include/imagine/io/PosixIO.hh index 3c9c6ef1e..c53b98f6c 100644 --- a/imagine/include/imagine/io/PosixIO.hh +++ b/imagine/include/imagine/io/PosixIO.hh @@ -22,14 +22,13 @@ namespace IG { -enum class IOMapFlagsMask: uint8_t +struct IOMapFlags { - Write = bit(0), - PopulatePages = bit(1), + uint8_t + write:1{}, + populatePages:1{}; }; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(IOMapFlagsMask); - class PosixIO : public IOUtils { public: @@ -45,7 +44,7 @@ public: constexpr PosixIO() = default; PosixIO(UniqueFileDescriptor fd):fd_{std::move(fd)} {} - PosixIO(CStringView path, OpenFlagsMask oFlags = {}); + PosixIO(CStringView path, OpenFlags oFlags = {}); UniqueFileDescriptor releaseFd(); int fd() const; ssize_t read(void *buff, size_t bytes, std::optional offset = {}); @@ -58,7 +57,7 @@ public: void advise(off_t offset, size_t bytes, Advice advice); explicit operator bool() const; IOBuffer releaseBuffer(); - IOBuffer mapRange(off_t start, size_t size, IOMapFlagsMask); + IOBuffer mapRange(off_t start, size_t size, IOMapFlags); static IOBuffer byteBufferFromMmap(void *data, size_t size); protected: diff --git a/imagine/include/imagine/io/ioDefs.hh b/imagine/include/imagine/io/ioDefs.hh index 66014bf73..437d89563 100644 --- a/imagine/include/imagine/io/ioDefs.hh +++ b/imagine/include/imagine/io/ioDefs.hh @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with Imagine. If not, see */ -#include -#include + +#include #include // for SEEK_* #include @@ -46,26 +46,33 @@ enum class IOSeekMode End = SEEK_END, }; -enum class OpenFlagsMask: uint8_t +struct OpenFlags { + using BitSetClassInt = uint8_t; + + BitSetClassInt // allow reading file - Read = bit(0), + read:1{}, // allow modifying file - Write = bit(1), + write:1{}, // create a new file if it doesn't already exist - Create = bit(2), + create:1{}, // if using WRITE, truncate any existing file to 0 bytes - Truncate = bit(3), + truncate:1{}, // return from constructor without throwing exception if opening fails, // used to avoid redundant FS::exists() tests when searching for a file to open - Test = bit(4), + test:1{}; - // common flag combinations - New = Write | Create | Truncate, - CreateRW = Read | Write | Create -}; + constexpr bool operator==(OpenFlags const&) const = default; -IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(OpenFlagsMask); + // common flag combinations: + // create a file for writing, clobbering an existing one + static constexpr OpenFlags newFile() { return {.write = 1, .create = 1, .truncate = 1}; } + static constexpr OpenFlags testNewFile() { return {.write = 1, .create = 1, .truncate = 1, .test = 1}; } + // create a file for reading/writing, keeping an existing one + static constexpr OpenFlags createFile() { return {.read = 1, .write = 1, .create = 1}; } + static constexpr OpenFlags testCreateFile() { return {.read = 1, .write = 1, .create = 1, .test = 1}; } +}; template concept Readable = diff --git a/imagine/include/imagine/pixmap/PixelDesc.hh b/imagine/include/imagine/pixmap/PixelDesc.hh index a4a5352d7..7c586d88d 100644 --- a/imagine/include/imagine/pixmap/PixelDesc.hh +++ b/imagine/include/imagine/pixmap/PixelDesc.hh @@ -16,7 +16,7 @@ along with Imagine. If not, see */ #include -#include +#include #include #include #include diff --git a/imagine/include/imagine/util/bit.hh b/imagine/include/imagine/util/bit.hh index 459c0c156..cb913d21f 100755 --- a/imagine/include/imagine/util/bit.hh +++ b/imagine/include/imagine/util/bit.hh @@ -17,10 +17,62 @@ #include #include +#include namespace IG { +template +concept BitSet = + requires(T &&v) + { + ~v; + v | T{}; + v & T{}; + v ^ T{}; + }; + +template +constexpr inline auto bitSize = std::numeric_limits::digits; + +template +constexpr T bit(int bitIdx) +{ + return T{1} << bitIdx; +} + +template +constexpr T bits(int numBits) +{ + return numBits ? std::numeric_limits::max() >> (bitSize - numBits) : 0; +} + +constexpr auto clearBits(BitSet auto x, BitSet auto mask) +{ + return x & ~mask; // AND with the NOT of mask to unset +} + +constexpr auto setOrClearBits(BitSet auto x, BitSet auto mask, bool condition) +{ + return condition ? (x | mask) : clearBits(x, mask); +} + +constexpr auto updateBits(BitSet auto x, BitSet auto mask, BitSet auto updateMask) +{ + return clearBits(x, updateMask) | mask; +} + +constexpr auto swapBits(std::integral auto x, std::integral auto range1, std::integral auto range2, std::integral auto rangeSize) +{ + auto t = ((x >> range1) ^ (x >> range2)) & ((1 << rangeSize) - 1); // XOR temporary + return x ^ ((t << range1) | (t << range2)); +} + +constexpr bool isBitMaskSet(BitSet auto x, BitSet auto mask) +{ + return (x & mask) == mask; //AND mask, if the result equals mask, all bits match +} + constexpr int ctz(unsigned int x) { return __builtin_ctz(x); @@ -56,4 +108,29 @@ constexpr int fls(std::unsigned_integral auto x) return x ? sizeof(x) * 8 - clz(x) : 0; } +// Utility functions for classes representing bit sets, define BitSetClassInt as the underlying int type +template +concept BitSetClass = requires {typename T::BitSetClassInt;}; + +template +constexpr auto asInt(const T &val) {return std::bit_cast(val); } + +template +constexpr T operator|(T lhs, T rhs) +{ + return std::bit_cast(typename T::BitSetClassInt(asInt(lhs) | asInt(rhs))); +}; + +template +constexpr T& operator|=(T &lhs, T rhs) { lhs = lhs | rhs; return lhs; } + +template +constexpr T operator&(T lhs, T rhs) +{ + return std::bit_cast(typename T::BitSetClassInt(asInt(lhs) & asInt(rhs))); +}; + +template +constexpr T& operator&=(T &lhs, T rhs) { lhs = lhs & rhs; return lhs; } + } diff --git a/imagine/include/imagine/util/bitset.hh b/imagine/include/imagine/util/bitset.hh deleted file mode 100755 index 519a36bdf..000000000 --- a/imagine/include/imagine/util/bitset.hh +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -/* This file is part of Imagine. - - Imagine is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Imagine is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Imagine. If not, see */ - -#include -#include - -namespace IG -{ - -template -concept BitSet = - requires(T &&v) - { - ~v; - v | T{}; - v & T{}; - v ^ T{}; - }; - -template -constexpr inline auto bitSize = std::numeric_limits::digits; - -template -constexpr T bit(int bitIdx) -{ - return T{1} << bitIdx; -} - -template -constexpr T bits(int numBits) -{ - return numBits ? std::numeric_limits::max() >> (bitSize - numBits) : 0; -} - -constexpr auto clearBits(BitSet auto x, BitSet auto mask) -{ - return x & ~mask; // AND with the NOT of mask to unset -} - -constexpr auto setOrClearBits(BitSet auto x, BitSet auto mask, bool condition) -{ - return condition ? (x | mask) : clearBits(x, mask); -} - -constexpr auto updateBits(BitSet auto x, BitSet auto mask, BitSet auto updateMask) -{ - return clearBits(x, updateMask) | mask; -} - -constexpr auto swapBits(std::integral auto x, std::integral auto range1, std::integral auto range2, std::integral auto rangeSize) -{ - auto t = ((x >> range1) ^ (x >> range2)) & ((1 << rangeSize) - 1); // XOR temporary - return x ^ ((t << range1) | (t << range2)); -} - -constexpr bool isBitMaskSet(BitSet auto x, BitSet auto mask) -{ - return (x & mask) == mask; //AND mask, if the result equals mask, all bits match -} - -} diff --git a/imagine/include/imagine/util/enum.hh b/imagine/include/imagine/util/enum.hh index 69ddfa58c..a7eb9bb55 100644 --- a/imagine/include/imagine/util/enum.hh +++ b/imagine/include/imagine/util/enum.hh @@ -24,12 +24,3 @@ template constexpr auto lastEnum = wise_enum::range.back().value; } - -#define IG_DEFINE_ENUM_BIT_FLAG_FUNCTIONS(T) \ -constexpr T operator~(T a) { return static_cast(~std::to_underlying(a)); } \ -constexpr T operator|(T a, T b) { return static_cast(std::to_underlying(a) | std::to_underlying(b)); } \ -constexpr T operator&(T a, T b) { return static_cast(std::to_underlying(a) & std::to_underlying(b)); } \ -constexpr T operator^(T a, T b) { return static_cast(std::to_underlying(a) ^ std::to_underlying(b)); } \ -constexpr T& operator|= (T& a, T b) { a = a | b; return a; } \ -constexpr T& operator&= (T& a, T b) { a = a & b; return a; } \ -constexpr T& operator^= (T& a, T b) { a = a ^ b; return a; } diff --git a/imagine/include/imagine/util/memory/Buffer.hh b/imagine/include/imagine/util/memory/Buffer.hh index c01948d28..e81e8096f 100644 --- a/imagine/include/imagine/util/memory/Buffer.hh +++ b/imagine/include/imagine/util/memory/Buffer.hh @@ -36,7 +36,7 @@ struct BufferDeleter constexpr void operator()(T *ptr) const { - del(ptr, size); + del.callSafe(ptr, size); } constexpr bool operator ==(BufferDeleter const&) const = default; @@ -55,7 +55,7 @@ public: constexpr Buffer() = default; - constexpr Buffer(std::span span, DeleterFunc deleter = [](const T*, size_t){}): + constexpr Buffer(std::span span, DeleterFunc deleter = {}): data_{span.data(), {deleter, span.size()}} {} constexpr Buffer(size_t size): diff --git a/imagine/include/imagine/util/rectangle2.h b/imagine/include/imagine/util/rectangle2.h index 43fbddf77..878965a59 100644 --- a/imagine/include/imagine/util/rectangle2.h +++ b/imagine/include/imagine/util/rectangle2.h @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace IG diff --git a/imagine/src/audio/android/aaudio.cc b/imagine/src/audio/android/aaudio.cc index 538c89674..d2146a9a8 100755 --- a/imagine/src/audio/android/aaudio.cc +++ b/imagine/src/audio/android/aaudio.cc @@ -55,7 +55,7 @@ static void loadAAudioLib(const Manager &manager) if(loadedAAudioLib()) return; log.info("loading libaaudio.so functions"); - auto lib = openSharedLibrary("libaaudio.so", RESOLVE_ALL_SYMBOLS_FLAG); + auto lib = openSharedLibrary("libaaudio.so", {.resolveAllSymbols = true}); if(!lib) { log.error("error opening libaaudio.so"); diff --git a/imagine/src/base/android/AndroidWindow.cc b/imagine/src/base/android/AndroidWindow.cc index a83d419cd..3154a23dc 100644 --- a/imagine/src/base/android/AndroidWindow.cc +++ b/imagine/src/base/android/AndroidWindow.cc @@ -333,14 +333,14 @@ void AndroidWindow::setContentRect(WindowRect rect, WSize winSize) if(win.updateSize(winSize)) { contentRect = rect; - surfaceChangeFlags |= WindowSurfaceChange::CONTENT_RECT_RESIZED; + surfaceChangeFlags.contentRectResized = true; } else { contentRect.start(*static_cast(this), contentRect.value(), rect, Milliseconds{165}, [](auto &win, auto newRect) { - win.surfaceChangeFlags |= WindowSurfaceChange::CONTENT_RECT_RESIZED; + win.surfaceChangeFlags.contentRectResized = true; win.setNeedsDraw(true); }); } diff --git a/imagine/src/base/android/Application.cc b/imagine/src/base/android/Application.cc index 852d890d5..a360c39c1 100644 --- a/imagine/src/base/android/Application.cc +++ b/imagine/src/base/android/Application.cc @@ -135,14 +135,14 @@ FS::PathString AndroidApplication::externalMediaPath(JNIEnv *env, jobject baseAc return FS::PathString{JNI::StringChars{env, extMediaDir(env, baseActivity)}}; } -UniqueFileDescriptor AndroidApplication::openFileUriFd(JNIEnv *env, jobject baseActivity, CStringView uri, OpenFlagsMask openFlags) const +UniqueFileDescriptor AndroidApplication::openFileUriFd(JNIEnv *env, jobject baseActivity, CStringView uri, OpenFlags openFlags) const { - int fd = openUriFd(env, baseActivity, env->NewStringUTF(uri), (jint)openFlags); + int fd = openUriFd(env, baseActivity, env->NewStringUTF(uri), jint(std::bit_cast(openFlags))); if(fd == -1) { if constexpr(Config::DEBUG_BUILD) logErr("error opening URI:%s", uri.data()); - if(to_underlying(openFlags & OpenFlagsMask::Test)) + if(openFlags.test) return -1; else throw std::system_error{ENOENT, std::system_category(), uri}; @@ -194,12 +194,12 @@ bool AndroidApplication::createDirectoryUri(JNIEnv *env, jobject baseActivity, C } bool AndroidApplication::forEachInDirectoryUri(JNIEnv *env, jobject baseActivity, - CStringView uri, DirectoryEntryDelegate del, FS::DirOpenFlagsMask flags) const + CStringView uri, DirectoryEntryDelegate del, FS::DirOpenFlags flags) const { logMsg("listing directory URI:%s", uri.data()); if(!listUriFiles(env, baseActivity, (jlong)&del, env->NewStringUTF(uri))) { - if(to_underlying(flags & FS::DirOpenFlagsMask::Test)) + if(flags.test) return false; else throw std::system_error{ENOENT, std::system_category(), uri}; @@ -522,26 +522,27 @@ void AndroidApplication::setStatusBarHidden(JNIEnv *env, jobject baseActivity, b } } -void AndroidApplication::setSysUIStyle(JNIEnv *env, jobject baseActivity, int32_t androidSDK, uint32_t flags) +void AndroidApplication::setSysUIStyle(JNIEnv *env, jobject baseActivity, int32_t androidSDK, SystemUIStyleFlags flags) { // Flags mapped directly to SYSTEM_UI_FLAG_* - // SYS_UI_STYLE_DIM_NAV -> SYSTEM_UI_FLAG_LOW_PROFILE (0) - // SYS_UI_STYLE_HIDE_NAV -> SYSTEM_UI_FLAG_HIDE_NAVIGATION (1) - // SYS_UI_STYLE_HIDE_STATUS -> SYSTEM_UI_FLAG_FULLSCREEN (2) - // SYS_UI_STYLE_NO_FLAGS -> SYSTEM_UI_FLAG_VISIBLE (no bits set) + // dimNavigation -> SYSTEM_UI_FLAG_LOW_PROFILE (0) + // hideNavigation -> SYSTEM_UI_FLAG_HIDE_NAVIGATION (1) + // hideStatus -> SYSTEM_UI_FLAG_FULLSCREEN (2) + // (unset) -> SYSTEM_UI_FLAG_VISIBLE (no bits set) // always handle status bar hiding via full-screen window flag // even on SDK level >= 11 so our custom view has the correct insets - setStatusBarHidden(env, baseActivity, flags & SYS_UI_STYLE_HIDE_STATUS); + setStatusBarHidden(env, baseActivity, flags.hideStatus); if(androidSDK >= 11) { constexpr uint32_t SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x1000; + uint32_t nativeFlags = std::bit_cast(flags); // Add SYSTEM_UI_FLAG_IMMERSIVE_STICKY for use with Android 4.4+ if flags contain OS_NAV_STYLE_HIDDEN - if(flags & SYS_UI_STYLE_HIDE_NAV) - flags |= SYSTEM_UI_FLAG_IMMERSIVE_STICKY; - logMsg("setting UI visibility: 0x%X", flags); - uiVisibilityFlags = flags; - jSetUIVisibility(env, baseActivity, flags); + if(flags.hideNavigation) + nativeFlags |= SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + logMsg("setting UI visibility: 0x%X", nativeFlags); + uiVisibilityFlags = nativeFlags; + jSetUIVisibility(env, baseActivity, nativeFlags); } } diff --git a/imagine/src/base/android/ApplicationContext.cc b/imagine/src/base/android/ApplicationContext.cc index 5129fd240..a4a5a16a8 100644 --- a/imagine/src/base/android/ApplicationContext.cc +++ b/imagine/src/base/android/ApplicationContext.cc @@ -141,14 +141,14 @@ FS::PathString ApplicationContext::libPath(const char *) const return {}; } -FileIO ApplicationContext::openFileUri(CStringView uri, IOAccessHint access, OpenFlagsMask openFlags) const +FileIO ApplicationContext::openFileUri(CStringView uri, IOAccessHint access, OpenFlags openFlags) const { if(androidSDK() < 19 || !isUri(uri)) return {uri, access, openFlags}; return {application().openFileUriFd(thisThreadJniEnv(), baseActivityObject(), uri, openFlags), access, openFlags}; } -UniqueFileDescriptor ApplicationContext::openFileUriFd(CStringView uri, OpenFlagsMask openFlags) const +UniqueFileDescriptor ApplicationContext::openFileUriFd(CStringView uri, OpenFlags openFlags) const { if(androidSDK() < 19 || !isUri(uri)) return PosixIO{uri, openFlags}.releaseFd(); @@ -212,7 +212,7 @@ bool ApplicationContext::removeDirectoryUri(CStringView uri) const } bool ApplicationContext::forEachInDirectoryUri(CStringView uri, DirectoryEntryDelegate del, - FS::DirOpenFlagsMask flags) const + FS::DirOpenFlags flags) const { if(androidSDK() < 21 || !isUri(uri)) { @@ -310,7 +310,7 @@ void ApplicationContext::endIdleByUserActivity() application().endIdleByUserActivity(*this); } -void ApplicationContext::setSysUIStyle(uint32_t flags) +void ApplicationContext::setSysUIStyle(SystemUIStyleFlags flags) { return application().setSysUIStyle(mainThreadJniEnv(), baseActivityObject(), androidSDK(), flags); } diff --git a/imagine/src/base/common/ApplicationContext.cc b/imagine/src/base/common/ApplicationContext.cc index 2dfb41c7b..e6a10d4e1 100644 --- a/imagine/src/base/common/ApplicationContext.cc +++ b/imagine/src/base/common/ApplicationContext.cc @@ -226,7 +226,7 @@ FS::RootPathInfo ApplicationContext::rootPathInfo(std::string_view path) const return nearestPtr->root.info; } -AssetIO ApplicationContext::openAsset(CStringView name, IOAccessHint hint, OpenFlagsMask openFlags, const char *appName) const +AssetIO ApplicationContext::openAsset(CStringView name, IOAccessHint hint, OpenFlags openFlags, const char *appName) const { #ifdef __ANDROID__ return {*this, name, hint, openFlags}; @@ -254,17 +254,17 @@ FS::AssetDirectoryIterator ApplicationContext::openAssetDirectory(CStringView pa [[gnu::weak]] bool ApplicationContext::showSystemCreateDocumentPicker(SystemDocumentPickerDelegate) { return false; } -[[gnu::weak]] FileIO ApplicationContext::openFileUri(CStringView uri, IOAccessHint access, OpenFlagsMask openFlags) const +[[gnu::weak]] FileIO ApplicationContext::openFileUri(CStringView uri, IOAccessHint access, OpenFlags openFlags) const { return {uri, access, openFlags}; } -FileIO ApplicationContext::openFileUri(CStringView uri, OpenFlagsMask openFlags) const +FileIO ApplicationContext::openFileUri(CStringView uri, OpenFlags openFlags) const { return openFileUri(uri, IOAccessHint::Normal, openFlags); } -[[gnu::weak]] UniqueFileDescriptor ApplicationContext::openFileUriFd(CStringView uri, OpenFlagsMask openFlags) const +[[gnu::weak]] UniqueFileDescriptor ApplicationContext::openFileUriFd(CStringView uri, OpenFlags openFlags) const { return PosixIO{uri, openFlags}.releaseFd(); } @@ -310,7 +310,7 @@ FileIO ApplicationContext::openFileUri(CStringView uri, OpenFlagsMask openFlags) } [[gnu::weak]] bool ApplicationContext::forEachInDirectoryUri(CStringView uri, - DirectoryEntryDelegate del, FS::DirOpenFlagsMask flags) const + DirectoryEntryDelegate del, FS::DirOpenFlags flags) const { return forEachInDirectory(uri, del, flags); } @@ -356,7 +356,7 @@ void ApplicationContext::setSwappedConfirmKeys(std::optional opt) application().setSwappedConfirmKeys(opt); } -[[gnu::weak]] void ApplicationContext::setSysUIStyle(uint32_t flags) {} +[[gnu::weak]] void ApplicationContext::setSysUIStyle(SystemUIStyleFlags) {} [[gnu::weak]] bool ApplicationContext::hasTranslucentSysUI() const { return false; } @@ -532,14 +532,14 @@ namespace IG::FileUtils ssize_t writeToUri(ApplicationContext ctx, CStringView uri, std::span src) { - auto f = ctx.openFileUri(uri, OpenFlagsMask::New | OpenFlagsMask::Test); + auto f = ctx.openFileUri(uri, OpenFlags::testNewFile()); return f.write(src).bytes; } ssize_t readFromUri(ApplicationContext ctx, CStringView uri, std::span dest, IOAccessHint accessHint) { - auto f = ctx.openFileUri(uri, accessHint, OpenFlagsMask::Test); + auto f = ctx.openFileUri(uri, accessHint, {.test = true}); return f.read(dest).bytes; } @@ -570,7 +570,7 @@ std::pair readFromUriWithArchiveScan(ApplicationContext } } -IOBuffer bufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlagsMask openFlags, size_t sizeLimit) +IOBuffer bufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlags openFlags, size_t sizeLimit) { if(!sizeLimit) [[unlikely]] return {}; @@ -579,7 +579,7 @@ IOBuffer bufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlagsMask op return {}; else if(file.size() > sizeLimit) { - if(to_underlying(openFlags & OpenFlagsMask::Test)) + if(openFlags.test) return {}; else throw std::runtime_error(std::format("{} exceeds {} byte limit", uri, sizeLimit)); @@ -587,11 +587,11 @@ IOBuffer bufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlagsMask op return file.buffer(IOBufferMode::Release); } -IOBuffer rwBufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlagsMask extraOFlags, size_t size, uint8_t initValue) +IOBuffer rwBufferFromUri(ApplicationContext ctx, CStringView uri, OpenFlags extraOFlags, size_t size, uint8_t initValue) { if(!size) [[unlikely]] return {}; - auto file = ctx.openFileUri(uri, IOAccessHint::Random, OpenFlagsMask::CreateRW | extraOFlags); + auto file = ctx.openFileUri(uri, IOAccessHint::Random, OpenFlags::createFile() | extraOFlags); if(!file) [[unlikely]] return {}; auto fileSize = file.size(); @@ -610,13 +610,13 @@ FILE *fopenUri(ApplicationContext ctx, CStringView path, CStringView mode) if(isUri(path)) { assert(!mode.contains('a')); //append mode not supported - OpenFlagsMask openFlags{OpenFlagsMask::Test}; + OpenFlags openFlags{.test = true}; if(mode.contains('r')) - openFlags |= OpenFlagsMask::Read; + openFlags.read = true; if(mode.contains('w')) - openFlags |= OpenFlagsMask::New; + openFlags |= OpenFlags::newFile(); if(mode.contains('+')) - openFlags |= OpenFlagsMask::Write; + openFlags.write = true; return ctx.openFileUri(path, openFlags).toFileStream(mode); } else diff --git a/imagine/src/base/common/Base.cc b/imagine/src/base/common/Base.cc index 831dd0090..a6ef1f8e0 100755 --- a/imagine/src/base/common/Base.cc +++ b/imagine/src/base/common/Base.cc @@ -69,9 +69,9 @@ bool FDEventSource::attach(PollEventDelegate callback, uint32_t events) return attach({}, callback, events); } -SharedLibraryRef openSharedLibrary(const char *name, unsigned flags) +SharedLibraryRef openSharedLibrary(const char *name, OpenSharedLibraryFlags flags) { - int mode = flags & RESOLVE_ALL_SYMBOLS_FLAG ? RTLD_NOW : RTLD_LAZY; + int mode = flags.resolveAllSymbols ? RTLD_NOW : RTLD_LAZY; auto lib = dlopen(name, mode); if(Config::DEBUG_BUILD && !lib) { diff --git a/imagine/src/base/common/Window.cc b/imagine/src/base/common/Window.cc index cca37f99c..afdd9bc81 100644 --- a/imagine/src/base/common/Window.cc +++ b/imagine/src/base/common/Window.cc @@ -253,7 +253,7 @@ void Window::dispatchDismissRequest() void Window::dispatchSurfaceCreated() { onEvent.callCopy(*this, WindowSurfaceChangeEvent{SurfaceChange::Action::CREATED}); - surfaceChangeFlags |= SurfaceChange::SURFACE_RESIZED; + surfaceChangeFlags.surfaceResized = true; } void Window::dispatchSurfaceChanged() @@ -263,12 +263,12 @@ void Window::dispatchSurfaceChanged() void Window::dispatchSurfaceDestroyed() { - surfaceChangeFlags = 0; + surfaceChangeFlags = {}; unpostDraw(); onEvent.callCopy(*this, WindowSurfaceChangeEvent{SurfaceChange::Action::DESTROYED}); } -void Window::signalSurfaceChanged(uint8_t flags) +void Window::signalSurfaceChanged(WindowSurfaceChangeFlags flags) { surfaceChangeFlags |= flags; postDraw(); @@ -301,7 +301,7 @@ void Window::draw(bool needsSync) { DrawParams params; params.needsSync = needsSync; - if(surfaceChangeFlags) [[unlikely]] + if(asInt(surfaceChangeFlags)) [[unlikely]] { dispatchSurfaceChanged(); params.wasResized = true; @@ -332,7 +332,7 @@ bool Window::updateSize(IG::Point2D surfaceSize) { updatePhysicalSize(pixelSizeAsMM({realWidth(), realHeight()})); } - surfaceChangeFlags |= SurfaceChange::SURFACE_RESIZED; + surfaceChangeFlags.surfaceResized = true; return true; } diff --git a/imagine/src/base/iphone/IOSWindow.mm b/imagine/src/base/iphone/IOSWindow.mm index aec679124..49ad927f5 100644 --- a/imagine/src/base/iphone/IOSWindow.mm +++ b/imagine/src/base/iphone/IOSWindow.mm @@ -153,7 +153,7 @@ static auto defaultValidOrientationMask() { log.info("using full window size for content rect {},{}", contentRect.x2, contentRect.y2); } - surfaceChangeFlags |= WindowSurfaceChange::CONTENT_RECT_RESIZED; + surfaceChangeFlags.contentRectResized = true; } IG::Point2D Window::pixelSizeAsMM(IG::Point2D size) diff --git a/imagine/src/base/iphone/iphone.mm b/imagine/src/base/iphone/iphone.mm index 51ac58b83..2c7e1abab 100755 --- a/imagine/src/base/iphone/iphone.mm +++ b/imagine/src/base/iphone/iphone.mm @@ -342,9 +342,9 @@ static void setStatusBarHidden(ApplicationContext ctx, bool hidden) } } -void ApplicationContext::setSysUIStyle(uint32_t flags) +void ApplicationContext::setSysUIStyle(SystemUIStyleFlags flags) { - setStatusBarHidden(uiApp(), flags & SYS_UI_STYLE_HIDE_STATUS); + setStatusBarHidden(uiApp(), flags.hideStatus); } bool ApplicationContext::hasTranslucentSysUI() const diff --git a/imagine/src/base/x11/xdnd.cc b/imagine/src/base/x11/xdnd.cc index c438c606e..28e568daa 100644 --- a/imagine/src/base/x11/xdnd.cc +++ b/imagine/src/base/x11/xdnd.cc @@ -14,7 +14,7 @@ along with Imagine. If not, see */ #include -#include +#include #include #include #include "xdnd.hh" diff --git a/imagine/src/bluetooth/IControlPad.cc b/imagine/src/bluetooth/IControlPad.cc index 27e099f03..0ea948982 100644 --- a/imagine/src/bluetooth/IControlPad.cc +++ b/imagine/src/bluetooth/IControlPad.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "../input/PackedInputAccess.hh" #include diff --git a/imagine/src/bluetooth/PS3Controller.cc b/imagine/src/bluetooth/PS3Controller.cc index e23485277..28f23ae0b 100644 --- a/imagine/src/bluetooth/PS3Controller.cc +++ b/imagine/src/bluetooth/PS3Controller.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "../input/PackedInputAccess.hh" diff --git a/imagine/src/bluetooth/Wiimote.cc b/imagine/src/bluetooth/Wiimote.cc index f43f42ce2..e730a435c 100644 --- a/imagine/src/bluetooth/Wiimote.cc +++ b/imagine/src/bluetooth/Wiimote.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "../input/PackedInputAccess.hh" diff --git a/imagine/src/data-type/image/LibPNG.cc b/imagine/src/data-type/image/LibPNG.cc index e3abc965f..0a2d4f729 100755 --- a/imagine/src/data-type/image/LibPNG.cc +++ b/imagine/src/data-type/image/LibPNG.cc @@ -398,7 +398,7 @@ PixmapImage PixmapReader::load(const char *name, PixmapReaderParams params) cons logErr("suffix doesn't match PNG image"); return {}; } - return load(FileIO{name, IOAccessHint::All, OpenFlagsMask::Test}, params); + return load(FileIO{name, IOAccessHint::All, {.test = true}}, params); } PixmapImage PixmapReader::loadAsset(const char *name, PixmapReaderParams params, const char *appName) const @@ -408,7 +408,7 @@ PixmapImage PixmapReader::loadAsset(const char *name, PixmapReaderParams params, bool PixmapWriter::writeToFile(PixmapView pix, const char *path) const { - FileIO fp{path, OpenFlagsMask::New | OpenFlagsMask::Test}; + FileIO fp{path, OpenFlags::testNewFile()}; if(!fp) { return false; diff --git a/imagine/src/fs/FS.cc b/imagine/src/fs/FS.cc index 328e43914..8447064a1 100755 --- a/imagine/src/fs/FS.cc +++ b/imagine/src/fs/FS.cc @@ -105,7 +105,7 @@ size_t directoryItems(CStringView path) return items; } -bool forEachInDirectory(CStringView path, DirectoryEntryDelegate del, DirOpenFlagsMask flags) +bool forEachInDirectory(CStringView path, DirectoryEntryDelegate del, DirOpenFlags flags) { bool entriesRead{}; for(FS::DirectoryStream dirStream{path, flags}; dirStream.hasEntry(); dirStream.readNextDir()) diff --git a/imagine/src/fs/PosixFS.cc b/imagine/src/fs/PosixFS.cc index 6f871f239..4ea04471b 100644 --- a/imagine/src/fs/PosixFS.cc +++ b/imagine/src/fs/PosixFS.cc @@ -49,14 +49,14 @@ static bool isDotName(std::string_view name) return name == "." || name == ".."; } -DirectoryStream::DirectoryStream(CStringView path, DirOpenFlagsMask flags): +DirectoryStream::DirectoryStream(CStringView path, DirOpenFlags flags): dir{opendir(path)} { if(!dir) { if(Config::DEBUG_BUILD) logErr("opendir(%s) error:%s", path.data(), strerror(errno)); - if(to_underlying(flags & FS::DirOpenFlagsMask::Test)) + if(flags.test) return; else throw std::system_error{errno, std::system_category(), path}; diff --git a/imagine/src/gfx/common/GlyphTextureSet.cc b/imagine/src/gfx/common/GlyphTextureSet.cc index 065920652..97fcd499a 100755 --- a/imagine/src/gfx/common/GlyphTextureSet.cc +++ b/imagine/src/gfx/common/GlyphTextureSet.cc @@ -15,7 +15,7 @@ #define LOGTAG "GlyphTexture" -#include +#include #include #include #include diff --git a/imagine/src/gfx/opengl/Renderer.cc b/imagine/src/gfx/opengl/Renderer.cc index a421a463f..cd43b7312 100755 --- a/imagine/src/gfx/opengl/Renderer.cc +++ b/imagine/src/gfx/opengl/Renderer.cc @@ -478,7 +478,7 @@ void Renderer::animateWindowRotation(Window &win, float srcAngle, float destAngl winData(win).projAngleM = {srcAngle, destAngle, {}, SteadyClock::now(), Milliseconds{165}}; win.addOnFrame([this, &win](FrameParams params) { - win.signalSurfaceChanged(WindowSurfaceChange::CONTENT_RECT_RESIZED); + win.signalSurfaceChanged({.contentRectResized = true}); bool didUpdate = winData(win).projAngleM.update(params.timestamp); return didUpdate; }); diff --git a/imagine/src/gfx/opengl/RendererCommands.cc b/imagine/src/gfx/opengl/RendererCommands.cc index c37db7bf3..db0463e0e 100644 --- a/imagine/src/gfx/opengl/RendererCommands.cc +++ b/imagine/src/gfx/opengl/RendererCommands.cc @@ -506,10 +506,10 @@ void GLRendererCommands::setupVertexArrayPointers(const char *v, int stride, #endif #ifdef CONFIG_GFX_OPENGL_SHADER_PIPELINE -void GLRendererCommands::setupShaderVertexArrayPointers(const char *v, int stride, VertexLayoutAttribMask enableMask, +void GLRendererCommands::setupShaderVertexArrayPointers(const char *v, int stride, VertexLayoutFlags enabledLayout, AttribDesc textureAttrib, AttribDesc colorAttrib, AttribDesc posAttrib) { - if(currentVertexLayoutEnableMask != enableMask) + if(currentEnabledVertexLayout != enabledLayout) { if(textureAttrib.size) glEnableVertexAttribArray(VATTR_TEX_UV); @@ -519,7 +519,7 @@ void GLRendererCommands::setupShaderVertexArrayPointers(const char *v, int strid glEnableVertexAttribArray(VATTR_COLOR); else glDisableVertexAttribArray(VATTR_COLOR); - currentVertexLayoutEnableMask = enableMask; + currentEnabledVertexLayout = enabledLayout; } glVertexAttribPointer(VATTR_POS, posAttrib.size, asGLType(posAttrib.type), posAttrib.normalize, stride, v + posAttrib.offset); diff --git a/imagine/src/gfx/opengl/RendererTask.cc b/imagine/src/gfx/opengl/RendererTask.cc index 9462fb13d..a6c285a6a 100644 --- a/imagine/src/gfx/opengl/RendererTask.cc +++ b/imagine/src/gfx/opengl/RendererTask.cc @@ -144,7 +144,7 @@ void RendererTask::updateDrawableForSurfaceChange(Window &win, WindowSurfaceChan r->makeWindowDrawable(*this, win, data.bufferConfig, data.colorSpace); return; case WindowSurfaceChange::Action::CHANGED: - if(change.surfaceResized()) + if(change.flags.surfaceResized) { GLTask::run( [this, drawable = (Drawable)drawable, v = data.viewportRect, swapInterval = data.swapInterval](TaskContext ctx) diff --git a/imagine/src/input/evdev/evdev.cc b/imagine/src/input/evdev/evdev.cc index 70b7b7eaa..d3ea1018f 100644 --- a/imagine/src/input/evdev/evdev.cc +++ b/imagine/src/input/evdev/evdev.cc @@ -15,7 +15,7 @@ #define LOGTAG "Evdev" #include "EvdevInputDevice.hh" -#include +#include #include #include #include diff --git a/imagine/src/io/AAssetIO.cc b/imagine/src/io/AAssetIO.cc index 9a26d66f8..47dcaac88 100755 --- a/imagine/src/io/AAssetIO.cc +++ b/imagine/src/io/AAssetIO.cc @@ -40,13 +40,13 @@ static int asAAssetMode(IOAccessHint advice) } } -AAssetIO::AAssetIO(ApplicationContext ctx, CStringView name, AccessHint access, OpenFlagsMask openFlags): +AAssetIO::AAssetIO(ApplicationContext ctx, CStringView name, AccessHint access, OpenFlags openFlags): asset{AAssetManager_open(ctx.aAssetManager(), name, asAAssetMode(access))} { if(!asset) [[unlikely]] { logErr("error in AAssetManager_open(%s, %s)", name.data(), asString(access)); - if(to_underlying(openFlags & OpenFlagsMask::Test)) + if(openFlags.test) return; else throw std::runtime_error{std::format("Error opening asset: {}", name)}; @@ -151,7 +151,7 @@ IOBuffer AAssetIO::releaseBuffer() return {}; auto map = mapIO.map(); logMsg("releasing asset:%p with buffer:%p (%zu bytes)", asset.get(), map.data(), map.size()); - return {map, 0, + return {map, {}, [asset = asset.release()](const uint8_t *ptr, size_t) { logMsg("closing released asset:%p", asset); diff --git a/imagine/src/io/IO.cc b/imagine/src/io/IO.cc index 2527f839e..30236463c 100644 --- a/imagine/src/io/IO.cc +++ b/imagine/src/io/IO.cc @@ -18,7 +18,6 @@ #include #include #include -#include #include "IOUtils.hh" namespace IG @@ -88,30 +87,30 @@ namespace IG::FileUtils ssize_t writeToPath(CStringView path, std::span src) { - auto f = FileIO{path, OpenFlagsMask::New | OpenFlagsMask::Test}; + auto f = FileIO{path, OpenFlags::testNewFile()}; return f.write(src).bytes; } ssize_t writeToPath(CStringView path, IO &io) { - auto f = FileIO{path, OpenFlagsMask::New | OpenFlagsMask::Test}; + auto f = FileIO{path, OpenFlags::testNewFile()}; return io.send(f, nullptr, io.size()); } ssize_t readFromPath(CStringView path, std::span dest, IO::AccessHint accessHint) { - FileIO f{path, accessHint, OpenFlagsMask::Test}; + FileIO f{path, accessHint, {.test = true}}; return f.read(dest).bytes; } -IOBuffer bufferFromPath(CStringView path, OpenFlagsMask openFlags, size_t sizeLimit) +IOBuffer bufferFromPath(CStringView path, OpenFlags openFlags, size_t sizeLimit) { FileIO file{path, IOAccessHint::All, openFlags}; if(!file) return {}; if(file.size() > sizeLimit) { - if(to_underlying(openFlags & OpenFlagsMask::Test)) + if(openFlags.test) return {}; else throw std::runtime_error(std::format("{} exceeds {} byte limit", path, sizeLimit)); diff --git a/imagine/src/io/IOUtils.hh b/imagine/src/io/IOUtils.hh index 0c9ca3870..d7ffd52a9 100644 --- a/imagine/src/io/IOUtils.hh +++ b/imagine/src/io/IOUtils.hh @@ -69,7 +69,7 @@ IOBuffer IOUtils::buffer(IOBufferMode mode) { auto map = io.map(); if(map.data()) - return {map, IOBuffer::MAPPED_FILE_BIT}; + return {map, {.mappedFile = true}}; } } return makeBufferCopy(io); diff --git a/imagine/src/io/PosixFileIO.cc b/imagine/src/io/PosixFileIO.cc index 5f018ae45..ec8f341b1 100644 --- a/imagine/src/io/PosixFileIO.cc +++ b/imagine/src/io/PosixFileIO.cc @@ -45,46 +45,46 @@ static void applyAccessHint(PosixFileIO &io, IOAccessHint access, bool isMapped) } } -PosixFileIO::PosixFileIO(UniqueFileDescriptor fd_, IOAccessHint access, OpenFlagsMask openFlags): +PosixFileIO::PosixFileIO(UniqueFileDescriptor fd_, IOAccessHint access, OpenFlags openFlags): ioImpl{std::in_place_type, std::move(fd_)} { initMmap(access, openFlags); } -PosixFileIO::PosixFileIO(UniqueFileDescriptor fd, OpenFlagsMask openFlags): +PosixFileIO::PosixFileIO(UniqueFileDescriptor fd, OpenFlags openFlags): PosixFileIO{std::move(fd), IOAccessHint::Normal, openFlags} {} -PosixFileIO::PosixFileIO(CStringView path, IOAccessHint access, OpenFlagsMask openFlags): +PosixFileIO::PosixFileIO(CStringView path, IOAccessHint access, OpenFlags openFlags): ioImpl{std::in_place_type, path, openFlags} { initMmap(access, openFlags); } -PosixFileIO::PosixFileIO(CStringView path, OpenFlagsMask openFlags): +PosixFileIO::PosixFileIO(CStringView path, OpenFlags openFlags): PosixFileIO{path, IOAccessHint::Normal, openFlags} {} -void PosixFileIO::initMmap(IOAccessHint access, OpenFlagsMask openFlags) +void PosixFileIO::initMmap(IOAccessHint access, OpenFlags openFlags) { if(!*std::get_if(&ioImpl)) return; - if(to_underlying(openFlags & OpenFlagsMask::Write) + if(openFlags.write || !tryMap(access, openFlags)) // try to open as memory map only if read-only { applyAccessHint(*this, access, false); } } -bool PosixFileIO::tryMap(IOAccessHint access, OpenFlagsMask openFlags) +bool PosixFileIO::tryMap(IOAccessHint access, OpenFlags openFlags) { return visit(overloaded { [&](PosixIO &io) { - IOMapFlagsMask flags{}; + IOMapFlags flags{}; if(access == IOAccessHint::All) - flags |= IOMapFlagsMask::PopulatePages; - if(to_underlying(openFlags & OpenFlagsMask::Write)) - flags |= IOMapFlagsMask::Write; + flags.populatePages = true; + if(openFlags.write) + flags.write = true; MapIO mappedFile{io.mapRange(0, io.size(), flags)}; if(!mappedFile) return false; diff --git a/imagine/src/io/PosixIO.cc b/imagine/src/io/PosixIO.cc index 6a5eec0dd..00f2b60d1 100755 --- a/imagine/src/io/PosixIO.cc +++ b/imagine/src/io/PosixIO.cc @@ -37,13 +37,13 @@ template class IOUtils; constexpr int MAP_POPULATE = 0; #endif -static auto flagsString(OpenFlagsMask openFlags) +static auto flagsString(OpenFlags openFlags) { IG::StaticString<5> logFlagsStr{}; - if(to_underlying(openFlags & OpenFlagsMask::Read)) logFlagsStr += 'r'; - if(to_underlying(openFlags & OpenFlagsMask::Write)) logFlagsStr += 'w'; - if(to_underlying(openFlags & OpenFlagsMask::Create)) logFlagsStr += 'c'; - if(to_underlying(openFlags & OpenFlagsMask::Truncate)) logFlagsStr += 't'; + if(openFlags.read) logFlagsStr += 'r'; + if(openFlags.write) logFlagsStr += 'w'; + if(openFlags.create) logFlagsStr += 'c'; + if(openFlags.truncate) logFlagsStr += 't'; return logFlagsStr; } @@ -55,16 +55,16 @@ static auto protectionFlagsString(int flags) return logFlagsStr; } -PosixIO::PosixIO(CStringView path, OpenFlagsMask openFlags) +PosixIO::PosixIO(CStringView path, OpenFlags openFlags) { constexpr mode_t defaultOpenMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int flags = 0; mode_t openMode{}; // setup flags - if(to_underlying(openFlags & OpenFlagsMask::Write)) + if(openFlags.write) { - if(to_underlying(openFlags & OpenFlagsMask::Read)) + if(openFlags.read) { flags |= O_RDWR; } @@ -77,11 +77,11 @@ PosixIO::PosixIO(CStringView path, OpenFlagsMask openFlags) { flags |= O_RDONLY; } - if(to_underlying(openFlags & OpenFlagsMask::Create)) + if(openFlags.create) { flags |= O_CREAT; openMode = defaultOpenMode; - if(to_underlying(openFlags & OpenFlagsMask::Truncate)) + if(openFlags.truncate) { flags |= O_TRUNC; } @@ -91,7 +91,7 @@ PosixIO::PosixIO(CStringView path, OpenFlagsMask openFlags) { if constexpr(Config::DEBUG_BUILD) logErr("error opening file (%s) @ %s:%s", flagsString(openFlags).data(), path.data(), strerror(errno)); - if(to_underlying(openFlags & OpenFlagsMask::Test)) + if(openFlags.test) return; else throw std::system_error{errno, std::system_category(), path}; @@ -231,16 +231,16 @@ IOBuffer PosixIO::releaseBuffer() flags = 0; } bool isWritable = (flags & O_WRONLY) || (flags & O_RDWR); - return mapRange(0, size(), isWritable ? IOMapFlagsMask::Write : IOMapFlagsMask{}); + return mapRange(0, size(), isWritable ? IOMapFlags{.write = true} : IOMapFlags{}); } -IOBuffer PosixIO::mapRange(off_t start, size_t size, IOMapFlagsMask mapFlags) +IOBuffer PosixIO::mapRange(off_t start, size_t size, IOMapFlags mapFlags) { int flags = MAP_SHARED; - if(to_underlying(mapFlags & IOMapFlagsMask::PopulatePages)) + if(mapFlags.populatePages) flags |= MAP_POPULATE; int prot = PROT_READ; - if(to_underlying(mapFlags & IOMapFlagsMask::Write)) + if(mapFlags.write) prot |= PROT_WRITE; void *data = mmap(nullptr, size, prot, flags, fd(), start); if(data == MAP_FAILED) [[unlikely]] @@ -256,7 +256,7 @@ IOBuffer PosixIO::byteBufferFromMmap(void *data, size_t size) { return { - {(uint8_t*)data, size}, IOBuffer::MAPPED_FILE_BIT, + {(uint8_t*)data, size}, {.mappedFile = true}, [](const uint8_t *ptr, size_t size) { logMsg("unmapping:%p (%zu bytes)", ptr, size);