TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
2 / 2
100.0%
Branches:
-
-%
Functions:
1 / 1
100.0%

config/json.h
Line Branch Exec Source
1 /// @file
2 /// @brief Configurations as JSON: parsing, loading, writing, catalog and schema.
3 #pragma once
4
5 #include "terraingen/config/config.h"
6
7 #include <filesystem>
8 #include <stdexcept>
9 #include <string>
10 #include <string_view>
11
12 namespace terraingen {
13
14 /// A problem with a configuration, located by the JSON path of the offending value, such as
15 /// "layers[1].density.age_gyr" or "layers[0].stack[1].octaves".
16 class ConfigError : public std::runtime_error {
17 public:
18 /// An error at a path; the message is "path: message", or the message alone at the root.
19 /// @param path The JSON path of the value; empty for the document as a whole.
20 ConfigError(std::string path, const std::string& message);
21
22 /// The JSON path of the value; empty for the document as a whole.
23 226 const std::string& Path() const {
24 226 return path_;
25 }
26
27 private:
28 std::string path_;
29 };
30
31 /// Reads a configuration from JSON text.
32 ///
33 /// {"schema_version": 1,
34 /// "layers": [{"type": "noise", "stack": [{"wavelength": 500, "amplitude": 50}]},
35 /// {"type": "craters",
36 /// "density": {"type": "production_surface", "age_gyr": 3.5},
37 /// "rim_smoothing": {"sigma_radii": 0.05}}],
38 /// "outputs": [{"type": "heightmap", "path": "terrain.tif",
39 /// "region": {"width": 513, "height": 513, "pixel_size": 2}}]}
40 ///
41 /// Keys are snake_case versions of the C++ fields; bodies, bases, layers, outputs and models are
42 /// objects with a "type". Omitted keys take their defaults and omitted lists are empty.
43 /// @throws ConfigError for malformed JSON, a missing or unsupported "schema_version", an unknown
44 /// key, or a value of the wrong type.
45 TerrainConfig ParseConfig(std::string_view json);
46
47 /// `ParseConfig` on the contents of a file.
48 /// @throws ConfigError as `ParseConfig`, or when the file cannot be read.
49 TerrainConfig LoadConfig(const std::filesystem::path& path);
50
51 /// A configuration as JSON with every value written out but an unset base and albedo; parsing it
52 /// gives back an equal configuration.
53 std::string ConfigToJson(const TerrainConfig& config, int indent = 2);
54
55 /// A reference of every configuration type with its defaults, as JSON.
56 ///
57 /// The lists "body", "base", "layers" and "outputs" hold each type of their kind,
58 /// "albedo" the albedo, and "models" one noise layer and every density, ages, degradation,
59 /// profile, boulder size, region shape, albedo source and albedo layer type. Each entry parses
60 /// where its kind belongs in a configuration.
61 std::string ConfigCatalog(int indent = 2);
62
63 /// The structure of a configuration as JSON, for editors: what each field holds and its
64 /// default, from the same field lists the parser reads.
65 ///
66 /// The document has "schema_version", "root" (the configuration object) and "definitions", each
67 /// struct and choice described once by id ("d0", "d1", ...) and referred to as
68 /// {"kind": "ref", "ref": id}. A schema has a "kind":
69 /// - "number", "integer" ("minimum" 0 for counts, "fixed" for the schema version), "boolean",
70 /// "string";
71 /// - "enum" with its "choices" and their "descriptions";
72 /// - "optional" and "array" with the schema "of" what they hold and that thing's "default";
73 /// - "object" with its "fields", each {"name", "description", "unit", "schema", "default"}, and for
74 /// a bounded number (or each number of a list) "minimum" and "exclusive_minimum", "maximum"
75 /// and "exclusive_maximum";
76 /// - "choice" with its "alternatives", each {"type", "description", "fields", "default"}.
77 std::string ConfigSchema(int indent = 2);
78
79 /// A layer's JSON "type", with the type of the layer inside for a region: "region (boulders)".
80 std::string LayerType(const LayerSpec& layer);
81
82 } // namespace terraingen
83