Load scene render params
This commit is contained in:
1 parent
a3684b20b6
commit
0ba0ebfe71
4 files changed
+94
-8
No files matched your search
+32
-2
@@ -1,5 +1,25 @@
|
||||
tree;
|
||||
tree_prefix P;
|
||||
ptype double;
|
||||
|
||||
<<header
|
||||
/* User terminate codes. */
|
||||
#define PARSER_TERMINATE_NUMBER_RANGE 1u
|
||||
>>
|
||||
|
||||
<<
|
||||
#include <charconv>
|
||||
|
||||
/* Store the numeric value of the matched text in *out. Returns false if the
|
||||
* value cannot be represented. */
|
||||
static bool parse_number(uint8_t const * match_text, size_t match_length, double * out)
|
||||
{
|
||||
const char * first = (const char *)match_text;
|
||||
const char * last = first + match_length;
|
||||
std::from_chars_result r = std::from_chars(first, last, *out);
|
||||
return (r.ec == std::errc()) && (r.ptr == last);
|
||||
}
|
||||
>>
|
||||
|
||||
drop /\s+/;
|
||||
|
||||
@@ -14,8 +34,18 @@ token rcurly /\}/;
|
||||
token scene;
|
||||
token width;
|
||||
|
||||
token uint /\d+/;
|
||||
token number /-?\d+(\.\d+)?/;
|
||||
token uint /\d+/ <<
|
||||
if (!parse_number(match_text, match_length, &$$))
|
||||
{
|
||||
$terminate(PARSER_TERMINATE_NUMBER_RANGE);
|
||||
}
|
||||
>>
|
||||
token number /-?\d+(\.\d+)?/ <<
|
||||
if (!parse_number(match_text, match_length, &$$))
|
||||
{
|
||||
$terminate(PARSER_TERMINATE_NUMBER_RANGE);
|
||||
}
|
||||
>>
|
||||
|
||||
Start -> RenderParams Scene;
|
||||
|
||||
|
||||
@@ -62,5 +62,9 @@ int Engine::run(string_view input_file, opt<string_view> output_file)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* CLI params take precedence over scene params; defaults fill the rest. */
|
||||
params.merge(scene->params);
|
||||
params.apply_defaults();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+57
-5
@@ -1,6 +1,7 @@
|
||||
#include <fart/Parser.h>
|
||||
#include <fart/propane.h>
|
||||
#include <fart/read_file.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Scene * Parser::load_scene(const string_view & input_file)
|
||||
@@ -49,6 +50,19 @@ Scene * Parser::load_scene(const string_view & input_file)
|
||||
break;
|
||||
}
|
||||
|
||||
case P_USER_TERMINATED:
|
||||
if (p_user_terminate_code(context) == PARSER_TERMINATE_NUMBER_RANGE)
|
||||
{
|
||||
fprintf(stderr, "%.*s:%u:%u: error: number out of range\n",
|
||||
fname_len, fname, pos.row, pos.col);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%.*s:%u:%u: internal error: unknown terminate code %zu\n",
|
||||
fname_len, fname, pos.row, pos.col, p_user_terminate_code(context));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%.*s:%u:%u: internal error: unknown parser result %zu\n",
|
||||
fname_len, fname, pos.row, pos.col, result);
|
||||
@@ -61,29 +75,67 @@ Scene * Parser::load_scene(const string_view & input_file)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Scene * scene = build_scene(p_result(context));
|
||||
Scene * scene = build_scene(input_file, p_result(context));
|
||||
p_context_delete(context);
|
||||
return scene;
|
||||
}
|
||||
|
||||
Scene * Parser::build_scene(PStart start)
|
||||
/* Convert a uint token value to a size_t, reporting an error if it does not
|
||||
* fit. */
|
||||
static bool token_to_size(const string_view & input_file, PToken token, opt<size_t> * out)
|
||||
{
|
||||
/* SIZE_MAX + 1, computed so that it is exactly representable as a double. */
|
||||
const double size_limit = (double)(SIZE_MAX / 2u + 1u) * 2.0;
|
||||
double value = token.pvalue();
|
||||
if (value >= size_limit)
|
||||
{
|
||||
p_position_t pos = token.position();
|
||||
fprintf(stderr, "%.*s:%u:%u: error: value out of range\n",
|
||||
(int)input_file.size(), input_file.data(), pos.row, pos.col);
|
||||
return false;
|
||||
}
|
||||
*out = (size_t)value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Color vector_to_color(PVector vector)
|
||||
{
|
||||
Color color{
|
||||
vector.pNumber2().pToken().pvalue(),
|
||||
vector.pNumber4().pToken().pvalue(),
|
||||
vector.pNumber6().pToken().pvalue(),
|
||||
};
|
||||
if (PNumber a = vector.pNumber8(); p_node_valid(a))
|
||||
{
|
||||
color.a = a.pToken().pvalue();
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
Scene * Parser::build_scene(const string_view & input_file, PStart start)
|
||||
{
|
||||
Scene * scene = new Scene();
|
||||
|
||||
for (PRenderParams rps = start.pRenderParams(); p_node_valid(rps); rps = rps.pRenderParams())
|
||||
{
|
||||
PRenderParam rp = rps.pRenderParam();
|
||||
bool ok = true;
|
||||
if (PBackground background = rp.pBackground(); p_node_valid(background))
|
||||
{
|
||||
/* TODO: set scene->params.background from the Vector. */
|
||||
scene->params.background = vector_to_color(background.pVector());
|
||||
}
|
||||
else if (PHeight height = rp.pHeight(); p_node_valid(height))
|
||||
{
|
||||
/* TODO: set scene->params.height from the uint token. */
|
||||
ok = token_to_size(input_file, height.pToken2(), &scene->params.height);
|
||||
}
|
||||
else if (PWidth width = rp.pWidth(); p_node_valid(width))
|
||||
{
|
||||
/* TODO: set scene->params.width from the uint token. */
|
||||
ok = token_to_size(input_file, width.pToken2(), &scene->params.width);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
delete scene;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -10,5 +10,5 @@ public:
|
||||
static Scene * load_scene(const string_view & input_file);
|
||||
|
||||
private:
|
||||
static Scene * build_scene(PStart start);
|
||||
static Scene * build_scene(const string_view & input_file, PStart start);
|
||||
};
|
||||
Reference in new issue
Block a user