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 
16 #ifndef META_INTERFACE_IOBJECT_HIERARCHY_OBSERVER_H
17 #define META_INTERFACE_IOBJECT_HIERARCHY_OBSERVER_H
18 
19 #include <meta/base/bit_field.h>
20 #include <meta/interface/intf_container.h>
21 
22 META_BEGIN_NAMESPACE()
23 
24 META_REGISTER_INTERFACE(IObjectHierarchyObserver, "6ffa83ee-716a-4cff-aa09-b87f84c97056")
25 META_REGISTER_INTERFACE(IOnHierarchyChanged, "e7dfaaee-79fa-4dbe-9fb0-1e89a1025183")
26 
27 struct IOnHierarchyChangedInfo {
28     constexpr static BASE_NS::Uid UID { META_NS::InterfaceId::IOnHierarchyChanged };
29     constexpr static char const* NAME { "OnHierarchyChanged" };
30 };
31 
32 /**
33  * @brief The HierarchyChangeType enum lists operations that IObjectHierarchyObserver can monitor.
34  */
35 enum class HierarchyChangeType : uint32_t {
36     /** An object is about to be added to the hierarchy being monitored */
37     ADDING = 1,
38     /** An object was added to the hierarchy being monitored */
39     ADDED = 2,
40     /** An object is about to be removed from the hierarchy being monitored */
41     REMOVING = 3,
42     /** An object was removed from the hierarchy being monitored */
43     REMOVED = 4,
44     /** An object was moved inside a container in the hierarchy being monitored */
45     MOVED = 5,
46     /** An object changed */
47     CHANGED = 6
48 };
49 
50 /**
51  * @brief The HierarchyChangeObjectType enum lists different object types within the hierarchy.
52  */
53 enum class HierarchyChangeObjectType : uint32_t {
54     /** The root object */
55     ROOT = 1,
56     /** The object is a child of an IContainer */
57     CHILD = 2,
58     /** The object is the content of IContent::Content */
59     CONTENT = 3,
60     /** The object is an attachment */
61     ATTACHMENT = 4,
62 };
63 
64 enum class HierarchyChangeMode : uint8_t {
65     /** Get notifications for IContainer changes */
66     NOTIFY_CONTAINER = 1,
67     /** Get notifications for IContent::Content changes */
68     NOTIFY_CONTENT = 2,
69     /** Get notifications for IAttachment changes */
70     NOTIFY_ATTACHMENT = 4,
71     /** Get Notifications for INotifyOnChange changes for the object itself */
72     NOTIFY_OBJECT = 8,
73     /** Default notify mode */
74     NOTIFY_DEFAULT = NOTIFY_CONTAINER | NOTIFY_CONTENT | NOTIFY_ATTACHMENT
75 };
76 
77 using HierarchyChangeModeValue = EnumBitField<HierarchyChangeMode>;
78 
79 /**
80  * @brief The ChildChangedInfo struct defines the parameters for an event which is invoked when
81  *        an object is added to or removed from an IContainer.
82  */
83 struct HierarchyChangedInfo {
84     /** The object that the operation concerns */
85     IObject::Ptr object;
86     /** Type of change within the hierarchy */
87     HierarchyChangeType change;
88     /** Type of the object */
89     HierarchyChangeObjectType objectType;
90     /** Index of the object within the container where change happened if available, otherwise maximum value of size_t.
91      *  Only valid for CHILD and ATTACHMENT object types */
92     size_t index { size_t(-1) };
93     /** Parent object in the hierarchy. */
94     IObject::WeakPtr parent;
95 };
96 
97 using IOnHierarchyChanged = META_NS::SimpleEvent<IOnHierarchyChangedInfo, void(const HierarchyChangedInfo&)>;
98 
99 /**
100  * @brief The IContainerObserver interface
101  */
102 class IObjectHierarchyObserver : public CORE_NS::IInterface {
103     META_INTERFACE(CORE_NS::IInterface, IObjectHierarchyObserver)
104 public:
105     /**
106      * @brief Sets the root object of the hierarchy to observe.
107      * @param root The root object of the hierarchy.
108      * @param optional mode to use used, if not given, NOTIFY_DEFAULT is used.
109      */
110     virtual void SetTarget(const IObject::Ptr& root, HierarchyChangeModeValue mode) = 0;
SetTarget(const IObject::Ptr & root)111     void SetTarget(const IObject::Ptr& root)
112     {
113         SetTarget(root, HierarchyChangeMode::NOTIFY_DEFAULT);
114     }
115     /**
116      * @brief Returns the current target object.
117      */
118     virtual IObject::Ptr GetTarget() const = 0;
119     /**
120      * @brief Returns a list of all objects which are currently being monitored.
121      */
122     virtual BASE_NS::vector<IObject::Ptr> GetAllObserved() const = 0;
123     /**
124      * @brief Returns all currently monitored objects which implement a given interface.
125      */
126     template<class T>
GetAllObserved()127     BASE_NS::vector<typename T::Ptr> GetAllObserved() const
128     {
129         return PtrArrayCast<T>(GetAllObserved());
130     }
131     /**
132      * @brief Invoked when the hierarchy has changed in some way.
133      */
134     META_EVENT(IOnHierarchyChanged, OnHierarchyChanged)
135 };
136 
137 META_END_NAMESPACE()
138 
139 META_TYPE(META_NS::HierarchyChangedInfo)
140 
141 #endif // META_INTERFACE_IOBJECT_HIERARCHY_OBSERVER_H
142