Keep node by id + Make SceneGraphTraveler don't travel anymore
[platform/core/uifw/dali-core.git] / dali / internal / event / common / stage-impl.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/common/stage-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cmath>
24 #include <cstring> // for strcmp
25
26 // INTERNAL INCLUDES
27 #include <dali/integration-api/platform-abstraction.h>
28 #include <dali/internal/event/actors/camera-actor-impl.h>
29 #include <dali/internal/event/actors/layer-impl.h>
30 #include <dali/internal/event/actors/layer-list.h>
31 #include <dali/internal/event/common/object-registry-impl.h>
32 #include <dali/internal/event/common/property-notification-manager.h>
33 #include <dali/internal/event/common/thread-local-storage.h>
34 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
35 #include <dali/internal/event/update/frame-callback-interface-impl.h>
36 #include <dali/internal/update/manager/scene-graph-frame-callback.h>
37 #include <dali/internal/update/nodes/node.h>
38 #include <dali/public-api/common/constants.h>
39 #include <dali/public-api/events/touch-event.h>
40 #include <dali/public-api/object/type-registry.h>
41 #include <dali/public-api/render-tasks/render-task-list.h>
42 #include <dali/public-api/rendering/frame-buffer.h>
43
44 using Dali::Internal::SceneGraph::Node;
45
46 namespace
47 {
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
50 #endif
51 } // namespace
52
53 namespace Dali
54 {
55 namespace Internal
56 {
57 namespace
58 {
59 // Signals
60
61 static constexpr std::string_view SIGNAL_KEY_EVENT                 = "keyEvent";
62 static constexpr std::string_view SIGNAL_KEY_EVENT_GENERATED       = "keyEventGenerated";
63 static constexpr std::string_view SIGNAL_EVENT_PROCESSING_FINISHED = "eventProcessingFinished";
64 static constexpr std::string_view SIGNAL_TOUCHED                   = "touched";
65 static constexpr std::string_view SIGNAL_WHEEL_EVENT               = "wheelEvent";
66 static constexpr std::string_view SIGNAL_CONTEXT_LOST              = "contextLost";
67 static constexpr std::string_view SIGNAL_CONTEXT_REGAINED          = "contextRegained";
68 static constexpr std::string_view SIGNAL_SCENE_CREATED             = "sceneCreated";
69
70 TypeRegistration mType(typeid(Dali::Stage), typeid(Dali::BaseHandle), nullptr);
71
72 SignalConnectorType signalConnector1(mType, std::string(SIGNAL_KEY_EVENT), &Stage::DoConnectSignal);
73 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_EVENT_PROCESSING_FINISHED), &Stage::DoConnectSignal);
74 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_WHEEL_EVENT), &Stage::DoConnectSignal);
75 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_CONTEXT_LOST), &Stage::DoConnectSignal);
76 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_CONTEXT_REGAINED), &Stage::DoConnectSignal);
77 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_SCENE_CREATED), &Stage::DoConnectSignal);
78 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_KEY_EVENT_GENERATED), &Stage::DoConnectSignal);
79 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_TOUCHED), &Stage::DoConnectSignal);
80
81 } // unnamed namespace
82
83 StagePtr Stage::New(SceneGraph::UpdateManager& updateManager)
84 {
85   return StagePtr(new Stage(updateManager));
86 }
87
88 void Stage::Initialize(Scene& scene)
89 {
90   mScene = &scene;
91   mScene->SetBackgroundColor(Dali::DEFAULT_BACKGROUND_COLOR);
92   mScene->EventProcessingFinishedSignal().Connect(this, &Stage::OnEventProcessingFinished);
93   mScene->KeyEventSignal().Connect(this, &Stage::OnKeyEvent);
94   mScene->TouchedSignal().Connect(this, &Stage::OnTouchEvent);
95   mScene->WheelEventSignal().Connect(this, &Stage::OnWheelEvent);
96 }
97
98 StagePtr Stage::GetCurrent()
99 {
100   StagePtr stage(nullptr);
101   // no checking in this version
102   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
103   if(tls)
104   {
105     stage = tls->GetCurrentStage();
106   }
107   return stage;
108 }
109
110 bool Stage::IsInstalled()
111 {
112   return ThreadLocalStorage::Created();
113 }
114
115 bool Stage::IsShuttingDown()
116 {
117   return ThreadLocalStorage::IsShuttingDown();
118 }
119
120 ObjectRegistry& Stage::GetObjectRegistry()
121 {
122   return ThreadLocalStorage::Get().GetObjectRegistry();
123 }
124
125 Layer& Stage::GetRootActor()
126 {
127   Dali::Layer rootLayer = GetRootLayer();
128   return GetImplementation(rootLayer);
129 }
130
131 void Stage::Add(Actor& actor)
132 {
133   mScene->Add(actor);
134 }
135
136 void Stage::Remove(Actor& actor)
137 {
138   mScene->Remove(actor);
139 }
140
141 Vector2 Stage::GetSize() const
142 {
143   return mScene->GetSize();
144 }
145
146 RenderTaskList& Stage::GetRenderTaskList() const
147 {
148   return mScene->GetRenderTaskList();
149 }
150
151 Actor& Stage::GetDefaultRootActor()
152 {
153   return mScene->GetDefaultRootActor();
154 }
155
156 CameraActor& Stage::GetDefaultCameraActor() const
157 {
158   return mScene->GetDefaultCameraActor();
159 }
160
161 uint32_t Stage::GetLayerCount() const
162 {
163   return mScene->GetLayerCount();
164 }
165
166 Dali::Layer Stage::GetLayer(uint32_t depth) const
167 {
168   return mScene->GetLayer(depth);
169 }
170
171 Dali::Layer Stage::GetRootLayer() const
172 {
173   return mScene->GetRootLayer();
174 }
175
176 LayerList& Stage::GetLayerList()
177 {
178   return mScene->GetLayerList();
179 }
180
181 void Stage::SetBackgroundColor(Vector4 color)
182 {
183   mScene->SetBackgroundColor(color);
184 }
185
186 Vector4 Stage::GetBackgroundColor() const
187 {
188   return mScene->GetBackgroundColor();
189 }
190
191 Vector2 Stage::GetDpi() const
192 {
193   return mScene->GetDpi();
194 }
195
196 void Stage::KeepRendering(float durationSeconds)
197 {
198   // Send message to keep rendering
199   KeepRenderingMessage(mUpdateManager, durationSeconds);
200 }
201
202 void Stage::SetRenderingBehavior(DevelStage::Rendering renderingBehavior)
203 {
204   if(mRenderingBehavior != renderingBehavior)
205   {
206     // Send message to change the rendering behavior
207     SetRenderingBehaviorMessage(mUpdateManager, renderingBehavior);
208
209     mRenderingBehavior = renderingBehavior;
210   }
211 }
212
213 DevelStage::Rendering Stage::GetRenderingBehavior() const
214 {
215   return mRenderingBehavior;
216 }
217
218 Dali::UpdateProxy::NotifySyncPoint Stage::NotifyFrameCallback(FrameCallbackInterface& frameCallback)
219 {
220   static Dali::UpdateProxy::NotifySyncPoint sSyncPoint = 0;
221   ++sSyncPoint;
222
223   NotifyFrameCallbackMessage(mUpdateManager, &frameCallback, sSyncPoint);
224   return sSyncPoint;
225 }
226
227 bool Stage::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
228 {
229   bool             connected(true);
230   Stage*           stage = static_cast<Stage*>(object); // TypeRegistry guarantees that this is the correct type.
231   std::string_view name(signalName);
232
233   if(name == SIGNAL_KEY_EVENT)
234   {
235     stage->KeyEventSignal().Connect(tracker, functor);
236   }
237   else if(name == SIGNAL_KEY_EVENT_GENERATED)
238   {
239     stage->KeyEventGeneratedSignal().Connect(tracker, functor);
240   }
241   else if(name == SIGNAL_EVENT_PROCESSING_FINISHED)
242   {
243     stage->EventProcessingFinishedSignal().Connect(tracker, functor);
244   }
245   else if(name == SIGNAL_TOUCHED)
246   {
247     stage->TouchedSignal().Connect(tracker, functor);
248   }
249   else if(name == SIGNAL_WHEEL_EVENT)
250   {
251     stage->WheelEventSignal().Connect(tracker, functor);
252   }
253   else if(name == SIGNAL_CONTEXT_LOST)
254   {
255     stage->ContextLostSignal().Connect(tracker, functor);
256   }
257   else if(name == SIGNAL_CONTEXT_REGAINED)
258   {
259     stage->ContextRegainedSignal().Connect(tracker, functor);
260   }
261   else if(name == SIGNAL_SCENE_CREATED)
262   {
263     stage->SceneCreatedSignal().Connect(tracker, functor);
264   }
265   else
266   {
267     // signalName does not match any signal
268     connected = false;
269   }
270
271   return connected;
272 }
273
274 void Stage::OnEventProcessingFinished()
275 {
276   EmitEventProcessingFinishedSignal();
277 }
278
279 void Stage::OnKeyEvent(const Dali::KeyEvent& event)
280 {
281   bool consumed = EmitKeyEventGeneratedSignal(event);
282   if(!consumed)
283   {
284     EmitKeyEventSignal(event);
285   }
286 }
287
288 void Stage::OnTouchEvent(const Dali::TouchEvent& touch)
289 {
290   EmitTouchedSignal(touch);
291 }
292
293 void Stage::OnWheelEvent(const Dali::WheelEvent& event)
294 {
295   EmitWheelEventSignal(event);
296 }
297
298 void Stage::EmitKeyEventSignal(const KeyEvent& event)
299 {
300   // Emit the key event signal when no actor in the stage has gained the key input focus
301
302   mKeyEventSignal.Emit(event);
303 }
304
305 bool Stage::EmitKeyEventGeneratedSignal(const KeyEvent& event)
306 {
307   // Emit the KeyEventGenerated signal when KeyEvent is generated
308
309   return mKeyEventGeneratedSignal.Emit(event);
310 }
311
312 void Stage::EmitEventProcessingFinishedSignal()
313 {
314   mEventProcessingFinishedSignal.Emit();
315 }
316
317 void Stage::EmitTouchedSignal(const Dali::TouchEvent& touch)
318 {
319   mTouchedSignal.Emit(touch);
320 }
321
322 void Stage::EmitWheelEventSignal(const WheelEvent& event)
323 {
324   // Emit the wheel event signal when no actor in the stage has gained the wheel input focus
325
326   mWheelEventSignal.Emit(event);
327 }
328
329 void Stage::EmitSceneCreatedSignal()
330 {
331   mSceneCreatedSignal.Emit();
332 }
333
334 Dali::Stage::KeyEventSignalType& Stage::KeyEventSignal()
335 {
336   return mKeyEventSignal;
337 }
338
339 Dali::DevelStage::KeyEventGeneratedSignalType& Stage::KeyEventGeneratedSignal()
340 {
341   return mKeyEventGeneratedSignal;
342 }
343
344 void Stage::AddFrameCallback(FrameCallbackInterface& frameCallback, Actor& rootActor)
345 {
346   DALI_ASSERT_ALWAYS((!FrameCallbackInterface::Impl::Get(frameCallback).IsConnectedToSceneGraph()) && "FrameCallbackInterface implementation already added");
347
348   // Create scene-graph object and transfer to UpdateManager
349   OwnerPointer<SceneGraph::FrameCallback> transferOwnership(SceneGraph::FrameCallback::New(frameCallback));
350   AddFrameCallbackMessage(mUpdateManager, transferOwnership, rootActor.GetNode());
351 }
352
353 void Stage::AddGlobalFrameCallback(FrameCallbackInterface& frameCallback)
354 {
355   DALI_ASSERT_ALWAYS((!FrameCallbackInterface::Impl::Get(frameCallback).IsConnectedToSceneGraph()) && "FrameCallbackInterface implementation already added");
356
357   // Create scene-graph object and transfer to UpdateManager
358   OwnerPointer<SceneGraph::FrameCallback> transferOwnership(SceneGraph::FrameCallback::New(frameCallback));
359   AddGlobalFrameCallbackMessage(mUpdateManager, transferOwnership);
360 }
361
362 void Stage::RemoveFrameCallback(FrameCallbackInterface& frameCallback)
363 {
364   FrameCallbackInterface::Impl::Get(frameCallback).Invalidate();
365   RemoveFrameCallbackMessage(mUpdateManager, frameCallback);
366 }
367
368 Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
369 {
370   return mEventProcessingFinishedSignal;
371 }
372
373 Dali::Stage::TouchEventSignalType& Stage::TouchedSignal()
374 {
375   return mTouchedSignal;
376 }
377
378 Dali::Stage::WheelEventSignalType& Stage::WheelEventSignal()
379 {
380   return mWheelEventSignal;
381 }
382
383 Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
384 {
385   return mContextLostSignal;
386 }
387
388 Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
389 {
390   return mContextRegainedSignal;
391 }
392
393 Dali::Stage::SceneCreatedSignalType& Stage::SceneCreatedSignal()
394 {
395   return mSceneCreatedSignal;
396 }
397
398 void Stage::NotifyContextLost()
399 {
400   mContextLostSignal.Emit();
401 }
402
403 void Stage::NotifyContextRegained()
404 {
405   mContextRegainedSignal.Emit();
406 }
407
408 Stage::Stage(SceneGraph::UpdateManager& updateManager)
409 : mUpdateManager(updateManager),
410   mKeyEventSignal(),
411   mKeyEventGeneratedSignal(),
412   mEventProcessingFinishedSignal(),
413   mTouchedSignal(),
414   mWheelEventSignal(),
415   mContextLostSignal(),
416   mContextRegainedSignal(),
417   mSceneCreatedSignal(),
418   mRenderingBehavior(DevelStage::Rendering::IF_REQUIRED)
419 {
420 }
421
422 Stage::~Stage() = default;
423
424 } // namespace Internal
425
426 } // namespace Dali