diff --git a/deps/ox/src/ox/model/modelvalue.hpp b/deps/ox/src/ox/model/modelvalue.hpp index 82892714..67bec3a5 100644 --- a/deps/ox/src/ox/model/modelvalue.hpp +++ b/deps/ox/src/ox/model/modelvalue.hpp @@ -760,7 +760,7 @@ constexpr std::size_t alignOf(const ModelValue &t) noexcept { size = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::String: - size = PlatSpec::alignOf(t.get()); + size = alignOf(t.get()); break; case ModelValue::Type::Object: size = alignOf(t.get()); diff --git a/deps/ox/src/ox/preloader/platspecs.hpp b/deps/ox/src/ox/preloader/platspecs.hpp index 8f9c8397..dc5d6567 100644 --- a/deps/ox/src/ox/preloader/platspecs.hpp +++ b/deps/ox/src/ox/preloader/platspecs.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include "alignmentcatcher.hpp" diff --git a/deps/ox/src/ox/preloader/preloader.hpp b/deps/ox/src/ox/preloader/preloader.hpp index 909b8c8d..f9fe6e82 100644 --- a/deps/ox/src/ox/preloader/preloader.hpp +++ b/deps/ox/src/ox/preloader/preloader.hpp @@ -14,10 +14,12 @@ #include #include #include +#include #include #include #include #include +#include #include "platspecs.hpp" @@ -105,9 +107,9 @@ class Preloader: public ModelHandlerBase, OpType::Reflect> { template constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; - constexpr ox::Result startAlloc(std::size_t sz) noexcept; + constexpr ox::Result startAlloc(size_t sz, size_t align) noexcept; - constexpr ox::Result startAlloc(std::size_t sz, std::size_t restore) noexcept; + constexpr ox::Result startAlloc(size_t sz, size_t align, std::size_t restore) noexcept; constexpr ox::Error endAlloc() noexcept; @@ -169,14 +171,16 @@ constexpr ox::Error Preloader::field(CRStringView name, const T *val) } oxReturnError(pad(val)); if constexpr(ox::is_integral_v) { - //oxDebugf("Preloader::field(name, val): {}", name); return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val)); } else if constexpr(ox::is_pointer_v) { - const PtrType a = startAlloc(sizeOf(*val), m_writer.tellp()) + PlatSpec::RomStart; + const PtrType a = startAlloc(sizeOf(val), alignOf(*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 || ox::is_same_v) { + } else if constexpr(ox::isVector_v) { + return fieldVector(name, val); + } else if constexpr(ox::is_same_v) { + val->types(); return fieldVector(name, val); } else { m_unionIdx.emplace_back(-1); @@ -222,6 +226,7 @@ constexpr ox::Error Preloader::field(CRStringView name, const ox::Arra if (!unionCheckAndIt()) { return {}; } + oxReturnError(pad(&(*val)[0])); // serialize the Array elements if constexpr(sz) { m_unionIdx.emplace_back(-1); @@ -239,27 +244,36 @@ constexpr ox::Error Preloader::field(CRStringView, const T **val, std: if (!unionCheckAndIt()) { return {}; } - // serialize the array - m_unionIdx.emplace_back(-1); - for (std::size_t i = 0; i < cnt; ++i) { - oxReturnError(this->interface()->field(nullptr, &val[i])); + if (cnt) { + oxReturnError(pad(*val)); + // serialize the array + m_unionIdx.emplace_back(-1); + for (std::size_t i = 0; i < cnt; ++i) { + oxReturnError(this->interface()->field(nullptr, &val[i])); + } + m_unionIdx.pop_back(); } - m_unionIdx.pop_back(); return {}; } template -constexpr ox::Result Preloader::startAlloc(std::size_t sz) noexcept { - oxRequire(a, ox::allocate(&m_writer, sz)); +constexpr ox::Result Preloader::startAlloc(size_t sz, size_t align) noexcept { m_allocStack.emplace_back(static_cast(m_writer.tellp())); + oxReturnError(m_writer.seekp(0, ox::ios_base::end)); + const auto padding = m_writer.tellp() % align; + oxRequireM(a, ox::allocate(&m_writer, sz + padding)); + a += padding; oxReturnError(m_writer.seekp(a)); return a; } template -constexpr ox::Result Preloader::startAlloc(std::size_t sz, std::size_t restore) noexcept { - oxRequire(a, ox::allocate(&m_writer, sz)); +constexpr ox::Result Preloader::startAlloc(std::size_t sz, size_t align, std::size_t restore) noexcept { m_allocStack.emplace_back(restore, ox::ios_base::beg); + oxReturnError(m_writer.seekp(0, ox::ios_base::end)); + const auto padding = m_writer.tellp() % align; + oxRequireM(a, ox::allocate(&m_writer, sz + padding)); + a += padding; oxReturnError(m_writer.seekp(a)); return a; } @@ -331,7 +345,11 @@ constexpr ox::Error Preloader::fieldVector( // serialize the Vector elements if (val->size()) { const auto sz = sizeOf(&(*val)[0]) * val->size(); - oxRequire(p, ox::allocate(&m_writer, sz)); + const auto align = alignOf((*val)[0]); + oxReturnError(m_writer.seekp(0, ox::ios_base::end)); + const auto padding = m_writer.tellp() % align; + oxRequireM(p, ox::allocate(&m_writer, sz + padding)); + p += padding; oxReturnError(m_writer.seekp(p)); m_unionIdx.emplace_back(-1); for (std::size_t i = 0; i < val->size(); ++i) { diff --git a/deps/ox/src/ox/std/strops.hpp b/deps/ox/src/ox/std/strops.hpp index 3528ddac..d3236d87 100644 --- a/deps/ox/src/ox/std/strops.hpp +++ b/deps/ox/src/ox/std/strops.hpp @@ -20,7 +20,7 @@ namespace ox { template [[nodiscard]] -constexpr ox::StringView substr(Str const&str, std::size_t pos) noexcept { +constexpr Str substr(Str const&str, std::size_t pos) noexcept { if (str.len() >= pos) { return Str(str.data() + pos, str.len() - pos); } diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index 87033fda..9ccd9aba 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -239,6 +239,9 @@ class Vector: detail::VectorAllocator { [[nodiscard]] constexpr Result back() const noexcept; + [[nodiscard]] + constexpr std::size_t capacity() const noexcept; + [[nodiscard]] constexpr std::size_t size() const noexcept; @@ -424,7 +427,7 @@ constexpr const T &Vector::operator[](std::size_t template constexpr Result Vector::at(size_t i) noexcept { - if (i < size()) { + if (i < size()) [[likely]] { return &operator[](i); } return OxError(1, "Vector: Invalid index"); @@ -432,7 +435,7 @@ constexpr Result Vector::at(size_t i) noexcep template constexpr Result Vector::at(size_t i) const noexcept { - if (i < size()) { + if (i < size()) [[likely]] { return &operator[](i); } return OxError(1, "Vector: Invalid index"); @@ -470,6 +473,11 @@ constexpr Result Vector::back() const n return &m_items[m_size - 1]; } +template +constexpr std::size_t Vector::capacity() const noexcept { + return m_cap; +} + template constexpr std::size_t Vector::size() const noexcept { return m_size; diff --git a/src/olympic/keel/include/keel/pack.hpp b/src/olympic/keel/include/keel/pack.hpp index eb8baa52..3f7afe48 100644 --- a/src/olympic/keel/include/keel/pack.hpp +++ b/src/olympic/keel/include/keel/pack.hpp @@ -91,9 +91,9 @@ ox::Error preloadObj( oxRequireM(buff, romFs.read(path)); oxRequireM(obj, keel::readAsset(ts, buff)); if (obj.type()->preloadable) { - oxOutf("preloading {}\n", path); + oxOutf("preloading {} as a {}\n", path, obj.type()->typeName); // preload - oxRequire(a, pl.startAlloc(ox::sizeOf(&obj))); + oxRequire(a, pl.startAlloc(ox::sizeOf(&obj), ox::alignOf(obj))); auto const err = ox::preload(&pl, &obj); oxReturnError(pl.endAlloc()); oxReturnError(err);