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