Add IdleEnterer callback 83/180783/4
authorHeeyong Song <heeyong.song@samsung.com>
Mon, 4 Jun 2018 07:04:13 +0000 (16:04 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Fri, 15 Jun 2018 00:37:59 +0000 (00:37 +0000)
- 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

13 files changed:
dali/devel-api/adaptor-framework/application-devel.cpp
dali/devel-api/adaptor-framework/application-devel.h
dali/integration-api/adaptor.h
dali/internal/adaptor/common/adaptor-impl.cpp
dali/internal/adaptor/common/adaptor-impl.h
dali/internal/adaptor/common/adaptor.cpp
dali/internal/adaptor/common/application-impl.cpp
dali/internal/adaptor/common/application-impl.h
dali/internal/system/common/callback-manager-ecore.cpp
dali/internal/system/common/callback-manager-ecore.h
dali/internal/system/common/callback-manager.h
dali/public-api/adaptor-framework/application.cpp
dali/public-api/adaptor-framework/application.h

index 8ed500a..85a4347 100644 (file)
@@ -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
index 05bc65a..5ffbd2e 100644 (file)
@@ -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
index e3a2115..6ce71a3 100755 (executable)
@@ -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.
index af8a13e..0a2708a 100755 (executable)
@@ -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
index 5588cd8..432bdcd 100755 (executable)
@@ -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:
 
   /**
index 4086605..b0c6047 100755 (executable)
@@ -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 )
index e5a4f45..d2ccfda 100644 (file)
@@ -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
index 239f373..2a16014 100644 (file)
@@ -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();
index a05d2cc..d04118d 100644 (file)
@@ -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();
 }
index de5035d..10f437f 100644 (file)
@@ -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();
index 63870f0..463fea6 100644 (file)
@@ -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;
index 1604932..3405faf 100644 (file)
@@ -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()
index 638b9be..b24742b 100644 (file)
@@ -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.
    */