• 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 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