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 #include <base/math/matrix.h>
16 #include <base/math/quaternion.h>
17 #include <base/math/vector.h>
18 
19 #include <meta/base/meta_types.h>
20 #include <meta/base/namespace.h>
21 #include <meta/base/time_span.h>
22 #include <meta/ext/serialization/common_value_serializers.h>
23 #include <meta/interface/builtin_objects.h>
24 #include <meta/interface/detail/any.h>
25 #include <meta/interface/intf_iterable.h>
26 #include <meta/interface/intf_object_registry.h>
27 #include <meta/interface/intf_startable.h>
28 
29 META_BEGIN_NAMESPACE()
30 
31 namespace Internal {
32 
33 // workaround for VC bug not being able to handle decltype(out.x) in lambda below
34 template<typename T>
ExportVector(IExportFunctions & f,const T * v,size_t size)35 static ISerNode::Ptr ExportVector(IExportFunctions& f, const T* v, size_t size)
36 {
37     return f.ExportToNode(ArrayAny<T>(BASE_NS::array_view<const T>(v, v + size)));
38 }
39 
40 // workaround for VC bug not being able to handle decltype(out.x) in lambda below
41 template<typename T>
ImportVector(IImportFunctions & f,const ISerNode::ConstPtr & node,T * out,size_t size)42 static bool ImportVector(IImportFunctions& f, const ISerNode::ConstPtr& node, T* out, size_t size)
43 {
44     ArrayAny<T> arr;
45     if (f.ImportFromNode(node, arr)) {
46         const auto& vec = arr.InternalGetValue();
47         if (vec.size() == size) {
48             for (size_t i = 0; i != size; ++i) {
49                 out[i] = vec[i];
50             }
51             return true;
52         }
53     }
54     return false;
55 };
56 
RegisterValueSerializers(IObjectRegistry & registry)57 void RegisterValueSerializers(IObjectRegistry& registry)
58 {
59     auto vecExport = [](IExportFunctions& f, const auto& v) {
60         constexpr size_t size = sizeof(v.data) / sizeof(v.data[0]); /*NOLINT(bugprone-sizeof-expression)*/
61         return ExportVector(f, v.data, size);
62     };
63     auto vecImport = [](IImportFunctions& f, const ISerNode::ConstPtr& node, auto& out) {
64         constexpr size_t size = sizeof(out.data) / sizeof(out.data[0]); /*NOLINT(bugprone-sizeof-expression)*/
65         return ImportVector(f, node, out.data, size);
66     };
67     auto matExport = [](IExportFunctions& f, const auto& v) {
68         constexpr size_t size = sizeof(v.base) / sizeof(v.base[0]); /*NOLINT(bugprone-sizeof-expression)*/
69         return ExportVector(f, v.base, size);
70     };
71     auto matImport = [](IImportFunctions& f, const ISerNode::ConstPtr& node, auto& out) {
72         constexpr size_t size = sizeof(out.base) / sizeof(out.base[0]); /*NOLINT(bugprone-sizeof-expression)*/
73         return ImportVector(f, node, out.base, size);
74     };
75     auto enumExport = [](IExportFunctions& f, const auto& v) { return EnumExport(f, v); };
76     auto enumImport = [](IImportFunctions& f, const ISerNode::ConstPtr& node, auto& out) {
77         return EnumImport(f, node, out);
78     };
79 
80     auto& data = registry.GetGlobalSerializationData();
81     RegisterSerializer<BASE_NS::Math::Vec2>(data, vecExport, vecImport);
82     RegisterSerializer<BASE_NS::Math::Vec3>(data, vecExport, vecImport);
83     RegisterSerializer<BASE_NS::Math::Vec4>(data, vecExport, vecImport);
84     RegisterSerializer<BASE_NS::Math::UVec2>(data, vecExport, vecImport);
85     RegisterSerializer<BASE_NS::Math::UVec3>(data, vecExport, vecImport);
86     RegisterSerializer<BASE_NS::Math::UVec4>(data, vecExport, vecImport);
87     RegisterSerializer<BASE_NS::Math::IVec2>(data, vecExport, vecImport);
88     RegisterSerializer<BASE_NS::Math::IVec3>(data, vecExport, vecImport);
89     RegisterSerializer<BASE_NS::Math::IVec4>(data, vecExport, vecImport);
90     RegisterSerializer<BASE_NS::Math::Quat>(data, vecExport, vecImport);
91     RegisterSerializer<BASE_NS::Math::Mat3X3>(data, matExport, matImport);
92     RegisterSerializer<BASE_NS::Math::Mat4X4>(data, matExport, matImport);
93 
94     RegisterSerializer<BASE_NS::Uid>(
95         data,
96         [](IExportFunctions& f, const auto& v) {
97             return f.ExportToNode(Any<BASE_NS::string>(BASE_NS::to_string(v).c_str()));
98         },
99         [](IImportFunctions& f, const ISerNode::ConstPtr& node, auto& out) {
100             Any<BASE_NS::string> any;
101             if (f.ImportFromNode(node, any)) {
102                 out = BASE_NS::StringToUid(any.InternalGetValue());
103                 return true;
104             }
105             return false;
106         });
107 
108     RegisterSerializer<TimeSpan>(
109         data, [](IExportFunctions& f, const auto& v) { return f.ExportToNode(Any<int64_t>(v.ToMicroseconds())); },
110         [](IImportFunctions& f, const ISerNode::ConstPtr& node, auto& out) {
111             Any<int64_t> any;
112             if (f.ImportFromNode(node, any)) {
113                 out = TimeSpan::Microseconds(any.InternalGetValue());
114                 return true;
115             }
116             return false;
117         });
118 
119     RegisterSerializer<StartableState>(data, enumExport, enumImport);
120     RegisterSerializer<StartBehavior>(data, enumExport, enumImport);
121     RegisterSerializer<TraversalType>(data, enumExport, enumImport);
122 }
123 
UnRegisterValueSerializers(IObjectRegistry & registry)124 void UnRegisterValueSerializers(IObjectRegistry& registry)
125 {
126     auto& data = registry.GetGlobalSerializationData();
127     UnregisterSerializer<TraversalType>(data);
128     UnregisterSerializer<StartBehavior>(data);
129     UnregisterSerializer<StartableState>(data);
130     UnregisterSerializer<TimeSpan>(data);
131     UnregisterSerializer<BASE_NS::Uid>(data);
132     UnregisterSerializer<BASE_NS::Math::Mat4X4>(data);
133     UnregisterSerializer<BASE_NS::Math::Mat3X3>(data);
134     UnregisterSerializer<BASE_NS::Math::Quat>(data);
135     UnregisterSerializer<BASE_NS::Math::IVec4>(data);
136     UnregisterSerializer<BASE_NS::Math::IVec3>(data);
137     UnregisterSerializer<BASE_NS::Math::IVec2>(data);
138     UnregisterSerializer<BASE_NS::Math::UVec4>(data);
139     UnregisterSerializer<BASE_NS::Math::UVec3>(data);
140     UnregisterSerializer<BASE_NS::Math::UVec2>(data);
141     UnregisterSerializer<BASE_NS::Math::Vec4>(data);
142     UnregisterSerializer<BASE_NS::Math::Vec3>(data);
143     UnregisterSerializer<BASE_NS::Math::Vec2>(data);
144 }
145 
146 } // namespace Internal
147 META_END_NAMESPACE()
148