1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef META_SRC_CONTAINER_OBSERVER_H 16 #define META_SRC_CONTAINER_OBSERVER_H 17 18 #include <base/containers/unordered_map.h> 19 20 #include <meta/ext/event_impl.h> 21 #include <meta/interface/builtin_objects.h> 22 #include <meta/interface/intf_container_observer.h> 23 24 #include "object.h" 25 26 META_BEGIN_NAMESPACE() 27 28 class ContainerChangeListener final { 29 public: 30 META_NO_COPY(ContainerChangeListener) 31 ~ContainerChangeListener(); 32 ContainerChangeListener() = delete; 33 ContainerChangeListener(ContainerChangeListener&& other); 34 ContainerChangeListener& operator=(ContainerChangeListener&& other); 35 36 explicit ContainerChangeListener(const IContainer::Ptr& container); 37 // Note the copy assignment implementation which is not directly applicable to all use cases 38 bool operator==(const ContainerChangeListener& other) const noexcept; 39 bool Subscribe(const IOnChildChanged::InterfaceTypePtr& onAdded, const IOnChildChanged::InterfaceTypePtr& onRemoved, 40 const IOnChildMoved::InterfaceTypePtr& onMoved); 41 void Unsubscribe(); 42 43 private: 44 mutable BASE_NS::pair<IEvent::Token, IOnChildChanged::InterfaceTypePtr> added_; 45 mutable BASE_NS::pair<IEvent::Token, IOnChildChanged::InterfaceTypePtr> removed_; 46 mutable BASE_NS::pair<IEvent::Token, IOnChildMoved::InterfaceTypePtr> moved_; 47 mutable IContainer::WeakPtr container_; 48 }; 49 50 class ContainerObserver 51 : public Internal::MetaObjectFwd<ContainerObserver, ClassId::ContainerObserver, IContainerObserver> { 52 using Super = Internal::MetaObjectFwd<ContainerObserver, ClassId::ContainerObserver, IContainerObserver>; 53 using Super::Super; 54 55 protected: // LifeCycle 56 bool Build(const IMetadata::Ptr&) override; 57 58 protected: // IContainerObjserver 59 void SetContainer(const IContainer::Ptr& container) override; 60 61 META_IMPLEMENT_INTERFACE_EVENT(IContainerObserver, IOnChildChanged, OnDescendantAdded) 62 META_IMPLEMENT_INTERFACE_EVENT(IContainerObserver, IOnChildChanged, OnDescendantRemoved) 63 META_IMPLEMENT_INTERFACE_EVENT(IContainerObserver, IOnChildMoved, OnDescendantMoved) 64 65 private: 66 void Subscribe(const IContainer::Ptr& base); 67 void Unsubscribe(const IContainer::Ptr& base); 68 void InvokeAdded(const ChildChangedInfo& info); 69 void InvokeRemoved(const ChildChangedInfo& info); 70 void InvokeMoved(const ChildMovedInfo& info); 71 IContainer::Ptr container_; 72 IOnChildChanged::InterfaceTypePtr addedCallable_; 73 IOnChildChanged::InterfaceTypePtr removedCallable_; 74 IOnChildMoved::InterfaceTypePtr movedCallable_; 75 76 struct Subscription { SubscriptionContainerObserver::Subscription77 Subscription(IContainer::WeakPtr container, ContainerChangeListener&& listener) 78 : container(BASE_NS::move(container)), listener(BASE_NS::move(listener)) 79 {} 80 IContainer::WeakPtr container; 81 ContainerChangeListener listener; 82 }; 83 84 BASE_NS::vector<Subscription> subscriptions_; 85 }; 86 87 META_END_NAMESPACE() 88 89 #endif // META_SRC_CONTAINER_OBSERVER_H 90