From b859bf7ab5948b117e940bc4a962c7355ecda10f Mon Sep 17 00:00:00 2001 From: William JCM Date: Wed, 9 Mar 2022 11:04:19 +0100 Subject: [PATCH] Update Corrade/Magnum and adapt to changes. Also a few misc things, but nothing really noteworthy. --- modules/FindCorrade.cmake | 12 ++-- modules/FindImGui.cmake | 13 ++-- modules/FindMagnum.cmake | 20 +++--- modules/FindMagnumIntegration.cmake | 2 +- modules/FindSDL2.cmake | 35 +++++------ src/Mass/Mass.cpp | 18 +++--- src/Mass/Mass.h | 2 +- src/MassManager/MassManager.cpp | 80 ++++++++++++------------ src/Profile/Profile.cpp | 9 ++- src/ProfileManager/ProfileManager.cpp | 85 +++++++++++++++----------- src/SaveTool/SaveTool.cpp | 28 ++++----- src/SaveTool/SaveTool_MainManager.cpp | 20 +++--- src/SaveTool/SaveTool_drawMainMenu.cpp | 24 ++++---- src/UESaveFile/UESaveFile.cpp | 12 ++-- third-party/corrade | 2 +- third-party/magnum | 2 +- third-party/magnum-integration | 2 +- 17 files changed, 194 insertions(+), 172 deletions(-) diff --git a/modules/FindCorrade.cmake b/modules/FindCorrade.cmake index 9a36cce..780932b 100644 --- a/modules/FindCorrade.cmake +++ b/modules/FindCorrade.cmake @@ -62,8 +62,8 @@ # # Features of found Corrade library are exposed in these variables: # -# CORRADE_MSVC2019_COMPATIBILITY - Defined if compiled with compatibility -# mode for MSVC 2019 +# CORRADE_MSVC_COMPATIBILITY - Defined if compiled with compatibility +# mode for MSVC 2019+ without the /permissive- flag set # CORRADE_MSVC2017_COMPATIBILITY - Defined if compiled with compatibility # mode for MSVC 2017 # CORRADE_MSVC2015_COMPATIBILITY - Defined if compiled with compatibility @@ -100,7 +100,7 @@ # CORRADE_TARGET_MINGW - Defined if compiling under MinGW # CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT - Defined if PluginManager # doesn't support dynamic plugin loading due to platform limitations -# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targetting Xcode +# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targeting Xcode # XCTest # CORRADE_UTILITY_USE_ANSI_COLORS - Defined if ANSI escape sequences are used # for colored output with Utility::Debug on Windows @@ -264,7 +264,7 @@ # This file is part of Corrade. # # Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, -# 2017, 2018, 2019, 2020, 2021 +# 2017, 2018, 2019, 2020, 2021, 2022 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -312,7 +312,7 @@ string(REGEX REPLACE "\n" ";" _corradeConfigure "${_corradeConfigure}") set(_corradeFlags MSVC2015_COMPATIBILITY MSVC2017_COMPATIBILITY - MSVC2019_COMPATIBILITY + MSVC_COMPATIBILITY BUILD_DEPRECATED BUILD_STATIC BUILD_STATIC_UNIQUE_GLOBALS @@ -529,7 +529,7 @@ foreach(_component ${Corrade_FIND_COMPONENTS}) set_property(TARGET Corrade::${_component} APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX CORRADE_CXX_STANDARD) - # Directory::libraryLocation() needs this + # Path::libraryLocation() needs this if(CORRADE_TARGET_UNIX) set_property(TARGET Corrade::${_component} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}) diff --git a/modules/FindImGui.cmake b/modules/FindImGui.cmake index 14f0e67..2bd46c5 100644 --- a/modules/FindImGui.cmake +++ b/modules/FindImGui.cmake @@ -36,7 +36,7 @@ # This file is part of Magnum. # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021 Vladimír Vondruš +# 2020, 2021, 2022 Vladimír Vondruš # Copyright © 2018 Jonathan Hale # # Permission is hereby granted, free of charge, to any person obtaining a @@ -59,11 +59,18 @@ # # In 1.71 ImGui depends on the ApplicationServices framework for macOS -# clipboard support. It's removed again in 1.72. TODO: remove once obsolete +# clipboard support. Since 1.72 the dependency is optional and used only if +# IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS is enabled, but link to it +# always to be nice to users. if(CORRADE_TARGET_APPLE) find_library(_IMGUI_ApplicationServices_LIBRARY ApplicationServices) mark_as_advanced(_IMGUI_ApplicationServices_LIBRARY) set(_IMGUI_EXTRA_LIBRARIES ${_IMGUI_ApplicationServices_LIBRARY}) + +# Since 1.82, ImGui on MinGW needs the imm32 library. For MSVC the library +# seems to be linked implicitly so this is not needed. +elseif(CORRADE_TARGET_WINDOWS AND CORRADE_TARGET_MINGW) + set(_IMGUI_EXTRA_LIBRARIES imm32) endif() # Vcpkg distributes imgui as a library with a config file, so try that first -- @@ -75,7 +82,6 @@ endif() if(NOT IMGUI_DIR AND TARGET imgui::imgui) if(NOT TARGET ImGui::ImGui) add_library(ImGui::ImGui INTERFACE IMPORTED) - # TODO: remove once 1.71 is obsolete set_property(TARGET ImGui::ImGui APPEND PROPERTY INTERFACE_LINK_LIBRARIES imgui::imgui ${_IMGUI_EXTRA_LIBRARIES}) @@ -104,7 +110,6 @@ else() add_library(ImGui::ImGui INTERFACE IMPORTED) set_property(TARGET ImGui::ImGui APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ImGui_INCLUDE_DIR}) - # TODO: remove once 1.71 is obsolete if(_IMGUI_EXTRA_LIBRARIES) set_property(TARGET ImGui::ImGui APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${_IMGUI_EXTRA_LIBRARIES}) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 1c150aa..caa6999 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -60,6 +60,7 @@ # MeshTools - MeshTools library # Primitives - Primitives library # SceneGraph - SceneGraph library +# SceneTools - SceneTools library # Shaders - Shaders library # ShaderTools - ShaderTools library # Text - Text library @@ -201,7 +202,7 @@ # This file is part of Magnum. # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021 Vladimír Vondruš +# 2020, 2021, 2022 Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -229,7 +230,7 @@ foreach(_component ${Magnum_FIND_COMPONENTS}) # Unrolling the transitive dependencies here so this doesn't need to be # after resolving inter-component dependencies. Listing also all plugins. - if(_component MATCHES "^(Audio|DebugTools|MeshTools|Primitives|ShaderTools|Text|TextureTools|Trade|.+Importer|.+ImageConverter|.+Font|.+ShaderConverter)$") + if(_component MATCHES "^(Audio|DebugTools|MeshTools|Primitives|SceneTools|ShaderTools|Text|TextureTools|Trade|.+Importer|.+ImageConverter|.+Font|.+ShaderConverter)$") set(_MAGNUM_${_COMPONENT}_CORRADE_DEPENDENCIES PluginManager) endif() @@ -354,8 +355,8 @@ endif() # Component distinction (listing them explicitly to avoid mistakes with finding # components from other repositories) set(_MAGNUM_LIBRARY_COMPONENTS - Audio DebugTools GL MeshTools Primitives SceneGraph Shaders ShaderTools - Text TextureTools Trade + Audio DebugTools GL MeshTools Primitives SceneGraph SceneTools Shaders + ShaderTools Text TextureTools Trade WindowlessEglApplication EglContext OpenGLTester) set(_MAGNUM_PLUGIN_COMPONENTS AnyAudioImporter AnyImageConverter AnyImageImporter AnySceneConverter @@ -387,8 +388,7 @@ if(CORRADE_TARGET_EMSCRIPTEN) endif() if(CORRADE_TARGET_IOS) list(APPEND _MAGNUM_LIBRARY_COMPONENTS WindowlessIosApplication) -endif() -if(CORRADE_TARGET_APPLE AND NOT CORRADE_TARGET_IOS) +elseif(CORRADE_TARGET_APPLE AND NOT MAGNUM_TARGET_GLES) list(APPEND _MAGNUM_LIBRARY_COMPONENTS WindowlessCglApplication CglContext) endif() if(CORRADE_TARGET_UNIX AND NOT CORRADE_TARGET_APPLE) @@ -430,7 +430,7 @@ if(MAGNUM_TARGET_HEADLESS OR CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessEglApplication) elseif(CORRADE_TARGET_IOS) list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessIosApplication) -elseif(CORRADE_TARGET_APPLE) +elseif(CORRADE_TARGET_APPLE AND NOT MAGNUM_TARGET_GLES) list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessCglApplication) elseif(CORRADE_TARGET_UNIX) if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES) @@ -451,8 +451,11 @@ if(MAGNUM_TARGET_GL) # GL not required by Primitives themselves, but transitively by MeshTools list(APPEND _MAGNUM_Primitives_DEPENDENCIES GL) endif() + set(_MAGNUM_SceneGraph_DEPENDENCIES ) +set(_MAGNUM_SceneTools_DEPENDENCIES Trade) set(_MAGNUM_Shaders_DEPENDENCIES GL) + set(_MAGNUM_Text_DEPENDENCIES TextureTools) if(MAGNUM_TARGET_GL) list(APPEND _MAGNUM_Text_DEPENDENCIES GL) @@ -466,6 +469,7 @@ endif() set(_MAGNUM_Trade_DEPENDENCIES ) set(_MAGNUM_VulkanTester_DEPENDENCIES Vk) set(_MAGNUM_AndroidApplication_DEPENDENCIES GL) + set(_MAGNUM_EmscriptenApplication_DEPENDENCIES) if(MAGNUM_TARGET_GL) list(APPEND _MAGNUM_EmscriptenApplication_DEPENDENCIES GL) @@ -608,7 +612,7 @@ foreach(_component ${Magnum_FIND_COMPONENTS}) # Dynamic plugins don't have any prefix (e.g. `lib` on Linux), # search with empty prefix and then reset that back so we don't - # accidentaly break something else + # accidentally break something else set(_tmp_prefixes "${CMAKE_FIND_LIBRARY_PREFIXES}") set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES};") diff --git a/modules/FindMagnumIntegration.cmake b/modules/FindMagnumIntegration.cmake index 05bfde7..f0d5351 100644 --- a/modules/FindMagnumIntegration.cmake +++ b/modules/FindMagnumIntegration.cmake @@ -48,7 +48,7 @@ # This file is part of Magnum. # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021 Vladimír Vondruš +# 2020, 2021, 2022 Vladimír Vondruš # Copyright © 2018 Konstantinos Chatzilygeroudis # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/modules/FindSDL2.cmake b/modules/FindSDL2.cmake index 54844d6..311b052 100644 --- a/modules/FindSDL2.cmake +++ b/modules/FindSDL2.cmake @@ -20,7 +20,7 @@ # This file is part of Magnum. # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021 Vladimír Vondruš +# 2020, 2021, 2022 Vladimír Vondruš # Copyright © 2018 Jonathan Hale # # Permission is hereby granted, free of charge, to any person obtaining a @@ -168,37 +168,38 @@ find_path(SDL2_INCLUDE_DIR if(CORRADE_TARGET_WINDOWS) find_file(SDL2_DLL_RELEASE NAMES SDL2.dll - PATH_SUFFIXES ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) + PATH_SUFFIXES bin ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) find_file(SDL2_DLL_DEBUG NAMES SDL2d.dll # not sure? - PATH_SUFFIXES ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) + PATH_SUFFIXES bin ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) endif() -# (Static) macOS / iOS dependencies -if(CORRADE_TARGET_APPLE AND SDL2_LIBRARY MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$") +# (Static) macOS / iOS dependencies. On macOS these were mainly needed when +# building SDL statically using its CMake project, on iOS always. +if(CORRADE_TARGET_APPLE AND (SDL2_LIBRARY_DEBUG MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$" OR SDL2_LIBRARY_RELEASE MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")) + set(_SDL2_FRAMEWORKS + iconv # should be in the system, needed by iOS as well now + AudioToolbox + AVFoundation + CoreHaptics # needed since 2.0.18(?) on iOS and macOS + Foundation + Metal # needed since 2.0.8 on iOS, since 2.0.14 on macOS + GameController) # needed since 2.0.18(?) on macOS as well if(CORRADE_TARGET_IOS) - set(_SDL2_FRAMEWORKS - AudioToolbox - AVFoundation + list(APPEND _SDL2_FRAMEWORKS + CoreBluetooth # needed since 2.0.10 CoreGraphics CoreMotion Foundation - GameController - Metal # needed since 2.0.8 QuartzCore UIKit) else() - # Those are needed when building SDL statically using its CMake project - set(_SDL2_FRAMEWORKS - iconv # should be in the system - AudioToolbox - AVFoundation + list(APPEND _SDL2_FRAMEWORKS Carbon Cocoa CoreAudio CoreVideo ForceFeedback - Foundation IOKit) endif() set(_SDL2_FRAMEWORK_LIBRARIES ) @@ -247,7 +248,7 @@ if(NOT TARGET SDL2::SDL2) endif() # Link frameworks on macOS / iOS if we have a static SDL - if(CORRADE_TARGET_APPLE AND SDL2_LIBRARY MATCHES ".*libSDL2.a$") + if(CORRADE_TARGET_APPLE AND (SDL2_LIBRARY_DEBUG MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$" OR SDL2_LIBRARY_RELEASE MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")) set_property(TARGET SDL2::SDL2 APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${_SDL2_FRAMEWORK_LIBRARIES}) endif() diff --git a/src/Mass/Mass.cpp b/src/Mass/Mass.cpp index 5a99ab9..905ea3d 100644 --- a/src/Mass/Mass.cpp +++ b/src/Mass/Mass.cpp @@ -15,11 +15,10 @@ // along with this program. If not, see . #include -#include #include -#include -#include +#include +#include #include "../UESaveFile/Types/ArrayProperty.h" #include "../UESaveFile/Types/BoolProperty.h" @@ -37,9 +36,10 @@ using namespace Containers::Literals; -Mass::Mass(const std::string& path) { - _folder = Utility::Directory::path(path); - _filename = Utility::Directory::filename(path); +Mass::Mass(Containers::StringView path) { + auto split = Utility::Path::split(path); + _folder = split.first(); + _filename = split.second(); refreshValues(); } @@ -49,7 +49,7 @@ auto Mass::lastError() -> Containers::StringView { } auto Mass::getNameFromFile(Containers::StringView path) -> Containers::Optional { - if(!Utility::Directory::exists(path)) { + if(!Utility::Path::exists(path)) { Utility::Error{} << path << "couldn't be found."_s; return Containers::NullOpt; } @@ -79,13 +79,13 @@ auto Mass::getNameFromFile(Containers::StringView path) -> Containers::Optional< } void Mass::refreshValues() { - if(!Utility::Directory::exists(Utility::Directory::join(_folder, _filename))) { + if(!Utility::Path::exists(Utility::Path::join(_folder, _filename))) { _state = State::Empty; return; } if(!_mass) { - _mass.emplace(Utility::Directory::join(_folder, _filename)); + _mass.emplace(Utility::Path::join(_folder, _filename)); if(!_mass->valid()) { _state = State::Invalid; return; diff --git a/src/Mass/Mass.h b/src/Mass/Mass.h index 8c5c136..2c2dd9e 100644 --- a/src/Mass/Mass.h +++ b/src/Mass/Mass.h @@ -48,7 +48,7 @@ class Mass { Empty, Invalid, Valid }; - explicit Mass(const std::string& path); + explicit Mass(Containers::StringView path); Mass(const Mass&) = delete; Mass& operator=(const Mass&) = delete; diff --git a/src/MassManager/MassManager.cpp b/src/MassManager/MassManager.cpp index 7fda7d4..341cde5 100644 --- a/src/MassManager/MassManager.cpp +++ b/src/MassManager/MassManager.cpp @@ -16,10 +16,8 @@ #include -#include -#include -#include -#include +#include +#include #include "MassManager.h" @@ -35,12 +33,12 @@ MassManager::MassManager(Containers::StringView save_path, Containers::StringVie Containers::String mass_filename = ""; for(int i = 0; i < 32; i++) { - mass_filename = Utility::Directory::join(_saveDirectory, Utility::formatString("{}Unit{:.2d}{}.sav", demo ? "Demo"_s : ""_s, i, _account)); + mass_filename = Utility::Path::join(_saveDirectory, Utility::format("{}Unit{:.2d}{}.sav", demo ? "Demo"_s : ""_s, i, _account)); Containers::arrayAppend(_hangars, Mass{mass_filename}); } - if(!Utility::Directory::exists(_stagingAreaDirectory)) { - Utility::Directory::mkpath(_stagingAreaDirectory); + if(!Utility::Path::exists(_stagingAreaDirectory)) { + Utility::Path::make(_stagingAreaDirectory); } refreshStagedMasses(); @@ -60,7 +58,8 @@ void MassManager::refreshHangar(Int hangar) { } Containers::String mass_filename = - Utility::Directory::join(_saveDirectory, Utility::formatString("{}Unit{:.2d}{}.sav", _demo ? "Demo" : "", hangar, _account)); + Utility::Path::join(_saveDirectory, + Utility::format("{}Unit{:.2d}{}.sav", _demo ? "Demo" : "", hangar, _account)); _hangars[hangar] = Mass{mass_filename}; } @@ -77,26 +76,26 @@ auto MassManager::importMass(Containers::StringView staged_fn, Int hangar) -> bo return false; } - Containers::String source = Utility::Directory::join(_stagingAreaDirectory, staged_fn); - Utility::Directory::copy(source, source + ".tmp"_s); + Containers::String source = Utility::Path::join(_stagingAreaDirectory, staged_fn); + Utility::Path::copy(source, source + ".tmp"_s); { Mass mass{source + ".tmp"_s}; if(!mass.updateAccount(_account)) { _lastError = mass.lastError(); - Utility::Directory::rm(source + ".tmp"_s); + Utility::Path::remove(source + ".tmp"_s); return false; } } - Containers::String dest = Utility::Directory::join(_saveDirectory, _hangars[hangar].filename()); + Containers::String dest = Utility::Path::join(_saveDirectory, _hangars[hangar].filename()); - if(Utility::Directory::exists(dest)) { - Utility::Directory::rm(dest); + if(Utility::Path::exists(dest)) { + Utility::Path::remove(dest); } - if(!Utility::Directory::move(source + ".tmp"_s, dest)) { - _lastError = Utility::formatString("Couldn't move {} to hangar {:.2d}", staged_fn, hangar + 1); + if(!Utility::Path::move(source + ".tmp"_s, dest)) { + _lastError = Utility::format("Couldn't move {} to hangar {:.2d}", staged_fn, hangar + 1); return false; } @@ -110,16 +109,16 @@ auto MassManager::exportMass(Int hangar) -> bool { } if(_hangars[hangar].state() != Mass::State::Valid) { - _lastError = Utility::formatString("There is no valid data to export in hangar {:.2d}", hangar + 1); + _lastError = Utility::format("There is no valid data to export in hangar {:.2d}", hangar + 1); return false; } - Containers::String source = Utility::Directory::join(_saveDirectory, _hangars[hangar].filename()); - Containers::String dest = Utility::Directory::join(_stagingAreaDirectory, - Utility::formatString("{}_{}.sav", _hangars[hangar].name(), _account)); + Containers::String source = Utility::Path::join(_saveDirectory, _hangars[hangar].filename()); + Containers::String dest = Utility::Path::join(_stagingAreaDirectory, + Utility::format("{}_{}.sav", _hangars[hangar].name(), _account)); - if(!Utility::Directory::copy(source, dest)) { - _lastError = Utility::formatString("Couldn't export data from hangar {:.2d} to {}", hangar, dest); + if(!Utility::Path::copy(source, dest)) { + _lastError = Utility::format("Couldn't export data from hangar {:.2d} to {}", hangar, dest); return false; } @@ -137,25 +136,25 @@ auto MassManager::moveMass(Int source, Int destination) -> bool { return false; } - Containers::String source_file = Utility::Directory::join(_saveDirectory, _hangars[source].filename()); - Containers::String dest_file = Utility::Directory::join(_saveDirectory, _hangars[destination].filename()); + Containers::String source_file = Utility::Path::join(_saveDirectory, _hangars[source].filename()); + Containers::String dest_file = Utility::Path::join(_saveDirectory, _hangars[destination].filename()); Mass::State dest_state = _hangars[destination].state(); switch(dest_state) { case Mass::State::Empty: break; case Mass::State::Invalid: - Utility::Directory::rm(dest_file); + Utility::Path::remove(dest_file); break; case Mass::State::Valid: - Utility::Directory::move(dest_file, dest_file + ".tmp"_s); + Utility::Path::move(dest_file, dest_file + ".tmp"_s); break; } - Utility::Directory::move(source_file, dest_file); + Utility::Path::move(source_file, dest_file); if(dest_state == Mass::State::Valid) { - Utility::Directory::move(dest_file + ".tmp"_s, source_file); + Utility::Path::move(dest_file + ".tmp"_s, source_file); } return true; @@ -167,8 +166,8 @@ auto MassManager::deleteMass(Int hangar) -> bool { return false; } - if(!Utility::Directory::rm(Utility::Directory::join(_saveDirectory, _hangars[hangar].filename()))) { - _lastError = Utility::formatString("Deletion failed: {}", std::strerror(errno)); + if(!Utility::Path::remove(Utility::Path::join(_saveDirectory, _hangars[hangar].filename()))) { + _lastError = Utility::format("Deletion failed: {}", std::strerror(errno)); return false; } @@ -182,17 +181,22 @@ auto MassManager::stagedMasses() -> std::mapbegin(), file_list->end(), [](Containers::StringView file){ + return file.hasSuffix(".sav"_s); }); - file_list.erase(iter, file_list.end()); + auto list_view = file_list->except(file_list->end() - iter); - for(auto& file : file_list) { - auto name = Mass::getNameFromFile(Utility::Directory::join(_stagingAreaDirectory, file)); + for(Containers::StringView file : list_view) { + auto name = Mass::getNameFromFile(Utility::Path::join(_stagingAreaDirectory, file)); if(name) { _stagedMasses[file] = *name; @@ -206,7 +210,7 @@ auto MassManager::deleteStagedMass(Containers::StringView filename) -> bool { return false; } - if(!Utility::Directory::rm(Utility::Directory::join(_stagingAreaDirectory, filename))) { + if(!Utility::Path::remove(Utility::Path::join(_stagingAreaDirectory, filename))) { _lastError = filename + " couldn't be deleted: " + std::strerror(errno); return false; } diff --git a/src/Profile/Profile.cpp b/src/Profile/Profile.cpp index 6931dcc..d791b84 100644 --- a/src/Profile/Profile.cpp +++ b/src/Profile/Profile.cpp @@ -17,11 +17,10 @@ #include #include +#include #include -#include -#include -#include -#include +#include +#include #include "../UESaveFile/Types/ArrayProperty.h" #include "../UESaveFile/Types/ResourceItemValue.h" @@ -41,7 +40,7 @@ Profile::Profile(Containers::StringView path): return; } - _filename = Utility::Directory::filename(path); + _filename = Utility::Path::split(path).second(); if(_filename.hasPrefix("Demo"_s)) { _type = ProfileType::Demo; diff --git a/src/ProfileManager/ProfileManager.cpp b/src/ProfileManager/ProfileManager.cpp index cc995ed..3f4bc8a 100644 --- a/src/ProfileManager/ProfileManager.cpp +++ b/src/ProfileManager/ProfileManager.cpp @@ -23,9 +23,8 @@ #include #include -#include -#include -#include +#include +#include #include #include @@ -56,8 +55,14 @@ auto ProfileManager::profiles() -> Containers::ArrayView { auto ProfileManager::refreshProfiles() -> bool { _profiles = Containers::Array{}; - using Utility::Directory::Flag; - auto files = Utility::Directory::list(_saveDirectory, Flag::SkipSpecial|Flag::SkipDirectories|Flag::SkipDotAndDotDot); + using Utility::Path::ListFlag; + auto files = Utility::Path::list(_saveDirectory, + ListFlag::SkipSpecial|ListFlag::SkipDirectories|ListFlag::SkipDotAndDotDot); + + if(!files) { + _lastError = _saveDirectory + " can't be opened."; + return false; + } auto predicate = [](Containers::StringView file)->bool{ std::regex legacy_regex("(Demo)?Profile[0-9]{17}\\.sav", std::regex::nosubs); @@ -66,13 +71,13 @@ auto ProfileManager::refreshProfiles() -> bool { return !std::regex_match(file.data(), m, legacy_regex) && !std::regex_match(file.data(), m, new_regex); }; - files.erase(std::remove_if(files.begin(), files.end(), predicate), files.end()); + auto files_view = files->except(files->end() - std::remove_if(files->begin(), files->end(), predicate)); - for(const auto& file : files) { - Profile profile{Utility::Directory::join(_saveDirectory, file)}; + for(const auto& file : files_view) { + Profile profile{Utility::Path::join(_saveDirectory, file)}; if(!profile.valid()) { - Utility::Warning{} << "Profile"_s << file.c_str() << "is invalid:"_s << profile.lastError(); + Utility::Warning{} << "Profile"_s << file << "is invalid:"_s << profile.lastError(); continue; } @@ -92,7 +97,7 @@ auto ProfileManager::getProfile(std::size_t index) -> Profile* { } auto ProfileManager::deleteProfile(std::size_t index, bool delete_builds) -> bool { - if(!Utility::Directory::rm(Utility::Directory::join(_saveDirectory, _profiles[index].filename()))) { + if(!Utility::Path::remove(Utility::Path::join(_saveDirectory, _profiles[index].filename()))) { _lastError = Utility::format("Couldn't delete {} (filename: {}).", _profiles[index].companyName(), _profiles[index].filename()); @@ -105,7 +110,7 @@ auto ProfileManager::deleteProfile(std::size_t index, bool delete_builds) -> boo auto filename = Utility::format("{}Unit{:.2d}{}.sav", _profiles[index].type() == ProfileType::Demo ? "Demo": "", i, _profiles[index].account()); - Utility::Directory::rm(Utility::Directory::join(_saveDirectory, filename)); + Utility::Path::remove(Utility::Path::join(_saveDirectory, filename)); } } @@ -124,20 +129,20 @@ auto ProfileManager::backupProfile(std::size_t index, bool backup_builds) -> boo std::tm* time = std::localtime(×tamp); auto filename = Utility::format("{}_{}{:.2d}{:.2d}_{:.2d}{:.2d}{:.2d}.mbprofbackup", - Utility::String::replaceAll(_profiles[index].companyName(), " ", "_"), + Utility::String::replaceAll(_profiles[index].companyName().data(), " ", "_").c_str(), time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec); int error_code = 0; zip_error_t error; - zip_t* zip = zip_open(Utility::Directory::join(_backupsDirectory, filename).c_str(), ZIP_CREATE|ZIP_TRUNCATE, &error_code); + zip_t* zip = zip_open(Utility::Path::join(_backupsDirectory, filename).data(), ZIP_CREATE|ZIP_TRUNCATE, &error_code); if(zip == nullptr) { zip_error_init_with_code(&error, error_code); _lastError = zip_error_strerror(&error); return false; } - zip_source_t* profile_source = zip_source_file(zip, Utility::Directory::toNativeSeparators(Utility::Directory::join(_saveDirectory, _profiles[index].filename())).c_str(), 0, 0); + zip_source_t* profile_source = zip_source_file(zip, Utility::Path::toNativeSeparators(Utility::Path::join(_saveDirectory, _profiles[index].filename())).data(), 0, 0); if(profile_source == nullptr) { _lastError = zip_strerror(zip); zip_source_free(profile_source); @@ -163,11 +168,11 @@ auto ProfileManager::backupProfile(std::size_t index, bool backup_builds) -> boo _profiles[index].type() == ProfileType::Demo ? "Demo"_s : ""_s, i, _profiles[index].account()); - if(!Utility::Directory::exists(Utility::Directory::join(_saveDirectory, build_filename))) { + if(!Utility::Path::exists(Utility::Path::join(_saveDirectory, build_filename))) { continue; } - zip_source_t* build_source = zip_source_file(zip, Utility::Directory::toNativeSeparators(Utility::Directory::join(_saveDirectory, build_filename)).c_str(), 0, 0); + zip_source_t* build_source = zip_source_file(zip, Utility::Path::toNativeSeparators(Utility::Path::join(_saveDirectory, build_filename)).data(), 0, 0); if(build_source == nullptr) { zip_source_free(build_source); continue; @@ -197,28 +202,40 @@ auto ProfileManager::backups() -> Containers::ArrayView { void ProfileManager::refreshBackups() { _backups = Containers::Array{}; - using Utility::Directory::Flag; - std::vector files = Utility::Directory::list(_backupsDirectory, Flag::SkipSpecial|Flag::SkipDirectories|Flag::SkipDotAndDotDot); + using Utility::Path::ListFlag; + auto files = Utility::Path::list(_backupsDirectory, + ListFlag::SkipSpecial|ListFlag::SkipDirectories|ListFlag::SkipDotAndDotDot); + + if(!files) { + _lastError = _backupsDirectory + " can't be opened."; + return; + } auto predicate = [](Containers::StringView file)->bool{ return !file.hasSuffix(".mbprofbackup"_s); }; - files.erase(std::remove_if(files.begin(), files.end(), predicate), files.end()); + auto files_view = files->except(files->end() - std::remove_if(files->begin(), files->end(), predicate)); int error_code = 0; zip_t* zip = nullptr; - for(const std::string& file : files) { + for(Containers::StringView file : files_view) { Backup backup; backup.filename = file; - zip = zip_open(Utility::Directory::join(_backupsDirectory, file).c_str(), ZIP_RDONLY, &error_code); + zip = zip_open(Utility::Path::join(_backupsDirectory, file).data(), ZIP_RDONLY, &error_code); if(zip == nullptr) { continue; } Containers::ScopeGuard guard{zip, zip_close}; + Long num_entries = zip_get_num_entries(zip, ZIP_FL_UNCHANGED); + + if(num_entries == 0) { + continue; + } + int comment_length; Containers::StringView comment = zip_get_archive_comment(zip, &comment_length, ZIP_FL_UNCHANGED); if(comment == nullptr) { @@ -248,18 +265,12 @@ void ProfileManager::refreshBackups() { continue; } - backup.timestamp.year = std::stoi(ts[0]); - backup.timestamp.month = std::stoi(ts[1]); - backup.timestamp.day = std::stoi(ts[2]); - backup.timestamp.hour = std::stoi(ts[3]); - backup.timestamp.minute = std::stoi(ts[4]); - backup.timestamp.second = std::stoi(ts[5]); - - Long num_entries = zip_get_num_entries(zip, ZIP_FL_UNCHANGED); - - if(num_entries == 0) { - continue; - } + backup.timestamp.year = std::strtol(ts[0].data(), nullptr, 10); + backup.timestamp.month = std::strtol(ts[1].data(), nullptr, 10); + backup.timestamp.day = std::strtol(ts[2].data(), nullptr, 10); + backup.timestamp.hour = std::strtol(ts[3].data(), nullptr, 10); + backup.timestamp.minute = std::strtol(ts[4].data(), nullptr, 10); + backup.timestamp.second = std::strtol(ts[5].data(), nullptr, 10); arrayReserve(backup.includedFiles, num_entries); @@ -272,7 +283,7 @@ void ProfileManager::refreshBackups() { } auto ProfileManager::deleteBackup(std::size_t index) -> bool { - if(!Utility::Directory::rm(Utility::Directory::join(_backupsDirectory, _backups[index].filename))) { + if(!Utility::Path::remove(Utility::Path::join(_backupsDirectory, _backups[index].filename))) { _lastError = "Couldn't delete " + _backups[index].filename; return false; } @@ -295,7 +306,7 @@ auto ProfileManager::restoreBackup(std::size_t index) -> bool { int error_code = 0; zip_t* zip = nullptr; - zip = zip_open(Utility::Directory::join(_backupsDirectory, backup.filename).c_str(), ZIP_RDONLY, &error_code); + zip = zip_open(Utility::Path::join(_backupsDirectory, backup.filename).data(), ZIP_RDONLY, &error_code); if(zip == nullptr) { zip_error_t error; zip_error_init_with_code(&error, error_code); @@ -306,9 +317,9 @@ auto ProfileManager::restoreBackup(std::size_t index) -> bool { Containers::ScopeGuard zip_guard{zip, zip_close}; for(Containers::StringView file : backup.includedFiles) { - FILE* out = std::fopen(Utility::Directory::join(_saveDirectory, file).c_str(), "wb"); + FILE* out = std::fopen(Utility::Path::join(_saveDirectory, file).data(), "wb"); if(out == nullptr) { - _lastError = Utility::formatString(error_format.data(), file, std::strerror(errno)); + _lastError = Utility::format(error_format.data(), file, std::strerror(errno)); return false; } diff --git a/src/SaveTool/SaveTool.cpp b/src/SaveTool/SaveTool.cpp index cceac79..d949892 100644 --- a/src/SaveTool/SaveTool.cpp +++ b/src/SaveTool/SaveTool.cpp @@ -18,10 +18,10 @@ #include +#include #include -#include -#include #include +#include #include #include @@ -104,9 +104,9 @@ SaveTool::SaveTool(const Arguments& arguments): return; } - _configDir = Utility::Directory::join(_gameDataDir, "Saved/Config/WindowsNoEditor"); - _saveDir = Utility::Directory::join(_gameDataDir, "Saved/SaveGames"); - _screenshotsDir = Utility::Directory::join(_gameDataDir, "Saved/Screenshots/WindowsNoEditor"); + _configDir = Utility::Path::join(_gameDataDir, "Saved/Config/WindowsNoEditor"); + _saveDir = Utility::Path::join(_gameDataDir, "Saved/SaveGames"); + _screenshotsDir = Utility::Path::join(_gameDataDir, "Saved/Screenshots/WindowsNoEditor"); if(SDL_InitSubSystem(SDL_INIT_TIMER) != 0) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error initialising the app", SDL_GetError(), window()); @@ -535,19 +535,19 @@ void SaveTool::initialiseManager() { } void SaveTool::initialiseToolDirectories() { - _backupsDir = Utility::Directory::join(Utility::Directory::path(Utility::Directory::executableLocation()), "backups"); - _stagingDir = Utility::Directory::join(Utility::Directory::path(Utility::Directory::executableLocation()), "staging"); + _backupsDir = Utility::Path::join(Utility::Path::split(*Utility::Path::executableLocation()).first(), "backups"); + _stagingDir = Utility::Path::join(Utility::Path::split(*Utility::Path::executableLocation()).first(), "staging"); //_armouryDir = Utility::Directory::join(Utility::Directory::path(Utility::Directory::executableLocation()), "armoury"); //_armoursDir = Utility::Directory::join(_armouryDir, "armours"); //_weaponsDir = Utility::Directory::join(_armouryDir, "weapons"); //_stylesDir = Utility::Directory::join(_armouryDir, "styles"); - if(!Utility::Directory::exists(_backupsDir)) { - Utility::Directory::mkpath(_backupsDir); + if(!Utility::Path::exists(_backupsDir)) { + Utility::Path::make(_backupsDir); } - if(!Utility::Directory::exists(_stagingDir)) { - Utility::Directory::mkpath(_stagingDir); + if(!Utility::Path::exists(_stagingDir)) { + Utility::Path::make(_stagingDir); } //if(!Utility::Directory::exists(_armouryDir)) { @@ -576,9 +576,9 @@ auto SaveTool::findGameDataDirectory() -> bool { return false; } - _gameDataDir = Utility::Directory::join(Utility::Directory::fromNativeSeparators(Utility::Unicode::narrow(localappdata_path)), "MASS_Builder"); + _gameDataDir = Utility::Path::join(Utility::Path::fromNativeSeparators(Utility::Unicode::narrow(localappdata_path)), "MASS_Builder"_s); - if(!Utility::Directory::exists(_gameDataDir)) { + if(!Utility::Path::exists(_gameDataDir)) { _lastError = _gameDataDir + " wasn't found. Make sure to play the game at least once."_s; return false; } @@ -774,7 +774,7 @@ void SaveTool::drawTooltip(Containers::StringView text, Float wrap_pos) { } void SaveTool::openUri(Containers::StringView uri) { - ShellExecuteW(nullptr, nullptr, Utility::Unicode::widen(uri.data()).c_str(), nullptr, nullptr, SW_SHOWDEFAULT); + ShellExecuteW(nullptr, nullptr, Utility::Unicode::widen(uri.data()), nullptr, nullptr, SW_SHOWDEFAULT); } void SaveTool::checkGameState() { diff --git a/src/SaveTool/SaveTool_MainManager.cpp b/src/SaveTool/SaveTool_MainManager.cpp index 24b0d3c..98a65f6 100644 --- a/src/SaveTool/SaveTool_MainManager.cpp +++ b/src/SaveTool/SaveTool_MainManager.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include #include #include "../FontAwesome/IconsFontAwesome5.h" @@ -28,8 +28,6 @@ #include "../Maps/LastMissionId.h" #include "../Maps/StoryProgress.h" -static const std::string empty_str; - void SaveTool::drawManager() { ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always); ImGui::SetNextWindowSize({Float(windowSize().x()), Float(windowSize().y()) - ImGui::GetItemRectSize().y}, @@ -43,7 +41,7 @@ void SaveTool::drawManager() { } drawAlignedText("Current profile: %s (%s)", - _currentProfile->companyName(), + _currentProfile->companyName().data(), _currentProfile->type() == ProfileType::Demo ? "demo" : "full game"); ImGui::SameLine(); if(ImGui::Button(ICON_FA_ARROW_LEFT " Back to profile manager")) { @@ -464,7 +462,7 @@ void SaveTool::drawMassManager() { static int drag_drop_index = 0; ImGui::TableSetColumnIndex(0); - ImGui::Selectable(Utility::formatString("{:.2d}", i + 1).c_str(), + ImGui::Selectable(Utility::format("{:.2d}", i + 1).data(), false, ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap); if(_massManager->hangar(i).state() == Mass::State::Valid && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) @@ -573,16 +571,16 @@ void SaveTool::drawMassManager() { ImGui::TextUnformatted("Staging area"); ImGui::SameLine(); if(ImGui::SmallButton(ICON_FA_FOLDER_OPEN " Open staging folder")) { - openUri(Utility::Directory::toNativeSeparators(_stagingDir)); + openUri(Utility::Path::toNativeSeparators(_stagingDir)); } for(const auto& pair : _massManager->stagedMasses()) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - std::string staged_formatted = Utility::formatString("{} ({})", pair.second, pair.first); - ImGui::Selectable(staged_formatted.c_str()); - if((ImGui::CalcTextSize(staged_formatted.c_str()).x + ImGui::GetStyle().FramePadding.x) > ImGui::GetContentRegionAvailWidth()) { - drawTooltip(staged_formatted.c_str()); + Containers::String staged_formatted = Utility::format("{} ({})", pair.second, pair.first); + ImGui::Selectable(staged_formatted.data()); + if((ImGui::CalcTextSize(staged_formatted.data()).x + ImGui::GetStyle().FramePadding.x) > ImGui::GetContentRegionAvailWidth()) { + drawTooltip(staged_formatted.data()); } if(ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) { ImGui::SetDragDropPayload("StagedMass", &(pair.first), sizeof(std::string)); diff --git a/src/SaveTool/SaveTool_drawMainMenu.cpp b/src/SaveTool/SaveTool_drawMainMenu.cpp index 07ce855..ac0d5f6 100644 --- a/src/SaveTool/SaveTool_drawMainMenu.cpp +++ b/src/SaveTool/SaveTool_drawMainMenu.cpp @@ -16,7 +16,7 @@ #include "SaveTool.h" -#include +#include #include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5Brands.h" @@ -24,29 +24,29 @@ void SaveTool::drawMainMenu() { if(ImGui::BeginMainMenuBar()) { if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) { - if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Directory::exists(_gameDataDir))) { - if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Directory::exists(_configDir))) { - openUri(Utility::Directory::toNativeSeparators(_configDir)); + if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Path::exists(_gameDataDir))) { + if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Path::exists(_configDir))) { + openUri(Utility::Path::toNativeSeparators(_configDir)); } - if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Directory::exists(_saveDir))) { - openUri(Utility::Directory::toNativeSeparators(_saveDir)); + if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Path::exists(_saveDir))) { + openUri(Utility::Path::toNativeSeparators(_saveDir)); } - if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Directory::exists(_screenshotsDir))) { - openUri(Utility::Directory::toNativeSeparators(_screenshotsDir)); + if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Path::exists(_screenshotsDir))) { + openUri(Utility::Path::toNativeSeparators(_screenshotsDir)); } ImGui::EndMenu(); } if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open manager directory")) { - if(ImGui::MenuItem(ICON_FA_FILE_ARCHIVE " Profile backups", nullptr, false, Utility::Directory::exists(_backupsDir))) { - openUri(Utility::Directory::toNativeSeparators(_backupsDir)); + if(ImGui::MenuItem(ICON_FA_FILE_ARCHIVE " Profile backups", nullptr, false, Utility::Path::exists(_backupsDir))) { + openUri(Utility::Path::toNativeSeparators(_backupsDir)); } - if(ImGui::MenuItem(ICON_FA_EXCHANGE_ALT " Staging area", nullptr, false, Utility::Directory::exists(_stagingDir))) { - openUri(Utility::Directory::toNativeSeparators(_stagingDir)); + if(ImGui::MenuItem(ICON_FA_EXCHANGE_ALT " Staging area", nullptr, false, Utility::Path::exists(_stagingDir))) { + openUri(Utility::Path::toNativeSeparators(_stagingDir)); } ImGui::EndMenu(); diff --git a/src/UESaveFile/UESaveFile.cpp b/src/UESaveFile/UESaveFile.cpp index 449bda8..115d3ad 100644 --- a/src/UESaveFile/UESaveFile.cpp +++ b/src/UESaveFile/UESaveFile.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include "BinaryReader.h" #include "BinaryWriter.h" @@ -124,16 +124,16 @@ auto UESaveFile::saveToFile() -> bool { writer.closeFile(); - if(!Utility::Directory::copy(_filepath, _filepath + ".bak"_s)) { + if(!Utility::Path::copy(_filepath, _filepath + ".bak"_s)) { return false; } - if(!Utility::Directory::rm(_filepath)) { + if(!Utility::Path::remove(_filepath)) { return false; } - if(!Utility::Directory::move(_filepath + ".tmp"_s, _filepath)) { - Utility::Directory::move(_filepath + ".bak"_s, _filepath); + if(!Utility::Path::move(_filepath + ".tmp"_s, _filepath)) { + Utility::Path::move(_filepath + ".bak"_s, _filepath); return false; } @@ -145,7 +145,7 @@ auto UESaveFile::saveToFile() -> bool { void UESaveFile::loadData() { _valid = false; - if(!Utility::Directory::exists(_filepath)) { + if(!Utility::Path::exists(_filepath)) { return; } diff --git a/third-party/corrade b/third-party/corrade index 98922c0..dc4f2ea 160000 --- a/third-party/corrade +++ b/third-party/corrade @@ -1 +1 @@ -Subproject commit 98922c0dd19a00eb9f1ab2617c1d522b0b9b1743 +Subproject commit dc4f2eac6814b37b5257d295c2838bcde95272aa diff --git a/third-party/magnum b/third-party/magnum index 5f54cc4..3fc9028 160000 --- a/third-party/magnum +++ b/third-party/magnum @@ -1 +1 @@ -Subproject commit 5f54cc4702ac101c6d598933b2179d659b0c83b9 +Subproject commit 3fc9028b5451aa95973f104d1ef2a1c0df589e64 diff --git a/third-party/magnum-integration b/third-party/magnum-integration index f29c091..323c23f 160000 --- a/third-party/magnum-integration +++ b/third-party/magnum-integration @@ -1 +1 @@ -Subproject commit f29c091b0b699cdd092c9b80b4cb5535cf481758 +Subproject commit 323c23f4e8e7cda9a7848c03401a3ba0a1de0bd4