mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user