Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / animations / FUiAnim_AnimationManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiAnim_AnimationManager.cpp
20  * @brief       This file contains implementation of _AnimationManager class
21  *
22  * This file contains implementation _AnimationManager class.
23  */
24
25 #include <Ecore.h>
26
27 #include <FBaseSysLog.h>
28
29 #include <FUiAnimLinearTimingFunction.h>
30 #include <FUiAnimVisualElementPropertyAnimation.h>
31 #include <FUiAnimVisualElement.h>
32 #include <FUiAnimIAnimationTransactionEventListener.h>
33
34 #include "FUi_EcoreEvas.h"
35 #include "FUi_EcoreEvasMgr.h"
36
37 #include "FUiAnim_RootVisualElement.h"
38 #include "FUiAnim_VisualElementImpl.h"
39 #include "FUiAnim_VisualElementAnimationImpl.h"
40 #include "FUiAnim_TransactionNode.h"
41 #include "FUiAnim_VisualElementAnimationVariantInterpolator.h"
42
43 #include "FUiAnim_AnimationManager.h"
44 #include "FUiAnim_DisplayManager.h"
45
46 #include "FUiAnim_Debug.h"
47
48 #if 0
49 class ElapsedTime
50 {
51 public:
52         ElapsedTime(const char* tag = null)
53         {
54                 struct timeval tv;
55
56                 tagName = tag;
57
58                 gettimeofday(&tv, null);
59                 start_time = (long long)tv.tv_sec * 1000000LL + (long long)tv.tv_usec / 1LL;
60         }
61
62         ~ElapsedTime(void)
63         {
64                 long long end_time;
65                 struct timeval tv;
66                 gettimeofday(&tv, null);
67                 end_time = (long long)tv.tv_sec * 1000000LL + (long long)tv.tv_usec / 1LL;
68
69 //              Tizen::Ui::Animations::_AnimationManager* pAnimationManager = Tizen::Ui::Animations::_AnimationManager::GetInstance();
70 //              Tizen::Ui::Animations::_RootVisualElement* pRoot = (Tizen::Ui::Animations::_RootVisualElement*)pAnimationManager->GetRoot()->GetPresentation();
71         }
72
73
74 public:
75         long long start_time;
76         const char* tagName;
77 };
78 #endif
79
80
81 static const double fpsLimitInterval = 1.0 / 55.0;
82 Ecore_Animator* pAnimator = null;
83
84
85 Eina_Bool
86 __AnimatorCallback(void* pData)
87 {
88 #ifndef VE_VSYNC_UPDATE
89         pAnimationManager->ProcessAnimationTick();
90 //      pManager->PreRender();
91 #endif
92
93         return EINA_TRUE;
94 }
95
96 namespace Tizen { namespace Ui { namespace Animations
97 {
98
99 #ifdef VE_DEBUG_MODULE
100 Eina_Bool
101 __SigProcUser(void* pData, int type, void* pEvent)
102 {
103         _VeDebug::DumpVeTree(0, 0);
104         _VeDebug::DumpEvasTree(0, 0);
105         _VeDebug::DumpAllEvas();
106         return ECORE_CALLBACK_PASS_ON;
107 }
108 #endif
109
110
111 // default transaction event listener
112 class _TransactionEventListener
113         : public IAnimationTransactionEventListener
114         , virtual public Tizen::Base::Runtime::IEventListener
115 {
116 public:
117         _TransactionEventListener(void);
118         virtual ~_TransactionEventListener(void);
119
120         void SetTransactionEventListener(const IAnimationTransactionEventListener* pListener);
121
122         virtual void OnAnimationTransactionStarted(int transactionId);
123         virtual void OnAnimationTransactionStopped(int transactionId);
124         virtual void OnAnimationTransactionFinished(int transactionId);
125
126 private:
127         IAnimationTransactionEventListener* __pEventListener;
128 };
129
130 _TransactionEventListener::_TransactionEventListener(void)
131         : __pEventListener(null)
132 {
133 }
134
135 _TransactionEventListener::~_TransactionEventListener(void)
136 {
137 }
138
139 void
140 _TransactionEventListener::SetTransactionEventListener(const IAnimationTransactionEventListener* pListener)
141 {
142         __pEventListener = const_cast< IAnimationTransactionEventListener* >(pListener);
143 }
144
145 void
146 _TransactionEventListener::OnAnimationTransactionStarted(int transactionId)
147 {
148         if (__pEventListener)
149         {
150                 __pEventListener->OnAnimationTransactionStarted(transactionId);
151         }
152 }
153
154 void
155 _TransactionEventListener::OnAnimationTransactionStopped(int transactionId)
156 {
157         if (__pEventListener)
158         {
159                 __pEventListener->OnAnimationTransactionStopped(transactionId);
160         }
161 }
162
163 void
164 _TransactionEventListener::OnAnimationTransactionFinished(int transactionId)
165 {
166         if (__pEventListener)
167         {
168                 __pEventListener->OnAnimationTransactionFinished(transactionId);
169         }
170 }
171
172 _AnimationManager* _AnimationManager::__pInstance = null;
173
174 _AnimationManager::_AnimationManager(void)
175         : __isAnimating(false)
176         , __isInAnimationTick(false)
177         , __pRootTransaction(null)
178         , __pCurrentTransaction(null)
179         , __pCurrentTransactionExceptGroup(null)
180         , __pDefaultTransactionEventListener(null)
181         , __pDefaultTimingFunction(null)
182         , __pDefaultInterpolator(null)
183 {
184 }
185
186 _AnimationManager::~_AnimationManager(void)
187 {
188 }
189
190 _AnimationManager*
191 _AnimationManager::GetInstance(void)
192 {
193         return __pInstance;
194 }
195
196 result
197 _AnimationManager::CreateInstance(void)
198 {
199         SysAssertf((__pInstance == null), "Already created.");
200
201         __pInstance = new (std::nothrow) _AnimationManager();
202         SysTryReturnResult(NID_UI_ANIM, __pInstance != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
203
204         result r = __pInstance->Construct();
205         if (r != E_SUCCESS)
206         {
207                 SysLogException(NID_UI_ANIM, r, "[%s] Failed to construct _AnimationManager instance.", GetErrorMessage(r));
208
209                 delete __pInstance;
210                 __pInstance = null;
211
212                 return null;
213         }
214
215         return E_SUCCESS;
216 }
217
218 void
219 _AnimationManager::ReleaseInstance(void)
220 {
221         if (__pInstance != null)
222         {
223                 __pInstance->Release();
224
225                 delete __pInstance;
226                 __pInstance = null;
227         }
228 }
229
230 result
231 _AnimationManager::Release(void)
232 {
233         if (pAnimator)
234         {
235                 ecore_animator_del(pAnimator);
236         }
237
238         pAnimator = null;
239
240         delete __pRootTransaction;
241         __pRootTransaction = null;
242
243         delete __pDefaultTransactionEventListener;
244         __pDefaultTransactionEventListener = null;
245
246         delete __pDefaultTimingFunction;
247         __pDefaultTimingFunction = null;
248
249         delete __pDefaultInterpolator;
250         __pDefaultInterpolator = null;
251
252         return E_SUCCESS;
253 }
254
255 result
256 _AnimationManager::Construct(void)
257 {
258         result r = E_SUCCESS;
259
260 #ifdef VE_DEBUG_MODULE
261         ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, __SigProcUser, null);
262 #endif
263
264         __pRootTransaction = new (std::nothrow) _TransactionNode();
265         SysTryReturnResult(NID_UI_ANIM, (__pRootTransaction != null), E_OUT_OF_MEMORY, "Memory allocation failed. Failed to create root transaction");
266
267         r = GetLastResult();
268         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to create root transaction.", GetErrorMessage(r));
269
270         __pRootTransaction->Commit();   //root is always committed.
271
272         __pCurrentTransaction = __pRootTransaction;
273         __pCurrentTransactionExceptGroup = __pRootTransaction;
274
275         __pDefaultTransactionEventListener = new (std::nothrow) _TransactionEventListener();
276         SysTryCatch(NID_UI_ANIM, __pDefaultTransactionEventListener != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
277                 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default transaction event listener.");
278
279         __pDefaultTimingFunction = new (std::nothrow) LinearTimingFunction();
280         SysTryCatch(NID_UI_ANIM, __pDefaultTimingFunction != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
281                 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default timing function map.");
282
283         __pDefaultInterpolator = new (std::nothrow) _VisualElementAnimationVariantInterpolator();
284         SysTryCatch(NID_UI_ANIM, __pDefaultInterpolator != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
285                 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default interpolator.");
286
287         return E_SUCCESS;
288
289 CATCH:
290         delete __pDefaultInterpolator;
291         delete __pDefaultTimingFunction;
292         delete __pDefaultTransactionEventListener;
293         delete __pRootTransaction;
294
295         return r;
296 }
297
298
299 #ifdef  VE_DEBUG
300 static long __RenderCount = 0;    //Need?
301 #endif
302
303 void
304 _AnimationManager::SetAnimatorEnabled(bool animating)
305 {
306 #ifdef VE_VSYNC_UPDATE
307
308         __isAnimating = animating;
309
310         if (likely(animating))
311         {
312                 if (likely(pAnimator == null))
313                 {
314                         ecore_animator_frametime_set(fpsLimitInterval);
315                         pAnimator = (Ecore_Animator*)ecore_animator_add(__AnimatorCallback, _AnimationManager::GetInstance());
316                 }
317         }
318         else
319         {
320                 if (pAnimator)
321                 {
322                         ecore_animator_del(pAnimator);
323                         pAnimator = null;
324                 }
325         }
326 #else
327         if (animating)
328         {
329                 _DisplayManager::GetInstance()->AddWakeUpEvent();
330         }
331 #endif
332 }
333
334 result
335 _AnimationManager::AddAnimation(VisualElement& target, const Tizen::Base::String* pKeyName, VisualElementAnimation& animation)
336 {
337         SysTryReturnResult(NID_UI_ANIM, (__pCurrentTransaction != null), E_SYSTEM, "A system error has been occurred. Current transaction is null.");
338
339         if (pKeyName != null && pKeyName->IsEmpty() == false)
340         {
341                 SysTryReturnResult(NID_UI_ANIM, (DoesAnimationExist(target, *pKeyName) == false), E_INVALID_ARG, "Invalid argument(s) is used. Animation with keyName exists. key name = %ls", pKeyName->GetPointer());
342         }
343
344         result r = E_SUCCESS;
345
346         if (_VisualElementAnimationImpl::GetInstance(animation)->GetTimingFunction() == null)
347         {
348                 animation.SetTimingFunction(__pDefaultTimingFunction);
349         }
350
351         if (_VisualElementAnimationImpl::GetInstance(animation)->GetValueInterpolator() == null)
352         {
353                 animation.SetValueInterpolator(__pDefaultInterpolator);
354         }
355
356         // current trasaction
357         r = __pCurrentTransaction->AddAnimation(target, pKeyName, animation);
358         SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Failed to add animation.");
359
360         if (__pCurrentTransaction == __pRootTransaction && __isAnimating == false)
361         {
362                 SetAnimatorEnabled(true);
363         }
364
365         return E_SUCCESS;
366 }
367
368 result
369 _AnimationManager::RemoveAnimation(VisualElement& target, const Tizen::Base::String& keyName)
370 {
371         return __pRootTransaction->RemoveChildrenAnimation(target, keyName);
372 }
373
374 void
375 _AnimationManager::RemoveAnimationForProperty(VisualElement& target, const Tizen::Base::String& property)
376 {
377         __pRootTransaction->RemoveChildrenAnimationByProperty(target, property);
378 }
379
380 void
381 _AnimationManager::RemoveAllAnimations(VisualElement& target)
382 {
383         __pRootTransaction->RemoveChildrenAllAnimations(target);
384 }
385
386 VisualElementAnimation*
387 _AnimationManager::GetAnimationN(VisualElement& target, const Tizen::Base::String& keyName) const
388 {
389         VisualElementAnimation* pAnimation = const_cast< VisualElementAnimation* >(__pRootTransaction->GetChildrenAnimation(target, keyName));
390
391         if (pAnimation != null)
392         {
393                 SetLastResult(E_SUCCESS);
394                 return pAnimation->CloneN();
395         }
396
397         SetLastResult(E_OBJ_NOT_FOUND);
398         return null;
399 }
400
401 bool
402 _AnimationManager::DoesAnimationExist(VisualElement& target, const Tizen::Base::String& keyName) const
403 {
404         return (__pRootTransaction->GetChildrenAnimation(target, keyName) != null);
405 }
406
407 VisualElementAnimation*
408 _AnimationManager::GetAnimationForPropertyN(VisualElement& target, const Tizen::Base::String& property) const
409 {
410         VisualElementAnimation* pAnimation = const_cast< VisualElementAnimation* >(__pRootTransaction->GetChildrenAnimationByProperty(target, property));
411
412         if (pAnimation != null)
413         {
414                 SetLastResult(E_SUCCESS);
415                 return pAnimation->CloneN();
416         }
417
418         SetLastResult(E_OBJ_NOT_FOUND);
419         return null;
420 }
421
422 int
423 _AnimationManager::BeginTransaction(void)
424 {
425         SysTryReturn(NID_UI_ANIM, (__pCurrentTransaction != null), -1, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Current transaction is null.");
426
427         _TransactionNode* pNode = new (std::nothrow) _TransactionNode(*__pCurrentTransaction);
428         SysTryReturn(NID_UI_ANIM, (pNode != null), -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _TransactionNode.");
429
430         result r = GetLastResult();
431         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to create _TransactionNode instance.", GetErrorMessage(r));
432
433         r = __pCurrentTransaction->AddChild(*pNode);
434         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to add child.", GetErrorMessage(r));
435
436         __pCurrentTransaction = pNode;
437         __pCurrentTransactionExceptGroup = pNode;
438
439         pNode->SetDefaultEventListener(__pDefaultTransactionEventListener);
440
441         return pNode->GetId();
442
443 CATCH:
444         delete pNode;
445
446         return -1;
447 }
448
449 int
450 _AnimationManager::BeginGroupTransaction(VisualElement& target, const Tizen::Base::String* pKeyName, VisualElementAnimation& animation)
451 {
452         SysTryReturn(NID_UI_ANIM, (__pCurrentTransaction != null), -1, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Current transaction is null.");
453
454         if (pKeyName != null && pKeyName->IsEmpty() == false)
455         {
456                 SysTryReturn(NID_UI_ANIM, (DoesAnimationExist(target, *pKeyName) == false), 0, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(s) is used. Animation with keyName exists.");
457         }
458
459         _AnimationGroupNode* pNode = new (std::nothrow) _AnimationGroupNode(target, pKeyName, animation);
460         SysTryReturn(NID_UI_ANIM, (pNode != null), -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _AnimationNode.");
461
462         result r = GetLastResult();
463         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to _AnimationGroupNode instance.", GetErrorMessage(r));
464
465         r = __pCurrentTransaction->AddChild(*pNode);
466         SysTryCatch(NID_UI_ANIM, r == E_SUCCESS, , r, "[%s] Failed to add a child.", GetErrorMessage(r));
467
468         __pCurrentTransaction = pNode;
469
470         return pNode->GetId();
471
472 CATCH:
473
474         delete pNode;
475
476         return -1;
477 }
478
479 result
480 _AnimationManager::CommitTransaction(void)
481 {
482         SysTryReturnResult(NID_UI_ANIM, __pCurrentTransaction != null, E_SYSTEM, "A system error has been occurred. Current transaction is null.");
483         SysTryReturnResult(NID_UI_ANIM, __pCurrentTransaction != __pRootTransaction, E_INVALID_OPERATION, "Transaction isn't opened.");
484
485         _TransactionNode* pParentTransaction = __pCurrentTransaction->GetParent();
486
487         if (__pCurrentTransaction->IsEmpty())
488         {
489                 pParentTransaction->RemoveChild(*__pCurrentTransaction);
490         }
491         else
492         {
493                 if (pParentTransaction == __pRootTransaction && __pRootTransaction->IsEmpty() == false)
494                 {
495                         __pCurrentTransaction->SetChildrenBaseTime(_AnimationTime::GetTime());
496
497                         SetAnimatorEnabled(true);
498                 }
499
500                 __pCurrentTransaction->Commit();
501         }
502
503         __pCurrentTransaction = pParentTransaction;
504
505         if (dynamic_cast< _AnimationGroupNode* > (pParentTransaction) == null)
506         {
507                 __pCurrentTransactionExceptGroup = pParentTransaction;
508         }
509
510         return E_SUCCESS;
511 }
512
513 result
514 _AnimationManager::DiscardTransaction(void)
515 {
516         SysTryReturnResult(NID_UI_ANIM, (__pCurrentTransaction != __pRootTransaction), E_INVALID_OPERATION, "Transaction isn't opened.");
517
518         _TransactionNode* pLastChild = __pRootTransaction->GetLastChild();
519         SysTryReturnResult(NID_UI_ANIM, pLastChild != null, E_SYSTEM, "A system error has been occurred. Last child is null.");
520
521         __pRootTransaction->RemoveChild(*pLastChild);
522
523         __pCurrentTransaction = __pRootTransaction;
524         __pCurrentTransactionExceptGroup = __pRootTransaction;
525
526         return E_SUCCESS;
527 }
528
529 result
530 _AnimationManager::StopTransaction(int transactionId)
531 {
532         _TransactionNode* pChild = __pRootTransaction->GetChild(transactionId);
533
534         if (pChild != null && pChild->IsCommitted(true) == true)
535         {
536                 __pRootTransaction->RemoveChild(transactionId);
537
538                 return E_SUCCESS;
539         }
540
541         return E_INVALID_ARG;
542 }
543
544 result
545 _AnimationManager::CancelTransaction(int transactionId)
546 {
547         if (__pCurrentTransaction->GetId() == transactionId)
548         {
549                 _TransactionNode* pParentTransaction = __pCurrentTransaction->GetParent();
550
551                 __pCurrentTransaction = pParentTransaction;
552
553                 if (dynamic_cast< _AnimationGroupNode* > (pParentTransaction) == null)
554                 {
555                         __pCurrentTransactionExceptGroup = pParentTransaction;
556                 }
557         }
558
559         __pRootTransaction->RemoveChild(transactionId);
560
561         return E_SUCCESS;
562 }
563
564 bool
565 _AnimationManager::IsTransactionRunning(int transactionId) const
566 {
567         _TransactionNode* pChild = __pRootTransaction->GetChild(transactionId);
568
569         if (pChild != null)
570         {
571                 return pChild->IsRunning();
572         }
573
574         return false;
575 }
576
577 bool
578 _AnimationManager::IsImplicitAnimationEnabled(void) const
579 {
580         return __pCurrentTransactionExceptGroup->IsImplicitAnimationEnabled();
581 }
582
583 _TransactionNode*
584 _AnimationManager::GetCurrentTransaction(bool withGroup) const
585 {
586         if (__pCurrentTransaction == __pRootTransaction)
587         {
588                 return null;
589         }
590
591         if (withGroup == false)
592         {
593                 return __pCurrentTransactionExceptGroup;
594         }
595
596         return __pCurrentTransaction;
597 }
598
599 void
600 _AnimationManager::SetTransactionEventListener(const IAnimationTransactionEventListener* pListener)
601 {
602         static_cast< _TransactionEventListener* >(__pDefaultTransactionEventListener)->SetTransactionEventListener(pListener);
603 }
604
605 void
606 _AnimationManager::ProcessAnimationTick(void)
607 {
608         if (unlikely(__isInAnimationTick))
609         {
610                 return;
611         }
612
613         __isInAnimationTick = true;
614
615         // process transactions;
616         __pRootTransaction->ProcessAnimationTick(_AnimationTime::GetTime());
617
618         if (likely(__pRootTransaction->IsEmpty() == true))
619         {
620                 SetAnimatorEnabled(false);
621         }
622
623         __isInAnimationTick = false;
624 }
625
626
627 }}}   // Tizen::Ui::Animations
628