[turbine] Cleanup type safety code for application data
All checks were successful
Build / build (push) Successful in 2m35s
All checks were successful
Build / build (push) Successful in 2m35s
This commit is contained in:
parent
aa43cb3d8d
commit
82f02896c9
@ -39,20 +39,57 @@ inline ox::FileSystem *rom(Context &ctx) noexcept {
|
|||||||
|
|
||||||
struct WrapBase {
|
struct WrapBase {
|
||||||
virtual ~WrapBase() = default;
|
virtual ~WrapBase() = default;
|
||||||
|
virtual WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
|
||||||
|
virtual operator bool() const noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Wrap: public WrapBase {
|
struct Wrap: public WrapBase {
|
||||||
T *data{};
|
T *data{};
|
||||||
|
Wrap(T *pData) noexcept: data(pData) {
|
||||||
|
}
|
||||||
|
WrapBase *copyTo(ox::Span<char> s) noexcept override {
|
||||||
|
oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
|
||||||
|
return new(s.data()) Wrap{data};
|
||||||
|
}
|
||||||
|
operator bool() const noexcept override {
|
||||||
|
return data != nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void setApplicationDataRaw(Context &ctx, void *applicationData) noexcept;
|
class WrapPtr {
|
||||||
|
private:
|
||||||
|
WrapBase *m_wrapPtr{};
|
||||||
|
ox::Array<char, sizeof(WrapBase) + sizeof(void*)> m_wrapData;
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
inline WrapPtr &operator=(T *ptr) noexcept {
|
||||||
|
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline WrapPtr &operator=(WrapBase &ptr) noexcept {
|
||||||
|
if (ptr) {
|
||||||
|
m_wrapPtr = ptr.copyTo(m_wrapData);
|
||||||
|
} else {
|
||||||
|
m_wrapPtr = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline operator bool() const noexcept {
|
||||||
|
return m_wrapPtr && *m_wrapPtr;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
inline WrapBase *getWrapBase() const noexcept {
|
||||||
|
return m_wrapPtr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void setApplicationDataRaw(Context &ctx, WrapBase &applicationData) noexcept;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void setApplicationData(Context &ctx, T *applicationData) noexcept {
|
void setApplicationData(Context &ctx, T *applicationData) noexcept {
|
||||||
Wrap<T> w;
|
Wrap<T> w(applicationData);
|
||||||
w.data = applicationData;
|
setApplicationDataRaw(ctx, w);
|
||||||
setApplicationDataRaw(ctx, &w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -61,13 +98,14 @@ WrapBase *applicationDataRaw(Context &ctx) noexcept;
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
T *applicationData(Context &ctx) noexcept {
|
T *applicationData(Context &ctx) noexcept {
|
||||||
|
auto const raw = applicationDataRaw(ctx);
|
||||||
#ifdef OX_BARE_METAL
|
#ifdef OX_BARE_METAL
|
||||||
return static_cast<Wrap<T>*>(applicationDataRaw(ctx))->data;
|
auto const out = static_cast<Wrap<T>*>(raw);
|
||||||
#else
|
#else
|
||||||
auto const out = dynamic_cast<Wrap<T>*>(applicationDataRaw(ctx));
|
auto const out = dynamic_cast<Wrap<T>*>(raw);
|
||||||
oxAssert(out, "Cast failed - wrong type");
|
|
||||||
return out->data;
|
|
||||||
#endif
|
#endif
|
||||||
|
oxAssert(out || !raw, "Cast failed - wrong type");
|
||||||
|
return out->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setKeyEventHandler(Context &ctx, KeyEventHandler h) noexcept;
|
void setKeyEventHandler(Context &ctx, KeyEventHandler h) noexcept;
|
||||||
|
@ -18,20 +18,12 @@ keel::Context &keelCtx(Context &ctx) noexcept {
|
|||||||
return ctx.keelCtx;
|
return ctx.keelCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setApplicationDataRaw(Context &ctx, void const*applicationData) noexcept {
|
void setApplicationDataRaw(Context &ctx, WrapBase &applicationData) noexcept {
|
||||||
if (applicationData) {
|
ctx.applicationData = applicationData;
|
||||||
ctx.applicationData.emplace();
|
|
||||||
memcpy(&ctx.applicationData.value(), applicationData, sizeof(Wrap<void>));
|
|
||||||
} else {
|
|
||||||
ctx.applicationData.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapBase *applicationDataRaw(Context &ctx) noexcept {
|
WrapBase *applicationDataRaw(Context &ctx) noexcept {
|
||||||
if (!ctx.applicationData) {
|
return ctx.applicationData.getWrapBase();
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return std::bit_cast<WrapBase*>(&*ctx.applicationData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class Context {
|
|||||||
UpdateHandler updateHandler = [](Context&) -> int {return 0;};
|
UpdateHandler updateHandler = [](Context&) -> int {return 0;};
|
||||||
keel::Context keelCtx;
|
keel::Context keelCtx;
|
||||||
KeyEventHandler keyEventHandler = nullptr;
|
KeyEventHandler keyEventHandler = nullptr;
|
||||||
ox::Optional<std::array<char, sizeof(WrapBase) + sizeof(uintptr_t)>> applicationData;
|
WrapPtr applicationData;
|
||||||
|
|
||||||
// GBA impl data /////////////////////////////////////////////////////////
|
// GBA impl data /////////////////////////////////////////////////////////
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
@ -20,20 +20,12 @@ keel::Context &keelCtx(Context &ctx) noexcept {
|
|||||||
return ctx.keelCtx;
|
return ctx.keelCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setApplicationDataRaw(Context &ctx, void *applicationData) noexcept {
|
void setApplicationDataRaw(Context &ctx, WrapBase &applicationData) noexcept {
|
||||||
if (applicationData) {
|
ctx.applicationData = applicationData;
|
||||||
ctx.applicationData.emplace();
|
|
||||||
memcpy(&ctx.applicationData.value(), applicationData, sizeof(Wrap<void>));
|
|
||||||
} else {
|
|
||||||
ctx.applicationData.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapBase *applicationDataRaw(Context &ctx) noexcept {
|
WrapBase *applicationDataRaw(Context &ctx) noexcept {
|
||||||
if (!ctx.applicationData) {
|
return ctx.applicationData.getWrapBase();
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return std::bit_cast<WrapBase*>(&*ctx.applicationData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Context {
|
|||||||
UpdateHandler updateHandler = [](Context&) -> int {return 0;};
|
UpdateHandler updateHandler = [](Context&) -> int {return 0;};
|
||||||
keel::Context keelCtx;
|
keel::Context keelCtx;
|
||||||
KeyEventHandler keyEventHandler = nullptr;
|
KeyEventHandler keyEventHandler = nullptr;
|
||||||
ox::Optional<std::array<char, sizeof(WrapBase) + sizeof(uintptr_t)>> applicationData;
|
WrapPtr applicationData;
|
||||||
|
|
||||||
// GLFW impl data ////////////////////////////////////////////////////////
|
// GLFW impl data ////////////////////////////////////////////////////////
|
||||||
int uninterruptedRefreshes = 3;
|
int uninterruptedRefreshes = 3;
|
||||||
|
Loading…
Reference in New Issue
Block a user