Simplify template code for faster compile and reduce .obj size.

This commit is contained in:
Syoyo Fujita
2022-10-16 05:13:36 +09:00
parent ef49ebc24a
commit d492495759
6 changed files with 416 additions and 467 deletions

View File

@@ -0,0 +1,2 @@
all:
python gen-timesamples.py

View File

@@ -0,0 +1,21 @@
# Simple Ascii parser code gen experiment.
## Why
* C macro is not enough
* C++ template is too overkill
* Slow compilation
* sometimes it generates lots of code sections which fails to compile(need /bigobj switch in MSVC)
Want a something like between C macro and C++ template. So this codegen approach will fill the gap.
## How to use
Simply run
```
$ python gen.py
```
Put generated .h and .cc to ../../src/

View File

@@ -0,0 +1,180 @@
import os
import sys
import copy
basefilename = "ascii-parser-timesamples"
# typename in USD ascc, typename in TinyUSDZ C++
types = {
"float": "float",
"float2": "value::float2",
}
try_parse_timesamples_template =
"""
nonstd::optional<AsciiParser::TimeSampleData<__ty>>
AsciiParser::TryParseTimeSamples() {
// timeSamples = '{' ((int : T) sep)+ '}'
// sep = ','(may ok to omit for the last element.
TimeSampleData<__ty> data;
if (!Expect('{')) {
return nonstd::nullopt;
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
}
while (!Eof()) {
char c;
if (!Char1(&c)) {
return nonstd::nullopt;
}
if (c == '}') {
break;
}
Rewind(1);
double timeVal;
// -inf, inf and nan are handled.
if (!ReadBasicType(&timeVal)) {
PushError("Parse time value failed.");
return nonstd::nullopt;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
}
if (!Expect(':')) {
return nonstd::nullopt;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
}
nonstd::optional<__ty> value;
if (!ReadBasicType(&value)) {
return nonstd::nullopt;
}
// The last element may have separator ','
{
// Semicolon ';' is not allowed as a separator for timeSamples array
// values.
if (!SkipWhitespace()) {
return nonstd::nullopt;
}
char sep;
if (!Char1(&sep)) {
return nonstd::nullopt;
}
DCOUT("sep = " << sep);
if (sep == '}') {
// End of item
data.push_back({timeVal, value});
break;
} else if (sep == ',') {
// ok
} else {
Rewind(1);
// Look ahead Newline + '}'
auto loc = CurrLoc();
if (SkipWhitespaceAndNewline()) {
char nc;
if (!Char1(&nc)) {
return nonstd::nullopt;
}
if (nc == '}') {
// End of item
data.push_back({timeVal, value});
break;
}
}
// Rewind and continue parsing.
SeekTo(loc);
}
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
}
data.push_back({timeVal, value});
}
DCOUT("Parse TimeSamples success. # of items = " << data.size());
return std::move(data);
}
convert_ts_template = """
value::TimeSamples AsciiParser::ConvertToTimeSamples___Ty(
const TimeSampleData<__ty> &ts) {
value::TimeSamples dst;
for (const auto &item : ts) {
dst.times.push_back(std::get<0>(item));
if (item.second) {
dst.values.push_back(item.second.value());
} else {
// Blocked.
dst.values.push_back(value::ValueBlock());
}
}
return dst;
}
"""
def gen_header():
ss = ""
for k, v in types.items():
print(k)
#subs = ss.replace("__ty", v)
#print(subs)
with open(basefilename + ".hh", "w") as f:
f.write(ss)
def gen_source():
ss = ""
for k, v in types.items():
print(k)
subs = copy.copy(convert_ts_template)
subs = subs.replace("__Ty", k)
subs = subs.replace("__ty", v)
print(subs)
with open(basefilename + ".cc", "w") as f:
f.write(ss)
def gen():
gen_header()
gen_source()
if __name__ == '__main__':
gen()

View File

@@ -5,7 +5,7 @@
// Split ParseTimeSamples to two .cc files.
//
// TODO
// - [ ] Rewrite code with less C++ template code.
// - [x] Rewrite code with less C++ template code.
#include <cstdio>
#ifdef _MSC_VER
@@ -80,57 +80,6 @@ namespace tinyusdz {
namespace ascii {
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<bool>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<int32_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<uint32_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<int64_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<uint64_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<float>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<double>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix2d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix4d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quath>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quatf>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quatd>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::token>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<StringData>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<std::string>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<Reference>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<Path>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::AssetPath>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<bool> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<int32_t> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<uint32_t> *result);
@@ -187,27 +136,90 @@ extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::AssetP
//
// TODO: Share code with array version as much as possible.
template <typename T>
nonstd::optional<AsciiParser::TimeSampleData<std::vector<T>>>
AsciiParser::TryParseTimeSamplesOfArray() {
// timeSamples = '{' ((int : [T]) sep)+ '}'
// sep = ','(may ok to omit for the last element.
// `type_name` does not contain "[]"
bool AsciiParser::ParseTimeSampleValueOfArrayType(const std::string &type_name, value::Value *result) {
TimeSampleData<std::vector<T>> data;
if (!result) {
return false;
}
if (MaybeNone()) {
(*result) = value::ValueBlock();
return true;
}
value::Value val;
#define PARSE_TYPE(__tyname, __type) \
if (__tyname == value::TypeTraits<__type>::type_name()) { \
std::vector<__type> typed_val; \
if (!ParseBasicTypeArray(&typed_val)) { \
PUSH_ERROR_AND_RETURN("Failed to parse value with requested type `" + __tyname + "[]`"); \
} \
val = value::Value(typed_val); \
} else
// NOTE: `string` does not support multi-line string.
PARSE_TYPE(type_name, value::AssetPath)
PARSE_TYPE(type_name, value::token)
PARSE_TYPE(type_name, std::string)
PARSE_TYPE(type_name, float)
PARSE_TYPE(type_name, int32_t)
PARSE_TYPE(type_name, uint32_t)
PARSE_TYPE(type_name, int64_t)
PARSE_TYPE(type_name, uint64_t)
PARSE_TYPE(type_name, value::half)
PARSE_TYPE(type_name, value::half2)
PARSE_TYPE(type_name, value::half3)
PARSE_TYPE(type_name, value::half4)
PARSE_TYPE(type_name, float)
PARSE_TYPE(type_name, value::float2)
PARSE_TYPE(type_name, value::float3)
PARSE_TYPE(type_name, value::float4)
PARSE_TYPE(type_name, double)
PARSE_TYPE(type_name, value::double2)
PARSE_TYPE(type_name, value::double3)
PARSE_TYPE(type_name, value::double4)
PARSE_TYPE(type_name, value::quath)
PARSE_TYPE(type_name, value::quatf)
PARSE_TYPE(type_name, value::quatd)
PARSE_TYPE(type_name, value::color3f)
PARSE_TYPE(type_name, value::color4f)
PARSE_TYPE(type_name, value::color3d)
PARSE_TYPE(type_name, value::color4d)
PARSE_TYPE(type_name, value::vector3f)
PARSE_TYPE(type_name, value::normal3f)
PARSE_TYPE(type_name, value::point3f)
PARSE_TYPE(type_name, value::texcoord2f)
PARSE_TYPE(type_name, value::texcoord3f)
PARSE_TYPE(type_name, value::matrix4d) {
PUSH_ERROR_AND_RETURN(" : TODO: timeSamples type " + type_name);
}
#undef PARSE_TYPE
(*result) = val;
return true;
}
bool AsciiParser::ParseTimeSamplesOfArray(const std::string &type_name,
value::TimeSamples *ts_out) {
value::TimeSamples ts;
if (!Expect('{')) {
return nonstd::nullopt;
return false;
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
return false;
}
while (!Eof()) {
char c;
if (!Char1(&c)) {
return nonstd::nullopt;
return false;
}
if (c == '}') {
@@ -220,33 +232,24 @@ AsciiParser::TryParseTimeSamplesOfArray() {
// -inf, inf and nan are handled.
if (!ReadBasicType(&timeVal)) {
PushError("Parse time value failed.");
return nonstd::nullopt;
return false;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
if (!Expect(':')) {
return nonstd::nullopt;
return false;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
// None(nullopt) or T[]
nonstd::optional<std::vector<T>> tsValue;
if (MaybeNone()) {
tsValue = nonstd::nullopt;
} else {
std::vector<T> value;
if (!ParseBasicTypeArray(&value)) {
PushError("Failed to parse array value.");
return nonstd::nullopt;
}
tsValue = value;
value::Value value;
if (!ParseTimeSampleValueOfArrayType(type_name, &value)) { // could be None(ValueBlock)
return false;
}
// The last element may have separator ','
@@ -254,18 +257,19 @@ AsciiParser::TryParseTimeSamplesOfArray() {
// Semicolon ';' is not allowed as a separator for timeSamples array
// values.
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
char sep;
char sep{};
if (!Char1(&sep)) {
return nonstd::nullopt;
return false;
}
DCOUT("sep = " << sep);
if (sep == '}') {
// End of item
data.push_back({timeVal, tsValue});
ts.times.push_back(timeVal);
ts.values.push_back(value);
break;
} else if (sep == ',') {
// ok
@@ -278,12 +282,13 @@ AsciiParser::TryParseTimeSamplesOfArray() {
if (SkipWhitespaceAndNewline()) {
char nc;
if (!Char1(&nc)) {
return nonstd::nullopt;
return false;
}
if (nc == '}') {
// End of item
data.push_back({timeVal, tsValue});
ts.times.push_back(timeVal);
ts.values.push_back(value);
break;
}
}
@@ -294,92 +299,14 @@ AsciiParser::TryParseTimeSamplesOfArray() {
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
return false;
}
data.push_back({timeVal, tsValue});
ts.times.push_back(timeVal);
ts.values.push_back(value);
}
DCOUT(
"Parse TimeSamples of array type success. # of items = " << data.size());
return std::move(data);
}
template <typename T>
value::TimeSamples AsciiParser::ConvertToTimeSamples(
const TimeSampleData<T> &ts) {
value::TimeSamples dst;
for (const auto &item : ts) {
dst.times.push_back(std::get<0>(item));
if (item.second) {
dst.values.push_back(item.second.value());
} else {
// Blocked.
dst.values.push_back(value::ValueBlock());
}
}
return dst;
}
bool AsciiParser::ParseTimeSamplesOfArray(const std::string &type_name,
value::TimeSamples *ts_out) {
// 1D and scalar
#define PARSE_TYPE(__tyname, __type, __ts) \
if ((__tyname == value::TypeTraits<__type>::type_name())) { \
if (auto pv = TryParseTimeSamplesOfArray<__type>()) { \
__ts = ConvertToTimeSamples<std::vector<__type>>(pv.value()); \
} else { \
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
<< value::TypeTraits<__type>::type_name() \
<< "[]`"); \
} \
} else
value::TimeSamples ts;
// NOTE: `string` does not support multi-line string.
PARSE_TYPE(type_name, value::AssetPath, ts)
PARSE_TYPE(type_name, value::token, ts)
PARSE_TYPE(type_name, std::string, ts)
PARSE_TYPE(type_name, float, ts)
PARSE_TYPE(type_name, int, ts)
PARSE_TYPE(type_name, uint32_t, ts)
PARSE_TYPE(type_name, int64_t, ts)
PARSE_TYPE(type_name, uint64_t, ts)
PARSE_TYPE(type_name, value::half, ts)
PARSE_TYPE(type_name, value::half2, ts)
PARSE_TYPE(type_name, value::half3, ts)
PARSE_TYPE(type_name, value::half4, ts)
PARSE_TYPE(type_name, float, ts)
PARSE_TYPE(type_name, value::float2, ts)
PARSE_TYPE(type_name, value::float3, ts)
PARSE_TYPE(type_name, value::float4, ts)
PARSE_TYPE(type_name, double, ts)
PARSE_TYPE(type_name, value::double2, ts)
PARSE_TYPE(type_name, value::double3, ts)
PARSE_TYPE(type_name, value::double4, ts)
PARSE_TYPE(type_name, value::quath, ts)
PARSE_TYPE(type_name, value::quatf, ts)
PARSE_TYPE(type_name, value::quatd, ts)
PARSE_TYPE(type_name, value::color3f, ts)
PARSE_TYPE(type_name, value::color4f, ts)
PARSE_TYPE(type_name, value::color3d, ts)
PARSE_TYPE(type_name, value::color4d, ts)
PARSE_TYPE(type_name, value::vector3f, ts)
PARSE_TYPE(type_name, value::normal3f, ts)
PARSE_TYPE(type_name, value::point3f, ts)
PARSE_TYPE(type_name, value::texcoord2f, ts)
PARSE_TYPE(type_name, value::texcoord3f, ts)
PARSE_TYPE(type_name, value::matrix4d, ts) {
PUSH_ERROR_AND_RETURN(" : TODO: timeSamples type " + type_name);
}
#undef PARSE_TYPE
DCOUT("Parse TimeSamples success. # of items = " << ts.times.size());
if (ts_out) {
(*ts_out) = std::move(ts);

View File

@@ -5,7 +5,7 @@
// Split ParseTimeSamples to two .cc files.
//
// TODO
// - [ ] Rewrite code with less C++ template code.
// - [x] Rewrite code with less C++ template code.
#include <cstdio>
#ifdef _MSC_VER
@@ -32,10 +32,6 @@
#endif
#include <vector>
#include "ascii-parser.hh"
#include "str-util.hh"
#include "tiny-format.hh"
//
#if !defined(TINYUSDZ_DISABLE_MODULE_USDA_READER)
@@ -66,7 +62,10 @@
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#include "common-macros.inc"
#include "ascii-parser.hh"
#include "str-util.hh"
#include "tiny-format.hh"
//
#include "io-util.hh"
#include "pprinter.hh"
#include "prim-types.hh"
@@ -75,138 +74,97 @@
#include "tinyusdz.hh"
#include "value-pprint.hh"
#include "value-types.hh"
//
#include "common-macros.inc"
namespace tinyusdz {
namespace ascii {
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<bool>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<int32_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<uint32_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<int64_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<uint64_t>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::half4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<float>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::float4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<double>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double2>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double3>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::double4>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord2d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::texcoord3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::point3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::normal3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::vector3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4h>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4f>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::color4d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix2d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix3d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::matrix4d>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quath>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quatf>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::quatd>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::token>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<StringData>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<std::string>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<Reference>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<Path>> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<nonstd::optional<value::AssetPath>> *result);
bool AsciiParser::ParseTimeSampleValue(const std::string &type_name, value::Value *result) {
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<bool> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<int32_t> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<uint32_t> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<int64_t> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<uint64_t> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::half> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::half2> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::half3> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::half4> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<float> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::float2> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::float3> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::float4> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<double> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::double2> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::double3> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::double4> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord2h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord2f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord2d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord3h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord3f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::texcoord3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::point3h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::point3f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::point3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::normal3h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::normal3f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::normal3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::vector3h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::vector3f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::vector3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color3h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color3f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color4h> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color4f> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::color4d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::matrix2d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::matrix3d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::matrix4d> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::quath> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::quatf> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::quatd> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::token> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<StringData> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<std::string> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<Reference> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<Path> *result);
extern template bool AsciiParser::ParseBasicTypeArray(std::vector<value::AssetPath> *result);
if (!result) {
return false;
}
//
// -- impl ParseTimeSampleData
//
if (MaybeNone()) {
(*result) = value::ValueBlock();
return true;
}
// TODO: Share code with array version as much as possible.
template <typename T>
nonstd::optional<AsciiParser::TimeSampleData<T>>
AsciiParser::TryParseTimeSamples() {
// timeSamples = '{' ((int : T) sep)+ '}'
// sep = ','(may ok to omit for the last element.
value::Value val;
TimeSampleData<T> data;
#define PARSE_TYPE(__tyname, __type) \
if (__tyname == value::TypeTraits<__type>::type_name()) { \
__type typed_val; \
if (!ReadBasicType(&typed_val)) { \
PUSH_ERROR_AND_RETURN("Failed to parse value with requested type `" + __tyname + "`"); \
} \
val = value::Value(typed_val); \
} else
// NOTE: `string` does not support multi-line string.
PARSE_TYPE(type_name, value::AssetPath)
PARSE_TYPE(type_name, value::token)
PARSE_TYPE(type_name, std::string)
PARSE_TYPE(type_name, float)
PARSE_TYPE(type_name, int32_t)
PARSE_TYPE(type_name, uint32_t)
PARSE_TYPE(type_name, int64_t)
PARSE_TYPE(type_name, uint64_t)
PARSE_TYPE(type_name, value::half)
PARSE_TYPE(type_name, value::half2)
PARSE_TYPE(type_name, value::half3)
PARSE_TYPE(type_name, value::half4)
PARSE_TYPE(type_name, float)
PARSE_TYPE(type_name, value::float2)
PARSE_TYPE(type_name, value::float3)
PARSE_TYPE(type_name, value::float4)
PARSE_TYPE(type_name, double)
PARSE_TYPE(type_name, value::double2)
PARSE_TYPE(type_name, value::double3)
PARSE_TYPE(type_name, value::double4)
PARSE_TYPE(type_name, value::quath)
PARSE_TYPE(type_name, value::quatf)
PARSE_TYPE(type_name, value::quatd)
PARSE_TYPE(type_name, value::color3f)
PARSE_TYPE(type_name, value::color4f)
PARSE_TYPE(type_name, value::color3d)
PARSE_TYPE(type_name, value::color4d)
PARSE_TYPE(type_name, value::vector3f)
PARSE_TYPE(type_name, value::normal3f)
PARSE_TYPE(type_name, value::point3f)
PARSE_TYPE(type_name, value::texcoord2f)
PARSE_TYPE(type_name, value::texcoord3f)
PARSE_TYPE(type_name, value::matrix4d) {
PUSH_ERROR_AND_RETURN(" : TODO: timeSamples type " + type_name);
}
#undef PARSE_TYPE
(*result) = val;
return true;
}
bool AsciiParser::ParseTimeSamples(const std::string &type_name,
value::TimeSamples *ts_out) {
value::TimeSamples ts;
if (!Expect('{')) {
return nonstd::nullopt;
return false;
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
return false;
}
while (!Eof()) {
char c;
if (!Char1(&c)) {
return nonstd::nullopt;
return false;
}
if (c == '}') {
@@ -219,24 +177,24 @@ AsciiParser::TryParseTimeSamples() {
// -inf, inf and nan are handled.
if (!ReadBasicType(&timeVal)) {
PushError("Parse time value failed.");
return nonstd::nullopt;
return false;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
if (!Expect(':')) {
return nonstd::nullopt;
return false;
}
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
nonstd::optional<T> value;
if (!ReadBasicType(&value)) {
return nonstd::nullopt;
value::Value value;
if (!ParseTimeSampleValue(type_name, &value)) { // could be None(ValueBlock)
return false;
}
// The last element may have separator ','
@@ -244,18 +202,19 @@ AsciiParser::TryParseTimeSamples() {
// Semicolon ';' is not allowed as a separator for timeSamples array
// values.
if (!SkipWhitespace()) {
return nonstd::nullopt;
return false;
}
char sep;
char sep{};
if (!Char1(&sep)) {
return nonstd::nullopt;
return false;
}
DCOUT("sep = " << sep);
if (sep == '}') {
// End of item
data.push_back({timeVal, value});
ts.times.push_back(timeVal);
ts.values.push_back(value);
break;
} else if (sep == ',') {
// ok
@@ -268,12 +227,13 @@ AsciiParser::TryParseTimeSamples() {
if (SkipWhitespaceAndNewline()) {
char nc;
if (!Char1(&nc)) {
return nonstd::nullopt;
return false;
}
if (nc == '}') {
// End of item
data.push_back({timeVal, value});
ts.times.push_back(timeVal);
ts.values.push_back(value);
break;
}
}
@@ -284,91 +244,14 @@ AsciiParser::TryParseTimeSamples() {
}
if (!SkipWhitespaceAndNewline()) {
return nonstd::nullopt;
return false;
}
data.push_back({timeVal, value});
ts.times.push_back(timeVal);
ts.values.push_back(value);
}
DCOUT("Parse TimeSamples success. # of items = " << data.size());
return std::move(data);
}
template <typename T>
value::TimeSamples AsciiParser::ConvertToTimeSamples(
const TimeSampleData<T> &ts) {
value::TimeSamples dst;
for (const auto &item : ts) {
dst.times.push_back(std::get<0>(item));
if (item.second) {
dst.values.push_back(item.second.value());
} else {
// Blocked.
dst.values.push_back(value::ValueBlock());
}
}
return dst;
}
bool AsciiParser::ParseTimeSamples(const std::string &type_name,
value::TimeSamples *ts_out) {
// 1D and scalar
#define PARSE_TYPE(__tyname, __type, __ts) \
if (__tyname == value::TypeTraits<__type>::type_name()) { \
if (auto pv = TryParseTimeSamples<__type>()) { \
__ts = ConvertToTimeSamples<__type>(pv.value()); \
} else { \
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
<< value::TypeTraits<__type>::type_name() << "`"); \
} \
} else
value::TimeSamples ts;
// NOTE: `string` does not support multi-line string.
PARSE_TYPE(type_name, value::AssetPath, ts)
PARSE_TYPE(type_name, value::token, ts)
PARSE_TYPE(type_name, std::string, ts)
PARSE_TYPE(type_name, float, ts)
PARSE_TYPE(type_name, int, ts)
PARSE_TYPE(type_name, uint32_t, ts)
PARSE_TYPE(type_name, int64_t, ts)
PARSE_TYPE(type_name, uint64_t, ts)
PARSE_TYPE(type_name, value::half, ts)
PARSE_TYPE(type_name, value::half2, ts)
PARSE_TYPE(type_name, value::half3, ts)
PARSE_TYPE(type_name, value::half4, ts)
PARSE_TYPE(type_name, float, ts)
PARSE_TYPE(type_name, value::float2, ts)
PARSE_TYPE(type_name, value::float3, ts)
PARSE_TYPE(type_name, value::float4, ts)
PARSE_TYPE(type_name, double, ts)
PARSE_TYPE(type_name, value::double2, ts)
PARSE_TYPE(type_name, value::double3, ts)
PARSE_TYPE(type_name, value::double4, ts)
PARSE_TYPE(type_name, value::quath, ts)
PARSE_TYPE(type_name, value::quatf, ts)
PARSE_TYPE(type_name, value::quatd, ts)
PARSE_TYPE(type_name, value::color3f, ts)
PARSE_TYPE(type_name, value::color4f, ts)
PARSE_TYPE(type_name, value::color3d, ts)
PARSE_TYPE(type_name, value::color4d, ts)
PARSE_TYPE(type_name, value::vector3f, ts)
PARSE_TYPE(type_name, value::normal3f, ts)
PARSE_TYPE(type_name, value::point3f, ts)
PARSE_TYPE(type_name, value::texcoord2f, ts)
PARSE_TYPE(type_name, value::texcoord3f, ts)
PARSE_TYPE(type_name, value::matrix4d, ts) {
PUSH_ERROR_AND_RETURN(" : TODO: timeSamples type " + type_name);
}
#undef PARSE_TYPE
DCOUT("Parse TimeSamples success. # of items = " << ts.times.size());
if (ts_out) {
(*ts_out) = std::move(ts);

View File

@@ -306,6 +306,17 @@ class AsciiParser {
///
bool Parse(LoadState state = LoadState::TOPLEVEL);
///
/// Parse TimeSample value with specified `type_name`(Appears in USDA. .e.g. "float", "matrix2d")
///
bool ParseTimeSampleValue(const std::string &type_name, value::Value *result);
///
/// Parse TimeSample value with specified array type of `type_name`("[]" omiotted. .e.g. "float" for "float[]")
///
bool ParseTimeSampleValueOfArrayType(const std::string &type_name, value::Value *result);
// TODO: ParseBasicType?
bool ParsePurpose(Purpose *result);
@@ -463,15 +474,6 @@ class AsciiParser {
template <typename T, size_t N>
bool ParseTupleArray(std::vector<std::array<T, N>> *result);
#if 0
template<> bool ParseTupleArray(std::vector<std::array<float, 2>> *result);
template<> bool ParseTupleArray(std::vector<std::array<float, 3>> *result);
template<> bool ParseTupleArray(std::vector<std::array<float, 4>> *result);
template<> bool ParseTupleArray(std::vector<std::array<double, 2>> *result);
template<> bool ParseTupleArray(std::vector<std::array<double, 3>> *result);
template<> bool ParseTupleArray(std::vector<std::array<double, 4>> *result);
#endif
///
/// Parse the array of tuple. some may be None(e.g. `float3`: [(0, 1, 2),
/// None, (2, 3, 4), ...] )
@@ -479,15 +481,6 @@ class AsciiParser {
template <typename T, size_t N>
bool ParseTupleArray(std::vector<nonstd::optional<std::array<T, N>>> *result);
#if 0
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<float, 2>>> *result);
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<float, 3>>> *result);
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<float, 4>>> *result);
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<double, 2>>> *result);
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<double, 3>>> *result);
template<> bool ParseTupleArray(std::vector<nonstd::optional<std::array<double, 4>>> *result);
#endif
template <typename T>
bool SepBy1BasicType(const char sep, std::vector<T> *result);
@@ -511,56 +504,6 @@ class AsciiParser {
template <typename T>
bool ParseBasicTypeArray(std::vector<T> *result);
#if 0
template<> bool ParseBasicTypeArray(std::vector<bool> *result);
template<> bool ParseBasicTypeArray(std::vector<int32_t> *result);
template<> bool ParseBasicTypeArray(std::vector<uint32_t> *result);
template<> bool ParseBasicTypeArray(std::vector<int64_t> *result);
template<> bool ParseBasicTypeArray(std::vector<uint64_t> *result);
template<> bool ParseBasicTypeArray(std::vector<value::half> *result);
template<> bool ParseBasicTypeArray(std::vector<value::half2> *result);
template<> bool ParseBasicTypeArray(std::vector<value::half3> *result);
template<> bool ParseBasicTypeArray(std::vector<value::half4> *result);
template<> bool ParseBasicTypeArray(std::vector<float> *result);
template<> bool ParseBasicTypeArray(std::vector<value::float2> *result);
template<> bool ParseBasicTypeArray(std::vector<value::float3> *result);
template<> bool ParseBasicTypeArray(std::vector<value::float4> *result);
template<> bool ParseBasicTypeArray(std::vector<double> *result);
template<> bool ParseBasicTypeArray(std::vector<value::double2> *result);
template<> bool ParseBasicTypeArray(std::vector<value::double3> *result);
template<> bool ParseBasicTypeArray(std::vector<value::double4> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord2h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord2f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord2d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord3h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord3f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::texcoord3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::point3h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::point3f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::point3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::normal3h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::normal3f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::normal3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::vector3h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::vector3f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::vector3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color3h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color3f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color4h> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color4f> *result);
template<> bool ParseBasicTypeArray(std::vector<value::color4d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::matrix2d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::matrix3d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::matrix4d> *result);
template<> bool ParseBasicTypeArray(std::vector<value::token> *result);
template<> bool ParseBasicTypeArray(std::vector<StringData> *result);
template<> bool ParseBasicTypeArray(std::vector<std::string> *result);
template<> bool ParseBasicTypeArray(std::vector<Reference> *result);
template<> bool ParseBasicTypeArray(std::vector<Path> *result);
template<> bool ParseBasicTypeArray(std::vector<value::AssetPath> *result);
#endif
///
/// Parses 1 or more occurences of value with basic type 'T', separated by
/// `sep`
@@ -655,13 +598,6 @@ class AsciiParser {
///
std::string GetWarning();
#if 0
///
/// Get as scene
///
const HighLevelScene& GetHighLevelScene() const;
#endif
// Return the flag if the .usda is read from `references`
bool IsReferenced() { return _referenced; }
@@ -720,7 +656,7 @@ class AsciiParser {
bool ParseCustomMetaValue();
// TODO: Return Path
// TODO: Return Path?
bool ParseReference(Reference *out, bool *triple_deliminated);
// `#` style comment
@@ -789,8 +725,8 @@ class AsciiParser {
// -- [TimeSamples] -------------------
template <typename T>
using TimeSampleData = std::vector<std::pair<double, nonstd::optional<T>>>;
//template <typename T>
//using TimeSampleData = std::vector<std::pair<double, nonstd::optional<T>>>;
// template <typename T>
// using TimeSampleDataArray = std::vector<std::pair<double,
@@ -800,19 +736,19 @@ class AsciiParser {
/// Convert TimeSampleData<T> to TimeSamples(type-erased TimeSample Sdata
/// struct)
///
template <typename T>
value::TimeSamples ConvertToTimeSamples(const TimeSampleData<T> &in);
//template <typename T>
//value::TimeSamples ConvertToTimeSamples(const TimeSampleData<T> &in);
template <typename T>
value::TimeSamples ConvertToTimeSamples(
const TimeSampleData<std::vector<T>> &in);
//template <typename T>
//value::TimeSamples ConvertToTimeSamples(
// const TimeSampleData<std::vector<T>> &in);
// T = scalar(e.g. `float`)
template <typename T>
nonstd::optional<TimeSampleData<T>> TryParseTimeSamples();
//// T = scalar(e.g. `float`)
//template <typename T>
//nonstd::optional<TimeSampleData<T>> TryParseTimeSamples();
template <typename T>
nonstd::optional<TimeSampleData<std::vector<T>>> TryParseTimeSamplesOfArray();
//template <typename T>
//nonstd::optional<TimeSampleData<std::vector<T>>> TryParseTimeSamplesOfArray();
// ---------------------------------------