Lagrange
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/scene/api.h>
15#include <lagrange/utils/assert.h>
16#include <lagrange/utils/invalid.h>
17#include <lagrange/utils/span.h>
18#include <lagrange/utils/value_ptr.h>
19
20#include <any>
21#include <cstring>
22#include <map>
23#include <string>
24#include <unordered_map>
25#include <variant>
26#include <vector>
27
28namespace lagrange {
29namespace scene {
30
31// Json-like value used in scene extensions
32class LA_SCENE_API Value
33{
34public:
35 typedef std::vector<Value> Array;
36 typedef std::map<std::string, Value> Object;
37 typedef std::vector<unsigned char> Buffer;
38 using variant_type = std::variant<bool, int, double, std::string, Buffer, Array, Object>;
39
43 template <typename T>
44 static constexpr bool is_variant_type()
45 {
46 return variant_index<T>() < (std::variant_size_v<variant_type>);
47 }
48
52 template <typename T, std::size_t index = 0>
53 static constexpr std::size_t variant_index()
54 {
55 if constexpr (index == std::variant_size_v<variant_type>) {
56 return index;
57 } else if constexpr (std::is_same_v<std::variant_alternative_t<index, variant_type>, T>) {
58 return index;
59 } else {
60 return variant_index<T, index + 1>();
61 }
62 }
63
64 static constexpr size_t bool_index() { return variant_index<bool>(); }
65 static constexpr size_t int_index() { return variant_index<int>(); }
66 static constexpr size_t real_index() { return variant_index<double>(); }
67 static constexpr size_t string_index() { return variant_index<std::string>(); }
68 static constexpr size_t buffer_index() { return variant_index<Buffer>(); }
69 static constexpr size_t array_index() { return variant_index<Array>(); }
70 static constexpr size_t object_index() { return variant_index<Object>(); }
71
72 static Value create_buffer() { return Value(Buffer()); }
73 static Value create_array() { return Value(Array()); }
74 static Value create_object() { return Value(Object()); }
75
76 Value() = default;
77 explicit Value(bool b) { value = b; }
78 explicit Value(int i) { value = i; }
79 explicit Value(double n) { value = n; }
80 explicit Value(std::string s) { value = std::move(s); }
81 explicit Value(std::string_view s) { value = std::string(s); }
82 explicit Value(const char* s) { value = std::string(s); }
83 explicit Value(span<unsigned char> s)
84 {
85 Buffer vec(s.size());
86 std::memcpy(vec.data(), s.data(), s.size());
87 value = std::move(vec);
88 }
89 explicit Value(const Buffer& v) { value = v; }
90 explicit Value(Buffer&& v) { value = std::move(v); }
91 explicit Value(const Array& a) { value = a; }
92 explicit Value(Array&& a) { value = std::move(a); }
93 explicit Value(const Object& o) { value = o; }
94 explicit Value(Object&& o) { value = std::move(o); }
95
96 template <typename T>
97 bool is_type() const
98 {
99 return std::holds_alternative<T>(value);
100 }
101 bool is_bool() const { return is_type<bool>(); }
102 bool is_int() const { return is_type<int>(); }
103 bool is_real() const { return is_type<double>(); }
104 bool is_number() const { return is_int() || is_real(); }
105 bool is_string() const { return is_type<std::string>(); }
106 bool is_buffer() const { return is_type<Buffer>(); }
107 bool is_array() const { return is_type<Array>(); }
108 bool is_object() const { return is_type<Object>(); }
109 size_t get_type_index() const { return value.index(); }
110
111 template <typename T>
112 const T& get() const
113 {
114 return std::get<T>(value);
115 }
116 template <typename T>
117 T& get()
118 {
119 return std::get<T>(value);
120 }
121 bool get_bool() const { return get<bool>(); }
122 int get_int() const { return get<int>(); }
123 double get_real() const { return get<double>(); }
124 const std::string& get_string() const { return get<std::string>(); }
125 std::string get_string() { return get<std::string>(); }
126 const Buffer& get_buffer() const { return get<Buffer>(); }
127 Buffer& get_buffer() { return get<Buffer>(); }
128 const Array& get_array() const { return get<Array>(); }
129 Array& get_array() { return get<Array>(); }
130 const Object& get_object() const { return get<Object>(); }
131 Object& get_object() { return get<Object>(); }
132
133 template <typename T>
134 void set(T t)
135 {
136 value = t;
137 }
138 void set_bool(bool b) { value = b; }
139 void set_int(int i) { value = i; }
140 void set_real(double n) { value = n; }
141
142 // Only valid for array values:
143 const Value& operator[](size_t idx) const
144 {
145 la_debug_assert(is_array());
146 return get_array()[idx];
147 }
148 Value& operator[](size_t idx)
149 {
150 la_debug_assert(is_array());
151 return get_array()[idx];
152 }
153
154 // Only valid for object values:
155 bool has(const std::string& key) const { return get_object().find(key) != get_object().end(); }
156 const Value& operator[](const std::string& key) const
157 {
158 la_debug_assert(is_object());
159 return get_object().find(key)->second;
160 }
161 Value& operator[](const std::string& key)
162 {
163 la_debug_assert(is_object());
164 return get_object().find(key)->second;
165 }
166
167 // Only valid for some value types (string, array, object, buffer).
168 size_t size() const
169 {
170 if (is_string()) return get_string().size();
171 if (is_buffer()) return get_buffer().size();
172 if (is_array()) return get_array().size();
173 if (is_object()) return get_object().size();
174 return 0;
175 }
176
177protected:
178 variant_type value;
179};
180
181struct LA_SCENE_API UserDataConverter
182{
183 virtual bool is_supported(const std::string& key) const = 0;
184 virtual bool can_read(const std::string& key) const { return is_supported(key); }
185 virtual bool can_write(const std::string& key) const { return is_supported(key); }
186
187 virtual std::any read(const Value& value) const = 0;
188 virtual Value write(const std::any& value) const = 0;
189};
190
191struct LA_SCENE_API Extensions
192{
196 std::unordered_map<std::string, Value> data;
197
202 std::unordered_map<std::string, std::any> user_data;
203
204 size_t size() const { return data.size() + user_data.size(); }
205 bool empty() const { return data.empty() && user_data.empty(); }
206};
207
208} // namespace scene
209} // namespace lagrange
Definition: SceneExtension.h:33
static constexpr std::size_t variant_index()
Returns index of the element type in the variant.
Definition: SceneExtension.h:53
static constexpr bool is_variant_type()
Checks if the type is in the variant.
Definition: SceneExtension.h:44
@ Value
Values that are not attached to a specific element.
Definition: AttributeFwd.h:42
#define la_debug_assert(...)
Debug assertion check.
Definition: assert.h:189
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: SceneExtension.h:192
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:202
std::unordered_map< std::string, Value > data
A map of extensions as json-like Value objects.
Definition: SceneExtension.h:196
Definition: SceneExtension.h:182