18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci#ifndef META_SRC_OBJECT_HIERARCHY_OBSERVER_H 168bf80f4bSopenharmony_ci#define META_SRC_OBJECT_HIERARCHY_OBSERVER_H 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <shared_mutex> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/unordered_map.h> 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ci#include <meta/api/event_handler.h> 238bf80f4bSopenharmony_ci#include <meta/ext/event_impl.h> 248bf80f4bSopenharmony_ci#include <meta/interface/builtin_objects.h> 258bf80f4bSopenharmony_ci#include <meta/interface/intf_attachment.h> 268bf80f4bSopenharmony_ci#include <meta/interface/intf_object_hierarchy_observer.h> 278bf80f4bSopenharmony_ci 288bf80f4bSopenharmony_ci#include "object.h" 298bf80f4bSopenharmony_ci 308bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 318bf80f4bSopenharmony_ci 328bf80f4bSopenharmony_ciclass ObjectHierarchyObserver; 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_ciclass ObjectChangeListener final { 358bf80f4bSopenharmony_cipublic: 368bf80f4bSopenharmony_ci META_NO_COPY_MOVE(ObjectChangeListener) 378bf80f4bSopenharmony_ci ObjectChangeListener() = delete; 388bf80f4bSopenharmony_ci ~ObjectChangeListener(); 398bf80f4bSopenharmony_ci 408bf80f4bSopenharmony_ci ObjectChangeListener(const IObject::Ptr& object, HierarchyChangeObjectType myType, const IObject::WeakPtr& parent, 418bf80f4bSopenharmony_ci ObjectHierarchyObserver* observer, HierarchyChangeModeValue mode); 428bf80f4bSopenharmony_ci 438bf80f4bSopenharmony_ci HierarchyChangeObjectType GetType() const 448bf80f4bSopenharmony_ci { 458bf80f4bSopenharmony_ci return type_; 468bf80f4bSopenharmony_ci } 478bf80f4bSopenharmony_ci 488bf80f4bSopenharmony_ciprivate: 498bf80f4bSopenharmony_ci bool Subscribe(HierarchyChangeModeValue mode); 508bf80f4bSopenharmony_ci void Unsubscribe(); 518bf80f4bSopenharmony_ci 528bf80f4bSopenharmony_ci void SubscribeContainer(const IObject::Ptr& object); 538bf80f4bSopenharmony_ci void SubscribeAttachment(const IObject::Ptr& object); 548bf80f4bSopenharmony_ci 558bf80f4bSopenharmony_ci IObject::WeakPtr object_; 568bf80f4bSopenharmony_ci HierarchyChangeObjectType type_; 578bf80f4bSopenharmony_ci IObject::WeakPtr parent_; 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ci // Currently IContent does not support "OnChanging" and so the content might be destroyed already 608bf80f4bSopenharmony_ci // which would make it impossible to notify about 618bf80f4bSopenharmony_ci IObject::Ptr content_; 628bf80f4bSopenharmony_ci 638bf80f4bSopenharmony_ci ObjectHierarchyObserver* observer_ {}; 648bf80f4bSopenharmony_ci BASE_NS::vector<EventHandler> handlers_; 658bf80f4bSopenharmony_ci bool containerPreTransaction_ { false }; 668bf80f4bSopenharmony_ci bool attachmentPreTransaction_ { false }; 678bf80f4bSopenharmony_ci 688bf80f4bSopenharmony_ci void NotifyObjectChangedOp(); 698bf80f4bSopenharmony_ci void NotifyContainerChangeOp( 708bf80f4bSopenharmony_ci const ChildChangedInfo& info, HierarchyChangeType operation, HierarchyChangeObjectType objectType); 718bf80f4bSopenharmony_ci void NotifyContainerMoveOp( 728bf80f4bSopenharmony_ci const ChildMovedInfo& info, HierarchyChangeType operation, HierarchyChangeObjectType objectType); 738bf80f4bSopenharmony_ci void NotifyContentChangeOp(); 748bf80f4bSopenharmony_ci}; 758bf80f4bSopenharmony_ci 768bf80f4bSopenharmony_ciclass ObjectHierarchyObserver final : public Internal::MetaObjectFwd<ObjectHierarchyObserver, 778bf80f4bSopenharmony_ci ClassId::ObjectHierarchyObserver, IObjectHierarchyObserver, IAttachment> { 788bf80f4bSopenharmony_ci using Super = Internal::MetaObjectFwd<ObjectHierarchyObserver, ClassId::ObjectHierarchyObserver, 798bf80f4bSopenharmony_ci IObjectHierarchyObserver, IAttachment>; 808bf80f4bSopenharmony_ci 818bf80f4bSopenharmony_cipublic: 828bf80f4bSopenharmony_ci void HierarchyChanged(const HierarchyChangedInfo& info, ObjectChangeListener* listener); 838bf80f4bSopenharmony_ci 848bf80f4bSopenharmony_ciprotected: // LifeCycle 858bf80f4bSopenharmony_ci bool Build(const IMetadata::Ptr&) override; 868bf80f4bSopenharmony_ci void Destroy() override; 878bf80f4bSopenharmony_ci 888bf80f4bSopenharmony_ciprotected: // IObjectHierarchyObserver 898bf80f4bSopenharmony_ci void SetTarget(const IObject::Ptr& root, HierarchyChangeModeValue mode) override; 908bf80f4bSopenharmony_ci IObject::Ptr GetTarget() const override; 918bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> GetAllObserved() const override; 928bf80f4bSopenharmony_ci META_IMPLEMENT_INTERFACE_EVENT(IObjectHierarchyObserver, IOnHierarchyChanged, OnHierarchyChanged) 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_ciprotected: // IAttachment 958bf80f4bSopenharmony_ci bool Attaching(const META_NS::IAttach::Ptr& target, const META_NS::IObject::Ptr& dataContext) override; 968bf80f4bSopenharmony_ci bool Detaching(const META_NS::IAttach::Ptr& target) override; 978bf80f4bSopenharmony_ci 988bf80f4bSopenharmony_ci META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IObject::WeakPtr, DataContext); 998bf80f4bSopenharmony_ci META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IAttach::WeakPtr, AttachedTo, {}); 1008bf80f4bSopenharmony_ci 1018bf80f4bSopenharmony_ciprivate: 1028bf80f4bSopenharmony_ci void Subscribe(const IObject::Ptr& root, HierarchyChangeObjectType type, const IObject::WeakPtr& parent = nullptr); 1038bf80f4bSopenharmony_ci void Unsubscribe(const IObject::Ptr& root); 1048bf80f4bSopenharmony_ci void ClearSubscriptions(); 1058bf80f4bSopenharmony_ci void NotifyOnDetach(); 1068bf80f4bSopenharmony_ci 1078bf80f4bSopenharmony_ci HierarchyChangeModeValue mode_ {}; 1088bf80f4bSopenharmony_ci IObject::WeakPtr root_; 1098bf80f4bSopenharmony_ci 1108bf80f4bSopenharmony_ci struct Subscription final { 1118bf80f4bSopenharmony_ci META_NO_COPY(Subscription) 1128bf80f4bSopenharmony_ci Subscription(IObject::WeakPtr object, BASE_NS::unique_ptr<ObjectChangeListener>&& listener) 1138bf80f4bSopenharmony_ci : object_(BASE_NS::move(object)), listener_(BASE_NS::move(listener)) 1148bf80f4bSopenharmony_ci {} 1158bf80f4bSopenharmony_ci ~Subscription() = default; 1168bf80f4bSopenharmony_ci Subscription(Subscription&& other) noexcept = default; 1178bf80f4bSopenharmony_ci Subscription& operator=(Subscription&& other) = default; 1188bf80f4bSopenharmony_ci IObject::WeakPtr object_; 1198bf80f4bSopenharmony_ci BASE_NS::unique_ptr<ObjectChangeListener> listener_; 1208bf80f4bSopenharmony_ci }; 1218bf80f4bSopenharmony_ci 1228bf80f4bSopenharmony_ci void AddSubscription(const IObject::Ptr& object, HierarchyChangeObjectType type, const IObject::WeakPtr& parent); 1238bf80f4bSopenharmony_ci void RemoveSubscription(const IObject::Ptr& object); 1248bf80f4bSopenharmony_ci 1258bf80f4bSopenharmony_ci void AddImmediateChild(const HierarchyChangedInfo& info); 1268bf80f4bSopenharmony_ci void RemoveImmediateChild(const HierarchyChangedInfo& info); 1278bf80f4bSopenharmony_ci 1288bf80f4bSopenharmony_ci BASE_NS::unordered_map<ObjectChangeListener*, Subscription> subscriptions_; 1298bf80f4bSopenharmony_ci struct ImmediateChild { 1308bf80f4bSopenharmony_ci BASE_NS::weak_ptr<IObject> object; 1318bf80f4bSopenharmony_ci HierarchyChangeObjectType type {}; 1328bf80f4bSopenharmony_ci }; 1338bf80f4bSopenharmony_ci bool keepTrackOfImmediate_ {}; 1348bf80f4bSopenharmony_ci BASE_NS::vector<ImmediateChild> immediateChildren_; 1358bf80f4bSopenharmony_ci mutable std::shared_mutex mutex_; 1368bf80f4bSopenharmony_ci}; 1378bf80f4bSopenharmony_ci 1388bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 1398bf80f4bSopenharmony_ci 1408bf80f4bSopenharmony_ci#endif // META_SRC_OBJECT_HIERARCHY_OBSERVER_H 141