[dali_1.4.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / signals / signal-manager.h
1 #ifndef DALI_V8PLUGIN_SIGNAL_MANAGER_H
2 #define DALI_V8PLUGIN_SIGNAL_MANAGER_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 // EXTERNAL INCLUDES
22 #include <v8.h>
23 #include <string>
24 #include <dali/public-api/common/dali-vector.h>
25
26 // INTERNAL INCLUDES
27 #include <signals/emit-notification-interface.h>
28
29
30
31 namespace Dali
32 {
33
34 namespace V8Plugin
35 {
36
37 class BaseCallBack;
38 class HandleWrapper;
39
40 /**
41  * Manages signal connection / disconnection.
42  *
43  * How it works...
44  * 1) SignalConnect, SignalDisconnect is installed on to a dali-wrapped object template. E.g.
45  *
46  *   objTemplate->Set( v8::String::NewFromUtf8( isolate, "Connect"),
47                      v8::FunctionTemplate::New( isolate, SignalManager::SignalConnect) );
48  *
49  * 2) When the  actor.Connect(...) is called, v8 runs SignalManager::SignalConnect( args )
50  *
51  * args.This() == Dali object ( e.g. Actor / Animation / Image ).
52  * args[ 0 ] == Signal name, e.g. "touched"
53  * args[ 1 ] ==  JavaScript function to run when the signal is fired.
54  *
55  * 3) SignalManager uses the signal name, to decide what type of Dali Signal is required.
56  * It then creates a C++ object which can be connected to the Signal.
57  * That object also holds a pointer to the JavaScript callback function
58  *
59  * 4) When the signal is fired, it triggers the signal in the C++ object, which then fires
60  * the JavaScript function. See ActorCallback::OnTouch
61  *
62  *  When the object that holds SignalManager dies (e.g. an ActorWrapper), the signal manager for that
63  *  object is destroyed, which automatically disconnects any signal connections.
64  *
65  *  @TODO
66  *  Currently DALi Core supports 'DoConnectSignal' which passes in no parameters and expects no return value.
67  *  If we could extend this, so DoConnect supports a generic function such as
68  *  Dali::Any (*CallbackFunction) (Dali::Vector< Dali::Any > parameters );
69  *  then we should be able to remove most of the code in this file.
70  *  As this is how BaseJavaScriptCallback::Call() in SignalManager.cpp works.
71  *
72  *
73  *
74  */
75 class SignalManager : public EmitNotificationInterface
76 {
77 public:
78
79   /**
80    * Constructor
81    */
82   SignalManager();
83
84   /**
85    * Destructor
86    */
87   virtual ~SignalManager();
88
89   /**
90    * signal connect function, installed on dali-wrapped object
91    */
92   static void SignalConnect( const v8::FunctionCallbackInfo< v8::Value >& args );
93
94   /**
95    * signal disconnect function, installed on dali-wrapped object
96    */
97   static void SignalDisconnect( const v8::FunctionCallbackInfo< v8::Value >& args );
98
99   /**
100    * Add a callback
101    * @param[in] callback
102    */
103   void AddCallback( BaseCallBack* callback );
104
105   /**
106    * Remove a callback
107    * @param[in] signalName name
108    * @param[in] function to remove
109    */
110   void RemoveCallback( v8::Isolate* isolate, const std::string& signalName, const v8::Local<v8::Function>& function );
111
112 private:
113
114 public:
115
116   /**
117    * @copydoc EmitNotificationInterface::CallbackEnter()
118    */
119   virtual void CallbackEnter();
120
121   /**
122    * @copydoc EmitNotificationInterface::CallbackExit()
123    */
124   virtual void CallbackExit();
125
126
127   // typically an object will only have 1 callback, so a vector is ok, e.g.
128   // there's no point in storing a map of callbacks for an actor that will only have 1 connection
129   // for OnTouch.
130   typedef Dali::Vector< BaseCallBack* > CallBackContainer;
131
132   CallBackContainer mCallbacks;               ///< List of callbacks
133   CallBackContainer mDisconnectedCallbacks;   ///< List of disconnected callbacks
134   bool mInsideCallback;                       ///< To prevent recursive loops
135
136 };
137
138 } // namespace V8Plugin
139
140 } // namespace Dali
141
142 #endif // DALI_V8PLUGIN_SIGNAL_MANAGER_H