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