nv-sgl 0.6.0__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. include/tevclient.h +393 -0
  2. nv_sgl-0.6.0.dist-info/LICENSE +29 -0
  3. nv_sgl-0.6.0.dist-info/METADATA +21 -0
  4. nv_sgl-0.6.0.dist-info/RECORD +133 -0
  5. nv_sgl-0.6.0.dist-info/WHEEL +6 -0
  6. nv_sgl-0.6.0.dist-info/top_level.txt +1 -0
  7. sgl/__init__.py +15 -0
  8. sgl/__init__.pyi +6738 -0
  9. sgl/include/sgl/app/app.h +113 -0
  10. sgl/include/sgl/core/bitmap.h +302 -0
  11. sgl/include/sgl/core/crypto.h +89 -0
  12. sgl/include/sgl/core/data_type.h +46 -0
  13. sgl/include/sgl/core/dds_file.h +103 -0
  14. sgl/include/sgl/core/enum.h +201 -0
  15. sgl/include/sgl/core/error.h +161 -0
  16. sgl/include/sgl/core/file_stream.h +77 -0
  17. sgl/include/sgl/core/file_system_watcher.h +141 -0
  18. sgl/include/sgl/core/format.h +36 -0
  19. sgl/include/sgl/core/fwd.h +90 -0
  20. sgl/include/sgl/core/hash.h +45 -0
  21. sgl/include/sgl/core/input.h +522 -0
  22. sgl/include/sgl/core/logger.h +214 -0
  23. sgl/include/sgl/core/macros.h +184 -0
  24. sgl/include/sgl/core/maths.h +45 -0
  25. sgl/include/sgl/core/memory_mapped_file.h +112 -0
  26. sgl/include/sgl/core/memory_mapped_file_stream.h +32 -0
  27. sgl/include/sgl/core/memory_stream.h +74 -0
  28. sgl/include/sgl/core/object.h +683 -0
  29. sgl/include/sgl/core/platform.h +239 -0
  30. sgl/include/sgl/core/plugin.h +331 -0
  31. sgl/include/sgl/core/resolver.h +39 -0
  32. sgl/include/sgl/core/short_vector.h +141 -0
  33. sgl/include/sgl/core/static_vector.h +111 -0
  34. sgl/include/sgl/core/stream.h +54 -0
  35. sgl/include/sgl/core/string.h +276 -0
  36. sgl/include/sgl/core/struct.h +360 -0
  37. sgl/include/sgl/core/thread.h +28 -0
  38. sgl/include/sgl/core/timer.h +52 -0
  39. sgl/include/sgl/core/traits.h +15 -0
  40. sgl/include/sgl/core/type_utils.h +19 -0
  41. sgl/include/sgl/core/window.h +177 -0
  42. sgl/include/sgl/device/agility_sdk.h +24 -0
  43. sgl/include/sgl/device/blit.h +88 -0
  44. sgl/include/sgl/device/buffer_cursor.h +162 -0
  45. sgl/include/sgl/device/command.h +539 -0
  46. sgl/include/sgl/device/cuda_api.h +766 -0
  47. sgl/include/sgl/device/cuda_interop.h +39 -0
  48. sgl/include/sgl/device/cuda_utils.h +107 -0
  49. sgl/include/sgl/device/cursor_utils.h +129 -0
  50. sgl/include/sgl/device/device.h +668 -0
  51. sgl/include/sgl/device/device_resource.h +37 -0
  52. sgl/include/sgl/device/fence.h +91 -0
  53. sgl/include/sgl/device/formats.h +330 -0
  54. sgl/include/sgl/device/framebuffer.h +85 -0
  55. sgl/include/sgl/device/fwd.h +164 -0
  56. sgl/include/sgl/device/helpers.h +20 -0
  57. sgl/include/sgl/device/hot_reload.h +75 -0
  58. sgl/include/sgl/device/input_layout.h +74 -0
  59. sgl/include/sgl/device/kernel.h +69 -0
  60. sgl/include/sgl/device/memory_heap.h +155 -0
  61. sgl/include/sgl/device/native_formats.h +342 -0
  62. sgl/include/sgl/device/native_handle.h +73 -0
  63. sgl/include/sgl/device/native_handle_traits.h +65 -0
  64. sgl/include/sgl/device/pipeline.h +138 -0
  65. sgl/include/sgl/device/print.h +45 -0
  66. sgl/include/sgl/device/python/cursor_utils.h +853 -0
  67. sgl/include/sgl/device/query.h +52 -0
  68. sgl/include/sgl/device/raytracing.h +84 -0
  69. sgl/include/sgl/device/reflection.h +1254 -0
  70. sgl/include/sgl/device/resource.h +705 -0
  71. sgl/include/sgl/device/sampler.h +57 -0
  72. sgl/include/sgl/device/shader.h +516 -0
  73. sgl/include/sgl/device/shader_cursor.h +85 -0
  74. sgl/include/sgl/device/shader_object.h +94 -0
  75. sgl/include/sgl/device/shader_offset.h +67 -0
  76. sgl/include/sgl/device/shared_handle.h +12 -0
  77. sgl/include/sgl/device/slang_utils.h +54 -0
  78. sgl/include/sgl/device/swapchain.h +74 -0
  79. sgl/include/sgl/device/types.h +782 -0
  80. sgl/include/sgl/math/colorspace.h +56 -0
  81. sgl/include/sgl/math/constants.h +7 -0
  82. sgl/include/sgl/math/float16.h +146 -0
  83. sgl/include/sgl/math/matrix.h +6 -0
  84. sgl/include/sgl/math/matrix_math.h +746 -0
  85. sgl/include/sgl/math/matrix_types.h +207 -0
  86. sgl/include/sgl/math/python/primitivetype.h +33 -0
  87. sgl/include/sgl/math/quaternion.h +6 -0
  88. sgl/include/sgl/math/quaternion_math.h +484 -0
  89. sgl/include/sgl/math/quaternion_types.h +83 -0
  90. sgl/include/sgl/math/ray.h +47 -0
  91. sgl/include/sgl/math/scalar_math.h +249 -0
  92. sgl/include/sgl/math/scalar_types.h +107 -0
  93. sgl/include/sgl/math/vector.h +6 -0
  94. sgl/include/sgl/math/vector_math.h +1796 -0
  95. sgl/include/sgl/math/vector_types.h +336 -0
  96. sgl/include/sgl/python/nanobind.h +489 -0
  97. sgl/include/sgl/python/py_doc.h +11600 -0
  98. sgl/include/sgl/python/sgl_ext_pch.h +8 -0
  99. sgl/include/sgl/sgl.h +21 -0
  100. sgl/include/sgl/sgl_pch.h +6 -0
  101. sgl/include/sgl/stl/bit.h +377 -0
  102. sgl/include/sgl/tests/testing.h +54 -0
  103. sgl/include/sgl/ui/fwd.h +34 -0
  104. sgl/include/sgl/ui/imgui_config.h +43 -0
  105. sgl/include/sgl/ui/ui.h +71 -0
  106. sgl/include/sgl/ui/widgets.h +918 -0
  107. sgl/include/sgl/utils/python/slangpy.h +366 -0
  108. sgl/include/sgl/utils/renderdoc.h +50 -0
  109. sgl/include/sgl/utils/slangpy.h +153 -0
  110. sgl/include/sgl/utils/tev.h +93 -0
  111. sgl/include/sgl/utils/texture_loader.h +106 -0
  112. sgl/libgfx.so +0 -0
  113. sgl/libsgl.so +0 -0
  114. sgl/libslang-glslang.so +0 -0
  115. sgl/libslang.so +0 -0
  116. sgl/libtevclient.a +0 -0
  117. sgl/math/__init__.pyi +5083 -0
  118. sgl/platform/__init__.pyi +102 -0
  119. sgl/renderdoc/__init__.pyi +51 -0
  120. sgl/sgl_ext.cpython-313-x86_64-linux-gnu.so +0 -0
  121. sgl/shaders/sgl/device/blit.slang +93 -0
  122. sgl/shaders/sgl/device/nvapi.slang +5 -0
  123. sgl/shaders/sgl/device/nvapi.slangh +7 -0
  124. sgl/shaders/sgl/device/print.slang +445 -0
  125. sgl/shaders/sgl/math/constants.slang +4 -0
  126. sgl/shaders/sgl/math/ray.slang +29 -0
  127. sgl/shaders/sgl/ui/imgui.slang +49 -0
  128. sgl/slangpy/__init__.pyi +268 -0
  129. sgl/tev/__init__.pyi +108 -0
  130. sgl/thread/__init__.pyi +4 -0
  131. sgl/ui/__init__.pyi +1118 -0
  132. share/cmake/tevclient/tevclient-config-release.cmake +19 -0
  133. share/cmake/tevclient/tevclient-config.cmake +103 -0
@@ -0,0 +1,239 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include "sgl/core/macros.h"
6
+
7
+ #include <filesystem>
8
+ #include <functional>
9
+ #include <optional>
10
+ #include <span>
11
+ #include <string_view>
12
+ #include <string>
13
+ #include <vector>
14
+
15
+ #if SGL_WINDOWS
16
+ #define DECLARE_HANDLE(name) \
17
+ struct name##__; \
18
+ typedef struct name##__* name
19
+ DECLARE_HANDLE(HWND);
20
+ #undef DECLARE_HANDLE
21
+ #endif
22
+
23
+ namespace sgl {
24
+ /// Native window handle.
25
+ struct WindowHandle {
26
+ #if SGL_WINDOWS
27
+ HWND hwnd;
28
+ #elif SGL_LINUX
29
+ void* xdisplay;
30
+ uint32_t xwindow;
31
+ #elif SGL_MACOS
32
+ void* nswindow;
33
+ #endif
34
+ };
35
+
36
+ /// Shared library handle.
37
+ using SharedLibraryHandle = void*;
38
+ } // namespace sgl
39
+
40
+ namespace sgl::platform {
41
+
42
+
43
+ /// Initialize the platform layer.
44
+ SGL_API void static_init();
45
+
46
+ /// Shutdown the platform layer.
47
+ SGL_API void static_shutdown();
48
+
49
+ /// Inform the platform that the library is loaded from python.
50
+ SGL_API void set_python_active(bool active);
51
+
52
+ /// Check if the library is loaded from python.
53
+ [[nodiscard]] SGL_API bool is_python_active();
54
+
55
+
56
+ /// Set the window icon.
57
+ SGL_API void set_window_icon(WindowHandle handle, const std::filesystem::path& path);
58
+
59
+ /// The pixel scale factor of the primary display.
60
+ [[nodiscard]] SGL_API float display_scale_factor();
61
+
62
+ /// Setup a callback function to be called when Ctrl-C is detected.
63
+ /// Use nullptr to remove handler.
64
+ SGL_API void set_keyboard_interrupt_handler(std::function<void()> handler);
65
+
66
+ // -------------------------------------------------------------------------------------------------
67
+ // File dialogs
68
+ // -------------------------------------------------------------------------------------------------
69
+
70
+ struct FileDialogFilter {
71
+ /// Readable name (e.g. "JPEG").
72
+ std::string name;
73
+ /// File extension pattern (e.g. "*.jpg" or "*.jpg,*.jpeg").
74
+ std::string pattern;
75
+
76
+ FileDialogFilter() = default;
77
+ FileDialogFilter(std::string_view name, std::string_view pattern)
78
+ : name(name)
79
+ , pattern(pattern)
80
+ {
81
+ }
82
+ FileDialogFilter(std::pair<std::string_view, std::string_view> pair)
83
+ : name(pair.first)
84
+ , pattern(pair.second)
85
+ {
86
+ }
87
+ };
88
+ using FileDialogFilterList = std::vector<FileDialogFilter>;
89
+
90
+ /// Show a file open dialog.
91
+ /// \param filters List of file filters.
92
+ /// \return The selected file path or nothing if the dialog was cancelled.
93
+ [[nodiscard]] SGL_API std::optional<std::filesystem::path>
94
+ open_file_dialog(std::span<const FileDialogFilter> filters = {});
95
+
96
+ /// Show a file save dialog.
97
+ /// \param filters List of file filters.
98
+ /// \return The selected file path or nothing if the dialog was cancelled.
99
+ [[nodiscard]] SGL_API std::optional<std::filesystem::path>
100
+ save_file_dialog(std::span<const FileDialogFilter> filters = {});
101
+
102
+ /// Show a folder selection dialog.
103
+ /// \return The selected folder path or nothing if the dialog was cancelled.
104
+ [[nodiscard]] SGL_API std::optional<std::filesystem::path> choose_folder_dialog();
105
+
106
+ // -------------------------------------------------------------------------------------------------
107
+ // Filesystem
108
+ // -------------------------------------------------------------------------------------------------
109
+
110
+ /// Compares two paths in their weakly canonical form, returning true if they match.
111
+ /// Operator == on path does a string comparison, ignoring the fact that windows paths are case insensitive.
112
+ /// STL's equivalent comparator throws when either of the paths does not exist.
113
+ /// This complements the two by allowing comparing non-existent paths, but at the same time ignoring case on windows.
114
+ [[nodiscard]] SGL_API bool is_same_path(const std::filesystem::path& lhs, const std::filesystem::path& rhs);
115
+
116
+ /// Check if a file path has a given file extension. Does a case-insensitive comparison.
117
+ [[nodiscard]] SGL_API bool has_extension(const std::filesystem::path& path, const std::string_view ext);
118
+
119
+ /// Get the file extension from a path in lower-case and without the leading '.' character.
120
+ [[nodiscard]] SGL_API std::string get_extension_from_path(const std::filesystem::path& path);
121
+
122
+ /// Create a unique path to a temporary file.
123
+ /// Note: A file with the same name could still be created by another process.
124
+ [[nodiscard]] SGL_API std::filesystem::path get_temp_file_path();
125
+
126
+ /// Create a junction (soft link).
127
+ [[nodiscard]] SGL_API bool create_junction(const std::filesystem::path& link, const std::filesystem::path& target);
128
+
129
+ /// Delete a junction (sof link).
130
+ [[nodiscard]] SGL_API bool delete_junction(const std::filesystem::path& link);
131
+
132
+ // -------------------------------------------------------------------------------------------------
133
+ // System paths
134
+ // -------------------------------------------------------------------------------------------------
135
+
136
+ /// The full path to the current executable.
137
+ [[nodiscard]] SGL_API const std::filesystem::path& executable_path();
138
+
139
+ /// The current executable directory.
140
+ [[nodiscard]] SGL_API const std::filesystem::path& executable_directory();
141
+
142
+ /// The current executable name.
143
+ [[nodiscard]] SGL_API const std::string& executable_name();
144
+
145
+ /// The application data directory.
146
+ [[nodiscard]] SGL_API const std::filesystem::path& app_data_directory();
147
+
148
+ /// The home directory.
149
+ [[nodiscard]] SGL_API const std::filesystem::path& home_directory();
150
+
151
+ /// The project source directory. Note that this is only valid during development.
152
+ [[nodiscard]] SGL_API const std::filesystem::path& project_directory();
153
+
154
+ /// The runtime directory. This is the path where the sgl runtime library
155
+ /// (sgl.dll, libsgl.so or libsgl.dynlib) resides.
156
+ [[nodiscard]] SGL_API const std::filesystem::path& runtime_directory();
157
+
158
+ // -------------------------------------------------------------------------------------------------
159
+ // Environment
160
+ // -------------------------------------------------------------------------------------------------
161
+
162
+ /// Get the content of a system environment variable.
163
+ [[nodiscard]] SGL_API std::optional<std::string> get_environment_variable(const char* name);
164
+
165
+ // -------------------------------------------------------------------------------------------------
166
+ // Memory
167
+ // -------------------------------------------------------------------------------------------------
168
+
169
+ /// The page size of the system.
170
+ [[nodiscard]] SGL_API size_t page_size();
171
+
172
+ struct MemoryStats {
173
+ /// Current resident/working set size in bytes.
174
+ uint64_t rss;
175
+ /// Peak resident/working set size in bytes.
176
+ uint64_t peak_rss;
177
+ };
178
+
179
+ /// Get the current memory stats.
180
+ [[nodiscard]] SGL_API MemoryStats memory_stats();
181
+
182
+ // -------------------------------------------------------------------------------------------------
183
+ // Shared libraries
184
+ // -------------------------------------------------------------------------------------------------
185
+
186
+ /// Load a shared library.
187
+ [[nodiscard]] SGL_API SharedLibraryHandle load_shared_library(const std::filesystem::path& path);
188
+
189
+ /// Release a shared library.
190
+ SGL_API void release_shared_library(SharedLibraryHandle library);
191
+
192
+ /// Get a function pointer from a library.
193
+ SGL_API void* get_proc_address(SharedLibraryHandle library, const char* proc_name);
194
+
195
+ // -------------------------------------------------------------------------------------------------
196
+ // Debugger
197
+ // -------------------------------------------------------------------------------------------------
198
+
199
+ /// Check if a debugger session is attached.
200
+ [[nodiscard]] SGL_API bool is_debugger_present();
201
+
202
+ /// Breaks in debugger (int 3 functionality).
203
+ SGL_API void debug_break();
204
+
205
+ /// Print a message into the debug window.
206
+ SGL_API void print_to_debug_window(const char* str);
207
+
208
+ // -------------------------------------------------------------------------------------------------
209
+ // Stacktrace
210
+ // -------------------------------------------------------------------------------------------------
211
+
212
+ using StackFrame = uintptr_t;
213
+ using StackTrace = std::vector<StackFrame>;
214
+
215
+ struct ResolvedStackFrame {
216
+ uintptr_t address;
217
+ std::string module;
218
+ std::string symbol;
219
+ size_t offset;
220
+ std::string source;
221
+ uint32_t line;
222
+ };
223
+
224
+ using ResolvedStackTrace = std::vector<ResolvedStackFrame>;
225
+
226
+ /// Generate a backtrace.
227
+ [[nodiscard]] SGL_API StackTrace backtrace(size_t skip_frames = 1);
228
+
229
+ /// Resolve a stack trace with symbol information.
230
+ [[nodiscard]] SGL_API ResolvedStackTrace resolve_stacktrace(std::span<const StackFrame> trace);
231
+
232
+ /// Convert resolved stack trace to a human readable string.
233
+ [[nodiscard]] SGL_API std::string format_stacktrace(std::span<const ResolvedStackFrame> trace, size_t max_frames = 0);
234
+
235
+ /// Convert resolved stack trace to a human readable string.
236
+ [[nodiscard]] SGL_API std::string format_stacktrace(std::span<const StackFrame> trace, size_t max_frames = 0);
237
+
238
+
239
+ } // namespace sgl::platform
@@ -0,0 +1,331 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include "sgl/core/macros.h"
6
+ #include "sgl/core/error.h"
7
+ #include "sgl/core/platform.h"
8
+
9
+ #include <filesystem>
10
+ #include <map>
11
+ #include <memory>
12
+ #include <mutex>
13
+ #include <span>
14
+ #include <string>
15
+ #include <type_traits>
16
+ #include <vector>
17
+
18
+ namespace sgl {
19
+
20
+ /**
21
+ * \brief Plugin manager for loading plugin libraries and creating plugin instances.
22
+ *
23
+ * The plugin system is based around the following principles:
24
+ * - Plugins are compiled into shared libraries known as _plugin libraries_.
25
+ * - A _plugin library_ registers one or more _plugin classes_ when being loaded.
26
+ * - A _plugin class_ needs to inherit from a known _plugin base class_, implementing it's interface.
27
+ * - A _plugin base class_ defines a `PluginInfo` struct, describing meta information about each
28
+ * _plugin class_ as well as a `PluginCreate` typedef used for instantiating plugin classes.
29
+ *
30
+ * A _plugin base class_ can be any class that is exported from the main sgl library.
31
+ * It needs to define a `PluginInfo` struct as well as a `PluginCreate` typedef.
32
+ * The SGL_PLUGIN_BASE_CLASS macro extends the class with the required members for the plugin system.
33
+ * For example:
34
+ *
35
+ * \code
36
+ * class SGL_API PluginBase
37
+ * {
38
+ * public:
39
+ * struct PluginInfo { const char* desc };
40
+ * using PluginCreate = (PluginBase *)(*)();
41
+ * SGL_PLUGIN_BASE_CLASS(PluginBase);
42
+ *
43
+ * virtual void do_struff() = 0;
44
+ * };
45
+ * \endcode
46
+ *
47
+ * To implement a _plugin class_ type, we simply inherit from the base class.
48
+ * The SGL_PLUGIN_CLASS macro extends the class with the required members for the plugin system.
49
+ * The class also needs to implement a static create function, matching the `PluginCreate` type of the base class.
50
+ * For example:
51
+ *
52
+ * \code
53
+ * class PluginA : public PluginBase
54
+ * {
55
+ * public:
56
+ * SGL_PLUGIN_CLASS(PluginA, "PluginA", PluginInfo({"plugin description string"}));
57
+ *
58
+ * static PluginBase* create() { return new PluginA(); }
59
+ *
60
+ * void do_struff() override { ... }
61
+ * };
62
+ * \endcode
63
+ *
64
+ * The _plugin library_ must export a `register_plugin` function for registering all the plugin class types when called.
65
+ *
66
+ * \code
67
+ * extern "C" SGL_API_EXPORT void register_plugin(sgl::PluginRegistry& registry)
68
+ * {
69
+ * registry.register_class<PluginBase, PluginA>();
70
+ * }
71
+ * \endcode
72
+ *
73
+ * At runtime, the plugin manager can load plugin libraries using `load_plugin_by_name` and `load_plugin`.
74
+ * New plugin instances can be created using `create_class`, for example:
75
+ *
76
+ * \code
77
+ * PluginBase* p = PluginManager::instance().create_class<PluginBase>("PluginA");
78
+ * \endcode
79
+ *
80
+ * The `get_infos` function returns a list of plugin infos for all loaded plugin types of a given plugin base class.
81
+ */
82
+ class SGL_API PluginManager {
83
+ public:
84
+ /// Singleton accessor.
85
+ static PluginManager& instance();
86
+
87
+ /**
88
+ * \brief Create an instance of a plugin class.
89
+ *
90
+ * \tparam BaseT The plugin base class.
91
+ * \tparam Args The argument type pack used for construction.
92
+ * \param type The plugin type name.
93
+ * \param args Additional arguments passed on construction.
94
+ * \return Returns a new instance of the requested plugin type or nullptr if not registered.
95
+ */
96
+ template<typename BaseT, typename... Args>
97
+ std::invoke_result_t<typename BaseT::PluginCreate, Args...> create_class(std::string_view type, Args... args) const
98
+ {
99
+ std::lock_guard<std::mutex> lock(m_class_descs_mutex);
100
+ const ClassDesc<BaseT>* class_desc = find_class_desc<BaseT>(type);
101
+ return class_desc ? class_desc->create(args...)
102
+ : std::invoke_result_t<typename BaseT::PluginCreate, Args...>{nullptr};
103
+ }
104
+
105
+ /**
106
+ * \brief Check if a given type of a plugin is available.
107
+ *
108
+ * \tparam BaseT The plugin base class.
109
+ * \param type The plugin type name.
110
+ * \return True if plugin type is available.
111
+ */
112
+ template<typename BaseT>
113
+ bool has_class(std::string_view type) const
114
+ {
115
+ std::lock_guard<std::mutex> lock(m_class_descs_mutex);
116
+ const ClassDesc<BaseT>* class_desc = find_class_desc<BaseT>(type);
117
+ return class_desc != nullptr;
118
+ }
119
+
120
+ /**
121
+ * \brief Get infos for all registered plugin types for a given plugin base class.
122
+ *
123
+ * \tparam BaseT The plugin base class.
124
+ * \return A list of infos.
125
+ */
126
+ template<typename BaseT>
127
+ std::vector<std::pair<std::string, typename BaseT::PluginInfo>> get_infos() const
128
+ {
129
+ std::lock_guard<std::mutex> lock(m_class_descs_mutex);
130
+ std::vector<std::pair<std::string, typename BaseT::PluginInfo>> result;
131
+
132
+ for (const auto& [name, desc] : m_class_descs)
133
+ if (auto match_desc = dynamic_cast<const ClassDesc<BaseT>*>(desc.get()))
134
+ result.push_back(std::make_pair(match_desc->type, match_desc->info));
135
+
136
+ return result;
137
+ }
138
+
139
+ /**
140
+ * \brief Load a plugin library by name.
141
+ * This will automatically determine the plugin path and file extension.
142
+ * \param plugin_dir Path to plugin directory.
143
+ * \param name Name of the plugin library.
144
+ * \return True if successful.
145
+ */
146
+ bool load_plugin_by_name(const std::filesystem::path& plugin_dir, std::string_view name);
147
+
148
+ /**
149
+ * Load a list of plugin libraries.
150
+ * \param plugin_dir Path to plugin directory.
151
+ * \param names Names of the plugin libraries.
152
+ */
153
+ void load_plugins_by_name(const std::filesystem::path& plugin_dir, std::span<const std::string> names);
154
+
155
+ /**
156
+ * Load a plugin library.
157
+ * \param path File path of the plugin library.
158
+ * \return True if successful.
159
+ */
160
+ bool load_plugin(const std::filesystem::path& path);
161
+
162
+ /**
163
+ * Release a previously loaded plugin library.
164
+ * \param path File path of the plugin library.
165
+ * \return True if successful.
166
+ */
167
+ bool release_plugin(const std::filesystem::path& path);
168
+
169
+ /**
170
+ * Release all loaded plugin libraries.
171
+ */
172
+ void release_all_plugins();
173
+
174
+ private:
175
+ struct ClassDescBase {
176
+ ClassDescBase(SharedLibraryHandle library, std::string_view type)
177
+ : library(library)
178
+ , type(type)
179
+ {
180
+ }
181
+ virtual ~ClassDescBase() { }
182
+
183
+ SharedLibraryHandle library;
184
+ std::string type;
185
+ };
186
+
187
+ template<typename BaseT>
188
+ struct ClassDesc : public ClassDescBase {
189
+ typename BaseT::PluginInfo info;
190
+ typename BaseT::PluginCreate create;
191
+
192
+ ClassDesc(
193
+ SharedLibraryHandle library,
194
+ std::string_view type,
195
+ typename BaseT::PluginInfo info,
196
+ typename BaseT::PluginCreate create
197
+ )
198
+ : ClassDescBase(library, type)
199
+ , info(info)
200
+ , create(create)
201
+ {
202
+ }
203
+ };
204
+
205
+ template<typename BaseT>
206
+ void register_class(
207
+ SharedLibraryHandle library,
208
+ std::string_view type,
209
+ typename BaseT::PluginInfo info,
210
+ typename BaseT::PluginCreate create
211
+ )
212
+ {
213
+ std::lock_guard<std::mutex> lock(m_class_descs_mutex);
214
+
215
+ if (find_class_desc<BaseT>(type) != nullptr)
216
+ SGL_THROW(
217
+ "A plugin class with type name \"{}\" (base class type \"{}\") has already been registered.",
218
+ type,
219
+ BaseT::get_plugin_base_type()
220
+ );
221
+
222
+ auto desc = std::make_shared<ClassDesc<BaseT>>(library, type, info, create);
223
+ m_class_descs.emplace(type, std::move(desc));
224
+ }
225
+
226
+ template<typename BaseT>
227
+ const ClassDesc<BaseT>* find_class_desc(std::string_view type) const
228
+ {
229
+ if (auto it = m_class_descs.find(std::string(type)); it != m_class_descs.end())
230
+ if (auto desc = dynamic_cast<const ClassDesc<BaseT>*>(it->second.get()); desc && desc->type == type)
231
+ return desc;
232
+
233
+ return nullptr;
234
+ }
235
+
236
+ std::map<std::filesystem::path, SharedLibraryHandle> m_libraries;
237
+ std::map<std::string, std::shared_ptr<ClassDescBase>> m_class_descs;
238
+
239
+ mutable std::mutex m_libraries_mutex;
240
+ mutable std::mutex m_class_descs_mutex;
241
+
242
+ friend class PluginRegistry;
243
+ };
244
+
245
+ /**
246
+ * \brief Helper class passed to plugin libraries to register plugin classes.
247
+ */
248
+ class PluginRegistry {
249
+ public:
250
+ PluginRegistry(PluginManager& plugin_manager, SharedLibraryHandle library)
251
+ : m_plugin_manager(plugin_manager)
252
+ , m_library(library)
253
+ {
254
+ }
255
+ PluginRegistry(const PluginRegistry&) = delete;
256
+ PluginRegistry& operator=(const PluginRegistry&) = delete;
257
+
258
+ /**
259
+ * \brief Register a plugin class.
260
+ * Throws if a class with the same type name (and same base class) has already been registered.
261
+ *
262
+ * \tparam BaseT The plugin base class.
263
+ * \param type The plugin type name.
264
+ * \param info The plugin info (type of BaseT::PluginInfo).
265
+ * \param create The plugin create function (type of BaseT::PluginCreate).
266
+ */
267
+ template<typename BaseT>
268
+ void register_class(std::string_view type, typename BaseT::PluginInfo info, typename BaseT::PluginCreate create)
269
+ {
270
+ m_plugin_manager.register_class<BaseT>(m_library, type, info, create);
271
+ }
272
+
273
+ /**
274
+ * \brief Register a plugin class.
275
+ * This helper assumes that the plugin class has a `create` function matching the BaseT::PluginCreate type.
276
+ *
277
+ * \tparam BaseT The plugin base class.
278
+ * \tparam T The plugin class.
279
+ */
280
+ template<typename BaseT, typename T>
281
+ void register_class()
282
+ {
283
+ register_class<BaseT>(T::k_plugin_type, T::k_plugin_info, T::create);
284
+ }
285
+
286
+ private:
287
+ PluginManager& m_plugin_manager;
288
+ SharedLibraryHandle m_library;
289
+ };
290
+
291
+ /**
292
+ * \brief Macro for extending a class to be used as a plugin base class.
293
+ *
294
+ * This macro must be applied in the class declaration of the plugin base class.
295
+ * It assumes that both a public PluginInfo struct type and a PluginCreate typedef
296
+ * are defined when invoked.
297
+ */
298
+ #define SGL_PLUGIN_BASE_CLASS(cls) \
299
+ public: \
300
+ static_assert(std::is_class_v<cls> == true); \
301
+ /* TODO: check for existance of cls::PluginCreate */ \
302
+ static_assert(std::is_class_v<cls::PluginInfo> == true); \
303
+ static const std::string& get_plugin_base_type() \
304
+ { \
305
+ static std::string type{#cls}; \
306
+ return type; \
307
+ } \
308
+ virtual const std::string& get_plugin_type() const = 0; \
309
+ virtual const PluginInfo& get_plugin_info() const = 0;
310
+
311
+ /**
312
+ * \brief Macro for extending a class to be used as a plugin class.
313
+ *
314
+ * This macro must be applied in the class declaration of the plugin class.
315
+ */
316
+ #define SGL_PLUGIN_CLASS(cls, type, info) \
317
+ public: \
318
+ static_assert(std::is_class_v<cls> == true); \
319
+ /* TODO: check inheritance of base plugin class */ \
320
+ static inline const std::string k_plugin_type{type}; \
321
+ static inline const PluginInfo k_plugin_info{info}; \
322
+ virtual const std::string& get_plugin_type() const final \
323
+ { \
324
+ return k_plugin_type; \
325
+ } \
326
+ virtual const PluginInfo& get_plugin_info() const final \
327
+ { \
328
+ return k_plugin_info; \
329
+ }
330
+
331
+ } // namespace sgl
@@ -0,0 +1,39 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include <vector>
6
+ #include <filesystem>
7
+
8
+ namespace sgl {
9
+
10
+ class Resolver {
11
+ public:
12
+ virtual ~Resolver() = default;
13
+ virtual std::filesystem::path resolve(const std::filesystem::path& path) = 0;
14
+ };
15
+
16
+ class SearchPathsResolver : public Resolver {
17
+ public:
18
+ SearchPathsResolver(std::vector<std::filesystem::path> search_paths)
19
+ : m_search_paths(std::move(search_paths))
20
+ {
21
+ }
22
+
23
+ std::filesystem::path resolve(const std::filesystem::path& path) override
24
+ {
25
+ if (!path.is_absolute()) {
26
+ for (const std::filesystem::path& search_path : m_search_paths) {
27
+ auto full_path = search_path / path;
28
+ if (std::filesystem::exists(full_path))
29
+ return full_path;
30
+ }
31
+ }
32
+ return path;
33
+ }
34
+
35
+ private:
36
+ std::vector<std::filesystem::path> m_search_paths;
37
+ };
38
+
39
+ } // namespace sgl