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_IATTACH_H
17 #define META_INTERFACE_IATTACH_H
18 
19 #include <base/containers/vector.h>
20 
21 #include <meta/base/interface_utils.h>
22 #include <meta/base/namespace.h>
23 #include <meta/base/shared_ptr.h>
24 #include <meta/base/types.h>
25 #include <meta/interface/intf_container.h>
26 #include <meta/interface/intf_object.h>
27 
28 META_BEGIN_NAMESPACE()
29 
30 META_REGISTER_INTERFACE(IAttach, "2cc0d7b9-ccec-474e-acdd-d06fb5aeb714")
31 
32 class IAttachment;
33 
34 /**
35  * @brief The IAttach interface defines a common interface for classes to which attachments can be attached.
36  */
37 class IAttach : public CORE_NS::IInterface {
META_INTERFACE(CORE_NS::IInterface,IAttach)38     META_INTERFACE(CORE_NS::IInterface, IAttach)
39 public:
40     /**
41      * @brief Attach an attachment to this object. The object being attached to will be used as the data context.
42      * @param attachment The attachment to add
43      * @return True if the operation succeeded. False otherwise.
44      */
45     bool Attach(const IObject::Ptr& attachment)
46     {
47         return Attach(attachment, {});
48     }
49     /** Type helper for Attach */
50     template<class T>
Attach(const T & object)51     bool Attach(const T& object)
52     {
53         return Attach(interface_pointer_cast<IObject>(object), {});
54     }
55     /**
56      * @brief Attach an attachment to this object.
57      * @param attachment The attachment to add
58      * @param dataContext The object to use as the data context for the attachment. If dataContext is null,
59      *                    the object being attached to will be used as the data context.
60      * @return True if the operation succeeded. False otherwise.
61      */
62     virtual bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext) = 0;
63     /** Type helper for Attach */
64     template<class T, class U>
Attach(const T & object,const U & dataContext)65     bool Attach(const T& object, const U& dataContext)
66     {
67         return Attach(interface_pointer_cast<IObject>(object), interface_pointer_cast<IObject>(dataContext));
68     }
69     /**
70      * @brief Detach an attachment from this object.
71      * @param attachment The attachment to detach.
72      * @return True if the opeation succeeded, false otherwise.
73      */
74     virtual bool Detach(const IObject::Ptr& attachment) = 0;
75     /** Type helper for Detach */
76     template<class T>
Detach(const T & object)77     bool Detach(const T& object)
78     {
79         return Detach(interface_pointer_cast<IObject>(object));
80     }
81     /**
82      * @brief Returns true if any attachments have been attached to the object.
83      */
84     virtual bool HasAttachments() const = 0;
85     /**
86      * @brief Returns the attachment container or nullptr if no attachments have been added.
87      */
GetAttachmentContainer()88     IContainer::Ptr GetAttachmentContainer() const
89     {
90         return GetAttachmentContainer(false);
91     }
92     /**
93      * @brief Returns the container which hosts all attachments attached to the object.
94      * @param initializeAlways If true, always return a valid IContainer::Ptr. If false,
95      *        the function may return nullptr in case no attachments have been added to
96      *        the object.
97      * @return An IContainer instance which holds all attachments that have been added
98      *         to the container.
99      */
100     virtual IContainer::Ptr GetAttachmentContainer(bool initializeAlways) const = 0;
101     /**
102      * @brief Returns a list of all attachments attached to this object.
103      * @return A list of attachments which are attached to this object.
104      */
GetAttachments()105     BASE_NS::vector<IObject::Ptr> GetAttachments() const
106     {
107         return GetAttachments({}, false);
108     }
109     /**
110      * @brief Returns a list of all attachments attached to this object.
111      * @param uids A list of interface Uids the returned attachments should implement. If the list is empty, return
112      *             all attachments.
113      * @param strict If true, the attachments added to the list must implement all of the given interfaces.
114      *               If false, it is enough for the attachment to implement one (or more) of the given uids to be
115      *               added to the list.
116      * @return A list of attachments which are attached to this object and fullfil the requirements.
117      */
118     virtual BASE_NS::vector<IObject::Ptr> GetAttachments(const BASE_NS::vector<TypeId>& uids, bool strict) const = 0;
119     /**
120      * @brief A helper template which can be used to retrieve a list of attachments which implement a given interface.
121      *        The returned list contains the found attachments pre-casted to T::Ptr.
122      */
123     template<class T>
GetAttachments()124     BASE_NS::vector<typename T::Ptr> GetAttachments() const
125     {
126         return PtrArrayCast<T>(GetAttachments({ T::UID }, false));
127     }
128 };
129 
130 META_END_NAMESPACE()
131 
132 META_INTERFACE_TYPE(META_NS::IAttach);
133 
134 // Include intf_attachment.h to ensure that we get full implementation of our forward declarations
135 #include <meta/interface/intf_attachment.h>
136 
137 #endif
138