From 33281871892d0ae05147ff4f766639d99dcddaae Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 09:10:45 +0100 Subject: [PATCH 01/12] updated --- libs/yocto/yocto_common.h | 161 ++++++++++++-------------------------- 1 file changed, 49 insertions(+), 112 deletions(-) diff --git a/libs/yocto/yocto_common.h b/libs/yocto/yocto_common.h index 290ac80d0..6e908f4fe 100644 --- a/libs/yocto/yocto_common.h +++ b/libs/yocto/yocto_common.h @@ -37,31 +37,15 @@ // INCLUDES // ----------------------------------------------------------------------------- -#include -#include -#include +#include #include -#include // ----------------------------------------------------------------------------- // USING DIRECTIVES // ----------------------------------------------------------------------------- namespace yocto { -// using directives -using std::pair; -using std::string; -using std::vector; - -} // namespace yocto - -// ----------------------------------------------------------------------------- -// TIMING UTILITIES -// ----------------------------------------------------------------------------- -namespace yocto { - -// get time in nanoseconds - useful only to compute difference of times -inline int64_t get_time(); +// No using directives yet } // namespace yocto @@ -70,29 +54,21 @@ inline int64_t get_time(); // ----------------------------------------------------------------------------- namespace yocto { -// Python `range()` equivalent. Construct an object that c over an +// Python `range()` equivalent. Construct an object that iterates over an // integer sequence. template -inline auto range(T min, T max); +constexpr auto range(T max); template -inline auto range(T max); +constexpr auto range(T min, T max); +template +constexpr auto range(T min, T max, T step); // Python `enumerate()` equivalent. Construct an object that iterates over a // sequence of elements and numbers them. -template -inline auto enumerate(const vector& vals); -template -inline auto enumerate(vector& vals); - -// Vector append and concatenation -template -inline vector& append(vector& a, const vector& b); -template -inline vector& append(vector& a, const T& b); -template -inline vector join(const vector& a, const vector& b); -template -inline vector join(const vector& a, const T& b); +template ())), + typename = decltype(std::end(std::declval()))> +constexpr auto enumerate(T&& iterable); } // namespace yocto @@ -104,100 +80,61 @@ inline vector join(const vector& a, const T& b); // // ----------------------------------------------------------------------------- -// ----------------------------------------------------------------------------- -// TIMING UTILITIES -// ----------------------------------------------------------------------------- -namespace yocto { - -// get time in nanoseconds - useful only to compute difference of times -inline int64_t get_time() { - return std::chrono::high_resolution_clock::now().time_since_epoch().count(); -} - -} // namespace yocto - // ----------------------------------------------------------------------------- // PYTHON-LIKE ITERATORS // ----------------------------------------------------------------------------- namespace yocto { -// Range object to support Python-like iteration. Use with `range()`. -template -struct range_helper { - struct iterator { - T pos = 0; - iterator& operator++() { - pos++; - return *this; - } - bool operator!=(const iterator& other) const { return pos != other.pos; } - T operator*() const { return pos; } - }; - T begin_ = 0, end_ = 0; - iterator begin() const { return {begin_}; } - iterator end() const { return {end_}; } -}; - // Python `range()` equivalent. Construct an object to iterate over a sequence. template -inline auto range(T min, T max) { - return range_helper{min, max}; +constexpr auto range(T max) { + return range((T)0, max, (T)1); } template -inline auto range(T max) { - return range((T)0, max); +constexpr auto range(T min, T max) { + return range(min, max, (T)1); } - -// Enumerate object to support Python-like enumeration. Use with `enumerate()`. template -struct enumerate_helper { +constexpr auto range(T min, T max, T step) { struct iterator { - T* data = nullptr; - int64_t pos = 0; - iterator& operator++() { - pos++; - return *this; + T index; + void operator++() { ++index; } + bool operator!=(const iterator& other) const { + return index != other.index; } - bool operator!=(const iterator& other) const { return pos != other.pos; } - pair operator*() const { return {pos, *(data + pos)}; } + T operator*() const { return index; } + }; + struct range_helper { + T begin_ = 0, end_ = 0; + iterator begin() const { return {begin_}; } + iterator end() const { return {end_}; } }; - T* data = nullptr; - int64_t size = 0; - iterator begin() const { return {data, 0}; } - iterator end() const { return {data, size}; } -}; + return range_helper{min, max}; +} // Python `enumerate()` equivalent. Construct an object that iteraterates over a // sequence of elements and numbers them. -template -inline auto enumerate(const vector& vals) { - return enumerate_helper{vals.data(), (int64_t)vals.size()}; -} -template -inline auto enumerate(vector& vals) { - return enumerate_helper{vals.data(), (int64_t)vals.size()}; -} - -// Vector append and concatenation -template -inline vector& append(vector& a, const vector& b) { - a.insert(a.end(), b.begin(), b.end()); - return a; -} -template -inline vector& append(vector& a, const T& b) { - a.push_back(b); - return a; -} -template -inline vector join(const vector& a, const vector& b) { - auto c = a; - return append(b); -} -template -inline vector join(const vector& a, const T& b) { - auto c = a; - return append(b); +// Implementation from http://reedbeta.com/blog/python-like-enumerate-in-cpp17/ +template ())), + typename = decltype(std::end(std::declval()))> +constexpr auto enumerate(T&& iterable) { + struct iterator { + std::size_t index; + Iterator iter; + bool operator!=(const iterator& other) const { return iter != other.iter; } + void operator++() { + ++index; + ++iter; + } + auto operator*() const { return std::tie(index, *iter); } + }; + struct iterable_wrapper { + T iterable; + auto begin() { return iterator{0, std::begin(iterable)}; } + auto end() { return iterator{0, std::end(iterable)}; } + }; + return iterable_wrapper{std::forward(iterable)}; } } // namespace yocto From a3aa4de4b8dd7150147a037578b85444bb69c2bb Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 09:22:05 +0100 Subject: [PATCH 02/12] updated --- libs/yocto/yocto_common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/yocto/yocto_common.h b/libs/yocto/yocto_common.h index 6e908f4fe..ecadf8dc5 100644 --- a/libs/yocto/yocto_common.h +++ b/libs/yocto/yocto_common.h @@ -119,6 +119,7 @@ template ())), typename = decltype(std::end(std::declval()))> constexpr auto enumerate(T&& iterable) { + // maybe we should avoid tuples here struct iterator { std::size_t index; Iterator iter; From 5f783a760b5748b71f8cb6d8c0c00f2b136788c0 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 15:08:07 +0100 Subject: [PATCH 03/12] updated --- libs/yocto/yocto_json.cpp | 22 +- libs/yocto/yocto_json.h | 416 ++++++++++++++++++++++----------- libs/yocto/yocto_trace.cpp | 115 +++++++++ libs/yocto/yocto_trace.h | 20 ++ libs/yocto_gui/yocto_imgui.cpp | 4 +- 5 files changed, 434 insertions(+), 143 deletions(-) diff --git a/libs/yocto/yocto_json.cpp b/libs/yocto/yocto_json.cpp index 80236af51..62ef64c55 100644 --- a/libs/yocto/yocto_json.cpp +++ b/libs/yocto/yocto_json.cpp @@ -96,11 +96,11 @@ void to_json(json_value& json, const njson& njs) { void from_json(const json_value& json, njson& njs) { switch (json.type()) { case json_type::null: njs = {}; break; - case json_type::integer: njs = json.get_ref(); break; - case json_type::unsigned_: njs = json.get_ref(); break; - case json_type::real: njs = json.get_ref(); break; + case json_type::ninteger: njs = json.get_ref(); break; + case json_type::nunsigned: njs = json.get_ref(); break; + case json_type::nfloat: njs = json.get_ref(); break; case json_type::boolean: njs = json.get_ref(); break; - case json_type::string_: njs = json.get_ref(); break; + case json_type::string: njs = json.get_ref(); break; case json_type::array: njs = njson::array(); for (auto& ejs : json) from_json(ejs, njs.emplace_back()); @@ -287,7 +287,7 @@ static bool validate_json(const json_value& value, const string& path, if (schema.contains("type") && schema.at("type").is_string()) { auto& type = schema.at("type").get_ref(); auto type_ok = (type == "null" && value.is_null()) || - (type == "integer" && value.is_integral()) || + (type == "integer" && value.is_integer()) || (type == "number" && value.is_number()) || (type == "boolean" && value.is_boolean()) || (type == "string" && value.is_string()) || @@ -303,7 +303,7 @@ static bool validate_json(const json_value& value, const string& path, if (type_ok) break; auto& type = tschema.get_ref(); type_ok = (type == "null" && value.is_null()) || - (type == "integer" && value.is_integral()) || + (type == "integer" && value.is_integer()) || (type == "number" && value.is_number()) || (type == "boolean" && value.is_boolean()) || (type == "string" && value.is_string()) || @@ -349,7 +349,7 @@ static bool validate_json(const json_value& value, const string& path, if (item.is_string() && value.is_string() && item.get_ref() == value.get_ref()) found = true; - if (item.is_integral() && value.is_integral() && + if (item.is_integer() && value.is_integer() && item.get() == value.get()) found = true; if (item.is_number() && value.is_number() && @@ -859,11 +859,11 @@ namespace yocto { void to_json(njson& njs, json_cview json) { switch (get_type(json)) { case json_type::null: njs = nullptr; break; - case json_type::integer: njs = get_integer(json); break; - case json_type::unsigned_: njs = get_unsigned(json); break; - case json_type::real: njs = get_real(json); break; + case json_type::ninteger: njs = get_number_integer(json); break; + case json_type::nunsigned: njs = get_number_unsigned(json); break; + case json_type::nfloat: njs = get_number_real(json); break; case json_type::boolean: njs = get_boolean(json); break; - case json_type::string_: njs = get_string(json); break; + case json_type::string: njs = get_string(json); break; case json_type::array: njs = njson::array(); for (auto ejs : iterate_array(json)) to_json(njs.emplace_back(), ejs); diff --git a/libs/yocto/yocto_json.h b/libs/yocto/yocto_json.h index b60986ad9..8ce7db240 100644 --- a/libs/yocto/yocto_json.h +++ b/libs/yocto/yocto_json.h @@ -78,7 +78,7 @@ namespace yocto { // Json type enum struct json_type { // clang-format off - null, integer, unsigned_, real, boolean, string_, array, object, binary + null, ninteger, nunsigned, nfloat, boolean, string, array, object, binary // clang-format on }; @@ -130,15 +130,15 @@ struct json_value { json_type type() const; bool is_null() const; bool is_integer() const; - bool is_unsigned() const; - bool is_real() const; - bool is_integral() const; bool is_number() const; bool is_boolean() const; bool is_string() const; bool is_array() const; bool is_object() const; bool is_binary() const; + bool is_number_integer() const; + bool is_number_unsigned() const; + bool is_number_float() const; // conversions (see get) explicit operator int32_t() const; @@ -286,6 +286,8 @@ template inline void from_json(const json_value& json, vector& value); template inline void from_json(const json_value& json, array& value); +template >> +inline void from_json(const json_value& json, T& value); // Conversion to json from values inline void to_json(json_value& json, int64_t value); @@ -300,6 +302,8 @@ template inline void to_json(json_value& json, const vector& value); template inline void to_json(json_value& json, const array& value); +template >> +inline void to_json(json_value& json, T value); } // namespace yocto @@ -308,6 +312,32 @@ inline void to_json(json_value& json, const array& value); // ----------------------------------------------------------------------------- namespace yocto { +// Convenience function +template +inline json_value to_schema(const T& value, const string& descr); + +// Conversion to json schema from values +inline void to_schema(json_value& schema, int64_t value, const string& descr); +inline void to_schema(json_value& schema, int32_t value, const string& descr); +inline void to_schema(json_value& schema, uint64_t value, const string& descr); +inline void to_schema(json_value& schema, uint32_t value, const string& descr); +inline void to_schema(json_value& schema, double value, const string& descr); +inline void to_schema(json_value& schema, float value, const string& descr); +inline void to_schema(json_value& schema, bool value, const string& descr); +inline void to_schema(json_value& schema, const string& value, const string& descr); +template +inline void to_schema(json_value& schema, const vector& value, const string& descr); +template +inline void to_schema(json_value& schema, const array& value, const string& descr); +template >> +inline void to_schema(json_value& schema, T value, const string& descr); + +// Schema for objects +inline json_value to_schema_object(const string& descr); +inline void to_schema_object(json_value& schema, const string& descr); +inline json_value& get_schema_properties(json_value& schema); +inline const json_value& get_schema_properties(const json_value& schema); + // Validate a value against a schema bool validate_json( const json_value& value, const json_value& schema, string& error); @@ -424,15 +454,15 @@ inline json_type get_type(json_cview json); // Type inline bool is_null(json_cview json); inline bool is_integer(json_cview json); -inline bool is_unsigned(json_cview json); -inline bool is_real(json_cview json); -inline bool is_integral(json_cview json); inline bool is_number(json_cview json); inline bool is_boolean(json_cview json); inline bool is_string(json_cview json); inline bool is_array(json_cview json); inline bool is_object(json_cview json); inline bool is_binary(json_cview json); +inline bool is_number_integer(json_cview json); +inline bool is_number_unsigned(json_cview json); +inline bool is_number_float(json_cview json); // Initialization to basic types inline bool set_null(json_view json); @@ -449,27 +479,27 @@ inline bool set_number(json_view json, double value); inline bool set_number(json_view json, float value); // Get basic values -inline bool get_integer(json_cview json, int64_t& value); -inline bool get_unsigned(json_cview json, uint64_t& value); -inline bool get_real(json_cview json, double& value); inline bool get_boolean(json_cview json, bool& value); inline bool get_string(json_cview json, string& value); -inline bool get_integral(json_cview json, int64_t& value); -inline bool get_integral(json_cview json, uint64_t& value); +inline bool get_integer(json_cview json, int64_t& value); +inline bool get_integer(json_cview json, uint64_t& value); inline bool get_number(json_cview json, double& value); -inline bool get_integral(json_cview json, int32_t& value); -inline bool get_integral(json_cview json, uint32_t& value); +inline bool get_integer(json_cview json, int32_t& value); +inline bool get_integer(json_cview json, uint32_t& value); inline bool get_number(json_cview json, float& value); +inline bool get_number_integer(json_cview json, int64_t& value); +inline bool get_number_unsigned(json_cview json, uint64_t& value); +inline bool get_number_float(json_cview json, double& value); // Get basic values - ignore errors if present -inline int64_t get_integer(json_cview json); -inline uint64_t get_unsigned(json_cview json); -inline double get_real(json_cview json); inline bool get_boolean(json_cview json); inline string get_string(json_cview json); -inline int64_t get_integral(json_cview json); -inline uint64_t get_uintegral(json_cview json); +inline int64_t get_integer(json_cview json); +inline uint64_t get_integeru(json_cview json); inline double get_number(json_cview json); +inline int64_t get_number_integer(json_cview json); +inline uint64_t get_number_unsigned(json_cview json); +inline double get_number_real(json_cview json); // Compound type inline bool is_empty(json_cview json); @@ -602,24 +632,24 @@ inline json_value::json_value(const json_value& other) _type = json_type::null; _integer = other._integer; break; - case json_type::integer: - _type = json_type::integer; + case json_type::ninteger: + _type = json_type::ninteger; _integer = other._integer; break; - case json_type::unsigned_: - _type = json_type::unsigned_; + case json_type::nunsigned: + _type = json_type::nunsigned; _unsigned = other._unsigned; break; - case json_type::real: - _type = json_type::real; + case json_type::nfloat: + _type = json_type::nfloat; _real = other._real; break; case json_type::boolean: _type = json_type::boolean; _boolean = other._boolean; break; - case json_type::string_: - _type = json_type::string_; + case json_type::string: + _type = json_type::string; _string = new string{*other._string}; break; case json_type::array: @@ -643,25 +673,25 @@ inline json_value::json_value(json_value&& other) inline json_value::json_value(std::nullptr_t) : _type{json_type::null}, _unsigned{0} {} inline json_value::json_value(int64_t value) - : _type{json_type::integer}, _integer{value} {} + : _type{json_type::ninteger}, _integer{value} {} inline json_value::json_value(int32_t value) - : _type{json_type::integer}, _integer{value} {} + : _type{json_type::ninteger}, _integer{value} {} inline json_value::json_value(uint64_t value) - : _type{json_type::unsigned_}, _unsigned{value} {} + : _type{json_type::nunsigned}, _unsigned{value} {} inline json_value::json_value(uint32_t value) - : _type{json_type::unsigned_}, _unsigned{value} {} + : _type{json_type::nunsigned}, _unsigned{value} {} inline json_value::json_value(double value) - : _type{json_type::real}, _real{value} {} + : _type{json_type::nfloat}, _real{value} {} inline json_value::json_value(float value) - : _type{json_type::real}, _real{value} {} + : _type{json_type::nfloat}, _real{value} {} inline json_value::json_value(bool value) : _type{json_type::boolean}, _boolean{value} {} inline json_value::json_value(const string& value) - : _type{json_type::string_}, _string{new string{value}} {} + : _type{json_type::string}, _string{new string{value}} {} inline json_value::json_value(string_view value) - : _type{json_type::string_}, _string{new string{value}} {} + : _type{json_type::string}, _string{new string{value}} {} inline json_value::json_value(const char* value) - : _type{json_type::string_}, _string{new string{value}} {} + : _type{json_type::string}, _string{new string{value}} {} inline json_value::json_value(const json_array& value) : _type{json_type::array}, _array{new json_array{value}} {} inline json_value::json_value(const json_object& value) @@ -674,7 +704,7 @@ inline json_value::json_value(const T& value) { } #ifdef __APPLE__ inline json_value::json_value(size_t value) - : _type{json_type::unsigned_}, _unsigned{(uint64_t)value} {} + : _type{json_type::nunsigned}, _unsigned{(uint64_t)value} {} #endif // assignments @@ -697,25 +727,25 @@ inline json_value& json_value::operator=(const T& value) { // type inline json_type json_value::type() const { return _type; } inline bool json_value::is_null() const { return _type == json_type::null; } -inline bool json_value::is_integer() const { - return _type == json_type::integer; +inline bool json_value::is_number_integer() const { + return _type == json_type::ninteger; } -inline bool json_value::is_unsigned() const { - return _type == json_type::unsigned_; +inline bool json_value::is_number_unsigned() const { + return _type == json_type::nunsigned; } -inline bool json_value::is_real() const { return _type == json_type::real; } -inline bool json_value::is_integral() const { - return _type == json_type::integer || _type == json_type::unsigned_; +inline bool json_value::is_number_float() const { return _type == json_type::nfloat; } +inline bool json_value::is_integer() const { + return _type == json_type::ninteger || _type == json_type::nunsigned; } inline bool json_value::is_number() const { - return _type == json_type::real || _type == json_type::integer || - _type == json_type::unsigned_; + return _type == json_type::nfloat || _type == json_type::ninteger || + _type == json_type::nunsigned; } inline bool json_value::is_boolean() const { return _type == json_type::boolean; } inline bool json_value::is_string() const { - return _type == json_type::string_; + return _type == json_type::string; } inline bool json_value::is_array() const { return _type == json_type::array; } inline bool json_value::is_object() const { return _type == json_type::object; } @@ -723,52 +753,52 @@ inline bool json_value::is_binary() const { return _type == json_type::binary; } // conversions inline json_value::operator int64_t() const { - if (_type != json_type::integer && _type != json_type::unsigned_) + if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::integer ? (int64_t)_integer : (int64_t)_unsigned; + return _type == json_type::ninteger ? (int64_t)_integer : (int64_t)_unsigned; } inline json_value::operator int32_t() const { - if (_type != json_type::integer && _type != json_type::unsigned_) + if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::integer ? (int32_t)_integer : (int32_t)_unsigned; + return _type == json_type::ninteger ? (int32_t)_integer : (int32_t)_unsigned; } inline json_value::operator uint64_t() const { - if (_type != json_type::integer && _type != json_type::unsigned_) + if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::integer ? (uint64_t)_integer : (uint64_t)_unsigned; + return _type == json_type::ninteger ? (uint64_t)_integer : (uint64_t)_unsigned; } inline json_value::operator uint32_t() const { - if (_type != json_type::integer && _type != json_type::unsigned_) + if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::integer ? (uint32_t)_integer : (uint32_t)_unsigned; + return _type == json_type::ninteger ? (uint32_t)_integer : (uint32_t)_unsigned; } inline json_value::operator double() const { - if (_type != json_type::real && _type != json_type::integer && - _type != json_type::unsigned_) + if (_type != json_type::nfloat && _type != json_type::ninteger && + _type != json_type::nunsigned) throw json_error{"number expected"}; - return _type == json_type::real + return _type == json_type::nfloat ? (double)_real - : _type == json_type::integer ? (double)_integer + : _type == json_type::ninteger ? (double)_integer : (double)_unsigned; } inline json_value::operator float() const { - if (_type != json_type::real && _type != json_type::integer && - _type != json_type::unsigned_) + if (_type != json_type::nfloat && _type != json_type::ninteger && + _type != json_type::nunsigned) throw json_error{"number expected"}; - return _type == json_type::real + return _type == json_type::nfloat ? (float)_real - : _type == json_type::integer ? (float)_integer : (float)_unsigned; + : _type == json_type::ninteger ? (float)_integer : (float)_unsigned; } inline json_value::operator bool() const { if (_type != json_type::boolean) throw json_error{"boolean expected"}; return _boolean; } inline json_value::operator string() const { - if (_type != json_type::string_) throw json_error{"string expected"}; + if (_type != json_type::string) throw json_error{"string expected"}; return *_string; } inline json_value::operator string_view() const { - if (_type != json_type::string_) throw json_error{"string expected"}; + if (_type != json_type::string) throw json_error{"string expected"}; return *_string; } template @@ -803,19 +833,19 @@ inline T& json_value::get_ref() { std::is_same_v || std::is_same_v, "type not in the json variant"); if constexpr (std::is_same_v) { - if (_type != json_type::integer) throw json_error{"integer expected"}; + if (_type != json_type::ninteger) throw json_error{"integer expected"}; return _integer; } else if constexpr (std::is_same_v) { - if (_type != json_type::unsigned_) throw json_error{"unsigned expected"}; + if (_type != json_type::nunsigned) throw json_error{"unsigned expected"}; return _unsigned; } else if constexpr (std::is_same_v) { - if (_type != json_type::real) throw json_error{"real expected"}; + if (_type != json_type::nfloat) throw json_error{"real expected"}; return _real; } else if constexpr (std::is_same_v) { if (_type != json_type::boolean) throw json_error{"boolean expected"}; return _boolean; } else if constexpr (std::is_same_v) { - if (_type != json_type::string_) throw json_error{"string expected"}; + if (_type != json_type::string) throw json_error{"string expected"}; return *_string; } else if constexpr (std::is_same_v) { if (_type != json_type::array) throw json_error{"array expected"}; @@ -856,11 +886,11 @@ inline size_t json_value::size() const { inline void json_value::clear() { switch (_type) { case json_type::null: _unsigned = 0; break; - case json_type::integer: _integer = 0; break; - case json_type::unsigned_: _unsigned = 0; break; - case json_type::real: _real = 0; break; + case json_type::ninteger: _integer = 0; break; + case json_type::nunsigned: _unsigned = 0; break; + case json_type::nfloat: _real = 0; break; case json_type::boolean: _boolean = false; break; - case json_type::string_: _string->clear(); break; + case json_type::string: _string->clear(); break; case json_type::array: _array->clear(); break; case json_type::object: _object->clear(); break; case json_type::binary: _binary->clear(); break; @@ -1042,7 +1072,7 @@ inline void json_value::swap(json_value& other) { // destructor inline json_value::~json_value() { switch (_type) { - case json_type::string_: delete _string; break; + case json_type::string: delete _string; break; case json_type::array: delete _array; break; case json_type::object: delete _object; break; case json_type::binary: delete _binary; break; @@ -1130,6 +1160,18 @@ inline void from_json(const json_value& json, array& value) { for (auto idx = (size_t)0; idx < value.size(); idx++) from_json(json.at(idx), value.at(idx)); } +template +inline void from_json(const json_value& json, T& value) { + auto label = json.get(); + auto& labels = json_enum_labels(value); + for (auto& [value_, label_] : labels) { + if (label_ == label) { + value = value_; + return; + } + } + throw json_error{"unknown enum label " + label}; +} // Conversion to json from values inline void to_json(json_value& json, int64_t value) { json = value; } @@ -1152,6 +1194,120 @@ inline void to_json(json_value& json, const array& value) { for (auto idx = (size_t)0; idx < value.size(); idx++) to_json(json.at(idx), value.at(idx)); } +template +inline void to_json(json_value& json, T value) { + auto& labels = json_enum_labels(value); + for (auto& [value_, label] : labels) { + if (value_ == value) { + json = label; + return; + } + } + throw json_error{"unknown enum label"}; +} + +} // namespace yocto + +// ----------------------------------------------------------------------------- +// JSON SCHEMA +// ----------------------------------------------------------------------------- +namespace yocto { + +// Convenience function +template +inline json_value to_schema(const T& value, const string& descr) { + auto schema = json_value{}; + to_schema(schema, value, descr); + return schema; +} + +// Conversion to json schema from values +inline void to_schema(json_value& schema, int64_t value, const string& descr) { + schema["type"] = "integer"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, int32_t value, const string& descr) { + schema["type"] = "integer"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, uint64_t value, const string& descr) { + schema["type"] = "integer"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, uint32_t value, const string& descr) { + schema["type"] = "integer"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, double value, const string& descr) { + schema["type"] = "number"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, float value, const string& descr) { + schema["type"] = "number"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, bool value, const string& descr) { + schema["type"] = "number"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema(json_value& schema, const string& value, const string& descr) { + schema["type"] = "string"; + schema["description"] = descr; + schema["default"] = value; +} +template +inline void to_schema(json_value& schema, const vector& value, const string& descr) { + schema["type"] = "array"; + schema["description"] = descr; + schema["default"] = value; + if(value.empty()) schema["items"] = to_schema(T{}, descr); +} +template +inline void to_schema(json_value& schema, const array& value, const string& descr) { + schema["type"] = "array"; + schema["description"] = descr; + schema["default"] = value; + schema["minSize"] = N; + schema["maxSize"] = N; + for(auto& item : value) schema["items"].push_back(to_schema(item, descr)); +} +template +inline void to_schema(json_value& schema, T value, const string& descr) { + schema["type"] = "string"; + schema["description"] = descr; + auto& labels = json_enum_labels(value); + for(auto& [value_, label] : labels) { + if(value == value_) schema["default"] = label; + schema["enum"].push_back(label); + } +} + +// Schema for objects +inline json_value to_schema_object(const string& descr) { + auto schema = json_value{}; + to_schema_object(schema, descr); + return schema; +} +inline void to_schema_object(json_value& schema, const string& descr) { + schema["type"] = "object"; + schema["description"] = descr; + schema["properties"] = json_value::object(); +} +inline json_value& get_schema_properties(json_value& schema) { + if (schema.is_null()) to_schema_object(schema, ""); + if (schema.contains("properties")) schema["properties"] = json_value::object(); + return schema.at("properties"); +} +inline const json_value& get_schema_properties(const json_value& schema) { + return schema.at("properties"); +} } // namespace yocto @@ -1214,7 +1370,7 @@ inline string_view _get_key(json_cview json) { if (!is_valid(json)) throw std::invalid_argument{"bad tree"}; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::string_) throw std::invalid_argument{"bad key"}; + if (jst != json_type::string) throw std::invalid_argument{"bad key"}; return {json.root->keys.data() + jsv._string.start, jsv._string.length}; } inline void _find_path(json_view json, vector& path); @@ -1247,31 +1403,31 @@ inline bool is_null(json_cview json) { auto& jst = _get_type(json); return jst == json_type::null; } -inline bool is_integer(json_cview json) { +inline bool is_number_integer(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::integer; + return jst == json_type::ninteger; } -inline bool is_unsigned(json_cview json) { +inline bool is_number_unsigned(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::unsigned_; + return jst == json_type::nunsigned; } -inline bool is_real(json_cview json) { +inline bool is_number_float(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::real; + return jst == json_type::nfloat; } -inline bool is_integral(json_cview json) { +inline bool is_integer(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::integer || jst == json_type::unsigned_; + return jst == json_type::ninteger || jst == json_type::nunsigned; } inline bool is_number(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::integer || jst == json_type::unsigned_ || - jst == json_type::real; + return jst == json_type::ninteger || jst == json_type::nunsigned || + jst == json_type::nfloat; } inline bool is_boolean(json_cview json) { if (!is_valid(json)) return false; @@ -1281,7 +1437,7 @@ inline bool is_boolean(json_cview json) { inline bool is_string(json_cview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); - return jst == json_type::string_; + return jst == json_type::string; } inline bool is_array(json_cview json) { if (!is_valid(json)) return false; @@ -1310,7 +1466,7 @@ inline bool set_integer(json_view json, int64_t value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - jst = json_type::integer; + jst = json_type::ninteger; jsv._integer = value; return true; } @@ -1318,7 +1474,7 @@ inline bool set_unsigned(json_view json, uint64_t value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - jst = json_type::unsigned_; + jst = json_type::nunsigned; jsv._unsigned = value; return true; } @@ -1326,7 +1482,7 @@ inline bool set_real(json_view json, double value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - jst = json_type::real; + jst = json_type::nfloat; jsv._real = value; return true; } @@ -1342,7 +1498,7 @@ inline bool set_string(json_view json, const string& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - jst = json_type::string_; + jst = json_type::string; jsv._string.start = (uint32_t)json.root->strings.size(); jsv._string.length = (uint32_t)value.size(); json.root->strings.insert( @@ -1370,27 +1526,27 @@ inline bool set_number(json_view json, float value) { } // Get basic values -inline bool get_integer(json_cview json, int64_t& value) { +inline bool get_number_integer(json_cview json, int64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::integer) return set_error(json, "integer expected"); + if (jst != json_type::ninteger) return set_error(json, "integer expected"); value = jsv._integer; return true; } -inline bool get_unsigned(json_cview json, uint64_t& value) { +inline bool get_number_unsigned(json_cview json, uint64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::unsigned_) return set_error(json, "unsigned expected"); + if (jst != json_type::nunsigned) return set_error(json, "unsigned expected"); value = jsv._unsigned; return true; } -inline bool get_real(json_cview json, double& value) { +inline bool get_number_float(json_cview json, double& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::real) return set_error(json, "real expected"); + if (jst != json_type::nfloat) return set_error(json, "real expected"); value = jsv._real; return true; } @@ -1406,28 +1562,28 @@ inline bool get_string(json_cview json, string& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::string_) return set_error(json, "string expected"); + if (jst != json_type::string) return set_error(json, "string expected"); value = string{json.root->strings.data() + jsv._string.start, json.root->strings.data() + jsv._string.start + jsv._string.length}; return true; } -inline bool get_integral(json_cview json, int64_t& value) { +inline bool get_integer(json_cview json, int64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::integer && jst != json_type::unsigned_) + if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); - value = (jst == json_type::integer) ? (int64_t)jsv._integer + value = (jst == json_type::ninteger) ? (int64_t)jsv._integer : (int64_t)jsv._unsigned; return true; } -inline bool get_integral(json_cview json, uint64_t& value) { +inline bool get_integer(json_cview json, uint64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::integer && jst != json_type::unsigned_) + if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); - value = (jst == json_type::integer) ? (uint64_t)jsv._integer + value = (jst == json_type::ninteger) ? (uint64_t)jsv._integer : (uint64_t)jsv._unsigned; return true; } @@ -1435,32 +1591,32 @@ inline bool get_number(json_cview json, double& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::real && jst != json_type::integer && - jst != json_type::unsigned_) + if (jst != json_type::nfloat && jst != json_type::ninteger && + jst != json_type::nunsigned) return set_error(json, "number expected"); - value = (jst == json_type::real) + value = (jst == json_type::nfloat) ? (double)jsv._real - : (jst == json_type::integer) ? (double)jsv._integer + : (jst == json_type::ninteger) ? (double)jsv._integer : (double)jsv._unsigned; return true; } -inline bool get_integral(json_cview json, int32_t& value) { +inline bool get_integer(json_cview json, int32_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::integer && jst != json_type::unsigned_) + if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); - value = (jst == json_type::integer) ? (int32_t)jsv._integer + value = (jst == json_type::ninteger) ? (int32_t)jsv._integer : (int32_t)jsv._unsigned; return true; } -inline bool get_integral(json_cview json, uint32_t& value) { +inline bool get_integer(json_cview json, uint32_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::integer && jst != json_type::unsigned_) + if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); - value = (jst == json_type::integer) ? (uint32_t)jsv._integer + value = (jst == json_type::ninteger) ? (uint32_t)jsv._integer : (uint32_t)jsv._unsigned; return true; } @@ -1468,28 +1624,28 @@ inline bool get_number(json_cview json, float& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); - if (jst != json_type::real && jst != json_type::integer && - jst != json_type::unsigned_) + if (jst != json_type::nfloat && jst != json_type::ninteger && + jst != json_type::nunsigned) return set_error(json, "number expected"); - value = (jst == json_type::real) + value = (jst == json_type::nfloat) ? (float)jsv._real - : (jst == json_type::integer) ? (float)jsv._integer + : (jst == json_type::ninteger) ? (float)jsv._integer : (float)jsv._unsigned; return true; } // Get basic values -inline int64_t get_integer(json_cview json) { +inline int64_t get_number_integer(json_cview json) { auto value = (int64_t)0; - return get_integer(json, value) ? value : 0; + return get_number_integer(json, value) ? value : 0; } -inline uint64_t get_unsigned(json_cview json) { +inline uint64_t get_number_unsigned(json_cview json) { auto value = (uint64_t)0; - return get_unsigned(json, value) ? value : 0; + return get_number_unsigned(json, value) ? value : 0; } -inline double get_real(json_cview json) { +inline double get_number_real(json_cview json) { auto value = (double)0; - return get_real(json, value) ? value : 0; + return get_number_float(json, value) ? value : 0; } inline bool get_boolean(json_cview json) { auto value = false; @@ -1499,9 +1655,9 @@ inline string get_string(json_cview json) { auto value = string{}; return get_string(json, value) ? value : string{}; } -inline int64_t get_integral(json_cview json) { +inline int64_t get_integer(json_cview json) { auto value = (int64_t)0; - return get_integral(json, value) ? value : 0; + return get_integer(json, value) ? value : 0; } inline double get_number(json_cview json) { auto value = (double)0; @@ -1802,7 +1958,7 @@ inline json_view insert_element(json_view json, string_view key) { jsv._object.length += 1; auto& jkt = json.root->types.emplace_back(); auto& jkv = json.root->values.emplace_back(); - jkt = json_type::string_; + jkt = json_type::string; for (auto kv : json.root->key_list) { auto okey = string_view{ json.root->keys.data() + kv._string.start, kv._string.length}; @@ -1895,16 +2051,16 @@ inline string compute_path(json_cview json) { // Conversion from json to values inline bool get_value(json_cview json, int64_t& value) { - return get_integral(json, value); + return get_integer(json, value); } inline bool get_value(json_cview json, int32_t& value) { - return get_integral(json, value); + return get_integer(json, value); } inline bool get_value(json_cview json, uint64_t& value) { - return get_integral(json, value); + return get_integer(json, value); } inline bool get_value(json_cview json, uint32_t& value) { - return get_integral(json, value); + return get_integer(json, value); } inline bool get_value(json_cview json, double& value) { return get_number(json, value); diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index 040735104..bb05add95 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -37,6 +37,7 @@ #include "yocto_color.h" #include "yocto_geometry.h" +#include "yocto_json.h" #include "yocto_parallel.h" #include "yocto_sampling.h" #include "yocto_shading.h" @@ -1932,3 +1933,117 @@ void trace_stop(trace_state* state) { } } // namespace yocto + +// ----------------------------------------------------------------------------- +// TRACE IO +// ----------------------------------------------------------------------------- +namespace yocto { + +// Json conversion +void to_json(json_value& json, const trace_params& value) { + json["resolution"] = value.resolution; + json["sampler"] = value.sampler; + json["falsecolor"] = value.falsecolor; + json["samples"] = value.samples; + json["bounces"] = value.bounces; + json["clamp"] = value.clamp; + json["nocaustics"] = value.nocaustics; + json["envhidden"] = value.envhidden; + json["tentfilter"] = value.tentfilter; + json["seed"] = value.seed; + json["bvh"] = value.bvh; + json["noparallel"] = value.noparallel; + json["pratio"] = value.pratio; + json["exposure"] = value.exposure; +} +void from_json(const json_value& json, trace_params& value) { + static auto default_ = trace_params{}; + value.resolution = json.value("resolution", default_.resolution); + value.sampler = json.value("sampler", default_.sampler); + value.falsecolor = json.value("falsecolor", default_.falsecolor); + value.samples = json.value("samples", default_.samples); + value.bounces = json.value("bounces", default_.bounces); + value.clamp = json.value("clamp", default_.clamp); + value.nocaustics = json.value("nocaustics", default_.nocaustics); + value.envhidden = json.value("envhidden", default_.envhidden); + value.tentfilter = json.value("tentfilter", default_.tentfilter); + value.seed = json.value("seed", default_.seed); + value.bvh = json.value("bvh", default_.bvh); + value.noparallel = json.value("noparallel", default_.noparallel); + value.pratio = json.value("pratio", default_.pratio); + value.exposure = json.value("exposure", default_.exposure); +} +void to_schema(json_value& schema, const trace_params& value, const string& descr) { + schema = to_schema_object(descr); + auto& properties = get_schema_properties(schema); + properties["resolution"] = to_schema(value.resolution, "Image resolution."); + properties["sampler"] = to_schema(value.sampler, "Sampler type."); + properties["falsecolor"] = to_schema(value.falsecolor, "False color type."); + properties["samples"] = to_schema(value.samples, "Number of samples."); + properties["bounces"] = to_schema(value.bounces, "Number of bounces."); + properties["clamp"] = to_schema(value.clamp, "Clamp value."); + properties["nocaustics"] = to_schema(value.nocaustics, "Disable caustics."); + properties["envhidden"] = to_schema(value.envhidden, "Hide environment."); + properties["tentfilter"] = to_schema(value.tentfilter, "Filter image."); + properties["seed"] = to_schema(value.seed, "Random seed."); + properties["bvh"] = to_schema(value.bvh, "Bvh type."); + properties["noparallel"] = to_schema(value.noparallel, "Disable threading."); + properties["pratio"] = to_schema(value.pratio, "Preview ratio."); + properties["exposure"] = to_schema(value.exposure, "Image exposure."); +} + +// Json enum conventions +const vector>& json_enum_labels(trace_bvh_type) { +static const auto trace_bvh_labels = vector>{ + {trace_bvh_type::default_, "default"}, + {trace_bvh_type::highquality, "highquality"}, + {trace_bvh_type::middle, "middle"}, + {trace_bvh_type::balanced, "balanced"}, +#ifdef YOCTO_EMBREE + {trace_bvh_type::embree_default, "embree-default"}, + {trace_bvh_type::embree_highquality, "embree-highquality"}, + {trace_bvh_type::embree_compact, "embree-compact"}, +#endif +}; +return trace_bvh_labels;} + +const vector>& json_enum_labels( + trace_falsecolor_type) { +static const auto trace_falsecolor_labels = + vector>{ + {trace_falsecolor_type::position, "position"}, + {trace_falsecolor_type::normal, "normal"}, + {trace_falsecolor_type::frontfacing, "frontfacing"}, + {trace_falsecolor_type::gnormal, "gnormal"}, + {trace_falsecolor_type::gfrontfacing, "gfrontfacing"}, + {trace_falsecolor_type::texcoord, "texcoord"}, + {trace_falsecolor_type::color, "color"}, + {trace_falsecolor_type::emission, "emission"}, + {trace_falsecolor_type::diffuse, "diffuse"}, + {trace_falsecolor_type::specular, "specular"}, + {trace_falsecolor_type::coat, "coat"}, + {trace_falsecolor_type::metal, "metal"}, + {trace_falsecolor_type::transmission, "transmission"}, + {trace_falsecolor_type::translucency, "translucency"}, + {trace_falsecolor_type::refraction, "refraction"}, + {trace_falsecolor_type::roughness, "roughness"}, + {trace_falsecolor_type::opacity, "opacity"}, + {trace_falsecolor_type::ior, "ior"}, + {trace_falsecolor_type::instance, "instance"}, + {trace_falsecolor_type::element, "element"}, + {trace_falsecolor_type::highlight, "highlight"}}; + return trace_falsecolor_labels; +} + +const vector>& json_enum_labels( + trace_sampler_type) { + static const auto trace_sampler_labels = vector>{ + {trace_sampler_type::path, "path"}, {trace_sampler_type::naive, "naive"}, + {trace_sampler_type::eyelight, "eyelight"}, + {trace_sampler_type::falsecolor, "falsecolor"}, + {trace_sampler_type::albedo, "albedo"}, + {trace_sampler_type::normal, "normal"}}; + return trace_sampler_labels; +} + +} // namespace yocto diff --git a/libs/yocto/yocto_trace.h b/libs/yocto/yocto_trace.h index c41fbc5fc..034d314cc 100644 --- a/libs/yocto/yocto_trace.h +++ b/libs/yocto/yocto_trace.h @@ -544,4 +544,24 @@ void trace_stop(trace_state* state); } // namespace yocto +// ----------------------------------------------------------------------------- +// TRACE IO +// ----------------------------------------------------------------------------- +namespace yocto { + +// Json conversion +struct json_value; +void to_json(json_value& json, const trace_params& value); +void from_json(const json_value& json, trace_params& value); +void to_schema(json_value& json, const trace_params& value, const string& descr); + +// Json enum conventions +const vector>& json_enum_labels(trace_bvh_type); +const vector>& json_enum_labels( + trace_falsecolor_type); +const vector>& json_enum_labels( + trace_sampler_type); + +} // namespace yocto + #endif diff --git a/libs/yocto_gui/yocto_imgui.cpp b/libs/yocto_gui/yocto_imgui.cpp index 431665a8f..bb67f1bf7 100644 --- a/libs/yocto_gui/yocto_imgui.cpp +++ b/libs/yocto_gui/yocto_imgui.cpp @@ -998,7 +998,7 @@ static bool draw_textinput_params( } bool draw_params(gui_window* win, const char* lbl, json_value& value) { - if (value.is_integral()) { + if (value.is_integer()) { return draw_dragger_params(win, lbl, value); } else if (value.is_number()) { return draw_dragger_params(win, lbl, value); @@ -1010,7 +1010,7 @@ bool draw_params(gui_window* win, const char* lbl, json_value& value) { if (value.size() > 4) return false; // skip auto is_integer_array = true, is_number_array = true; for (auto& item : value) { - if (!item.is_integral()) is_integer_array = false; + if (!item.is_integer()) is_integer_array = false; if (!item.is_number()) is_number_array = false; } if (!is_integer_array && !is_number_array) return false; // skip From 3758dad5b913a78c8438f49cc73c6ddffcfeb56d Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 15:26:51 +0100 Subject: [PATCH 04/12] updated --- libs/yocto/yocto_json.cpp | 12 +- libs/yocto/yocto_json.h | 528 +++++++++++++++++------------------ libs/yocto/yocto_sceneio.cpp | 22 +- 3 files changed, 281 insertions(+), 281 deletions(-) diff --git a/libs/yocto/yocto_json.cpp b/libs/yocto/yocto_json.cpp index 62ef64c55..8209be6fa 100644 --- a/libs/yocto/yocto_json.cpp +++ b/libs/yocto/yocto_json.cpp @@ -856,7 +856,7 @@ void parse_cli( namespace yocto { // convert json -void to_json(njson& njs, json_cview json) { +void to_json(njson& njs, json_ctview json) { switch (get_type(json)) { case json_type::null: njs = nullptr; break; case json_type::ninteger: njs = get_number_integer(json); break; @@ -881,7 +881,7 @@ void to_json(njson& njs, json_cview json) { } // convert json -void from_json(const njson& njs, json_view json) { +void from_json(const njson& njs, json_tview json) { switch (njs.type()) { case njson::value_t::null: set_null(json); break; case njson::value_t::number_integer: set_integer(json, (int64_t)njs); break; @@ -916,13 +916,13 @@ bool load_json(const string& filename, json_tree& json, string& error) { // sax handler struct sax_handler { // stack - json_view root; - std::vector stack = {}; + json_tview root; + std::vector stack = {}; std::string current_key; - explicit sax_handler(json_view root_) : root{root_}, stack{root_} {} + explicit sax_handler(json_tview root_) : root{root_}, stack{root_} {} // get current value - json_view next_value() { + json_tview next_value() { if (stack.size() == 1) return root; auto& jst = _get_type(stack.back()); if (jst == json_type::array) return append_element(stack.back()); diff --git a/libs/yocto/yocto_json.h b/libs/yocto/yocto_json.h index 8ce7db240..44c65612c 100644 --- a/libs/yocto/yocto_json.h +++ b/libs/yocto/yocto_json.h @@ -376,8 +376,8 @@ bool parse_cli(json_value& value, const json_value& schema, namespace yocto { // Declarations -struct json_view; -struct json_cview; +struct json_tview; +struct json_ctview; // Json tree struct json_tree { @@ -419,194 +419,194 @@ bool load_json(const string& filename, json_tree& json, string& error); bool save_json(const string& filename, const json_tree& json, string& error); // Get view from value -inline json_view get_root(json_tree& json); -inline json_cview get_croot(json_tree& json); +inline json_tview get_root(json_tree& json); +inline json_ctview get_croot(json_tree& json); // Error handling inline void set_error(json_tree& json, string_view error); inline void clear_error(json_tree& json); // Json view -struct json_view { +struct json_tview { json_tree* root = nullptr; uint32_t index = 0; - json_view(json_tree* root_) : root{root_}, index{(uint32_t)-1} {} - json_view(json_tree* root_, uint32_t index_) : root{root_}, index{index_} {} + json_tview(json_tree* root_) : root{root_}, index{(uint32_t)-1} {} + json_tview(json_tree* root_, uint32_t index_) : root{root_}, index{index_} {} }; -struct json_cview { +struct json_ctview { json_tree* root = nullptr; uint32_t index = 0; - json_cview(json_tree* root_) : root{root_}, index{(uint32_t)-1} {} - json_cview(json_tree* root_, uint32_t index_) : root{root_}, index{index_} {} - json_cview(json_view other) : root{other.root}, index{other.index} {} + json_ctview(json_tree* root_) : root{root_}, index{(uint32_t)-1} {} + json_ctview(json_tree* root_, uint32_t index_) : root{root_}, index{index_} {} + json_ctview(json_tview other) : root{other.root}, index{other.index} {} }; // Error check -inline bool is_valid(json_cview json); -inline bool is_valid(json_view json); -inline string get_error(json_cview json); -inline string get_error(json_view json); -inline string compute_path(json_cview json); -inline bool set_error(json_cview json, string_view error); +inline bool is_valid(json_ctview json); +inline bool is_valid(json_tview json); +inline string get_error(json_ctview json); +inline string get_error(json_tview json); +inline string compute_path(json_ctview json); +inline bool set_error(json_ctview json, string_view error); // Type -inline json_type get_type(json_cview json); +inline json_type get_type(json_ctview json); // Type -inline bool is_null(json_cview json); -inline bool is_integer(json_cview json); -inline bool is_number(json_cview json); -inline bool is_boolean(json_cview json); -inline bool is_string(json_cview json); -inline bool is_array(json_cview json); -inline bool is_object(json_cview json); -inline bool is_binary(json_cview json); -inline bool is_number_integer(json_cview json); -inline bool is_number_unsigned(json_cview json); -inline bool is_number_float(json_cview json); +inline bool is_null(json_ctview json); +inline bool is_integer(json_ctview json); +inline bool is_number(json_ctview json); +inline bool is_boolean(json_ctview json); +inline bool is_string(json_ctview json); +inline bool is_array(json_ctview json); +inline bool is_object(json_ctview json); +inline bool is_binary(json_ctview json); +inline bool is_number_integer(json_ctview json); +inline bool is_number_unsigned(json_ctview json); +inline bool is_number_float(json_ctview json); // Initialization to basic types -inline bool set_null(json_view json); -inline bool set_integer(json_view json, int64_t value); -inline bool set_unsigned(json_view json, uint64_t value); -inline bool set_real(json_view json, double value); -inline bool set_boolean(json_view json, bool value); -inline bool set_string(json_view json, const string& value); -inline bool set_integral(json_view json, int64_t value); -inline bool set_integral(json_view json, int32_t value); -inline bool set_integral(json_view json, uint64_t value); -inline bool set_integral(json_view json, uint32_t value); -inline bool set_number(json_view json, double value); -inline bool set_number(json_view json, float value); +inline bool set_null(json_tview json); +inline bool set_integer(json_tview json, int64_t value); +inline bool set_unsigned(json_tview json, uint64_t value); +inline bool set_real(json_tview json, double value); +inline bool set_boolean(json_tview json, bool value); +inline bool set_string(json_tview json, const string& value); +inline bool set_integral(json_tview json, int64_t value); +inline bool set_integral(json_tview json, int32_t value); +inline bool set_integral(json_tview json, uint64_t value); +inline bool set_integral(json_tview json, uint32_t value); +inline bool set_number(json_tview json, double value); +inline bool set_number(json_tview json, float value); // Get basic values -inline bool get_boolean(json_cview json, bool& value); -inline bool get_string(json_cview json, string& value); -inline bool get_integer(json_cview json, int64_t& value); -inline bool get_integer(json_cview json, uint64_t& value); -inline bool get_number(json_cview json, double& value); -inline bool get_integer(json_cview json, int32_t& value); -inline bool get_integer(json_cview json, uint32_t& value); -inline bool get_number(json_cview json, float& value); -inline bool get_number_integer(json_cview json, int64_t& value); -inline bool get_number_unsigned(json_cview json, uint64_t& value); -inline bool get_number_float(json_cview json, double& value); +inline bool get_boolean(json_ctview json, bool& value); +inline bool get_string(json_ctview json, string& value); +inline bool get_integer(json_ctview json, int64_t& value); +inline bool get_integer(json_ctview json, uint64_t& value); +inline bool get_number(json_ctview json, double& value); +inline bool get_integer(json_ctview json, int32_t& value); +inline bool get_integer(json_ctview json, uint32_t& value); +inline bool get_number(json_ctview json, float& value); +inline bool get_number_integer(json_ctview json, int64_t& value); +inline bool get_number_unsigned(json_ctview json, uint64_t& value); +inline bool get_number_float(json_ctview json, double& value); // Get basic values - ignore errors if present -inline bool get_boolean(json_cview json); -inline string get_string(json_cview json); -inline int64_t get_integer(json_cview json); -inline uint64_t get_integeru(json_cview json); -inline double get_number(json_cview json); -inline int64_t get_number_integer(json_cview json); -inline uint64_t get_number_unsigned(json_cview json); -inline double get_number_real(json_cview json); +inline bool get_boolean(json_ctview json); +inline string get_string(json_ctview json); +inline int64_t get_integer(json_ctview json); +inline uint64_t get_integeru(json_ctview json); +inline double get_number(json_ctview json); +inline int64_t get_number_integer(json_ctview json); +inline uint64_t get_number_unsigned(json_ctview json); +inline double get_number_real(json_ctview json); // Compound type -inline bool is_empty(json_cview json); -inline size_t get_size(json_cview json); +inline bool is_empty(json_ctview json); +inline size_t get_size(json_ctview json); // Array -inline bool set_array(json_view json); -inline bool set_array(json_view json, size_t size); -inline bool array_size(json_cview json, size_t& size); -inline bool has_element(json_view json, size_t idx); -inline bool has_element(json_cview json, size_t idx); -inline json_view get_element(json_view json, size_t idx); -inline json_cview get_element(json_cview json, size_t idx); -inline json_view append_element(json_view json); -inline auto iterate_array(json_view json); -inline auto iterate_array(json_cview json); +inline bool set_array(json_tview json); +inline bool set_array(json_tview json, size_t size); +inline bool array_size(json_ctview json, size_t& size); +inline bool has_element(json_tview json, size_t idx); +inline bool has_element(json_ctview json, size_t idx); +inline json_tview get_element(json_tview json, size_t idx); +inline json_ctview get_element(json_ctview json, size_t idx); +inline json_tview append_element(json_tview json); +inline auto iterate_array(json_tview json); +inline auto iterate_array(json_ctview json); // Object -inline bool set_object(json_view json); -inline bool object_size(json_cview json, size_t& size); -inline bool has_element(json_view json, string_view key); -inline bool has_element(json_cview json, string_view key); -inline json_view get_element(json_view json, string_view key); -inline json_cview get_element(json_cview json, string_view key); -inline json_view insert_element(json_view json, string_view key); -inline auto iterate_object(json_view json); -inline auto iterate_object(json_cview json); +inline bool set_object(json_tview json); +inline bool object_size(json_ctview json, size_t& size); +inline bool has_element(json_tview json, string_view key); +inline bool has_element(json_ctview json, string_view key); +inline json_tview get_element(json_tview json, string_view key); +inline json_ctview get_element(json_ctview json, string_view key); +inline json_tview insert_element(json_tview json, string_view key); +inline auto iterate_object(json_tview json); +inline auto iterate_object(json_ctview json); // Binary -inline bool set_binary(json_view json, const json_binary& value); -inline bool get_binary(json_cview json, json_binary& value); +inline bool set_binary(json_tview json, const json_binary& value); +inline bool get_binary(json_ctview json, json_binary& value); // Get the path of a json view -inline string compute_path(json_cview json); +inline string compute_path(json_ctview json); // Conversion from json to values template -inline bool get_value(json_cview json, T& value); +inline bool get_value(json_ctview json, T& value); // Conversion from json to values -inline bool get_value(json_cview json, int64_t& value); -inline bool get_value(json_cview json, int32_t& value); -inline bool get_value(json_cview json, uint64_t& value); -inline bool get_value(json_cview json, uint32_t& value); -inline bool get_value(json_cview json, double& value); -inline bool get_value(json_cview json, float& value); -inline bool get_value(json_cview json, bool& value); -inline bool get_value(json_cview json, string& value); +inline bool get_value(json_ctview json, int64_t& value); +inline bool get_value(json_ctview json, int32_t& value); +inline bool get_value(json_ctview json, uint64_t& value); +inline bool get_value(json_ctview json, uint32_t& value); +inline bool get_value(json_ctview json, double& value); +inline bool get_value(json_ctview json, float& value); +inline bool get_value(json_ctview json, bool& value); +inline bool get_value(json_ctview json, string& value); template -inline bool get_value(json_cview json, vector& value); +inline bool get_value(json_ctview json, vector& value); template -inline bool get_value(json_cview json, array& value); +inline bool get_value(json_ctview json, array& value); // Get value at a key or index template -inline bool get_value_at(json_cview json, string_view key, T& value); +inline bool get_value_at(json_ctview json, string_view key, T& value); template -inline bool get_value_at(json_cview json, size_t idx, T& value); +inline bool get_value_at(json_ctview json, size_t idx, T& value); // Get value at a key or nothing is key is not preesent template -inline bool get_value_if(json_cview json, string_view key, T& value); +inline bool get_value_if(json_ctview json, string_view key, T& value); // Conversion to json from values template -inline bool set_value(json_view json, const T& value); +inline bool set_value(json_tview json, const T& value); // Conversion to json from values -inline bool set_value(json_view json, int64_t value); -inline bool set_value(json_view json, int32_t value); -inline bool set_value(json_view json, uint64_t value); -inline bool set_value(json_view json, uint32_t value); -inline bool set_value(json_view json, double value); -inline bool set_value(json_view json, float value); -inline bool set_value(json_view json, bool value); -inline bool set_value(json_view json, const string& value); -inline bool set_value(json_view json, const char* value); +inline bool set_value(json_tview json, int64_t value); +inline bool set_value(json_tview json, int32_t value); +inline bool set_value(json_tview json, uint64_t value); +inline bool set_value(json_tview json, uint32_t value); +inline bool set_value(json_tview json, double value); +inline bool set_value(json_tview json, float value); +inline bool set_value(json_tview json, bool value); +inline bool set_value(json_tview json, const string& value); +inline bool set_value(json_tview json, const char* value); template -inline bool set_value(json_view json, const vector& value); +inline bool set_value(json_tview json, const vector& value); template -inline bool set_value(json_view json, const array& value); +inline bool set_value(json_tview json, const array& value); // Helpers for user-defined types -inline bool check_array(json_cview json); -inline bool check_array(json_cview json, size_t size_); -inline bool check_object(json_cview json); +inline bool check_array(json_ctview json); +inline bool check_array(json_ctview json, size_t size_); +inline bool check_object(json_ctview json); // Helpers for user-defined types -inline bool set_array(json_view json); +inline bool set_array(json_tview json); template -inline bool set_value_at(json_view json, size_t idx, const T& value); +inline bool set_value_at(json_tview json, size_t idx, const T& value); template -inline bool append_value(json_view json, const T& value); -inline json_view append_array(json_view json); -inline json_view append_object(json_view json); +inline bool append_value(json_tview json, const T& value); +inline json_tview append_array(json_tview json); +inline json_tview append_object(json_tview json); // Helpers for user-defined types -inline bool set_object(json_view json); +inline bool set_object(json_tview json); template -inline bool set_value_at(json_view json, string_view key, const T& value); +inline bool set_value_at(json_tview json, string_view key, const T& value); template -inline bool insert_value(json_view json, string_view key, const T& value); +inline bool insert_value(json_tview json, string_view key, const T& value); template inline bool insert_value_if( - json_view json, string_view key, const T& value, const T& default_); -inline json_view insert_array(json_view json, string_view key); -inline json_view insert_object(json_view json, string_view key); + json_tview json, string_view key, const T& value, const T& default_); +inline json_tview insert_array(json_tview json, string_view key); +inline json_tview insert_object(json_tview json, string_view key); } // namespace yocto @@ -1317,14 +1317,14 @@ inline const json_value& get_schema_properties(const json_value& schema) { namespace yocto { // Get view from value -inline json_view get_root(json_tree& json) { return {&json, 0}; } -inline json_cview get_croot(json_tree& json) { return {&json, 0}; } -inline bool set_error(json_cview json, string_view error) { +inline json_tview get_root(json_tree& json) { return {&json, 0}; } +inline json_ctview get_croot(json_tree& json) { return {&json, 0}; } +inline bool set_error(json_ctview json, string_view error) { if (!is_valid(json)) return false; set_error(*json.root, string{error} + " at " + compute_path(json)); return false; } -inline json_view set_error_view(json_cview json, string_view error) { +inline json_tview set_error_view(json_ctview json, string_view error) { if (!is_valid(json)) return {json.root}; set_error(*json.root, string{error} + " at " + compute_path(json)); return {json.root}; @@ -1342,19 +1342,19 @@ inline void clear_error(json_tree& json) { } // Helpers -inline json_type& _get_type(json_view json) { +inline json_type& _get_type(json_tview json) { if (!is_valid(json)) throw std::invalid_argument{"bad json"}; return json.root->types[json.index]; } -inline const json_type& _get_type(json_cview json) { +inline const json_type& _get_type(json_ctview json) { if (!is_valid(json)) throw std::invalid_argument{"bad json"}; return json.root->types[json.index]; } -inline json_tree::json_value& _get_value(json_view json) { +inline json_tree::json_value& _get_value(json_tview json) { if (!is_valid(json)) throw std::invalid_argument{"bad json"}; return json.root->values[json.index]; } -inline const json_tree::json_value& _get_value(json_cview json) { +inline const json_tree::json_value& _get_value(json_ctview json) { if (!is_valid(json)) throw std::invalid_argument{"bad json"}; return json.root->values[json.index]; } @@ -1366,103 +1366,103 @@ inline uint32_t _get_capacity(uint32_t length) { while (capacity < length) capacity *= 2; return capacity; } -inline string_view _get_key(json_cview json) { +inline string_view _get_key(json_ctview json) { if (!is_valid(json)) throw std::invalid_argument{"bad tree"}; auto& jst = _get_type(json); auto& jsv = _get_value(json); if (jst != json_type::string) throw std::invalid_argument{"bad key"}; return {json.root->keys.data() + jsv._string.start, jsv._string.length}; } -inline void _find_path(json_view json, vector& path); +inline void _find_path(json_tview json, vector& path); // Error check -inline bool is_valid(json_cview json) { +inline bool is_valid(json_ctview json) { return json.root != nullptr && json.root->valid && json.index != (uint32_t)-1; } -inline bool is_valid(json_view json) { +inline bool is_valid(json_tview json) { return json.root != nullptr && json.root->valid && json.index != (uint32_t)-1; } -inline string get_error(json_cview json) { +inline string get_error(json_ctview json) { if (json.root == nullptr) return "bad root"; if (json.root->valid) return ""; return json.root->error; } -inline string get_error(json_view json) { +inline string get_error(json_tview json) { if (json.root == nullptr) return "bad root"; if (json.root->valid) return ""; return json.root->error; } // Type -inline json_type get_type(json_cview json) { +inline json_type get_type(json_ctview json) { if (!is_valid(json)) return json_type::null; return _get_type(json); } -inline bool is_null(json_cview json) { +inline bool is_null(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::null; } -inline bool is_number_integer(json_cview json) { +inline bool is_number_integer(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::ninteger; } -inline bool is_number_unsigned(json_cview json) { +inline bool is_number_unsigned(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::nunsigned; } -inline bool is_number_float(json_cview json) { +inline bool is_number_float(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::nfloat; } -inline bool is_integer(json_cview json) { +inline bool is_integer(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::ninteger || jst == json_type::nunsigned; } -inline bool is_number(json_cview json) { +inline bool is_number(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::ninteger || jst == json_type::nunsigned || jst == json_type::nfloat; } -inline bool is_boolean(json_cview json) { +inline bool is_boolean(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::boolean; } -inline bool is_string(json_cview json) { +inline bool is_string(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::string; } -inline bool is_array(json_cview json) { +inline bool is_array(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::array; } -inline bool is_object(json_cview json) { +inline bool is_object(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::object; } -inline bool is_binary(json_cview json) { +inline bool is_binary(json_ctview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); return jst == json_type::binary; } // Initialization to basic types -inline bool set_null(json_view json) { +inline bool set_null(json_tview json) { if (!is_valid(json)) return false; auto& jst = _get_type(json); jst = json_type::null; return true; } -inline bool set_integer(json_view json, int64_t value) { +inline bool set_integer(json_tview json, int64_t value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1470,7 +1470,7 @@ inline bool set_integer(json_view json, int64_t value) { jsv._integer = value; return true; } -inline bool set_unsigned(json_view json, uint64_t value) { +inline bool set_unsigned(json_tview json, uint64_t value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1478,7 +1478,7 @@ inline bool set_unsigned(json_view json, uint64_t value) { jsv._unsigned = value; return true; } -inline bool set_real(json_view json, double value) { +inline bool set_real(json_tview json, double value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1486,7 +1486,7 @@ inline bool set_real(json_view json, double value) { jsv._real = value; return true; } -inline bool set_boolean(json_view json, bool value) { +inline bool set_boolean(json_tview json, bool value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1494,7 +1494,7 @@ inline bool set_boolean(json_view json, bool value) { jsv._boolean = value; return true; } -inline bool set_string(json_view json, const string& value) { +inline bool set_string(json_tview json, const string& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1506,27 +1506,27 @@ inline bool set_string(json_view json, const string& value) { json.root->strings.push_back(0); return true; } -inline bool set_integral(json_view json, int64_t value) { +inline bool set_integral(json_tview json, int64_t value) { return set_integer(json, value); } -inline bool set_integral(json_view json, int32_t value) { +inline bool set_integral(json_tview json, int32_t value) { return set_integer(json, value); } -inline bool set_integral(json_view json, uint64_t value) { +inline bool set_integral(json_tview json, uint64_t value) { return set_unsigned(json, value); } -inline bool set_integral(json_view json, uint32_t value) { +inline bool set_integral(json_tview json, uint32_t value) { return set_unsigned(json, value); } -inline bool set_number(json_view json, double value) { +inline bool set_number(json_tview json, double value) { return set_real(json, value); } -inline bool set_number(json_view json, float value) { +inline bool set_number(json_tview json, float value) { return set_real(json, value); } // Get basic values -inline bool get_number_integer(json_cview json, int64_t& value) { +inline bool get_number_integer(json_ctview json, int64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1534,7 +1534,7 @@ inline bool get_number_integer(json_cview json, int64_t& value) { value = jsv._integer; return true; } -inline bool get_number_unsigned(json_cview json, uint64_t& value) { +inline bool get_number_unsigned(json_ctview json, uint64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1542,7 +1542,7 @@ inline bool get_number_unsigned(json_cview json, uint64_t& value) { value = jsv._unsigned; return true; } -inline bool get_number_float(json_cview json, double& value) { +inline bool get_number_float(json_ctview json, double& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1550,7 +1550,7 @@ inline bool get_number_float(json_cview json, double& value) { value = jsv._real; return true; } -inline bool get_boolean(json_cview json, bool& value) { +inline bool get_boolean(json_ctview json, bool& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1558,7 +1558,7 @@ inline bool get_boolean(json_cview json, bool& value) { value = jsv._boolean; return true; } -inline bool get_string(json_cview json, string& value) { +inline bool get_string(json_ctview json, string& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1567,7 +1567,7 @@ inline bool get_string(json_cview json, string& value) { json.root->strings.data() + jsv._string.start + jsv._string.length}; return true; } -inline bool get_integer(json_cview json, int64_t& value) { +inline bool get_integer(json_ctview json, int64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1577,7 +1577,7 @@ inline bool get_integer(json_cview json, int64_t& value) { : (int64_t)jsv._unsigned; return true; } -inline bool get_integer(json_cview json, uint64_t& value) { +inline bool get_integer(json_ctview json, uint64_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1587,7 +1587,7 @@ inline bool get_integer(json_cview json, uint64_t& value) { : (uint64_t)jsv._unsigned; return true; } -inline bool get_number(json_cview json, double& value) { +inline bool get_number(json_ctview json, double& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1600,7 +1600,7 @@ inline bool get_number(json_cview json, double& value) { : (double)jsv._unsigned; return true; } -inline bool get_integer(json_cview json, int32_t& value) { +inline bool get_integer(json_ctview json, int32_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1610,7 +1610,7 @@ inline bool get_integer(json_cview json, int32_t& value) { : (int32_t)jsv._unsigned; return true; } -inline bool get_integer(json_cview json, uint32_t& value) { +inline bool get_integer(json_ctview json, uint32_t& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1620,7 +1620,7 @@ inline bool get_integer(json_cview json, uint32_t& value) { : (uint32_t)jsv._unsigned; return true; } -inline bool get_number(json_cview json, float& value) { +inline bool get_number(json_ctview json, float& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1635,43 +1635,43 @@ inline bool get_number(json_cview json, float& value) { } // Get basic values -inline int64_t get_number_integer(json_cview json) { +inline int64_t get_number_integer(json_ctview json) { auto value = (int64_t)0; return get_number_integer(json, value) ? value : 0; } -inline uint64_t get_number_unsigned(json_cview json) { +inline uint64_t get_number_unsigned(json_ctview json) { auto value = (uint64_t)0; return get_number_unsigned(json, value) ? value : 0; } -inline double get_number_real(json_cview json) { +inline double get_number_real(json_ctview json) { auto value = (double)0; return get_number_float(json, value) ? value : 0; } -inline bool get_boolean(json_cview json) { +inline bool get_boolean(json_ctview json) { auto value = false; return get_boolean(json, value) ? value : false; } -inline string get_string(json_cview json) { +inline string get_string(json_ctview json) { auto value = string{}; return get_string(json, value) ? value : string{}; } -inline int64_t get_integer(json_cview json) { +inline int64_t get_integer(json_ctview json) { auto value = (int64_t)0; return get_integer(json, value) ? value : 0; } -inline double get_number(json_cview json) { +inline double get_number(json_ctview json) { auto value = (double)0; return get_number(json, value) ? value : 0; } // Compound type -inline bool is_empty(json_cview json); -inline size_t get_size(json_cview json); +inline bool is_empty(json_ctview json); +inline size_t get_size(json_ctview json); // Array iteeration -inline auto iterate_array(json_view json) { +inline auto iterate_array(json_tview json) { struct iterator { - json_view json; + json_tview json; bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } @@ -1684,11 +1684,11 @@ inline auto iterate_array(json_view json) { if (jst == json_type::object) json.index += jsv._object.skip; return *this; } - json_view operator*() const { return json; } + json_tview operator*() const { return json; } }; struct iterator_wrapper { - json_view begin_; - json_view end_; + json_tview begin_; + json_tview end_; iterator begin() { return {begin_}; } iterator end() { return {end_}; } }; @@ -1702,9 +1702,9 @@ inline auto iterate_array(json_view json) { return iterator_wrapper{{json.root, json.index + 1}, {json.root, json.index + 1 + jsv._array.skip}}; } -inline auto iterate_array(json_cview json) { +inline auto iterate_array(json_ctview json) { struct iterator { - json_cview json; + json_ctview json; bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } @@ -1717,11 +1717,11 @@ inline auto iterate_array(json_cview json) { if (jst == json_type::object) json.index += jsv._object.skip; return *this; } - json_cview operator*() const { return json; } + json_ctview operator*() const { return json; } }; struct iterator_wrapper { - json_cview begin_; - json_cview end_; + json_ctview begin_; + json_ctview end_; iterator begin() { return {begin_}; } iterator end() { return {end_}; } }; @@ -1739,7 +1739,7 @@ inline auto iterate_array(json_cview json) { } // Array -inline bool set_array(json_view json) { +inline bool set_array(json_tview json) { if (!is_valid(json)) return false; if (json.index != json.root->values.size() - 1) throw std::out_of_range{"can only add at the end"}; @@ -1749,7 +1749,7 @@ inline bool set_array(json_view json) { jsv._array = {0, 0}; return true; } -inline bool array_size(json_cview json, size_t& size) { +inline bool array_size(json_ctview json, size_t& size) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1757,7 +1757,7 @@ inline bool array_size(json_cview json, size_t& size) { size = (size_t)jsv._array.length; return true; } -inline json_view get_element(json_view json, size_t idx) { +inline json_tview get_element(json_tview json, size_t idx) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1774,7 +1774,7 @@ inline json_view get_element(json_view json, size_t idx) { return set_error_view(json, "index out of bounds"); } } -inline json_cview get_element(json_cview json, size_t idx) { +inline json_ctview get_element(json_ctview json, size_t idx) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1791,7 +1791,7 @@ inline json_cview get_element(json_cview json, size_t idx) { return set_error_view(json, "index out of bounds"); } } -inline json_view append_element(json_view json) { +inline json_tview append_element(json_tview json) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1802,7 +1802,7 @@ inline json_view append_element(json_view json) { auto index = (uint32_t)json.root->values.size(); json.root->types.emplace_back(json_type::null); json.root->values.emplace_back(); - auto stack = vector{}; + auto stack = vector{}; _find_path(json, stack); for (auto jss : stack) { auto& jsst = _get_type(jss); @@ -1819,28 +1819,28 @@ inline json_view append_element(json_view json) { } // Object iteration -inline auto iterate_object(json_view json) { +inline auto iterate_object(json_tview json) { struct iterator { - json_view json; + json_tview json; bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { if (!is_valid(json)) return *this; - auto& jst = _get_type(json_view{json.root, json.index + 1}); - auto& jsv = _get_value(json_view{json.root, json.index + 1}); + auto& jst = _get_type(json_tview{json.root, json.index + 1}); + auto& jsv = _get_value(json_tview{json.root, json.index + 1}); json.index += 2; if (jst == json_type::array) json.index += jsv._array.skip; if (jst == json_type::object) json.index += jsv._object.skip; return *this; } - pair operator*() const { - return {_get_key(json), json_view{json.root, json.index + 1}}; + pair operator*() const { + return {_get_key(json), json_tview{json.root, json.index + 1}}; } }; struct iterator_wrapper { - json_view begin_; - json_view end_; + json_tview begin_; + json_tview end_; iterator begin() { return {begin_}; } iterator end() { return {end_}; } }; @@ -1854,28 +1854,28 @@ inline auto iterate_object(json_view json) { return iterator_wrapper{{json.root, json.index + 1}, {json.root, json.index + 1 + jsv._object.skip}}; } -inline auto iterate_object(json_cview json) { +inline auto iterate_object(json_ctview json) { struct iterator { - json_cview json; + json_ctview json; bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { if (!is_valid(json)) return *this; - auto& jst = _get_type(json_cview{json.root, json.index + 1}); - auto& jsv = _get_value(json_cview{json.root, json.index + 1}); + auto& jst = _get_type(json_ctview{json.root, json.index + 1}); + auto& jsv = _get_value(json_ctview{json.root, json.index + 1}); json.index += 2; if (jst == json_type::array) json.index += jsv._array.skip; if (jst == json_type::object) json.index += jsv._object.skip; return *this; } - pair operator*() const { - return {_get_key(json), json_cview{json.root, json.index + 1}}; + pair operator*() const { + return {_get_key(json), json_ctview{json.root, json.index + 1}}; } }; struct iterator_wrapper { - json_cview begin_; - json_cview end_; + json_ctview begin_; + json_ctview end_; iterator begin() { return {begin_}; } iterator end() { return {end_}; } }; @@ -1891,7 +1891,7 @@ inline auto iterate_object(json_cview json) { } // Object -inline bool set_object(json_view json) { +inline bool set_object(json_tview json) { if (!is_valid(json)) return false; if (json.index != json.root->values.size() - 1) throw std::out_of_range{"can only add at the end"}; @@ -1901,7 +1901,7 @@ inline bool set_object(json_view json) { jsv._array = {0, 0}; return true; } -inline bool object_size(json_cview json, size_t& size) { +inline bool object_size(json_ctview json, size_t& size) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1909,7 +1909,7 @@ inline bool object_size(json_cview json, size_t& size) { size = (size_t)jsv._object.length; return true; } -inline json_view get_element(json_view json, string_view key) { +inline json_tview get_element(json_tview json, string_view key) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); if (jst != json_type::object) return set_error_view(json, "object expected"); @@ -1918,7 +1918,7 @@ inline json_view get_element(json_view json, string_view key) { } return set_error_view(json, "missing key " + string{key}); } -inline json_cview get_element(json_cview json, string_view key) { +inline json_ctview get_element(json_ctview json, string_view key) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); if (jst != json_type::object) return set_error_view(json, "object expected"); @@ -1927,7 +1927,7 @@ inline json_cview get_element(json_cview json, string_view key) { } return set_error_view(json, "missing key " + string{key}); } -inline bool has_element(json_view json, string_view key) { +inline bool has_element(json_tview json, string_view key) { if (!is_valid(json)) return false; auto& jst = _get_type(json); if (jst != json_type::object) return set_error(json, "object expected"); @@ -1936,7 +1936,7 @@ inline bool has_element(json_view json, string_view key) { } return false; } -inline bool has_element(json_cview json, string_view key) { +inline bool has_element(json_ctview json, string_view key) { if (!is_valid(json)) return false; auto& jst = _get_type(json); if (jst != json_type::object) return set_error(json, "object expected"); @@ -1945,7 +1945,7 @@ inline bool has_element(json_cview json, string_view key) { } return false; } -inline json_view insert_element(json_view json, string_view key) { +inline json_tview insert_element(json_tview json, string_view key) { if (!is_valid(json)) return {json.root}; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -1973,7 +1973,7 @@ inline json_view insert_element(json_view json, string_view key) { auto index = (uint32_t)json.root->values.size(); json.root->types.emplace_back(json_type::null); json.root->values.emplace_back(); - auto stack = vector{}; + auto stack = vector{}; _find_path(json, stack); for (auto jss : stack) { auto& jsst = _get_type(jss); @@ -1990,7 +1990,7 @@ inline json_view insert_element(json_view json, string_view key) { } // Binary -inline bool set_binary(json_view json, const json_binary& value) { +inline bool set_binary(json_tview json, const json_binary& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -2002,7 +2002,7 @@ inline bool set_binary(json_view json, const json_binary& value) { json.root->binaries.end(), value.begin(), value.end()); return true; } -inline bool get_binary(json_cview json, json_binary& value) { +inline bool get_binary(json_ctview json, json_binary& value) { if (!is_valid(json)) return false; auto& jst = _get_type(json); auto& jsv = _get_value(json); @@ -2013,7 +2013,7 @@ inline bool get_binary(json_cview json, json_binary& value) { } // Get the path of a json view -inline bool _compute_path(json_cview json, json_cview jsv, string& path) { +inline bool _compute_path(json_ctview json, json_ctview jsv, string& path) { if (!is_valid(json) || !is_valid(jsv)) { return false; } else if (json.index == jsv.index) { @@ -2040,7 +2040,7 @@ inline bool _compute_path(json_cview json, json_cview jsv, string& path) { return false; } } -inline string compute_path(json_cview json) { +inline string compute_path(json_ctview json) { auto path = string{}; if (_compute_path({json.root, 0}, json, path)) { return path; @@ -2050,32 +2050,32 @@ inline string compute_path(json_cview json) { } // Conversion from json to values -inline bool get_value(json_cview json, int64_t& value) { +inline bool get_value(json_ctview json, int64_t& value) { return get_integer(json, value); } -inline bool get_value(json_cview json, int32_t& value) { +inline bool get_value(json_ctview json, int32_t& value) { return get_integer(json, value); } -inline bool get_value(json_cview json, uint64_t& value) { +inline bool get_value(json_ctview json, uint64_t& value) { return get_integer(json, value); } -inline bool get_value(json_cview json, uint32_t& value) { +inline bool get_value(json_ctview json, uint32_t& value) { return get_integer(json, value); } -inline bool get_value(json_cview json, double& value) { +inline bool get_value(json_ctview json, double& value) { return get_number(json, value); } -inline bool get_value(json_cview json, float& value) { +inline bool get_value(json_ctview json, float& value) { return get_number(json, value); } -inline bool get_value(json_cview json, bool& value) { +inline bool get_value(json_ctview json, bool& value) { return get_boolean(json, value); } -inline bool get_value(json_cview json, string& value) { +inline bool get_value(json_ctview json, string& value) { return get_string(json, value); } template -inline bool get_value(json_cview json, vector& value) { +inline bool get_value(json_ctview json, vector& value) { if (!is_valid(json)) return false; if (!is_array(json)) return set_error(json, "array expected"); value.clear(); @@ -2088,7 +2088,7 @@ inline bool get_value(json_cview json, vector& value) { return true; } template -inline bool get_value(json_cview json, array& value) { +inline bool get_value(json_ctview json, array& value) { if (!is_valid(json)) return false; if (!is_array(json)) return set_error(json, "array expected"); auto size = (size_t)0; @@ -2103,13 +2103,13 @@ inline bool get_value(json_cview json, array& value) { // Get value at a key or index template -inline bool get_value_at(json_cview json, string_view key, T& value) { +inline bool get_value_at(json_ctview json, string_view key, T& value) { if (!is_valid(json)) return false; auto element = get_element(json, key); return get_value(element, value); } template -inline bool get_value_at(json_cview json, size_t idx, T& value) { +inline bool get_value_at(json_ctview json, size_t idx, T& value) { if (!is_valid(json)) return false; auto element = get_element(json, idx); if (!is_valid(element)) return false; @@ -2118,7 +2118,7 @@ inline bool get_value_at(json_cview json, size_t idx, T& value) { // Get value at a key or nothing is key is not preesent template -inline bool get_value_if(json_cview json, string_view key, T& value) { +inline bool get_value_if(json_ctview json, string_view key, T& value) { if (!is_valid(json)) return false; if (!has_element(json, key)) return true; auto element = get_element(json, key); @@ -2127,35 +2127,35 @@ inline bool get_value_if(json_cview json, string_view key, T& value) { } // Conversion to json from values -inline bool set_value(json_view json, int64_t value) { +inline bool set_value(json_tview json, int64_t value) { return set_integral(json, value); } -inline bool set_value(json_view json, int32_t value) { +inline bool set_value(json_tview json, int32_t value) { return set_integral(json, value); } -inline bool set_value(json_view json, uint64_t value) { +inline bool set_value(json_tview json, uint64_t value) { return set_integral(json, value); } -inline bool set_value(json_view json, uint32_t value) { +inline bool set_value(json_tview json, uint32_t value) { return set_integral(json, value); } -inline bool set_value(json_view json, double value) { +inline bool set_value(json_tview json, double value) { return set_number(json, value); } -inline bool set_value(json_view json, float value) { +inline bool set_value(json_tview json, float value) { return set_number(json, value); } -inline bool set_value(json_view json, bool value) { +inline bool set_value(json_tview json, bool value) { return set_boolean(json, value); } -inline bool set_value(json_view json, const string& value) { +inline bool set_value(json_tview json, const string& value) { return set_string(json, value); } -inline bool set_value(json_view json, const char* value) { +inline bool set_value(json_tview json, const char* value) { return set_string(json, value); } template -inline bool set_value(json_view json, const vector& value) { +inline bool set_value(json_tview json, const vector& value) { if (!set_array(json)) return false; for (auto& v : value) { if (!set_value(append_element(json), v)) return false; @@ -2163,7 +2163,7 @@ inline bool set_value(json_view json, const vector& value) { return true; } template -inline bool set_value(json_view json, const array& value) { +inline bool set_value(json_tview json, const array& value) { if (!set_array(json)) return false; for (auto& v : value) { if (!set_value(append_element(json), v)) return false; @@ -2172,12 +2172,12 @@ inline bool set_value(json_view json, const array& value) { } // Helpers for user-defined types -inline bool check_array(json_cview json) { +inline bool check_array(json_ctview json) { if (!is_valid(json)) return false; if (!is_array(json)) return set_error(json, "array expected"); return true; } -inline bool check_array(json_cview json, size_t size_) { +inline bool check_array(json_ctview json, size_t size_) { if (!is_valid(json)) return false; if (!is_array(json)) return set_error(json, "array expected"); auto size = (size_t)0; @@ -2185,7 +2185,7 @@ inline bool check_array(json_cview json, size_t size_) { return set_error(json, "mismatched size"); return true; } -inline bool check_object(json_cview json) { +inline bool check_object(json_ctview json) { if (!is_valid(json)) return false; if (!is_object(json)) return set_error(json, "array expected"); return true; @@ -2193,27 +2193,27 @@ inline bool check_object(json_cview json) { // Helpers for user-defined types template -inline bool set_value_at(json_view json, size_t idx, const T& value) { +inline bool set_value_at(json_tview json, size_t idx, const T& value) { if (!is_valid(json)) return false; auto ejs = get_element(json, idx); if (!is_valid(ejs)) return false; return set_value(ejs, value); } template -inline bool append_value(json_view json, const T& value) { +inline bool append_value(json_tview json, const T& value) { if (!is_valid(json)) return false; auto ejs = append_element(json); if (!is_valid(ejs)) return false; return set_value(ejs, value); } -inline json_view append_array(json_view json) { +inline json_tview append_array(json_tview json) { if (!is_valid(json)) return {json.root}; auto ejs = append_element(json); if (!is_valid(ejs)) return {json.root}; if (!set_array(ejs)) return {json.root}; return ejs; } -inline json_view append_object(json_view json) { +inline json_tview append_object(json_tview json) { if (!is_valid(json)) return {json.root}; auto ejs = append_element(json); if (!is_valid(ejs)) return {json.root}; @@ -2223,14 +2223,14 @@ inline json_view append_object(json_view json) { // Helpers for user-defined types template -inline bool set_value_at(json_view json, string_view key, const T& value) { +inline bool set_value_at(json_tview json, string_view key, const T& value) { if (!is_valid(json)) return false; auto ejs = get_element(json, key); if (!is_valid(ejs)) return false; return set_value(ejs, value); } template -inline bool insert_value(json_view json, string_view key, const T& value) { +inline bool insert_value(json_tview json, string_view key, const T& value) { if (!is_valid(json)) return false; auto ejs = insert_element(json, key); if (!is_valid(ejs)) return false; @@ -2238,21 +2238,21 @@ inline bool insert_value(json_view json, string_view key, const T& value) { } template inline bool insert_value_if( - json_view json, string_view key, const T& value, const T& default_) { + json_tview json, string_view key, const T& value, const T& default_) { if (!is_valid(json)) return false; if (value == default_) return true; auto ejs = insert_element(json, key); if (!is_valid(ejs)) return false; return set_value(ejs, value); } -inline json_view insert_array(json_view json, string_view key) { +inline json_tview insert_array(json_tview json, string_view key) { if (!is_valid(json)) return {json.root}; auto ejs = insert_element(json, key); if (!is_valid(ejs)) return {json.root}; if (!set_array(ejs)) return {json.root}; return ejs; } -inline json_view insert_object(json_view json, string_view key) { +inline json_tview insert_object(json_tview json, string_view key) { if (!is_valid(json)) return {json.root}; auto ejs = insert_element(json, key); if (!is_valid(ejs)) return {json.root}; @@ -2262,7 +2262,7 @@ inline json_view insert_object(json_view json, string_view key) { // Helpers that need to be declared here inline bool _find_anchestors( - json_view json, uint32_t index, vector& path) { + json_tview json, uint32_t index, vector& path) { auto& jst = _get_type(json); if (jst == json_type::array) { if (json.index == index) { @@ -2298,7 +2298,7 @@ inline bool _find_anchestors( return false; } } -inline void _find_path(json_view json, vector& path) { +inline void _find_path(json_tview json, vector& path) { path.clear(); _find_anchestors({json.root, 0}, json.index, path); } diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 0c3935d48..f81cb9e52 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1189,26 +1189,26 @@ inline void from_json(const njson& j, frame3f& value) { #endif // support for json conversions -inline bool set_value(json_view js, const vec3f& value) { +inline bool set_value(json_tview js, const vec3f& value) { return set_value(js, (const array&)value); } -inline bool set_value(json_view js, const vec4f& value) { +inline bool set_value(json_tview js, const vec4f& value) { return set_value(js, (const array&)value); } -inline bool set_value(json_view js, const frame3f& value) { +inline bool set_value(json_tview js, const frame3f& value) { return set_value(js, (const array&)value); } -inline bool set_value(json_view js, const mat4f& value) { +inline bool set_value(json_tview js, const mat4f& value) { return set_value(js, (const array&)value); } -inline bool get_value(json_cview js, vec3f& value) { +inline bool get_value(json_ctview js, vec3f& value) { return get_value(js, (array&)value); } -inline bool get_value(json_cview js, mat3f& value) { +inline bool get_value(json_ctview js, mat3f& value) { return get_value(js, (array&)value); } -inline bool get_value(json_cview js, frame3f& value) { +inline bool get_value(json_ctview js, frame3f& value) { return get_value(js, (array&)value); } @@ -1258,7 +1258,7 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene, // parse json reference auto get_shape = [scene, &shape_map]( - json_cview js, sceneio_shape*& value) -> bool { + json_ctview js, sceneio_shape*& value) -> bool { auto name = ""s; if (!get_value(js, name)) return false; auto it = shape_map.find(name); @@ -1274,7 +1274,7 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene, // parse json reference auto get_material = [scene, &material_map]( - json_cview js, sceneio_material*& value) -> bool { + json_ctview js, sceneio_material*& value) -> bool { auto name = ""s; if (!get_value(js, name)) return false; auto it = material_map.find(name); @@ -1290,7 +1290,7 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene, // parse json reference auto get_texture = [scene, &texture_map]( - json_cview js, sceneio_texture*& value) -> bool { + json_ctview js, sceneio_texture*& value) -> bool { auto name = ""s; if (!get_value(js, name)) return false; auto it = texture_map.find(name); @@ -1313,7 +1313,7 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene, auto ply_instance_map = unordered_map{{"", nullptr}}; auto instance_ply = unordered_map{}; auto get_ply_instances = [&ply_instances, &ply_instance_map, &instance_ply]( - json_cview js, + json_ctview js, sceneio_instance* instance) -> bool { auto name = ""s; if (!get_value(js, name)) return false; From 0073cd306a7280e0ebd8f8510cd6e87b014a50de Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 16:25:57 +0100 Subject: [PATCH 05/12] updated --- apps/ytrace/ytrace.cpp | 205 +++++++++++++++++++-------------- libs/yocto/yocto_json.h | 244 ++++++++++++++++++++++++++-------------- 2 files changed, 283 insertions(+), 166 deletions(-) diff --git a/apps/ytrace/ytrace.cpp b/apps/ytrace/ytrace.cpp index d389028d7..b0a659ce3 100644 --- a/apps/ytrace/ytrace.cpp +++ b/apps/ytrace/ytrace.cpp @@ -162,15 +162,47 @@ void init_scene(trace_scene* scene, sceneio_scene* ioscene, } // render params -struct render_params { - string scene = "scene.json"; - string output = "out.png"; - trace_params params = {}; - string camera = ""; - bool addsky = false; - bool savebatch = false; +struct render_params : trace_params { + string scene = "scene.json"; + string output = "out.png"; + string camera = ""; + bool addsky = false; + bool savebatch = false; }; +// Json IO +void to_json(json_value& json, const render_params& value) { + json["scene"] = value.scene; + json["output"] = value.output; + json["camera"] = value.camera; + json["addsky"] = value.addsky; + json["savebatch"] = value.savebatch; + to_json(json, (const trace_params&)value); +} +void from_json(const json_value& json, render_params& value) { + auto default_ = render_params{}; + value.scene = json.value("scene", default_.scene); + value.output = json.value("output", default_.output); + value.camera = json.value("camera", default_.camera); + value.addsky = json.value("addsky", default_.addsky); + value.savebatch = json.value("savebatch", default_.savebatch); + from_json(json, (trace_params&)value); +} +void to_schema( + json_value& schema, const render_params& value, const string& descr) { + schema = to_schema_object(descr); + auto& properties = get_schema_properties(schema); + properties["scene"] = to_schema(value.scene, "Scene filename."); + properties["output"] = to_schema(value.output, "Output filename."); + properties["camera"] = to_schema(value.camera, "Camera name."); + properties["addsky"] = to_schema(value.addsky, "Add sky."); + properties["savebatch"] = to_schema(value.savebatch, "Save batch."); + properties.update( + get_schema_properties(to_schema((const trace_params&)value, ""))); + get_schema_required(schema).push_back("scene"); + get_schema_positional(schema).push_back("scene"); +} + // convert images int run_render(const render_params& params) { // scene loading @@ -201,21 +233,20 @@ int run_render(const render_params& params) { // build bvh auto bvh_guard = std::make_unique(); auto bvh = bvh_guard.get(); - init_bvh(bvh, scene, params.params, print_progress); + init_bvh(bvh, scene, params, print_progress); // init renderer auto lights_guard = std::make_unique(); auto lights = lights_guard.get(); - init_lights(lights, scene, params.params, print_progress); + init_lights(lights, scene, params, print_progress); // fix renderer type if no lights - if (lights->lights.empty() && is_sampler_lit(params.params)) { + if (lights->lights.empty() && is_sampler_lit(params)) { print_info("no lights presents, image will be black"); } // render - auto render = trace_image(scene, camera, bvh, lights, params.params, - print_progress, + auto render = trace_image(scene, camera, bvh, lights, params, print_progress, [savebatch = params.savebatch, output = params.output]( const image& render, int sample, int samples) { if (!savebatch) return; @@ -237,15 +268,47 @@ int run_render(const render_params& params) { } // convert params -struct view_params { - string scene = "scene.json"; - string output = "out.png"; - trace_params params = {}; - string camera = ""; - bool addsky = false; - bool savebatch = false; +struct view_params : trace_params { + string scene = "scene.json"; + string output = "out.png"; + string camera = ""; + bool addsky = false; + bool savebatch = false; }; +// Json IO +void to_json(json_value& json, const view_params& value) { + json["scene"] = value.scene; + json["output"] = value.output; + json["camera"] = value.camera; + json["addsky"] = value.addsky; + json["savebatch"] = value.savebatch; + to_json(json, (const trace_params&)value); +} +void from_json(const json_value& json, view_params& value) { + auto default_ = view_params{}; + value.scene = json.value("scene", default_.scene); + value.output = json.value("output", default_.output); + value.camera = json.value("camera", default_.camera); + value.addsky = json.value("addsky", default_.addsky); + value.savebatch = json.value("savebatch", default_.savebatch); + from_json(json, (trace_params&)value); +} +void to_schema( + json_value& schema, const view_params& value, const string& descr) { + schema = to_schema_object(descr); + auto& properties = get_schema_properties(schema); + properties["scene"] = to_schema(value.scene, "Scene filename."); + properties["output"] = to_schema(value.output, "Output filename."); + properties["camera"] = to_schema(value.camera, "Camera name."); + properties["addsky"] = to_schema(value.addsky, "Add sky."); + properties["savebatch"] = to_schema(value.savebatch, "Save batch."); + properties.update( + get_schema_properties(to_schema((const trace_params&)value, ""))); + get_schema_required(schema).push_back("scene"); + get_schema_positional(schema).push_back("scene"); +} + #ifndef YOCTO_OPENGL // convert images @@ -289,15 +352,15 @@ int run_view(const view_params& params) { // build bvh auto bvh_guard = std::make_unique(); auto bvh = bvh_guard.get(); - init_bvh(bvh, scene, params.params, print_progress); + init_bvh(bvh, scene, params, print_progress); // init renderer auto lights_guard = std::make_unique(); auto lights = lights_guard.get(); - init_lights(lights, scene, params.params, print_progress); + init_lights(lights, scene, params, print_progress); // fix renderer type if no lights - if (lights->lights.empty() && is_sampler_lit(params.params)) { + if (lights->lights.empty() && is_sampler_lit(params)) { print_info("no lights presents, image will be black"); } @@ -307,7 +370,7 @@ int run_view(const view_params& params) { // render start trace_start( - state, scene, camera, bvh, lights, params.params, + state, scene, camera, bvh, lights, params, [viewer](const string& message, int sample, int nsamples) { set_param(viewer, "render", "sample", to_json(sample)); print_progress(message, sample, nsamples); @@ -340,71 +403,45 @@ int run_view(const view_params& params) { #endif -int main(int argc, const char* argv[]) { - // command line parameters - auto render = render_params{}; - auto view = view_params{}; - - // parse command line - auto cli = make_cli("ytrace", "render images from scenes"); - - auto cli_render = add_command(cli, "render", "render images"); - add_optional(cli_render, "camera", render.camera, "camera name"); - add_optional(cli_render, "resolution", render.params.resolution, - "image resolution", "r"); - add_optional( - cli_render, "samples", render.params.samples, "number of samples", "s"); - add_optional(cli_render, "tracer", render.params.sampler, "trace type", - trace_sampler_labels, "t"); - add_optional(cli_render, "falsecolor", render.params.falsecolor, - "tracer false color type", trace_falsecolor_labels, "F"); - add_optional(cli_render, "bounces", render.params.bounces, - "maximum number of bounces", "b"); - add_optional( - cli_render, "clamp", render.params.clamp, "final pixel clamping"); - add_optional(cli_render, "filter", render.params.tentfilter, "filter image"); - add_optional(cli_render, "envhidden", render.params.envhidden, - "environments are hidden"); - add_optional( - cli_render, "savebatch", render.savebatch, "save images progressively"); - add_optional( - cli_render, "bvh", render.params.bvh, "bvh type", trace_bvh_labels); - add_optional(cli_render, "skyenv", render.addsky, "add sky envmap"); - add_optional(cli_render, "output", render.output, "image filename", "o"); - add_positional(cli_render, "scene", render.scene, "scene filename"); - - auto cli_view = add_command(cli, "view", "render images interactively"); - add_optional(cli_view, "camera", view.camera, "camera name"); - add_optional( - cli_view, "resolution", view.params.resolution, "image resolution", "r"); - add_optional( - cli_view, "samples", view.params.samples, "number of samples", "s"); - add_optional(cli_view, "tracer", view.params.sampler, "trace type", - trace_sampler_labels, "t"); - add_optional(cli_view, "falsecolor", view.params.falsecolor, - "tracer false color type", trace_falsecolor_labels, "F"); - add_optional(cli_view, "bounces", view.params.bounces, - "maximum number of bounces", "b"); - add_optional(cli_view, "clamp", view.params.clamp, "final pixel clamping"); - add_optional(cli_view, "filter", view.params.tentfilter, "filter image"); - add_optional( - cli_view, "envhidden", view.params.envhidden, "environments are hidden"); - add_optional( - cli_view, "savebatch", view.savebatch, "save images progressively"); - add_optional(cli_view, "bvh", view.params.bvh, "bvh type", trace_bvh_labels); - add_optional(cli_view, "skyenv", view.addsky, "add sky envmap"); - add_optional(cli_view, "output", view.output, "image filename", "o"); - add_positional(cli_view, "scene", view.scene, "scene filename"); +struct app_params { + string command = "render"; + render_params render = {}; + view_params view = {}; +}; +// Json IO +void to_json(json_value& json, const app_params& value) { + json["command"] = value.command; + json["render"] = value.render; + json["view"] = value.view; +} +void from_json(const json_value& json, app_params& value) { + auto default_ = app_params{}; + value.command = json.value("command", default_.command); + value.render = json.value("render", default_.render); + value.view = json.value("view", default_.view); +} +void to_schema( + json_value& schema, const app_params& value, const string& descr) { + schema = to_schema_object(descr); + auto& properties = get_schema_properties(schema); + properties["command"] = to_schema(value.command, "Command."); + properties["render"] = to_schema(value.render, "Render final images."); + properties["view"] = to_schema(value.view, "Render interactively."); + get_schema_required(schema).push_back("command"); + get_schema_command(schema) = "command"; +} + +int main(int argc, const char* argv[]) { // parse cli - parse_cli(cli, argc, argv); + auto params = app_params{}; + parse_cli(params, "Render images from scenes", argc, argv); // dispatch commands - auto command = get_command(cli); - if (command == "render") { - return run_render(render); - } else if (command == "view") { - return run_view(view); + if (params.command == "render") { + return run_render(params.render); + } else if (params.command == "view") { + return run_view(params.view); } else { print_fatal("unknown command"); return 1; diff --git a/libs/yocto/yocto_json.h b/libs/yocto/yocto_json.h index 44c65612c..d15742684 100644 --- a/libs/yocto/yocto_json.h +++ b/libs/yocto/yocto_json.h @@ -297,6 +297,7 @@ inline void to_json(json_value& json, uint32_t value); inline void to_json(json_value& json, double value); inline void to_json(json_value& json, float value); inline void to_json(json_value& json, bool value); +inline void to_json(json_value& json, const char* value); inline void to_json(json_value& json, const string& value); template inline void to_json(json_value& json, const vector& value); @@ -313,7 +314,7 @@ inline void to_json(json_value& json, T value); namespace yocto { // Convenience function -template +template inline json_value to_schema(const T& value, const string& descr); // Conversion to json schema from values @@ -324,19 +325,29 @@ inline void to_schema(json_value& schema, uint32_t value, const string& descr); inline void to_schema(json_value& schema, double value, const string& descr); inline void to_schema(json_value& schema, float value, const string& descr); inline void to_schema(json_value& schema, bool value, const string& descr); -inline void to_schema(json_value& schema, const string& value, const string& descr); +inline void to_schema(json_value& schema, const char* value, const string& descr); +inline void to_schema( + json_value& schema, const string& value, const string& descr); template -inline void to_schema(json_value& schema, const vector& value, const string& descr); +inline void to_schema( + json_value& schema, const vector& value, const string& descr); template -inline void to_schema(json_value& schema, const array& value, const string& descr); +inline void to_schema( + json_value& schema, const array& value, const string& descr); template >> inline void to_schema(json_value& schema, T value, const string& descr); // Schema for objects -inline json_value to_schema_object(const string& descr); -inline void to_schema_object(json_value& schema, const string& descr); +inline json_value to_schema_object(const string& descr); +inline void to_schema_object(json_value& schema, const string& descr); inline json_value& get_schema_properties(json_value& schema); inline const json_value& get_schema_properties(const json_value& schema); +inline json_value& get_schema_required(json_value& schema); +inline const json_value& get_schema_required(const json_value& schema); +inline json_value& get_schema_positional(json_value& schema); +inline const json_value& get_schema_positional(const json_value& schema); +inline json_value& get_schema_command(json_value& schema); +inline const json_value& get_schema_command(const json_value& schema); // Validate a value against a schema bool validate_json( @@ -364,6 +375,14 @@ bool parse_cli(json_value& value, const json_value& schema, bool parse_cli(json_value& value, const json_value& schema, int argc, const char** argv, string& error, string& usage); +// Parse the command line for a type that supports it +template +inline void parse_cli( + T& value, const string& usage, int argc, const char** argv); +template +inline void parse_cli( + T& value, const string& usage, const vector& args); + // Low-level parsing routine bool parse_cli(json_value& value, const json_value& schema, const vector& args, string& error, string& usage, string& command); @@ -506,27 +525,27 @@ inline bool is_empty(json_ctview json); inline size_t get_size(json_ctview json); // Array -inline bool set_array(json_tview json); -inline bool set_array(json_tview json, size_t size); -inline bool array_size(json_ctview json, size_t& size); -inline bool has_element(json_tview json, size_t idx); -inline bool has_element(json_ctview json, size_t idx); +inline bool set_array(json_tview json); +inline bool set_array(json_tview json, size_t size); +inline bool array_size(json_ctview json, size_t& size); +inline bool has_element(json_tview json, size_t idx); +inline bool has_element(json_ctview json, size_t idx); inline json_tview get_element(json_tview json, size_t idx); inline json_ctview get_element(json_ctview json, size_t idx); inline json_tview append_element(json_tview json); -inline auto iterate_array(json_tview json); -inline auto iterate_array(json_ctview json); +inline auto iterate_array(json_tview json); +inline auto iterate_array(json_ctview json); // Object -inline bool set_object(json_tview json); -inline bool object_size(json_ctview json, size_t& size); -inline bool has_element(json_tview json, string_view key); -inline bool has_element(json_ctview json, string_view key); +inline bool set_object(json_tview json); +inline bool object_size(json_ctview json, size_t& size); +inline bool has_element(json_tview json, string_view key); +inline bool has_element(json_ctview json, string_view key); inline json_tview get_element(json_tview json, string_view key); inline json_ctview get_element(json_ctview json, string_view key); inline json_tview insert_element(json_tview json, string_view key); -inline auto iterate_object(json_tview json); -inline auto iterate_object(json_ctview json); +inline auto iterate_object(json_tview json); +inline auto iterate_object(json_ctview json); // Binary inline bool set_binary(json_tview json, const json_binary& value); @@ -592,7 +611,7 @@ inline bool set_array(json_tview json); template inline bool set_value_at(json_tview json, size_t idx, const T& value); template -inline bool append_value(json_tview json, const T& value); +inline bool append_value(json_tview json, const T& value); inline json_tview append_array(json_tview json); inline json_tview append_object(json_tview json); @@ -733,7 +752,9 @@ inline bool json_value::is_number_integer() const { inline bool json_value::is_number_unsigned() const { return _type == json_type::nunsigned; } -inline bool json_value::is_number_float() const { return _type == json_type::nfloat; } +inline bool json_value::is_number_float() const { + return _type == json_type::nfloat; +} inline bool json_value::is_integer() const { return _type == json_type::ninteger || _type == json_type::nunsigned; } @@ -744,9 +765,7 @@ inline bool json_value::is_number() const { inline bool json_value::is_boolean() const { return _type == json_type::boolean; } -inline bool json_value::is_string() const { - return _type == json_type::string; -} +inline bool json_value::is_string() const { return _type == json_type::string; } inline bool json_value::is_array() const { return _type == json_type::array; } inline bool json_value::is_object() const { return _type == json_type::object; } inline bool json_value::is_binary() const { return _type == json_type::binary; } @@ -765,12 +784,14 @@ inline json_value::operator int32_t() const { inline json_value::operator uint64_t() const { if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::ninteger ? (uint64_t)_integer : (uint64_t)_unsigned; + return _type == json_type::ninteger ? (uint64_t)_integer + : (uint64_t)_unsigned; } inline json_value::operator uint32_t() const { if (_type != json_type::ninteger && _type != json_type::nunsigned) throw json_error{"integer expected"}; - return _type == json_type::ninteger ? (uint32_t)_integer : (uint32_t)_unsigned; + return _type == json_type::ninteger ? (uint32_t)_integer + : (uint32_t)_unsigned; } inline json_value::operator double() const { if (_type != json_type::nfloat && _type != json_type::ninteger && @@ -779,7 +800,7 @@ inline json_value::operator double() const { return _type == json_type::nfloat ? (double)_real : _type == json_type::ninteger ? (double)_integer - : (double)_unsigned; + : (double)_unsigned; } inline json_value::operator float() const { if (_type != json_type::nfloat && _type != json_type::ninteger && @@ -787,7 +808,8 @@ inline json_value::operator float() const { throw json_error{"number expected"}; return _type == json_type::nfloat ? (float)_real - : _type == json_type::ninteger ? (float)_integer : (float)_unsigned; + : _type == json_type::ninteger ? (float)_integer + : (float)_unsigned; } inline json_value::operator bool() const { if (_type != json_type::boolean) throw json_error{"boolean expected"}; @@ -1181,6 +1203,7 @@ inline void to_json(json_value& json, uint32_t value) { json = value; } inline void to_json(json_value& json, double value) { json = value; } inline void to_json(json_value& json, float value) { json = value; } inline void to_json(json_value& json, bool value) { json = value; } +inline void to_json(json_value& json, const char* value) { json = string{value}; } inline void to_json(json_value& json, const string& value) { json = value; } template inline void to_json(json_value& json, const vector& value) { @@ -1214,7 +1237,7 @@ inline void to_json(json_value& json, T value) { namespace yocto { // Convenience function -template +template inline json_value to_schema(const T& value, const string& descr) { auto schema = json_value{}; to_schema(schema, value, descr); @@ -1223,68 +1246,77 @@ inline json_value to_schema(const T& value, const string& descr) { // Conversion to json schema from values inline void to_schema(json_value& schema, int64_t value, const string& descr) { - schema["type"] = "integer"; + schema["type"] = "integer"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, int32_t value, const string& descr) { - schema["type"] = "integer"; + schema["type"] = "integer"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, uint64_t value, const string& descr) { - schema["type"] = "integer"; + schema["type"] = "integer"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, uint32_t value, const string& descr) { - schema["type"] = "integer"; + schema["type"] = "integer"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, double value, const string& descr) { - schema["type"] = "number"; + schema["type"] = "number"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, float value, const string& descr) { - schema["type"] = "number"; + schema["type"] = "number"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } inline void to_schema(json_value& schema, bool value, const string& descr) { - schema["type"] = "number"; + schema["type"] = "boolean"; + schema["description"] = descr; + schema["default"] = value; +} +inline void to_schema( + json_value& schema, const char* value, const string& descr) { + schema["type"] = "string"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } -inline void to_schema(json_value& schema, const string& value, const string& descr) { - schema["type"] = "string"; +inline void to_schema( + json_value& schema, const string& value, const string& descr) { + schema["type"] = "string"; schema["description"] = descr; - schema["default"] = value; + schema["default"] = value; } template -inline void to_schema(json_value& schema, const vector& value, const string& descr) { - schema["type"] = "array"; +inline void to_schema( + json_value& schema, const vector& value, const string& descr) { + schema["type"] = "array"; schema["description"] = descr; - schema["default"] = value; - if(value.empty()) schema["items"] = to_schema(T{}, descr); + schema["default"] = value; + if (value.empty()) schema["items"] = to_schema(T{}, descr); } template -inline void to_schema(json_value& schema, const array& value, const string& descr) { - schema["type"] = "array"; +inline void to_schema( + json_value& schema, const array& value, const string& descr) { + schema["type"] = "array"; schema["description"] = descr; - schema["default"] = value; - schema["minSize"] = N; - schema["maxSize"] = N; - for(auto& item : value) schema["items"].push_back(to_schema(item, descr)); + schema["default"] = value; + schema["minSize"] = N; + schema["maxSize"] = N; + for (auto& item : value) schema["items"].push_back(to_schema(item, descr)); } template inline void to_schema(json_value& schema, T value, const string& descr) { - schema["type"] = "string"; + schema["type"] = "string"; schema["description"] = descr; - auto& labels = json_enum_labels(value); - for(auto& [value_, label] : labels) { - if(value == value_) schema["default"] = label; + auto& labels = json_enum_labels(value); + for (auto& [value_, label] : labels) { + if (value == value_) schema["default"] = label; schema["enum"].push_back(label); } } @@ -1296,18 +1328,66 @@ inline json_value to_schema_object(const string& descr) { return schema; } inline void to_schema_object(json_value& schema, const string& descr) { - schema["type"] = "object"; + schema["type"] = "object"; schema["description"] = descr; - schema["properties"] = json_value::object(); + schema["properties"] = json_value::object(); } inline json_value& get_schema_properties(json_value& schema) { if (schema.is_null()) to_schema_object(schema, ""); - if (schema.contains("properties")) schema["properties"] = json_value::object(); + if (!schema.contains("properties")) + schema["properties"] = json_value::object(); return schema.at("properties"); } inline const json_value& get_schema_properties(const json_value& schema) { return schema.at("properties"); } +inline json_value& get_schema_required(json_value& schema) { + if (schema.is_null()) to_schema_object(schema, ""); + if (!schema.contains("required")) schema["required"] = json_value::array(); + return schema.at("required"); +} +inline const json_value& get_schema_required(const json_value& schema) { + return schema.at("required"); +} +inline json_value& get_schema_positional(json_value& schema) { + if (schema.is_null()) to_schema_object(schema, ""); + if (!schema.contains("cli_positional")) + schema["cli_positional"] = json_value::array(); + return schema.at("cli_positional"); +} +inline const json_value& get_schema_positional(const json_value& schema) { + return schema.at("cli_positional"); +} +inline json_value& get_schema_command(json_value& schema) { + if (schema.is_null()) to_schema_object(schema, ""); + if (!schema.contains("cli_command")) schema["cli_command"] = string{}; + return schema.at("cli_command"); +} +inline const json_value& get_schema_command(const json_value& schema) { + return schema.at("cli_command"); +} + +} // namespace yocto + +// ----------------------------------------------------------------------------- +// COMMAND LINE INTERFACE +// ----------------------------------------------------------------------------- +namespace yocto { + +// Parse the command line for a type that supports it +template +inline void parse_cli( + T& value, const string& usage, const vector& args) { + auto json = to_json(value); + auto schema = to_schema(value, usage); + parse_cli(json, schema, args); + value = from_json(json); +} +template +inline void parse_cli( + T& value, const string& usage, int argc, const char** argv) { + return parse_cli(value, usage, vector{argv, argv + argc}); +} } // namespace yocto @@ -1319,7 +1399,7 @@ namespace yocto { // Get view from value inline json_tview get_root(json_tree& json) { return {&json, 0}; } inline json_ctview get_croot(json_tree& json) { return {&json, 0}; } -inline bool set_error(json_ctview json, string_view error) { +inline bool set_error(json_ctview json, string_view error) { if (!is_valid(json)) return false; set_error(*json.root, string{error} + " at " + compute_path(json)); return false; @@ -1574,7 +1654,7 @@ inline bool get_integer(json_ctview json, int64_t& value) { if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); value = (jst == json_type::ninteger) ? (int64_t)jsv._integer - : (int64_t)jsv._unsigned; + : (int64_t)jsv._unsigned; return true; } inline bool get_integer(json_ctview json, uint64_t& value) { @@ -1584,7 +1664,7 @@ inline bool get_integer(json_ctview json, uint64_t& value) { if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); value = (jst == json_type::ninteger) ? (uint64_t)jsv._integer - : (uint64_t)jsv._unsigned; + : (uint64_t)jsv._unsigned; return true; } inline bool get_number(json_ctview json, double& value) { @@ -1597,7 +1677,7 @@ inline bool get_number(json_ctview json, double& value) { value = (jst == json_type::nfloat) ? (double)jsv._real : (jst == json_type::ninteger) ? (double)jsv._integer - : (double)jsv._unsigned; + : (double)jsv._unsigned; return true; } inline bool get_integer(json_ctview json, int32_t& value) { @@ -1607,7 +1687,7 @@ inline bool get_integer(json_ctview json, int32_t& value) { if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); value = (jst == json_type::ninteger) ? (int32_t)jsv._integer - : (int32_t)jsv._unsigned; + : (int32_t)jsv._unsigned; return true; } inline bool get_integer(json_ctview json, uint32_t& value) { @@ -1617,7 +1697,7 @@ inline bool get_integer(json_ctview json, uint32_t& value) { if (jst != json_type::ninteger && jst != json_type::nunsigned) return set_error(json, "integer expected"); value = (jst == json_type::ninteger) ? (uint32_t)jsv._integer - : (uint32_t)jsv._unsigned; + : (uint32_t)jsv._unsigned; return true; } inline bool get_number(json_ctview json, float& value) { @@ -1630,7 +1710,7 @@ inline bool get_number(json_ctview json, float& value) { value = (jst == json_type::nfloat) ? (float)jsv._real : (jst == json_type::ninteger) ? (float)jsv._integer - : (float)jsv._unsigned; + : (float)jsv._unsigned; return true; } @@ -1672,7 +1752,7 @@ inline size_t get_size(json_ctview json); inline auto iterate_array(json_tview json) { struct iterator { json_tview json; - bool operator!=(const iterator& other) { + bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { @@ -1689,8 +1769,8 @@ inline auto iterate_array(json_tview json) { struct iterator_wrapper { json_tview begin_; json_tview end_; - iterator begin() { return {begin_}; } - iterator end() { return {end_}; } + iterator begin() { return {begin_}; } + iterator end() { return {end_}; } }; if (!is_valid(json)) return iterator_wrapper{{json.root}, {json.root}}; auto& jst = _get_type(json); @@ -1705,7 +1785,7 @@ inline auto iterate_array(json_tview json) { inline auto iterate_array(json_ctview json) { struct iterator { json_ctview json; - bool operator!=(const iterator& other) { + bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { @@ -1722,8 +1802,8 @@ inline auto iterate_array(json_ctview json) { struct iterator_wrapper { json_ctview begin_; json_ctview end_; - iterator begin() { return {begin_}; } - iterator end() { return {end_}; } + iterator begin() { return {begin_}; } + iterator end() { return {end_}; } }; if (!is_valid(json)) return iterator_wrapper{{json.root}, {json.root}}; auto& jst = _get_type(json); @@ -1822,7 +1902,7 @@ inline json_tview append_element(json_tview json) { inline auto iterate_object(json_tview json) { struct iterator { json_tview json; - bool operator!=(const iterator& other) { + bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { @@ -1841,8 +1921,8 @@ inline auto iterate_object(json_tview json) { struct iterator_wrapper { json_tview begin_; json_tview end_; - iterator begin() { return {begin_}; } - iterator end() { return {end_}; } + iterator begin() { return {begin_}; } + iterator end() { return {end_}; } }; if (!is_valid(json)) return iterator_wrapper{{json.root}, {json.root}}; auto& jst = _get_type(json); @@ -1857,7 +1937,7 @@ inline auto iterate_object(json_tview json) { inline auto iterate_object(json_ctview json) { struct iterator { json_ctview json; - bool operator!=(const iterator& other) { + bool operator!=(const iterator& other) { return is_valid(json) && json.index != other.json.index; } iterator& operator++() { @@ -1876,8 +1956,8 @@ inline auto iterate_object(json_ctview json) { struct iterator_wrapper { json_ctview begin_; json_ctview end_; - iterator begin() { return {begin_}; } - iterator end() { return {end_}; } + iterator begin() { return {begin_}; } + iterator end() { return {end_}; } }; if (!is_valid(json)) return iterator_wrapper{{json.root}, {json.root}}; auto& jst = _get_type(json); From ca3c91cc772d66784584670dc75b804514b185ba Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 16:26:35 +0100 Subject: [PATCH 06/12] updated --- libs/yocto/yocto_json.cpp | 2 +- libs/yocto/yocto_json.h | 7 +- libs/yocto/yocto_sceneio.cpp | 2 +- libs/yocto/yocto_trace.cpp | 140 ++++++++++++++++++----------------- libs/yocto/yocto_trace.h | 3 +- 5 files changed, 81 insertions(+), 73 deletions(-) diff --git a/libs/yocto/yocto_json.cpp b/libs/yocto/yocto_json.cpp index 8209be6fa..b6a1221ce 100644 --- a/libs/yocto/yocto_json.cpp +++ b/libs/yocto/yocto_json.cpp @@ -918,7 +918,7 @@ bool load_json(const string& filename, json_tree& json, string& error) { // stack json_tview root; std::vector stack = {}; - std::string current_key; + std::string current_key; explicit sax_handler(json_tview root_) : root{root_}, stack{root_} {} // get current value diff --git a/libs/yocto/yocto_json.h b/libs/yocto/yocto_json.h index d15742684..767bd8bf0 100644 --- a/libs/yocto/yocto_json.h +++ b/libs/yocto/yocto_json.h @@ -325,7 +325,8 @@ inline void to_schema(json_value& schema, uint32_t value, const string& descr); inline void to_schema(json_value& schema, double value, const string& descr); inline void to_schema(json_value& schema, float value, const string& descr); inline void to_schema(json_value& schema, bool value, const string& descr); -inline void to_schema(json_value& schema, const char* value, const string& descr); +inline void to_schema( + json_value& schema, const char* value, const string& descr); inline void to_schema( json_value& schema, const string& value, const string& descr); template @@ -1203,7 +1204,9 @@ inline void to_json(json_value& json, uint32_t value) { json = value; } inline void to_json(json_value& json, double value) { json = value; } inline void to_json(json_value& json, float value) { json = value; } inline void to_json(json_value& json, bool value) { json = value; } -inline void to_json(json_value& json, const char* value) { json = string{value}; } +inline void to_json(json_value& json, const char* value) { + json = string{value}; +} inline void to_json(json_value& json, const string& value) { json = value; } template inline void to_json(json_value& json, const vector& value) { diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index f81cb9e52..da7c28b0c 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1313,7 +1313,7 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene, auto ply_instance_map = unordered_map{{"", nullptr}}; auto instance_ply = unordered_map{}; auto get_ply_instances = [&ply_instances, &ply_instance_map, &instance_ply]( - json_ctview js, + json_ctview js, sceneio_instance* instance) -> bool { auto name = ""s; if (!get_value(js, name)) return false; diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index bb05add95..523305e08 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -1958,92 +1958,96 @@ void to_json(json_value& json, const trace_params& value) { } void from_json(const json_value& json, trace_params& value) { static auto default_ = trace_params{}; - value.resolution = json.value("resolution", default_.resolution); - value.sampler = json.value("sampler", default_.sampler); - value.falsecolor = json.value("falsecolor", default_.falsecolor); - value.samples = json.value("samples", default_.samples); - value.bounces = json.value("bounces", default_.bounces); - value.clamp = json.value("clamp", default_.clamp); - value.nocaustics = json.value("nocaustics", default_.nocaustics); - value.envhidden = json.value("envhidden", default_.envhidden); - value.tentfilter = json.value("tentfilter", default_.tentfilter); - value.seed = json.value("seed", default_.seed); - value.bvh = json.value("bvh", default_.bvh); - value.noparallel = json.value("noparallel", default_.noparallel); - value.pratio = json.value("pratio", default_.pratio); - value.exposure = json.value("exposure", default_.exposure); -} -void to_schema(json_value& schema, const trace_params& value, const string& descr) { - schema = to_schema_object(descr); - auto& properties = get_schema_properties(schema); + value.resolution = json.value("resolution", default_.resolution); + value.sampler = json.value("sampler", default_.sampler); + value.falsecolor = json.value("falsecolor", default_.falsecolor); + value.samples = json.value("samples", default_.samples); + value.bounces = json.value("bounces", default_.bounces); + value.clamp = json.value("clamp", default_.clamp); + value.nocaustics = json.value("nocaustics", default_.nocaustics); + value.envhidden = json.value("envhidden", default_.envhidden); + value.tentfilter = json.value("tentfilter", default_.tentfilter); + value.seed = json.value("seed", default_.seed); + value.bvh = json.value("bvh", default_.bvh); + value.noparallel = json.value("noparallel", default_.noparallel); + value.pratio = json.value("pratio", default_.pratio); + value.exposure = json.value("exposure", default_.exposure); +} +void to_schema( + json_value& schema, const trace_params& value, const string& descr) { + schema = to_schema_object(descr); + auto& properties = get_schema_properties(schema); properties["resolution"] = to_schema(value.resolution, "Image resolution."); - properties["sampler"] = to_schema(value.sampler, "Sampler type."); + properties["sampler"] = to_schema(value.sampler, "Sampler type."); properties["falsecolor"] = to_schema(value.falsecolor, "False color type."); - properties["samples"] = to_schema(value.samples, "Number of samples."); - properties["bounces"] = to_schema(value.bounces, "Number of bounces."); - properties["clamp"] = to_schema(value.clamp, "Clamp value."); + properties["samples"] = to_schema(value.samples, "Number of samples."); + properties["bounces"] = to_schema(value.bounces, "Number of bounces."); + properties["clamp"] = to_schema(value.clamp, "Clamp value."); properties["nocaustics"] = to_schema(value.nocaustics, "Disable caustics."); - properties["envhidden"] = to_schema(value.envhidden, "Hide environment."); + properties["envhidden"] = to_schema(value.envhidden, "Hide environment."); properties["tentfilter"] = to_schema(value.tentfilter, "Filter image."); - properties["seed"] = to_schema(value.seed, "Random seed."); - properties["bvh"] = to_schema(value.bvh, "Bvh type."); + properties["seed"] = to_schema(value.seed, "Random seed."); + properties["bvh"] = to_schema(value.bvh, "Bvh type."); properties["noparallel"] = to_schema(value.noparallel, "Disable threading."); - properties["pratio"] = to_schema(value.pratio, "Preview ratio."); - properties["exposure"] = to_schema(value.exposure, "Image exposure."); + properties["pratio"] = to_schema(value.pratio, "Preview ratio."); + properties["exposure"] = to_schema(value.exposure, "Image exposure."); } // Json enum conventions const vector>& json_enum_labels(trace_bvh_type) { -static const auto trace_bvh_labels = vector>{ - {trace_bvh_type::default_, "default"}, - {trace_bvh_type::highquality, "highquality"}, - {trace_bvh_type::middle, "middle"}, - {trace_bvh_type::balanced, "balanced"}, + static const auto trace_bvh_labels = vector>{ + {trace_bvh_type::default_, "default"}, + {trace_bvh_type::highquality, "highquality"}, + {trace_bvh_type::middle, "middle"}, + {trace_bvh_type::balanced, "balanced"}, #ifdef YOCTO_EMBREE - {trace_bvh_type::embree_default, "embree-default"}, - {trace_bvh_type::embree_highquality, "embree-highquality"}, - {trace_bvh_type::embree_compact, "embree-compact"}, + {trace_bvh_type::embree_default, "embree-default"}, + {trace_bvh_type::embree_highquality, "embree-highquality"}, + {trace_bvh_type::embree_compact, "embree-compact"}, #endif -}; -return trace_bvh_labels;} + }; + return trace_bvh_labels; +} const vector>& json_enum_labels( trace_falsecolor_type) { -static const auto trace_falsecolor_labels = - vector>{ - {trace_falsecolor_type::position, "position"}, - {trace_falsecolor_type::normal, "normal"}, - {trace_falsecolor_type::frontfacing, "frontfacing"}, - {trace_falsecolor_type::gnormal, "gnormal"}, - {trace_falsecolor_type::gfrontfacing, "gfrontfacing"}, - {trace_falsecolor_type::texcoord, "texcoord"}, - {trace_falsecolor_type::color, "color"}, - {trace_falsecolor_type::emission, "emission"}, - {trace_falsecolor_type::diffuse, "diffuse"}, - {trace_falsecolor_type::specular, "specular"}, - {trace_falsecolor_type::coat, "coat"}, - {trace_falsecolor_type::metal, "metal"}, - {trace_falsecolor_type::transmission, "transmission"}, - {trace_falsecolor_type::translucency, "translucency"}, - {trace_falsecolor_type::refraction, "refraction"}, - {trace_falsecolor_type::roughness, "roughness"}, - {trace_falsecolor_type::opacity, "opacity"}, - {trace_falsecolor_type::ior, "ior"}, - {trace_falsecolor_type::instance, "instance"}, - {trace_falsecolor_type::element, "element"}, - {trace_falsecolor_type::highlight, "highlight"}}; - return trace_falsecolor_labels; + static const auto trace_falsecolor_labels = + vector>{ + {trace_falsecolor_type::position, "position"}, + {trace_falsecolor_type::normal, "normal"}, + {trace_falsecolor_type::frontfacing, "frontfacing"}, + {trace_falsecolor_type::gnormal, "gnormal"}, + {trace_falsecolor_type::gfrontfacing, "gfrontfacing"}, + {trace_falsecolor_type::texcoord, "texcoord"}, + {trace_falsecolor_type::color, "color"}, + {trace_falsecolor_type::emission, "emission"}, + {trace_falsecolor_type::diffuse, "diffuse"}, + {trace_falsecolor_type::specular, "specular"}, + {trace_falsecolor_type::coat, "coat"}, + {trace_falsecolor_type::metal, "metal"}, + {trace_falsecolor_type::transmission, "transmission"}, + {trace_falsecolor_type::translucency, "translucency"}, + {trace_falsecolor_type::refraction, "refraction"}, + {trace_falsecolor_type::roughness, "roughness"}, + {trace_falsecolor_type::opacity, "opacity"}, + {trace_falsecolor_type::ior, "ior"}, + {trace_falsecolor_type::instance, "instance"}, + {trace_falsecolor_type::element, "element"}, + {trace_falsecolor_type::highlight, "highlight"}}; + return trace_falsecolor_labels; } const vector>& json_enum_labels( trace_sampler_type) { - static const auto trace_sampler_labels = vector>{ - {trace_sampler_type::path, "path"}, {trace_sampler_type::naive, "naive"}, - {trace_sampler_type::eyelight, "eyelight"}, - {trace_sampler_type::falsecolor, "falsecolor"}, - {trace_sampler_type::albedo, "albedo"}, - {trace_sampler_type::normal, "normal"}}; - return trace_sampler_labels; + static const auto trace_sampler_labels = + vector>{ + {trace_sampler_type::path, "path"}, + {trace_sampler_type::naive, "naive"}, + {trace_sampler_type::eyelight, "eyelight"}, + {trace_sampler_type::falsecolor, "falsecolor"}, + {trace_sampler_type::albedo, "albedo"}, + {trace_sampler_type::normal, "normal"}}; + return trace_sampler_labels; } } // namespace yocto diff --git a/libs/yocto/yocto_trace.h b/libs/yocto/yocto_trace.h index 034d314cc..5ca9619fc 100644 --- a/libs/yocto/yocto_trace.h +++ b/libs/yocto/yocto_trace.h @@ -553,7 +553,8 @@ namespace yocto { struct json_value; void to_json(json_value& json, const trace_params& value); void from_json(const json_value& json, trace_params& value); -void to_schema(json_value& json, const trace_params& value, const string& descr); +void to_schema( + json_value& json, const trace_params& value, const string& descr); // Json enum conventions const vector>& json_enum_labels(trace_bvh_type); From 4cb9436f5b92eb5af1c1c6d7d9afe86dc30a2acb Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 16:32:54 +0100 Subject: [PATCH 07/12] updated --- apps/ytrace/ytrace.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/ytrace/ytrace.cpp b/apps/ytrace/ytrace.cpp index b0a659ce3..43017914e 100644 --- a/apps/ytrace/ytrace.cpp +++ b/apps/ytrace/ytrace.cpp @@ -386,6 +386,9 @@ int run_view(const view_params& params) { // app->display[ij] = tonemap(app->render[ij], app->exposure); }); + // show rendering params + set_params(viewer, "render", to_json(params)); + // run view run_view(viewer); From 80e2a87c0376af238710c9fe0dd539df9b4b56ae Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 17:08:48 +0100 Subject: [PATCH 08/12] updated --- libs/yocto_gui/yocto_imageviewer.cpp | 2 +- libs/yocto_gui/yocto_imgui.cpp | 103 +++++++++++++++++++++------ libs/yocto_gui/yocto_imgui.h | 5 +- 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/libs/yocto_gui/yocto_imageviewer.cpp b/libs/yocto_gui/yocto_imageviewer.cpp index ea72eff29..be41c6d73 100644 --- a/libs/yocto_gui/yocto_imageviewer.cpp +++ b/libs/yocto_gui/yocto_imageviewer.cpp @@ -247,7 +247,7 @@ void draw_widgets( } } if (!state->selected->params.empty()) { - draw_params(win, "params", state->selected->params); + draw_params(win, "params", state->selected->params, true); } } diff --git a/libs/yocto_gui/yocto_imgui.cpp b/libs/yocto_gui/yocto_imgui.cpp index bb67f1bf7..4ce415b93 100644 --- a/libs/yocto_gui/yocto_imgui.cpp +++ b/libs/yocto_gui/yocto_imgui.cpp @@ -964,10 +964,10 @@ void draw_log(gui_window* win) { } template -static bool draw_dragger_params( - gui_window* win, const char* lbl, json_value& value) { +static bool draw_number_param( + gui_window* win, const char* lbl, json_value& value, bool readonly) { auto gvalue = value.get(); - if (draw_dragger(win, lbl, gvalue)) { + if (draw_dragger(win, lbl, gvalue) && !readonly) { value = gvalue; return true; } else { @@ -975,10 +975,10 @@ static bool draw_dragger_params( } } -static bool draw_checkbox_params( - gui_window* win, const char* lbl, json_value& value) { +static bool draw_boolean_param( + gui_window* win, const char* lbl, json_value& value, bool readonly) { auto gvalue = value.get(); - if (draw_checkbox(win, lbl, gvalue)) { + if (draw_checkbox(win, lbl, gvalue) && !readonly) { value = gvalue; return true; } else { @@ -986,10 +986,10 @@ static bool draw_checkbox_params( } } -static bool draw_textinput_params( - gui_window* win, const char* lbl, json_value& value) { +static bool draw_string_param( + gui_window* win, const char* lbl, json_value& value, bool readonly) { auto gvalue = value.get(); - if (draw_textinput(win, lbl, gvalue)) { + if (draw_textinput(win, lbl, gvalue) && !readonly) { value = gvalue; return true; } else { @@ -997,15 +997,16 @@ static bool draw_textinput_params( } } -bool draw_params(gui_window* win, const char* lbl, json_value& value) { +bool draw_params( + gui_window* win, const char* lbl, json_value& value, bool readonly) { if (value.is_integer()) { - return draw_dragger_params(win, lbl, value); + return draw_number_param(win, lbl, value, readonly); } else if (value.is_number()) { - return draw_dragger_params(win, lbl, value); + return draw_number_param(win, lbl, value, readonly); } else if (value.is_boolean()) { - return draw_checkbox_params(win, lbl, value); + return draw_boolean_param(win, lbl, value, readonly); } else if (value.is_string()) { - return draw_textinput_params(win, lbl, value); + return draw_string_param(win, lbl, value, readonly); } else if (value.is_array()) { if (value.size() > 4) return false; // skip auto is_integer_array = true, is_number_array = true; @@ -1016,19 +1017,19 @@ bool draw_params(gui_window* win, const char* lbl, json_value& value) { if (!is_integer_array && !is_number_array) return false; // skip if (is_integer_array) { if (value.size() == 2) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); if (value.size() == 3) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); if (value.size() == 4) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); return false; // skip } else if (is_number_array) { if (value.size() == 2) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); if (value.size() == 3) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); if (value.size() == 4) - return draw_dragger_params>(win, lbl, value); + return draw_number_param>(win, lbl, value, readonly); return false; // skip } else { return false; // skip @@ -1037,7 +1038,67 @@ bool draw_params(gui_window* win, const char* lbl, json_value& value) { if (begin_header(win, lbl)) { auto edited = 0; for (auto& [name, item] : value.items()) { - edited += (int)draw_params(win, name.c_str(), item); + edited += (int)draw_params(win, name.c_str(), item, readonly); + } + end_header(win); + return (bool)edited; + } else { + return false; + } + } else { + return false; // skip + } +} + +bool draw_params(gui_window* win, const char* lbl, json_value& value, + const json_value& schema, bool readonly) { + if (value.is_integer()) { + return draw_number_param(win, lbl, value, readonly); + } else if (value.is_number()) { + return draw_number_param(win, lbl, value, readonly); + } else if (value.is_boolean()) { + return draw_boolean_param(win, lbl, value, readonly); + } else if (value.is_string()) { + return draw_string_param(win, lbl, value, readonly); + } else if (value.is_array()) { + if (value.size() > 4) return false; // skip + auto is_integer_array = true, is_number_array = true; + for (auto& item : value) { + if (!item.is_integer()) is_integer_array = false; + if (!item.is_number()) is_number_array = false; + } + if (!is_integer_array && !is_number_array) return false; // skip + if (is_integer_array) { + if (value.size() == 2) + return draw_number_param>(win, lbl, value, readonly); + if (value.size() == 3) + return draw_number_param>(win, lbl, value, readonly); + if (value.size() == 4) + return draw_number_param>(win, lbl, value, readonly); + return false; // skip + } else if (is_number_array) { + if (value.size() == 2) + return draw_number_param>(win, lbl, value, readonly); + if (value.size() == 3) + return draw_number_param>(win, lbl, value, readonly); + if (value.size() == 4) + return draw_number_param>(win, lbl, value, readonly); + return false; // skip + } else { + return false; // skip + } + } else if (value.is_object()) { + if (begin_header(win, lbl)) { + auto edited = 0; + for (auto& [name, item] : value.items()) { + auto item_readonly = false; + if (!readonly && schema.contains("gui_readonly")) { + for (auto& readonly_name : schema.at("gui_readonly")) { + if (name == readonly_name.get()) item_readonly = true; + } + } + edited += (int)draw_params( + win, name.c_str(), item, readonly || item_readonly); } end_header(win); return (bool)edited; diff --git a/libs/yocto_gui/yocto_imgui.h b/libs/yocto_gui/yocto_imgui.h index 19594ebfa..cbb3f0b23 100644 --- a/libs/yocto_gui/yocto_imgui.h +++ b/libs/yocto_gui/yocto_imgui.h @@ -195,7 +195,10 @@ void set_close(gui_window* win, bool close); namespace yocto { struct json_value; -bool draw_params(gui_window* win, const char* title, json_value& value); +bool draw_params( + gui_window* win, const char* title, json_value& value, bool readonly); +bool draw_params(gui_window* win, const char* title, json_value& value, + const json_value& schema, bool readonly); bool begin_header(gui_window* win, const char* title); void end_header(gui_window* win); From ba8161e0e52a34dc95191687734966042ce820ab Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 17:22:08 +0100 Subject: [PATCH 09/12] updated --- apps/ytrace/ytrace.cpp | 6 ++++-- libs/yocto_gui/yocto_imageviewer.cpp | 25 ++++++++++++++++--------- libs/yocto_gui/yocto_imageviewer.h | 12 +++++++----- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/apps/ytrace/ytrace.cpp b/apps/ytrace/ytrace.cpp index 43017914e..80089e208 100644 --- a/apps/ytrace/ytrace.cpp +++ b/apps/ytrace/ytrace.cpp @@ -372,7 +372,8 @@ int run_view(const view_params& params) { trace_start( state, scene, camera, bvh, lights, params, [viewer](const string& message, int sample, int nsamples) { - set_param(viewer, "render", "sample", to_json(sample)); + set_param(viewer, "render", "sample", to_json(sample), + to_schema(sample, "Current sample")); print_progress(message, sample, nsamples); }, [viewer](const image& render, int current, int total) { @@ -387,7 +388,8 @@ int run_view(const view_params& params) { }); // show rendering params - set_params(viewer, "render", to_json(params)); + set_params( + viewer, "render", to_json(params), to_schema(params, "Render params")); // run view run_view(viewer); diff --git a/libs/yocto_gui/yocto_imageviewer.cpp b/libs/yocto_gui/yocto_imageviewer.cpp index be41c6d73..cb7817619 100644 --- a/libs/yocto_gui/yocto_imageviewer.cpp +++ b/libs/yocto_gui/yocto_imageviewer.cpp @@ -112,21 +112,26 @@ void tonemap_image( // Set params void set_param(imageview_state* state, const string& name, const string& pname, - const json_value& param) { - auto command = imageview_command{}; - command.type = imageview_command_type::param; - command.name = name; - auto params = json_value::object(); - params[pname] = param; - command.params = params; + const json_value& param, const json_value& schema) { + auto command = imageview_command{}; + command.type = imageview_command_type::param; + command.name = name; + auto params = json_value::object(); + params[pname] = param; + command.params = params; + auto pschema = json_value::object(); + auto& properties = pschema["properties"]; + properties[pname] = schema; + command.schema = pschema; state->queue.push(command); } -void set_params( - imageview_state* state, const string& name, const json_value& params) { +void set_params(imageview_state* state, const string& name, + const json_value& params, const json_value& schema) { auto command = imageview_command{}; command.type = imageview_command_type::params; command.name = name; command.params = params; + command.schema = schema; state->queue.push(command); } @@ -332,6 +337,7 @@ void update(gui_window* win, imageview_state* state, const gui_input& input) { } if (img != nullptr) { img->params.update(command.params); + img->schema.at("properties").update(command.schema.at("properties")); } } break; case imageview_command_type::params: { @@ -344,6 +350,7 @@ void update(gui_window* win, imageview_state* state, const gui_input& input) { } if (img != nullptr) { img->params = command.params; + img->schema = command.schema; } } break; case imageview_command_type::quit: { diff --git a/libs/yocto_gui/yocto_imageviewer.h b/libs/yocto_gui/yocto_imageviewer.h index 6bc70d981..9ea70dc4f 100644 --- a/libs/yocto_gui/yocto_imageviewer.h +++ b/libs/yocto_gui/yocto_imageviewer.h @@ -81,9 +81,9 @@ void close_image(imageview_state* viewer, const string& name); // Set params void set_param(imageview_state* viewer, const string& name, const string& pname, - const json_value& param); -void set_params( - imageview_state* viewer, const string& name, const json_value& params); + const json_value& param, const json_value& schema); +void set_params(imageview_state* viewer, const string& name, + const json_value& params, const json_value& schema); // Open and asycn viewer struct imageview_state; @@ -114,8 +114,9 @@ struct imageview_command { image hdr = {}; image ldr = {}; float exposure = 0; - bool filmic; - json_value params = {}; + bool filmic = false; + json_value params = {}; + json_value schema = {}; }; // Image view command queue and runner @@ -142,6 +143,7 @@ struct imageview_image { // user params json_value params = json_value::object(); + json_value schema = to_schema_object("User params."); ~imageview_image() { if (glimage) delete glimage; From f4b67317d0ec90ad1a2941bebe0e25d608db7398 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 17:37:54 +0100 Subject: [PATCH 10/12] updated --- libs/yocto_gui/yocto_imageviewer.cpp | 3 ++- libs/yocto_gui/yocto_imgui.cpp | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libs/yocto_gui/yocto_imageviewer.cpp b/libs/yocto_gui/yocto_imageviewer.cpp index cb7817619..da33ebb71 100644 --- a/libs/yocto_gui/yocto_imageviewer.cpp +++ b/libs/yocto_gui/yocto_imageviewer.cpp @@ -252,7 +252,8 @@ void draw_widgets( } } if (!state->selected->params.empty()) { - draw_params(win, "params", state->selected->params, true); + draw_params( + win, "params", state->selected->params, state->selected->schema, true); } } diff --git a/libs/yocto_gui/yocto_imgui.cpp b/libs/yocto_gui/yocto_imgui.cpp index 4ce415b93..4197e66f2 100644 --- a/libs/yocto_gui/yocto_imgui.cpp +++ b/libs/yocto_gui/yocto_imgui.cpp @@ -997,6 +997,18 @@ static bool draw_string_param( } } +static bool draw_enum_param(gui_window* win, const char* lbl, json_value& value, + bool readonly, const json_value& labels) { + auto gvalue = value.get(); + auto glabels = labels.get>(); + if (draw_combobox(win, lbl, gvalue, glabels) && !readonly) { + value = gvalue; + return true; + } else { + return false; + } +} + bool draw_params( gui_window* win, const char* lbl, json_value& value, bool readonly) { if (value.is_integer()) { @@ -1059,7 +1071,11 @@ bool draw_params(gui_window* win, const char* lbl, json_value& value, } else if (value.is_boolean()) { return draw_boolean_param(win, lbl, value, readonly); } else if (value.is_string()) { - return draw_string_param(win, lbl, value, readonly); + if (schema.contains("enum")) { + return draw_enum_param(win, lbl, value, readonly, schema.at("enum")); + } else { + return draw_string_param(win, lbl, value, readonly); + } } else if (value.is_array()) { if (value.size() > 4) return false; // skip auto is_integer_array = true, is_number_array = true; From 2181c6a8ab8a1136af932d0b2efeaf37e1ea4b28 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 17:39:20 +0100 Subject: [PATCH 11/12] updated --- libs/yocto_gui/yocto_imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/yocto_gui/yocto_imgui.cpp b/libs/yocto_gui/yocto_imgui.cpp index 4197e66f2..7e1bbcbd5 100644 --- a/libs/yocto_gui/yocto_imgui.cpp +++ b/libs/yocto_gui/yocto_imgui.cpp @@ -1113,8 +1113,8 @@ bool draw_params(gui_window* win, const char* lbl, json_value& value, if (name == readonly_name.get()) item_readonly = true; } } - edited += (int)draw_params( - win, name.c_str(), item, readonly || item_readonly); + edited += (int)draw_params(win, name.c_str(), item, + schema.at("properties").at(name), readonly || item_readonly); } end_header(win); return (bool)edited; From 3d9c00cb87ec0ba7e685bc5dfe365975b6feefc7 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 30 Dec 2020 18:01:10 +0100 Subject: [PATCH 12/12] updated --- apps/ytrace/ytrace.cpp | 8 ++++++++ libs/yocto/yocto_json.cpp | 12 ++++++++++-- libs/yocto/yocto_json.h | 11 +++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/ytrace/ytrace.cpp b/apps/ytrace/ytrace.cpp index 80089e208..88bf8ba17 100644 --- a/apps/ytrace/ytrace.cpp +++ b/apps/ytrace/ytrace.cpp @@ -201,6 +201,10 @@ void to_schema( get_schema_properties(to_schema((const trace_params&)value, ""))); get_schema_required(schema).push_back("scene"); get_schema_positional(schema).push_back("scene"); + get_schema_alternate(schema)["samples"] = "s"; + get_schema_alternate(schema)["bounces"] = "b"; + get_schema_alternate(schema)["output"] = "o"; + get_schema_alternate(schema)["tracer"] = "t"; } // convert images @@ -307,6 +311,10 @@ void to_schema( get_schema_properties(to_schema((const trace_params&)value, ""))); get_schema_required(schema).push_back("scene"); get_schema_positional(schema).push_back("scene"); + get_schema_alternate(schema)["samples"] = "s"; + get_schema_alternate(schema)["bounces"] = "b"; + get_schema_alternate(schema)["output"] = "o"; + get_schema_alternate(schema)["tracer"] = "t"; } #ifndef YOCTO_OPENGL diff --git a/libs/yocto/yocto_json.cpp b/libs/yocto/yocto_json.cpp index b6a1221ce..b1ee4dabd 100644 --- a/libs/yocto/yocto_json.cpp +++ b/libs/yocto/yocto_json.cpp @@ -516,6 +516,14 @@ static string get_cliusage( } return false; }; + auto get_alternate = [](const json_value& schema, + const string& alt) -> string { + if (!schema.contains("cli_alternate")) return ""; + if (!schema.at("cli_alternate").is_object()) return ""; + if (!schema.at("cli_alternate").contains(alt)) return ""; + if (!schema.at("cli_alternate").at(alt).is_string()) return ""; + return schema.at("cli_alternate").at(alt).get(); + }; auto message = string{}; auto usage_optional = string{}, usage_positional = string{}, @@ -528,8 +536,8 @@ static string get_cliusage( decorated_name = "--" + name; if (property.value("type", "") == "boolean") decorated_name += "/--no-" + name; - if (property.contains("cli_alt")) - decorated_name += ", -" + property.value("cli_alt", ""); + if (auto alt = get_alternate(schema, name); !alt.empty()) + decorated_name += ", -" + alt; } auto line = " " + decorated_name; if (property.value("type", "") != "boolean") { diff --git a/libs/yocto/yocto_json.h b/libs/yocto/yocto_json.h index 767bd8bf0..5bac7594a 100644 --- a/libs/yocto/yocto_json.h +++ b/libs/yocto/yocto_json.h @@ -349,6 +349,8 @@ inline json_value& get_schema_positional(json_value& schema); inline const json_value& get_schema_positional(const json_value& schema); inline json_value& get_schema_command(json_value& schema); inline const json_value& get_schema_command(const json_value& schema); +inline json_value& get_schema_alternate(json_value& schema); +inline const json_value& get_schema_alternate(const json_value& schema); // Validate a value against a schema bool validate_json( @@ -1369,6 +1371,15 @@ inline json_value& get_schema_command(json_value& schema) { inline const json_value& get_schema_command(const json_value& schema) { return schema.at("cli_command"); } +inline json_value& get_schema_alternate(json_value& schema) { + if (schema.is_null()) to_schema_object(schema, ""); + if (!schema.contains("cli_alternate")) + schema["cli_alternate"] = json_value::object(); + return schema.at("cli_alternate"); +} +inline const json_value& get_schema_alternate(const json_value& schema) { + return schema.at("cli_alternate"); +} } // namespace yocto