• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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