Lagrange
Loading...
Searching...
No Matches
SceneExtension.h
1/*
2 * Copyright 2024 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/internal/SafeVector.h>
15#include <lagrange/scene/api.h>
16#include <lagrange/utils/assert.h>
17#include <lagrange/utils/invalid.h>
18#include <lagrange/utils/span.h>
19#include <lagrange/utils/value_ptr.h>
20
21#include <any>
22#include <cstring>
23#include <map>
24#include <string>
25#include <unordered_map>
26#include <variant>
27#include <vector>
28
29namespace lagrange {
30namespace scene {
31
32// Json-like value used in scene extensions
33class LA_SCENE_API Value
34{
35public:
36 using Array = std::vector<Value>;
37 // using Array = SafeVector<Value>; // TODO: Switch to this?
38 using Object = std::map<std::string, Value>;
39 using Buffer = std::vector<unsigned char>;
40 using variant_type = std::variant<bool, int, double, std::string, Buffer, Array, Object>;
41
45 template <typename T>
46 static constexpr bool is_variant_type()
47 {
48 return variant_index<T>() < (std::variant_size_v<variant_type>);
49 }
50
54 template <typename T, std::size_t index = 0>
55 static constexpr std::size_t variant_index()
56 {
57 if constexpr (index == std::variant_size_v<variant_type>) {
58 return index;
59 } else if constexpr (std::is_same_v<std::variant_alternative_t<index, variant_type>, T>) {
60 return index;
61 } else {
63 }
64 }
65
66 static constexpr size_t bool_index() { return variant_index<bool>(); }
67 static constexpr size_t int_index() { return variant_index<int>(); }
68 static constexpr size_t real_index() { return variant_index<double>(); }
69 static constexpr size_t string_index() { return variant_index<std::string>(); }
70 static constexpr size_t buffer_index() { return variant_index<Buffer>(); }
71 static constexpr size_t array_index() { return variant_index<Array>(); }
72 static constexpr size_t object_index() { return variant_index<Object>(); }
73
74 static Value create_buffer() { return Value(Buffer()); }
75 static Value create_array() { return Value(Array()); }
76 static Value create_object() { return Value(Object()); }
77
78 Value() = default;
79 explicit Value(bool b) { value = b; }
80 explicit Value(int i) { value = i; }
81 explicit Value(double n) { value = n; }
82 explicit Value(std::string s) { value = std::move(s); }
83 explicit Value(std::string_view s) { value = std::string(s); }
84 explicit Value(const char* s) { value = std::string(s); }
85 explicit Value(span<unsigned char> s)
86 {
87 Buffer vec(s.size());
88 std::memcpy(vec.data(), s.data(), s.size());
89 value = std::move(vec);
90 }
91 explicit Value(const Buffer& v) { value = v; }
92 explicit Value(Buffer&& v) { value = std::move(v); }
93 explicit Value(const Array& a) { value = a; }
94 explicit Value(Array&& a) { value = std::move(a); }
95 explicit Value(const Object& o) { value = o; }
96 explicit Value(Object&& o) { value = std::move(o); }
97
98 template <typename T>
99 bool is_type() const
100 {
101 return std::holds_alternative<T>(value);
102 }
103 bool is_bool() const { return is_type<bool>(); }
104 bool is_int() const { return is_type<int>(); }
105 bool is_real() const { return is_type<double>(); }
106 bool is_number() const { return is_int() || is_real(); }
107 bool is_string() const { return is_type<std::string>(); }
108 bool is_buffer() const { return is_type<Buffer>(); }
109 bool is_array() const { return is_type<Array>(); }
110 bool is_object() const { return is_type<Object>(); }
111 size_t get_type_index() const { return value.index(); }
112
113 template <typename T>
114 const T& get() const
115 {
116 return std::get<T>(value);
117 }
118 template <typename T>
119 T& get()
120 {
121 return std::get<T>(value);
122 }
123 bool get_bool() const { return get<bool>(); }
124 int get_int() const { return get<int>(); }
125 double get_real() const { return get<double>(); }
126 const std::string& get_string() const { return get<std::string>(); }
127 std::string get_string() { return get<std::string>(); }
128 const Buffer& get_buffer() const { return get<Buffer>(); }
129 Buffer& get_buffer() { return get<Buffer>(); }
130 const Array& get_array() const { return get<Array>(); }
131 Array& get_array() { return get<Array>(); }
132 const Object& get_object() const { return get<Object>(); }
133 Object& get_object() { return get<Object>(); }
134
135 template <typename T>
136 void set(T t)
137 {
138 value = t;
139 }
140 void set_bool(bool b) { value = b; }
141 void set_int(int i) { value = i; }
142 void set_real(double n) { value = n; }
143
144 // Only valid for array values:
145 const Value& operator[](size_t idx) const
146 {
147 la_debug_assert(is_array());
148 return get_array()[idx];
149 }
150 Value& operator[](size_t idx)
151 {
152 la_debug_assert(is_array());
153 return get_array()[idx];
154 }
155
156 // Only valid for object values:
157 bool has(const std::string& key) const { return get_object().find(key) != get_object().end(); }
158 const Value& operator[](const std::string& key) const
159 {
160 la_debug_assert(is_object());
161 return get_object().find(key)->second;
162 }
163 Value& operator[](const std::string& key)
164 {
165 la_debug_assert(is_object());
166 return get_object().find(key)->second;
167 }
168
169 // Only valid for some value types (string, array, object, buffer).
170 size_t size() const
171 {
172 if (is_string()) return get_string().size();
173 if (is_buffer()) return get_buffer().size();
174 if (is_array()) return get_array().size();
175 if (is_object()) return get_object().size();
176 return 0;
177 }
178
179protected:
180 variant_type value;
181};
182
183struct LA_SCENE_API UserDataConverter
184{
185 virtual bool is_supported(const std::string& key) const = 0;
186 virtual bool can_read(const std::string& key) const { return is_supported(key); }
187 virtual bool can_write(const std::string& key) const { return is_supported(key); }
188
189 virtual std::any read(const Value& value) const = 0;
190 virtual Value write(const std::any& value) const = 0;
191};
192
193struct LA_SCENE_API Extensions
194{
198 std::unordered_map<std::string, Value> data;
199
204 std::unordered_map<std::string, std::any> user_data;
205
206 size_t size() const { return data.size() + user_data.size(); }
207 bool empty() const { return data.empty() && user_data.empty(); }
208};
209
210} // namespace scene
211} // namespace lagrange
Definition SceneExtension.h:34
static constexpr std::size_t variant_index()
Returns index of the element type in the variant.
Definition SceneExtension.h:55
static constexpr bool is_variant_type()
Checks if the type is in the variant.
Definition SceneExtension.h:46
@ Value
Values that are not attached to a specific element.
Definition AttributeFwd.h:42
#define la_debug_assert(...)
Debug assertion check.
Definition assert.h:194
Main namespace for Lagrange.
Definition SceneExtension.h:194
std::unordered_map< std::string, std::any > user_data
A map of extensions as user-defined objects, stored in an std::any.
Definition SceneExtension.h:204
std::unordered_map< std::string, Value > data
A map of extensions as json-like Value objects.
Definition SceneExtension.h:198
Definition SceneExtension.h:184