2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
19 * @file FUiAnim_AnimationManager.cpp
20 * @brief This file contains implementation of _AnimationManager class
22 * This file contains implementation _AnimationManager class.
27 #include <FBaseSysLog.h>
29 #include <FUiAnimLinearTimingFunction.h>
30 #include <FUiAnimVisualElementPropertyAnimation.h>
31 #include <FUiAnimVisualElement.h>
32 #include <FUiAnimIAnimationTransactionEventListener.h>
34 #include "FUi_EcoreEvas.h"
35 #include "FUi_EcoreEvasMgr.h"
37 #include "FUiAnim_RootVisualElement.h"
38 #include "FUiAnim_VisualElementImpl.h"
39 #include "FUiAnim_VisualElementAnimationImpl.h"
40 #include "FUiAnim_TransactionNode.h"
41 #include "FUiAnim_AnimationGroupNode.h"
42 #include "FUiAnim_VisualElementAnimationVariantInterpolator.h"
43 #include "FUiAnim_AnimationManager.h"
44 #include "FUiAnim_DisplayManager.h"
47 Ecore_Animator* pAnimator = null;
50 __AnimatorCallback(void* pData)
52 #ifndef VE_VSYNC_UPDATE
53 pAnimationManager->ProcessAnimationTick();
59 namespace Tizen { namespace Ui { namespace Animations
62 // default transaction event listener
63 class _TransactionEventListener
64 : public IAnimationTransactionEventListener
65 , virtual public Tizen::Base::Runtime::IEventListener
68 _TransactionEventListener(void);
69 virtual ~_TransactionEventListener(void);
71 void SetTransactionEventListener(const IAnimationTransactionEventListener* pListener);
73 virtual void OnAnimationTransactionStarted(int transactionId);
74 virtual void OnAnimationTransactionStopped(int transactionId);
75 virtual void OnAnimationTransactionFinished(int transactionId);
78 IAnimationTransactionEventListener* __pEventListener;
81 _TransactionEventListener::_TransactionEventListener(void)
82 : __pEventListener(null)
86 _TransactionEventListener::~_TransactionEventListener(void)
91 _TransactionEventListener::SetTransactionEventListener(const IAnimationTransactionEventListener* pListener)
93 __pEventListener = const_cast< IAnimationTransactionEventListener* >(pListener);
97 _TransactionEventListener::OnAnimationTransactionStarted(int transactionId)
101 __pEventListener->OnAnimationTransactionStarted(transactionId);
106 _TransactionEventListener::OnAnimationTransactionStopped(int transactionId)
108 if (__pEventListener)
110 __pEventListener->OnAnimationTransactionStopped(transactionId);
115 _TransactionEventListener::OnAnimationTransactionFinished(int transactionId)
117 if (__pEventListener)
119 __pEventListener->OnAnimationTransactionFinished(transactionId);
123 _AnimationManager* _AnimationManager::__pInstance = null;
125 _AnimationManager::_AnimationManager(void)
126 : __isAnimating(false)
127 , __isInAnimationTick(false)
128 , __pRootTransaction(null)
129 , __pCurrentTransaction(null)
130 , __pCurrentTransactionExceptGroup(null)
131 , __pDefaultTransactionEventListener(null)
132 , __pDefaultTimingFunction(null)
133 , __pDefaultInterpolator(null)
138 _AnimationManager::~_AnimationManager(void)
144 _AnimationManager::GetInstance(void)
150 _AnimationManager::CreateInstance(void)
152 SysAssertf((__pInstance == null), "Already created.");
154 __pInstance = new (std::nothrow) _AnimationManager();
155 SysTryReturnResult(NID_UI_ANIM, __pInstance != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
157 result r = __pInstance->Construct();
160 SysLogException(NID_UI_ANIM, r, "[%s] Failed to construct _AnimationManager instance.", GetErrorMessage(r));
172 _AnimationManager::ReleaseInstance(void)
174 if (__pInstance != null)
176 __pInstance->Release();
184 _AnimationManager::Release(void)
188 ecore_animator_del(pAnimator);
192 if (__pCurrentTransaction)
194 delete __pCurrentTransaction;
195 __pCurrentTransaction = null;
198 __committedList.RemoveAllNodes();
200 delete __pRootTransaction;
201 __pRootTransaction = null;
203 delete __pDefaultTransactionEventListener;
204 __pDefaultTransactionEventListener = null;
206 delete __pDefaultTimingFunction;
207 __pDefaultTimingFunction = null;
209 delete __pDefaultInterpolator;
210 __pDefaultInterpolator = null;
216 _AnimationManager::Construct(void)
218 result r = E_SUCCESS;
220 __committedList.Construct();
222 __pRootTransaction = new (std::nothrow) _TransactionNode();
223 SysTryReturnResult(NID_UI_ANIM, (__pRootTransaction != null), E_OUT_OF_MEMORY, "Memory allocation failed. Failed to create root transaction");
226 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to create root transaction.", GetErrorMessage(r));
228 __pRootTransaction->Commit(); //root is always committed.
230 __pDefaultTransactionEventListener = new (std::nothrow) _TransactionEventListener();
231 SysTryCatch(NID_UI_ANIM, __pDefaultTransactionEventListener != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
232 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default transaction event listener.");
234 __pDefaultTimingFunction = new (std::nothrow) LinearTimingFunction();
235 SysTryCatch(NID_UI_ANIM, __pDefaultTimingFunction != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
236 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default timing function map.");
238 __pDefaultInterpolator = new (std::nothrow) _VisualElementAnimationVariantInterpolator();
239 SysTryCatch(NID_UI_ANIM, __pDefaultInterpolator != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
240 "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create default interpolator.");
245 delete __pRootTransaction;
246 delete __pDefaultTransactionEventListener;
247 delete __pDefaultTimingFunction;
248 delete __pDefaultInterpolator;
254 _AnimationManager::SetAnimatorEnabled(bool animating)
256 #ifdef VE_VSYNC_UPDATE
257 __isAnimating = animating;
259 if (likely(animating))
261 if (likely(pAnimator == null))
263 pAnimator = (Ecore_Animator*)ecore_animator_add(__AnimatorCallback, _AnimationManager::GetInstance());
270 ecore_animator_del(pAnimator);
277 _DisplayManager* pDisplayManager = _DisplayManager::GetInstance();
280 pDisplayManager->AddWakeUpEvent();
287 _AnimationManager::AddAnimation(VisualElement& target, const Tizen::Base::String* pKeyName, VisualElementAnimation& animation)
289 SysTryReturnResult(NID_UI_ANIM, (CreateCurrentTransactionIfNeeded() == true), E_SYSTEM, "A system error has been occurred. Current transaction is null.");
291 if (pKeyName != null && pKeyName->IsEmpty() == false)
293 SysTryReturnResult(NID_UI_ANIM, (DoesAnimationExist(target, *pKeyName) == false), E_OBJ_ALREADY_EXIST, "Animation with keyName already exists. key name = %ls", pKeyName->GetPointer());
296 result r = E_SUCCESS;
298 if (_VisualElementAnimationImpl::GetInstance(animation)->GetTimingFunction() == null)
300 animation.SetTimingFunction(__pDefaultTimingFunction);
303 if (_VisualElementAnimationImpl::GetInstance(animation)->GetValueInterpolator() == null)
305 animation.SetValueInterpolator(__pDefaultInterpolator);
308 // current trasaction
309 r = __pCurrentTransaction->AddAnimation(target, pKeyName, animation);
310 SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Failed to add animation.");
312 if (__pCurrentTransaction->IsCommitted() && __isAnimating == false)
314 SetAnimatorEnabled(true);
321 _AnimationManager::RemoveAnimation(VisualElement& target, const Tizen::Base::String& keyName)
323 result r = E_SUCCESS;
325 if (__pCurrentTransaction)
327 r = __pCurrentTransaction->RemoveChildrenAnimation(target, keyName);
335 if (__committedList.IsEmpty() == false)
337 int committedCount = __committedList.GetCount();
339 _TransactionNode* pNode = null;
341 for(int index = 0; index < committedCount; index++)
343 pNode = __committedList.GetNodeAt(index);
347 r = pNode->RemoveChildrenAnimation(target, keyName);
357 return __pRootTransaction->RemoveChildrenAnimation(target, keyName);
361 _AnimationManager::RemoveAnimationByProperty(VisualElement& target, const Tizen::Base::String& property)
363 if (__pCurrentTransaction)
365 __pCurrentTransaction->RemoveChildrenAnimationByProperty(target, property);
368 if (__committedList.IsEmpty() == false)
370 int committedCount = __committedList.GetCount();
372 _TransactionNode* pNode = null;
374 for(int index = 0; index < committedCount; index++)
376 pNode = __committedList.GetNodeAt(index);
380 pNode->RemoveChildrenAnimationByProperty(target, property);
385 __pRootTransaction->RemoveChildrenAnimationByProperty(target, property);
389 _AnimationManager::RemoveAllAnimations(VisualElement& target)
391 if (__pCurrentTransaction)
393 __pCurrentTransaction->RemoveChildrenAllAnimations(target);
396 if (__committedList.IsEmpty() == false)
398 int committedCount = __committedList.GetCount();
400 _TransactionNode* pNode = null;
402 for(int index = 0; index < committedCount; index++)
404 pNode = __committedList.GetNodeAt(index);
408 pNode->RemoveChildrenAllAnimations(target);
413 __pRootTransaction->RemoveChildrenAllAnimations(target);
416 const VisualElementAnimation*
417 _AnimationManager::GetAnimation(VisualElement& target, const Tizen::Base::String& keyName) const
419 const VisualElementAnimation* pAnimation = null;
421 if (__pCurrentTransaction)
423 pAnimation = __pCurrentTransaction->GetChildrenAnimation(target, keyName);
431 if (__committedList.IsEmpty() == false)
433 int committedCount = __committedList.GetCount();
435 _TransactionNode* pNode = null;
437 for(int index = 0; index < committedCount; index++)
439 pNode = __committedList.GetNodeAt(index);
443 pAnimation = pNode->GetChildrenAnimation(target, keyName);
453 return __pRootTransaction->GetChildrenAnimation(target, keyName);
456 VisualElementAnimation*
457 _AnimationManager::GetAnimationN(VisualElement& target, const Tizen::Base::String& keyName) const
459 const VisualElementAnimation* pAnimation = GetAnimation(target, keyName);
461 if (pAnimation != null)
463 SetLastResult(E_SUCCESS);
464 return pAnimation->CloneN();
467 SetLastResult(E_OBJ_NOT_FOUND);
472 _AnimationManager::DoesAnimationExist(VisualElement& target, const Tizen::Base::String& keyName) const
474 return (GetAnimation(target, keyName) != null);
478 _AnimationManager::BeginTransaction(void)
480 CommitCurrentTransactionIfNeeded();
482 _TransactionNode* pNode = null;
484 if (__pCurrentTransaction == null)
486 pNode = new (std::nothrow) _TransactionNode(*__pRootTransaction);
487 SysTryReturn(NID_UI_ANIM, (pNode != null), -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _TransactionNode.");
489 result r = GetLastResult();
490 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to create _TransactionNode instance.", GetErrorMessage(r));
494 pNode = new (std::nothrow) _TransactionNode(*__pCurrentTransaction);
495 SysTryReturn(NID_UI_ANIM, (pNode != null), -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _TransactionNode.");
497 result r = GetLastResult();
498 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to create _TransactionNode instance.", GetErrorMessage(r));
500 r = __pCurrentTransaction->AddChild(*pNode);
501 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to add child.", GetErrorMessage(r));
504 __pCurrentTransaction = pNode;
505 __pCurrentTransactionExceptGroup = pNode;
507 pNode->SetDefaultEventListener(__pDefaultTransactionEventListener);
509 return pNode->GetId();
518 _AnimationManager::BeginGroupTransaction(VisualElement& target, const Tizen::Base::String* pKeyName, VisualElementAnimation& animation)
520 SysTryReturn(NID_UI_ANIM, (CreateCurrentTransactionIfNeeded() == true), -1, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Current transaction is null.");
522 if (pKeyName != null && pKeyName->IsEmpty() == false)
524 SysTryReturn(NID_UI_ANIM, (DoesAnimationExist(target, *pKeyName) == false), -1, E_OBJ_ALREADY_EXIST, "[E_OBJ_ALREADY_EXIST] Animation with keyName already exists. key name = %ls", pKeyName->GetPointer());
527 _AnimationGroupNode* pNode = new (std::nothrow) _AnimationGroupNode(target, pKeyName, animation);
528 SysTryReturn(NID_UI_ANIM, (pNode != null), -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _AnimationNode.");
530 result r = GetLastResult();
531 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , r, "[%s] Failed to _AnimationGroupNode instance.", GetErrorMessage(r));
533 r = __pCurrentTransaction->AddChild(*pNode);
534 SysTryCatch(NID_UI_ANIM, r == E_SUCCESS, , r, "[%s] Failed to add a child.", GetErrorMessage(r));
536 __pCurrentTransaction = pNode;
538 return pNode->GetId();
548 _AnimationManager::CommitTransaction(void)
550 SysTryReturnResult(NID_UI_ANIM, __pCurrentTransaction != null, E_SYSTEM, "A system error has been occurred. Current transaction is null.");
552 _TransactionNode* pParentTransaction = __pCurrentTransaction->GetParent();
554 if (__pCurrentTransaction->IsEmpty())
556 if (pParentTransaction)
558 pParentTransaction->RemoveChild(*__pCurrentTransaction);
562 delete __pCurrentTransaction;
567 __pCurrentTransaction->Commit();
569 if (pParentTransaction == null)
571 __committedList.Add(__pCurrentTransaction);
573 if (__isAnimating == false)
575 SetAnimatorEnabled(true);
580 __pCurrentTransaction = pParentTransaction;
582 if (dynamic_cast< _AnimationGroupNode* > (pParentTransaction) == null)
584 __pCurrentTransactionExceptGroup = pParentTransaction;
591 _AnimationManager::DiscardTransaction(void)
593 SysTryReturnResult(NID_UI_ANIM, (__pCurrentTransaction != null && __pCurrentTransaction->IsCommitted() == false), E_INVALID_OPERATION, "Transaction isn't opened.");
595 delete __pCurrentTransaction;
597 __pCurrentTransaction = null;
598 __pCurrentTransactionExceptGroup = null;
604 _AnimationManager::DiscardTransaction(int transactionId)
606 SysTryReturnResult(NID_UI_ANIM, (__pCurrentTransaction != null), E_INVALID_OPERATION, "Transaction isn't opened.");
608 if (__pCurrentTransaction->GetId() == transactionId)
610 _TransactionNode* pParentTransaction = __pCurrentTransaction->GetParent();
612 if (pParentTransaction)
614 pParentTransaction->RemoveChild(*__pCurrentTransaction);
618 delete __pCurrentTransaction;
621 __pCurrentTransaction = pParentTransaction;
623 if (dynamic_cast< _AnimationGroupNode* > (pParentTransaction) == null)
625 __pCurrentTransactionExceptGroup = pParentTransaction;
630 __pCurrentTransaction->RemoveChild(transactionId);
637 _AnimationManager::StopTransaction(int transactionId)
639 _TransactionNode* pChild = null;
641 if (__committedList.IsEmpty() == false)
643 int committedCount = __committedList.GetCount();
645 _TransactionNode* pNode = null;
647 for (int index = 0; index < committedCount; index++)
649 pNode = __committedList.GetNodeAt(index);
653 if (pNode->GetId() == transactionId)
657 if (__isInAnimationTick == false)
659 __committedList.RemoveAt(index);
667 pChild = pNode->GetChild(transactionId);
671 pNode->RemoveChild(transactionId);
679 pChild = __pRootTransaction->GetChild(transactionId);
683 __pRootTransaction->RemoveChild(transactionId);
688 return E_INVALID_ARG;
692 _AnimationManager::IsTransactionRunning(int transactionId) const
694 _TransactionNode* pChild = __pRootTransaction->GetChild(transactionId);
698 return pChild->IsRunning();
705 _AnimationManager::IsImplicitAnimationEnabled(void) const
707 if (__pCurrentTransactionExceptGroup)
709 return __pCurrentTransactionExceptGroup->IsImplicitAnimationEnabled();
716 _AnimationManager::GetCurrentTransaction(bool withGroup) const
718 // default transaction is always committed.
719 if (__pCurrentTransaction && __pCurrentTransaction->IsCommitted())
724 if (withGroup == false)
726 return __pCurrentTransactionExceptGroup;
729 return __pCurrentTransaction;
733 _AnimationManager::CreateCurrentTransactionIfNeeded(void)
735 if (__pCurrentTransaction != null)
740 int transactionId = BeginTransaction();
741 SysTryReturn(NID_UI_ANIM, (transactionId >= 0), false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed. Failed to create _TransactionNode.");
743 __pCurrentTransaction->SetDefaultEventListener(null);
745 __pCurrentTransaction->Commit(); // default transaction is always committed.
751 _AnimationManager::CommitCurrentTransactionIfNeeded()
753 // if current transaction is default transaction, only status of default transaction is committed, so must process to commit transaction.
754 if (__pCurrentTransaction != null && __pCurrentTransaction->IsCommitted(true))
761 _AnimationManager::SetTransactionEventListener(const IAnimationTransactionEventListener* pListener)
763 static_cast< _TransactionEventListener* >(__pDefaultTransactionEventListener)->SetTransactionEventListener(pListener);
767 _AnimationManager::ProcessCommittedTransaction(void)
769 if (__committedList.IsEmpty())
774 int committedCount = __committedList.GetCount();
776 _TransactionNode* pNode = null;
779 for(int index = 0; index < committedCount; index++)
781 pNode = __committedList.GetNodeAt(index);
785 pNode->DrawTargets();
786 pNode->SetChildrenBaseTime(_AnimationTime::GetTime());
788 __pRootTransaction->AddChild(*pNode);
790 __committedList.SetAt(null, index);
794 __committedList.RemoveAll();
798 _AnimationManager::ProcessAnimationTick(void)
800 if (unlikely(__isInAnimationTick))
805 __isInAnimationTick = true;
807 CommitCurrentTransactionIfNeeded();
808 ProcessCommittedTransaction();
810 // process transactions;
811 __pRootTransaction->ProcessAnimationTick(_AnimationTime::GetTime());
813 if (likely(__pRootTransaction->IsEmpty() && __committedList.IsEmpty()))
815 SetAnimatorEnabled(false);
818 __isInAnimationTick = false;
822 }}} // Tizen::Ui::Animations