Sync with libloot v0.26.1

Aside from adding GameType::oblivionRemastered and its usage, this is almost entirely about moving C++ files and tests around.
This commit is contained in:
Oliver Hamlet
2025-05-02 17:56:49 +01:00
parent f1186e4c08
commit eabc7a5d85
52 changed files with 1100 additions and 184 deletions
+6 -6
View File
@@ -67,8 +67,10 @@ set(LIBLOOT_SRC_API_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/api/api.cpp"
"${CMAKE_SOURCE_DIR}/src/api/convert.cpp"
"${CMAKE_SOURCE_DIR}/src/api/database.cpp"
"${CMAKE_SOURCE_DIR}/src/api/error_categories.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception/cyclic_interaction_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception/error_categories.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception/exception.cpp"
"${CMAKE_SOURCE_DIR}/src/api/exception/undefined_group_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/conditional_metadata.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/file.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/filename.cpp"
@@ -81,8 +83,6 @@ set(LIBLOOT_SRC_API_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/api/metadata/tag.cpp"
"${CMAKE_SOURCE_DIR}/src/api/game.cpp"
"${CMAKE_SOURCE_DIR}/src/api/plugin.cpp"
"${CMAKE_SOURCE_DIR}/src/api/sorting/cyclic_interaction_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/sorting/undefined_group_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/vertex.cpp")
set(LIBLOOT_INCLUDE_H_FILES
@@ -116,7 +116,7 @@ set(LIBLOOT_INCLUDE_H_FILES
set(LIBLOOT_SRC_API_H_FILES
"${CMAKE_SOURCE_DIR}/src/api/convert.h"
"${CMAKE_SOURCE_DIR}/src/api/database.h"
"${CMAKE_SOURCE_DIR}/src/api/exception.h"
"${CMAKE_SOURCE_DIR}/src/api/exception/exception.h"
"${CMAKE_SOURCE_DIR}/src/api/game.h"
"${CMAKE_SOURCE_DIR}/src/api/plugin.h")
@@ -239,7 +239,7 @@ endif()
# Install
########################################
set(LIBLOOT_VERSION "0.26.0")
set(LIBLOOT_VERSION "0.26.1")
set_property(TARGET loot PROPERTY VERSION ${LIBLOOT_VERSION})
set_property(TARGET loot PROPERTY SOVERSION 0)
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "libloot-cpp"
version = "0.26.0"
version = "0.26.1"
edition = "2024"
license = "GPL-3.0"
+2 -2
View File
@@ -1,6 +1,6 @@
# libloot-rs C++ wrapper
This is an **experimental** wrapper around the Rust reimplementation of libloot that provides a C++ interface that's ABI-compatible with libloot v0.26.0.
This is an **experimental** wrapper around the Rust reimplementation of libloot that provides a C++ interface that's ABI-compatible with libloot v0.26.1.
The wrapper has two layers:
@@ -44,7 +44,7 @@ cmake --build build --parallel
### Tests & Packaging
The build process also builds a copy of the public API tests from C++ libloot v0.26.0 by default. To skip building the tests, pass `-DLIBLOOT_BUILD_TESTS=OFF` when first running CMake.
The build process also builds a copy of the public API tests from C++ libloot v0.26.1 by default. To skip building the tests, pass `-DLIBLOOT_BUILD_TESTS=OFF` when first running CMake.
If built, the tests can be run using:
+15 -15
View File
@@ -36,16 +36,7 @@ set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_INITIAL})
set(LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/main.cpp")
set(LIBLOOT_SRC_TESTS_INTERNALS_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/conditional_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/tag_test.h")
# set(LIBLOOT_SRC_TESTS_INTERNALS_H_FILES)
set(LIBLOOT_SRC_TESTS_INTERFACE_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/main.cpp")
@@ -55,15 +46,24 @@ set(LIBLOOT_SRC_TESTS_INTERFACE_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/create_game_handle_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/database_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/game_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/is_compatible_test.h")
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/is_compatible_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/conditional_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/tag_test.h")
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
PREFIX "Source Files"
FILES ${LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
PREFIX "Header Files"
FILES ${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES})
# source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
# PREFIX "Header Files"
# FILES ${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES})
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/interface"
PREFIX "Source Files"
@@ -77,7 +77,7 @@ source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/interface"
set(LIBLOOT_INTERNALS_TESTS_ALL_SOURCES
${LIBLOOT_ALL_SOURCES}
${LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES}
${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES}
# ${LIBLOOT_SRC_TESTS_INTERNALS_H_FILES}
"${CMAKE_SOURCE_DIR}/src/tests/common_game_test_fixture.h"
"${CMAKE_SOURCE_DIR}/src/tests/test_helpers.h"
"${CMAKE_SOURCE_DIR}/src/tests/printers.h")
+3 -1
View File
@@ -52,7 +52,9 @@ enum struct GameType : unsigned int {
/** Starfield */
starfield,
/** OpenMW */
openmw
openmw,
/** The Elder Scrolls IV: Oblivion Remastered */
oblivionRemastered
};
}
+1 -1
View File
@@ -37,7 +37,7 @@ inline constexpr unsigned int LIBLOOT_VERSION_MAJOR = 0;
inline constexpr unsigned int LIBLOOT_VERSION_MINOR = 26;
/** @brief libloot's patch version number. */
inline constexpr unsigned int LIBLOOT_VERSION_PATCH = 0;
inline constexpr unsigned int LIBLOOT_VERSION_PATCH = 1;
/**
* @brief Get the library version.
+1 -1
View File
@@ -1,6 +1,6 @@
#include "api/convert.h"
#include "api/exception.h"
#include "api/exception/exception.h"
namespace loot {
// To public types
+1 -1
View File
@@ -2,7 +2,7 @@
#include "api/database.h"
#include "api/convert.h"
#include "api/exception.h"
#include "api/exception/exception.h"
namespace loot {
Database::Database(::rust::Box<loot::rust::Database>&& database) :
@@ -1,4 +1,4 @@
#include "api/exception.h"
#include "api/exception/exception.h"
#include <charconv>
+5 -1
View File
@@ -2,7 +2,7 @@
#include "api/game.h"
#include "api/convert.h"
#include "api/exception.h"
#include "api/exception/exception.h"
namespace {
loot::GameType convert(loot::rust::GameType gameType) {
@@ -29,6 +29,8 @@ loot::GameType convert(loot::rust::GameType gameType) {
return loot::GameType::starfield;
case loot::rust::GameType::OpenMW:
return loot::GameType::openmw;
case loot::rust::GameType::OblivionRemastered:
return loot::GameType::oblivionRemastered;
default:
throw std::logic_error("Unsupported GameType value");
}
@@ -58,6 +60,8 @@ loot::rust::GameType convert(loot::GameType gameType) {
return loot::rust::GameType::Starfield;
case loot::GameType::openmw:
return loot::rust::GameType::OpenMW;
case loot::GameType::oblivionRemastered:
return loot::rust::GameType::OblivionRemastered;
default:
throw std::logic_error("Unsupported GameType value");
}
+1 -1
View File
@@ -22,7 +22,7 @@ public:
GameType GetType() const override;
std::vector<std::filesystem::path> GetAdditionalDataPaths() const;
std::vector<std::filesystem::path> GetAdditionalDataPaths() const override;
void SetAdditionalDataPaths(
const std::vector<std::filesystem::path>& additionalDataPaths) override;
+2 -4
View File
@@ -4,7 +4,7 @@
#include <typeinfo>
#include "api/convert.h"
#include "api/exception.h"
#include "api/exception/exception.h"
namespace loot {
Plugin::Plugin(::rust::Box<loot::rust::Plugin> plugin) :
@@ -101,9 +101,7 @@ bool Plugin::DoRecordsOverlap(const PluginInterface& plugin) const {
return plugin_->do_records_overlap(*otherPlugin.plugin_);
} catch (std::bad_cast&) {
throw std::invalid_argument(
"Tried to check if records overlapped with a different concrete type "
"implementing PluginInterface");
return false;
} catch (const ::rust::Error& e) {
std::rethrow_exception(mapError(e));
}
+2 -2
View File
@@ -13,12 +13,12 @@ BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "LOOT"
VALUE "FileDescription", "Library providing LOOT's core functionality"
VALUE "FileVersion", "0.26.0"
VALUE "FileVersion", "0.26.1"
VALUE "InternalName", "loot"
VALUE "LegalCopyright", "Copyright (C) 2013-2022 Oliver Hamlet"
VALUE "OriginalFilename", "loot.dll"
VALUE "ProductName", "LOOT"
VALUE "ProductVersion", "0.26.0"
VALUE "ProductVersion", "0.26.1"
END
END
BLOCK "VarFileInfo"
+2
View File
@@ -21,6 +21,7 @@ impl TryFrom<libloot::GameType> for GameType {
libloot::GameType::Morrowind => Ok(GameType::Morrowind),
libloot::GameType::Starfield => Ok(GameType::Starfield),
libloot::GameType::OpenMW => Ok(GameType::OpenMW),
libloot::GameType::OblivionRemastered => Ok(GameType::OblivionRemastered),
_ => Err(UnsupportedEnumValueError),
}
}
@@ -42,6 +43,7 @@ impl TryFrom<GameType> for libloot::GameType {
GameType::Morrowind => Ok(libloot::GameType::Morrowind),
GameType::Starfield => Ok(libloot::GameType::Starfield),
GameType::OpenMW => Ok(libloot::GameType::OpenMW),
GameType::OblivionRemastered => Ok(libloot::GameType::OblivionRemastered),
_ => Err(UnsupportedEnumValueError),
}
}
+1
View File
@@ -232,6 +232,7 @@ mod ffi {
Morrowind,
Starfield,
OpenMW,
OblivionRemastered,
}
pub enum MessageType {
@@ -88,17 +88,7 @@ protected:
// but we only have the one so no prefix is necessary.
INSTANTIATE_TEST_SUITE_P(,
CreateGameHandleTest,
::testing::Values(GameType::tes4,
GameType::tes5,
GameType::fo3,
GameType::fonv,
GameType::fo4,
GameType::tes5se,
GameType::fo4vr,
GameType::tes5vr,
GameType::tes3,
GameType::starfield,
GameType::openmw));
::testing::ValuesIn(ALL_GAME_TYPES));
TEST_P(CreateGameHandleTest,
shouldSucceedIfPassedValidParametersWithRelativePaths) {
@@ -151,6 +141,74 @@ TEST_P(CreateGameHandleTest,
EXPECT_TRUE(handle_);
}
#endif
#ifndef _WIN32
TEST_P(
CreateGameHandleTest,
shouldThrowOnLinuxIfLocalPathIsNotGivenExceptForMorrowindOpenMWAndOblivionRemastered) {
if (GetParam() == GameType::tes3 || GetParam() == GameType::openmw ||
GetParam() == GameType::oblivionRemastered) {
EXPECT_NO_THROW(CreateGameHandle(GetParam(), gamePath));
} else {
EXPECT_THROW(CreateGameHandle(GetParam(), gamePath), std::system_error);
}
}
#else
TEST_P(CreateGameHandleTest,
shouldNotThrowOnWindowsIfLocalPathIsNotGiven) {
EXPECT_NO_THROW(CreateGameHandle(GetParam(), gamePath));
}
#endif
TEST_P(CreateGameHandleTest,
shouldNotThrowIfGameAndLocalPathsAreNotEmpty) {
EXPECT_NO_THROW(CreateGameHandle(GetParam(), gamePath, localPath));
}
TEST_P(
CreateGameHandleTest,
shouldSetAdditionalDataPathsForFallout4FromMicrosoftStoreOrStarfield) {
if (GetParam() == GameType::fo4) {
// Create the file that indicates it's a Microsoft Store install.
touch(gamePath / "appxmanifest.xml");
} else if (GetParam() == GameType::openmw) {
std::ofstream out(gamePath / "openmw.cfg");
out << "data-local=\"" << (localPath / "data").u8string() << "\""
<< std::endl
<< "config=\"" << localPath.u8string() << "\"";
}
const auto game = CreateGameHandle(GetParam(), gamePath, localPath);
if (GetParam() == GameType::fo4) {
const auto basePath = gamePath / ".." / "..";
EXPECT_EQ(std::vector<std::filesystem::path>(
{basePath / "Fallout 4- Automatron (PC)" / "Content" / "Data",
basePath / "Fallout 4- Nuka-World (PC)" / "Content" / "Data",
basePath / "Fallout 4- Wasteland Workshop (PC)" / "Content" /
"Data",
basePath / "Fallout 4- High Resolution Texture Pack" /
"Content" / "Data",
basePath / "Fallout 4- Vault-Tec Workshop (PC)" / "Content" /
"Data",
basePath / "Fallout 4- Far Harbor (PC)" / "Content" / "Data",
basePath / "Fallout 4- Contraptions Workshop (PC)" /
"Content" / "Data"}),
game->GetAdditionalDataPaths());
} else if (GetParam() == GameType::starfield) {
ASSERT_EQ(1, game->GetAdditionalDataPaths().size());
const auto expectedSuffix = std::filesystem::u8path("Documents") /
"My Games" / "Starfield" / "Data";
EXPECT_TRUE(endsWith(game->GetAdditionalDataPaths()[0].u8string(),
expectedSuffix.u8string()));
} else if (GetParam() == GameType::openmw) {
EXPECT_EQ(std::vector<std::filesystem::path>{localPath / "data"},
game->GetAdditionalDataPaths());
} else {
EXPECT_TRUE(game->GetAdditionalDataPaths().empty());
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More