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_FLAGS_H
17 #define META_INTERFACE_IOBJECT_FLAGS_H
18 
19 #include <core/plugin/intf_interface.h>
20 
21 #include <meta/base/bit_field.h>
22 #include <meta/base/namespace.h>
23 #include <meta/base/shared_ptr.h>
24 #include <meta/base/types.h>
25 
26 META_BEGIN_NAMESPACE()
27 
28 META_REGISTER_INTERFACE(IObjectFlags, "18f6d873-174e-406b-a252-3cb11a9f45c0")
29 
30 /**
31  * @brief Flags for all object types.
32  * @note  Depending on the interfaces a particular class implements, some of the flags
33  *        may not have any effect.
34  */
35 enum class ObjectFlagBits : uint8_t {
36     /** No bits set */
37     NONE = 0,
38     /** Should this object be serialized.*/
39     SERIALIZE = 1,
40     /** If the object contains a sub-hierarchy (e.g. through implementing IContainer or IContent),
41      *  this flag controls whether the hierarchy is serialized.
42      *  If SERIALIZE flag is not set, this flag has no effect. */
43     SERIALIZE_HIERARCHY = 2,
44     /** If the object has attachments, this flag controls whether they are serialized.
45      *  If SERIALIZE flag is not set, this flag has no effect. */
46     SERIALIZE_ATTACHMENTS = 4,
47     /** The object is an internal object for the implementation.
48      * E.g. a user interface editor should not show the object in the UI. */
49     INTERNAL = 8,
50     /** The object is native to the system, e.g. property predefined in the implementing class, BorderWidth
51      * is a native property of the Rectangle. This flag is not set when object was created by the user. */
52     NATIVE = 16,
53     /** The default object flags for for objects. The default flags for a class can be
54         queried by calling IObjectFlags::GetObjectDefaultFlags. */
55     DEFAULT_FLAGS = SERIALIZE | SERIALIZE_HIERARCHY | SERIALIZE_ATTACHMENTS,
56 };
57 
58 inline ObjectFlagBits operator|(ObjectFlagBits l, ObjectFlagBits r)
59 {
60     return ObjectFlagBits(uint8_t(l) | uint8_t(r));
61 }
62 
63 /**
64  * @brief All flags for object, first 8 bits are generic object flags and rest of the bits are
65  * for specific objects to define as their extension.
66  */
67 using ObjectFlagBitsValue = EnumBitField<ObjectFlagBits, uint64_t>;
68 
69 /**
70  * @brief Offset where user defined extension bits start and how many there are.
71  */
72 constexpr size_t USER_FLAG_BASE = 8;
73 constexpr size_t USER_FLAG_SIZE = 56;
74 
75 /**
76  * @brief The IObjectFlags interface can be implemented by classes which
77  *        allow setting flags on the objects.
78  */
79 class IObjectFlags : public CORE_NS::IInterface {
80     META_INTERFACE(CORE_NS::IInterface, IObjectFlags)
81 public:
82     /**
83      * @brief Get Flags associated with this object
84      */
85     virtual ObjectFlagBitsValue GetObjectFlags() const = 0;
86     /**
87      * @brief Set Flags associated with this object
88      */
89     virtual void SetObjectFlags(const ObjectFlagBitsValue& value) = 0;
90     /**
91      * @brief Returns the default object flags for the class which implements IObjectFlags.
92      */
93     virtual ObjectFlagBitsValue GetObjectDefaultFlags() const = 0;
94 };
95 
96 /**
97  * @brief A helper function for setting the state of an object flag.
98  * @param object The object to set flags on.
99  * @param value The ObjectFlagBitsValue to set.
100  * @param isSet If true, the bits should be set. If false, bits should be unset.
101  */
102 template<typename T, typename = BASE_NS::enable_if<IsKindOfPointer_v<T>>>
SetObjectFlags(const T & object,ObjectFlagBitsValue value,bool isSet)103 void SetObjectFlags(const T& object, ObjectFlagBitsValue value, bool isSet)
104 {
105     if (auto objectFlagsPtr = interface_cast<IObjectFlags>(object)) {
106         const auto flags = objectFlagsPtr->GetObjectFlags();
107         objectFlagsPtr->SetObjectFlags(isSet ? flags | value : flags & ~value);
108     }
109 }
110 
111 template<typename T, typename = BASE_NS::enable_if<IsKindOfPointer_v<T>>>
GetObjectFlags(const T & object)112 ObjectFlagBitsValue GetObjectFlags(const T& object)
113 {
114     const auto objectFlagsPtr = interface_cast<IObjectFlags>(object);
115     return objectFlagsPtr ? objectFlagsPtr->GetObjectFlags() : ObjectFlagBitsValue(ObjectFlagBits::NONE);
116 }
117 
118 template<typename T, typename = BASE_NS::enable_if<IsKindOfPointer_v<T>>>
IsFlagSet(const T & object,ObjectFlagBitsValue value)119 bool IsFlagSet(const T& object, ObjectFlagBitsValue value)
120 {
121     if (auto objectFlagsPtr = interface_cast<IObjectFlags>(object)) {
122         return objectFlagsPtr->GetObjectFlags().IsSet(value);
123     }
124     return false;
125 }
126 
127 META_END_NAMESPACE()
128 
129 META_TYPE(META_NS::IObjectFlags::Ptr);
130 META_TYPE(META_NS::IObjectFlags::WeakPtr);
131 META_TYPE(META_NS::IObjectFlags::ConstPtr);
132 META_TYPE(META_NS::IObjectFlags::ConstWeakPtr);
133 
134 #endif // META_INTERFACE_IOBJECT_FLAGS_H
135