1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef API_CORE_PLUGIN_IPLUGIN_H 17 #define API_CORE_PLUGIN_IPLUGIN_H 18 19 #include <cstdint> 20 21 #include <base/containers/array_view.h> 22 #include <base/util/compile_time_hashes.h> 23 #include <base/util/uid.h> 24 #include <core/namespace.h> 25 26 CORE_BEGIN_NAMESPACE() 27 class IEngine; 28 class IComponentManager; 29 class ISystem; 30 class IEcs; 31 class IInterface; 32 class IClassFactory; 33 class IClassRegister; 34 class IPluginRegister; 35 36 /** \addtogroup group_plugin_iplugin 37 * @{ 38 */ 39 /** Plugin version */ 40 struct Version { 41 /** UID for identifying different versions of the plugin. */ 42 const BASE_NS::Uid uid; 43 /** Function returning a free form version string. */ 44 const char* (*GetVersionString)() { nullptr }; 45 }; 46 47 /** Type information. Base for different registrable information structures. */ 48 struct ITypeInfo { 49 BASE_NS::Uid typeUid; 50 }; 51 52 /** Information needed from the plugin for managing ComponentManagers. */ 53 struct ComponentManagerTypeInfo : public ITypeInfo { 54 /** TypeInfo UID for component manager. */ 55 static constexpr BASE_NS::Uid UID { "f812e951-c860-4208-99e0-66b45841bb58" }; 56 57 using CreateComponentManagerFn = IComponentManager* (*)(IEcs&); 58 using DestroyComponentManagerFn = void (*)(IComponentManager* instance); 59 60 /** Unique ID of the component manager. */ 61 const BASE_NS::Uid uid; 62 /** Name used during component manager creation to identify the type of the component manager. */ 63 char const* const typeName { "" }; 64 /** Pointer to function which is used to create component manager instances. */ 65 const CreateComponentManagerFn createManager; 66 /** Pointer to function which is used to destroy component manager instances. */ 67 const DestroyComponentManagerFn destroyManager; 68 }; 69 70 /** Information needed from the plugin for managing Systems. */ 71 struct SystemTypeInfo : public ITypeInfo { 72 /** TypeInfo UID for system. */ 73 static constexpr BASE_NS::Uid UID { "31321549-70db-495c-81e9-6fd1cf30af5e" }; 74 75 using CreateSystemFn = ISystem* (*)(IEcs&); 76 using DestroySystemFn = void (*)(ISystem* instance); 77 78 /** Unique ID of the system. */ 79 const BASE_NS::Uid uid; 80 /** Name used during system creation to identify the type of the system. */ 81 char const* const typeName { "" }; 82 /** Pointer to function which is used to create system instances. */ 83 const CreateSystemFn createSystem; 84 /** Pointer to function which is used to destroy system instances. */ 85 const DestroySystemFn destroySystem; 86 /** List of component managers the system might modify during ISystem::Update. Combined with 87 * readOnlyComponentDependencies they form a list of component managers to be created before creating this system. 88 * These can be also used to determine which systems can be executed in parallel. Default constructed UID can be 89 * used as wild card to indicate dependencies not known at compile time. */ 90 const BASE_NS::array_view<const BASE_NS::Uid> componentDependencies; 91 /** List of component managers the system would only read during ISystem::Update. Combined with 92 * componentDependencies they form a list of component managers to be created before creating this system. 93 * These can be also used to determine which systems can be executed in parallel. Default constructed UID can be 94 * used as wild card to indicate dependencies not known at compile time. */ 95 const BASE_NS::array_view<const BASE_NS::Uid> readOnlyComponentDependencies; 96 }; 97 98 // Plugin token is a plugin defined token to identify instance. 99 // Think of this as an instance to the factory that provides the get/create interface method. 100 using PluginToken = void*; 101 102 /** Information needed from the plugin for managing Interfaces. */ 103 struct InterfaceTypeInfo { 104 using CreateInstanceFn = IInterface* (*)(IClassFactory&, PluginToken); 105 using GetInstanceFn = IInterface* (*)(IClassRegister&, PluginToken); 106 107 /* Token created by the plugin. (plugin specific instance data for the interface factory) */ 108 const PluginToken token; 109 /** Unique ID of the interface implementation. */ 110 const BASE_NS::Uid uid; 111 /** Name used during system creation to identify the type of the interface. */ 112 char const* const typeName { "" }; 113 /** Pointer to function which is used to create interface instances bound to IClassFactory instance. 114 * It is acceptable to return same pointer, but with a added reference count. 115 */ 116 const CreateInstanceFn createInterface; 117 /** Pointer to function which is used to get singleton interface instances bound to IClassRegister instance. 118 * It is acceptable to return same pointer, but with a added reference count. 119 */ 120 const GetInstanceFn getInterface; 121 }; 122 123 /** Exported information from a plugin (.so/.dll). */ 124 struct IPlugin : public ITypeInfo { 125 /** TypeInfo UID for a plugin. */ 126 static constexpr BASE_NS::Uid UID { "5fc9b017-5b13-4612-81c2-5a6d6fc3d897" }; 127 128 /* 129 Plugin lifecycle. 130 1. registerInterfaces, once during IPluginRegister::LoadPlugins 131 (First call to plugin is here, initialize "global" resources/data/state here.) 132 2. IEnginePlugin::createPlugin, IEcsPlugin::createPlugin etc., multiple times. 133 (during e.g. engine and ESC initialization) 134 3. IEnginePlugin::destroyPlugin, IEcsPlugin::destroyPlugin etc., multiple times. 135 (during e.g. engine and ESC destruction) 136 4. unregisterInterfaces, once during IPluginRegister::UnloadPlugins 137 (Last call to plugin is here, uninitialize "global" resources/data/state here.) 138 */ 139 140 using RegisterInterfacesFn = PluginToken (*)(IPluginRegister&); 141 using UnregisterInterfacesFn = void (*)(PluginToken); 142 143 /** Name of this plugin. */ 144 const char* const name { "" }; 145 /** Version information of the plugin. */ 146 const Version version; 147 148 /** Called when attaching plugin to plugin registry. 149 * Is expected to register its own named interfaces (IInterface) which are globally available and also register to 150 * different plugin categories e.g. IEnginePlugin and IEcsPlugin when there's a dependency to a specific instance. 151 * Think of this as "CreateInterfaceFactory" 152 */ 153 const RegisterInterfacesFn registerInterfaces { nullptr }; 154 155 /** Called when detaching plugin from plugin registry. 156 * Is expected to unregister its own named interfaces (IInterface) from the global registry and also unregister 157 * different plugin categories e.g. IEnginePlugin and IEcsPlugin when there's a dependency to a specific instance. 158 */ 159 const UnregisterInterfacesFn unregisterInterfaces { nullptr }; 160 161 /** List of plugins this plugin requires. */ 162 const BASE_NS::array_view<const BASE_NS::Uid> pluginDependencies; 163 }; 164 165 /** A plugin which adds new interfaces to the engine. */ 166 struct IEnginePlugin : public ITypeInfo { 167 /** TypeInfo UID for engine plugin. */ 168 static constexpr BASE_NS::Uid UID { "a81c121b-160c-467e-8bd6-63902da85c6b" }; 169 170 /* 171 Plugin lifecycle. 172 1. createPlugin (*as many times as engines instantiated) (initialize IEngine specific state here.) 173 2. destroyPlugin (*as many times as engines instantiated) (deinitialize IEngine specific state here.) 174 */ 175 176 using CreatePluginFn = PluginToken (*)(IEngine&); 177 using DestroyPluginFn = void (*)(PluginToken); 178 IEnginePluginIEnginePlugin179 constexpr IEnginePlugin(CreatePluginFn create, DestroyPluginFn destroy) 180 : ITypeInfo { UID }, createPlugin { create }, destroyPlugin { destroy } 181 {} 182 183 /** Initialize function for engine plugin. 184 * Called when plugin is initially loaded by engine. Used to register paths etc. 185 * Is expected to register its own named interfaces (IInterface) which are tied to the engine instance. 186 * Called when attaching to engine. 187 */ 188 const CreatePluginFn createPlugin { nullptr }; 189 190 /** Deinitialize function for engine plugin. 191 * Called when plugin is about to be unloaded by engine. 192 * Called when detaching from engine. 193 */ 194 const DestroyPluginFn destroyPlugin { nullptr }; 195 }; 196 197 /** A plugin which adds new component managers and systems to the ECS. */ 198 struct IEcsPlugin : public ITypeInfo { 199 /** TypeInfo UID for ECS plugin. */ 200 static constexpr BASE_NS::Uid UID { "b4843032-e144-4757-a28c-03c119c3a10c" }; 201 202 using CreatePluginFn = PluginToken (*)(IEcs&); 203 using DestroyPluginFn = void (*)(PluginToken); 204 IEcsPluginIEcsPlugin205 constexpr IEcsPlugin(CreatePluginFn create, DestroyPluginFn destroy) 206 : ITypeInfo { UID }, createPlugin { create }, destroyPlugin { destroy } 207 {} 208 209 /** Initialize function for ECS plugin. 210 * Called when attaching to ECS. 211 */ 212 const CreatePluginFn createPlugin { nullptr }; 213 214 /** Deinitialize function for ECS plugin. 215 * Called when detaching from ECS. 216 */ 217 const DestroyPluginFn destroyPlugin { nullptr }; 218 }; 219 220 /** @} */ 221 CORE_END_NAMESPACE() 222 223 #endif // API_CORE_PLUGIN_IPLUGIN_H 224