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