love.graphics.newImage, love.image.newImageData, etc. no longer leave Lua-owned FileData objects floating around waiting to be GC'd when called with filename arguments, resulting in less memory use on startup (resolves issue #890.)

Moved love.filesystem Lua wrapper code from src/modules/filesystem/physfs/ to src/modules/filesystem/.
This commit is contained in:
Alex Szpakowski
2014-06-02 00:22:41 -03:00
parent 4d0bbb97d8
commit 724bdbd296
17 changed files with 215 additions and 177 deletions
+3 -2
View File
@@ -31,11 +31,12 @@ namespace love
{
namespace filesystem
{
namespace physfs
{
extern bool hack_setupWriteDirectory();
namespace physfs
{
File::File(const std::string &filename)
: filename(filename)
, file(0)
@@ -20,6 +20,8 @@
#include "wrap_File.h"
#include "physfs/Filesystem.h"
#include "common/Data.h"
#include "common/Exception.h"
#include "common/int.h"
@@ -28,8 +30,6 @@ namespace love
{
namespace filesystem
{
namespace physfs
{
int luax_ioError(lua_State *L, const char *fmt, ...)
{
@@ -242,7 +242,7 @@ int w_File_lines(lua_State *L)
return luaL_error(L, "Could not open file.");
}
lua_pushcclosure(L, Filesystem::lines_i, 3);
lua_pushcclosure(L, physfs::Filesystem::lines_i, 3);
return 1;
}
@@ -323,6 +323,5 @@ extern "C" int luaopen_file(lua_State *L)
return luax_register_type(L, "File", functions);
}
} // physfs
} // filesystem
} // love
@@ -18,20 +18,17 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
#ifndef LOVE_FILESYSTEM_WRAP_FILE_H
#define LOVE_FILESYSTEM_WRAP_FILE_H
// LOVE
#include "common/runtime.h"
#include "Filesystem.h"
#include "File.h"
namespace love
{
namespace filesystem
{
namespace physfs
{
// Does not use lua_error, so it's safe to call in exception handling code.
int luax_ioError(lua_State *L, const char *fmt, ...);
@@ -53,8 +50,7 @@ int w_File_getBuffer(lua_State *L);
int w_File_getMode(lua_State *L);
extern "C" int luaopen_file(lua_State *L);
} // physfs
} // filesystem
} // love
#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_H
#endif // LOVE_FILESYSTEM_WRAP_FILE_H
@@ -26,8 +26,6 @@ namespace love
{
namespace filesystem
{
namespace physfs
{
FileData *luax_checkfiledata(lua_State *L, int idx)
{
@@ -66,6 +64,5 @@ extern "C" int luaopen_filedata(lua_State *L)
return luax_register_type(L, "FileData", w_FileData_functions);
}
} // physfs
} // filesystem
} // love
@@ -18,28 +18,24 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
#ifndef LOVE_FILESYSTEM_WRAP_FILE_DATA_H
#define LOVE_FILESYSTEM_WRAP_FILE_DATA_H
// LOVE
#include "common/runtime.h"
#include "filesystem/FileData.h"
#include "FileData.h"
namespace love
{
namespace filesystem
{
namespace physfs
{
FileData *luax_checkfiledata(lua_State *L, int idx);
int w_FileData_getFilename(lua_State *L);
int w_FileData_getExtension(lua_State *L);
extern "C" int luaopen_filedata(lua_State *L);
} // physfs
} // filesystem
} // love
#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILE_DATA_H
#endif // LOVE_FILESYSTEM_WRAP_FILE_DATA_H
@@ -20,6 +20,10 @@
// LOVE
#include "wrap_Filesystem.h"
#include "wrap_File.h"
#include "wrap_FileData.h"
#include "physfs/Filesystem.h"
// SDL
#include <SDL_loadso.h>
@@ -28,10 +32,8 @@ namespace love
{
namespace filesystem
{
namespace physfs
{
static Filesystem *instance = 0;
static physfs::Filesystem *instance = 0;
bool hack_setupWriteDirectory()
{
@@ -146,18 +148,73 @@ int w_newFile(lua_State *L)
return 1;
}
FileData *luax_getFileData(lua_State *L, int idx)
{
FileData *data = nullptr;
File *file = nullptr;
if (lua_isstring(L, idx))
{
const char *filename = luaL_checkstring(L, idx);
file = instance->newFile(filename);
}
else if (luax_istype(L, idx, FILESYSTEM_FILE_T))
{
file = luax_checkfile(L, idx);
file->retain();
}
else if (luax_istype(L, idx, FILESYSTEM_FILE_DATA_T))
{
data = luax_checkfiledata(L, idx);
data->retain();
}
if (!data && !file)
{
luaL_argerror(L, idx, "filename, File, or FileData expected");
return nullptr; // Never reached.
}
if (file)
{
bool should_error = false;
// We don't use EXCEPT_GUARD_FINALLY because it returns int.
try
{
data = file->read();
}
catch (love::Exception &e)
{
should_error = true;
lua_pushstring(L, e.what());
}
file->release();
if (should_error)
{
luaL_error(L, "%s", lua_tostring(L, -1));
return nullptr; // Never reached.
}
}
return data;
}
int w_newFileData(lua_State *L)
{
// Single argument: treat as filepath or File.
if (lua_gettop(L) == 1)
{
// We don't use luax_getFileData because we want to use an ioError.
if (lua_isstring(L, 1))
luax_convobj(L, 1, "filesystem", "newFile");
// Get FileData from the File.
if (luax_istype(L, 1, FILESYSTEM_FILE_T))
{
File *file = luax_checktype<File>(L, 1, "File", FILESYSTEM_FILE_T);
File *file = luax_checkfile(L, 1);
FileData *data = 0;
try
@@ -172,7 +229,7 @@ int w_newFileData(lua_State *L)
return 1;
}
else
return luaL_argerror(L, 1, "string or File expected");
return luaL_argerror(L, 1, "filename or File expected");
}
size_t length = 0;
@@ -369,7 +426,7 @@ int w_lines(lua_State *L)
else
return luaL_argerror(L, 1, "expected filename.");
lua_pushcclosure(L, Filesystem::lines_i, 1);
lua_pushcclosure(L, physfs::Filesystem::lines_i, 1);
return 1;
}
@@ -576,32 +633,32 @@ int extloader(lua_State *L)
// List of functions to wrap.
static const luaL_Reg functions[] =
{
{ "init", w_init },
{ "init", w_init },
{ "setFused", w_setFused },
{ "isFused", w_isFused },
{ "setIdentity", w_setIdentity },
{ "setIdentity", w_setIdentity },
{ "getIdentity", w_getIdentity },
{ "setSource", w_setSource },
{ "setSource", w_setSource },
{ "getSource", w_getSource },
{ "mount", w_mount },
{ "unmount", w_unmount },
{ "newFile", w_newFile },
{ "getWorkingDirectory", w_getWorkingDirectory },
{ "getUserDirectory", w_getUserDirectory },
{ "getAppdataDirectory", w_getAppdataDirectory },
{ "getSaveDirectory", w_getSaveDirectory },
{ "newFile", w_newFile },
{ "getWorkingDirectory", w_getWorkingDirectory },
{ "getUserDirectory", w_getUserDirectory },
{ "getAppdataDirectory", w_getAppdataDirectory },
{ "getSaveDirectory", w_getSaveDirectory },
{ "getSourceBaseDirectory", w_getSourceBaseDirectory },
{ "exists", w_exists },
{ "isDirectory", w_isDirectory },
{ "isFile", w_isFile },
{ "createDirectory", w_createDirectory },
{ "remove", w_remove },
{ "read", w_read },
{ "write", w_write },
{ "exists", w_exists },
{ "isDirectory", w_isDirectory },
{ "isFile", w_isFile },
{ "createDirectory", w_createDirectory },
{ "remove", w_remove },
{ "read", w_read },
{ "write", w_write },
{ "append", w_append },
{ "getDirectoryItems", w_getDirectoryItems },
{ "lines", w_lines },
{ "load", w_load },
{ "getDirectoryItems", w_getDirectoryItems },
{ "lines", w_lines },
{ "load", w_load },
{ "getLastModified", w_getLastModified },
{ "getSize", w_getSize },
{ "newFileData", w_newFileData },
@@ -619,7 +676,7 @@ extern "C" int luaopen_love_filesystem(lua_State *L)
{
if (instance == 0)
{
EXCEPT_GUARD(instance = new Filesystem();)
EXCEPT_GUARD(instance = new physfs::Filesystem();)
}
else
instance->retain();
@@ -638,6 +695,5 @@ extern "C" int luaopen_love_filesystem(lua_State *L)
return luax_register_module(L, w);
}
} // physfs
} // filesystem
} // love
@@ -18,20 +18,26 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
#define LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
#ifndef LOVE_FILESYSTEM_WRAP_FILESYSTEM_H
#define LOVE_FILESYSTEM_WRAP_FILESYSTEM_H
// LOVE
#include "Filesystem.h"
#include "wrap_File.h"
#include "wrap_FileData.h"
#include "common/runtime.h"
#include "FileData.h"
namespace love
{
namespace filesystem
{
namespace physfs
{
/**
* Gets FileData at the specified index. If the index contains a filepath or
* a File object, the FileData will be created from that.
* Note that this function retains the FileData object (possibly by creating it),
* so a matching release() is required!
* May trigger a Lua error.
**/
FileData *luax_getFileData(lua_State *L, int idx);
bool hack_setupWriteDirectory();
int w_init(lua_State *L);
@@ -69,8 +75,7 @@ int loader(lua_State *L);
int extloader(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State *L);
} // physfs
} // filesystem
} // love
#endif // LOVE_FILESYSTEM_PHYSFS_WRAP_FILESYSTEM_H
#endif // LOVE_FILESYSTEM_WRAP_FILESYSTEM_H