• 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 // 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 inline constexpr PropertyChangeFlag PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD = 1 << 9;
50 
51 bool CheckNeedRender(PropertyChangeFlag propertyChangeFlag);
52 
53 bool CheckNeedRequestMeasureAndLayout(PropertyChangeFlag propertyChangeFlag);
54 
55 bool CheckNeedRequestParentMeasure(PropertyChangeFlag propertyChangeFlag);
56 
57 bool CheckNeedMeasure(PropertyChangeFlag propertyChangeFlag);
58 
59 bool CheckNeedLayout(PropertyChangeFlag propertyChangeFlag);
60 
61 bool CheckMeasureFlag(PropertyChangeFlag propertyChangeFlag);
62 
63 bool CheckForceParentMeasureFlag(PropertyChangeFlag propertyChangeFlag);
64 
65 bool CheckLayoutFlag(PropertyChangeFlag propertyChangeFlag);
66 
67 bool CheckMeasureSelfFlag(PropertyChangeFlag propertyChangeFlag);
68 
69 bool CheckMeasureSelfAndParentFlag(PropertyChangeFlag propertyChangeFlag);
70 
71 bool CheckMeasureSelfAndChildFlag(PropertyChangeFlag propertyChangeFlag);
72 
73 bool CheckUpdateByChildRequest(PropertyChangeFlag propertyChangeFlag);
74 
75 bool CheckNoChanged(PropertyChangeFlag propertyChangeFlag);
76 
77 // For XXXProperty Class
78 #define ACE_DEFINE_PROPERTY_GROUP(group, type)              \
79 public:                                                     \
80     const std::unique_ptr<type>& GetOrCreate##group()       \
81     {                                                       \
82         if (!prop##group##_) {                              \
83             prop##group##_ = std::make_unique<type>();      \
84         }                                                   \
85         return prop##group##_;                              \
86     }                                                       \
87     const std::unique_ptr<type>& Get##group() const         \
88     {                                                       \
89         return prop##group##_;                              \
90     }                                                       \
91     std::unique_ptr<type> Clone##group() const              \
92     {                                                       \
93         if (prop##group##_) {                               \
94             return std::make_unique<type>(*prop##group##_); \
95         }                                                   \
96         return nullptr;                                     \
97     }                                                       \
98     void Reset##group()                                     \
99     {                                                       \
100         return prop##group##_.reset();                      \
101     }                                                       \
102                                                             \
103 protected:                                                  \
104     std::unique_ptr<type> prop##group##_;
105 
106 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \
107 public:                                                            \
108     std::optional<type> Get##name() const                          \
109     {                                                              \
110         auto& groupProperty = Get##group();                        \
111         if (groupProperty) {                                       \
112             return groupProperty->Get##name();                     \
113         }                                                          \
114         return std::nullopt;                                       \
115     }                                                              \
116     bool Has##name() const                                         \
117     {                                                              \
118         auto& groupProperty = Get##group();                        \
119         if (groupProperty) {                                       \
120             return groupProperty->Has##name();                     \
121         }                                                          \
122         return false;                                              \
123     }                                                              \
124     type Get##name##Value(const type& defaultValue) const          \
125     {                                                              \
126         auto& groupProperty = Get##group();                        \
127         if (groupProperty) {                                       \
128             if (groupProperty->Has##name()) {                      \
129                 return groupProperty->Get##name##Value();          \
130             }                                                      \
131         }                                                          \
132         return defaultValue;                                       \
133     }                                                              \
134     void Reset##name()                                             \
135     {                                                              \
136         auto& groupProperty = Get##group();                        \
137         if (groupProperty) {                                       \
138             groupProperty->Reset##name();                          \
139         }                                                          \
140     }
141 
142 // For different members of the same type, such as the same foreground and background color types, but the interface
143 // names provided to the outside world need to be different.
144 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type) \
145 public:                                                                            \
146     std::optional<type> Get##name() const                                          \
147     {                                                                              \
148         auto& groupProperty = Get##group();                                        \
149         if (groupProperty) {                                                       \
150             return groupProperty->Get##groupItem();                                \
151         }                                                                          \
152         return std::nullopt;                                                       \
153     }                                                                              \
154     bool Has##name() const                                                         \
155     {                                                                              \
156         auto& groupProperty = Get##group();                                        \
157         if (groupProperty) {                                                       \
158             return groupProperty->Has##groupItem();                                \
159         }                                                                          \
160         return false;                                                              \
161     }                                                                              \
162     type Get##name##Value(const type& defaultValue) const                          \
163     {                                                                              \
164         auto& groupProperty = Get##group();                                        \
165         if (groupProperty) {                                                       \
166             if (groupProperty->Has##groupItem()) {                                 \
167                 return groupProperty->Get##groupItem##Value();                     \
168             }                                                                      \
169         }                                                                          \
170         return defaultValue;                                                       \
171     }
172 
173 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(group, name, type, changeFlag) \
174     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type)             \
175     void Update##name(const type& value)                                   \
176     {                                                                      \
177         auto& groupProperty = GetOrCreate##group();                        \
178         if (groupProperty->Check##name(value)) {                           \
179             LOGD("the %{public}s is same, just ignore", #name);            \
180             return;                                                        \
181         }                                                                  \
182         groupProperty->Update##name(value);                                \
183         UpdatePropertyChangeFlag(changeFlag);                              \
184     }
185 
186 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM(group, groupItem, name, type, changeFlag) \
187     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type)             \
188     void Update##name(const type& value)                                                   \
189     {                                                                                      \
190         auto& groupProperty = GetOrCreate##group();                                        \
191         if (groupProperty->Check##groupItem(value)) {                                      \
192             LOGD("the %{public}s is same, just ignore", #name);                            \
193             return;                                                                        \
194         }                                                                                  \
195         groupProperty->Update##groupItem(value);                                           \
196         UpdatePropertyChangeFlag(changeFlag);                                              \
197     }
198 
199 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_AND_CALLBACK(group, name, type, changeFlag) \
200     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type)                          \
201     void Update##name(const type& value)                                                \
202     {                                                                                   \
203         auto& groupProperty = GetOrCreate##group();                                     \
204         if (groupProperty->Check##name(value)) {                                        \
205             LOGD("the %{public}s is same, just ignore", #name);                         \
206             return;                                                                     \
207         }                                                                               \
208         groupProperty->Update##name(value);                                             \
209         UpdatePropertyChangeFlag(changeFlag);                                           \
210         On##name##Update(value);                                                        \
211     }
212 
213 #define ACE_DEFINE_PROPERTY_FUNC_WITH_GROUP(group, name, type)  \
214     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type)  \
215     void Update##name(const type& value)                        \
216     {                                                           \
217         auto& groupProperty = GetOrCreate##group();             \
218         if (groupProperty->Check##name(value)) {                \
219             LOGD("the %{public}s is same, just ignore", #name); \
220             return;                                             \
221         }                                                       \
222         groupProperty->Update##name(value);                     \
223         On##name##Update(value);                                \
224     }
225 
226 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)   \
227 public:                                                          \
228     const std::optional<type>& Get##name() const                 \
229     {                                                            \
230         return prop##name##_;                                    \
231     }                                                            \
232     bool Has##name() const                                       \
233     {                                                            \
234         return prop##name##_.has_value();                        \
235     }                                                            \
236     const type& Get##name##Value() const                         \
237     {                                                            \
238         return prop##name##_.value();                            \
239     }                                                            \
240     const type& Get##name##Value(const type& defaultValue) const \
241     {                                                            \
242         if (!Has##name()) {                                      \
243             return defaultValue;                                 \
244         }                                                        \
245         return prop##name##_.value();                            \
246     }                                                            \
247     std::optional<type> Clone##name() const                      \
248     {                                                            \
249         return prop##name##_;                                    \
250     }                                                            \
251     void Reset##name()                                           \
252     {                                                            \
253         return prop##name##_.reset();                            \
254     }                                                            \
255                                                                  \
256 protected:                                                       \
257     std::optional<type> prop##name##_;
258 
259 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(name, type, changeFlag) \
260     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)             \
261 public:                                                                \
262     void Update##name(const type& value)                               \
263     {                                                                  \
264         if (prop##name##_.has_value()) {                               \
265             if (NearEqual(prop##name##_.value(), value)) {             \
266                 LOGD("the %{public}s is same, just ignore", #name);    \
267                 return;                                                \
268             }                                                          \
269         }                                                              \
270         prop##name##_ = value;                                         \
271         UpdatePropertyChangeFlag(changeFlag);                          \
272     }
273 
274 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_AND_USING_CALLBACK(name, type, changeFlag) \
275     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)                                \
276 public:                                                                                   \
277     void Update##name(const type& value)                                                  \
278     {                                                                                     \
279         if (prop##name##_.has_value()) {                                                  \
280             if (NearEqual(prop##name##_.value(), value)) {                                \
281                 LOGD("the %{public}s is same, just ignore", #name);                       \
282                 return;                                                                   \
283             }                                                                             \
284         }                                                                                 \
285         prop##name##_ = value;                                                            \
286         UpdatePropertyChangeFlag(changeFlag);                                             \
287         On##name##Update(value);                                                          \
288     }
289 
290 #define ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(name, type)     \
291     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)          \
292 public:                                                             \
293     void Update##name(const type& value)                            \
294     {                                                               \
295         if (prop##name##_.has_value()) {                            \
296             if (NearEqual(prop##name##_.value(), value)) {          \
297                 LOGD("the %{public}s is same, just ignore", #name); \
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