mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-23 07:13:44 +02:00
Handle disposal when deserializing save states in libretro builds
This commit is contained in:
parent
1f5d90822c
commit
6f472fb732
22 changed files with 250 additions and 129 deletions
|
@ -237,7 +237,7 @@ binding_base::object::~object() {
|
|||
if (typenum > typenum_table_size) {
|
||||
std::abort();
|
||||
}
|
||||
typenum_table[typenum - 1].destructor(inner.ptr);
|
||||
typenum_table[typenum - 1].destroy(inner.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ void binding_base::destroy_object(wasm_objkey_t key) {
|
|||
if (object.typenum == 0 || object.typenum > typenum_table_size) {
|
||||
std::abort();
|
||||
}
|
||||
typenum_table[object.typenum - 1].destructor(object.inner.ptr);
|
||||
typenum_table[object.typenum - 1].destroy(object.inner.ptr);
|
||||
object.typenum = 0;
|
||||
object.inner.next = next_free_objkey;
|
||||
next_free_objkey = key;
|
||||
|
|
|
@ -199,10 +199,14 @@ namespace mkxp_sandbox {
|
|||
}
|
||||
|
||||
struct typenum_table_entry {
|
||||
void *(*constructor)();
|
||||
void (*destructor)(void *self);
|
||||
void *(*construct)();
|
||||
void (*destroy)(void *self);
|
||||
void (*destroy_without_signal)(void *self);
|
||||
void (*dispose_without_signal)(void *self);
|
||||
bool (*disposed)(void *self);
|
||||
bool (*serialize)(const void *self, void *&data, wasm_size_t &max_size);
|
||||
bool (*deserialize)(void *self, const void *&data, wasm_size_t &max_size);
|
||||
void (*deserialize_end)(void *self);
|
||||
};
|
||||
|
||||
extern const struct typenum_table_entry typenum_table[];
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
|
||||
#include "binding-util.h"
|
||||
#include "sharedstate.h"
|
||||
#include <boost/type_traits/is_detected.hpp>
|
||||
|
||||
using namespace mkxp_sandbox;
|
||||
|
||||
template <typename T> static typename std::enable_if<std::is_constructible<T>::value, void *>::type constructor() {
|
||||
template <typename T> static typename std::enable_if<std::is_constructible<T>::value, void *>::type construct() {
|
||||
return new T;
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<!std::is_constructible<T>::value && std::is_constructible<T, Exception &>::value, void *>::type constructor() {
|
||||
template <typename T> static typename std::enable_if<!std::is_constructible<T>::value && std::is_constructible<T, Exception &>::value, void *>::type construct() {
|
||||
Exception e;
|
||||
T *obj = new T(e);
|
||||
if (e.is_ok()) {
|
||||
|
@ -39,12 +40,40 @@ template <typename T> static typename std::enable_if<!std::is_constructible<T>::
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T> static void destructor(void *self) {
|
||||
template <typename T> static void destroy(void *self) {
|
||||
if (self != nullptr) {
|
||||
delete (T *)self;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<std::is_base_of<Disposable, T>::value>::type destroy_without_signal(void *self) {
|
||||
if (self != nullptr) {
|
||||
((T *)self)->wasDisposed.disconnect_all();
|
||||
delete (T *)self;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<!std::is_base_of<Disposable, T>::value>::type destroy_without_signal(void *self) {
|
||||
destroy<T>(self);
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<std::is_base_of<Disposable, T>::value>::type dispose_without_signal(void *self) {
|
||||
if (self != nullptr) {
|
||||
((T *)self)->wasDisposed.disconnect_all();
|
||||
((T *)self)->dispose();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<!std::is_base_of<Disposable, T>::value>::type dispose_without_signal(void *self) {}
|
||||
|
||||
template <typename T> static typename std::enable_if<std::is_base_of<Disposable, T>::value, bool>::type disposed(void *self) {
|
||||
return self == nullptr || ((T *)self)->isDisposed();
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<!std::is_base_of<Disposable, T>::value, bool>::type disposed(void *self) {
|
||||
return self == nullptr;
|
||||
}
|
||||
|
||||
template <typename T> static bool serialize(const void *self, void *&data, wasm_size_t &max_size) {
|
||||
return ((const T *)self)->sandbox_serialize(data, max_size);
|
||||
}
|
||||
|
@ -53,7 +82,15 @@ template <typename T> static bool deserialize(void *self, const void *&data, was
|
|||
return ((T *)self)->sandbox_deserialize(data, max_size);
|
||||
}
|
||||
|
||||
#define _SANDBOX_DEF_TYPENUM_TABLE_ENTRY(_r, _data, T) {constructor<T>, destructor<T>, serialize<T>, deserialize<T>},
|
||||
template <typename T> using deserialize_end_declaration = decltype(std::declval<T *>()->sandbox_deserialize_end());
|
||||
|
||||
template <typename T> static typename std::enable_if<boost::is_detected<deserialize_end_declaration, T>::value>::type deserialize_end(void *self) {
|
||||
((T *)self)->sandbox_deserialize_end();
|
||||
}
|
||||
|
||||
template <typename T> static typename std::enable_if<!boost::is_detected<deserialize_end_declaration, T>::value>::type deserialize_end(void *self) {}
|
||||
|
||||
#define _SANDBOX_DEF_TYPENUM_TABLE_ENTRY(_r, _data, T) {construct<T>, destroy<T>, destroy_without_signal<T>, dispose_without_signal<T>, disposed<T>, serialize<T>, deserialize<T>, deserialize_end<T>},
|
||||
extern const struct typenum_table_entry mkxp_sandbox::typenum_table[SANDBOX_NUM_TYPENUMS] = {BOOST_PP_SEQ_FOR_EACH(_SANDBOX_DEF_TYPENUM_TABLE_ENTRY, _, SANDBOX_TYPENUM_TYPES)};
|
||||
extern const wasm_size_t mkxp_sandbox::typenum_table_size = SANDBOX_NUM_TYPENUMS;
|
||||
|
||||
|
|
|
@ -84,11 +84,11 @@ bool sandbox_object_deser_info::set_ptr(void *ptr, wasm_size_t typenum) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void *sandbox_object_deser_info::get_ptr() {
|
||||
void *sandbox_object_deser_info::get_ptr() const {
|
||||
return exists ? ptr : nullptr;
|
||||
}
|
||||
|
||||
wasm_size_t sandbox_object_deser_info::get_typenum() {
|
||||
wasm_size_t sandbox_object_deser_info::get_typenum() const {
|
||||
return typenum;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ namespace mkxp_sandbox {
|
|||
return true;
|
||||
}
|
||||
bool set_ptr(void *ptr, wasm_size_t typenum);
|
||||
void *get_ptr();
|
||||
wasm_size_t get_typenum();
|
||||
void *get_ptr() const;
|
||||
wasm_size_t get_typenum() const;
|
||||
|
||||
private:
|
||||
// If `exists` is true, this is a pointer to the object. Otherwise, this is a `std::vector<void **>` of pointers that are waiting to point to the object.
|
||||
|
@ -76,8 +76,8 @@ namespace mkxp_sandbox {
|
|||
extern std::unordered_map<wasm_size_t, struct sandbox_object_deser_info> objects_deser;
|
||||
extern std::unordered_map<wasm_size_t, struct sandbox_object_deser_info> extra_objects_deser;
|
||||
|
||||
template <typename T> using sandbox_serialize_member_declaration = decltype(std::declval<const T &>().sandbox_serialize(std::declval<void *&>(), std::declval<wasm_size_t &>()));
|
||||
template <typename T> using sandbox_deserialize_member_declaration = decltype(std::declval<T &>().sandbox_deserialize(std::declval<const void *&>(), std::declval<wasm_size_t &>()));
|
||||
template <typename T> using sandbox_serialize_member_declaration = decltype(std::declval<const T *>()->sandbox_serialize(std::declval<void *&>(), std::declval<wasm_size_t &>()));
|
||||
template <typename T> using sandbox_deserialize_member_declaration = decltype(std::declval<T *>()->sandbox_deserialize(std::declval<const void *&>(), std::declval<wasm_size_t &>()));
|
||||
|
||||
template <typename T> typename std::enable_if<std::is_same<T, bool>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size);
|
||||
template <typename T> typename std::enable_if<std::is_enum<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size);
|
||||
|
@ -228,7 +228,7 @@ namespace mkxp_sandbox {
|
|||
for (auto &pair : extra_objects_deser) {
|
||||
struct sandbox_object_deser_info &info = pair.second;
|
||||
if (info.get_ref_count() == 0 && info.get_ptr() != nullptr) {
|
||||
typenum_table[info.get_typenum() - 1].destructor(info.get_ptr());
|
||||
typenum_table[info.get_typenum() - 1].destroy(info.get_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
59
src/core.cpp
59
src/core.cpp
|
@ -1669,7 +1669,11 @@ extern "C" RETRO_API bool retro_serialize(void *data, size_t len) {
|
|||
num_free_objects = 0;
|
||||
}
|
||||
if (!sandbox_serialize(object.typenum, data, max_size)) SER_OBJECTS_END_FAIL;
|
||||
if (!typenum_table[object.typenum - 1].serialize(object.inner.ptr, data, max_size)) SER_OBJECTS_END_FAIL;
|
||||
bool disposed = typenum_table[object.typenum - 1].disposed(object.inner.ptr);
|
||||
if (!sandbox_serialize(disposed, data, max_size)) SER_OBJECTS_END_FAIL;
|
||||
if (!disposed) {
|
||||
if (!typenum_table[object.typenum - 1].serialize(object.inner.ptr, data, max_size)) SER_OBJECTS_END_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num_free_objects > 0) {
|
||||
|
@ -1835,31 +1839,50 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) {
|
|||
wasm_size_t num_free_objects;
|
||||
if (!::sandbox_deserialize(num_free_objects, data, max_size)) DESER_OBJECTS_END_FAIL;
|
||||
if (object_key - 1 + num_free_objects > num_objects || object_key + num_free_objects < object_key) DESER_OBJECTS_END_FAIL;
|
||||
|
||||
// Destroy objects that currently exist but don't exist in the save state
|
||||
for (wasm_size_t i = object_key; i < object_key + num_free_objects; ++i) {
|
||||
auto &object = sb()->objects[i - 1];
|
||||
if (object.typenum > 0) {
|
||||
if (object.typenum > SANDBOX_NUM_TYPENUMS) {
|
||||
std::abort();
|
||||
}
|
||||
typenum_table[object.typenum - 1].destructor(object.inner.ptr);
|
||||
typenum_table[object.typenum - 1].destroy_without_signal(object.inner.ptr);
|
||||
object.typenum = 0;
|
||||
}
|
||||
object.inner.next = sb()->next_free_objkey;
|
||||
sb()->next_free_objkey = i;
|
||||
}
|
||||
|
||||
object_key += num_free_objects;
|
||||
} else {
|
||||
if (typenum > SANDBOX_NUM_TYPENUMS) DESER_OBJECTS_END_FAIL;
|
||||
|
||||
bool should_be_disposed;
|
||||
if (!sandbox_deserialize(should_be_disposed, data, max_size)) return false;
|
||||
|
||||
// Destroy and recreate objects that don't match the type in the save state, or are currently disposed but not disposed in the save state
|
||||
auto &object = sb()->objects[object_key - 1];
|
||||
if (object.typenum > 0 && object.typenum != typenum) {
|
||||
typenum_table[object.typenum - 1].destructor(object.inner.ptr);
|
||||
bool currently_disposed = object.typenum == 0 || typenum_table[object.typenum - 1].disposed(object.inner.ptr);
|
||||
bool should_create = object.typenum != typenum || (currently_disposed && !should_be_disposed);
|
||||
bool should_destroy = should_create && object.typenum > 0;
|
||||
if (should_destroy) {
|
||||
typenum_table[object.typenum - 1].destroy_without_signal(object.inner.ptr);
|
||||
}
|
||||
if (object.typenum != typenum) {
|
||||
if (should_create) {
|
||||
object.typenum = typenum;
|
||||
object.inner.ptr = typenum_table[typenum - 1].constructor();
|
||||
object.inner.ptr = typenum_table[typenum - 1].construct();
|
||||
if (object.inner.ptr == nullptr) DESER_OBJECTS_END_FAIL;
|
||||
}
|
||||
if (!typenum_table[typenum - 1].deserialize(object.inner.ptr, data, max_size)) DESER_OBJECTS_END_FAIL;
|
||||
|
||||
// Deserialize the object
|
||||
if (!should_be_disposed) {
|
||||
if (!typenum_table[typenum - 1].deserialize(object.inner.ptr, data, max_size)) DESER_OBJECTS_END_FAIL;
|
||||
} else if (!currently_disposed) {
|
||||
typenum_table[typenum - 1].dispose_without_signal(object.inner.ptr);
|
||||
}
|
||||
|
||||
// Add it to the pointer map so that other objects that reference this one will be able to see it
|
||||
auto it = objects_deser.find(object_key);
|
||||
if (it == objects_deser.end()) {
|
||||
objects_deser.emplace(object_key, sandbox_object_deser_info(object.inner.ptr, typenum));
|
||||
|
@ -1878,24 +1901,40 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) {
|
|||
wasm_size_t typenum;
|
||||
if (!sandbox_deserialize(typenum, data, max_size)) DESER_OBJECTS_END_FAIL;
|
||||
if (typenum != get_typenum<Color>::value && typenum != get_typenum<Tone>::value && typenum != get_typenum<Rect>::value) DESER_OBJECTS_END_FAIL;
|
||||
void *ptr = typenum_table[typenum - 1].constructor();
|
||||
|
||||
// Create a new object
|
||||
void *ptr = typenum_table[typenum - 1].construct();
|
||||
if (ptr == nullptr) DESER_OBJECTS_END_FAIL;
|
||||
|
||||
// Deserialize into the newly created object
|
||||
if (!typenum_table[typenum - 1].deserialize(ptr, data, max_size)) {
|
||||
typenum_table[typenum - 1].destructor(ptr);
|
||||
typenum_table[typenum - 1].destroy(ptr);
|
||||
DESER_OBJECTS_END_FAIL;
|
||||
}
|
||||
|
||||
// Add it to the pointer map so that other objects that reference this one will be able to see it
|
||||
auto it = extra_objects_deser.find(extra_object_key);
|
||||
if (it == extra_objects_deser.end()) {
|
||||
extra_objects_deser.emplace(extra_object_key, sandbox_object_deser_info(ptr, typenum));
|
||||
} else {
|
||||
if (!it->second.set_ptr(ptr, typenum)) {
|
||||
typenum_table[typenum - 1].destructor(ptr);
|
||||
typenum_table[typenum - 1].destroy(ptr);
|
||||
DESER_OBJECTS_END_FAIL;
|
||||
}
|
||||
}
|
||||
++extra_object_key;
|
||||
}
|
||||
|
||||
for (const auto &object : sb()->objects) {
|
||||
if (object.typenum > 0 && !typenum_table[object.typenum - 1].disposed(object.inner.ptr)) {
|
||||
typenum_table[object.typenum - 1].deserialize_end(object.inner.ptr);
|
||||
}
|
||||
}
|
||||
for (const auto &pair : extra_objects_deser) {
|
||||
if (pair.second.get_typenum() > 0 && !typenum_table[pair.second.get_typenum() - 1].disposed(pair.second.get_ptr())) {
|
||||
typenum_table[pair.second.get_typenum() - 1].deserialize_end(pair.second.get_ptr());
|
||||
}
|
||||
}
|
||||
DESER_OBJECTS_END;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3392,9 +3392,6 @@ void Bitmap::loresDisposal()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool Bitmap::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->path, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize((int32_t)width(), data, max_size)) return false;
|
||||
|
@ -3422,16 +3419,6 @@ bool Bitmap::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
|||
|
||||
bool Bitmap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->path, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->gl.width, data, max_size)) return false;
|
||||
|
@ -3460,4 +3447,15 @@ bool Bitmap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bitmap::sandbox_deserialize_end()
|
||||
{
|
||||
if (isDisposed()) return;
|
||||
if (p->selfLores != nullptr) {
|
||||
loresDispCon = p->selfLores->wasDisposed.connect(&Bitmap::loresDisposal, this);
|
||||
if (p->selfLores->isDisposed()) {
|
||||
p->selfLores->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -199,6 +199,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -353,9 +353,6 @@ void Plane::releaseResources()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool Plane::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->opacity, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->blendType, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize((int32_t)p->ox, data, max_size)) return false;
|
||||
|
@ -375,16 +372,6 @@ bool Plane::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
|||
|
||||
bool Plane::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->opacity, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->blendType, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->ox, data, max_size)) return false;
|
||||
|
@ -401,4 +388,17 @@ bool Plane::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &ma
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Plane::sandbox_deserialize_end()
|
||||
{
|
||||
sandbox_deserialize_end_viewport_element();
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->bitmap != nullptr) {
|
||||
p->bitmapDispCon = p->bitmap->wasDisposed.connect(&PlanePrivate::bitmapDisposal, p);
|
||||
if (p->bitmap->isDisposed()) {
|
||||
p->bitmap->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -859,9 +859,6 @@ void Sprite::releaseResources()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool Sprite::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->quad, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->trans, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->mirrored, data, max_size)) return false;
|
||||
|
@ -899,16 +896,6 @@ bool Sprite::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
|||
|
||||
bool Sprite::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->quad, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->trans, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->mirrored, data, max_size)) return false;
|
||||
|
@ -943,4 +930,17 @@ bool Sprite::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sprite::sandbox_deserialize_end()
|
||||
{
|
||||
sandbox_deserialize_end_viewport_element();
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->bitmap != nullptr) {
|
||||
p->bitmapDispCon = p->bitmap->wasDisposed.connect(&SpritePrivate::bitmapDisposal, p);
|
||||
if (p->bitmap->isDisposed()) {
|
||||
p->bitmap->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -1475,9 +1475,6 @@ bool Tilemap::Autotiles::sandbox_deserialize(const void *&data, mkxp_sandbox::wa
|
|||
|
||||
bool Tilemap::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->visible, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->origin, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->dispPos, data, max_size)) return false;
|
||||
|
@ -1530,16 +1527,6 @@ bool Tilemap::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size
|
|||
|
||||
bool Tilemap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->visible, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->origin, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->dispPos, data, max_size)) return false;
|
||||
|
@ -1597,4 +1584,33 @@ bool Tilemap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tilemap::sandbox_deserialize_end()
|
||||
{
|
||||
if (isDisposed()) return;
|
||||
p->elem.ground->sandbox_deserialize_end_viewport_element();
|
||||
|
||||
for (size_t i = 0; i < zlayersMax; ++i) {
|
||||
if (isDisposed()) return;
|
||||
p->elem.zlayers[i]->sandbox_deserialize_end_viewport_element();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < autotileCount; ++i) {
|
||||
if (isDisposed()) return;
|
||||
if (p->autotiles[i] != nullptr) {
|
||||
p->autotilesDispCon[i] = p->autotiles[i]->wasDisposed.connect( [i, this] { p->atlasContentsDisposal(i); } );
|
||||
if (p->autotiles[i]->isDisposed()) {
|
||||
p->autotiles[i]->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->tileset != nullptr) {
|
||||
p->tilesetDispCon = p->tileset->wasDisposed.connect(&TilemapPrivate::tilesetDisposal, p);
|
||||
if (p->tileset->isDisposed()) {
|
||||
p->tileset->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -633,9 +633,6 @@ bool TilemapVX::BitmapArray::sandbox_deserialize(const void *&data, mkxp_sandbox
|
|||
|
||||
bool TilemapVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->origin, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->dispPos, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->groundVert, data, max_size)) return false;
|
||||
|
@ -660,16 +657,6 @@ bool TilemapVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_si
|
|||
|
||||
bool TilemapVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->origin, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->dispPos, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->groundVert, data, max_size)) return false;
|
||||
|
@ -703,4 +690,23 @@ bool TilemapVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TilemapVX::sandbox_deserialize_end()
|
||||
{
|
||||
if (isDisposed()) return;
|
||||
p->above.sandbox_deserialize_end_viewport_element();
|
||||
|
||||
if (isDisposed()) return;
|
||||
p->sandbox_deserialize_end_viewport_element();
|
||||
|
||||
for (size_t i = 0; i < BM_COUNT; ++i) {
|
||||
if (isDisposed()) return;
|
||||
if (p->bitmaps[i] != nullptr) {
|
||||
p->bmDisposedCons[i] = p->bitmaps[i]->wasDisposed.connect( [i, this] { p->atlasDisposal(i); } );
|
||||
if (p->bitmaps[i]->isDisposed()) {
|
||||
p->bitmaps[i]->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -232,9 +232,6 @@ void Viewport::releaseResources()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool Viewport::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->screenRect, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->isOnScreen, data, max_size)) return false;
|
||||
if (!sandbox_serialize_scene_element(data, max_size)) return false;
|
||||
|
@ -247,16 +244,6 @@ bool Viewport::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz
|
|||
|
||||
bool Viewport::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->screenRect, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->isOnScreen, data, max_size)) return false;
|
||||
if (!sandbox_deserialize_scene_element(data, max_size)) return false;
|
||||
|
@ -323,4 +310,14 @@ bool ViewportElement::sandbox_deserialize_viewport_element(const void *&data, mk
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewportElement::sandbox_deserialize_end_viewport_element()
|
||||
{
|
||||
if (m_viewport != nullptr) {
|
||||
viewportDispCon = m_viewport->wasDisposed.connect(&ViewportElement::viewportElementDisposal, this);
|
||||
if (m_viewport->isDisposed()) {
|
||||
m_viewport->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MXKPZ_RETRO
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize_viewport_element(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize_viewport_element(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end_viewport_element();
|
||||
#endif // MXKPZ_RETRO
|
||||
|
||||
protected:
|
||||
|
|
|
@ -953,9 +953,6 @@ void Window::releaseResources()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool Window::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->bgStretch, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->active, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->pause, data, max_size)) return false;
|
||||
|
@ -985,16 +982,6 @@ bool Window::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
|||
|
||||
bool Window::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->bgStretch, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->active, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->pause, data, max_size)) return false;
|
||||
|
@ -1021,4 +1008,25 @@ bool Window::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::sandbox_deserialize_end()
|
||||
{
|
||||
sandbox_deserialize_end_viewport_element();
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->windowskin != nullptr) {
|
||||
p->windowskinDispCon = p->windowskin->wasDisposed.connect(&WindowPrivate::windowskinDisposal, p);
|
||||
if (p->windowskin->isDisposed()) {
|
||||
p->windowskin->wasDisposed();
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->contents != nullptr) {
|
||||
p->contentsDispCon = p->contents->wasDisposed.connect(&WindowPrivate::contentsDisposal, p);
|
||||
if (p->contents->isDisposed()) {
|
||||
p->contents->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
|
@ -1166,9 +1166,6 @@ void WindowVX::releaseResources()
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool WindowVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const
|
||||
{
|
||||
if (isDisposed()) return mkxp_sandbox::sandbox_serialize(false, data, max_size);
|
||||
if (!mkxp_sandbox::sandbox_serialize(true, data, max_size)) return false;
|
||||
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->active, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->arrowsVisible, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_serialize(p->pause, data, max_size)) return false;
|
||||
|
@ -1202,16 +1199,6 @@ bool WindowVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz
|
|||
|
||||
bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size)
|
||||
{
|
||||
{
|
||||
bool active;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(active, data, max_size)) return false;
|
||||
if (!active) {
|
||||
dispose();
|
||||
return true;
|
||||
}
|
||||
// TODO: undispose
|
||||
}
|
||||
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->active, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->arrowsVisible, data, max_size)) return false;
|
||||
if (!mkxp_sandbox::sandbox_deserialize(p->pause, data, max_size)) return false;
|
||||
|
@ -1242,4 +1229,25 @@ bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowVX::sandbox_deserialize_end()
|
||||
{
|
||||
sandbox_deserialize_end_viewport_element();
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->windowskin != nullptr) {
|
||||
p->windowskinDispCon = p->windowskin->wasDisposed.connect(&WindowVXPrivate::windowskinDisposal, p);
|
||||
if (p->windowskin->isDisposed()) {
|
||||
p->windowskin->wasDisposed();
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisposed()) return;
|
||||
if (p->contents != nullptr) {
|
||||
p->contentsDispCon = p->contents->wasDisposed.connect(&WindowVXPrivate::contentsDisposal, p);
|
||||
if (p->contents->isDisposed()) {
|
||||
p->contents->wasDisposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
#ifdef MKXPZ_RETRO
|
||||
bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
|
||||
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
|
||||
void sandbox_deserialize_end();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue