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 "engine.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci#include <chrono> 208bf80f4bSopenharmony_ci#include <cstring> 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ci#include <base/containers/array_view.h> 238bf80f4bSopenharmony_ci#include <base/containers/iterator.h> 248bf80f4bSopenharmony_ci#include <base/containers/refcnt_ptr.h> 258bf80f4bSopenharmony_ci#include <base/containers/string.h> 268bf80f4bSopenharmony_ci#include <base/containers/string_view.h> 278bf80f4bSopenharmony_ci#include <base/containers/type_traits.h> 288bf80f4bSopenharmony_ci#include <base/containers/unique_ptr.h> 298bf80f4bSopenharmony_ci#include <base/containers/unordered_map.h> 308bf80f4bSopenharmony_ci#include <base/containers/vector.h> 318bf80f4bSopenharmony_ci#include <base/namespace.h> 328bf80f4bSopenharmony_ci#include <base/util/uid.h> 338bf80f4bSopenharmony_ci#include <core/ecs/intf_ecs.h> 348bf80f4bSopenharmony_ci#include <core/engine_info.h> 358bf80f4bSopenharmony_ci#include <core/implementation_uids.h> 368bf80f4bSopenharmony_ci#include <core/intf_engine.h> 378bf80f4bSopenharmony_ci#include <core/io/intf_file_manager.h> 388bf80f4bSopenharmony_ci#include <core/io/intf_filesystem_api.h> 398bf80f4bSopenharmony_ci#include <core/log.h> 408bf80f4bSopenharmony_ci#include <core/namespace.h> 418bf80f4bSopenharmony_ci#include <core/os/intf_platform.h> 428bf80f4bSopenharmony_ci#include <core/plugin/intf_class_factory.h> 438bf80f4bSopenharmony_ci#include <core/plugin/intf_class_register.h> 448bf80f4bSopenharmony_ci#include <core/plugin/intf_interface.h> 458bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin.h> 468bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin_register.h> 478bf80f4bSopenharmony_ci#include <core/threading/intf_thread_pool.h> 488bf80f4bSopenharmony_ci 498bf80f4bSopenharmony_ci#include "image/image_loader_manager.h" 508bf80f4bSopenharmony_ci#include "image/loaders/image_loader_ktx.h" 518bf80f4bSopenharmony_ci#include "image/loaders/image_loader_stb_image.h" 528bf80f4bSopenharmony_ci#include "os/platform.h" 538bf80f4bSopenharmony_ci 548bf80f4bSopenharmony_ci#if (CORE_PERF_ENABLED == 1) 558bf80f4bSopenharmony_ci#include "perf/performance_data_manager.h" 568bf80f4bSopenharmony_ci#endif 578bf80f4bSopenharmony_ci 588bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE() 598bf80f4bSopenharmony_cinamespace { 608bf80f4bSopenharmony_ci#if (CORE_EMBEDDED_ASSETS_ENABLED == 1) 618bf80f4bSopenharmony_ci// Core Rofs Data. 628bf80f4bSopenharmony_ciextern "C" const uint64_t SIZEOFDATAFORCORE; 638bf80f4bSopenharmony_ciextern "C" const void* const BINARYDATAFORCORE[]; 648bf80f4bSopenharmony_ci#endif 658bf80f4bSopenharmony_ci 668bf80f4bSopenharmony_ciusing BASE_NS::array_view; 678bf80f4bSopenharmony_ciusing BASE_NS::make_unique; 688bf80f4bSopenharmony_ciusing BASE_NS::pair; 698bf80f4bSopenharmony_ciusing BASE_NS::string; 708bf80f4bSopenharmony_ciusing BASE_NS::string_view; 718bf80f4bSopenharmony_ciusing BASE_NS::Uid; 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_ci// This is defined in the CMake generated version.cpp 748bf80f4bSopenharmony_civoid LogEngineBuildInfo() 758bf80f4bSopenharmony_ci{ 768bf80f4bSopenharmony_ci#define CORE_TO_STRING_INTERNAL(x) #x 778bf80f4bSopenharmony_ci#define CORE_TO_STRING(x) CORE_TO_STRING_INTERNAL(x) 788bf80f4bSopenharmony_ci 798bf80f4bSopenharmony_ci#ifdef NDEBUG 808bf80f4bSopenharmony_ci CORE_LOG_I("Core engine version: %s", GetVersion().data()); 818bf80f4bSopenharmony_ci#else 828bf80f4bSopenharmony_ci CORE_LOG_I("Version: %s (DEBUG)", GetVersion().data()); 838bf80f4bSopenharmony_ci#endif 848bf80f4bSopenharmony_ci 858bf80f4bSopenharmony_ci CORE_LOG_I("CORE_VALIDATION_ENABLED=" CORE_TO_STRING(CORE_VALIDATION_ENABLED)); 868bf80f4bSopenharmony_ci CORE_LOG_I("CORE_DEV_ENABLED=" CORE_TO_STRING(CORE_DEV_ENABLED)); 878bf80f4bSopenharmony_ci} 888bf80f4bSopenharmony_ci} // namespace 898bf80f4bSopenharmony_ci 908bf80f4bSopenharmony_ciEngine::Engine(EngineCreateInfo const& createInfo) 918bf80f4bSopenharmony_ci : platform_(Platform::Create(createInfo.platformCreateInfo)), applicationContext_(createInfo.applicationContext) 928bf80f4bSopenharmony_ci{ 938bf80f4bSopenharmony_ci LogEngineBuildInfo(); 948bf80f4bSopenharmony_ci auto factory = CORE_NS::GetInstance<IFileSystemApi>(UID_FILESYSTEM_API_FACTORY); 958bf80f4bSopenharmony_ci fileManager_ = factory->CreateFilemanager(); 968bf80f4bSopenharmony_ci fileManager_->RegisterFilesystem("file", factory->CreateStdFileSystem()); 978bf80f4bSopenharmony_ci fileManager_->RegisterFilesystem("memory", factory->CreateMemFileSystem()); 988bf80f4bSopenharmony_ci#if (CORE_EMBEDDED_ASSETS_ENABLED == 1) 998bf80f4bSopenharmony_ci fileManager_->RegisterFilesystem( 1008bf80f4bSopenharmony_ci "corerofs", factory->CreateROFilesystem(BINARYDATAFORCORE, static_cast<size_t>(SIZEOFDATAFORCORE))); 1018bf80f4bSopenharmony_ci#endif 1028bf80f4bSopenharmony_ci 1038bf80f4bSopenharmony_ci RegisterDefaultPaths(); 1048bf80f4bSopenharmony_ci} 1058bf80f4bSopenharmony_ci 1068bf80f4bSopenharmony_ciEngine::~Engine() 1078bf80f4bSopenharmony_ci{ 1088bf80f4bSopenharmony_ci GetPluginRegister().RemoveListener(*this); 1098bf80f4bSopenharmony_ci 1108bf80f4bSopenharmony_ci#if (CORE_PERF_ENABLED == 1) 1118bf80f4bSopenharmony_ci if (auto perfFactory = CORE_NS::GetInstance<IPerformanceDataManagerFactory>(UID_PERFORMANCE_FACTORY); perfFactory) { 1128bf80f4bSopenharmony_ci for (const auto& perfMan : perfFactory->GetAllCategories()) { 1138bf80f4bSopenharmony_ci CORE_LOG_I("%s PerformanceData for this run:", perfMan->GetCategory().data()); 1148bf80f4bSopenharmony_ci static_cast<const PerformanceDataManager&>(*perfMan).DumpToLog(); 1158bf80f4bSopenharmony_ci } 1168bf80f4bSopenharmony_ci } 1178bf80f4bSopenharmony_ci#endif 1188bf80f4bSopenharmony_ci 1198bf80f4bSopenharmony_ci UnloadPlugins(); 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci fileManager_.reset(); 1228bf80f4bSopenharmony_ci} 1238bf80f4bSopenharmony_ci 1248bf80f4bSopenharmony_ciCORE_NS::IEcs* IEcsInstance(IClassFactory&, const IThreadPool::Ptr&); 1258bf80f4bSopenharmony_ci 1268bf80f4bSopenharmony_ciIEcs::Ptr Engine::CreateEcs() 1278bf80f4bSopenharmony_ci{ 1288bf80f4bSopenharmony_ci // construct a secondary ecs instance. 1298bf80f4bSopenharmony_ci if (auto threadFactory = CORE_NS::GetInstance<ITaskQueueFactory>(UID_TASK_QUEUE_FACTORY); threadFactory) { 1308bf80f4bSopenharmony_ci auto threadPool = threadFactory->CreateThreadPool(threadFactory->GetNumberOfCores()); 1318bf80f4bSopenharmony_ci return IEcs::Ptr { IEcsInstance(*this, threadPool) }; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci 1348bf80f4bSopenharmony_ci return IEcs::Ptr {}; 1358bf80f4bSopenharmony_ci} 1368bf80f4bSopenharmony_ci 1378bf80f4bSopenharmony_ciIEcs::Ptr Engine::CreateEcs(IThreadPool& threadPool) 1388bf80f4bSopenharmony_ci{ 1398bf80f4bSopenharmony_ci return IEcs::Ptr { IEcsInstance(*this, IThreadPool::Ptr { &threadPool }) }; 1408bf80f4bSopenharmony_ci} 1418bf80f4bSopenharmony_ci 1428bf80f4bSopenharmony_civoid Engine::Init() 1438bf80f4bSopenharmony_ci{ 1448bf80f4bSopenharmony_ci CORE_LOG_D("Engine init."); 1458bf80f4bSopenharmony_ci 1468bf80f4bSopenharmony_ci imageManager_ = make_unique<ImageLoaderManager>(*fileManager_); 1478bf80f4bSopenharmony_ci 1488bf80f4bSopenharmony_ci // Pre-register some basic image formats. 1498bf80f4bSopenharmony_ci 1508bf80f4bSopenharmony_ci LoadPlugins(); 1518bf80f4bSopenharmony_ci 1528bf80f4bSopenharmony_ci GetPluginRegister().AddListener(*this); 1538bf80f4bSopenharmony_ci} 1548bf80f4bSopenharmony_ci 1558bf80f4bSopenharmony_civoid Engine::RegisterDefaultPaths() 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci platform_->RegisterDefaultPaths(*fileManager_); 1588bf80f4bSopenharmony_ci#if (CORE_EMBEDDED_ASSETS_ENABLED == 1) 1598bf80f4bSopenharmony_ci // Create engine:// protocol that points to embedded engine asset files. 1608bf80f4bSopenharmony_ci CORE_LOG_D("Registered core asset path: 'corerofs://core/'"); 1618bf80f4bSopenharmony_ci fileManager_->RegisterPath("engine", "corerofs://core/", false); 1628bf80f4bSopenharmony_ci#endif 1638bf80f4bSopenharmony_ci 1648bf80f4bSopenharmony_ci // Create shaders:// protocol that points to shader files. 1658bf80f4bSopenharmony_ci fileManager_->RegisterPath("shaders", "engine://shaders/", false); 1668bf80f4bSopenharmony_ci // Create shaderstates:// protocol that points to (graphics) shader state files. 1678bf80f4bSopenharmony_ci fileManager_->RegisterPath("shaderstates", "engine://shaderstates/", false); 1688bf80f4bSopenharmony_ci // Create vertexinputdeclarations:// protocol that points to vid files. 1698bf80f4bSopenharmony_ci fileManager_->RegisterPath("vertexinputdeclarations", "engine://vertexinputdeclarations/", false); 1708bf80f4bSopenharmony_ci // Create pipelinelayouts:// protocol that points to vid files. 1718bf80f4bSopenharmony_ci fileManager_->RegisterPath("pipelinelayouts", "engine://pipelinelayouts/", false); 1728bf80f4bSopenharmony_ci // Create renderdataconfigurations:// protocol that points to render byteData configurations. 1738bf80f4bSopenharmony_ci fileManager_->RegisterPath("renderdataconfigurations", "engine://renderdataconfigurations/", false); 1748bf80f4bSopenharmony_ci} 1758bf80f4bSopenharmony_ci 1768bf80f4bSopenharmony_civoid Engine::UnloadPlugins() 1778bf80f4bSopenharmony_ci{ 1788bf80f4bSopenharmony_ci for (auto& plugin : plugins_) { 1798bf80f4bSopenharmony_ci if (plugin.second->destroyPlugin) { 1808bf80f4bSopenharmony_ci plugin.second->destroyPlugin(plugin.first); 1818bf80f4bSopenharmony_ci } 1828bf80f4bSopenharmony_ci } 1838bf80f4bSopenharmony_ci} 1848bf80f4bSopenharmony_ci 1858bf80f4bSopenharmony_civoid Engine::LoadPlugins() 1868bf80f4bSopenharmony_ci{ 1878bf80f4bSopenharmony_ci for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(IEnginePlugin::UID)) { 1888bf80f4bSopenharmony_ci if (auto enginePlugin = static_cast<const IEnginePlugin*>(info); enginePlugin && enginePlugin->createPlugin) { 1898bf80f4bSopenharmony_ci auto token = enginePlugin->createPlugin(*this); 1908bf80f4bSopenharmony_ci plugins_.push_back({ token, enginePlugin }); 1918bf80f4bSopenharmony_ci } 1928bf80f4bSopenharmony_ci } 1938bf80f4bSopenharmony_ci} 1948bf80f4bSopenharmony_ci 1958bf80f4bSopenharmony_cibool Engine::TickFrame() 1968bf80f4bSopenharmony_ci{ 1978bf80f4bSopenharmony_ci return TickFrame({ nullptr, size_t(0) }); 1988bf80f4bSopenharmony_ci} 1998bf80f4bSopenharmony_ci 2008bf80f4bSopenharmony_cibool Engine::TickFrame(const array_view<IEcs*>& ecsInputs) 2018bf80f4bSopenharmony_ci{ 2028bf80f4bSopenharmony_ci using namespace std::chrono; 2038bf80f4bSopenharmony_ci const auto currentTime = 2048bf80f4bSopenharmony_ci static_cast<uint64_t>(duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count()); 2058bf80f4bSopenharmony_ci 2068bf80f4bSopenharmony_ci if (firstTime_ == ~0u) { 2078bf80f4bSopenharmony_ci previousFrameTime_ = firstTime_ = currentTime; 2088bf80f4bSopenharmony_ci } 2098bf80f4bSopenharmony_ci deltaTime_ = currentTime - previousFrameTime_; 2108bf80f4bSopenharmony_ci constexpr auto limitHz = duration_cast<microseconds>(duration<float, std::ratio<1, 15u>>(1)).count(); 2118bf80f4bSopenharmony_ci if (deltaTime_ > limitHz) { 2128bf80f4bSopenharmony_ci deltaTime_ = limitHz; // clamp the time step to no longer than 15hz. 2138bf80f4bSopenharmony_ci } 2148bf80f4bSopenharmony_ci previousFrameTime_ = currentTime; 2158bf80f4bSopenharmony_ci 2168bf80f4bSopenharmony_ci const uint64_t totalTime = currentTime - firstTime_; 2178bf80f4bSopenharmony_ci 2188bf80f4bSopenharmony_ci bool needRender = false; 2198bf80f4bSopenharmony_ci for (auto& ecs : ecsInputs) { 2208bf80f4bSopenharmony_ci if (TickFrame(*ecs, totalTime, deltaTime_)) { 2218bf80f4bSopenharmony_ci needRender = true; 2228bf80f4bSopenharmony_ci } 2238bf80f4bSopenharmony_ci } 2248bf80f4bSopenharmony_ci 2258bf80f4bSopenharmony_ci return needRender; 2268bf80f4bSopenharmony_ci} 2278bf80f4bSopenharmony_ci 2288bf80f4bSopenharmony_cibool Engine::TickFrame(IEcs& ecs, uint64_t totalTime, uint64_t deltaTime) 2298bf80f4bSopenharmony_ci{ 2308bf80f4bSopenharmony_ci // run garbage collection before updating the systems to ensure only valid entities/ components are available. 2318bf80f4bSopenharmony_ci ecs.ProcessEvents(); 2328bf80f4bSopenharmony_ci 2338bf80f4bSopenharmony_ci const bool needRender = ecs.Update(totalTime, deltaTime); 2348bf80f4bSopenharmony_ci 2358bf80f4bSopenharmony_ci // do gc also after the systems have been updated to ensure any deletes done by systems are effective 2368bf80f4bSopenharmony_ci // and client doesn't see stale entities. 2378bf80f4bSopenharmony_ci ecs.ProcessEvents(); 2388bf80f4bSopenharmony_ci 2398bf80f4bSopenharmony_ci return needRender; 2408bf80f4bSopenharmony_ci} 2418bf80f4bSopenharmony_ci 2428bf80f4bSopenharmony_ciIImageLoaderManager& Engine::GetImageLoaderManager() 2438bf80f4bSopenharmony_ci{ 2448bf80f4bSopenharmony_ci CORE_ASSERT_MSG(imageManager_, "Engine not initialized"); 2458bf80f4bSopenharmony_ci return *imageManager_; 2468bf80f4bSopenharmony_ci} 2478bf80f4bSopenharmony_ci 2488bf80f4bSopenharmony_ciIFileManager& Engine::GetFileManager() 2498bf80f4bSopenharmony_ci{ 2508bf80f4bSopenharmony_ci CORE_ASSERT_MSG(fileManager_, "Engine not initialized"); 2518bf80f4bSopenharmony_ci return *fileManager_; 2528bf80f4bSopenharmony_ci} 2538bf80f4bSopenharmony_ci 2548bf80f4bSopenharmony_ciEngineTime Engine::GetEngineTime() const 2558bf80f4bSopenharmony_ci{ 2568bf80f4bSopenharmony_ci return { previousFrameTime_ - firstTime_, deltaTime_ }; 2578bf80f4bSopenharmony_ci} 2588bf80f4bSopenharmony_ci 2598bf80f4bSopenharmony_ciconst IInterface* Engine::GetInterface(const Uid& uid) const 2608bf80f4bSopenharmony_ci{ 2618bf80f4bSopenharmony_ci if ((uid == IEngine::UID) || (uid == IClassFactory::UID) || (uid == IInterface::UID)) { 2628bf80f4bSopenharmony_ci return static_cast<const IEngine*>(this); 2638bf80f4bSopenharmony_ci } 2648bf80f4bSopenharmony_ci if (uid == IClassRegister::UID) { 2658bf80f4bSopenharmony_ci return static_cast<const IClassRegister*>(this); 2668bf80f4bSopenharmony_ci } 2678bf80f4bSopenharmony_ci 2688bf80f4bSopenharmony_ci return nullptr; 2698bf80f4bSopenharmony_ci} 2708bf80f4bSopenharmony_ci 2718bf80f4bSopenharmony_ciIInterface* Engine::GetInterface(const Uid& uid) 2728bf80f4bSopenharmony_ci{ 2738bf80f4bSopenharmony_ci if ((uid == IEngine::UID) || (uid == IClassFactory::UID) || (uid == IInterface::UID)) { 2748bf80f4bSopenharmony_ci return static_cast<IEngine*>(this); 2758bf80f4bSopenharmony_ci } 2768bf80f4bSopenharmony_ci if (uid == IClassRegister::UID) { 2778bf80f4bSopenharmony_ci return static_cast<IClassRegister*>(this); 2788bf80f4bSopenharmony_ci } 2798bf80f4bSopenharmony_ci 2808bf80f4bSopenharmony_ci return nullptr; 2818bf80f4bSopenharmony_ci} 2828bf80f4bSopenharmony_ci 2838bf80f4bSopenharmony_civoid Engine::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 2848bf80f4bSopenharmony_ci{ 2858bf80f4bSopenharmony_ci // keep interfaceTypeInfos_ sorted according to UIDs 2868bf80f4bSopenharmony_ci const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 2878bf80f4bSopenharmony_ci [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; }); 2888bf80f4bSopenharmony_ci interfaceTypeInfos_.insert(pos, &interfaceInfo); 2898bf80f4bSopenharmony_ci} 2908bf80f4bSopenharmony_ci 2918bf80f4bSopenharmony_civoid Engine::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo) 2928bf80f4bSopenharmony_ci{ 2938bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 2948bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid, 2958bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 2968bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == interfaceInfo.uid) { 2978bf80f4bSopenharmony_ci interfaceTypeInfos_.erase(pos); 2988bf80f4bSopenharmony_ci } 2998bf80f4bSopenharmony_ci } 3008bf80f4bSopenharmony_ci} 3018bf80f4bSopenharmony_ci 3028bf80f4bSopenharmony_ciarray_view<const InterfaceTypeInfo* const> Engine::GetInterfaceMetadata() const 3038bf80f4bSopenharmony_ci{ 3048bf80f4bSopenharmony_ci return interfaceTypeInfos_; 3058bf80f4bSopenharmony_ci} 3068bf80f4bSopenharmony_ci 3078bf80f4bSopenharmony_ciconst InterfaceTypeInfo& Engine::GetInterfaceMetadata(const Uid& uid) const 3088bf80f4bSopenharmony_ci{ 3098bf80f4bSopenharmony_ci static constexpr InterfaceTypeInfo invalidType {}; 3108bf80f4bSopenharmony_ci 3118bf80f4bSopenharmony_ci if (!interfaceTypeInfos_.empty()) { 3128bf80f4bSopenharmony_ci const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid, 3138bf80f4bSopenharmony_ci [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; }); 3148bf80f4bSopenharmony_ci if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == uid) { 3158bf80f4bSopenharmony_ci return *(*pos); 3168bf80f4bSopenharmony_ci } 3178bf80f4bSopenharmony_ci } 3188bf80f4bSopenharmony_ci return invalidType; 3198bf80f4bSopenharmony_ci} 3208bf80f4bSopenharmony_ci 3218bf80f4bSopenharmony_ciIInterface* Engine::GetInstance(const Uid& uid) const 3228bf80f4bSopenharmony_ci{ 3238bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 3248bf80f4bSopenharmony_ci if (data.getInterface) { 3258bf80f4bSopenharmony_ci return data.getInterface(const_cast<Engine&>(*this), data.token); 3268bf80f4bSopenharmony_ci } 3278bf80f4bSopenharmony_ci return nullptr; 3288bf80f4bSopenharmony_ci} 3298bf80f4bSopenharmony_ci 3308bf80f4bSopenharmony_ciIInterface::Ptr Engine::CreateInstance(const Uid& uid) 3318bf80f4bSopenharmony_ci{ 3328bf80f4bSopenharmony_ci const auto& data = GetInterfaceMetadata(uid); 3338bf80f4bSopenharmony_ci if (data.createInterface) { 3348bf80f4bSopenharmony_ci return IInterface::Ptr { data.createInterface(*this, data.token) }; 3358bf80f4bSopenharmony_ci } 3368bf80f4bSopenharmony_ci return {}; 3378bf80f4bSopenharmony_ci} 3388bf80f4bSopenharmony_ci 3398bf80f4bSopenharmony_civoid Engine::OnTypeInfoEvent(EventType type, array_view<const ITypeInfo* const> typeInfos) 3408bf80f4bSopenharmony_ci{ 3418bf80f4bSopenharmony_ci if (type == EventType::ADDED) { 3428bf80f4bSopenharmony_ci for (const auto* info : typeInfos) { 3438bf80f4bSopenharmony_ci if (info && info->typeUid == IEnginePlugin::UID && static_cast<const IEnginePlugin*>(info)->createPlugin) { 3448bf80f4bSopenharmony_ci auto enginePlugin = static_cast<const IEnginePlugin*>(info); 3458bf80f4bSopenharmony_ci if (std::none_of(plugins_.begin(), plugins_.end(), 3468bf80f4bSopenharmony_ci [enginePlugin](const pair<PluginToken, const IEnginePlugin*>& pluginData) { 3478bf80f4bSopenharmony_ci return pluginData.second == enginePlugin; 3488bf80f4bSopenharmony_ci })) { 3498bf80f4bSopenharmony_ci auto token = enginePlugin->createPlugin(*this); 3508bf80f4bSopenharmony_ci plugins_.push_back({ token, enginePlugin }); 3518bf80f4bSopenharmony_ci } 3528bf80f4bSopenharmony_ci } 3538bf80f4bSopenharmony_ci } 3548bf80f4bSopenharmony_ci } else if (type == EventType::REMOVED) { 3558bf80f4bSopenharmony_ci for (const auto* info : typeInfos) { 3568bf80f4bSopenharmony_ci if (info && info->typeUid == IEnginePlugin::UID) { 3578bf80f4bSopenharmony_ci auto enginePlugin = static_cast<const IEnginePlugin*>(info); 3588bf80f4bSopenharmony_ci if (auto pos = std::find_if(plugins_.cbegin(), plugins_.cend(), 3598bf80f4bSopenharmony_ci [enginePlugin](const pair<PluginToken, const IEnginePlugin*>& pluginData) { 3608bf80f4bSopenharmony_ci return pluginData.second == enginePlugin; 3618bf80f4bSopenharmony_ci }); 3628bf80f4bSopenharmony_ci pos != plugins_.cend()) { 3638bf80f4bSopenharmony_ci if (enginePlugin->destroyPlugin) { 3648bf80f4bSopenharmony_ci enginePlugin->destroyPlugin(pos->first); 3658bf80f4bSopenharmony_ci } 3668bf80f4bSopenharmony_ci plugins_.erase(pos); 3678bf80f4bSopenharmony_ci } 3688bf80f4bSopenharmony_ci } 3698bf80f4bSopenharmony_ci } 3708bf80f4bSopenharmony_ci } 3718bf80f4bSopenharmony_ci} 3728bf80f4bSopenharmony_ci 3738bf80f4bSopenharmony_cistring_view Engine::GetVersion() 3748bf80f4bSopenharmony_ci{ 3758bf80f4bSopenharmony_ci return CORE_NS::GetVersion(); 3768bf80f4bSopenharmony_ci} 3778bf80f4bSopenharmony_ci 3788bf80f4bSopenharmony_cibool Engine::IsDebugBuild() 3798bf80f4bSopenharmony_ci{ 3808bf80f4bSopenharmony_ci return CORE_NS::IsDebugBuild(); 3818bf80f4bSopenharmony_ci} 3828bf80f4bSopenharmony_ci 3838bf80f4bSopenharmony_ciIEngine::Ptr CreateEngine(EngineCreateInfo const& createInfo) 3848bf80f4bSopenharmony_ci{ 3858bf80f4bSopenharmony_ci auto engine = new Engine(createInfo); 3868bf80f4bSopenharmony_ci return IEngine::Ptr { engine }; 3878bf80f4bSopenharmony_ci} 3888bf80f4bSopenharmony_ci 3898bf80f4bSopenharmony_ciconst IPlatform& Engine::GetPlatform() const 3908bf80f4bSopenharmony_ci{ 3918bf80f4bSopenharmony_ci return *platform_; 3928bf80f4bSopenharmony_ci} 3938bf80f4bSopenharmony_ci 3948bf80f4bSopenharmony_civoid Engine::Ref() 3958bf80f4bSopenharmony_ci{ 3968bf80f4bSopenharmony_ci refCount_++; 3978bf80f4bSopenharmony_ci} 3988bf80f4bSopenharmony_ci 3998bf80f4bSopenharmony_civoid Engine::Unref() 4008bf80f4bSopenharmony_ci{ 4018bf80f4bSopenharmony_ci if (--refCount_ == 0) { 4028bf80f4bSopenharmony_ci delete this; 4038bf80f4bSopenharmony_ci } 4048bf80f4bSopenharmony_ci} 4058bf80f4bSopenharmony_ciCORE_END_NAMESPACE() 406