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 SCENE_SRC_CONVERTING_VALUE_H
17 #define SCENE_SRC_CONVERTING_VALUE_H
18
19 #include <atomic>
20 #include <scene/ext/intf_converting_value.h>
21
22 #include <meta/api/make_callback.h>
23 #include <meta/interface/property/intf_stack_property.h>
24 #include <meta/interface/property/intf_stack_resetable.h>
25
SCENE_BEGIN_NAMESPACE()26 SCENE_BEGIN_NAMESPACE()
27
28 template<typename PropertyType>
29 class ConvertingValueBase : public META_NS::IntroduceInterfaces<META_NS::INotifyOnChange, META_NS::IStackResetable,
30 META_NS::IValue, IConvertingValue> {
31 public:
32 ConvertingValueBase(PropertyType p) : p_(p) {}
33
34 META_NS::ResetResult ProcessOnReset(const META_NS::IAny&) override
35 {
36 return META_NS::RESET_CONTINUE;
37 }
38
39 BASE_NS::shared_ptr<META_NS::IEvent> EventOnChanged(META_NS::MetadataQuery) const override
40 {
41 return p_->OnChanged();
42 }
43
44 META_NS::IProperty::Ptr GetTargetProperty() override
45 {
46 return p_;
47 }
48
49 protected:
50 PropertyType p_;
51 };
52
53 template<typename Converter>
54 class ConvertingValue : public ConvertingValueBase<META_NS::Property<typename Converter::TargetType>> {
55 public:
56 using Super = ConvertingValueBase<META_NS::Property<typename Converter::TargetType>>;
57
58 using TargetType = typename Converter::TargetType;
59 using SourceType = typename Converter::SourceType;
60 using TargetProperty = META_NS::Property<TargetType>;
61
62 explicit ConvertingValue(TargetProperty p, Converter convert = {})
Super(p)63 : Super(p), any_(META_NS::ConstructAny<SourceType>()), convert_(BASE_NS::move(convert))
64 {}
65
SetValue(const META_NS::IAny & any)66 META_NS::AnyReturnValue SetValue(const META_NS::IAny& any) override
67 {
68 SourceType value {};
69 auto res = any.GetValue<SourceType>(value);
70 if (res) {
71 res = this->p_->SetValue(convert_.ConvertToTarget(value));
72 if (res) {
73 any_->SetValue(value);
74 }
75 }
76 return res;
77 }
GetValue()78 const META_NS::IAny& GetValue() const override
79 {
80 any_->SetValue(convert_.ConvertToSource(*any_, this->p_->GetValue()));
81 return *any_;
82 }
IsCompatible(const META_NS::TypeId & id)83 bool IsCompatible(const META_NS::TypeId& id) const override
84 {
85 return id == META_NS::UidFromType<SourceType>() || id == META_NS::UidFromType<TargetType>();
86 }
87
88 private:
89 META_NS::IAny::Ptr any_;
90 Converter convert_;
91 };
92
93 template<typename Converter>
94 class ConvertingArrayValue : public ConvertingValueBase<META_NS::ArrayProperty<typename Converter::TargetType>> {
95 public:
96 using Super = ConvertingValueBase<META_NS::ArrayProperty<typename Converter::TargetType>>;
97
98 using TargetType = typename Converter::TargetType;
99 using SourceType = typename Converter::SourceType;
100 using TargetProperty = META_NS::ArrayProperty<TargetType>;
101
102 explicit ConvertingArrayValue(TargetProperty p, Converter convert = {})
Super(p)103 : Super(p), any_(META_NS::ConstructArrayAny<SourceType>()), convert_(BASE_NS::move(convert))
104 {}
105
SetValue(const META_NS::IAny & any)106 META_NS::AnyReturnValue SetValue(const META_NS::IAny& any) override
107 {
108 BASE_NS::vector<SourceType> value {};
109 auto res = any.GetValue<BASE_NS::vector<SourceType>>(value);
110 if (res) {
111 BASE_NS::vector<TargetType> converted;
112 for (auto&& v : value) {
113 converted.push_back(convert_.ConvertToTarget(v));
114 }
115 res = this->p_->SetValue(converted);
116 if (res) {
117 any_->SetValue(converted);
118 }
119 }
120 return res;
121 }
GetValue()122 const META_NS::IAny& GetValue() const override
123 {
124 BASE_NS::vector<SourceType> result;
125 for (auto&& v : this->p_->GetValue()) {
126 result.push_back(convert_.ConvertToSource(*any_, v));
127 }
128 any_->SetValue(result);
129 return *any_;
130 }
IsCompatible(const META_NS::TypeId & id)131 bool IsCompatible(const META_NS::TypeId& id) const override
132 {
133 return id == META_NS::ArrayUidFromType<SourceType>() || id == META_NS::ArrayUidFromType<TargetType>();
134 }
135
136 private:
137 META_NS::IAny::Ptr any_;
138 Converter convert_;
139 };
140
141 SCENE_END_NAMESPACE()
142
143 #endif
144