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_BASE_TYPES_H 17 #define META_BASE_TYPES_H 18 19 #include <base/containers/string_view.h> 20 #include <base/util/uid.h> 21 22 #include <meta/base/ids.h> 23 #include <meta/base/namespace.h> 24 25 #include "macros.h" 26 27 META_BEGIN_NAMESPACE() 28 29 using nullptr_t = decltype(nullptr); 30 31 struct NoCheckT {}; 32 constexpr NoCheckT NOCHECK; 33 34 /** 35 * @brief The InterfaceInfo struct is used to register a new interface to the toolkit. 36 * Call META_REGISTER_INTERFACE(<InterfaceName>, <InterfaceId>) to register the interface. 37 */ 38 struct InterfaceInfo { 39 /** Returns the unique id of the interface. */ IdInterfaceInfo40 constexpr const TypeId& Id() const noexcept 41 { 42 return id; 43 } 44 /** Returns the name of the interface. */ NameInterfaceInfo45 constexpr const BASE_NS::string_view& Name() const noexcept 46 { 47 return name; 48 } 49 /** Returns the readable name of the interface. */ ReadableNameInterfaceInfo50 constexpr const BASE_NS::string_view& ReadableName() const noexcept 51 { 52 return readableName; 53 } TypeIdInterfaceInfo54 constexpr operator TypeId() const noexcept 55 { 56 return id; 57 } 58 /** Implicit conversion operator InterfaceInfo->Uid. */ UidInterfaceInfo59 constexpr operator BASE_NS::Uid() const noexcept 60 { 61 return id.ToUid(); 62 } IsValidInterfaceInfo63 constexpr bool IsValid() const noexcept 64 { 65 return id.IsValid(); 66 } 67 /** The Uid of the interface. Must be unique. */ 68 TypeId id; 69 /** The name of the interface. */ 70 BASE_NS::string_view name; 71 /** The readable name of the interface. */ 72 BASE_NS::string_view readableName; 73 }; 74 75 inline bool operator==(const InterfaceInfo& lhs, const InterfaceInfo& rhs) noexcept 76 { 77 return lhs.id == rhs.id; 78 } 79 80 inline bool operator!=(const InterfaceInfo& lhs, const InterfaceInfo& rhs) noexcept 81 { 82 return lhs.id != rhs.id; 83 } 84 85 inline bool operator<(const InterfaceInfo& lhs, const InterfaceInfo& rhs) noexcept 86 { 87 return lhs.id < rhs.id; 88 } 89 90 /** 91 * @brief List of supported object categories. 92 */ 93 namespace ObjectCategory { 94 enum Bits : uint64_t { 95 /** Bitmask indicating any category except DEPRECATED */ 96 ANY = 0, 97 /** The object does not belong to any specific category */ 98 NO_CATEGORY = 0x1, 99 /** The object is a UI control */ 100 WIDGET = 0x2, 101 /** The object is an animation */ 102 ANIMATION = 0x4, 103 /** The object is a layout object */ 104 LAYOUT = 0x8, 105 /** The object is a container object */ 106 CONTAINER = 0x10, 107 /** The object is a curve */ 108 CURVE = 0x20, 109 /** The object is a shape */ 110 SHAPE = 0x40, 111 /** The object is for implementation */ 112 INTERNAL = 0x80, 113 /** The object is an application-specific object. Objects registered by 114 applications should usually use this category. */ 115 APPLICATION = 0x100, 116 /** The object is an animation modifier */ 117 ANIMATION_MODIFIER = 0x200, 118 /** The object is a gesture */ 119 GESTURE = 0x400, 120 /** The object is deprecated */ 121 DEPRECATED = 0x800, 122 }; 123 } 124 125 using ObjectCategoryBits = ObjectCategory::Bits; 126 127 /** 128 * @brief The ClassInfo struct contains the basic type information for a given class. 129 */ 130 struct ClassInfo { 131 /** Returns the unique id of the class. */ IdClassInfo132 constexpr const ObjectId& Id() const noexcept 133 { 134 return id; 135 } 136 /** Returns the name of the class. */ NameClassInfo137 constexpr const BASE_NS::string_view& Name() const noexcept 138 { 139 return name; 140 } 141 /** Returns the readable name of the class. */ ReadableNameClassInfo142 constexpr const BASE_NS::string_view& ReadableName() const noexcept 143 { 144 return readableName; 145 } 146 /** Should the class be created as singleton? */ IsSingletonClassInfo147 constexpr bool IsSingleton() const noexcept 148 { 149 return singleton; 150 } 151 /** Implicit conversion operator ClassInfo->Uid. */ ObjectIdClassInfo152 constexpr operator ObjectId() const noexcept 153 { 154 return id; 155 } 156 /** The Uid of the class. Must be unique. */ 157 ObjectId id; 158 /** The name of the class. */ 159 BASE_NS::string_view name; 160 /** Category of the class */ 161 ObjectCategoryBits category; 162 /** A flag indicating if the class can be created as singleton. */ 163 bool singleton; 164 /** The readable name of the class. */ 165 BASE_NS::string_view readableName; 166 }; 167 168 inline bool operator==(const ClassInfo& lhs, const ClassInfo& rhs) noexcept 169 { 170 return lhs.id == rhs.id; 171 } 172 173 inline bool operator!=(const ClassInfo& lhs, const ClassInfo& rhs) noexcept 174 { 175 return lhs.id != rhs.id; 176 } 177 178 inline bool operator<(const ClassInfo& lhs, const ClassInfo& rhs) noexcept 179 { 180 return lhs.id < rhs.id; 181 } 182 183 /** 184 * @brief Register UID and category for class name. This tells there exists a concrete object type with this UID which 185 * can be constructed via ObjectRegistry. Example: META_REGISTER_CLASS(AnimationController, 186 * "32ccf293-e684-46e3-b733-85f9bbcc703c", ObjectCategoryBits::NO_CATEGORY) 187 */ 188 #define META_REGISTER_IMPL_CLASS4(singleton, name, id, cat, readable) \ 189 namespace ClassId { \ 190 [[maybe_unused]] inline constexpr ::META_NS::ClassInfo name { BASE_NS::Uid(id), #name, cat, singleton, readable }; \ 191 } 192 193 #define META_REGISTER_IMPL_CLASS3(singleton, name, id, cat) META_REGISTER_IMPL_CLASS4(singleton, name, id, cat, #name) 194 195 #define META_REGISTER_IMPL_CLASS(singleton, ...) \ 196 META_EXPAND(META_GET_MACRO4_IMPL(__VA_ARGS__, META_REGISTER_IMPL_CLASS4, META_REGISTER_IMPL_CLASS3)( \ 197 singleton, __VA_ARGS__)) 198 199 #define META_REGISTER_CLASS(...) META_REGISTER_IMPL_CLASS(false, __VA_ARGS__) 200 #define REGISTER_CLASS(...) META_REGISTER_CLASS(__VA_ARGS__) 201 202 /** 203 * @brief Register UID and category for class name. This tells there exists a singleton object with this UID which can 204 * be accessed via ObjectRegistry. 205 */ 206 #define META_REGISTER_SINGLETON_CLASS(...) META_REGISTER_IMPL_CLASS(true, __VA_ARGS__) 207 #define REGISTER_SINGLETON_CLASS(...) META_REGISTER_SINGLETON_CLASS(__VA_ARGS__) 208 209 /** 210 * @brief Register UID for interface type. This will associate interface name to UID. 211 * Note: One can use this with two parameter version of META_INTERFACE macro, or 212 * alternatively there is no need for this if using the three parameter version of META_INTERFACE. 213 * Example: 214 * META_REGISTER_INTERFACE(IAttach, "2cc0d7b9-ccec-474e-acdd-d06fb5aeb714") 215 * class IAttach : public CORE_NS::IInterface { 216 * META_INTERFACE(CORE_NS::IInterface, IAttach) 217 * Here the META_INTERFACE macro will find the UID using the name "IAttach". 218 */ 219 #define META_REGISTER_INTERFACE3(name, id, readable) \ 220 namespace InterfaceId { \ 221 [[maybe_unused]] inline constexpr ::META_NS::InterfaceInfo name { META_NS::TypeId(id), #name, readable }; \ 222 } 223 224 #define META_REGISTER_INTERFACE2(name, id) META_REGISTER_INTERFACE3(name, id, #name) 225 226 #define META_REGISTER_INTERFACE(...) \ 227 META_EXPAND(META_GET_MACRO3_IMPL(__VA_ARGS__, META_REGISTER_INTERFACE3, META_REGISTER_INTERFACE2)(__VA_ARGS__)) 228 229 #define REGISTER_INTERFACE(...) META_REGISTER_INTERFACE(__VA_ARGS__) 230 231 META_END_NAMESPACE() 232 233 #endif 234