1 /* 2 * Copyright (c) 2022-2023 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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_PROPERTY_H 18 19 #include <cstdint> 20 #include <optional> 21 22 #include "base/memory/ace_type.h" 23 #include "base/utils/macros.h" 24 #include "base/utils/noncopyable.h" 25 26 namespace OHOS::Ace::NG { 27 using PropertyChangeFlag = uint32_t; 28 29 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_NORMAL = 0; 30 // Mark self, parent, children to remeasure. 31 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_MEASURE = 1; 32 // Mark self to reLayout. 33 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_LAYOUT = 1 << 1; 34 35 // Mark self to remeasure. 36 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_MEASURE_SELF = 1 << 3; 37 38 // Mark self and parent to remeasure. 39 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT = 1 << 4; 40 41 // Mark self remeasure due to child size may change, which may mark parent, self and children to remeasure. 42 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_BY_CHILD_REQUEST = 1 << 5; 43 44 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_RENDER = 1 << 6; 45 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_RENDER_BY_CHILD_REQUEST = 1 << 7; 46 47 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_EVENT = 1 << 8; 48 49 bool CheckNeedRender(PropertyChangeFlag propertyChangeFlag); 50 51 bool CheckNeedRequestMeasureAndLayout(PropertyChangeFlag propertyChangeFlag); 52 53 bool CheckNeedRequestParentMeasure(PropertyChangeFlag propertyChangeFlag); 54 55 bool CheckNeedMeasure(PropertyChangeFlag propertyChangeFlag); 56 57 bool CheckNeedLayout(PropertyChangeFlag propertyChangeFlag); 58 59 bool CheckMeasureFlag(PropertyChangeFlag propertyChangeFlag); 60 61 bool CheckForceParentMeasureFlag(PropertyChangeFlag propertyChangeFlag); 62 63 bool CheckLayoutFlag(PropertyChangeFlag propertyChangeFlag); 64 65 bool CheckMeasureSelfFlag(PropertyChangeFlag propertyChangeFlag); 66 67 bool CheckMeasureSelfAndParentFlag(PropertyChangeFlag propertyChangeFlag); 68 69 bool CheckUpdateByChildRequest(PropertyChangeFlag propertyChangeFlag); 70 71 bool CheckNoChanged(PropertyChangeFlag propertyChangeFlag); 72 73 // For XXXProperty Class 74 #define ACE_DEFINE_PROPERTY_GROUP(group, type) \ 75 public: \ 76 const std::unique_ptr<type>& GetOrCreate##group() \ 77 { \ 78 if (!prop##group##_) { \ 79 prop##group##_ = std::make_unique<type>(); \ 80 } \ 81 return prop##group##_; \ 82 } \ 83 const std::unique_ptr<type>& Get##group() const \ 84 { \ 85 return prop##group##_; \ 86 } \ 87 std::unique_ptr<type> Clone##group() const \ 88 { \ 89 if (prop##group##_) { \ 90 return std::make_unique<type>(*prop##group##_); \ 91 } \ 92 return nullptr; \ 93 } \ 94 void Reset##group() \ 95 { \ 96 return prop##group##_.reset(); \ 97 } \ 98 \ 99 protected: \ 100 std::unique_ptr<type> prop##group##_; 101 102 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \ 103 public: \ 104 std::optional<type> Get##name() const \ 105 { \ 106 auto& groupProperty = Get##group(); \ 107 if (groupProperty) { \ 108 return groupProperty->Get##name(); \ 109 } \ 110 return std::nullopt; \ 111 } \ 112 bool Has##name() const \ 113 { \ 114 auto& groupProperty = Get##group(); \ 115 if (groupProperty) { \ 116 return groupProperty->Has##name(); \ 117 } \ 118 return false; \ 119 } \ 120 type Get##name##Value(const type& defaultValue) const \ 121 { \ 122 auto& groupProperty = Get##group(); \ 123 if (groupProperty) { \ 124 if (groupProperty->Has##name()) { \ 125 return groupProperty->Get##name##Value(); \ 126 } \ 127 } \ 128 return defaultValue; \ 129 } \ 130 void Reset##name() \ 131 { \ 132 auto& groupProperty = Get##group(); \ 133 if (groupProperty) { \ 134 groupProperty->Reset##name(); \ 135 } \ 136 } 137 138 // For different members of the same type, such as the same foreground and background color types, but the interface 139 // names provided to the outside world need to be different. 140 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type) \ 141 public: \ 142 std::optional<type> Get##name() const \ 143 { \ 144 auto& groupProperty = Get##group(); \ 145 if (groupProperty) { \ 146 return groupProperty->Get##groupItem(); \ 147 } \ 148 return std::nullopt; \ 149 } \ 150 bool Has##name() const \ 151 { \ 152 auto& groupProperty = Get##group(); \ 153 if (groupProperty) { \ 154 return groupProperty->Has##groupItem(); \ 155 } \ 156 return false; \ 157 } \ 158 type Get##name##Value(const type& defaultValue) const \ 159 { \ 160 auto& groupProperty = Get##group(); \ 161 if (groupProperty) { \ 162 if (groupProperty->Has##groupItem()) { \ 163 return groupProperty->Get##groupItem##Value(); \ 164 } \ 165 } \ 166 return defaultValue; \ 167 } 168 169 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(group, name, type, changeFlag) \ 170 ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \ 171 void Update##name(const type& value) \ 172 { \ 173 auto& groupProperty = GetOrCreate##group(); \ 174 if (groupProperty->Check##name(value)) { \ 175 LOGD("the %{public}s is same, just ignore", #name); \ 176 return; \ 177 } \ 178 groupProperty->Update##name(value); \ 179 UpdatePropertyChangeFlag(changeFlag); \ 180 } 181 182 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM(group, groupItem, name, type, changeFlag) \ 183 ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type) \ 184 void Update##name(const type& value) \ 185 { \ 186 auto& groupProperty = GetOrCreate##group(); \ 187 if (groupProperty->Check##groupItem(value)) { \ 188 LOGD("the %{public}s is same, just ignore", #name); \ 189 return; \ 190 } \ 191 groupProperty->Update##groupItem(value); \ 192 UpdatePropertyChangeFlag(changeFlag); \ 193 } 194 195 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_AND_CALLBACK(group, name, type, changeFlag) \ 196 ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \ 197 void Update##name(const type& value) \ 198 { \ 199 auto& groupProperty = GetOrCreate##group(); \ 200 if (groupProperty->Check##name(value)) { \ 201 LOGD("the %{public}s is same, just ignore", #name); \ 202 return; \ 203 } \ 204 groupProperty->Update##name(value); \ 205 UpdatePropertyChangeFlag(changeFlag); \ 206 On##name##Update(value); \ 207 } 208 209 #define ACE_DEFINE_PROPERTY_FUNC_WITH_GROUP(group, name, type) \ 210 ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \ 211 void Update##name(const type& value) \ 212 { \ 213 auto& groupProperty = GetOrCreate##group(); \ 214 if (groupProperty->Check##name(value)) { \ 215 LOGD("the %{public}s is same, just ignore", #name); \ 216 return; \ 217 } \ 218 groupProperty->Update##name(value); \ 219 On##name##Update(value); \ 220 } 221 222 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type) \ 223 public: \ 224 const std::optional<type>& Get##name() const \ 225 { \ 226 return prop##name##_; \ 227 } \ 228 bool Has##name() const \ 229 { \ 230 return prop##name##_.has_value(); \ 231 } \ 232 const type& Get##name##Value() const \ 233 { \ 234 return prop##name##_.value(); \ 235 } \ 236 const type& Get##name##Value(const type& defaultValue) const \ 237 { \ 238 if (!Has##name()) { \ 239 return defaultValue; \ 240 } \ 241 return prop##name##_.value(); \ 242 } \ 243 std::optional<type> Clone##name() const \ 244 { \ 245 return prop##name##_; \ 246 } \ 247 void Reset##name() \ 248 { \ 249 return prop##name##_.reset(); \ 250 } \ 251 \ 252 protected: \ 253 std::optional<type> prop##name##_; 254 255 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(name, type, changeFlag) \ 256 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type) \ 257 public: \ 258 void Update##name(const type& value) \ 259 { \ 260 if (prop##name##_.has_value()) { \ 261 if (NearEqual(prop##name##_.value(), value)) { \ 262 LOGD("the %{public}s is same, just ignore", #name); \ 263 return; \ 264 } \ 265 } \ 266 prop##name##_ = value; \ 267 UpdatePropertyChangeFlag(changeFlag); \ 268 } 269 270 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_AND_USING_CALLBACK(name, type, changeFlag) \ 271 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type) \ 272 public: \ 273 void Update##name(const type& value) \ 274 { \ 275 if (prop##name##_.has_value()) { \ 276 if (NearEqual(prop##name##_.value(), value)) { \ 277 LOGD("the %{public}s is same, just ignore", #name); \ 278 return; \ 279 } \ 280 } \ 281 prop##name##_ = value; \ 282 UpdatePropertyChangeFlag(changeFlag); \ 283 On##name##Update(value); \ 284 } 285 286 #define ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(name, type) \ 287 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type) \ 288 public: \ 289 void Update##name(const type& value) \ 290 { \ 291 if (prop##name##_.has_value()) { \ 292 if (NearEqual(prop##name##_.value(), value)) { \ 293 LOGD("the %{public}s is same, just ignore", #name); \ 294 return; \ 295 } \ 296 } \ 297 prop##name##_ = value; \ 298 On##name##Update(value); \ 299 } 300 301 // For Property Group Struct 302 #define ACE_DEFINE_PROPERTY_GROUP_ITEM(name, type) \ 303 std::optional<type> prop##name; \ 304 \ 305 const std::optional<type>& Get##name() const \ 306 { \ 307 return prop##name; \ 308 } \ 309 bool Has##name() const \ 310 { \ 311 return prop##name.has_value(); \ 312 } \ 313 type Get##name##Value() const \ 314 { \ 315 return prop##name.value(); \ 316 } \ 317 bool Update##name(const type& value) \ 318 { \ 319 if (prop##name.has_value()) { \ 320 if (NearEqual(prop##name.value(), value)) { \ 321 return false; \ 322 } \ 323 } \ 324 prop##name = value; \ 325 return true; \ 326 } \ 327 bool Check##name(const type& value) const \ 328 { \ 329 if (!prop##name.has_value()) { \ 330 return false; \ 331 } \ 332 return NearEqual(prop##name.value(), value); \ 333 } \ 334 void Reset##name() \ 335 { \ 336 prop##name.reset(); \ 337 } 338 339 #define ACE_PROPERTY_TO_JSON_VALUE(target, type) \ 340 do { \ 341 if (target) { \ 342 (target)->ToJsonValue(json); \ 343 } else { \ 344 type p; \ 345 p.ToJsonValue(json); \ 346 } \ 347 } while (false) 348 349 class ACE_EXPORT Property : public virtual AceType { 350 DECLARE_ACE_TYPE(Property, AceType); 351 352 public: 353 Property() = default; 354 355 ~Property() override = default; 356 GetPropertyChangeFlag()357 PropertyChangeFlag GetPropertyChangeFlag() const 358 { 359 return propertyChangeFlag_; 360 } 361 CleanDirty()362 void CleanDirty() 363 { 364 propertyChangeFlag_ = PROPERTY_UPDATE_NORMAL; 365 } 366 UpdatePropertyChangeFlag(PropertyChangeFlag propertyChangeFlag)367 void UpdatePropertyChangeFlag(PropertyChangeFlag propertyChangeFlag) 368 { 369 propertyChangeFlag_ = propertyChangeFlag_ | propertyChangeFlag; 370 } 371 372 protected: 373 PropertyChangeFlag propertyChangeFlag_ = PROPERTY_UPDATE_NORMAL; 374 375 ACE_DISALLOW_COPY_AND_MOVE(Property); 376 }; 377 } // namespace OHOS::Ace::NG 378 379 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_PROPERTY_H