Formatted API
[platform/core/uifw/dali-core.git] / dali / devel-api / common / addon-binder.h
1 #ifndef DALI_ADDON_BINDER_H
2 #define DALI_ADDON_BINDER_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 #include <dali/integration-api/addon-manager.h>
21
22 namespace Dali
23 {
24 namespace AddOn
25 {
26 /**
27  * Class automates binding an AddOn interface.
28  *
29  * This interface is meant to be used as a base
30  * for classes that use function binding macros.
31  *
32  * Sample use:
33  * \code{.cpp}
34  * #include <dali/devel-api/common/addon-binder.h>
35  * struct AddOnImageLoader : public Dali::DevelAddOn::AddOnBinder
36  * {
37  *   // Constructor requires the AddOn name and optional version (0 - any version accepted)
38  *   AddOnImageLoader( const char* addonname ) : Dali::DevelAddOn::AddOnBinder( addonname, 0 ) {}
39  *
40  *   ~AddOnImageLoader() = default;
41  *
42  *   // Binding block
43  *   // Using ADDON_BIND_FUNCTION() macro requires function name (resolved by the AddOn) and function
44  *   // signature. It will generate member function with correct binding.
45  *
46  *   // LoadBitmap
47  *   ADDON_BIND_FUNCTION( LoadBitmap, bool(const Dali::ImageLoader::Input&, Dali::Devel::PixelBuffer&) );
48  *
49  *   // LoadHeader
50  *   ADDON_BIND_FUNCTION( LoadHeader, bool(const Dali::ImageLoader::Input&, unsigned int&, unsigned int&) );
51  *
52  *   // GetFormatExtension
53  *   ADDON_BIND_FUNCTION( GetFormatExtension, const char*() );
54  *
55  *   // GetFormatMagicNumber
56  *   ADDON_BIND_FUNCTION( GetFormatMagicNumber, uint16_t() );
57  *
58  *   // GetBitmapProfile
59  *   ADDON_BIND_FUNCTION( GetBitmapProfile, Bitmap::Profile() );
60  *  };
61  *  \endcode
62  */
63
64 class AddOnBinder
65 {
66 public:
67   /**
68    * @brief Constructor. Opens an AddOn and creates interface
69    * @param[in] addonName Name of AddOn
70    * @param[in] version Version of AddOn
71    */
72   explicit AddOnBinder(const char* addonName, uint32_t version = 0u)
73   {
74     mAddOnManager = Dali::Integration::AddOnManager::Get();
75     if(mAddOnManager)
76     {
77       mAddOnHandle = mAddOnManager->GetAddOn(addonName);
78       if(mAddOnHandle)
79       {
80         mAddOnManager->GetAddOnInfo(addonName, mAddOnInfo);
81       }
82     }
83   }
84
85   /**
86    * @brief Destructor
87    */
88   virtual ~AddOnBinder() = default;
89
90   /**
91    * @brief Looks up and converts c-style void* function into pointer of type T
92    * @param[in] funcName name of the function
93    * @return Returns a new pointer
94    */
95   template<class T>
96   T* ConvertFunction(const std::string& funcName)
97   {
98     if(mAddOnHandle)
99     {
100       auto ptr = mAddOnManager->GetGlobalProc(mAddOnHandle, funcName.c_str());
101       return *reinterpret_cast<T**>(&ptr);
102     }
103     return nullptr;
104   }
105
106   /**
107    * @brief Returns a handle to the AddOn library
108    * @return Handle object
109    */
110   Dali::AddOnLibrary GetHandle()
111   {
112     return mAddOnHandle;
113   }
114
115   /**
116    * @brief Returns pointer to the global AddOn function.
117    * @param[in] name Name of the function
118    * @return Valid pointer or nullptr
119    */
120   void* GetGlobalProc(const char* name)
121   {
122     return mAddOnManager ? mAddOnManager->GetGlobalProc(mAddOnHandle, name) : nullptr;
123   }
124
125   /**
126    * @brief Returns pointer to the instance AddOn function.
127    * @param[in] name Name of the function
128    * @return Valid pointer or nullptr
129    */
130   void* GetInstanceProc(const char* name)
131   {
132     return mAddOnManager ? mAddOnManager->GetInstanceProc(mAddOnHandle, name) : nullptr;
133   }
134
135   /**
136    * @brief Tests whether the interface is valid
137    * @return True if valid, false otherwise
138    */
139   virtual bool IsValid()
140   {
141     return GetHandle() != nullptr;
142   }
143
144   /**
145    * @brief Returns AddOn info structure
146    * @return AddOn info structure.
147    */
148   const AddOnInfo& GetAddOnInfo() const
149   {
150     return mAddOnInfo;
151   }
152
153 protected:
154   static DALI_CORE_API Dali::Integration::AddOnManager* mAddOnManager; ///< Pointer to the AddOn manager
155
156   Dali::AddOnLibrary mAddOnHandle{nullptr}; ///< Handle to the AddOn library
157   Dali::AddOnInfo    mAddOnInfo{};          ///< Stored AddOnInfo structure
158 };
159
160 /**
161  * Macro binds function as a member function of the class, for example, the call:
162  *
163  * ADDON_BIND_FUNCTION( SomeAddOnFunction, void(int, char*) );
164  *
165  * will create a std::function object named SomeAddOnFunction and bound to the AddOn library.
166  */
167 #define ADDON_BIND_FUNCTION(FUNCNAME, FUNCTYPE) \
168   std::function<FUNCTYPE> FUNCNAME{ConvertFunction<FUNCTYPE>(std::string(#FUNCNAME))};
169
170 } // namespace AddOn
171 } // namespace Dali
172
173 #endif // DALI_ADDON_BINDER_H