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
29META_BEGIN_NAMESPACE()
30
31namespace Internal {
32
33// workaround for VC bug not being able to handle decltype(out.x) in lambda below
34template<typename T>
35static 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
41template<typename T>
42static 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
57void 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
124void 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
147META_END_NAMESPACE()
148