Add class 'SimpleDynamic' to base-writer, migrate AnimValue to use it

This commit is contained in:
2023-10-17 19:34:50 -04:00
parent edea43839f
commit 5373182a59
4 changed files with 166 additions and 199 deletions

View File

@@ -1,16 +1,90 @@
#pragma once
/////////////////////////////////////////////////////////////////
//
// IMPORTANT: This is a header-only library that is included
// by the graphics engine as well. It cannot contain references
// to anything else in the engine.
//
/////////////////////////////////////////////////////////////////
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <cassert>
#include <string_view>
///////////////////////////////////////////////////////////////
//
// SimpleDynamic
//
// A struct that holds a dynamically typed value.
// This can hold a string, number, vector, or boolean.
//
// The type is stored in the 'type' field.
//
// If it's a STRING, the value is in the field s
// If it's a NUMBER, the value is in the field x
// If it's a BOOLEAN, it's true if (x==1.0)
// If it's a VECTOR, the value is in x,y,z
//
///////////////////////////////////////////////////////////////
enum class SimpleDynamicTag {
UNINITIALIZED,
STRING,
NUMBER,
BOOLEAN,
VECTOR,
};
struct SimpleDynamic {
SimpleDynamicTag type;
double x, y, z;
std::string s;
SimpleDynamic() {
type = SimpleDynamicTag::UNINITIALIZED;
x=y=z=0;
}
static const char *type_name_of(SimpleDynamicTag t) {
switch (t) {
case SimpleDynamicTag::UNINITIALIZED: return "uninitialized";
case SimpleDynamicTag::BOOLEAN: return "boolean";
case SimpleDynamicTag::NUMBER: return "number";
case SimpleDynamicTag::STRING: return "string";
case SimpleDynamicTag::VECTOR: return "vector";
default: return "unknown";
}
}
const char *type_name() const {
return type_name_of(type);
}
void set_string(std::string_view is) {
type=SimpleDynamicTag::STRING; s=is; x=0; y=0; z=0;
}
void set_number(double n) {
type = SimpleDynamicTag::NUMBER; s.clear(); x=n; y=0; z=0;
}
void set_boolean(bool b) {
type = SimpleDynamicTag::BOOLEAN; s.clear(); x=(b?1:0); y=0; z=0;
}
void set_vector(double ix, double iy, double iz) {
type = SimpleDynamicTag::VECTOR; s.clear(); x=ix; y=iy; z=iz;
}
void copy_value(const SimpleDynamic &other) {
type = other.type;
s=other.s; x=other.x; y=other.y; z=other.z;
}
};
///////////////////////////////////////////////////////////////
//
// BaseWriter
@@ -30,6 +104,7 @@
// void write_double(double data)
// void write_length(size_t data)
// void write_string(std::string_view data)
// void write_simple_dynamic(const SimpleDynamic &sd);
//
// You should derive from BaseWriter using the CRTP pattern:
//
@@ -86,8 +161,20 @@ public:
write_length(s.size());
static_cast<Derived*>(this)->write_bytes(s.data(), s.size());
}
void write_simple_dynamic(const SimpleDynamic &sd) {
write_uint8(uint8_t(sd.type));
switch(sd.type) {
case SimpleDynamicTag::NUMBER: write_double(sd.x); break;
case SimpleDynamicTag::BOOLEAN: write_bool(sd.x == 1.0); break;
case SimpleDynamicTag::VECTOR: write_double(sd.x); write_double(sd.y); write_double(sd.z); break;
case SimpleDynamicTag::STRING: write_string(sd.s); break;
default: assert(false);
}
}
};
///////////////////////////////////////////////////////////////
//
// BaseReader
@@ -109,6 +196,7 @@ public:
// size_t read_length();
// String read_string_limit(uint64_t size);
// String read_string();
// SimpleDynamic read_simple_dynamic();
//
// You should derive from BaseReader using the CRTP pattern:
//
@@ -184,5 +272,22 @@ public:
}
auto read_string() { return read_string_limit(0x1000000); } // 16MB limit default
void read_simple_dynamic(SimpleDynamic *result) {
SimpleDynamicTag type = SimpleDynamicTag(read_uint8());
switch (type) {
case SimpleDynamicTag::NUMBER: result->set_number(read_double()); break;
case SimpleDynamicTag::BOOLEAN: result->set_boolean(read_bool()); break;
case SimpleDynamicTag::VECTOR: {
double x=read_double();
double y=read_double();
double z=read_double();
result->set_vector(x,y,z);
break;
}
case SimpleDynamicTag::STRING: result->set_string(read_string()); break;
default: assert(false);
}
}
};