Skip to content

Commit

Permalink
engine: Update API for C++17
Browse files Browse the repository at this point in the history
 - Rewrite getPluginsList
 - Update API
  • Loading branch information
mwestphal committed Dec 30, 2024
1 parent e239a50 commit f2ce510
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 196 deletions.
2 changes: 1 addition & 1 deletion application/F3DOptionsTools.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ void PrintPluginsScan()

appPath /= "share/f3d/plugins";

auto plugins = f3d::engine::getPluginsList(appPath.string());
auto plugins = f3d::engine::getPluginsList(appPath);

f3d::log::info("Found ", plugins.size(), " plugins:");

Expand Down
12 changes: 9 additions & 3 deletions application/F3DPluginsTools.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@
#include <engine.h>
#include <log.h>

namespace fs = std::filesystem;

namespace
{
//----------------------------------------------------------------------------
std::vector<std::string> GetPluginSearchPaths()
std::vector<fs::path> GetPluginSearchPaths()
{
std::vector<fs::path> searchPaths;

// Recover F3D_PLUGINS_PATH first
auto searchPaths = F3DSystemTools::GetVectorEnvironnementVariable("F3D_PLUGINS_PATH");
std::vector<std::string> stringPaths =
F3DSystemTools::GetVectorEnvironnementVariable("F3D_PLUGINS_PATH");
std::copy(stringPaths.begin(), stringPaths.end(), std::back_inserter(searchPaths));
#if F3D_MACOS_BUNDLE
return searchPaths;
#else
// Add a executable related path
auto tmpPath = F3DSystemTools::GetApplicationPath();
tmpPath = tmpPath.parent_path().parent_path();
tmpPath /= F3D::PluginsInstallDir;
searchPaths.push_back(tmpPath.string());
searchPaths.emplace_back(tmpPath);
return searchPaths;
#endif
}
Expand Down
14 changes: 13 additions & 1 deletion application/testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,19 @@ endif()
# Test plugin fail code path
f3d_test(NAME TestPluginVerbose ARGS --verbose REGEXP "Loading plugin \"native\"" NO_BASELINE)
f3d_test(NAME TestPluginNonExistent ARGS --load-plugins=dummy REGEXP "Plugin failed to load" NO_BASELINE)
f3d_test(NAME TestPluginInvalid ARGS --load-plugins=${F3D_SOURCE_DIR}/testing/data/invalid.so REGEXP "Cannot open the library" NO_BASELINE)
if(WIN32)
set(_TEST_PLUGIN_INVALID_REGEXP "is not a valid Win32 application")
elseif(APPLE)
set(_TEST_PLUGIN_INVALID_REGEXP "not a mach-o file")
else()
set(_TEST_PLUGIN_INVALID_REGEXP "file too short")
endif()
f3d_test(NAME TestPluginInvalid ARGS --load-plugins=${F3D_SOURCE_DIR}/testing/data/invalid.so REGEXP ${_TEST_PLUGIN_INVALID_REGEXP} NO_BASELINE)

if(UNIX AND NOT APPLE)
f3d_test(NAME TestPluginInvalidSystem ARGS --verbose --load-plugins=invalid REGEXP "file too short" ENV "LD_LIBRARY_PATH=${F3D_SOURCE_DIR}/testing/data" NO_BASELINE)
endif()

if(WIN32)
set(_dirname "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
else()
Expand Down
4 changes: 3 additions & 1 deletion java/F3DJavaBindings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#define JAVA_BIND(Cls, Func) JNICALL Java_app_f3d_F3D_##Cls##_##Func

namespace fs = std::filesystem;

inline f3d::engine* GetEngine(JNIEnv* env, jobject self)
{
jclass cls = env->GetObjectClass(self);
Expand Down Expand Up @@ -39,7 +41,7 @@ extern "C"
JNIEXPORT void JAVA_BIND(Engine, setCachePath)(JNIEnv* env, jobject self, jstring path)
{
const char* str = env->GetStringUTFChars(path, nullptr);
GetEngine(env, self)->setCachePath(str);
GetEngine(env, self)->setCachePath(fs::path(str));
env->ReleaseStringUTFChars(path, str);
}

Expand Down
2 changes: 1 addition & 1 deletion library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ endif ()

if(F3D_STRICT_BUILD AND MSVC)
# There are warnings in VTK related to deprecated features in C++17
target_compile_definitions(libf3d PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS)
target_compile_definitions(libf3d PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS _CRT_SECURE_NO_WARNINGS)
endif()

if(APPLE)
Expand Down
3 changes: 2 additions & 1 deletion library/private/window_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "log.h"
#include "window.h"

#include <filesystem>
#include <memory>
#include <optional>

Expand Down Expand Up @@ -108,7 +109,7 @@ class window_impl : public window
* Implementation only API.
* Set the cache path.
*/
void SetCachePath(const std::string& cachePath);
void SetCachePath(const std::filesystem::path& cachePath);

/**
* Implementation only API.
Expand Down
84 changes: 66 additions & 18 deletions library/public/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,17 @@ class F3D_EXPORT engine
* Linux: Try GLX, then EGL, then OSMesa
* Windows: Try Win32, then EGL, then OSMesa
* macOS: Always use Cocoa
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine create(bool offscreen = false);

/**
* Create an engine with no window.
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createNone();

Expand All @@ -57,7 +63,10 @@ class F3D_EXPORT engine
* Works on Linux only.
* VTK >= 9.4 required.
* Optionally, the window can be hidden by setting offscreen to true.
* Throws engine::loading_exception in case of window creation failure.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createGLX(bool offscreen = false);

Expand All @@ -66,7 +75,10 @@ class F3D_EXPORT engine
* Works on Windows only.
* VTK >= 9.4 required.
* Optionally, the window can be hidden by setting offscreen to true.
* Throws engine::loading_exception in case of window creation failure.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createWGL(bool offscreen = false);

Expand All @@ -75,14 +87,20 @@ class F3D_EXPORT engine
* VTK >= 9.4 required.
* If several GPU are available, the environment variable
* `VTK_DEFAULT_EGL_DEVICE_INDEX` allows its selection.
* Throws engine::loading_exception in case of failure.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createEGL();

/**
* Create an engine with an offscreen OSMesa window.
* VTK >= 9.4 required.
* Throws engine::loading_exception in case of window creation failure.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createOSMesa();

Expand All @@ -94,46 +112,63 @@ class F3D_EXPORT engine
* \code{.cpp}
* f3d::engine eng = f3d::engine::createExternal(glfwGetProcAddress);
* \endcode
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternal(const context::function& getProcAddress);

/**
* Create an engine with an external GLX context.
* Equivalent to createExternal(f3d::context::glx());
* VTK >= 9.4 required.
* Throws context::loading_exception if GLX library is not found or if not running on Linux.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternalGLX();

/**
* Create an engine with an external WGL context.
* Equivalent to createExternal(f3d::context::wgl());
* VTK >= 9.4 required.
* Throws context::loading_exception if WGL library is not found or if not running on Windows.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternalWGL();

/**
* Create an engine with an external COCOA context.
* Equivalent to createExternal(f3d::context::cocoa());
* VTK >= 9.4 required.
* Throws context::loading_exception if WGL library is not found or if not running on Windows.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternalCOCOA();

/**
* Create an engine with an external EGL context.
* Equivalent to createExternal(f3d::context::egl());
* VTK >= 9.4 required.
* Throws context::loading_exception if EGL library is not found.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternalEGL();

/**
* Create an engine with an external OSMesa context.
* Equivalent to createExternal(f3d::context::osmesa());
* VTK >= 9.4 required.
* Throws context::loading_exception if OSMesa library is not found.
* Throws a context::loading_exception if a needed graphic library cannot be loaded
* Throws a context::symbol_exception if a needed symbol cannot be found in graphic library
* Throws a engine::no_window_exception if the window cannot be created for another reason
* Throws a engine::cache_exception if the default cache directory cannot be used
*/
[[nodiscard]] static engine createExternalOSMesa();

Expand All @@ -153,14 +188,15 @@ class F3D_EXPORT engine
//@}

/**
* Set the cache path. Must be an absolute path.
* Set the cache path. The provided path is used as is.
* Currently, it's only used to store HDRI baked textures.
* By default, the cache path is:
* - Windows: %LOCALAPPDATA%\f3d
* - Linux: ~/.cache/f3d
* - macOS: ~/Library/Caches/f3d
* Throw a cache_exception if the provided cachePath cannot be used.
*/
engine& setCachePath(const std::string& cachePath);
engine& setCachePath(const std::filesystem::path& cachePath);

/**
* Engine provide a default options that you can use using engine::getOptions().
Expand Down Expand Up @@ -206,19 +242,19 @@ class F3D_EXPORT engine

/**
* Load a plugin.
* Supports full path, relative path, and plugin name.
* The provided pathOrName can be a full path, relative path, or plugin name.
* First try to load the plugin by name from the static plugins.
* Then try to load the path provided as if it is a full path to a plugin.
* Then try to load a plugin by its name looking into the provided plugin search paths.
* Then try to load a plugin by its name relying on internal system (eg: LD_LIBRARY_PATH).
* Then try to load a plugin by its name looking into the provided plugin search paths (used as
* is). Then try to load a plugin by its name relying on internal system (eg: LD_LIBRARY_PATH).
* The plugin "native" is always available and includes native VTK readers.
* If built and available in your build, F3D is providing 5 additional plugins:
* "alembic", "assimp", "draco", "exodus", "occt", "usd".
* Custom plugins can also be available that F3D is not supporting officially.
* Throw a plugin_exception if the plugin can't be loaded for some reason.
*/
static void loadPlugin(
const std::string& nameOrPath, const std::vector<std::string>& pluginSearchPaths = {});
static void loadPlugin(const std::string& pathOrName,
const std::vector<std::filesystem::path>& pluginSearchPaths = {});

/**
* Automatically load all the static plugins.
Expand All @@ -227,11 +263,14 @@ class F3D_EXPORT engine
static void autoloadPlugins();

/**
* List plugins based on associated json files located in the given directory.
* List plugins based on associated json files located in the given directory, used as is.
* Listed plugins can be loaded using engine::loadPlugin function.
* Note that the listed plugins may fail to load if the library is not found or incompatible.
* Return available plugins if any, or an empty vector if there are none or the provided path does
* not exist.
*/
[[nodiscard]] static std::vector<std::string> getPluginsList(const std::string& pluginPath);
[[nodiscard]] static std::vector<std::string> getPluginsList(
const std::filesystem::path& pluginPath);

/**
* A structure providing information about the libf3d.
Expand Down Expand Up @@ -302,6 +341,15 @@ class F3D_EXPORT engine
explicit plugin_exception(const std::string& what = "");
};

/**
* An exception that can be thrown by the engine
* when the cache cannot be used
*/
struct cache_exception : public exception
{
explicit cache_exception(const std::string& what = "");
};

private:
class internals;
internals* Internals;
Expand Down
Loading

0 comments on commit f2ce510

Please sign in to comment.