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;
|
||||||
tree_prefix P;
|
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+/;
|
drop /\s+/;
|
||||||
|
|
||||||
@@ -14,8 +34,18 @@ token rcurly /\}/;
|
|||||||
token scene;
|
token scene;
|
||||||
token width;
|
token width;
|
||||||
|
|
||||||
token uint /\d+/;
|
token uint /\d+/ <<
|
||||||
token number /-?\d+(\.\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;
|
Start -> RenderParams Scene;
|
||||||
|
|
||||||
|
|||||||
@@ -62,5 +62,9 @@ int Engine::run(string_view input_file, opt<string_view> output_file)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CLI params take precedence over scene params; defaults fill the rest. */
|
||||||
|
params.merge(scene->params);
|
||||||
|
params.apply_defaults();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
+57
-5
@@ -1,6 +1,7 @@
|
|||||||
#include <fart/Parser.h>
|
#include <fart/Parser.h>
|
||||||
#include <fart/propane.h>
|
#include <fart/propane.h>
|
||||||
#include <fart/read_file.h>
|
#include <fart/read_file.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
Scene * Parser::load_scene(const string_view & input_file)
|
Scene * Parser::load_scene(const string_view & input_file)
|
||||||
@@ -49,6 +50,19 @@ Scene * Parser::load_scene(const string_view & input_file)
|
|||||||
break;
|
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:
|
default:
|
||||||
fprintf(stderr, "%.*s:%u:%u: internal error: unknown parser result %zu\n",
|
fprintf(stderr, "%.*s:%u:%u: internal error: unknown parser result %zu\n",
|
||||||
fname_len, fname, pos.row, pos.col, result);
|
fname_len, fname, pos.row, pos.col, result);
|
||||||
@@ -61,29 +75,67 @@ Scene * Parser::load_scene(const string_view & input_file)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene * scene = build_scene(p_result(context));
|
Scene * scene = build_scene(input_file, p_result(context));
|
||||||
p_context_delete(context);
|
p_context_delete(context);
|
||||||
return scene;
|
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();
|
Scene * scene = new Scene();
|
||||||
|
|
||||||
for (PRenderParams rps = start.pRenderParams(); p_node_valid(rps); rps = rps.pRenderParams())
|
for (PRenderParams rps = start.pRenderParams(); p_node_valid(rps); rps = rps.pRenderParams())
|
||||||
{
|
{
|
||||||
PRenderParam rp = rps.pRenderParam();
|
PRenderParam rp = rps.pRenderParam();
|
||||||
|
bool ok = true;
|
||||||
if (PBackground background = rp.pBackground(); p_node_valid(background))
|
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))
|
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))
|
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);
|
static Scene * load_scene(const string_view & input_file);
|
||||||
|
|
||||||
private:
|
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