SK83RJOSH / cblend

A modern C/C++ library for reading blend files.
MIT License
3 stars 1 forks source link

Reflection Queries #2

Open SK83RJOSH opened 2 years ago

SK83RJOSH commented 2 years ago

Now that file parsing and reflection are complete it's time to improve ergonomics. After some discussions with friends, I think a query api will be a nice starting point.

Queries

Types and blocks should expose a set of Query functions. These functions will accept a std::string_view containing a query. Queries will be transformed (preferably at compile time) into a set of operations on the given BlendType "hierarchy".

BlendType::QueryValue(std::span, std::string_view query)

This template would allow you query a value of T from the given span. Would primarily be used internally.

using Vec3f = Vec2<float>;
auto mesh = blend.GetBlock(BLOCK_CODE_ME);
auto mesh_type = blend.GetBlockType(*mesh);
auto totlayer = mesh_type->QueryValue<Vec3f>(mesh.header.data, "size"); // size is an array of the fundamental type float

BlendType::QueryValue(const Block& block, std::string_view query)

This template would allow you query a value of T from the block Block. Would primarily be used internally.

auto mesh = blend.GetBlock(BLOCK_CODE_ME);
auto mesh_type = blend.GetBlockType(*mesh);
auto totlayer = mesh_type->QueryValue<int>(mesh, "vdata.totlayer"); // vdata is an aggregate field, and totlayer is a fundamental field

BlendBlock::QueryValue(std::string_view query)

This template would allow you query a value of T from the given Block.

auto mesh = blend.GetBlock(BLOCK_CODE_ME);
auto totlayer = mesh->QueryValue<int>("totvert"); // totvert is a fundamental field

Query Language

The query language should be as simple as possible while still being robust.

Aggregates

Aggregate fields can be indexed directly by name.

mesh->QueryValue<SymmetryMode>("symmetry");

Arrays

Arrays can be returned by value.

mesh->QueryValue<Vec3f>("size");
mesh->QueryValue<float[3]>("size");
mesh->QueryValue<std::array<float, 8>>("size");

Arrays values can be directly addressed.

mesh->QueryValue<float>("loc[0]");
mesh->QueryValue<float>("loc[1]");
mesh->QueryValue<float>("loc[2]");

Pointers

Pointers are treated as if they are references with safety.

mesh->QueryValue("vdata.data");

Pointers can be indexed as arrays without safety.

mesh->QueryValue<Vertex>("vdata.data[0]");

Pointers can be read as arrays without safety.

mesh->QueryValue<Vertex[8]>("vdata.data[0]");
SK83RJOSH commented 2 years ago

Open questions: