From c2d1a4c861048727abea56458fce06e1b88bb7cf Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 7 Jan 2024 01:18:15 +0000 Subject: [PATCH] Initial stab at OSG plugin checker It doesn't work yet due to osgDB::listAllAvailablePlugins returning a list of paths to dynamic libraries. That means: * the check fails when the required plugin is linked statically. * we're going to have to do something to slice up the filenames. * there'll probably be unicode errors when the OpenMW installation path isn't representable by the current eight-bit code page on Windows. Alternatively, we can switch to listing the required file extension support, and use osgDB::Registry::instance()->getReaderWriterList() and each element's supportedExtensions() function, but I don't think we've actually got that list of extensions anywhere and it might get desynced with the existing list of plugins if we add more. --- apps/openmw/main.cpp | 4 +++ components/CMakeLists.txt | 9 +++-- components/misc/osgpluginchecker.cpp.in | 47 +++++++++++++++++++++++++ components/misc/osgpluginchecker.hpp | 9 +++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 components/misc/osgpluginchecker.cpp.in create mode 100644 components/misc/osgpluginchecker.hpp diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 5bbc0211c1..adf50bea0e 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -228,6 +229,9 @@ int runApplication(int argc, char* argv[]) if (parseOptions(argc, argv, *engine, cfgMgr)) { + if (!Misc::checkRequiredOSGPluginsArePresent()) + return 1; + engine->go(); } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index f25a4cc621..ce4b431979 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -40,6 +40,11 @@ endif (GIT_CHECKOUT) list (APPEND COMPONENT_FILES "${OpenMW_BINARY_DIR}/${VERSION_CPP_FILE}") +# OSG plugin checker +set(OSG_PLUGIN_CHECKER_CPP_FILE "components/misc/osgpluginchecker.cpp") +configure_file("${OpenMW_SOURCE_DIR}/${OSG_PLUGIN_CHECKER_CPP_FILE}.in" "${OpenMW_BINARY_DIR}/${OSG_PLUGIN_CHECKER_CPP_FILE}") +list(APPEND COMPONENT_FILES "${OpenMW_BINARY_DIR}/${OSG_PLUGIN_CHECKER_CPP_FILE}") + # source files add_component_dir (lua @@ -274,8 +279,8 @@ add_component_dir (esm4 add_component_dir (misc barrier budgetmeasurement color compression constants convert coordinateconverter display endianness float16 frameratelimiter - guarded math mathutil messageformatparser notnullptr objectpool osguservalues progressreporter resourcehelpers rng - strongtypedef thread timeconvert timer tuplehelpers tuplemeta utf8stream weakcache windows + guarded math mathutil messageformatparser notnullptr objectpool osgpluginchecker osguservalues progressreporter resourcehelpers + rng strongtypedef thread timeconvert timer tuplehelpers tuplemeta utf8stream weakcache windows ) add_component_dir (misc/strings diff --git a/components/misc/osgpluginchecker.cpp.in b/components/misc/osgpluginchecker.cpp.in new file mode 100644 index 0000000000..56a7814d33 --- /dev/null +++ b/components/misc/osgpluginchecker.cpp.in @@ -0,0 +1,47 @@ +#include "components/misc/osgpluginchecker.hpp" + +#include + +#include + +#include +#include + +namespace Misc +{ + namespace + { + std::string_view USED_OSG_PLUGINS = "${USED_OSG_PLUGINS}"; + + constexpr std::vector getRequiredOSGPlugins() + { + std::vector requiredOSGPlugins; + auto currentStart = USED_OSG_PLUGINS.begin(); + while (currentStart != USED_OSG_PLUGINS.end()) + { + auto currentEnd = std::find(currentStart, USED_OSG_PLUGINS.end(), ';'); + requiredOSGPlugins.emplace_back(currentStart, currentEnd); + if (currentEnd == USED_OSG_PLUGINS.end()) + break; + currentStart = currentEnd + 1; + } + return requiredOSGPlugins; + } + } + + bool checkRequiredOSGPluginsArePresent() + { + auto availableOSGPlugins = osgDB::listAllAvailablePlugins(); + auto requiredOSGPlugins = getRequiredOSGPlugins(); + bool haveAllPlugins = true; + for (std::string_view plugin : requiredOSGPlugins) + { + if (std::find(availableOSGPlugins.begin(), availableOSGPlugins.end(), plugin) == availableOSGPlugins.end()) + { + Log(Debug::Error) << "Missing OSG plugin: " << plugin; + haveAllPlugins = false; + } + } + return haveAllPlugins; + } +} diff --git a/components/misc/osgpluginchecker.hpp b/components/misc/osgpluginchecker.hpp new file mode 100644 index 0000000000..2f5ea09700 --- /dev/null +++ b/components/misc/osgpluginchecker.hpp @@ -0,0 +1,9 @@ +#ifndef OPENMW_COMPONENTS_MISC_OSGPLUGINCHECKER_HPP +#define OPENMW_COMPONENTS_MISC_OSGPLUGINCHECKER_HPP + +namespace Misc +{ + bool checkRequiredOSGPluginsArePresent(); +} + +#endif