DALi Version 2.2.21
[platform/core/uifw/dali-core.git] / dali / integration-api / addon-manager.h
1 #ifndef DALI_INTEGRATION_ADDON_MANAGER_H
2 #define DALI_INTEGRATION_ADDON_MANAGER_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/base-handle.h>
23
24 // EXTERNAL EXCLUDES
25 #include <cstdio>
26 #include <functional>
27 #include <memory>
28 #include <string>
29 #include <vector>
30
31 namespace Dali
32 {
33 // Type of extensions (may be used internally)
34 enum class AddOnType
35 {
36   GENERIC,
37   IMAGE_LOADER
38 };
39
40 /**
41  * @brief Helper function building the version number as 32-bit integer.
42  * The return value should be used to encode AddOnInfo::version field.
43  *
44  * @param[in] maj Major version number
45  * @param[in] min Minor version number
46  * @param[in] rev Revision version number
47  * @return returns 32-bit version number
48  */
49 constexpr uint32_t DALI_ADDON_VERSION(uint32_t maj, uint32_t min, uint32_t rev)
50 {
51   return ((maj & 0xff) << 24) | ((min & 0xfff) << 16);
52 }
53
54 /**
55  * Structure describes AddOn details
56  */
57 struct AddOnInfo
58 {
59   AddOnType type; /// may be use in order to classify extension
60   void*     next; /// holds pointer to additional data-structures
61
62   std::string name; /// Name of the extension
63   uint32_t    version;
64
65   /**
66    * Structure contains details of build
67    */
68   struct BuildInfo
69   {
70     uint32_t libCoreVersion;
71     uint32_t libAdaptorVersion;
72     uint32_t libToolkitVersion;
73   } buildInfo;
74 };
75
76 /**
77  * The structure contains essential function pointers which AddOnManager
78  * requires in order to use AddOns.
79  */
80 struct AddOnDispatchTable
81 {
82   std::string name;
83   void (*GetAddOnInfo)(Dali::AddOnInfo&) = nullptr;
84   void* (*GetGlobalProc)(const char*)    = nullptr;
85   void* (*GetInstanceProc)(const char*)  = nullptr;
86
87   // Lifecycle callbacks
88   void (*OnStart)()  = nullptr;
89   void (*OnResume)() = nullptr;
90   void (*OnPause)()  = nullptr;
91   void (*OnStop)()   = nullptr;
92 };
93
94 /**
95  * The AddOnLibrary type represents fully opaque object which hides
96  * the actual handle to the library and other related data.
97  */
98 typedef void* AddOnLibrary;
99
100 namespace Integration
101 {
102 /**
103  * AddOnManager class
104  *
105  * Handles DALi AddOn support. The object of AddOnManager exists as a singleton and
106  * is created by the Adaptor. The AddOnManager is used by:
107  *
108  * 1) Application - query the AddOns and obtain AddOn interfaces
109  * 2) DALi - handling lifecycle events
110  * 3) AddOn - self-registering the AddOn dispatch table
111  *
112  * It is up to the implementation how the AddOn libraries are enumerated and opened. Any
113  * caching (functions, open libraries) must be handled by the implementation.
114  */
115 class DALI_CORE_API AddOnManager
116 {
117 protected:
118   /**
119    * @brief Constructor, initialised by the Adaptor
120    */
121   AddOnManager();
122
123 public:
124   /**
125    * @brief Destructor
126    */
127   virtual ~AddOnManager();
128
129   // Functions called by the application
130 public:
131   /**
132    * @brief Retrieves list of the available AddOns
133    * @return List of AddOn names
134    */
135   virtual std::vector<std::string> EnumerateAddOns() = 0;
136
137   /**
138    * @brief Returns AddOnInfo structure for specified AddOn name
139    * @param[in] name Name of AddOn
140    * @param[out]] info Output reference
141    * @return True on success, False if extension info cannot be retrieved
142    */
143   virtual bool GetAddOnInfo(const std::string& name, AddOnInfo& info) = 0;
144
145   /**
146    * @brief Loads and initialises specified extensions
147    * @param[in] extensionNames Array of extension names
148    * @return vector of initialised extension handles
149    */
150   virtual std::vector<AddOnLibrary> LoadAddOns(const std::vector<std::string>& addonNames) = 0;
151
152   /**
153    * @brief Loads AddOn with specified name
154    * @param[in] addOnName Name of AddOn to be acquired
155    * @return Returns a valid handle or nullptr
156    */
157   inline AddOnLibrary GetAddOn(const std::string& addonName)
158   {
159     return LoadAddOns({addonName})[0];
160   }
161
162   /**
163    * @brief Returns AddOn global function pointer
164    * @param[in] addOnLibrary valid AddOn library object
165    * @param[in] procName Name of the function to retrieve
166    * @return Pointer to the function or null if function doesn't exist
167    */
168   virtual void* GetGlobalProc(const Dali::AddOnLibrary& addOnLibrary, const char* procName) = 0;
169
170   /**
171    * @brief Returns addon instance function pointer
172    * @param[in] addOnLibrary valid AddOn library object
173    * @param[in] procName Name of the function to retrieve
174    * @return Pointer to the function or null if function doesn't exist
175    */
176   virtual void* GetInstanceProc(const Dali::AddOnLibrary& addOnLibrary, const char* procName) = 0;
177
178   /**
179    * @brief Returns addon global function of specified type
180    * @param[in] addOnLibrary valid AddOn library object
181    * @param[in] procName Name of the function to retrieve
182    * @return std::function object or null if function doesn't exist
183    */
184   template<class T>
185   DALI_INTERNAL std::function<T> GetGlobalProc(const Dali::AddOnLibrary& addonlibrary, const char* procName)
186   {
187     auto ptr = GetGlobalProc(addonlibrary, procName);
188     if(ptr)
189     {
190       return std::function<T>(*reinterpret_cast<T**>(&ptr));
191     }
192     return {};
193   };
194
195   /**
196    * @brief Returns AddOn instance function of specified type
197    * @param[in] addOnLibrary valid AddOn library object
198    * @param[in] procName Name of the function to retrieve
199    * @return std::function object or null if function doesn't exist
200    */
201   template<class T>
202   DALI_INTERNAL std::function<T> GetInstanceProc(const Dali::AddOnLibrary& addOnLibrary, const char* procName)
203   {
204     auto ptr = GetInstanceProc(addOnLibrary, procName);
205     if(ptr)
206     {
207       return std::function<T>(*reinterpret_cast<T**>(&ptr));
208     }
209     return {};
210   };
211
212   /**
213    * @brief Invokes global function by name
214    * @param[in] addOnLibrary valid AddOn library object
215    * @param[in] functionName Name of function to be called
216    * @param args[in] Arguments
217    * @return Result of called function
218    */
219   template<class R, class... Args>
220   DALI_INTERNAL R InvokeGlobalProc(AddOnLibrary addOnLibrary, const char* functionName, Args&&... args)
221   {
222     return std::move(GetGlobalProc<R(Args...)>(addOnLibrary, functionName)(args...));
223   }
224
225   // Lifecycle events, functions are called by the Adaptor
226 public:
227   /**
228    * @brief Lifecycle pause function
229    */
230   virtual void Pause() = 0;
231
232   /**
233    * @brief Lifecycle resume function
234    */
235   virtual void Resume() = 0;
236
237   /**
238    * @brief Lifecycle start function
239    */
240   virtual void Start() = 0;
241
242   /**
243    * @brief Lifecycle stop function
244    */
245   virtual void Stop() = 0;
246
247   // Functions called by the AddOn
248 public:
249   /**
250    * @brief Registers the dispatch table with AddOnManager.
251    *
252    * The function must be called by the AddOn in order to self-register and add
253    * the dispatch table. The platform-dependent implementation must override it
254    * in order to store the dispatch table. The way the dispatch table is stored
255    * depends on the implementation.
256    *
257    * @param[in] dispatchTable Pointer to the valid dispatch table
258    */
259   virtual void RegisterAddOnDispatchTable(const AddOnDispatchTable* dispatchTable) = 0;
260
261   /**
262    * @brief Retrieves AddOnManager singleton
263    * @return pointer to the AddOnManager
264    */
265   static AddOnManager* Get();
266
267 protected:
268   static AddOnManager* mSingleton; ///< Singleton storing an instance of AddOnManager
269 };
270 } // namespace Integration
271 } // namespace Dali
272
273 #endif // DALI_INTEGRATION_ADDON_MANAGER