Purge underscored header file barriers
[platform/core/uifw/dali-core.git] / dali / devel-api / signals / signal-delegate.h
1 #ifndef DALI_SIGNAL_DELEGATE_H
2 #define DALI_SIGNAL_DELEGATE_H
3
4 /*
5  * Copyright (c) 2019 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/actors/actor.h>
23 #include <dali/public-api/signals/connection-tracker-interface.h>
24
25 namespace Dali
26 {
27
28 /**
29  * @brief The SignalDelegate object allows direct connection to a signal that has been pre-configured internally.
30  *
31  * EG: The SignalDelegate can be created internally and exposed to the application-developer.
32  * They can then call the connect function to transparently bind to their callback.
33  */
34 class DALI_CORE_API SignalDelegate
35 {
36 public:
37
38   /**
39    * @brief Create and set up a signal delegate.
40    *
41    * @param[in] connectActor The actor whose signal should be connected to.
42    * @param[in] signalName The name of the signal within the actor to connect to.
43    */
44   SignalDelegate( Dali::Actor connectActor, const std::string& signalName );
45
46   /**
47    * @brief Destructor.
48    */
49   ~SignalDelegate()
50   {
51   }
52
53 public:
54
55   /**
56    * @brief Connect to a FunctorDelegate as received from a type-registry signal connection call.
57    *
58    * This is required to allow connection to an actor's signal. Typically this is done in a generic
59    * way (IE. via a string of the signal name) using the ConnectSignal function.
60    * This function requires a functor.
61    *
62    * @param[in] connectionTracker Passed in to the ConnectSignal function of the actor.
63    * @param[in] functorDelegate A functor delegate object that must be executed when the signal is emitted.
64    * @return    True of the connection was made, false otherwise.
65    */
66   bool Connect( ConnectionTrackerInterface* connectionTracker, FunctorDelegate* functorDelegate )
67   {
68     if( !mIsConnected )
69     {
70       // Note: We have to new the CallbackBaseFunctor rather than have it as a concrete object, as it
71       // is converted to a FunctorDelegate again within ConnectSignal. FunctorDelegates gain ownership
72       // of any functor they are created from and therefore always attempt to delete them.
73       CallbackBaseFunctor* callbackFunctor = new CallbackBaseFunctor( new CallbackFunctorDelegate0( functorDelegate ) );
74       mConnectActor.ConnectSignal( connectionTracker, mSignalName, *callbackFunctor );
75       mIsConnected = true;
76
77       return true;
78     }
79
80     return false;
81   }
82
83   /**
84    * @brief Connect to a non-static member function.
85    *
86    * The object that owns the member function must also inherit from ConnectionTracker.
87    *
88    * @param[in] object Object instance that houses the supplied member-function.
89    * @param[in] memberFunction The member-function to call when the signal is emitted.
90    * @return    True of the connection was made, false otherwise.
91    */
92   template< class T >
93   bool Connect( T* object, void ( T::*memberFunction )( void ) )
94   {
95     if( !mIsConnected )
96     {
97       CallbackBaseFunctor* callbackFunctor = new CallbackBaseFunctor( MakeCallback( object, memberFunction ) );
98       mConnectActor.ConnectSignal( object, mSignalName, *callbackFunctor );
99       mIsConnected = true;
100
101       return true;
102     }
103
104     return false;
105   }
106
107   /**
108    * @brief Checks if this delegate has been connected yet, so it can be determined if it
109    * can be used or a new delegate must be created to set up a new connection (to the same signal).
110    *
111    * @return True if this SignalDelegate has been connected to it's signal.
112    */
113   bool IsConnected();
114
115
116 private:
117
118   /**
119    * This functor is used by SignalDelegate in order to callback to a non-static member function
120    * (after it has been converted to a CallbackBase).
121    * The functor can be passed in to a ConnectSignal function of a BaseHandle and call into an
122    * object's member function on despatch.
123    */
124   struct CallbackBaseFunctor
125   {
126     /**
127      * @brief Create and initialise the functor with the callback to be called.
128      *
129      * @param[in] callback A CallbackBase which can be created from a member function, or a FunctorDelegate.
130      */
131     CallbackBaseFunctor( CallbackBase* callback );
132
133     /**
134      * @brief Executes the functor.
135      */
136     void operator()();
137
138     /**
139      * Destructor.
140      * Note that as this is passed in to a ConnectSignal method, it is converted to a FunctorDelegate.
141      * This means that this functor will automatically have it's destructor called, but we still own
142      * the CallbackBase, which must be destroyed manually here.
143      */
144     ~CallbackBaseFunctor();
145
146     private:
147
148       CallbackBase* mCallback;    ///< Stores (and owns) the callback to be called on execution.
149   };
150
151 private:
152
153   /**
154    * @brief Not defined.
155    */
156   SignalDelegate( const SignalDelegate& rhs );
157
158   /**
159    * @brief Not defined.
160    */
161   const SignalDelegate& operator=( const SignalDelegate& rhs );
162
163 private:
164   bool mIsConnected;         ///< Boolean to know if it is connected already.
165   Dali::Actor mConnectActor; ///< The actor owning the signal to connect to.
166   std::string mSignalName;   ///< The name of the signal to connect to.
167 };
168
169 } // namespace Dali
170
171 #endif // DALI_SIGNAL_DELEGATE_H