Support weak handle for BaseHandle 15/238115/3
authorRichard Huang <r.huang@samsung.com>
Wed, 8 Jul 2020 16:30:57 +0000 (17:30 +0100)
committerRichard Huang <r.huang@samsung.com>
Thu, 9 Jul 2020 14:41:37 +0000 (15:41 +0100)
Change-Id: I68bab2435d30c44cd1bf2c4457f3cfb92e0bb68e

automated-tests/src/dali/utc-Dali-WeakHandle.cpp
dali/internal/event/common/base-object-impl.cpp [new file with mode: 0755]
dali/internal/event/common/base-object-impl.h [new file with mode: 0755]
dali/internal/file.list
dali/public-api/object/base-object.cpp
dali/public-api/object/base-object.h
dali/public-api/object/weak-handle.cpp
dali/public-api/object/weak-handle.h

index 186e5c3..6848f1f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -206,12 +206,12 @@ int UtcDaliWeakHandleBaseConstructorVoid(void)
   END_TEST;
 }
 
-int UtcDaliWeakHandleBaseConstructorWithHandle(void)
+int UtcDaliWeakHandleBaseConstructorWithBaseHandle(void)
 {
   TestApplication application;
-  tet_infoline("Testing Dali::WeakHandleBase::WeakHandleBase(Handle)");
+  tet_infoline("Testing Dali::WeakHandleBase::WeakHandleBase(BaseHandle)");
 
-  Handle emptyHandle;
+  BaseHandle emptyHandle;
   WeakHandleBase emptyObject(emptyHandle);
   DALI_TEST_CHECK(!emptyObject.GetBaseHandle());
 
@@ -219,6 +219,10 @@ int UtcDaliWeakHandleBaseConstructorWithHandle(void)
   WeakHandleBase object(actor);
   DALI_TEST_CHECK(object.GetBaseHandle() == actor);
 
+  Animation animation = Animation::New( 1.0f );
+  WeakHandleBase animationObject( animation );
+  DALI_TEST_CHECK( animationObject.GetBaseHandle() == animation );
+
   END_TEST;
 }
 
@@ -352,6 +356,17 @@ int UtcDaliWeakHandleBaseGetBaseHandle(void)
   WeakHandleBase aDifferentWeakHandleBase(differentActor);
   DALI_TEST_CHECK(object.GetBaseHandle() != aDifferentWeakHandleBase.GetBaseHandle());
 
+  Animation animation = Animation::New( 1.0f );
+  WeakHandleBase animationObject( animation );
+  DALI_TEST_CHECK( animationObject.GetBaseHandle() == animation );
+
+  WeakHandleBase theSameAnimationObject = WeakHandleBase( animation );
+  DALI_TEST_CHECK( animationObject.GetBaseHandle() == theSameAnimationObject.GetBaseHandle() );
+
+  Animation differentAnimation = Animation::New( 1.0f );
+  WeakHandleBase aDifferentAnimationObject( differentAnimation );
+  DALI_TEST_CHECK( animationObject.GetBaseHandle() != aDifferentAnimationObject.GetBaseHandle() );
+
   END_TEST;
 }
 
@@ -387,8 +402,14 @@ int UtcDaliWeakHandleGetHandle(void)
 
   DALI_TEST_CHECK(object.GetHandle() != customObject.GetHandle());
 
+  Animation animation = Animation::New( 1.0f );
+  WeakHandle<Animation>  animationObject( animation );
+  DALI_TEST_CHECK( animationObject.GetHandle() == animation );
+
+  animation.Reset();
+  DALI_TEST_CHECK( animationObject.GetHandle() == Animation() );
+
   END_TEST;
 }
 
 
-
diff --git a/dali/internal/event/common/base-object-impl.cpp b/dali/internal/event/common/base-object-impl.cpp
new file mode 100755 (executable)
index 0000000..876f8af
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/common/base-object-impl.h>
+
+namespace Dali
+{
+
+BaseObject::Impl::Impl( BaseObject& baseObject )
+: mBaseObject( baseObject )
+{
+}
+
+BaseObject::Impl::~Impl()
+{
+  // Notification for observers
+  for( auto&& item : mObservers )
+  {
+    item->ObjectDestroyed( mBaseObject );
+  }
+}
+
+BaseObject::Impl& BaseObject::Impl::Get( BaseObject& baseObject )
+{
+  return *baseObject.mImpl;
+}
+
+const BaseObject::Impl& BaseObject::Impl::Get( const BaseObject& baseObject )
+{
+  return *baseObject.mImpl;
+}
+
+void BaseObject::Impl::AddObserver( Observer& observer )
+{
+  // make sure an observer doesn't observe the same object twice
+  // otherwise it will get multiple calls to ObjectDestroyed()
+  DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer) );
+
+  mObservers.PushBack( &observer );
+}
+
+void BaseObject::Impl::RemoveObserver( Observer& observer )
+{
+  // Find the observer...
+  const auto endIter =  mObservers.End();
+  for( auto iter = mObservers.Begin(); iter != endIter; ++iter )
+  {
+    if( ( *iter ) == &observer)
+    {
+      mObservers.Erase( iter );
+      break;
+    }
+  }
+  DALI_ASSERT_DEBUG( endIter != mObservers.End() );
+}
+
+} // namespace Dali
diff --git a/dali/internal/event/common/base-object-impl.h b/dali/internal/event/common/base-object-impl.h
new file mode 100755 (executable)
index 0000000..5bb491f
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef DALI_BASE_OBJECT_IMPL_H
+#define DALI_BASE_OBJECT_IMPL_H
+
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+
+/**
+ * @brief Holds the Implementation for the BaseObject class
+ */
+class BaseObject::Impl
+{
+
+public:
+
+  /**
+   * @brief Retrieves the implementation of the internal BaseObject class.
+   * @param[in] internalBaseObject A ref to the BaseObject whose internal implementation is required
+   * @return The internal implementation
+   */
+  static BaseObject::Impl& Get( BaseObject& baseObject );
+
+  /**
+   * @copydoc Get( BaseObject& )
+   */
+  static const BaseObject::Impl& Get( const BaseObject& baseObject );
+
+  /**
+   * @brief Constructor.
+   * @param[in] baseObject The base object which owns this implementation
+   */
+  Impl( BaseObject& baseObject );
+
+  /**
+   * @brief Destructor.
+   */
+  ~Impl();
+
+  class Observer
+  {
+  public:
+
+    /**
+     * Called shortly before the object itself is destroyed; no further callbacks will be received.
+     * @param[in] object The base object.
+     */
+    virtual void ObjectDestroyed( BaseObject& object ) = 0;
+
+  protected:
+
+    /**
+     * Virtual destructor
+     */
+    virtual ~Observer() {}
+  };
+
+  /**
+   * Add an observer to the object.
+   * @param[in] observer The observer to add.
+   */
+  void AddObserver( Observer& observer );
+
+  /**
+   * Remove an observer from the object
+   * @pre The observer has already been added.
+   * @param[in] observer The observer to remove.
+   */
+  void RemoveObserver( Observer& observer );
+
+private:
+
+  BaseObject& mBaseObject;
+  Dali::Vector<Observer*> mObservers;
+};
+
+} // namespace Dali
+
+#endif // DALI_BASE_OBJECT_IMPL_H
index 96fb149..36b2778 100644 (file)
@@ -26,6 +26,7 @@ SET( internal_src_files
   ${internal_src_dir}/event/animation/linear-constrainer-impl.cpp
   ${internal_src_dir}/event/animation/path-impl.cpp
   ${internal_src_dir}/event/animation/path-constrainer-impl.cpp
+  ${internal_src_dir}/event/common/base-object-impl.cpp
   ${internal_src_dir}/event/common/event-thread-services.cpp
   ${internal_src_dir}/event/common/notification-manager.cpp
   ${internal_src_dir}/event/common/object-impl.cpp
index 243fe27..d0b07e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/type-registry-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/common/base-object-impl.h>
 
 namespace Dali
 {
 
 BaseObject::BaseObject()
+: mImpl( new Impl( *this ) )
 {
 }
 
index 00d261c..87bf3c9 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_BASE_OBJECT_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <memory>
+
 // INTERNAL INCLUDES
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/object/base-handle.h>
@@ -118,6 +121,14 @@ private:
 
   // Not implemented
   DALI_INTERNAL BaseObject& operator=(const BaseObject& rhs);
+
+public:
+
+  class DALI_INTERNAL Impl;
+
+private:
+
+  std::unique_ptr<Impl> mImpl;
 };
 
 // Helpers for public-api forwarding methods
index 42905b0..cd5fcab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
 #include <dali/public-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/event/common/object-impl.h>
+#include <dali/internal/event/common/base-object-impl.h>
 
 namespace Dali
 {
 
-struct WeakHandleBase::Impl : public Internal::Object::Observer
+struct WeakHandleBase::Impl : public BaseObject::Impl::Observer
 {
   // Construction
   Impl()
-  : mObject( NULL )
+  : mObject( nullptr )
   {
   }
 
   // Construction
-  Impl( Handle& handle )
-  : mObject( NULL )
+  Impl( BaseHandle& handle )
+  : mObject( nullptr )
   {
-    if(handle)
+    if( handle )
     {
-      mObject = static_cast<Internal::Object*>( handle.GetObjectPtr() );
-      if(mObject)
+      mObject = static_cast<Dali::BaseObject*>( handle.GetObjectPtr() );
+      if( mObject )
       {
-        mObject->AddObserver( *this );
+        BaseObject::Impl::Get( *mObject ).AddObserver( *this );
       }
     }
   }
@@ -56,35 +56,21 @@ struct WeakHandleBase::Impl : public Internal::Object::Observer
   {
     if( mObject )
     {
-      mObject->RemoveObserver( *this );
-      mObject = NULL;
+      BaseObject::Impl::Get( *mObject ).RemoveObserver( *this );
+      mObject = nullptr;
     }
   }
 
   /**
-   * From Object::Observer
+   * From BaseObject::Impl::Observer
    */
-  virtual void SceneObjectAdded( Internal::Object& object )
+  virtual void ObjectDestroyed( BaseObject& object )
   {
-  }
-
-  /**
-   * From Object::Observer
-   */
-  virtual void SceneObjectRemoved( Internal::Object& object )
-  {
-  }
-
-  /**
-   * From Object::Observer
-   */
-  virtual void ObjectDestroyed( Internal::Object& object )
-  {
-    mObject = NULL;
+    mObject = nullptr;
   }
 
   // Data
-  Internal::Object* mObject;
+  Dali::BaseObject* mObject;
 };
 
 WeakHandleBase::WeakHandleBase()
@@ -92,7 +78,7 @@ WeakHandleBase::WeakHandleBase()
 {
 }
 
-WeakHandleBase::WeakHandleBase( Handle& handle )
+WeakHandleBase::WeakHandleBase( BaseHandle& handle )
 : mImpl( new Impl( handle ) )
 {
 }
@@ -100,13 +86,13 @@ WeakHandleBase::WeakHandleBase( Handle& handle )
 WeakHandleBase::~WeakHandleBase()
 {
   delete mImpl;
-  mImpl = NULL;
+  mImpl = nullptr;
 }
 
 WeakHandleBase::WeakHandleBase(const WeakHandleBase& handle)
-: mImpl( NULL )
+: mImpl( nullptr )
 {
-  Handle object = handle.GetBaseHandle();
+  BaseHandle object = handle.GetBaseHandle();
   mImpl = new Impl(object);
 }
 
@@ -116,7 +102,7 @@ WeakHandleBase& WeakHandleBase::operator=( const WeakHandleBase& rhs )
   {
     delete mImpl;
 
-    Handle handle = rhs.GetBaseHandle();
+    BaseHandle handle = rhs.GetBaseHandle();
     mImpl = new Impl(handle);
   }
 
@@ -133,9 +119,9 @@ bool WeakHandleBase::operator!=( const WeakHandleBase& rhs ) const
   return !( *this == rhs );
 }
 
-Handle WeakHandleBase::GetBaseHandle() const
+BaseHandle WeakHandleBase::GetBaseHandle() const
 {
-  return Handle( mImpl->mObject );
+  return BaseHandle( mImpl->mObject );
 }
 
 void WeakHandleBase::Reset()
index 25c980a..cb054bc 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_WEAK_HANDLE_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -19,7 +19,7 @@
  */
 
 // INTERNAL INCLUDES
-#include <dali/public-api/object/handle.h>
+#include <dali/public-api/object/base-handle.h>
 #include <dali/public-api/actors/custom-actor.h>
 
 namespace Dali
@@ -54,7 +54,7 @@ public:
    * @SINCE_1_2.60
    * @param [in] handle A reference to the handle of the DALi object
    */
-  WeakHandleBase( Handle& handle );
+  WeakHandleBase( BaseHandle& handle );
 
   /**
    * @brief Destructor to free resources.
@@ -104,7 +104,7 @@ public:
    * @SINCE_1_2.60
    * @return The handle of the DALi object pointed by this WeakHandleBase or an empty handle if the DALi object doesn't exist
    */
-  Handle GetBaseHandle() const;
+  BaseHandle GetBaseHandle() const;
 
   /**
    * @brief Resets this weak handle to not point to any DALi object
@@ -141,7 +141,7 @@ public:
   }
 
   /**
-   * @copydoc Dali::WeakHandleBase::WeakHandleBase(Handle&)
+   * @copydoc Dali::WeakHandleBase::WeakHandleBase( BaseHandle& )
    */
   WeakHandle( T& handle )
   : WeakHandleBase( handle )
@@ -191,7 +191,7 @@ public:
    */
   T GetHandle() const
   {
-    Handle handle( GetBaseHandle() );
+    BaseHandle handle( WeakHandleBase::GetBaseHandle() );
     if( handle )
     {
       return DownCast< T >( handle );