From: Youngsun Suh Date: Wed, 4 Sep 2024 01:59:32 +0000 (+0900) Subject: [Tizen] Add BaseObjectObserver X-Git-Tag: accepted/tizen/7.0/unified/20240924.164214^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d7c88144678bb15771853f654fb85e2e6e7da90b;p=platform%2Fcore%2Fuifw%2Fdali-core.git [Tizen] Add BaseObjectObserver Change-Id: I414126bece5aeb685835c1efa7c6ab8fba9ee67e --- diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 0baf3ec37..90a46f3ac 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -13,6 +13,7 @@ SET(TC_SOURCES utc-Dali-Animation.cpp utc-Dali-Any.cpp utc-Dali-BaseHandle.cpp + utc-Dali-BaseObjectObserver.cpp utc-Dali-CameraActor.cpp utc-Dali-CircularQueue.cpp utc-Dali-ConditionalWait.cpp diff --git a/automated-tests/src/dali/utc-Dali-BaseObjectObserver.cpp b/automated-tests/src/dali/utc-Dali-BaseObjectObserver.cpp new file mode 100644 index 000000000..71fca121d --- /dev/null +++ b/automated-tests/src/dali/utc-Dali-BaseObjectObserver.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include + +using namespace Dali; + +namespace +{ + +class TestBaseObjectObserver : public BaseObjectObserver +{ +public: + TestBaseObjectObserver(Actor actor) + : BaseObjectObserver(actor) {} + + void ObjectDestroyed() override + { + objectDestroyed = true; + if(mCallback) + { + mCallback(); + callbackCalled = true; + } + } + + void SetCallback(std::function callback) + { + mCallback = std::move(callback); + } + + bool objectDestroyed{false}; + bool callbackCalled{false}; + +private: + std::function mCallback; +}; + +} // anonymous namespace + + +int UtcDaliBaseObjectObserverObjectDestroyedCalledOnObjectDestruction(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + TestBaseObjectObserver observer(actor); + DALI_TEST_CHECK(!observer.objectDestroyed); + + observer.StartObservingDestruction(); + observer.StartObservingDestruction(); // Test app does not crash when calling Start twice + DALI_TEST_CHECK(!observer.objectDestroyed); + + actor.Reset(); + DALI_TEST_CHECK(observer.objectDestroyed); + DALI_TEST_CHECK(!observer.callbackCalled); + + END_TEST; +} + +int UtcDaliBaseObjectObserverObjectDestroyedIsNotCalledIfObserverStopped(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + TestBaseObjectObserver observer(actor); + DALI_TEST_CHECK(!observer.objectDestroyed); + + observer.StartObservingDestruction(); + DALI_TEST_CHECK(!observer.objectDestroyed); + observer.StopObservingDestruction(); + observer.StopObservingDestruction(); // Test app does not crash when calling Stop twice + + actor.Reset(); + DALI_TEST_CHECK(!observer.objectDestroyed); + DALI_TEST_CHECK(!observer.callbackCalled); + + END_TEST; +} + +int UtcDaliBaseObjectObserverObjectDestroyedIsNotCalledIfObserverNotStarted(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + TestBaseObjectObserver observer(actor); + DALI_TEST_CHECK(!observer.objectDestroyed); + + actor.Reset(); + DALI_TEST_CHECK(!observer.objectDestroyed); + DALI_TEST_CHECK(!observer.callbackCalled); + + END_TEST; +} + +int UtcDaliBaseObjectObserverRecursiveStart(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + TestBaseObjectObserver observer(actor); + observer.SetCallback([&observer] { + observer.StartObservingDestruction(); + }); + + observer.StartObservingDestruction(); + + actor.Reset(); + DALI_TEST_CHECK(observer.objectDestroyed); + DALI_TEST_CHECK(observer.callbackCalled); + + END_TEST; +} + +int UtcDaliBaseObjectObserverRecursiveStop(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + TestBaseObjectObserver observer(actor); + observer.SetCallback([&observer] { + observer.StopObservingDestruction(); + }); + + observer.StartObservingDestruction(); + + actor.Reset(); + DALI_TEST_CHECK(observer.objectDestroyed); + DALI_TEST_CHECK(observer.callbackCalled); + + END_TEST; +} diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index ab12aafd7..7d5e94598 100644 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -31,6 +31,7 @@ SET( devel_api_src_files ${devel_api_src_dir}/images/pixel-data-devel.cpp ${devel_api_src_dir}/object/handle-devel.cpp ${devel_api_src_dir}/object/csharp-type-registry.cpp + ${devel_api_src_dir}/object/base-object-observer.cpp ${devel_api_src_dir}/rendering/frame-buffer-devel.cpp ${devel_api_src_dir}/rendering/renderer-devel.cpp ${devel_api_src_dir}/rendering/texture-devel.cpp @@ -104,6 +105,7 @@ SET( devel_api_core_images_header_files SET( devel_api_core_object_header_files + ${devel_api_src_dir}/object/base-object-observer.h ${devel_api_src_dir}/object/csharp-type-info.h ${devel_api_src_dir}/object/csharp-type-registry.h ${devel_api_src_dir}/object/handle-devel.h diff --git a/dali/devel-api/object/base-object-observer.cpp b/dali/devel-api/object/base-object-observer.cpp new file mode 100644 index 000000000..494d1fa49 --- /dev/null +++ b/dali/devel-api/object/base-object-observer.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 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 + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +class BaseObjectObserver::Impl : public BaseObject::Impl::Observer +{ +public: +explicit Impl(const BaseHandle& handle) + { + if(handle) + { + mObject = static_cast(handle.GetObjectPtr()); + } + } + + ~Impl() override + { + Stop(); + } + + void Start(BaseObjectObserver *observerBase) + { + if (mObject && !mObserverBase && observerBase) + { + mObserverBase = observerBase; + BaseObject::Impl::Get(*mObject).AddObserver(*this); + } + } + + void Stop() + { + if(mObject && mObserverBase) + { + BaseObject::Impl::Get(*mObject).RemoveObserver(*this); + mObserverBase = nullptr; + } + } + + /** + * From BaseObject::Impl::Observer + */ + void ObjectDestroyed(BaseObject&) override + { + mObject = nullptr; + mObserverBase->ObjectDestroyed(); + } + +private: + Dali::BaseObject* mObject{nullptr}; + BaseObjectObserver* mObserverBase{nullptr}; +}; + +BaseObjectObserver::BaseObjectObserver(const BaseHandle& handle) +: mImpl{std::make_unique(handle)} +{ +} + +BaseObjectObserver::~BaseObjectObserver() = default; + +void BaseObjectObserver::StartObservingDestruction() +{ + mImpl->Start(this); +} + +void BaseObjectObserver::StopObservingDestruction() +{ + mImpl->Stop(); +} + +} // namespace Dali diff --git a/dali/devel-api/object/base-object-observer.h b/dali/devel-api/object/base-object-observer.h new file mode 100644 index 000000000..30b110b60 --- /dev/null +++ b/dali/devel-api/object/base-object-observer.h @@ -0,0 +1,70 @@ +#ifndef DALI_BASE_OBJECT_OBSERVER_H +#define DALI_BASE_OBJECT_OBSERVER_H + +/* + * Copyright (c) 2024 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. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +/** + * @brief Base class to provide observer interface for BaseOject destruction store a weak pointer to an internal DALi object. + */ +class DALI_CORE_API BaseObjectObserver +{ +public: + /** + * @brief The constructor initializes observer for given DALi object. + * @param [in] handle A reference to the handle of the DALi object + */ + explicit BaseObjectObserver(const BaseHandle& handle); + virtual ~BaseObjectObserver(); + + /** + * @brief Starts observing destruction of the registered object. + */ + void StartObservingDestruction(); + + /** + * @brief Stops observing destruction of the registered object. + */ + void StopObservingDestruction(); + + /** + * @brief Called shortly before the object itself is destroyed. + */ + virtual void ObjectDestroyed() = 0; + + // deleted constructors and operators + BaseObjectObserver(const BaseObjectObserver& handle) = delete; + BaseObjectObserver& operator=(const BaseObjectObserver& rhs) = delete; + BaseObjectObserver(BaseObjectObserver&& rhs) = delete; + BaseObjectObserver& operator=(BaseObjectObserver&& rhs) = delete; + +private: + /// @cond internal + struct Impl; + std::unique_ptr mImpl; + /// @endcond +}; + +} // namespace Dali + +#endif // DALI_BASE_OBJECT_OBSERVER_H