From 5d5c2f9a961d5dae4c33aee37af3bfb797a2e1a4 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 17 Dec 2018 16:44:13 -0400 Subject: [PATCH] math and data module instances are now deleted when they have no more Lua references (matches the behaviour of other modules.) Fixes the deprecation system not fully restarting when love.event.quit("restart") is called. Resolves issue #1462. --- src/modules/data/DataModule.cpp | 4 ---- src/modules/data/DataModule.h | 7 +----- src/modules/data/wrap_DataModule.cpp | 32 +++++++++++++++++----------- src/modules/math/MathModule.cpp | 5 ----- src/modules/math/MathModule.h | 9 ++------ src/modules/math/wrap_Math.cpp | 22 +++++++++++++------ 6 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/modules/data/DataModule.cpp b/src/modules/data/DataModule.cpp index 7997e47e3..ddf125b28 100644 --- a/src/modules/data/DataModule.cpp +++ b/src/modules/data/DataModule.cpp @@ -213,12 +213,8 @@ void hash(HashFunction::Function function, const char *input, uint64_t size, Has hashfunction->hash(function, input, size, output); } -DataModule DataModule::instance; - DataModule::DataModule() { - // prevent the runtime from free()-ing this - retain(); } DataModule::~DataModule() diff --git a/src/modules/data/DataModule.h b/src/modules/data/DataModule.h index 7b9ae4a3f..d5a0727ac 100644 --- a/src/modules/data/DataModule.h +++ b/src/modules/data/DataModule.h @@ -114,6 +114,7 @@ class DataModule : public Module { public: + DataModule(); virtual ~DataModule(); // Implements Module. @@ -125,12 +126,6 @@ public: ByteData *newByteData(const void *d, size_t size); ByteData *newByteData(void *d, size_t size, bool own); - static DataModule instance; - -private: - - DataModule(); - }; // DataModule } // data diff --git a/src/modules/data/wrap_DataModule.cpp b/src/modules/data/wrap_DataModule.cpp index 770a0b0a6..eac022239 100644 --- a/src/modules/data/wrap_DataModule.cpp +++ b/src/modules/data/wrap_DataModule.cpp @@ -41,6 +41,8 @@ namespace love namespace data { +#define instance() (Module::getInstance(Module::M_DATA)) + ContainerType luax_checkcontainertype(lua_State *L, int idx) { const char *str = luaL_checkstring(L, idx); @@ -60,7 +62,7 @@ int w_newDataView(lua_State *L) if (offset < 0 || size < 0) return luaL_error(L, "DataView offset and size must not be negative."); - DataView *d = DataModule::instance.newDataView(data, (size_t) offset, (size_t) size); + DataView *d = instance()->newDataView(data, (size_t) offset, (size_t) size); luax_pushtype(L, d); d->release(); @@ -89,20 +91,20 @@ int w_newByteData(lua_State *L) return luaL_error(L, "Offset and size arguments must fit within the given Data's size."); const char *bytes = (const char *) data->getData() + offset; - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(bytes, (size_t) size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(bytes, (size_t) size); }); } else if (lua_type(L, 1) == LUA_TSTRING) { size_t size = 0; const char *data = luaL_checklstring(L, 1, &size); - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(data, size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(data, size); }); } else { lua_Integer size = luaL_checkinteger(L, 1); if (size <= 0) return luaL_error(L, "Data size must be a positive number."); - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData((size_t) size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData((size_t) size); }); } luax_pushtype(L, d); @@ -184,7 +186,7 @@ int w_decompress(lua_State *L) if (ctype == CONTAINER_DATA) { ByteData *data = nullptr; - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(rawbytes, rawsize, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(rawbytes, rawsize, true); }); luax_pushtype(L, Data::type, data); data->release(); } @@ -228,9 +230,9 @@ int w_encode(lua_State *L) { ByteData *data = nullptr; if (dst != nullptr) - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(dst, dstlen, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(dst, dstlen, true); }); else - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(0); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(0); }); luax_pushtype(L, Data::type, data); data->release(); @@ -277,9 +279,9 @@ int w_decode(lua_State *L) { ByteData *data = nullptr; if (dst != nullptr) - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(dst, dstlen, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(dst, dstlen, true); }); else - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(0); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(0); }); luax_pushtype(L, Data::type, data); data->release(); @@ -331,7 +333,7 @@ int w_pack(lua_State *L) if (ctype == CONTAINER_DATA) { Data *d = nullptr; - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(b.nelems); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(b.nelems); }); memcpy(d->getData(), b.ptr, d->getSize()); lua53_cleanupbuffer(&b); @@ -392,10 +394,16 @@ static const lua_CFunction types[] = extern "C" int luaopen_love_data(lua_State *L) { - DataModule::instance.retain(); + DataModule *instance = instance(); + if (instance == nullptr) + { + luax_catchexcept(L, [&](){ instance = new DataModule(); }); + } + else + instance->retain(); WrappedModule w; - w.module = &DataModule::instance; + w.module = instance; w.name = "data"; w.type = &Module::type; w.functions = functions; diff --git a/src/modules/math/MathModule.cpp b/src/modules/math/MathModule.cpp index 02147e4f5..65e5ace92 100644 --- a/src/modules/math/MathModule.cpp +++ b/src/modules/math/MathModule.cpp @@ -199,14 +199,9 @@ float linearToGamma(float c) return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } -Math Math::instance; - Math::Math() : rng() { - // prevent the runtime from free()-ing this - retain(); - RandomGenerator::Seed seed; seed.b64 = (uint64) time(nullptr); rng.setSeed(seed); diff --git a/src/modules/math/MathModule.h b/src/modules/math/MathModule.h index e5b264d7b..06ca7b8c6 100644 --- a/src/modules/math/MathModule.h +++ b/src/modules/math/MathModule.h @@ -91,12 +91,9 @@ static float noise4(float x, float y, float z, float w); class Math : public Module { -private: - - RandomGenerator rng; - public: + Math(); virtual ~Math(); RandomGenerator *getRandomGenerator() @@ -128,11 +125,9 @@ public: return "love.math"; } - static Math instance; - private: - Math(); + RandomGenerator rng; }; // Math diff --git a/src/modules/math/wrap_Math.cpp b/src/modules/math/wrap_Math.cpp index 50969d72a..ca955e610 100644 --- a/src/modules/math/wrap_Math.cpp +++ b/src/modules/math/wrap_Math.cpp @@ -44,9 +44,11 @@ namespace love namespace math { +#define instance() (Module::getInstance(Module::M_MATH)) + int w__getRandomGenerator(lua_State *L) { - RandomGenerator *t = Math::instance.getRandomGenerator(); + RandomGenerator *t = instance()->getRandomGenerator(); luax_pushtype(L, t); return 1; } @@ -57,7 +59,7 @@ int w_newRandomGenerator(lua_State *L) if (lua_gettop(L) > 0) s = luax_checkrandomseed(L, 1); - RandomGenerator *t = Math::instance.newRandomGenerator(); + RandomGenerator *t = instance()->newRandomGenerator(); if (lua_gettop(L) > 0) { @@ -116,7 +118,7 @@ int w_newBezierCurve(lua_State *L) } } - BezierCurve *curve = Math::instance.newBezierCurve(points); + BezierCurve *curve = instance()->newBezierCurve(points); luax_pushtype(L, curve); curve->release(); return 1; @@ -127,7 +129,7 @@ int w_newTransform(lua_State *L) Transform *t = nullptr; if (lua_isnoneornil(L, 1)) - t = Math::instance.newTransform(); + t = instance()->newTransform(); else { float x = (float) luaL_checknumber(L, 1); @@ -139,7 +141,7 @@ int w_newTransform(lua_State *L) float oy = (float) luaL_optnumber(L, 7, 0.0); float kx = (float) luaL_optnumber(L, 8, 0.0); float ky = (float) luaL_optnumber(L, 9, 0.0); - t = Math::instance.newTransform(x, y, a, sx, sy, ox, oy, kx, ky); + t = instance()->newTransform(x, y, a, sx, sy, ox, oy, kx, ky); } luax_pushtype(L, t); @@ -478,10 +480,16 @@ static const lua_CFunction types[] = extern "C" int luaopen_love_math(lua_State *L) { - Math::instance.retain(); + Math *instance = instance(); + if (instance == nullptr) + { + luax_catchexcept(L, [&](){ instance = new Math(); }); + } + else + instance->retain(); WrappedModule w; - w.module = &Math::instance; + w.module = instance; w.name = "math"; w.type = &Module::type; w.functions = functions;