[ox/preloader] Add ptr handling

This commit is contained in:
Gary Talent 2022-12-05 17:40:22 -06:00
parent 030d46a999
commit 461e3d61ef

View File

@ -32,6 +32,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
friend constexpr ox::Error preload(Preloader<PS> *pl, ox::CommonPtrWith<T> auto *obj) noexcept; friend constexpr ox::Error preload(Preloader<PS> *pl, ox::CommonPtrWith<T> auto *obj) noexcept;
private: private:
using PtrType = typename PlatSpec::PtrType;
class UnionIdxTracker { class UnionIdxTracker {
private: private:
int m_unionIdx = -1; int m_unionIdx = -1;
@ -55,6 +56,14 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
}; };
ox::Vector<PtrPair> m_ptrs; ox::Vector<PtrPair> m_ptrs;
ox::Vector<UnionIdxTracker, 8> m_unionIdx = {{}}; ox::Vector<UnionIdxTracker, 8> m_unionIdx = {{}};
class AllocStackItem {
public:
PtrType restore = 0;
ox::ios_base::seekdir seekdir = ox::ios_base::end;
constexpr AllocStackItem(PtrType pRestore, ox::ios_base::seekdir pSeekdir = ox::ios_base::end) noexcept:
restore(pRestore), seekdir(pSeekdir) {}
};
ox::Vector<AllocStackItem, 8> m_allocStack;
constexpr Preloader() noexcept: m_writer(&m_buff) {} constexpr Preloader() noexcept: m_writer(&m_buff) {}
@ -86,7 +95,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
template<typename T> template<typename T>
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
constexpr ox::Error startAlloc(std::size_t sz) noexcept; constexpr ox::Result<std::size_t> startAlloc(std::size_t sz) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz, std::size_t restore) noexcept;
constexpr ox::Error endAlloc() noexcept; constexpr ox::Error endAlloc() noexcept;
@ -156,7 +167,10 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val)); return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
return {}; const PtrType a = startAlloc(sizeOf<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> || ox::is_same_v<T, ox::ModelValueVector>) { } else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) {
return fieldVector(name, val); return fieldVector(name, val);
} else { } else {
@ -188,7 +202,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
} else { } else {
a = restore; a = restore;
} }
vecVal.items = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(a) + PlatSpec::RomStart); vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart);
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
oxReturnError(m_writer.write(val->data(), sz)); oxReturnError(m_writer.write(val->data(), sz));
oxReturnError(m_writer.seekp(restore)); oxReturnError(m_writer.seekp(restore));
@ -230,14 +244,30 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept {
oxRequire(p, ox::allocate(&m_writer, sz)); oxRequire(a, ox::allocate(&m_writer, sz));
return m_writer.seekp(p); m_allocStack.emplace_back(m_writer.tellp());
oxReturnError(m_writer.seekp(a));
return a;
}
template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz, std::size_t restore) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
m_allocStack.emplace_back(restore, ox::ios_base::beg);
oxReturnError(m_writer.seekp(a));
return a;
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept { constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
if (m_allocStack.empty()) {
return m_writer.seekp(0, ox::ios_base::end); return m_writer.seekp(0, ox::ios_base::end);
}
const auto &si = m_allocStack.back().unwrap();
oxReturnError(m_writer.seekp(si.restore, si.seekdir));
m_allocStack.pop_back();
return {};
} }
template<typename PlatSpec> template<typename PlatSpec>