Added an optional search order enum ("first" or "last") to love.filesystem.setIdentity and love.filesystem.mount (resolves issue #694)

This commit is contained in:
Alex Szpakowski
2013-08-04 00:32:23 -03:00
parent 4d6bdf4857
commit 7a20bbc6c4
5 changed files with 122 additions and 69 deletions
+39 -21
View File
@@ -37,7 +37,7 @@ namespace physfs
Filesystem::Filesystem()
: open_count(0)
, buffer(0)
, isInited(false)
, initialized(false)
, release(false)
, releaseSet(false)
{
@@ -45,11 +45,8 @@ Filesystem::Filesystem()
Filesystem::~Filesystem()
{
if (isInited)
{
isInited = false;
if (initialized)
PHYSFS_deinit();
}
}
const char *Filesystem::getName() const
@@ -61,7 +58,7 @@ void Filesystem::init(const char *arg0)
{
if (!PHYSFS_init(arg0))
throw Exception(PHYSFS_getLastError());
isInited = true;
initialized = true;
}
void Filesystem::setRelease(bool release)
@@ -79,9 +76,9 @@ bool Filesystem::isRelease() const
return release;
}
bool Filesystem::setIdentity(const char *ident)
bool Filesystem::setIdentity(const char *ident, SearchOrder searchorder)
{
if (!isInited)
if (!initialized)
return false;
std::string old_save_path = save_path_full;
@@ -104,15 +101,16 @@ bool Filesystem::setIdentity(const char *ident)
// save_path_relative: ./LOVE/game
// save_path_full: C:\Documents and Settings\user\Application Data/LOVE/game
// We don't want old read-only save paths to accumulate when we set a new
// identity.
if (!old_save_path.empty())
PHYSFS_removeFromSearchPath(old_save_path.c_str());
bool append = (searchorder == SEARCH_ORDER_LAST);
// Try to add the save directory to the search path.
// (No error on fail, it means that the path doesn't exist).
if (PHYSFS_addToSearchPath(save_path_full.c_str(), 0))
{
// We don't want old read-only save paths to accumulate when we set a
// new identity.
if (old_save_path.compare(save_path_full) != 0)
PHYSFS_removeFromSearchPath(old_save_path.c_str());
}
PHYSFS_addToSearchPath(save_path_full.c_str(), append);
return true;
}
@@ -124,7 +122,7 @@ const char *Filesystem::getIdentity() const
bool Filesystem::setSource(const char *source)
{
if (!isInited)
if (!initialized)
return false;
// Check whether directory is already set.
@@ -143,7 +141,7 @@ bool Filesystem::setSource(const char *source)
bool Filesystem::setupWriteDirectory()
{
if (!isInited)
if (!initialized)
return false;
// These must all be set.
@@ -182,9 +180,9 @@ bool Filesystem::setupWriteDirectory()
return true;
}
bool Filesystem::mount(const char *archive, const char *mountpoint)
bool Filesystem::mount(const char *archive, const char *mountpoint, SearchOrder searchorder)
{
if (!isInited || !archive)
if (!initialized || !archive)
return false;
// Not allowed for safety reasons.
@@ -205,12 +203,14 @@ bool Filesystem::mount(const char *archive, const char *mountpoint)
realPath += LOVE_PATH_SEPARATOR;
realPath += archive;
return PHYSFS_mount(realPath.c_str(), mountpoint, 0);
bool append = (searchorder == SEARCH_ORDER_LAST);
return PHYSFS_mount(realPath.c_str(), mountpoint, append);
}
bool Filesystem::unmount(const char *archive)
{
if (!isInited || !archive)
if (!initialized || !archive)
return false;
// Not allowed for safety reasons.
@@ -535,6 +535,24 @@ int64 Filesystem::getSize(const char *filename) const
return size;
}
bool Filesystem::getConstant(const char *in, Filesystem::SearchOrder &out)
{
return orders.find(in, out);
}
bool Filesystem::getConstant(Filesystem::SearchOrder in, const char *&out)
{
return orders.find(in, out);
}
StringMap<Filesystem::SearchOrder, Filesystem::SEARCH_ORDER_MAX_ENUM>::Entry Filesystem::orderEntries[] =
{
{"first", Filesystem::SEARCH_ORDER_FIRST},
{"last", Filesystem::SEARCH_ORDER_LAST},
};
StringMap<Filesystem::SearchOrder, Filesystem::SEARCH_ORDER_MAX_ENUM> Filesystem::orders(Filesystem::orderEntries, sizeof(Filesystem::orderEntries));
} // physfs
} // filesystem
} // love
+53 -38
View File
@@ -31,6 +31,7 @@
#include "common/Module.h"
#include "common/config.h"
#include "common/int.h"
#include "common/StringMap.h"
#include "filesystem/FileData.h"
#include "File.h"
@@ -71,46 +72,19 @@ namespace filesystem
{
namespace physfs
{
class Filesystem : public Module
{
private:
// Counts open files.
int open_count;
// Pointer used for file reads.
char *buffer;
// Contains the current working directory (UTF8).
std::string cwd;
// %APPDATA% on Windows.
std::string appdata;
// This name will be used to create the folder
// in the appdata/userdata folder.
std::string save_identity;
// Full and relative paths of the game save folder.
// (Relative to the %APPDATA% folder, meaning that the
// relative string will look something like: ./LOVE/game)
std::string save_path_relative, save_path_full;
// The full path to the source of the game.
std::string game_source;
// Workaround for machines without PhysFS 2.0
bool isInited;
// Allow saving outside of the LOVE_APPDATA_FOLDER
// for release 'builds'
bool release;
bool releaseSet;
protected:
public:
// love.filesystem.setIdentity("foo", "last")
enum SearchOrder
{
SEARCH_ORDER_FIRST,
SEARCH_ORDER_LAST,
SEARCH_ORDER_MAX_ENUM
};
Filesystem();
~Filesystem();
@@ -134,7 +108,7 @@ public:
* @param ident The name of the game. Will be used to
* to create the folder in the LOVE data folder.
**/
bool setIdentity(const char *ident);
bool setIdentity(const char *ident, SearchOrder searchorder = SEARCH_ORDER_FIRST);
const char *getIdentity() const;
/**
@@ -143,7 +117,8 @@ public:
* @param source Path to a directory or a .love-file.
**/
bool setSource(const char *source);
bool mount(const char *archive, const char *mountpoint);
bool mount(const char *archive, const char *mountpoint, SearchOrder searchorder = SEARCH_ORDER_FIRST);
bool unmount(const char *archive);
/**
@@ -300,6 +275,46 @@ public:
**/
static int lines_i(lua_State *L);
static bool getConstant(const char *in, SearchOrder &out);
static bool getConstant(SearchOrder in, const char *&out);
private:
// Counts open files.
int open_count;
// Pointer used for file reads.
char *buffer;
// Contains the current working directory (UTF8).
std::string cwd;
// %APPDATA% on Windows.
std::string appdata;
// This name will be used to create the folder
// in the appdata/userdata folder.
std::string save_identity;
// Full and relative paths of the game save folder.
// (Relative to the %APPDATA% folder, meaning that the
// relative string will look something like: ./LOVE/game)
std::string save_path_relative, save_path_full;
// The full path to the source of the game.
std::string game_source;
// Workaround for machines without PhysFS 2.0
bool initialized;
// Allow saving outside of the LOVE_APPDATA_FOLDER
// for release 'builds'
bool release;
bool releaseSet;
static StringMap<SearchOrder, SEARCH_ORDER_MAX_ENUM>::Entry orderEntries[];
static StringMap<SearchOrder, SEARCH_ORDER_MAX_ENUM> orders;
}; // Filesystem
} // physfs
@@ -77,7 +77,13 @@ int w_setIdentity(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
if (!instance->setIdentity(arg))
Filesystem::SearchOrder order = Filesystem::SEARCH_ORDER_FIRST;
const char *ostr = lua_isnoneornil(L, 2) ? 0 : lua_tostring(L, 2);
if (ostr && !Filesystem::getConstant(ostr, order))
return luaL_error(L, "Invalid filesystem search order: %s", ostr);
if (!instance->setIdentity(arg, order))
return luaL_error(L, "Could not set write directory.");
return 0;
@@ -104,7 +110,13 @@ int w_mount(lua_State *L)
const char *archive = luaL_checkstring(L, 1);
const char *mountpoint = luaL_checkstring(L, 2);
luax_pushboolean(L, instance->mount(archive, mountpoint));
Filesystem::SearchOrder order = Filesystem::SEARCH_ORDER_FIRST;
const char *ostr = lua_isnoneornil(L, 3) ? 0 : lua_tostring(L, 3);
if (ostr && !Filesystem::getConstant(ostr, order))
return luaL_error(L, "Invalid filesystem search order: %s", ostr);
luax_pushboolean(L, instance->mount(archive, mountpoint, order));
return 1;
}
+5 -2
View File
@@ -294,6 +294,7 @@ function love.init()
},
console = false, -- Only relevant for windows.
identity = false,
identityorder = "first",
release = false,
}
@@ -381,8 +382,10 @@ function love.init()
if love.filesystem then
love.filesystem.setRelease(c.release and is_fused_game)
if c.identity then love.filesystem.setIdentity(c.identity) end
if love.filesystem.exists("main.lua") then require("main") end
love.filesystem.setIdentity(c.identity or love.filesystem.getIdentity(), c.identityorder)
if love.filesystem.exists("main.lua") then
require("main")
end
end
if no_game_code then
+11 -6
View File
@@ -509,6 +509,8 @@ const unsigned char boot_lua[] =
0x66, 0x6f, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2e, 0x0a,
0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65,
0x2c, 0x0a,
0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20,
0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a,
0x09, 0x7d, 0x0a,
0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65,
@@ -652,14 +654,17 @@ const unsigned char boot_lua[] =
0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x28, 0x63, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
0x73, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61,
0x6d, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x74, 0x68,
0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
0x2e, 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x2e, 0x69, 0x64, 0x65,
0x6e, 0x74, 0x69, 0x74, 0x79, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e,
0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28,
0x29, 0x2c, 0x20, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x6f, 0x72, 0x64, 0x65, 0x72,
0x29, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x2e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6c, 0x75,
0x61, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22,
0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x61, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x0a,