18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "plugin_registry.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/util/uid_util.h> 218bf80f4bSopenharmony_ci#include <core/ecs/intf_component_manager.h> 228bf80f4bSopenharmony_ci#include <core/log.h> 238bf80f4bSopenharmony_ci 248bf80f4bSopenharmony_ci#include "image/loaders/image_loader_ktx.h" 258bf80f4bSopenharmony_ci#include "image/loaders/image_loader_stb_image.h" 268bf80f4bSopenharmony_ci#include "image/loaders/image_loader_libpng.h" 278bf80f4bSopenharmony_ci#include "image/loaders/image_loader_libjpeg.h" 288bf80f4bSopenharmony_ci#include "io/file_manager.h" 298bf80f4bSopenharmony_ci#include "io/std_filesystem.h" 308bf80f4bSopenharmony_ci#include "os/intf_library.h" 318bf80f4bSopenharmony_ci#include "static_plugin_decl.h" 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE() 348bf80f4bSopenharmony_ciusing BASE_NS::array_view; 358bf80f4bSopenharmony_ciusing BASE_NS::move; 368bf80f4bSopenharmony_ciusing BASE_NS::pair; 378bf80f4bSopenharmony_ciusing BASE_NS::reverse_iterator; 388bf80f4bSopenharmony_ciusing BASE_NS::string; 398bf80f4bSopenharmony_ciusing BASE_NS::string_view; 408bf80f4bSopenharmony_ciusing BASE_NS::to_string; 418bf80f4bSopenharmony_ciusing BASE_NS::Uid; 428bf80f4bSopenharmony_ciusing BASE_NS::vector; 438bf80f4bSopenharmony_ci 448bf80f4bSopenharmony_ciIInterface* CreateFileMonitor(CORE_NS::IClassFactory& registry, CORE_NS::PluginToken token); 458bf80f4bSopenharmony_ciIInterface* GetFileApiFactory(CORE_NS::IClassRegister& registry, CORE_NS::PluginToken token); 468bf80f4bSopenharmony_ci 478bf80f4bSopenharmony_cinamespace StaticPluginRegistry { 488bf80f4bSopenharmony_ci// static_plugin_registry magic begin 498bf80f4bSopenharmony_ci#if defined(CORE_USE_COMPILER_GENERATED_STATIC_LIST) && (CORE_USE_COMPILER_GENERATED_STATIC_LIST == 1) 508bf80f4bSopenharmony_ci 518bf80f4bSopenharmony_ci#if _MSC_VER 528bf80f4bSopenharmony_ci#pragma section("spd$b", long, read) 538bf80f4bSopenharmony_ci#pragma section("spd$d", long, read) 548bf80f4bSopenharmony_ci#pragma section("spd$e", long, read) 558bf80f4bSopenharmony_ci__declspec(allocate("spd$b")) static constexpr const IPlugin* g_staticPluginList = nullptr; 568bf80f4bSopenharmony_ci__declspec(allocate("spd$e")) static constexpr const IPlugin* g_staticPluginListEnd = nullptr; 578bf80f4bSopenharmony_ci#else 588bf80f4bSopenharmony_ci// clang-format off 598bf80f4bSopenharmony_ci__asm__( 608bf80f4bSopenharmony_ci ".pushsection " SECTION(spl.1) 618bf80f4bSopenharmony_ci " .local g_staticPluginList\n" 628bf80f4bSopenharmony_ci " g_staticPluginList:\n" 638bf80f4bSopenharmony_ci ".dc.a 0x0\n" 648bf80f4bSopenharmony_ci ".section " SECTION(spl.2) 658bf80f4bSopenharmony_ci " .local g_staticPluginListData\n" 668bf80f4bSopenharmony_ci "g_staticPluginListData:\n" 678bf80f4bSopenharmony_ci " .dc.a 0x0\n" 688bf80f4bSopenharmony_ci " .section " SECTION(spl.3) 698bf80f4bSopenharmony_ci " .local g_staticPluginListEnd\n" 708bf80f4bSopenharmony_ci " g_staticPluginListEnd:\n" 718bf80f4bSopenharmony_ci ".dc.a 0x0\n" 728bf80f4bSopenharmony_ci " .popsection\n"); 738bf80f4bSopenharmony_ci// clang-format on 748bf80f4bSopenharmony_ciextern "C" { 758bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginList; 768bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginListData; 778bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginListEnd; 788bf80f4bSopenharmony_ci__attribute__((used)) CORE_NS::IPlugin const* const g_staticPluginListDataRef = g_staticPluginListData; 798bf80f4bSopenharmony_ci} 808bf80f4bSopenharmony_ci#endif 818bf80f4bSopenharmony_ci 828bf80f4bSopenharmony_ci#else 838bf80f4bSopenharmony_ci 848bf80f4bSopenharmony_ci#if _MSC_VER 858bf80f4bSopenharmony_cistatic CORE_NS::IPlugin const* const* g_staticPluginList = nullptr; 868bf80f4bSopenharmony_cistatic size_t g_staticPluginListCount = 0; 878bf80f4bSopenharmony_ci#else 888bf80f4bSopenharmony_ci__attribute__((visibility("hidden"))) static CORE_NS::IPlugin const* const* g_staticPluginList = nullptr; 898bf80f4bSopenharmony_ci__attribute__((visibility("hidden"))) static size_t g_staticPluginListCount = 0; 908bf80f4bSopenharmony_ci#endif 918bf80f4bSopenharmony_ci 928bf80f4bSopenharmony_civoid RegisterStaticPlugin(const CORE_NS::IPlugin& plugin) 938bf80f4bSopenharmony_ci{ 948bf80f4bSopenharmony_ci static BASE_NS::vector<const CORE_NS::IPlugin*> gGlobalPlugins; 958bf80f4bSopenharmony_ci gGlobalPlugins.push_back(&plugin); 968bf80f4bSopenharmony_ci g_staticPluginList = gGlobalPlugins.data(); 978bf80f4bSopenharmony_ci g_staticPluginListCount = gGlobalPlugins.size(); 988bf80f4bSopenharmony_ci} 998bf80f4bSopenharmony_ci#endif 1008bf80f4bSopenharmony_ci} // namespace StaticPluginRegistry 1018bf80f4bSopenharmony_ci 1028bf80f4bSopenharmony_cinamespace { 1038bf80f4bSopenharmony_cistruct LibPlugin { 1048bf80f4bSopenharmony_ci ILibrary::Ptr lib; 1058bf80f4bSopenharmony_ci const IPlugin* plugin; 1068bf80f4bSopenharmony_ci}; 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_citemplate<typename Container, typename Predicate> 1098bf80f4bSopenharmony_ciinline typename Container::const_iterator FindIf(const Container& container, Predicate&& predicate) 1108bf80f4bSopenharmony_ci{ 1118bf80f4bSopenharmony_ci return std::find_if(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate)); 1128bf80f4bSopenharmony_ci} 1138bf80f4bSopenharmony_ci 1148bf80f4bSopenharmony_citemplate<typename Container, typename Predicate> 1158bf80f4bSopenharmony_ciinline bool NoneOf(const Container& container, Predicate&& predicate) 1168bf80f4bSopenharmony_ci{ 1178bf80f4bSopenharmony_ci return std::none_of(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate)); 1188bf80f4bSopenharmony_ci} 1198bf80f4bSopenharmony_ci 1208bf80f4bSopenharmony_citemplate<typename Container, typename Predicate> 1218bf80f4bSopenharmony_ciinline bool AllOf(const Container& container, Predicate&& predicate) 1228bf80f4bSopenharmony_ci{ 1238bf80f4bSopenharmony_ci return std::all_of(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate)); 1248bf80f4bSopenharmony_ci} 1258bf80f4bSopenharmony_ci 1268bf80f4bSopenharmony_civoid GatherStaticPlugins(vector<LibPlugin>& plugins) 1278bf80f4bSopenharmony_ci{ 1288bf80f4bSopenharmony_ci CORE_LOG_V("Static plugins:"); 1298bf80f4bSopenharmony_ci#if defined(CORE_USE_COMPILER_GENERATED_STATIC_LIST) && (CORE_USE_COMPILER_GENERATED_STATIC_LIST == 1) 1308bf80f4bSopenharmony_ci const array_view<const IPlugin* const> staticPluginRegistry( 1318bf80f4bSopenharmony_ci &StaticPluginRegistry::g_staticPluginList, &StaticPluginRegistry::g_staticPluginListEnd); 1328bf80f4bSopenharmony_ci#else 1338bf80f4bSopenharmony_ci const array_view<const IPlugin* const> staticPluginRegistry( 1348bf80f4bSopenharmony_ci StaticPluginRegistry::g_staticPluginList, StaticPluginRegistry::g_staticPluginListCount); 1358bf80f4bSopenharmony_ci#endif 1368bf80f4bSopenharmony_ci 1378bf80f4bSopenharmony_ci for (const auto plugin : staticPluginRegistry) { 1388bf80f4bSopenharmony_ci if (plugin && (plugin->typeUid == IPlugin::UID)) { 1398bf80f4bSopenharmony_ci CORE_LOG_V("\t%s", plugin->name); 1408bf80f4bSopenharmony_ci plugins.push_back({ nullptr, plugin }); 1418bf80f4bSopenharmony_ci } 1428bf80f4bSopenharmony_ci } 1438bf80f4bSopenharmony_ci} 1448bf80f4bSopenharmony_ci 1458bf80f4bSopenharmony_civoid GatherDynamicPlugins(vector<LibPlugin>& plugins, IFileManager& fileManager) 1468bf80f4bSopenharmony_ci{ 1478bf80f4bSopenharmony_ci CORE_LOG_V("Dynamic plugins:"); 1488bf80f4bSopenharmony_ci const auto libraryFileExtension = ILibrary::GetFileExtension(); 1498bf80f4bSopenharmony_ci constexpr string_view pluginRoot { "plugins://" }; 1508bf80f4bSopenharmony_ci if (IDirectory::Ptr pluginFiles = fileManager.OpenDirectory(pluginRoot); pluginFiles) { 1518bf80f4bSopenharmony_ci for (const auto& file : pluginFiles->GetEntries()) { 1528bf80f4bSopenharmony_ci const string_view pluginFile = file.name; 1538bf80f4bSopenharmony_ci if (pluginFile.ends_with(libraryFileExtension)) { 1548bf80f4bSopenharmony_ci const string absoluteFile = fileManager.GetEntry(pluginRoot + file.name).name; 1558bf80f4bSopenharmony_ci if (ILibrary::Ptr lib = ILibrary::Load(absoluteFile); lib) { 1568bf80f4bSopenharmony_ci const IPlugin* plugin = lib->GetPlugin(); 1578bf80f4bSopenharmony_ci if (plugin && (plugin->typeUid == IPlugin::UID)) { 1588bf80f4bSopenharmony_ci CORE_LOG_V("\t%s", plugin->name); 1598bf80f4bSopenharmony_ci plugins.push_back({ move(lib), plugin }); 1608bf80f4bSopenharmony_ci } 1618bf80f4bSopenharmony_ci } 1628bf80f4bSopenharmony_ci } 1638bf80f4bSopenharmony_ci } 1648bf80f4bSopenharmony_ci } 1658bf80f4bSopenharmony_ci} 1668bf80f4bSopenharmony_ci 1678bf80f4bSopenharmony_civoid Notify(const array_view<IPluginRegister::ITypeInfoListener*> listeners, 1688bf80f4bSopenharmony_ci IPluginRegister::ITypeInfoListener::EventType type, array_view<const ITypeInfo* const> typeInfos) 1698bf80f4bSopenharmony_ci{ 1708bf80f4bSopenharmony_ci for (IPluginRegister::ITypeInfoListener* listener : listeners) { 1718bf80f4bSopenharmony_ci if (listener) { 1728bf80f4bSopenharmony_ci listener->OnTypeInfoEvent(type, typeInfos); 1738bf80f4bSopenharmony_ci } 1748bf80f4bSopenharmony_ci } 1758bf80f4bSopenharmony_ci} 1768bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo KTX_LOADER { 1778bf80f4bSopenharmony_ci { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID }, 1788bf80f4bSopenharmony_ci nullptr, 1798bf80f4bSopenharmony_ci BASE_NS::Uid { "306357a4-d49c-4670-9746-5ccbba567dc9" }, 1808bf80f4bSopenharmony_ci CreateImageLoaderKtx, 1818bf80f4bSopenharmony_ci KTX_IMAGE_TYPES, 1828bf80f4bSopenharmony_ci}; 1838bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo STB_LOADER { 1848bf80f4bSopenharmony_ci { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID }, 1858bf80f4bSopenharmony_ci nullptr, 1868bf80f4bSopenharmony_ci BASE_NS::Uid { "a5049cb8-10bb-4047-b7f5-e9939d5bb3a5" }, 1878bf80f4bSopenharmony_ci CreateImageLoaderStbImage, 1888bf80f4bSopenharmony_ci STB_IMAGE_TYPES, 1898bf80f4bSopenharmony_ci}; 1908bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo PNG_LOADER { 1918bf80f4bSopenharmony_ci { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID }, 1928bf80f4bSopenharmony_ci nullptr, 1938bf80f4bSopenharmony_ci BASE_NS::Uid { "dacbcb8d-60d6-4337-8295-7af99b517c1d" }, 1948bf80f4bSopenharmony_ci CreateImageLoaderLibPNGImage, 1958bf80f4bSopenharmony_ci PNG_IMAGE_TYPES, 1968bf80f4bSopenharmony_ci}; 1978bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo JPEG_LOADER { 1988bf80f4bSopenharmony_ci { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID }, 1998bf80f4bSopenharmony_ci nullptr, 2008bf80f4bSopenharmony_ci BASE_NS::Uid { "c5fb2284-561f-4078-8a00-74b82f161964" }, 2018bf80f4bSopenharmony_ci CreateImageLoaderLibJPEGImage, 2028bf80f4bSopenharmony_ci JPEG_IMAGE_TYPES, 2038bf80f4bSopenharmony_ci}; 2048bf80f4bSopenharmony_ci} // namespace 2058bf80f4bSopenharmony_ci 2068bf80f4bSopenharmony_civector<InterfaceTypeInfo> PluginRegistry::RegisterGlobalInterfaces(PluginRegistry& registry) 2078bf80f4bSopenharmony_ci{ 2088bf80f4bSopenharmony_ci vector<InterfaceTypeInfo> interfaces = { 2098bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_LOGGER, GetName<ILogger>().data(), nullptr, 2108bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2118bf80f4bSopenharmony_ci return &static_cast<PluginRegistry*>(token)->logger_; 2128bf80f4bSopenharmony_ci } }, 2138bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_FRUSTUM_UTIL, GetName<IFrustumUtil>().data(), nullptr, 2148bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2158bf80f4bSopenharmony_ci return &static_cast<PluginRegistry*>(token)->frustumUtil_; 2168bf80f4bSopenharmony_ci } }, 2178bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_ENGINE_FACTORY, GetName<IEngineFactory>().data(), nullptr, 2188bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2198bf80f4bSopenharmony_ci return static_cast<PluginRegistry*>(token)->engineFactory_.GetInterface(IEngineFactory::UID); 2208bf80f4bSopenharmony_ci } }, 2218bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_SYSTEM_GRAPH_LOADER, GetName<ISystemGraphLoaderFactory>().data(), nullptr, 2228bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2238bf80f4bSopenharmony_ci return &static_cast<PluginRegistry*>(token)->systemGraphLoadeFactory; 2248bf80f4bSopenharmony_ci } }, 2258bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_GLOBAL_FACTORY, "Global registry factory", nullptr, 2268bf80f4bSopenharmony_ci [](IClassRegister& registry, PluginToken /* token */) -> IInterface* { 2278bf80f4bSopenharmony_ci return registry.GetInterface<IClassFactory>(); 2288bf80f4bSopenharmony_ci } }, 2298bf80f4bSopenharmony_ci InterfaceTypeInfo { 2308bf80f4bSopenharmony_ci ®istry, UID_FILESYSTEM_API_FACTORY, "Filesystem API factory", nullptr, GetFileApiFactory }, 2318bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_FILE_MONITOR, "Filemonitor", CreateFileMonitor, nullptr }, 2328bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_FILE_MANAGER, "FileManager", 2338bf80f4bSopenharmony_ci [](IClassFactory& /* factory */, PluginToken /* token */) -> IInterface* { 2348bf80f4bSopenharmony_ci return new CORE_NS::FileManager(); 2358bf80f4bSopenharmony_ci }, 2368bf80f4bSopenharmony_ci nullptr }, 2378bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_TASK_QUEUE_FACTORY, "Task queue factory", nullptr, 2388bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2398bf80f4bSopenharmony_ci return &static_cast<PluginRegistry*>(token)->taskQueueFactory_; 2408bf80f4bSopenharmony_ci } }, 2418bf80f4bSopenharmony_ci#if (CORE_PERF_ENABLED == 1) 2428bf80f4bSopenharmony_ci InterfaceTypeInfo { ®istry, UID_PERFORMANCE_FACTORY, GetName<IPerformanceDataManagerFactory>().data(), 2438bf80f4bSopenharmony_ci nullptr, 2448bf80f4bSopenharmony_ci [](IClassRegister& /* registry */, PluginToken token) -> IInterface* { 2458bf80f4bSopenharmony_ci return &static_cast<PluginRegistry*>(token)->perfManFactory_; 2468bf80f4bSopenharmony_ci } } 2478bf80f4bSopenharmony_ci#endif 2488bf80f4bSopenharmony_ci }; 2498bf80f4bSopenharmony_ci 2508bf80f4bSopenharmony_ci for (const auto& info : interfaces) { 2518bf80f4bSopenharmony_ci registry.RegisterInterfaceType(info); 2528bf80f4bSopenharmony_ci } 2538bf80f4bSopenharmony_ci registry.RegisterTypeInfo(KTX_LOADER); 2548bf80f4bSopenharmony_ci registry.RegisterTypeInfo(STB_LOADER); 2558bf80f4bSopenharmony_ci registry.RegisterTypeInfo(PNG_LOADER); 2568bf80f4bSopenharmony_ci registry.RegisterTypeInfo(JPEG_LOADER); 2578bf80f4bSopenharmony_ci return interfaces; 2588bf80f4bSopenharmony_ci} 2598bf80f4bSopenharmony_ci 2608bf80f4bSopenharmony_civoid PluginRegistry::UnregisterGlobalInterfaces() 2618bf80f4bSopenharmony_ci{ 2628bf80f4bSopenharmony_ci UnregisterTypeInfo(STB_LOADER); 2638bf80f4bSopenharmony_ci UnregisterTypeInfo(KTX_LOADER); 2648bf80f4bSopenharmony_ci UnregisterTypeInfo(PNG_LOADER); 2658bf80f4bSopenharmony_ci UnregisterTypeInfo(JPEG_LOADER); 2668bf80f4bSopenharmony_ci for (const auto& info : ownInterfaceInfos_) { 2678bf80f4bSopenharmony_ci UnregisterInterfaceType(info); 2688bf80f4bSopenharmony_ci } 2698bf80f4bSopenharmony_ci} 2708bf80f4bSopenharmony_ci 2718bf80f4bSopenharmony_ciPluginRegistry::PluginRegistry() 2728bf80f4bSopenharmony_ci{ 2738bf80f4bSopenharmony_ci ownInterfaceInfos_ = RegisterGlobalInterfaces(*this); 2748bf80f4bSopenharmony_ci} 2758bf80f4bSopenharmony_ci 2768bf80f4bSopenharmony_ciPluginRegistry::~PluginRegistry() 2778bf80f4bSopenharmony_ci{ 2788bf80f4bSopenharmony_ci UnloadPlugins({}); 2798bf80f4bSopenharmony_ci UnregisterGlobalInterfaces(); 2808bf80f4bSopenharmony_ci} 2818bf80f4bSopenharmony_ci 2828bf80f4bSopenharmony_ci// IPluginRegister 2838bf80f4bSopenharmony_ciarray_view<const IPlugin* const> PluginRegistry::GetPlugins() const 2848bf80f4bSopenharmony_ci{ 2858bf80f4bSopenharmony_ci return plugins_; 2868bf80f4bSopenharmony_ci} 2878bf80f4bSopenharmony_ci 2888bf80f4bSopenharmony_cibool PluginRegistry::LoadPlugins(const array_view<const Uid> pluginUids) 2898bf80f4bSopenharmony_ci{ 2908bf80f4bSopenharmony_ci // Gather all the available static and dynamic libraries. 2918bf80f4bSopenharmony_ci vector<LibPlugin> plugins; 2928bf80f4bSopenharmony_ci GatherStaticPlugins(plugins); 2938bf80f4bSopenharmony_ci GatherDynamicPlugins(plugins, fileManager_); 2948bf80f4bSopenharmony_ci 2958bf80f4bSopenharmony_ci // If a list of UIDs was given remove all except the requires plugins. 2968bf80f4bSopenharmony_ci if (!pluginUids.empty()) { 2978bf80f4bSopenharmony_ci // Gather dependencies of each plugin. 2988bf80f4bSopenharmony_ci vector<Uid> toLoad; 2998bf80f4bSopenharmony_ci toLoad.reserve(plugins.size()); 3008bf80f4bSopenharmony_ci 3018bf80f4bSopenharmony_ci auto addDependencies = [](auto&& addDependencies, vector<Uid>& toBeLoaded, 3028bf80f4bSopenharmony_ci const vector<LibPlugin>& availablePlugins, 3038bf80f4bSopenharmony_ci BASE_NS::vector<const IPlugin*>& loadedPlugins, const Uid& uidToLoad) -> bool { 3048bf80f4bSopenharmony_ci bool found = true; 3058bf80f4bSopenharmony_ci // Only consider plugins which are not already loaded, and not yet in the loading list. 3068bf80f4bSopenharmony_ci if (NoneOf( 3078bf80f4bSopenharmony_ci loadedPlugins, [&uidToLoad](const IPlugin* loaded) { return loaded->version.uid == uidToLoad; }) && 3088bf80f4bSopenharmony_ci NoneOf(toBeLoaded, [&uidToLoad](const Uid& willLoad) { return willLoad == uidToLoad; })) { 3098bf80f4bSopenharmony_ci if (auto pos = FindIf(availablePlugins, 3108bf80f4bSopenharmony_ci [&uidToLoad]( 3118bf80f4bSopenharmony_ci const LibPlugin& libPlugin) { return libPlugin.plugin->version.uid == uidToLoad; }); 3128bf80f4bSopenharmony_ci pos != availablePlugins.end()) { 3138bf80f4bSopenharmony_ci found = AllOf(pos->plugin->pluginDependencies, [&](const Uid& dependency) { 3148bf80f4bSopenharmony_ci return addDependencies( 3158bf80f4bSopenharmony_ci addDependencies, toBeLoaded, availablePlugins, loadedPlugins, dependency); 3168bf80f4bSopenharmony_ci }); 3178bf80f4bSopenharmony_ci if (found) { 3188bf80f4bSopenharmony_ci toBeLoaded.push_back(uidToLoad); 3198bf80f4bSopenharmony_ci } else { 3208bf80f4bSopenharmony_ci CORE_LOG_E("Missing dependencies for: %s", to_string(uidToLoad).data()); 3218bf80f4bSopenharmony_ci } 3228bf80f4bSopenharmony_ci } else { 3238bf80f4bSopenharmony_ci CORE_LOG_E("Plugin not found: %s", to_string(uidToLoad).data()); 3248bf80f4bSopenharmony_ci found = false; 3258bf80f4bSopenharmony_ci } 3268bf80f4bSopenharmony_ci } 3278bf80f4bSopenharmony_ci return found; 3288bf80f4bSopenharmony_ci }; 3298bf80f4bSopenharmony_ci const bool found = AllOf(pluginUids, 3308bf80f4bSopenharmony_ci [&](const Uid& uid) { return addDependencies(addDependencies, toLoad, plugins, plugins_, uid); }); 3318bf80f4bSopenharmony_ci 3328bf80f4bSopenharmony_ci // Order the available plugins to match the to-be-loaded list and remove extras. 3338bf80f4bSopenharmony_ci auto begin = plugins.begin(); 3348bf80f4bSopenharmony_ci auto end = plugins.end(); 3358bf80f4bSopenharmony_ci for (const Uid& uid : toLoad) { 3368bf80f4bSopenharmony_ci if (auto pos = std::find_if( 3378bf80f4bSopenharmony_ci begin, end, [uid](const LibPlugin& libPlugin) { return libPlugin.plugin->version.uid == uid; }); 3388bf80f4bSopenharmony_ci pos != end) { 3398bf80f4bSopenharmony_ci std::rotate(begin, pos, end); 3408bf80f4bSopenharmony_ci ++begin; 3418bf80f4bSopenharmony_ci } 3428bf80f4bSopenharmony_ci } 3438bf80f4bSopenharmony_ci plugins.erase(begin, end); 3448bf80f4bSopenharmony_ci 3458bf80f4bSopenharmony_ci if (!found) { 3468bf80f4bSopenharmony_ci CORE_LOG_E("Unable to load plugins:"); 3478bf80f4bSopenharmony_ci for (const auto& uid : pluginUids) { 3488bf80f4bSopenharmony_ci if (NoneOf(plugins, [uid](const auto& available) { return available.plugin->version.uid == uid; })) { 3498bf80f4bSopenharmony_ci CORE_LOG_E("\t%s", to_string(uid).data()); 3508bf80f4bSopenharmony_ci } 3518bf80f4bSopenharmony_ci } 3528bf80f4bSopenharmony_ci return false; 3538bf80f4bSopenharmony_ci } 3548bf80f4bSopenharmony_ci } 3558bf80f4bSopenharmony_ci 3568bf80f4bSopenharmony_ci // Now we should have only the desired plugins and can load all of them. 3578bf80f4bSopenharmony_ci CORE_LOG_D("Load plugins:"); 3588bf80f4bSopenharmony_ci loading_ = true; 3598bf80f4bSopenharmony_ci for (auto& plugin : plugins) { 3608bf80f4bSopenharmony_ci RegisterPlugin(move(plugin.lib), *plugin.plugin, 3618bf80f4bSopenharmony_ci NoneOf(pluginUids, 3628bf80f4bSopenharmony_ci [&loading = (plugin.plugin->version.uid)](const Uid& userRequest) { return userRequest == loading; })); 3638bf80f4bSopenharmony_ci } 3648bf80f4bSopenharmony_ci loading_ = false; 3658bf80f4bSopenharmony_ci 3668bf80f4bSopenharmony_ci if (!newTypeInfos_.empty()) { 3678bf80f4bSopenharmony_ci Notify(typeInfoListeners_, ITypeInfoListener::EventType::ADDED, newTypeInfos_); 3688bf80f4bSopenharmony_ci newTypeInfos_.clear(); 3698bf80f4bSopenharmony_ci } 3708bf80f4bSopenharmony_ci 3718bf80f4bSopenharmony_ci return true; 3728bf80f4bSopenharmony_ci} 3738bf80f4bSopenharmony_ci 3748bf80f4bSopenharmony_civoid PluginRegistry::UnloadPlugins(const array_view<const Uid> pluginUids) 3758bf80f4bSopenharmony_ci{ 3768bf80f4bSopenharmony_ci CORE_LOG_D("Unload plugins:"); 3778bf80f4bSopenharmony_ci if (pluginUids.empty()) { 3788bf80f4bSopenharmony_ci while (!pluginDatas_.empty() && !plugins_.empty()) { 3798bf80f4bSopenharmony_ci UnregisterPlugin(*plugins_.back(), pluginDatas_.back().token); 3808bf80f4bSopenharmony_ci plugins_.pop_back(); 3818bf80f4bSopenharmony_ci pluginDatas_.pop_back(); 3828bf80f4bSopenharmony_ci } 3838bf80f4bSopenharmony_ci plugins_.clear(); 3848bf80f4bSopenharmony_ci pluginDatas_.clear(); 3858bf80f4bSopenharmony_ci } else { 3868bf80f4bSopenharmony_ci [](array_view<const IPlugin*> plugins, array_view<PluginData> pluginDatas, 3878bf80f4bSopenharmony_ci const array_view<const Uid>& pluginUids) { 3888bf80f4bSopenharmony_ci auto recurse = [](const array_view<const IPlugin*>& plugins, array_view<PluginData>& pluginDatas, 3898bf80f4bSopenharmony_ci const array_view<const Uid>& pluginUids, auto& recurseRef) -> void { 3908bf80f4bSopenharmony_ci for (const auto& uid : pluginUids) { 3918bf80f4bSopenharmony_ci if (auto pos = std::find_if(plugins.begin(), plugins.end(), 3928bf80f4bSopenharmony_ci [uid](const IPlugin* pl) { return pl && pl->version.uid == uid; }); 3938bf80f4bSopenharmony_ci pos != plugins.end()) { 3948bf80f4bSopenharmony_ci const auto index = static_cast<size_t>(std::distance(plugins.begin(), pos)); 3958bf80f4bSopenharmony_ci if (--pluginDatas[index].refcnt <= 0) { 3968bf80f4bSopenharmony_ci recurseRef(plugins, pluginDatas, (*pos)->pluginDependencies, recurseRef); 3978bf80f4bSopenharmony_ci } 3988bf80f4bSopenharmony_ci } 3998bf80f4bSopenharmony_ci } 4008bf80f4bSopenharmony_ci }; 4018bf80f4bSopenharmony_ci recurse(plugins, pluginDatas, pluginUids, recurse); 4028bf80f4bSopenharmony_ci }(plugins_, pluginDatas_, pluginUids); 4038bf80f4bSopenharmony_ci 4048bf80f4bSopenharmony_ci auto pdIt = pluginDatas_.crbegin(); 4058bf80f4bSopenharmony_ci for (auto pos = plugins_.crbegin(), last = plugins_.crend(); pos != last;) { 4068bf80f4bSopenharmony_ci if (pdIt->refcnt <= 0) { 4078bf80f4bSopenharmony_ci UnregisterPlugin(*(*pos), pdIt->token); 4088bf80f4bSopenharmony_ci plugins_.erase(pos.base() - 1); 4098bf80f4bSopenharmony_ci pluginDatas_.erase(pdIt.base() - 1); 4108bf80f4bSopenharmony_ci } 4118bf80f4bSopenharmony_ci ++pos; 4128bf80f4bSopenharmony_ci ++pdIt; 4138bf80f4bSopenharmony_ci } 4148bf80f4bSopenharmony_ci } 4158bf80f4bSopenharmony_ci} 4168bf80f4bSopenharmony_ci 4178bf80f4bSopenharmony_ciIClassRegister& PluginRegistry::GetClassRegister() const 4188bf80f4bSopenharmony_ci{ 4198bf80f4bSopenharmony_ci return *const_cast<PluginRegistry*>(this); 4208bf80f4bSopenharmony_ci} 4218bf80f4bSopenharmony_ci 4228bf80f4bSopenharmony_civoid PluginRegistry::RegisterTypeInfo(const ITypeInfo& type) 4238bf80f4bSopenharmony_ci{ 4248bf80f4bSopenharmony_ci if (const auto pos = typeInfos_.find(type.typeUid); pos != typeInfos_.cend()) { 4258bf80f4bSopenharmony_ci pos->second.push_back(&type); 4268bf80f4bSopenharmony_ci } else { 4278bf80f4bSopenharmony_ci typeInfos_.insert({ type.typeUid, {} }).first->second.push_back(&type); 4288bf80f4bSopenharmony_ci } 4298bf80f4bSopenharmony_ci 4308bf80f4bSopenharmony_ci // During plugin loading gather all the infos and send events once. 4318bf80f4bSopenharmony_ci if (loading_) { 4328bf80f4bSopenharmony_ci newTypeInfos_.push_back(&type); 4338bf80f4bSopenharmony_ci } else { 4348bf80f4bSopenharmony_ci const ITypeInfo* const infos[] = { &type }; 4358bf80f4bSopenharmony_ci Notify(typeInfoListeners_, ITypeInfoListener::EventType::ADDED, infos); 4368bf80f4bSopenharmony_ci } 4378bf80f4bSopenharmony_ci} 4388bf80f4bSopenharmony_ci 4398bf80f4bSopenharmony_civoid PluginRegistry::UnregisterTypeInfo(const ITypeInfo& type) 4408bf80f4bSopenharmony_ci{ 4418bf80f4bSopenharmony_ci if (const auto typeInfos = typeInfos_.find(type.typeUid); typeInfos != typeInfos_.cend()) { 4428bf80f4bSopenharmony_ci auto& infos = typeInfos->second; 4438bf80f4bSopenharmony_ci if (const auto info = std::find(infos.cbegin(), infos.cend(), &type); info != infos.cend()) { 4448bf80f4bSopenharmony_ci infos.erase(info); 4458bf80f4bSopenharmony_ci } 4468bf80f4bSopenharmony_ci } 4478bf80f4bSopenharmony_ci 4488bf80f4bSopenharmony_ci const ITypeInfo* const infos[] = { &type }; 4498bf80f4bSopenharmony_ci Notify(typeInfoListeners_, ITypeInfoListener::EventType::REMOVED, infos); 4508bf80f4bSopenharmony_ci} 4518bf80f4bSopenharmony_ci 4528bf80f4bSopenharmony_ciarray_view<const ITypeInfo* const> PluginRegistry::GetTypeInfos(const Uid& typeUid) const 4538bf80f4bSopenharmony_ci{ 4548bf80f4bSopenharmony_ci if (const auto typeInfos = typeInfos_.find(typeUid); typeInfos != typeInfos_.cend()) { 4558bf80f4bSopenharmony_ci return typeInfos->second; 4568bf80f4bSopenharmony_ci } 4578bf80f4bSopenharmony_ci return {}; 4588bf80f4bSopenharmony_ci} 4598bf80f4bSopenharmony_ci 4608bf80f4bSopenharmony_civoid PluginRegistry::AddListener(ITypeInfoListener& listener) 4618bf80f4bSopenharmony_ci{ 4628bf80f4bSopenharmony_ci if (std::none_of(typeInfoListeners_.begin(), typeInfoListeners_.end(), 4638bf80f4bSopenharmony_ci [adding = &listener](const auto& current) { return current == adding; })) { 4648bf80f4bSopenharmony_ci typeInfoListeners_.push_back(&listener); 4658bf80f4bSopenharmony_ci } 4668bf80f4bSopenharmony_ci} 4678bf80f4bSopenharmony_ci 4688bf80f4bSopenharmony_civoid PluginRegistry::RemoveListener(const ITypeInfoListener& listener) 4698bf80f4bSopenharmony_ci{ 4708bf80f4bSopenharmony_ci if (auto pos = std::find(typeInfoListeners_.begin(), typeInfoListeners_.end(), &listener); 4718bf80f4bSopenharmony_ci pos != typeInfoListeners_.end()) { 4728bf80f4bSopenharmony_ci *pos = nullptr; 4738bf80f4bSopenharmony_ci } 4748bf80f4bSopenharmony_ci} 4758bf80f4bSopenharmony_ci 4768bf80f4bSopenharmony_ci// IClassRegister 4778bf80f4bSopenharmony_civoid PluginRegistry::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 4788bf80f4bSopenharmony_ci{ 4798bf80f4bSopenharmony_ci // keep interfaceTypeInfos_ sorted according to UIDs 4808bf80f4bSopenharmony_ci const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 4818bf80f4bSopenharmony_ci [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; }); 4828bf80f4bSopenharmony_ci interfaceTypeInfos_.insert(pos, &interfaceInfo); 4838bf80f4bSopenharmony_ci} 4848bf80f4bSopenharmony_ci 4858bf80f4bSopenharmony_civoid PluginRegistry::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 4868bf80f4bSopenharmony_ci{ 4878bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 4888bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 4898bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 4908bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == interfaceInfo.uid) { 4918bf80f4bSopenharmony_ci interfaceTypeInfos_.erase(pos); 4928bf80f4bSopenharmony_ci } 4938bf80f4bSopenharmony_ci } 4948bf80f4bSopenharmony_ci} 4958bf80f4bSopenharmony_ci 4968bf80f4bSopenharmony_ciarray_view<const InterfaceTypeInfo* const> PluginRegistry::GetInterfaceMetadata() const 4978bf80f4bSopenharmony_ci{ 4988bf80f4bSopenharmony_ci return { interfaceTypeInfos_.data(), interfaceTypeInfos_.size() }; 4998bf80f4bSopenharmony_ci} 5008bf80f4bSopenharmony_ci 5018bf80f4bSopenharmony_ciconst InterfaceTypeInfo& PluginRegistry::GetInterfaceMetadata(const Uid& uid) const 5028bf80f4bSopenharmony_ci{ 5038bf80f4bSopenharmony_ci static constexpr InterfaceTypeInfo invalidType {}; 5048bf80f4bSopenharmony_ci 5058bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 5068bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid, 5078bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 5088bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == uid) { 5098bf80f4bSopenharmony_ci return *(*pos); 5108bf80f4bSopenharmony_ci } 5118bf80f4bSopenharmony_ci } 5128bf80f4bSopenharmony_ci return invalidType; 5138bf80f4bSopenharmony_ci} 5148bf80f4bSopenharmony_ci 5158bf80f4bSopenharmony_ciIInterface* PluginRegistry::GetInstance(const Uid& uid) const 5168bf80f4bSopenharmony_ci{ 5178bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 5188bf80f4bSopenharmony_ci if (data.getInterface) { 5198bf80f4bSopenharmony_ci return data.getInterface(const_cast<PluginRegistry&>(*this), data.token); 5208bf80f4bSopenharmony_ci } 5218bf80f4bSopenharmony_ci return nullptr; 5228bf80f4bSopenharmony_ci} 5238bf80f4bSopenharmony_ci 5248bf80f4bSopenharmony_ci// IClassFactory 5258bf80f4bSopenharmony_ciIInterface::Ptr PluginRegistry::CreateInstance(const Uid& uid) 5268bf80f4bSopenharmony_ci{ 5278bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 5288bf80f4bSopenharmony_ci if (data.createInterface) { 5298bf80f4bSopenharmony_ci return IInterface::Ptr { data.createInterface(*this, data.token) }; 5308bf80f4bSopenharmony_ci } 5318bf80f4bSopenharmony_ci return {}; 5328bf80f4bSopenharmony_ci} 5338bf80f4bSopenharmony_ci 5348bf80f4bSopenharmony_ci// IInterface 5358bf80f4bSopenharmony_ciconst IInterface* PluginRegistry::GetInterface(const Uid& uid) const 5368bf80f4bSopenharmony_ci{ 5378bf80f4bSopenharmony_ci return const_cast<PluginRegistry*>(this)->GetInterface(uid); 5388bf80f4bSopenharmony_ci} 5398bf80f4bSopenharmony_ci 5408bf80f4bSopenharmony_ciIInterface* PluginRegistry::GetInterface(const Uid& uid) 5418bf80f4bSopenharmony_ci{ 5428bf80f4bSopenharmony_ci if ((uid == IInterface::UID) || (uid == IClassRegister::UID)) { 5438bf80f4bSopenharmony_ci return static_cast<IClassRegister*>(this); 5448bf80f4bSopenharmony_ci } 5458bf80f4bSopenharmony_ci if (uid == IClassFactory::UID) { 5468bf80f4bSopenharmony_ci return static_cast<IClassFactory*>(this); 5478bf80f4bSopenharmony_ci } 5488bf80f4bSopenharmony_ci return nullptr; 5498bf80f4bSopenharmony_ci} 5508bf80f4bSopenharmony_ci 5518bf80f4bSopenharmony_civoid PluginRegistry::Ref() {} 5528bf80f4bSopenharmony_ci 5538bf80f4bSopenharmony_civoid PluginRegistry::Unref() {} 5548bf80f4bSopenharmony_ci 5558bf80f4bSopenharmony_ci// Public members 5568bf80f4bSopenharmony_civoid PluginRegistry::RegisterPluginPath(const string_view path) 5578bf80f4bSopenharmony_ci{ 5588bf80f4bSopenharmony_ci if (!fileProtocolRegistered_) { 5598bf80f4bSopenharmony_ci fileProtocolRegistered_ = true; 5608bf80f4bSopenharmony_ci fileManager_.RegisterFilesystem("file", IFilesystem::Ptr { new StdFilesystem("/") }); 5618bf80f4bSopenharmony_ci } 5628bf80f4bSopenharmony_ci fileManager_.RegisterPath("plugins", path, false); 5638bf80f4bSopenharmony_ci} 5648bf80f4bSopenharmony_ci 5658bf80f4bSopenharmony_ciIFileManager& PluginRegistry::GetFileManager() 5668bf80f4bSopenharmony_ci{ 5678bf80f4bSopenharmony_ci return fileManager_; 5688bf80f4bSopenharmony_ci} 5698bf80f4bSopenharmony_ci 5708bf80f4bSopenharmony_ci// Private members 5718bf80f4bSopenharmony_civoid PluginRegistry::RegisterPlugin(ILibrary::Ptr lib, const IPlugin& plugin, bool asDependency) 5728bf80f4bSopenharmony_ci{ 5738bf80f4bSopenharmony_ci CORE_LOG_D("\tRegister Plugin: %s %s", plugin.name, to_string(plugin.version.uid).data()); 5748bf80f4bSopenharmony_ci if (plugin.version.GetVersionString) { 5758bf80f4bSopenharmony_ci CORE_LOG_D("\tVersion Info: %s", plugin.version.GetVersionString()); 5768bf80f4bSopenharmony_ci } 5778bf80f4bSopenharmony_ci if (std::any_of(plugins_.begin(), plugins_.end(), 5788bf80f4bSopenharmony_ci [&plugin](const IPlugin* pl) { return strcmp(plugin.name, pl->name) == 0; })) { 5798bf80f4bSopenharmony_ci CORE_LOG_W("\tSkipping duplicate plugin: %s!", plugin.name); 5808bf80f4bSopenharmony_ci return; 5818bf80f4bSopenharmony_ci } 5828bf80f4bSopenharmony_ci // when a plugin is loaded/ registered due a requested plugin depends on it ref count starts from zero and it's 5838bf80f4bSopenharmony_ci // expected that some following plugin will place a reference. once that plugin releases its reference the 5848bf80f4bSopenharmony_ci // dependency is known to be a candidate for unloading. 5858bf80f4bSopenharmony_ci PluginData pd { move(lib), {}, asDependency ? 0 : 1 }; 5868bf80f4bSopenharmony_ci if (plugin.registerInterfaces) { 5878bf80f4bSopenharmony_ci pd.token = plugin.registerInterfaces(*static_cast<IPluginRegister*>(this)); 5888bf80f4bSopenharmony_ci } 5898bf80f4bSopenharmony_ci 5908bf80f4bSopenharmony_ci pluginDatas_.push_back(move(pd)); 5918bf80f4bSopenharmony_ci plugins_.push_back(&plugin); 5928bf80f4bSopenharmony_ci for (const auto& dependency : plugin.pluginDependencies) { 5938bf80f4bSopenharmony_ci if (auto pos = std::find_if(plugins_.begin(), plugins_.end(), 5948bf80f4bSopenharmony_ci [dependency](const IPlugin* plugin) { return plugin->version.uid == dependency; }); 5958bf80f4bSopenharmony_ci pos != plugins_.end()) { 5968bf80f4bSopenharmony_ci const auto index = static_cast<size_t>(std::distance(plugins_.begin(), pos)); 5978bf80f4bSopenharmony_ci ++pluginDatas_[index].refcnt; 5988bf80f4bSopenharmony_ci } 5998bf80f4bSopenharmony_ci } 6008bf80f4bSopenharmony_ci} 6018bf80f4bSopenharmony_ci 6028bf80f4bSopenharmony_civoid PluginRegistry::UnregisterPlugin(const IPlugin& plugin, PluginToken token) 6038bf80f4bSopenharmony_ci{ 6048bf80f4bSopenharmony_ci CORE_LOG_D("\tUnregister Plugin: %s %s", plugin.name, to_string(plugin.version.uid).data()); 6058bf80f4bSopenharmony_ci 6068bf80f4bSopenharmony_ci if (plugin.unregisterInterfaces) { 6078bf80f4bSopenharmony_ci plugin.unregisterInterfaces(token); 6088bf80f4bSopenharmony_ci } 6098bf80f4bSopenharmony_ci} 6108bf80f4bSopenharmony_ci 6118bf80f4bSopenharmony_ci// Library exports 6128bf80f4bSopenharmony_ciCORE_PUBLIC IPluginRegister& GetPluginRegister() 6138bf80f4bSopenharmony_ci{ 6148bf80f4bSopenharmony_ci static PluginRegistry registry; 6158bf80f4bSopenharmony_ci return registry; 6168bf80f4bSopenharmony_ci} 6178bf80f4bSopenharmony_ci 6188bf80f4bSopenharmony_ciCORE_PUBLIC void CreatePluginRegistry(const PlatformCreateInfo& platformCreateInfo) 6198bf80f4bSopenharmony_ci{ 6208bf80f4bSopenharmony_ci static bool once = false; 6218bf80f4bSopenharmony_ci if (!once) { 6228bf80f4bSopenharmony_ci once = true; 6238bf80f4bSopenharmony_ci auto& registry = static_cast<PluginRegistry&>(GetPluginRegister()); 6248bf80f4bSopenharmony_ci // Create plugins:// protocol that points to plugin files. 6258bf80f4bSopenharmony_ci // register path to system plugins 6268bf80f4bSopenharmony_ci // Root path is the location where system plugins , non-rofs assets etc could be held. 6278bf80f4bSopenharmony_ci auto platform = Platform::Create(platformCreateInfo); 6288bf80f4bSopenharmony_ci platform->RegisterPluginLocations(registry); 6298bf80f4bSopenharmony_ci } 6308bf80f4bSopenharmony_ci} 6318bf80f4bSopenharmony_ciCORE_END_NAMESPACE() 632