From 487dbc52b9fbe56f42abafc5ff5f09b54b79765f Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Mon, 4 Jun 2018 16:04:13 +0900 Subject: [PATCH] Add IdleEnterer callback - Add IdleEnterer callback - Use IdleEnterer callback insteat of idle callback to process events - Add a parameter to check a return value of the callback Change-Id: Ie5d34def02ded8db563cf4f98940b1c30b199063 --- .../adaptor-framework/application-devel.cpp | 7 +- .../adaptor-framework/application-devel.h | 18 ++++ dali/integration-api/adaptor.h | 11 +- dali/internal/adaptor/common/adaptor-impl.cpp | 24 ++++- dali/internal/adaptor/common/adaptor-impl.h | 18 +++- dali/internal/adaptor/common/adaptor.cpp | 4 +- dali/internal/adaptor/common/application-impl.cpp | 8 +- dali/internal/adaptor/common/application-impl.h | 4 +- .../system/common/callback-manager-ecore.cpp | 112 +++++++++++++++++---- .../system/common/callback-manager-ecore.h | 14 ++- dali/internal/system/common/callback-manager.h | 40 +++++++- dali/public-api/adaptor-framework/application.cpp | 2 +- dali/public-api/adaptor-framework/application.h | 1 + 13 files changed, 224 insertions(+), 39 deletions(-) diff --git a/dali/devel-api/adaptor-framework/application-devel.cpp b/dali/devel-api/adaptor-framework/application-devel.cpp index 8ed500a..85a4347 100644 --- a/dali/devel-api/adaptor-framework/application-devel.cpp +++ b/dali/devel-api/adaptor-framework/application-devel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,11 @@ void PreInitialize( int* argc, char** argv[] ) Internal::Adaptor::Application::PreInitialize( argc, argv ); } +bool AddIdleWithReturnValue( Application application, CallbackBase* callback ) +{ + return Internal::Adaptor::GetImplementation( application ).AddIdle( callback, true ); +} + } // namespace DevelApplication } // namespace Dali diff --git a/dali/devel-api/adaptor-framework/application-devel.h b/dali/devel-api/adaptor-framework/application-devel.h index 05bc65a..5ffbd2e 100644 --- a/dali/devel-api/adaptor-framework/application-devel.h +++ b/dali/devel-api/adaptor-framework/application-devel.h @@ -35,6 +35,24 @@ namespace DevelApplication */ DALI_ADAPTOR_API void PreInitialize( int* argc, char** argv[] ); +/** + * @brief Ensures that the function passed in is called from the main loop when it is idle. + * @param[in] application A handle to the Application + * @param[in] callback The function to call + * @return @c true if added successfully, @c false otherwise + * + * @note Function must be called from main event thread only + * + * A callback of the following type should be used: + * @code + * bool MyFunction(); + * @endcode + * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback. + * + * @note Ownership of the callback is passed onto this class. + */ +DALI_ADAPTOR_API bool AddIdleWithReturnValue( Application application, CallbackBase* callback ); + } // namespace DevelApplication } // namespace Dali diff --git a/dali/integration-api/adaptor.h b/dali/integration-api/adaptor.h index e3a2115..6ce71a3 100755 --- a/dali/integration-api/adaptor.h +++ b/dali/integration-api/adaptor.h @@ -184,17 +184,24 @@ public: * @brief Ensures that the function passed in is called from the main loop when it is idle. * @note Function must be called from the main event thread only. * - * A callback of the following type may be used: + * Callbacks of the following types may be used: * @code * void MyFunction(); * @endcode + * This callback will be deleted once it is called. + * + * @code + * bool MyFunction(); + * @endcode + * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback. * * @param[in] callback The function to call. + * @param[in] hasReturnValue Sould be set to true if the callback function has a return value. * @return true if added successfully, false otherwise * * @note Ownership of the callback is passed onto this class. */ - bool AddIdle( CallbackBase* callback ); + bool AddIdle( CallbackBase* callback, bool hasReturnValue ); /** * @brief Removes a previously added @p callback. diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index af8a13e..0a2708a 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -484,14 +484,14 @@ Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode) return mTtsPlayers[mode]; } -bool Adaptor::AddIdle( CallbackBase* callback, bool forceAdd ) +bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd ) { bool idleAdded(false); // Only add an idle if the Adaptor is actually running if( RUNNING == mState || READY == mState || forceAdd ) { - idleAdded = mCallbackManager->AddIdleCallback( callback ); + idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue ); } return idleAdded; @@ -735,7 +735,7 @@ void Adaptor::RequestProcessEventsOnIdle( bool forceProcess ) // and we haven't installed the idle notification if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) ) { - mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess ); + mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess ); } } @@ -909,6 +909,24 @@ void Adaptor::SetRootLayoutDirection( std::string locale ) static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) ); } +bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd ) +{ + bool idleAdded( false ); + + // Only add an idle if the Adaptor is actually running + if( RUNNING == mState || READY == mState || forceAdd ) + { + idleAdded = mCallbackManager->AddIdleEntererCallback( callback ); + } + + return idleAdded; +} + +void Adaptor::RemoveIdleEnterer( CallbackBase* callback ) +{ + mCallbackManager->RemoveIdleEntererCallback( callback ); +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/adaptor/common/adaptor-impl.h b/dali/internal/adaptor/common/adaptor-impl.h index 5588cd8..432bdcd 100755 --- a/dali/internal/adaptor/common/adaptor-impl.h +++ b/dali/internal/adaptor/common/adaptor-impl.h @@ -209,7 +209,7 @@ public: // AdaptorInternalServices implementation /** * @copydoc Dali::Adaptor::AddIdle() */ - virtual bool AddIdle( CallbackBase* callback, bool forceAdd ); + virtual bool AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd ); /** * @copydoc Dali::Adaptor::RemoveIdle() @@ -537,6 +537,22 @@ private: */ void SetupSystemInformation(); + /** + * Adds a callback to be run when entering an idle state. + * + * A callback of the following type should be used: + * @code + * bool MyFunction(); + * @endcode + * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback. + */ + bool AddIdleEnterer( CallbackBase* callback, bool forceAdd ); + + /** + * Removes a previously added the idle enterer callback. + */ + void RemoveIdleEnterer( CallbackBase* callback ); + private: /** diff --git a/dali/internal/adaptor/common/adaptor.cpp b/dali/internal/adaptor/common/adaptor.cpp index 4086605..b0c6047 100755 --- a/dali/internal/adaptor/common/adaptor.cpp +++ b/dali/internal/adaptor/common/adaptor.cpp @@ -78,9 +78,9 @@ void Adaptor::Stop() mImpl->Stop(); } -bool Adaptor::AddIdle( CallbackBase* callback ) +bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue ) { - return mImpl->AddIdle( callback, false ); + return mImpl->AddIdle( callback, hasReturnValue, false ); } void Adaptor::RemoveIdle( CallbackBase* callback ) diff --git a/dali/internal/adaptor/common/application-impl.cpp b/dali/internal/adaptor/common/application-impl.cpp index e5a4f45..d2ccfda 100644 --- a/dali/internal/adaptor/common/application-impl.cpp +++ b/dali/internal/adaptor/common/application-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -186,7 +186,7 @@ void Application::Quit() { // Actually quit the application. // Force a call to Quit even if adaptor is not running. - Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), true ); + Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true ); } void Application::QuitFromMainLoop() @@ -372,9 +372,9 @@ void Application::OnResize(Dali::Adaptor& adaptor) mResizeSignal.Emit( application ); } -bool Application::AddIdle( CallbackBase* callback ) +bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue ) { - return mAdaptor->AddIdle( callback ); + return mAdaptor->AddIdle( callback, hasReturnValue ); } std::string Application::GetRegion() const diff --git a/dali/internal/adaptor/common/application-impl.h b/dali/internal/adaptor/common/application-impl.h index 239f373..2a16014 100644 --- a/dali/internal/adaptor/common/application-impl.h +++ b/dali/internal/adaptor/common/application-impl.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_APPLICATION_H__ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,7 +114,7 @@ public: /** * @copydoc Dali::Application::AddIdle() */ - bool AddIdle( CallbackBase* callback ); + bool AddIdle( CallbackBase* callback, bool hasReturnValue ); /** * @copydoc Dali::Application::GetAdaptor(); diff --git a/dali/internal/system/common/callback-manager-ecore.cpp b/dali/internal/system/common/callback-manager-ecore.cpp index a05d2cc..d04118d 100644 --- a/dali/internal/system/common/callback-manager-ecore.cpp +++ b/dali/internal/system/common/callback-manager-ecore.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,10 +47,12 @@ struct CallbackData /** * Constructor */ - CallbackData( CallbackBase* callback ) - : mCallback(callback), - mRemoveFromContainerFunction(NULL), - mIdler(NULL) + CallbackData( CallbackBase* callback, bool hasReturnValue ) + : mCallback( callback ), + mRemoveFromContainerFunction( NULL ), + mIdler( NULL ), + mIdleEnterer( NULL ), + mHasReturnValue( hasReturnValue ) { } /** @@ -62,10 +64,12 @@ struct CallbackData delete mRemoveFromContainerFunction; } - CallbackBase* mCallback; ///< call back + CallbackBase* mCallback; ///< call back CallbackBase* mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container - Ecore_Idler* mIdler; ///< ecore idler - }; + Ecore_Idler* mIdler; ///< ecore idler + Ecore_Idle_Enterer* mIdleEnterer; ///< ecore idle enterer + bool mHasReturnValue; ///< true if the callback function has a return value. +}; namespace { @@ -75,19 +79,40 @@ namespace */ Eina_Bool IdleCallback(void *data) { + Eina_Bool ret = ECORE_CALLBACK_CANCEL; // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del CallbackData *callbackData = static_cast< CallbackData * >( data ); - // remove callback data from the container - CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData ); + if( callbackData->mHasReturnValue ) + { + // run the function + bool retValue = CallbackBase::ExecuteReturn< bool >( *callbackData->mCallback ); + if( retValue ) + { + // keep the callback + ret = ECORE_CALLBACK_RENEW; + } + else + { + // remove callback data from the container + CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData ); + + // delete our data + delete callbackData; + } + } + else + { + // remove callback data from the container + CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData ); - // run the function - CallbackBase::Execute( *callbackData->mCallback ); + // run the function + CallbackBase::Execute( *callbackData->mCallback ); - // delete our data - delete callbackData; + // delete our data + delete callbackData; + } - // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del - return ECORE_CALLBACK_CANCEL; + return ret; } } // unnamed namespace @@ -116,14 +141,14 @@ void EcoreCallbackManager::Stop() } -bool EcoreCallbackManager::AddIdleCallback( CallbackBase* callback ) +bool EcoreCallbackManager::AddIdleCallback( CallbackBase* callback, bool hasReturnValue ) { if( !mRunning ) { return false; } - CallbackData* callbackData = new CallbackData( callback ); + CallbackData* callbackData = new CallbackData( callback, hasReturnValue ); callbackData->mRemoveFromContainerFunction = MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer ); @@ -157,6 +182,47 @@ void EcoreCallbackManager::RemoveIdleCallback( CallbackBase* callback ) } } +bool EcoreCallbackManager::AddIdleEntererCallback( CallbackBase* callback ) +{ + if( !mRunning ) + { + return false; + } + + CallbackData* callbackData = new CallbackData( callback, true ); + + callbackData->mRemoveFromContainerFunction = MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer ); + + // add the call back to the container + mCallbackContainer.push_front( callbackData ); + + // add the idler + callbackData->mIdleEnterer = ecore_idle_enterer_add( IdleCallback, callbackData ); + + DALI_ASSERT_ALWAYS( ( callbackData->mIdleEnterer != NULL ) && "Idle method not created" ); + + return true; +} + +void EcoreCallbackManager::RemoveIdleEntererCallback( CallbackBase* callback ) +{ + for( CallbackList::iterator it = mCallbackContainer.begin(), + endIt = mCallbackContainer.end(); + it != endIt; + ++it ) + { + CallbackData* data = *it; + + if( data->mCallback == callback ) + { + // remove callback data from the container. + CallbackBase::Execute( *data->mRemoveFromContainerFunction, data ); + + ecore_idle_enterer_del( data->mIdleEnterer ); + } + } +} + void EcoreCallbackManager::RemoveCallbackFromContainer(CallbackData *callbackData) { mCallbackContainer.remove(callbackData); @@ -169,10 +235,16 @@ void EcoreCallbackManager::RemoveAllCallbacks() { CallbackData* data = (*iter); - ecore_idler_del( data->mIdler ); + if( data->mIdler ) + { + ecore_idler_del( data->mIdler ); + } + else if( data->mIdleEnterer ) + { + ecore_idle_enterer_del( data->mIdleEnterer ); + } delete data; - } mCallbackContainer.clear(); } diff --git a/dali/internal/system/common/callback-manager-ecore.h b/dali/internal/system/common/callback-manager-ecore.h index de5035d..10f437f 100644 --- a/dali/internal/system/common/callback-manager-ecore.h +++ b/dali/internal/system/common/callback-manager-ecore.h @@ -2,7 +2,7 @@ #define __DALI_ECORE_CALLBACK_MANAGER_H__ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ public: /** * @copydoc CallbackManager::AddIdleCallback() */ - virtual bool AddIdleCallback( CallbackBase* callback ); + virtual bool AddIdleCallback( CallbackBase* callback, bool hasReturnValue ); /** * @copydoc CallbackManager::RemoveIdleCallback() @@ -67,6 +67,16 @@ public: virtual void RemoveIdleCallback( CallbackBase* callback ); /** + * @copydoc CallbackManager::AddIdleEntererCallback() + */ + virtual bool AddIdleEntererCallback( CallbackBase* callback ); + + /** + * @copydoc CallbackManager::RemoveIdleEntererCallback() + */ + virtual void RemoveIdleEntererCallback( CallbackBase* callback ); + + /** * @copydoc CallbackManager::Start() */ virtual void Start(); diff --git a/dali/internal/system/common/callback-manager.h b/dali/internal/system/common/callback-manager.h index 63870f0..463fea6 100644 --- a/dali/internal/system/common/callback-manager.h +++ b/dali/internal/system/common/callback-manager.h @@ -55,11 +55,23 @@ public: * @brief Adds a @p callback to be run on idle. * @note Must be called from the main thread only. * + * Callbacks of the following types may be used: + * @code + * void MyFunction(); + * @endcode + * This callback will be deleted once it is called. + * + * @code + * bool MyFunction(); + * @endcode + * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback. + * * @param[in] callback custom callback function. + * @param[in] hasReturnValue Sould be set to true if the callback function has a return value. * * @return true on success */ - virtual bool AddIdleCallback( CallbackBase* callback ) = 0; + virtual bool AddIdleCallback( CallbackBase* callback, bool hasReturnValue ) = 0; /** * @brief Removes a previously added @p callback. @@ -72,6 +84,32 @@ public: virtual void RemoveIdleCallback( CallbackBase* callback ) = 0; /** + * @brief Adds a @p callback to be run when entering an idle state. + * @note Must be called from the main thread only. + * + * A callback of the following type should be used: + * @code + * bool MyFunction(); + * @endcode + * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback. + * + * @param[in] callback custom callback function. + * + * @return true on success + */ + virtual bool AddIdleEntererCallback( CallbackBase* callback ) = 0; + + /** + * @brief Removes a previously added the idle enterer callback. + * @note Must be called from main thread only. + * + * Does nothing if the @p callback doesn't exist. + * + * @param[in] callback The callback to be removed. + */ + virtual void RemoveIdleEntererCallback( CallbackBase* callback ) = 0; + + /** * Starts the callback manager. */ virtual void Start() = 0; diff --git a/dali/public-api/adaptor-framework/application.cpp b/dali/public-api/adaptor-framework/application.cpp index 1604932..3405faf 100644 --- a/dali/public-api/adaptor-framework/application.cpp +++ b/dali/public-api/adaptor-framework/application.cpp @@ -164,7 +164,7 @@ void Application::Quit() bool Application::AddIdle( CallbackBase* callback ) { - return Internal::Adaptor::GetImplementation(*this).AddIdle( callback ); + return Internal::Adaptor::GetImplementation(*this).AddIdle( callback, false ); } Window Application::GetWindow() diff --git a/dali/public-api/adaptor-framework/application.h b/dali/public-api/adaptor-framework/application.h index 638b9be..b24742b 100644 --- a/dali/public-api/adaptor-framework/application.h +++ b/dali/public-api/adaptor-framework/application.h @@ -267,6 +267,7 @@ public: * @code * void MyFunction(); * @endcode + * This callback will be deleted once it is called. * * @note Ownership of the callback is passed onto this class. */ -- 2.7.4