completely remove EnginePaths::resolve

This commit is contained in:
MihailRis 2025-02-04 12:35:19 +03:00
parent b955ae59c1
commit a653b063e6
12 changed files with 67 additions and 106 deletions

View File

@ -147,7 +147,7 @@ void LevelScreen::saveWorldPreview() {
worldRenderer->draw(ctx, camera, false, true, 0.0f, postProcessing.get()); worldRenderer->draw(ctx, camera, false, true, 0.0f, postProcessing.get());
auto image = postProcessing->toImage(); auto image = postProcessing->toImage();
image->flipY(); image->flipY();
imageio::write(paths.resolve("world:preview.png").string(), image.get()); imageio::write("world:preview.png", image.get());
} catch (const std::exception& err) { } catch (const std::exception& err) {
logger.error() << err.what(); logger.error() << err.what();
} }

View File

@ -10,6 +10,18 @@ namespace fs = std::filesystem;
static debug::Logger logger("io-stdfs"); static debug::Logger logger("io-stdfs");
StdfsDevice::StdfsDevice(fs::path root, bool createDirectory)
: root(std::move(root)) {
if (createDirectory && !fs::is_directory(this->root)) {
std::error_code ec;
fs::create_directories(this->root, ec);
if (ec) {
logger.error() << "error creating root directory " << this->root
<< ": " << ec.message();
}
}
}
fs::path StdfsDevice::resolve(std::string_view path) { fs::path StdfsDevice::resolve(std::string_view path) {
return root / fs::u8path(path); return root / fs::u8path(path);
} }
@ -54,7 +66,13 @@ bool StdfsDevice::isfile(std::string_view path) {
void StdfsDevice::mkdirs(std::string_view path) { void StdfsDevice::mkdirs(std::string_view path) {
auto resolved = resolve(path); auto resolved = resolve(path);
fs::create_directories(resolved);
std::error_code ec;
fs::create_directories(resolved, ec);
if (ec) {
logger.error() << "error creating directory " << resolved << ": "
<< ec.message();
}
} }
bool StdfsDevice::remove(std::string_view path) { bool StdfsDevice::remove(std::string_view path) {

View File

@ -3,7 +3,7 @@
namespace io { namespace io {
class StdfsDevice : public Device { class StdfsDevice : public Device {
public: public:
StdfsDevice(std::filesystem::path root) : root(std::move(root)) {} StdfsDevice(std::filesystem::path root, bool createDirectory = true);
std::filesystem::path resolve(std::string_view path) override; std::filesystem::path resolve(std::string_view path) override;
void write(std::string_view path, const void* data, size_t size) override; void write(std::string_view path, const void* data, size_t size) override;

View File

@ -20,8 +20,8 @@ static debug::Logger logger("engine-paths");
static inline auto SCREENSHOTS_FOLDER = std::filesystem::u8path("screenshots"); static inline auto SCREENSHOTS_FOLDER = std::filesystem::u8path("screenshots");
static inline auto CONTENT_FOLDER = std::filesystem::u8path("content"); static inline auto CONTENT_FOLDER = std::filesystem::u8path("content");
static inline auto WORLDS_FOLDER = std::filesystem::u8path("worlds"); static inline auto WORLDS_FOLDER = std::filesystem::u8path("worlds");
static inline auto CONFIG_FOLDER = std::filesystem::u8path("config"); static inline auto CONFIG_FOLDER = io::path("config");
static inline auto EXPORT_FOLDER = std::filesystem::u8path("export"); static inline auto EXPORT_FOLDER = io::path("export");
static inline auto CONTROLS_FILE = std::filesystem::u8path("controls.toml"); static inline auto CONTROLS_FILE = std::filesystem::u8path("controls.toml");
static inline auto SETTINGS_FILE = std::filesystem::u8path("settings.toml"); static inline auto SETTINGS_FILE = std::filesystem::u8path("settings.toml");
@ -52,7 +52,7 @@ static io::path toCanonic(io::path path) {
} }
void EnginePaths::prepare() { void EnginePaths::prepare() {
io::set_device("res", std::make_shared<io::StdfsDevice>(resourcesFolder)); io::set_device("res", std::make_shared<io::StdfsDevice>(resourcesFolder, false));
io::set_device("user", std::make_shared<io::StdfsDevice>(userFilesFolder)); io::set_device("user", std::make_shared<io::StdfsDevice>(userFilesFolder));
if (!io::is_directory("res:")) { if (!io::is_directory("res:")) {
@ -60,10 +60,6 @@ void EnginePaths::prepare() {
resourcesFolder.string() + " is not a directory" resourcesFolder.string() + " is not a directory"
); );
} }
if (!io::is_directory("user:")) {
io::create_directories("user:");
}
logger.info() << "resources folder: " << fs::canonical(resourcesFolder).u8string(); logger.info() << "resources folder: " << fs::canonical(resourcesFolder).u8string();
logger.info() << "user files folder: " << fs::canonical(userFilesFolder).u8string(); logger.info() << "user files folder: " << fs::canonical(userFilesFolder).u8string();
@ -71,14 +67,10 @@ void EnginePaths::prepare() {
if (!io::is_directory(contentFolder)) { if (!io::is_directory(contentFolder)) {
io::create_directories(contentFolder); io::create_directories(contentFolder);
} }
auto exportFolder = io::path("user:") / EXPORT_FOLDER;
if (!io::is_directory(exportFolder)) { io::create_subdevice("core", "res", "");
io::create_directories(exportFolder); io::create_subdevice("export", "user", EXPORT_FOLDER);
} io::create_subdevice("config", "user", CONFIG_FOLDER);
auto configFolder = io::path("user:") / CONFIG_FOLDER;
if (!io::is_directory(configFolder)) {
io::create_directories(configFolder);
}
} }
const std::filesystem::path& EnginePaths::getUserFilesFolder() const { const std::filesystem::path& EnginePaths::getUserFilesFolder() const {
@ -187,7 +179,16 @@ void EnginePaths::setCurrentWorldFolder(io::path folder) {
} }
void EnginePaths::setContentPacks(std::vector<ContentPack>* contentPacks) { void EnginePaths::setContentPacks(std::vector<ContentPack>* contentPacks) {
// Remove previous content entry-points
for (const auto& pack : *this->contentPacks) {
io::remove_device(pack.id);
}
this->contentPacks = contentPacks; this->contentPacks = contentPacks;
// Create content devices
for (const auto& pack : *contentPacks) {
auto parent = pack.folder.entryPoint();
io::create_subdevice(pack.id, parent, pack.folder);
}
} }
std::tuple<std::string, std::string> EnginePaths::parsePath(std::string_view path) { std::tuple<std::string, std::string> EnginePaths::parsePath(std::string_view path) {
@ -200,45 +201,6 @@ std::tuple<std::string, std::string> EnginePaths::parsePath(std::string_view pat
return {prefix, filename}; return {prefix, filename};
} }
// TODO: remove
io::path EnginePaths::resolve(
const std::string& path, bool throwErr
) const {
auto [prefix, filename] = EnginePaths::parsePath(path);
if (prefix.empty()) {
throw files_access_error("no entry point specified");
}
filename = toCanonic(filename).string();
if (prefix == "core") {
return io::path("res:") / filename;
}
if (prefix == "res" || prefix == "user" || prefix == "script") {
return prefix + ":" + filename;
}
if (prefix == "config") {
return getConfigFolder() / filename;
}
if (prefix == "world") {
return currentWorldFolder / filename;
}
if (prefix == "export") {
return io::path("user:") / EXPORT_FOLDER / filename;
}
if (contentPacks) {
for (auto& pack : *contentPacks) {
if (pack.id == prefix) {
return pack.folder / filename;
}
}
}
if (throwErr) {
throw files_access_error("unknown entry point '" + prefix + "'");
}
return filename;
}
ResPaths::ResPaths(io::path mainRoot, std::vector<PathsRoot> roots) ResPaths::ResPaths(io::path mainRoot, std::vector<PathsRoot> roots)
: mainRoot(std::move(mainRoot)), roots(std::move(roots)) { : mainRoot(std::move(mainRoot)), roots(std::move(roots)) {
} }

View File

@ -43,8 +43,6 @@ public:
std::vector<io::path> scanForWorlds() const; std::vector<io::path> scanForWorlds() const;
io::path resolve(const std::string& path, bool throwErr = true) const;
static std::tuple<std::string, std::string> parsePath(std::string_view view); static std::tuple<std::string, std::string> parsePath(std::string_view view);
static inline auto CONFIG_DEFAULTS = static inline auto CONFIG_DEFAULTS =

View File

@ -23,6 +23,10 @@ void io::set_device(const std::string& name, std::shared_ptr<io::Device> device)
devices[name] = device; devices[name] = device;
} }
void io::remove_device(const std::string& name) {
devices.erase(name);
}
std::shared_ptr<io::Device> io::get_device(const std::string& name) { std::shared_ptr<io::Device> io::get_device(const std::string& name) {
const auto& found = devices.find(name); const auto& found = devices.find(name);
if (found == devices.end()) { if (found == devices.end()) {

View File

@ -16,6 +16,7 @@ namespace io {
class Device; class Device;
void set_device(const std::string& name, std::shared_ptr<Device> device); void set_device(const std::string& name, std::shared_ptr<Device> device);
void remove_device(const std::string& name);
std::shared_ptr<Device> get_device(const std::string& name); std::shared_ptr<Device> get_device(const std::string& name);
Device& require_device(const std::string& name); Device& require_device(const std::string& name);

View File

@ -259,8 +259,7 @@ static int l_load_texture(lua::State* L) {
} }
static int l_open_folder(lua::State* L) { static int l_open_folder(lua::State* L) {
auto path = engine->getPaths().resolve(lua::require_string(L, 1)); platform::open_folder(io::resolve(lua::require_string(L, 1)));
platform::open_folder(io::resolve(path));
return 0; return 0;
} }

View File

@ -13,17 +13,6 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
using namespace scripting; using namespace scripting;
static io::path resolve_path(const std::string& path) {
return engine->getPaths().resolve(path);
}
static io::path resolve_path_soft(const std::string& path) {
if (path.find(':') == std::string::npos) {
return "";
}
return engine->getPaths().resolve(path, false);
}
static int l_find(lua::State* L) { static int l_find(lua::State* L) {
auto path = lua::require_string(L, 1); auto path = lua::require_string(L, 1);
try { try {
@ -34,12 +23,12 @@ static int l_find(lua::State* L) {
} }
static int l_resolve(lua::State* L) { static int l_resolve(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
return lua::pushstring(L, path.string()); return lua::pushstring(L, path.string());
} }
static int l_read(lua::State* L) { static int l_read(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
if (io::is_regular_file(path)) { if (io::is_regular_file(path)) {
return lua::pushstring(L, io::read_string(path)); return lua::pushstring(L, io::read_string(path));
} }
@ -53,9 +42,8 @@ static std::set<std::string> writeable_entry_points {
}; };
static io::path get_writeable_path(lua::State* L) { static io::path get_writeable_path(lua::State* L) {
std::string rawpath = lua::require_string(L, 1); io::path path = lua::require_string(L, 1);
io::path path = resolve_path(rawpath); auto entryPoint = path.entryPoint();
auto entryPoint = rawpath.substr(0, rawpath.find(':'));
if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) { if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) {
throw std::runtime_error("access denied"); throw std::runtime_error("access denied");
} }
@ -70,9 +58,8 @@ static int l_write(lua::State* L) {
} }
static int l_remove(lua::State* L) { static int l_remove(lua::State* L) {
std::string rawpath = lua::require_string(L, 1); io::path path = lua::require_string(L, 1);
io::path path = resolve_path(rawpath); auto entryPoint = path.entryPoint();
auto entryPoint = rawpath.substr(0, rawpath.find(':'));
if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) { if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) {
throw std::runtime_error("access denied"); throw std::runtime_error("access denied");
} }
@ -80,9 +67,8 @@ static int l_remove(lua::State* L) {
} }
static int l_remove_tree(lua::State* L) { static int l_remove_tree(lua::State* L) {
std::string rawpath = lua::require_string(L, 1); io::path path = lua::require_string(L, 1);
io::path path = resolve_path(rawpath); auto entryPoint = path.entryPoint();
auto entryPoint = rawpath.substr(0, rawpath.find(':'));
if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) { if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) {
throw std::runtime_error("access denied"); throw std::runtime_error("access denied");
} }
@ -90,23 +76,19 @@ static int l_remove_tree(lua::State* L) {
} }
static int l_exists(lua::State* L) { static int l_exists(lua::State* L) {
io::path path = resolve_path_soft(lua::require_string(L, 1)); return lua::pushboolean(L, io::exists(lua::require_string(L, 1)));
return lua::pushboolean(L, io::exists(path));
} }
static int l_isfile(lua::State* L) { static int l_isfile(lua::State* L) {
const char* string =lua::require_string(L, 1); return lua::pushboolean(L, io::is_regular_file(lua::require_string(L, 1)));
io::path path = resolve_path_soft(string);
return lua::pushboolean(L, io::is_regular_file(path));
} }
static int l_isdir(lua::State* L) { static int l_isdir(lua::State* L) {
io::path path = resolve_path_soft(lua::require_string(L, 1)); return lua::pushboolean(L, io::is_directory(lua::require_string(L, 1)));
return lua::pushboolean(L, io::is_directory(path));
} }
static int l_length(lua::State* L) { static int l_length(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
if (io::exists(path)) { if (io::exists(path)) {
return lua::pushinteger(L, io::file_size(path)); return lua::pushinteger(L, io::file_size(path));
} else { } else {
@ -115,17 +97,17 @@ static int l_length(lua::State* L) {
} }
static int l_mkdir(lua::State* L) { static int l_mkdir(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
return lua::pushboolean(L, io::create_directories(path)); // FIXME return lua::pushboolean(L, io::create_directories(path)); // FIXME
} }
static int l_mkdirs(lua::State* L) { static int l_mkdirs(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
return lua::pushboolean(L, io::create_directories(path)); return lua::pushboolean(L, io::create_directories(path));
} }
static int l_read_bytes(lua::State* L) { static int l_read_bytes(lua::State* L) {
io::path path = resolve_path(lua::require_string(L, 1)); io::path path = lua::require_string(L, 1);
if (io::is_regular_file(path)) { if (io::is_regular_file(path)) {
size_t length = static_cast<size_t>(io::file_size(path)); size_t length = static_cast<size_t>(io::file_size(path));
@ -177,7 +159,7 @@ static int l_list(lua::State* L) {
if (dirname.find(':') == std::string::npos) { if (dirname.find(':') == std::string::npos) {
return l_list_all_res(L, dirname); return l_list_all_res(L, dirname);
} }
io::path path = resolve_path(dirname); io::path path = dirname;
if (!io::is_directory(path)) { if (!io::is_directory(path)) {
throw std::runtime_error( throw std::runtime_error(
util::quote(path.string()) + " is not a directory" util::quote(path.string()) + " is not a directory"
@ -238,9 +220,8 @@ static int l_read_combined_object(lua::State* L) {
} }
static int l_is_writeable(lua::State* L) { static int l_is_writeable(lua::State* L) {
std::string rawpath = lua::require_string(L, 1); io::path path = lua::require_string(L, 1);
io::path path = resolve_path(rawpath); auto entryPoint = path.entryPoint();
auto entryPoint = rawpath.substr(0, rawpath.find(':'));
if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) { if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) {
return lua::pushboolean(L, false); return lua::pushboolean(L, false);
} }

View File

@ -14,7 +14,7 @@ using namespace scripting;
static int l_save_fragment(lua::State* L) { static int l_save_fragment(lua::State* L) {
const auto& paths = engine->getPaths(); const auto& paths = engine->getPaths();
auto fragment = lua::touserdata<lua::LuaVoxelFragment>(L, 1); auto fragment = lua::touserdata<lua::LuaVoxelFragment>(L, 1);
auto file = paths.resolve(lua::require_string(L, 2), true); auto file = lua::require_string(L, 2);
auto map = fragment->getFragment()->serialize(); auto map = fragment->getFragment()->serialize();
auto bytes = json::to_binary(map, true); auto bytes = json::to_binary(map, true);
io::write_bytes(file, bytes.data(), bytes.size()); io::write_bytes(file, bytes.data(), bytes.size());
@ -35,9 +35,7 @@ static int l_create_fragment(lua::State* L) {
} }
static int l_load_fragment(lua::State* L) { static int l_load_fragment(lua::State* L) {
const auto& paths = engine->getPaths(); io::path path = lua::require_string(L, 1);
auto filename = lua::require_string(L, 1);
auto path = paths.resolve(filename);
if (!io::exists(path)) { if (!io::exists(path)) {
throw std::runtime_error("file "+path.string()+" does not exist"); throw std::runtime_error("file "+path.string()+" does not exist");
} }

View File

@ -808,15 +808,15 @@ static int l_gui_alert(lua::State* L) {
} }
static int l_gui_load_document(lua::State* L) { static int l_gui_load_document(lua::State* L) {
auto filename = lua::require_string(L, 1); io::path filename = lua::require_string(L, 1);
auto alias = lua::require_string(L, 2); auto alias = lua::require_string(L, 2);
auto args = lua::tovalue(L, 3); auto args = lua::tovalue(L, 3);
auto documentPtr = UiDocument::read( auto documentPtr = UiDocument::read(
scripting::get_root_environment(), scripting::get_root_environment(),
alias, alias,
engine->getPaths().resolve(filename), filename,
filename filename.string()
); );
auto document = documentPtr.get(); auto document = documentPtr.get();
engine->getAssets()->store(std::move(documentPtr), alias); engine->getAssets()->store(std::move(documentPtr), alias);

View File

@ -52,7 +52,7 @@ const float* LuaHeightmap::getValues() const {
static int l_dump(lua::State* L) { static int l_dump(lua::State* L) {
const auto& paths = scripting::engine->getPaths(); const auto& paths = scripting::engine->getPaths();
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) { if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
auto file = paths.resolve(require_string(L, 2)); io::path file = require_string(L, 2);
uint w = heightmap->getWidth(); uint w = heightmap->getWidth();
uint h = heightmap->getHeight(); uint h = heightmap->getHeight();
ImageData image(ImageFormat::rgb888, w, h); ImageData image(ImageFormat::rgb888, w, h);