1Curv has an optional user-defined configuration file, which the `curv` 2command reads during startup. 3 4The configuration file provides default values for -O options which are 5given on the command line. 6 7Loading the Config File 8----------------------- 9$XDG_CONFIG_HOME defines the base directory relative to which the Curv 10config file is stored. If $XDG_CONFIG_HOME is either not set or empty, 11it defaults to "$HOME/.config", unless $HOME is either not set or empty, 12in which case there is no Curv config file. 13 14There are two possible names for the Curv user configuration file. 15First, we try "$XDG_CONFIG_HOME/curv.curv". 16If this file exists, we evaluate it as a Curv syntax source file, 17and the result must be a record value. 18Otherwise, if the directory $XDG_CONFIG_HOME/curv exists, we evaluate it 19using directory syntax. 20 21Update: At present, I just import $XDG_CONFIG_HOME/curv using either file 22syntax or directory syntax. 23 24Accessing Configuration 25----------------------- 26In libcurv, Curv configuration is stored in System::config_, 27as a value of type Shared<const Record>. Not implemented yet; don't need it. 28So far config is only used to provide defaults for export parameters in the 29Curv program, and libcurv knows nothing about this. 30 31Idea: `config` is a builtin binding. 32It sounds cool, but why do I need it? What are the use cases? 33Curv is a file format for sharing geometric models, and it's not obviously 34good for shared models to depend on config. So I've leave this feature out 35until required. 36 37The Config Namespace 38-------------------- 39Here's the current CLI -O configuration: 40 mesh (STL, OBJ, X3D) 41 vsize, jit, adaptive, 42 mesh (X3D) 43 colour 44 viewer, GPU (aka Frag options) 45 aa, taa, fdur, bg 46 PNG 47 xsize, ysize, fstart, animate, + the Frag options 48 49I could just put all these names at the top level of the config record. 50 51However, I might want different Frag options for PNG export vs the Viewer 52(eg, high quality for PNG export, higher performance for the Viewer). 53So then I need a 2-level namespace, eg like: 54 config 55 mesh 56 vsize, jit, adaptive, colour 57 view 58 aa, taa, fdur, bg 59 image 60 xsize, ysize, fstart, animate, + the Frag options 61I like this one better: 62 config 63 export 64 viewer 65 repl 66 67Command Line Overrides 68---------------------- 69All of the -O options can be given default values in the config file. 70Which means all -O option values are Curv values. 71What about '-O colour=face|vertex' for -o x3d? 72'face' and 'vertex' need to either be strings, or symbols. 73See <language/Symbols> proposal. 74Depending on the outcome of this proposal, we will use one of the following: 75 -O colour='"vertex"' -- in bash 76 -O "colour=""vertex""" -- in cmd.exe, but for caveats see (*) 77 -O colour=#vertex 78(*) https://stackoverflow.com/questions/562038/escaping-double-quotes-in-batch-script 79 80All configuration can be overidden on the command line. 81Currently, all of the relevant command line options are -O options. 82 83Algorithm for parsing configuration and -O options. 84* error checking: I want to report invalid -O options, and invalid config 85 settings. 86* For each internal options structure, like io::Frag_Export, there is a 87 Parse_Opt function that validates a specific name/value pair, 88 modelled after parse_frag_opt(). This validates a name/value pair from 89 either the config, or from a -O option. 90* template<T> typedef bool (*Parse_Opt)( 91 92Let's say there is a flat config namespace, and we ignore names not relevant 93to the current export context. 94 1. An option structure like Frag_Export is default initialized. 95 2. config values with matching names are copied into the option struct, 96 unknown names are ignored. curv::Values are converted to the correct type. 97 3. All of the -O options are processed. Bad names are reported as an error. 98 Strings are evaluated as Curv values, then converted to the correct type. 99What API do we use? 100 101I could extend the Export_Param::Map to contain a string field (for the -O 102value) and a Value field (for the config value). Load the config record into 103the Export_Param::Map. Then, the current API is mostly unaffected and only 104the internal implementation of Export_Params needs to change. 105 106A Map item now contains a string `opt` and an Value `config`, both nullable. 107How do we evaluate it? 108* Currently we build a Param_Prog pp(*this, p), then we use pp.eval() 109 and At_Program(pp) as an error context. 110* If the parameter has no opt string, only a config value, then we still 111 need a Context for reporting a type or range error on the config value. 112* The minimum config context is the pathname of the root config file and 113 the data path of the config field. 114* Alternatively, we need the 'Program' for the config source file. 115 The important part is the Location. But, what if the config file 116 is a directory tree containing multiple *.curv files? 117 The config value containing the error could come from multiple sources. 118 Tracking this is tricky. In theory, this information can be reconstructed 119 from the minimum config context. 120 121At_Param cx(*this, p); 122cx.eval(deflval) 123 124Lighting Models 125--------------- 126There is a default lighting model, which has two attributes, background_colour 127and contrast. The user can override either or both of these attributes, 128and can also replace the default lighting model with another, 129perhaps user-defined lighting model. 130 131Perhaps user-defined lighting models can provide additional parameters that 132can be selectively overridden using the config file or the command line. 133 134In 3D, these config variables are called 135 viewer.lighting 136 viewer.lighting.background_colour 137 viewer.lighting.contrast 138 139In 2D, there is still a background colour, but there is no lighting model. 140What is it called? Currently it is called -Obg=. 141