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