[ox/model,ox/preloader] Add ability to handle inline arrays
Some checks are pending
Build / build (push) Waiting to run

This commit is contained in:
Gary Talent 2024-02-11 17:23:38 -06:00
parent ee05118478
commit 4e50889b5c
3 changed files with 52 additions and 2 deletions

View File

@ -359,6 +359,12 @@ class ModelValueArray {
};
template<>
[[nodiscard]]
consteval bool isArray(ModelValueArray*) noexcept {
return true;
}
class ModelValueVector {
private:
Vector<ModelValue> m_vec;
@ -817,6 +823,12 @@ class ModelUnion {
};
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t sizeOf(ModelValueArray const*v) noexcept {
return sizeOf<PlatSpec>(&(*v)[0]) * v->size();
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t sizeOf(const ModelValueVector*) noexcept {
@ -888,6 +900,12 @@ constexpr std::size_t sizeOf(const ModelValue *t) noexcept {
return size;
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(ModelValueArray const&v) noexcept {
return alignOf<PlatSpec>(v[0]);
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
@ -1072,12 +1090,14 @@ constexpr Error ModelValue::setType(
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
m_type = Type::InlineArray;
m_data.array = new ModelValueArray;
oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
} else {
m_type = Type::Vector;
m_data.vec = new ModelValueVector;
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
}
return m_data.vec->setType(type, subscriptLevels - 1, subscriptStack);
return {};
} else if (type->typeName == types::Bool) {
m_type = Type::Bool;
} else if (type->typeName == types::BasicString ||

View File

@ -131,7 +131,12 @@ template<typename T, std::size_t sz>
constexpr bool isBareArray_v<T[sz]> = true;
template<typename T>
constexpr bool isArray_v = false;
consteval bool isArray(T*) noexcept {
return false;
}
template<typename T>
constexpr bool isArray_v = isArray(static_cast<T*>(nullptr));
template<typename T>
constexpr bool isArray_v<T[]> = true;
@ -142,6 +147,16 @@ constexpr bool isArray_v<T[sz]> = true;
template<typename T, std::size_t sz>
constexpr bool isArray_v<Array<T, sz>> = true;
template<typename T, std::size_t sz>
consteval bool isArray(T[sz]) noexcept {
return true;
}
template<typename T, std::size_t sz>
consteval bool isArray(Array<T, sz>) noexcept {
return true;
}
template<typename T>
constexpr bool isSmartPtr_v = false;

View File

@ -64,6 +64,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
restore(pRestore), seekdir(pSeekdir) {}
};
ox::Vector<AllocStackItem, 8> m_allocStack;
ox::Vector<size_t> m_allocStart{};
constexpr Preloader() noexcept: m_writer(&m_buff) {}
@ -173,18 +174,26 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
}
oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) {
//oxDebug(" integral");
//oxDebugf("Preloader::field(name, val): {}", name);
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) {
//oxDebug(" pointer");
const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
oxReturnError(field(name, *val));
oxReturnError(endAlloc());
return ox::serialize(&m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T>) {
//oxDebug(" vector");
return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueVector>) {
val->types();
//oxDebug(" vector");
return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueArray>) {
return fieldArray(name, val);
} else {
//oxDebug(" object");
m_unionIdx.emplace_back(-1);
const auto out = preload<PlatSpec, T>(this, val);
m_unionIdx.pop_back();
@ -266,6 +275,7 @@ constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, siz
oxRequireM(a, ox::allocate(&m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a;
}
@ -277,6 +287,7 @@ constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz
oxRequireM(a, ox::allocate(&m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a;
}
@ -288,6 +299,7 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
const auto &si = *m_allocStack.back().unwrap();
oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
m_allocStack.pop_back();
m_allocStart.pop_back();
return {};
}
@ -372,6 +384,9 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept {
oxDebugf("array size: {}", val->size());
oxDebugf("array sizeOf: {}", sizeOf<PlatSpec>(val));
oxReturnError(pad(&(*val)[0]));
for (auto const&v : *val) {
oxReturnError(this->interface()->field({}, &v));
}