diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarJsonExtra.hpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarJsonExtra.hpp')
-rw-r--r-- | source/core/StarJsonExtra.hpp | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/source/core/StarJsonExtra.hpp b/source/core/StarJsonExtra.hpp new file mode 100644 index 0000000..3bf5b9c --- /dev/null +++ b/source/core/StarJsonExtra.hpp @@ -0,0 +1,384 @@ +#ifndef STAR_JSON_EXTRA_HPP +#define STAR_JSON_EXTRA_HPP + +#include "StarJson.hpp" +#include "StarPoly.hpp" +#include "StarColor.hpp" +#include "StarSet.hpp" +#include "StarWeightedPool.hpp" + +namespace Star { + +// Extra methods to parse a variety of types out of pure JSON. Throws +// JsonException if json is not of correct type or size. + +size_t jsonToSize(Json const& v); +Json jsonFromSize(size_t s); + +// Must be array of appropriate size. + +Vec2D jsonToVec2D(Json const& v); +Vec2F jsonToVec2F(Json const& v); +Json jsonFromVec2F(Vec2F const& v); +Vec2I jsonToVec2I(Json const& v); +Json jsonFromVec2I(Vec2I const& v); +Vec2U jsonToVec2U(Json const& v); +Json jsonFromVec2U(Vec2U const& v); +Vec2B jsonToVec2B(Json const& v); +Json jsonFromVec2B(Vec2B const& v); + +Vec3D jsonToVec3D(Json const& v); +Vec3F jsonToVec3F(Json const& v); +Json jsonFromVec3F(Vec3F const& v); +Vec3I jsonToVec3I(Json const& v); +Json jsonFromVec3I(Vec3I const& v); +Vec3B jsonToVec3B(Json const& v); + +Vec4B jsonToVec4B(Json const& v); +Vec4I jsonToVec4I(Json const& v); +Vec4F jsonToVec4F(Json const& v); + +// Must be array of size 4 or 2 arrays of size 2 in an array. +RectD jsonToRectD(Json const& v); +Json jsonFromRectD(RectD const& rect); +RectF jsonToRectF(Json const& v); +Json jsonFromRectF(RectF const& rect); +RectI jsonToRectI(Json const& v); +Json jsonFromRectI(RectI const& rect); +RectU jsonToRectU(Json const& v); +Json jsonFromRectU(RectU const& rect); + +// Can be a string, array of size 3 or 4 of doubles or ints. If double, range +// is 0.0 to 1.0, if int range is 0-255 +Color jsonToColor(Json const& v); +Json jsonFromColor(Color const& color); + +// HACK: Fix clockwise specified polygons in coming from JSON +template <typename Float> +Polygon<Float> fixInsideOutPoly(Polygon<Float> p); + +// Array of size 2 arrays +PolyD jsonToPolyD(Json const& v); +PolyF jsonToPolyF(Json const& v); +PolyI jsonToPolyI(Json const& v); +Json jsonFromPolyF(PolyF const& poly); + +// Expects a size 2 array of size 2 arrays +Line2F jsonToLine2F(Json const& v); +Json jsonFromLine2F(Line2F const& line); + +Mat3F jsonToMat3F(Json const& v); +Json jsonFromMat3F(Mat3F const& v); + +StringList jsonToStringList(Json const& v); +Json jsonFromStringList(List<String> const& v); +StringSet jsonToStringSet(Json const& v); +Json jsonFromStringSet(StringSet const& v); +List<float> jsonToFloatList(Json const& v); +List<int> jsonToIntList(Json const& v); +List<Vec2I> jsonToVec2IList(Json const& v); +List<Vec2U> jsonToVec2UList(Json const& v); +List<Vec2F> jsonToVec2FList(Json const& v); +List<Vec4B> jsonToVec4BList(Json const& v); +List<Color> jsonToColorList(Json const& v); + +Json weightedChoiceFromJson(Json const& source, Json const& default_); + +// Assumes that the bins parameter is an array of pairs (arrays), where the +// first element is a minimum value and the second element is the actual +// important value. Finds the pair with the highest value that is less than or +// equal to the given target, and returns the second element. +Json binnedChoiceFromJson(Json const& bins, float target, Json const& def = Json()); + +template <typename T> +WeightedPool<T> jsonToWeightedPool(Json const& source); +template <typename T, typename Converter> +WeightedPool<T> jsonToWeightedPool(Json const& source, Converter&& converter); + +template <typename T> +Json jsonFromWeightedPool(WeightedPool<T> const& pool); +template <typename T, typename Converter> +Json jsonFromWeightedPool(WeightedPool<T> const& pool, Converter&& converter); + +template <size_t Size> +Array<unsigned, Size> jsonToArrayU(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToArrayU", Size).c_str()); + + Array<unsigned, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getUInt(i); + } + + return res; +} + +template <size_t Size> +Array<size_t, Size> jsonToArrayS(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToArrayS", Size).c_str()); + + Array<size_t, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getUInt(i); + } + + return res; +} + +template <size_t Size> +Array<int, Size> jsonToArrayI(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToArrayI", Size).c_str()); + + Array<int, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getInt(i); + } + + return res; +} + +template <size_t Size> +Array<float, Size> jsonToArrayF(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToArrayF", Size).c_str()); + + Array<float, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getFloat(i); + } + + return res; +} + +template <size_t Size> +Array<double, Size> jsonToArrayD(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToArrayD", Size).c_str()); + + Array<double, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getDouble(i); + } + + return res; +} + +template <size_t Size> +Array<String, Size> jsonToStringArray(Json const& v) { + if (v.size() != Size) + throw JsonException(strf("Json array not of size %d in jsonToStringArray", Size).c_str()); + + Array<String, Size> res; + for (size_t i = 0; i < Size; i++) { + res[i] = v.getString(i); + } + + return res; +} + +template <typename Value> +List<Value> jsonToList(Json const& v) { + return jsonToList<Value>(v, construct<Value>()); +} + +template <typename Value, typename Converter> +List<Value> jsonToList(Json const& v, Converter&& valueConvert) { + if (v.type() != Json::Type::Array) + throw JsonException("Json type is not a array in jsonToList"); + + List<Value> res; + for (auto const& entry : v.iterateArray()) + res.push_back(valueConvert(entry)); + + return res; +} + +template <typename Value> +Json jsonFromList(List<Value> const& list) { + return jsonFromList<Value>(list, construct<Json>()); +} + +template <typename Value, typename Converter> +Json jsonFromList(List<Value> const& list, Converter&& valueConvert) { + JsonArray res; + for (auto const& entry : list) + res.push_back(valueConvert(entry)); + + return res; +} + +template <typename Value> +Set<Value> jsonToSet(Json const& v) { + return jsonToSet<Value>(v, construct<Value>()); +} + +template <typename Value, typename Converter> +Set<Value> jsonToSet(Json const& v, Converter&& valueConvert) { + if (v.type() != Json::Type::Array) + throw JsonException("Json type is not an array in jsonToSet"); + + Set<Value> res; + for (auto const& entry : v.iterateArray()) + res.add(valueConvert(entry)); + + return res; +} + +template <typename Value> +Json jsonFromSet(Set<Value> const& Set) { + return jsonFromSet<Value>(Set, construct<Json>()); +} + +template <typename Value, typename Converter> +Json jsonFromSet(Set<Value> const& Set, Converter&& valueConvert) { + JsonArray res; + for (auto entry : Set) + res.push_back(valueConvert(entry)); + + return res; +} + +template <typename MapType, typename KeyConverter, typename ValueConverter> +MapType jsonToMapKV(Json const& v, KeyConverter&& keyConvert, ValueConverter&& valueConvert) { + if (v.type() != Json::Type::Object) + throw JsonException("Json type is not an object in jsonToMap"); + + MapType res; + for (auto const& pair : v.iterateObject()) + res.add(keyConvert(pair.first), valueConvert(pair.second)); + + return res; +} + +template <typename MapType, typename KeyConverter> +MapType jsonToMapK(Json const& v, KeyConverter&& keyConvert) { + return jsonToMapKV<MapType>(v, forward<KeyConverter>(keyConvert), construct<typename MapType::mapped_type>()); +} + +template <typename MapType, typename ValueConverter> +MapType jsonToMapV(Json const& v, ValueConverter&& valueConvert) { + return jsonToMapKV<MapType>(v, construct<typename MapType::key_type>(), forward<ValueConverter>(valueConvert)); +} + +template <typename MapType> +MapType jsonToMap(Json const& v) { + return jsonToMapKV<MapType>(v, construct<typename MapType::key_type>(), construct<typename MapType::mapped_type>()); +} + +template <typename MapType, typename KeyConverter, typename ValueConverter> +Json jsonFromMapKV(MapType const& map, KeyConverter&& keyConvert, ValueConverter&& valueConvert) { + JsonObject res; + for (auto pair : map) + res[keyConvert(pair.first)] = valueConvert(pair.second); + + return res; +} + +template <typename MapType, typename KeyConverter> +Json jsonFromMapK(MapType const& map, KeyConverter&& keyConvert) { + return jsonFromMapKV<MapType>(map, forward<KeyConverter>(keyConvert), construct<Json>()); +} + +template <typename MapType, typename ValueConverter> +Json jsonFromMapV(MapType const& map, ValueConverter&& valueConvert) { + return jsonFromMapKV<MapType>(map, construct<String>(), forward<ValueConverter>(valueConvert)); +} + +template <typename MapType> +Json jsonFromMap(MapType const& map) { + return jsonFromMapKV<MapType>(map, construct<String>(), construct<Json>()); +} + +template <typename T, typename Converter> +Json jsonFromMaybe(Maybe<T> const& m, Converter&& converter) { + return m.apply(converter).value(); +} + +template <typename T> +Json jsonFromMaybe(Maybe<T> const& m) { + return jsonFromMaybe(m, construct<Json>()); +} + +template <typename T, typename Converter> +Maybe<T> jsonToMaybe(Json v, Converter&& converter) { + if (v.isNull()) + return {}; + return converter(v); +} + +template <typename T> +Maybe<T> jsonToMaybe(Json const& v) { + return jsonToMaybe<T>(v, construct<T>()); +} + +template <typename T> +WeightedPool<T> jsonToWeightedPool(Json const& source) { + return jsonToWeightedPool<T>(source, construct<T>()); +} + +template <typename T, typename Converter> +WeightedPool<T> jsonToWeightedPool(Json const& source, Converter&& converter) { + WeightedPool<T> res; + if (source.isNull()) + return res; + for (auto entry : source.iterateArray()) { + if (entry.isType(Json::Type::Array)) + res.add(entry.get(0).toDouble(), converter(entry.get(1))); + else + res.add(entry.getDouble("weight"), converter(entry.get("item"))); + } + + return res; +} + +template <typename T> +Json jsonFromWeightedPool(WeightedPool<T> const& pool) { + return jsonFromWeightedPool<T>(pool, construct<Json>()); +} + +template <typename T, typename Converter> +Json jsonFromWeightedPool(WeightedPool<T> const& pool, Converter&& converter) { + JsonArray res; + for (auto const& pair : pool.items()) { + res.append(JsonObject{ + {"weight", pair.first}, {"item", converter(pair.second)}, + }); + } + return res; +} + +template <> +WeightedPool<int> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<unsigned> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<float> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<double> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<String> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<JsonArray> jsonToWeightedPool(Json const& source); + +template <> +WeightedPool<JsonObject> jsonToWeightedPool(Json const& source); + +template <typename Float> +Polygon<Float> fixInsideOutPoly(Polygon<Float> p) { + if (p.sides() > 2) { + if ((p.side(1).diff() ^ p.side(0).diff()) > 0) + reverse(p.vertexes()); + } + return p; +} + +} + +#endif |