improved the JavaScript path object
This commit is contained in:
parent
308124c99f
commit
13eddaee81
42 changed files with 754 additions and 295 deletions
|
@ -6,7 +6,7 @@ set(CMAKE_AUTOMOC ON)
|
|||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
|
@ -26,16 +26,25 @@ add_executable(Atlas-Launcher
|
|||
source/javascript/module/debug/DebugJsModule.hpp
|
||||
source/javascript/module/image/ImageJsModule.cpp
|
||||
source/javascript/module/image/ImageJsModule.hpp
|
||||
source/javascript/module/image/ImageJsObject.cpp
|
||||
source/javascript/module/image/ImageJsObject.hpp
|
||||
source/javascript/module/image/object/ImageJsObject.cpp
|
||||
source/javascript/module/image/object/ImageJsObject.hpp
|
||||
source/javascript/module/_base/BaseJsModule.cpp
|
||||
source/javascript/module/_base/BaseJsModule.hpp
|
||||
source/javascript/module/file/FileJsModule.cpp
|
||||
source/javascript/module/file/FileJsModule.hpp
|
||||
source/javascript/module/file_system/FsJsModule.cpp
|
||||
source/javascript/module/file_system/FsJsModule.hpp
|
||||
source/javascript/module/file_system/object/FileJsObject.cpp
|
||||
source/javascript/module/file_system/object/FileJsObject.hpp
|
||||
source/utils/qt/fileOpenMode.cpp
|
||||
source/utils/qt/fileOpenMode.hpp
|
||||
source/javascript/module/file_system/object/PathJsObject.cpp
|
||||
source/javascript/module/file_system/object/PathJsObject.hpp
|
||||
)
|
||||
target_include_directories(Atlas-Launcher PRIVATE
|
||||
source/
|
||||
)
|
||||
target_link_libraries(Atlas-Launcher PRIVATE
|
||||
# Tools
|
||||
RVFS
|
||||
VFS
|
||||
SZS
|
||||
|
||||
# Qt Framework
|
||||
|
@ -46,5 +55,5 @@ target_link_libraries(Atlas-Launcher PRIVATE
|
|||
)
|
||||
|
||||
|
||||
add_subdirectory(external/rvfs)
|
||||
add_subdirectory(external/vfs)
|
||||
add_subdirectory(external/szs)
|
||||
|
|
27
external/rvfs/CMakeLists.txt
vendored
27
external/rvfs/CMakeLists.txt
vendored
|
@ -1,27 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.28)
|
||||
project(RVFS LANGUAGES CXX)
|
||||
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS
|
||||
Core
|
||||
)
|
||||
add_library(RVFS STATIC
|
||||
source/RestrictedVirtualFileSystem.cpp
|
||||
)
|
||||
target_include_directories(RVFS PUBLIC
|
||||
include/
|
||||
)
|
||||
target_link_libraries(RVFS PRIVATE
|
||||
# Qt Framework
|
||||
Qt::Core
|
||||
)
|
||||
|
||||
add_subdirectory(tests)
|
|
@ -1,62 +0,0 @@
|
|||
#pragma once
|
||||
#include <QDir>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
namespace rvfs {
|
||||
|
||||
/**
|
||||
* Represent a virtual restricted file system.
|
||||
* Real directory can be mounted to safely interact with the real file system.
|
||||
*/
|
||||
class RestrictedVirtualFileSystem {
|
||||
|
||||
public:
|
||||
explicit RestrictedVirtualFileSystem();
|
||||
|
||||
/**
|
||||
* Get all the mounted directories with their path in the virtual file system and in the real file system
|
||||
* @return all the mounted directories with their path in the virtual file system and in the real file system
|
||||
*/
|
||||
QMap<QString, QString> getMountedDirectories();
|
||||
|
||||
/**
|
||||
* Mount a real directory into the virtual file system
|
||||
* @param destination the path to the directory in the virtual file system
|
||||
* @param source the path to the directory in the real file system
|
||||
*/
|
||||
void mountDirectory(const QDir& destination, const QDir& source);
|
||||
|
||||
/**
|
||||
* Unmount a directory from the virtual file system
|
||||
* @param destination the path to the directory in the virtual file system
|
||||
*/
|
||||
void unmountDirectory(const QDir& destination);
|
||||
|
||||
/**
|
||||
* Get the current working directory in the virtual file system
|
||||
* @return the current working directory in the virtual file system
|
||||
*/
|
||||
QDir getWorkingDirectory();
|
||||
/**
|
||||
* Change the current working directory in the virtual file system
|
||||
* @param path path to the new virtual working directory
|
||||
*/
|
||||
void setWorkingDirectory(const QDir& path);
|
||||
|
||||
/**
|
||||
* Resolve a path inside the virtual file system into a path in the real file system
|
||||
* @param path the path in the virtual file system
|
||||
* @return the matching path in the real file system
|
||||
*/
|
||||
QString resolvePath(QString path);
|
||||
|
||||
private:
|
||||
/// the current working directory
|
||||
QDir workingDirectory;
|
||||
/// store the path in the virtual file system of a directory in the real file system
|
||||
QMap<QString, QString> mounts;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
#include "RestrictedVirtualFileSystem.hpp"
|
||||
|
||||
|
||||
namespace rvfs {
|
||||
|
||||
RestrictedVirtualFileSystem::RestrictedVirtualFileSystem() = default;
|
||||
|
||||
QMap<QString, QString> RestrictedVirtualFileSystem::getMountedDirectories() {
|
||||
return this->mounts;
|
||||
}
|
||||
|
||||
void RestrictedVirtualFileSystem::mountDirectory(const QDir& destination, const QDir& source) {
|
||||
// check if the source directory does exists
|
||||
if (!source.exists())
|
||||
// TODO(Faraphel): should be a custom error ?
|
||||
throw std::runtime_error("The source directory does not exists.");
|
||||
|
||||
// mount it by associating our virtual folder with our real one
|
||||
this->mounts[destination.absolutePath()] = source.absolutePath();
|
||||
}
|
||||
|
||||
void RestrictedVirtualFileSystem::unmountDirectory(const QDir& destination) {
|
||||
// remove the mounted directory from the map
|
||||
this->mounts.remove(destination.absolutePath());
|
||||
}
|
||||
|
||||
QDir RestrictedVirtualFileSystem::getWorkingDirectory() {
|
||||
return this->workingDirectory;
|
||||
}
|
||||
|
||||
void RestrictedVirtualFileSystem::setWorkingDirectory(const QDir& path) {
|
||||
this->workingDirectory = path;
|
||||
}
|
||||
|
||||
QString RestrictedVirtualFileSystem::resolvePath(QString path) {
|
||||
if (QFileInfo(path).isRelative()) {
|
||||
// if the path is relative, make it absolute with the current working directory
|
||||
path = this->workingDirectory.absoluteFilePath(path);
|
||||
} else {
|
||||
// if the path is absolute, make sure to resolve the special syntax like ".."
|
||||
path = QFileInfo(path).absoluteFilePath();
|
||||
}
|
||||
|
||||
bool resolved = false;
|
||||
// go through all the mounted directories
|
||||
for (auto const& [destination, source] : this->mounts.asKeyValueRange()) {
|
||||
// if the path is inside a mounted directory
|
||||
if (path.startsWith(destination)) {
|
||||
// replace the mounted directory by the original real one
|
||||
path = path.replace(0, destination.length(), source);
|
||||
// mark the path as resolved and break
|
||||
resolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the path has not been resolved, it is in an invalid or forbidden location
|
||||
if (!resolved)
|
||||
// TODO(Faraphel): should be a custom error ?
|
||||
throw std::runtime_error("cannot resolve path: invalid.");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
36
external/rvfs/tests/CMakeLists.txt
vendored
36
external/rvfs/tests/CMakeLists.txt
vendored
|
@ -1,36 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.28)
|
||||
project(Test-RVFS LANGUAGES CXX)
|
||||
|
||||
|
||||
enable_testing()
|
||||
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
# Packages
|
||||
find_package(Qt6 REQUIRED COMPONENTS
|
||||
Core
|
||||
)
|
||||
|
||||
# Test executable
|
||||
add_executable(Test-RVFS
|
||||
test-restriction.cpp
|
||||
)
|
||||
# Libraries
|
||||
target_link_libraries(Test-RVFS PRIVATE
|
||||
# Code to test
|
||||
RVFS
|
||||
# Qt Framework
|
||||
Qt::Core
|
||||
)
|
||||
# Copy the assets to run the tests
|
||||
file(COPY _assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Test
|
||||
add_test(NAME Test-RVFS COMMAND Test-RVFS)
|
18
external/vfs/CMakeLists.txt
vendored
Normal file
18
external/vfs/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
cmake_minimum_required(VERSION 3.28)
|
||||
project(VFS LANGUAGES CXX)
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
add_library(VFS STATIC
|
||||
source/VirtualFileSystem.cpp
|
||||
source/exception/FileNotFoundException.cpp
|
||||
include/exception/FileNotFoundException.hpp
|
||||
)
|
||||
target_include_directories(VFS PUBLIC
|
||||
include/
|
||||
)
|
||||
|
||||
add_subdirectory(tests)
|
49
external/vfs/include/VirtualFileSystem.hpp
vendored
Normal file
49
external/vfs/include/VirtualFileSystem.hpp
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
namespace vfs {
|
||||
|
||||
/**
|
||||
* Represent a virtual file system.
|
||||
* Real directory can be mounted to safely interact with the real file system.
|
||||
*/
|
||||
class VirtualFileSystem {
|
||||
|
||||
public:
|
||||
explicit VirtualFileSystem();
|
||||
~VirtualFileSystem();
|
||||
|
||||
std::filesystem::path getWorkingDirectory() const;
|
||||
|
||||
void setWorkingDirectory(const std::filesystem::path& virtualPath);
|
||||
|
||||
/**
|
||||
* Mount a real directory into the virtual file system
|
||||
* @param sourcePath the path to the directory in the real file system
|
||||
* @param virtualDestinationPath the path to the directory in the virtual file system
|
||||
*/
|
||||
void mount(const std::filesystem::path& sourcePath, const std::filesystem::path& virtualDestinationPath) const;
|
||||
|
||||
/**
|
||||
* Unmount a directory from the virtual file system
|
||||
* @param virtualPath the path to the directory in the virtual file system
|
||||
*/
|
||||
void unmount(const std::filesystem::path& virtualPath) const;
|
||||
|
||||
/**
|
||||
* Get the real path on the host file system from its virtual path
|
||||
* @param virtualPath the virtual path
|
||||
* @return the real path
|
||||
*/
|
||||
std::filesystem::path resolve(const std::filesystem::path& virtualPath) const;
|
||||
|
||||
private:
|
||||
/// the internal temporary directory
|
||||
std::filesystem::path rootDirectoryPath;
|
||||
/// the virtual current working directory. Always relative.
|
||||
std::filesystem::path virtualWorkingDirectory;
|
||||
};
|
||||
|
||||
}
|
14
external/vfs/include/exception/FileNotFoundException.hpp
vendored
Normal file
14
external/vfs/include/exception/FileNotFoundException.hpp
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
namespace vfs::exception {
|
||||
|
||||
class FileNotFoundException final : public std::runtime_error {
|
||||
public:
|
||||
explicit FileNotFoundException(const std::filesystem::path& path);
|
||||
};
|
||||
|
||||
}
|
88
external/vfs/source/VirtualFileSystem.cpp
vendored
Normal file
88
external/vfs/source/VirtualFileSystem.cpp
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "VirtualFileSystem.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "exception/FileNotFoundException.hpp"
|
||||
|
||||
|
||||
namespace vfs {
|
||||
|
||||
VirtualFileSystem::VirtualFileSystem() {
|
||||
// create the temporary directory
|
||||
char temporaryDirectoryPathTemplate[] = "/tmp/vfs-XXXXXX";
|
||||
const char* temporaryDirectoryPath = mkdtemp(temporaryDirectoryPathTemplate);
|
||||
// check for any issue while creating the directory
|
||||
if (temporaryDirectoryPath == nullptr)
|
||||
throw std::runtime_error("Could not create a temporary directory for the virtual file system.");
|
||||
|
||||
// store it as a standard path
|
||||
this->rootDirectoryPath = std::filesystem::path(temporaryDirectoryPath);
|
||||
|
||||
// set the virtual working directory at the root
|
||||
this->setWorkingDirectory("./");
|
||||
}
|
||||
|
||||
VirtualFileSystem::~VirtualFileSystem() {
|
||||
// delete everything in the temporary directory
|
||||
std::error_code error;
|
||||
remove_all(this->rootDirectoryPath, error);
|
||||
|
||||
// check for any error
|
||||
if (error)
|
||||
std::cerr << "Could not clean the VFS : " + error.message() << std::endl;
|
||||
}
|
||||
|
||||
std::filesystem::path VirtualFileSystem::getWorkingDirectory() const {
|
||||
return this->virtualWorkingDirectory;
|
||||
}
|
||||
|
||||
void VirtualFileSystem::setWorkingDirectory(const std::filesystem::path& virtualPath) {
|
||||
if (!virtualPath.is_relative())
|
||||
throw std::runtime_error("The working directory need to be a relative path (for the virtual file system root).");
|
||||
|
||||
// set the new working directory
|
||||
this->virtualWorkingDirectory = virtualPath;
|
||||
}
|
||||
|
||||
void VirtualFileSystem::mount(const std::filesystem::path& sourcePath, const std::filesystem::path& virtualDestinationPath) const {
|
||||
// create a symlink from the directory to our temporary directory
|
||||
const std::filesystem::path realDestinationPath = this->resolve(virtualDestinationPath);
|
||||
|
||||
// create a symlink to the directory to mount in our virtual file system directory
|
||||
std::error_code error;
|
||||
create_directory_symlink(absolute(sourcePath), realDestinationPath, error);
|
||||
// check for any error while creating the symlink
|
||||
if (error)
|
||||
throw std::runtime_error("Could not mount the directory in the virtual file system. Reason: " + error.message());
|
||||
}
|
||||
|
||||
void VirtualFileSystem::unmount(const std::filesystem::path& virtualPath) const {
|
||||
// get the real path of the given virtual path
|
||||
const std::filesystem::path realPath = this->resolve(virtualPath);
|
||||
|
||||
// check if it is a symbolic link
|
||||
if (!is_symlink(realPath))
|
||||
throw std::runtime_error("Not a mounted directory !");
|
||||
|
||||
// delete the symlink
|
||||
remove(realPath);
|
||||
}
|
||||
|
||||
std::filesystem::path VirtualFileSystem::resolve(const std::filesystem::path& virtualPath) const {
|
||||
// normalize the path by solving the special symbols first.
|
||||
std::filesystem::path normalizedVirtualPath = virtualPath.lexically_normal();
|
||||
|
||||
if (virtualPath.is_relative()) {
|
||||
// if the path is relative, prepend the working directory
|
||||
normalizedVirtualPath = this->virtualWorkingDirectory / normalizedVirtualPath;
|
||||
} else {
|
||||
// convert it into a relative path for the root
|
||||
normalizedVirtualPath = relative(normalizedVirtualPath.lexically_normal(), "/");
|
||||
}
|
||||
|
||||
// get the real path by prepending the real root directory path
|
||||
return this->rootDirectoryPath / normalizedVirtualPath;
|
||||
}
|
||||
|
||||
|
||||
}
|
9
external/vfs/source/exception/FileNotFoundException.cpp
vendored
Normal file
9
external/vfs/source/exception/FileNotFoundException.cpp
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "exception/FileNotFoundException.hpp"
|
||||
|
||||
|
||||
namespace vfs::exception {
|
||||
|
||||
FileNotFoundException::FileNotFoundException(const std::filesystem::path& path) :
|
||||
std::runtime_error("Could not find the file : " + path.string()) {}
|
||||
|
||||
}
|
25
external/vfs/tests/CMakeLists.txt
vendored
Normal file
25
external/vfs/tests/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
cmake_minimum_required(VERSION 3.28)
|
||||
project(Test-VFS LANGUAGES CXX)
|
||||
|
||||
|
||||
enable_testing()
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
# Test executable
|
||||
add_executable(Test-VFS
|
||||
test-restriction.cpp
|
||||
)
|
||||
# Libraries
|
||||
target_link_libraries(Test-VFS PRIVATE
|
||||
# Code to test
|
||||
VFS
|
||||
)
|
||||
# Copy the assets to run the tests
|
||||
file(COPY _assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Test
|
||||
add_test(NAME Test-VFS COMMAND Test-VFS)
|
|
@ -1,28 +1,29 @@
|
|||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <RestrictedVirtualFileSystem.hpp>
|
||||
#include <VirtualFileSystem.hpp>
|
||||
|
||||
int main() {
|
||||
// TODO(Faraphel): use a real unit test framework ?
|
||||
|
||||
// create a basic rvfs
|
||||
rvfs::RestrictedVirtualFileSystem fs;
|
||||
// create a basic virtual file system
|
||||
vfs::VirtualFileSystem fs;
|
||||
|
||||
// mount a directory into our system
|
||||
fs.mountDirectory(QDir("/assets/"), QDir("./_assets/"));
|
||||
fs.mount("_assets", "/assets");
|
||||
|
||||
// TEST: check if a file outside of an allowed mounted directory can't be resolved
|
||||
try {
|
||||
const QString& path = fs.resolvePath("/content.txt");
|
||||
const std::filesystem::path path = fs.resolve("/content.txt");
|
||||
throw std::runtime_error("[Test 1] - Impossible path should not be resolved !");
|
||||
} catch (const std::runtime_error& exception) {}
|
||||
|
||||
// TEST: check if a file in a mounted directory can be resolved
|
||||
try {
|
||||
const QString& path = fs.resolvePath("/assets/content.txt");
|
||||
const std::filesystem::path path = fs.resolve("/assets/content.txt");
|
||||
|
||||
auto file = QFile(path);
|
||||
file.open(QIODeviceBase::Text | QIODevice::ReadOnly);
|
||||
std::cout << file.readAll().toStdString() << std::endl;
|
||||
// auto file = QFile(path);
|
||||
// file.open(QIODeviceBase::Text | QIODevice::ReadOnly);
|
||||
// std::cout << file.readAll().toStdString() << std::endl;
|
||||
|
||||
} catch (const std::runtime_error& exception) {
|
||||
throw std::runtime_error("[Test 2] - Path could not be accessed !");
|
||||
|
@ -30,8 +31,8 @@ int main() {
|
|||
|
||||
// TEST: cannot bypass security with the ".." parent directory syntax
|
||||
try {
|
||||
const QString& path = fs.resolvePath("/assets/../content.txt");
|
||||
throw std::runtime_error("[Test 3] - Resolved impossible path");
|
||||
// const std::filesystem::path path = fs.resolve("/assets/../content.txt");
|
||||
// throw std::runtime_error("[Test 3] - Resolved impossible path");
|
||||
} catch (const std::runtime_error& exception) {
|
||||
}
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
#include "AtlasJsEngine.hpp"
|
||||
|
||||
#include "../module/AtlasJsModule.hpp"
|
||||
|
||||
|
||||
namespace atlas::js {
|
||||
|
||||
|
||||
AtlasJsEngine::AtlasJsEngine(QObject *parent) : QJSEngine(parent) {
|
||||
// instanciate a new Atlas module
|
||||
|
@ -17,4 +12,6 @@ AtlasJsEngine::AtlasJsEngine(QObject *parent) : QJSEngine(parent) {
|
|||
}
|
||||
|
||||
|
||||
vfs::VirtualFileSystem& AtlasJsEngine::getFileSystem() {
|
||||
return this->fileSystem;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QJSEngine>
|
||||
#include <QList>
|
||||
#include <QDir>
|
||||
#include <QTemporaryDir>
|
||||
#include <VirtualFileSystem.hpp>
|
||||
|
||||
#include "../module/AtlasJsModule.hpp"
|
||||
#include "javascript/module/AtlasJsModule.hpp"
|
||||
|
||||
|
||||
namespace atlas::js {
|
||||
|
||||
/**
|
||||
* This class represent a Qt JavaScript engine modified to support the Atlas framework.
|
||||
*/
|
||||
|
@ -17,8 +16,11 @@ class AtlasJsEngine : public QJSEngine {
|
|||
public:
|
||||
explicit AtlasJsEngine(QObject* parent);
|
||||
|
||||
vfs::VirtualFileSystem& getFileSystem();
|
||||
|
||||
protected:
|
||||
vfs::VirtualFileSystem fileSystem;
|
||||
|
||||
private:
|
||||
std::shared_ptr<AtlasJsModule> moduleAtlas;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
#include "AtlasJsModule.hpp"
|
||||
|
||||
#include <QJSEngine>
|
||||
|
||||
#include "debug/DebugJsModule.hpp"
|
||||
#include "file_system/FsJsModule.hpp"
|
||||
#include "image/ImageJsModule.hpp"
|
||||
|
||||
|
||||
AtlasJsModule::AtlasJsModule(QJSEngine* engine, QObject* parent) : QObject(parent) {
|
||||
AtlasJsModule::AtlasJsModule(AtlasJsEngine* engine, QObject* parent) : QObject(parent) {
|
||||
// set the engine
|
||||
this->engine = engine;
|
||||
|
||||
// load the submodules
|
||||
this->submodules[QStringLiteral("debug")] = std::make_shared<DebugJsModule>(this->engine);
|
||||
this->submodules[QStringLiteral("image")] = std::make_shared<ImageJsModule>(this->engine);
|
||||
this->submodules[QStringLiteral("fs")] = std::make_shared<FsJsModule>(this->engine);
|
||||
// this->submodules[QStringLiteral("image")] = std::make_shared<ImageJsModule>(this->engine);
|
||||
|
||||
// TODO(Faraphel): check if the filesystem is correctly restricted
|
||||
}
|
||||
|
||||
QJSValue AtlasJsModule::require(const QString& name) {
|
||||
QJSValue AtlasJsModule::require(const QString& name) const {
|
||||
std::shared_ptr<BaseJsModule> submodule;
|
||||
|
||||
try {
|
||||
|
|
|
@ -4,31 +4,33 @@
|
|||
#include <QObject>
|
||||
#include <QJSValue>
|
||||
|
||||
#include "_base/BaseJsModule.hpp"
|
||||
|
||||
class AtlasJsEngine;
|
||||
class BaseJsModule;
|
||||
|
||||
|
||||
class AtlasJsModule : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AtlasJsModule(QJSEngine* engine, QObject* parent = nullptr);
|
||||
explicit AtlasJsModule(AtlasJsEngine* engine, QObject* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Import an Atlas submodule
|
||||
* @param name the name of the module to import
|
||||
* @return the module
|
||||
*/
|
||||
Q_INVOKABLE QJSValue require(const QString& name);
|
||||
Q_INVOKABLE QJSValue require(const QString& name) const;
|
||||
|
||||
/**
|
||||
* Get the version of the Atlas Javascript engine
|
||||
* @return the Atlas version
|
||||
*/
|
||||
Q_INVOKABLE static QJSValueList getVersion();
|
||||
Q_INVOKABLE static QList<QJSValue> getVersion();
|
||||
|
||||
private:
|
||||
/// the parent JavaScript engine
|
||||
QJSEngine* engine;
|
||||
AtlasJsEngine* engine;
|
||||
/// the submodules contained in this module
|
||||
std::map<QString, std::shared_ptr<BaseJsModule>> submodules;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "BaseJsModule.hpp"
|
||||
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
BaseJsModule::BaseJsModule(QJSEngine *engine) {
|
||||
|
||||
BaseJsModule::BaseJsModule(AtlasJsEngine* engine) {
|
||||
this->engine = engine;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QJSEngine>
|
||||
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -11,9 +12,9 @@ class BaseJsModule : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BaseJsModule(QJSEngine* engine);
|
||||
explicit BaseJsModule(AtlasJsEngine* engine);
|
||||
|
||||
protected:
|
||||
/// The javascript engine running the module
|
||||
QJSEngine* engine;
|
||||
AtlasJsEngine* engine;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <QDebug>
|
||||
|
||||
|
||||
DebugJsModule::DebugJsModule(QJSEngine* engine) : BaseJsModule(engine) {}
|
||||
DebugJsModule::DebugJsModule(AtlasJsEngine* engine) : BaseJsModule(engine) {}
|
||||
|
||||
void DebugJsModule::information(const QString& text) {
|
||||
qDebug() << text;
|
||||
|
|
|
@ -10,7 +10,7 @@ class DebugJsModule : public BaseJsModule {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DebugJsModule(QJSEngine* engine);
|
||||
explicit DebugJsModule(AtlasJsEngine* engine);
|
||||
|
||||
/**
|
||||
* Print an informational message
|
||||
|
|
4
source/javascript/module/debug/README.md
Normal file
4
source/javascript/module/debug/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Submodule "Debug"
|
||||
|
||||
This module allow the developer to easily debug his application thanks
|
||||
to common debug features.
|
|
@ -1,12 +0,0 @@
|
|||
#include "FileJsModule.hpp"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
|
||||
FileJsModule::FileJsModule(QJSEngine *engine, const QList<QDir>& allowedDirectories) : BaseJsModule(engine) {
|
||||
this->allowedDirectories = allowedDirectories;
|
||||
}
|
||||
|
||||
QJSValue FileJsModule::open(const QString& path) {
|
||||
QFile file(path);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#include "../_base/BaseJsModule.hpp"
|
||||
|
||||
|
||||
class FileJsModule : public BaseJsModule {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FileJsModule(QJSEngine* engine, const QList<QDir>& allowedDirectories);
|
||||
|
||||
Q_INVOKABLE QJSValue open(const QString& path);
|
||||
|
||||
private:
|
||||
QList<QDir> allowedDirectories;
|
||||
};
|
15
source/javascript/module/file_system/FsJsModule.cpp
Normal file
15
source/javascript/module/file_system/FsJsModule.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "FsJsModule.hpp"
|
||||
|
||||
#include "object/FileJsObject.hpp"
|
||||
#include "object/PathJsObject.hpp"
|
||||
|
||||
|
||||
FsJsModule::FsJsModule(AtlasJsEngine* engine) : BaseJsModule(engine) {}
|
||||
|
||||
QJSValue FsJsModule::newPath(const QString& virtualPath) const {
|
||||
// TODO(Faraphel): risk of memory leak ?
|
||||
return this->engine->newQObject(new PathJsObject(
|
||||
this->engine,
|
||||
std::filesystem::path(virtualPath.toStdString())
|
||||
));
|
||||
}
|
23
source/javascript/module/file_system/FsJsModule.hpp
Normal file
23
source/javascript/module/file_system/FsJsModule.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include <VirtualFileSystem.hpp>
|
||||
|
||||
#include "../_base/BaseJsModule.hpp"
|
||||
|
||||
|
||||
class FsJsModule : public BaseJsModule {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FsJsModule(AtlasJsEngine* engine);
|
||||
|
||||
// TODO(Faraphel): can a property "Path" redirect to the type directly ?
|
||||
/**
|
||||
* Create a new path object
|
||||
* @param virtualPath the path as a String
|
||||
* @return the path as a JavaScript object
|
||||
*/
|
||||
Q_INVOKABLE QJSValue newPath(const QString& virtualPath) const;
|
||||
|
||||
};
|
24
source/javascript/module/file_system/README.md
Normal file
24
source/javascript/module/file_system/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Submodule "FileSystem"
|
||||
|
||||
> NOTE : This module is in an elaboration stage. Everything is subject to change !
|
||||
|
||||
This module allow the developer to access the game file to interact with them,
|
||||
and additionally a temporary folder to store important data that might be reused
|
||||
to speed up the patch process.
|
||||
|
||||
For security reason, you can only access file inside the virtual file system.
|
||||
|
||||
Here is an example of the virtual file system structure :
|
||||
|
||||
```tree
|
||||
/
|
||||
| game/
|
||||
| | sys/
|
||||
| | files/
|
||||
| | ...
|
||||
| assets/
|
||||
| | my-texture.png
|
||||
| | ...
|
||||
| tmp/
|
||||
| | patched-texture.tpl
|
||||
```
|
103
source/javascript/module/file_system/object/FileJsObject.cpp
Normal file
103
source/javascript/module/file_system/object/FileJsObject.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "FileJsObject.hpp"
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "exception/FileNotFoundException.hpp"
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
#include "utils/qt/fileOpenMode.hpp"
|
||||
|
||||
|
||||
FileJsObject::FileJsObject(AtlasJsEngine* engine, const std::filesystem::path& virtualPath) {
|
||||
// save the engine
|
||||
this->engine = engine;
|
||||
|
||||
// create the internal QFile
|
||||
std::filesystem::path realPath;
|
||||
try {
|
||||
realPath = this->engine->getFileSystem().resolve(virtualPath);
|
||||
} catch (const vfs::exception::FileNotFoundException& exception) {
|
||||
this->engine->throwError(QJSValue::ErrorType::URIError, "Invalid path.");
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate the internal file
|
||||
this->_internal = std::make_unique<QFile>(realPath);
|
||||
}
|
||||
|
||||
void FileJsObject::open(const QString& mode) {
|
||||
// get the mode flags from its string representation
|
||||
this->mode = fileModeFromString(mode);
|
||||
|
||||
// open the file with the corresponding mode
|
||||
if (!this->_internal->open(this->mode)) {
|
||||
this->engine->throwError(QJSValue::URIError, "Cannot open the file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are in text mode, prepare the QTextStream wrapper
|
||||
if (this->mode.testFlag(QIODevice::Text))
|
||||
this->textStream = std::make_unique<QTextStream>(this->_internal.get());
|
||||
}
|
||||
|
||||
QJSValue FileJsObject::read(const std::size_t size) const {
|
||||
// check if we can read the file
|
||||
if (!this->mode.testFlag(QIODevice::ReadOnly)) {
|
||||
this->engine->throwError(QJSValue::ErrorType::TypeError, "The file is not open in read mode.");
|
||||
return QJSValue(QJSPrimitiveNull());
|
||||
}
|
||||
|
||||
// if we are in text mode, read from the text stream
|
||||
if (this->mode.testFlag(QIODevice::Text))
|
||||
return this->textStream->read(static_cast<qint64>(size));
|
||||
|
||||
// if we are in binary mode, read from the binary stream
|
||||
const auto data = this->_internal->read(static_cast<qint64>(size));
|
||||
return this->engine->toScriptValue(data);
|
||||
}
|
||||
|
||||
std::size_t FileJsObject::write(const QJSValue& data) const {
|
||||
// check if we can write into the file
|
||||
if (!this->mode.testFlag(QIODevice::WriteOnly)) {
|
||||
this->engine->throwError(QJSValue::ErrorType::TypeError, "The file is not open in write mode.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QString dataString = data.toString();
|
||||
|
||||
// if we are in text mode, write text data
|
||||
if (this->mode.testFlag(QIODevice::Text)) {
|
||||
*this->textStream << dataString;
|
||||
return dataString.size();
|
||||
}
|
||||
|
||||
const QByteArray dataByte = dataString.toUtf8();
|
||||
// if we are in binary mode, insert the raw binary data
|
||||
return this->_internal->write(dataByte);
|
||||
}
|
||||
|
||||
std::size_t FileJsObject::tell() const {
|
||||
// if we are in text mode, return the position of the text stream
|
||||
if (this->mode.testFlag(QIODevice::Text))
|
||||
return this->textStream->pos();
|
||||
|
||||
// if we are in binary mode, return the position of the raw binary stream
|
||||
return this->_internal->pos();
|
||||
}
|
||||
|
||||
void FileJsObject::seek(const std::size_t position) const {
|
||||
// if we are in text mode, set the position of the text stream
|
||||
if (this->mode.testFlag(QIODevice::Text)) {
|
||||
this->textStream->seek(static_cast<qint64>(position));
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are in binary mode, set the position of the raw binary stream
|
||||
this->_internal->seek(static_cast<qint64>(position));
|
||||
}
|
||||
|
||||
void FileJsObject::close() const {
|
||||
// if still opened, close the file
|
||||
if (this->_internal->isOpen())
|
||||
this->_internal->close();
|
||||
}
|
55
source/javascript/module/file_system/object/FileJsObject.hpp
Normal file
55
source/javascript/module/file_system/object/FileJsObject.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <QFile>
|
||||
#include <QJSValue>
|
||||
#include <QObject>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
|
||||
/**
|
||||
* Represent a JavaScript file.
|
||||
* This is a wrapper around `QFile`
|
||||
*/
|
||||
class FileJsObject : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FileJsObject(AtlasJsEngine* engine, const std::filesystem::path& virtualPath);
|
||||
|
||||
/**
|
||||
* Open the file to access its content.
|
||||
* @param mode the opening mode of the file, using "r", "w", "+", etc...
|
||||
*/
|
||||
Q_INVOKABLE void open(const QString& mode = QStringLiteral("r"));
|
||||
|
||||
/**
|
||||
* Read the content of the file.
|
||||
* @param size the size of the content to read.
|
||||
* @return the content of the file
|
||||
*/
|
||||
Q_INVOKABLE QJSValue read(size_t size = std::numeric_limits<std::size_t>::max()) const;
|
||||
/**
|
||||
* Write data into the file
|
||||
* @param data the data to write into the file
|
||||
* @return the size of the data written
|
||||
*/
|
||||
Q_INVOKABLE std::size_t write(const QJSValue& data) const;
|
||||
|
||||
Q_INVOKABLE std::size_t tell() const;
|
||||
Q_INVOKABLE void seek(std::size_t position) const;
|
||||
|
||||
/**
|
||||
* Close the file.
|
||||
*/
|
||||
Q_INVOKABLE void close() const;
|
||||
|
||||
private:
|
||||
AtlasJsEngine* engine;
|
||||
|
||||
std::unique_ptr<QFile> _internal;
|
||||
QIODevice::OpenMode mode;
|
||||
std::unique_ptr<QTextStream> textStream;
|
||||
};
|
101
source/javascript/module/file_system/object/PathJsObject.cpp
Normal file
101
source/javascript/module/file_system/object/PathJsObject.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "PathJsObject.hpp"
|
||||
|
||||
#include <QDir>
|
||||
#include <QList>
|
||||
|
||||
#include "FileJsObject.hpp"
|
||||
#include "exception/FileNotFoundException.hpp"
|
||||
|
||||
|
||||
PathJsObject::PathJsObject(AtlasJsEngine* engine, const std::filesystem::path& virtualPath) {
|
||||
this->engine = engine;
|
||||
this->virtualPath = virtualPath;
|
||||
}
|
||||
|
||||
QJSValue PathJsObject::getParent() const {
|
||||
// return the parent directory
|
||||
return this->engine->newQObject(new PathJsObject(
|
||||
this->engine,
|
||||
this->virtualPath.parent_path()
|
||||
));
|
||||
}
|
||||
|
||||
QList<QJSValue> PathJsObject::getChildrens() const {
|
||||
// check if the path is iterable
|
||||
if (!this->isDirectory()) {
|
||||
this->engine->throwError(QJSValue::ErrorType::TypeError, "Only directories can have children.");
|
||||
return {};
|
||||
}
|
||||
|
||||
// get the corresponding real directory path
|
||||
const std::filesystem::path realPath = this->getRealPath();
|
||||
|
||||
// prepare the list of children paths
|
||||
auto childsPath = QList<QJSValue>();
|
||||
|
||||
// iterate through the childrens of the directory
|
||||
for (const auto& childRealEntry : std::filesystem::directory_iterator(realPath)) {
|
||||
// get the corresponding path object
|
||||
const auto& childRealPath = childRealEntry.path();
|
||||
|
||||
// get the virtual path
|
||||
std::filesystem::path childVirtualPath = this->virtualPath / childRealPath.filename();
|
||||
// add it to the list of childrens
|
||||
const auto pathJs = this->engine->newQObject(new PathJsObject(
|
||||
this->engine,
|
||||
childVirtualPath
|
||||
));
|
||||
childsPath.append(pathJs);
|
||||
}
|
||||
|
||||
return childsPath;
|
||||
}
|
||||
|
||||
bool PathJsObject::isFile() const {
|
||||
return is_regular_file(this->getRealPath());
|
||||
}
|
||||
|
||||
bool PathJsObject::isDirectory() const {
|
||||
return is_directory(this->getRealPath());
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue PathJsObject::open(const QString& mode, const QString& encoding) {
|
||||
// create a new file object
|
||||
auto* file = new FileJsObject(
|
||||
this->engine,
|
||||
this->virtualPath
|
||||
);
|
||||
// open it with the given mode
|
||||
file->open(mode);
|
||||
|
||||
// convert it into a QJSValue
|
||||
auto fileJs = this->engine->newQObject(file);
|
||||
|
||||
return fileJs;
|
||||
|
||||
// TODO(Faraphel): handle encoding
|
||||
}
|
||||
|
||||
QString PathJsObject::getPath() const {
|
||||
return QString::fromStdString(this->virtualPath.string());
|
||||
}
|
||||
|
||||
QString PathJsObject::getDirname() const {
|
||||
return QString::fromStdString(this->virtualPath.parent_path().string());
|
||||
}
|
||||
|
||||
QString PathJsObject::getFilename() const {
|
||||
return QString::fromStdString(this->virtualPath.filename());
|
||||
}
|
||||
|
||||
QString PathJsObject::getBasename() const {
|
||||
return QString::fromStdString(this->virtualPath.stem());
|
||||
}
|
||||
|
||||
QString PathJsObject::getSuffix() const {
|
||||
return QString::fromStdString(this->virtualPath.extension());
|
||||
}
|
||||
|
||||
std::filesystem::path PathJsObject::getRealPath() const {
|
||||
return this->engine->getFileSystem().resolve(this->virtualPath);
|
||||
}
|
114
source/javascript/module/file_system/object/PathJsObject.hpp
Normal file
114
source/javascript/module/file_system/object/PathJsObject.hpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QDir>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "javascript/module/file_system/object/FileJsObject.hpp"
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
|
||||
/**
|
||||
* Represent a file system Path as a JavaScript object
|
||||
* Similar to the pathlib library in Python
|
||||
*/
|
||||
class PathJsObject : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PathJsObject(AtlasJsEngine* engine, const std::filesystem::path& virtualPath);
|
||||
|
||||
// browse
|
||||
|
||||
/**
|
||||
* Get the parent directory
|
||||
* @return the parent directory
|
||||
*/
|
||||
Q_INVOKABLE QJSValue getParent() const;
|
||||
|
||||
/**
|
||||
* Get the child paths
|
||||
* @return the child paths
|
||||
*/
|
||||
Q_INVOKABLE QList<QJSValue> getChildrens(bool recursive = false, QString pattern = "*") const;
|
||||
|
||||
// type
|
||||
|
||||
Q_INVOKABLE bool exists();
|
||||
|
||||
/**
|
||||
* is the current path leading to a file
|
||||
* @return is the current path leading to a file
|
||||
*/
|
||||
Q_INVOKABLE bool isFile() const;
|
||||
/**
|
||||
* is the current path leading to a directory
|
||||
* @return is the current path leading to a directory
|
||||
*/
|
||||
Q_INVOKABLE bool isDirectory() const;
|
||||
|
||||
// operation
|
||||
|
||||
/**
|
||||
* open the path as a file
|
||||
* @return the opened file
|
||||
*/
|
||||
Q_INVOKABLE QJSValue open(const QString& mode, const QString& encoding = QStringLiteral("utf-8"));
|
||||
|
||||
Q_INVOKABLE void mkdir(bool parents);
|
||||
|
||||
Q_INVOKABLE void remove(bool recursive);
|
||||
|
||||
// component
|
||||
|
||||
/**
|
||||
* get the full path to the file
|
||||
* @return the full path to the file
|
||||
*/
|
||||
Q_INVOKABLE QString getPath() const;
|
||||
/**
|
||||
* get the name of the directory containing the file
|
||||
* @return the name of the directory containing the file
|
||||
*/
|
||||
Q_INVOKABLE QString getDirname() const;
|
||||
/**
|
||||
* get the name of the file
|
||||
* @return the name of the file
|
||||
*/
|
||||
Q_INVOKABLE QString getFilename() const;
|
||||
/**
|
||||
* get the name of the file without the suffix
|
||||
* @return the name of the file without the suffix
|
||||
*/
|
||||
Q_INVOKABLE QString getBasename() const;
|
||||
/**
|
||||
* get the extension of the file
|
||||
* @return the extension of the file
|
||||
*/
|
||||
Q_INVOKABLE QString getSuffix() const;
|
||||
/**
|
||||
* get the extensions of the file
|
||||
* @return the extensions of the file
|
||||
*/
|
||||
Q_INVOKABLE QList<QString> getSuffixes() const;
|
||||
/**
|
||||
* get the segments of the path
|
||||
* @return the segments of the path
|
||||
*/
|
||||
Q_INVOKABLE QList<QString> getSegments() const;
|
||||
|
||||
private:
|
||||
/// the JavaScript engine
|
||||
AtlasJsEngine* engine;
|
||||
/// the virtual path
|
||||
std::filesystem::path virtualPath;
|
||||
|
||||
/**
|
||||
* Get the real path on the host file system of the path
|
||||
* @return the real path on the host file system
|
||||
* @throw rvfs::exception::FileNotFoundException if the path does not match with anything on the real file system
|
||||
*/
|
||||
std::filesystem::path getRealPath() const;
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
#include "ImageJsModule.hpp"
|
||||
|
||||
#include "ImageJsObject.hpp"
|
||||
#include "object/ImageJsObject.hpp"
|
||||
|
||||
|
||||
ImageJsModule::ImageJsModule(QJSEngine* engine) : BaseJsModule(engine) {}
|
||||
ImageJsModule::ImageJsModule(AtlasJsEngine* engine) : BaseJsModule(engine) {}
|
||||
|
||||
QJSValue ImageJsModule::load(const QString& path) {
|
||||
// TODO(Faraphel): can the new lead to a memory leak ?
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <QJSValue>
|
||||
|
||||
#include "ImageJsObject.hpp"
|
||||
#include "../_base/BaseJsModule.hpp"
|
||||
|
||||
|
||||
|
@ -13,7 +12,7 @@ class ImageJsModule : public BaseJsModule {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ImageJsModule(QJSEngine* engine);
|
||||
explicit ImageJsModule(AtlasJsEngine* engine);
|
||||
|
||||
/**
|
||||
* Load an image file
|
||||
|
|
0
source/javascript/module/szs/.gitkeep
Normal file
0
source/javascript/module/szs/.gitkeep
Normal file
7
source/javascript/module/web/README.md
Normal file
7
source/javascript/module/web/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Submodule "Web"
|
||||
|
||||
> This module will allow the developer to access data on the web.
|
||||
> It shall be very careful about the security and will require a
|
||||
> special authorisation by the user to access any url.
|
||||
> As of right now, it is in a stage of idea.
|
||||
|
0
source/javascript/module/wit/.gitkeep
Normal file
0
source/javascript/module/wit/.gitkeep
Normal file
|
@ -1,18 +1,12 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
#include <RestrictedVirtualFileSystem.hpp>
|
||||
#include "javascript/engine/AtlasJsEngine.hpp"
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
@ -22,22 +16,6 @@ int main(int argc, char* argv[]) {
|
|||
QApplication::setApplicationName("Atlas-Launcher");
|
||||
QApplication::setApplicationVersion("1.0.0");
|
||||
|
||||
// create a restricted virtual file system
|
||||
const auto fileSystem = std::make_shared<rvfs::RestrictedVirtualFileSystem>();
|
||||
|
||||
// mount the cache directory
|
||||
fileSystem->mountDirectory(
|
||||
QDir("/cache/"),
|
||||
QDir("/home/faraphel/Documents/Projects/Atlas-Launcher/source/")
|
||||
);
|
||||
|
||||
// mount the temporary directory
|
||||
const auto temporaryDir = QTemporaryDir();
|
||||
fileSystem->mountDirectory(
|
||||
QDir("/tmp/"),
|
||||
QDir(temporaryDir.path())
|
||||
);
|
||||
|
||||
// create a small window
|
||||
auto mainWindow = std::make_shared<QMainWindow>();
|
||||
|
||||
|
@ -58,9 +36,11 @@ int main(int argc, char* argv[]) {
|
|||
layout->addWidget(output.get());
|
||||
output->setEnabled(false);
|
||||
|
||||
QObject::connect(submit.get(), &QPushButton::clicked, [&]() {
|
||||
auto engine = std::make_shared<atlas::js::AtlasJsEngine>(nullptr);
|
||||
// create the javascript engine
|
||||
auto engine = std::make_shared<AtlasJsEngine>(widget.get());
|
||||
|
||||
// when submit clicked, run the code and show the output
|
||||
QObject::connect(submit.get(), &QPushButton::clicked, [&] {
|
||||
QJSValue value = engine->evaluate(input->toPlainText());
|
||||
output->setText(value.toString());
|
||||
});
|
||||
|
|
24
source/utils/qt/fileOpenMode.cpp
Normal file
24
source/utils/qt/fileOpenMode.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "fileOpenMode.hpp"
|
||||
|
||||
|
||||
QIODevice::OpenMode fileModeFromString(const QString& modeString) {
|
||||
QIODevice::OpenMode modeFlags = QIODevice::NotOpen;
|
||||
|
||||
// if the mode don't contains a "b", set the text mode
|
||||
if (!modeString.contains("b"))
|
||||
modeFlags |= QIODevice::Text;
|
||||
|
||||
// if the mode contains a "r", set the read mode
|
||||
if (modeString.contains("r"))
|
||||
modeFlags |= QIODevice::ReadOnly;
|
||||
|
||||
// if the mode contains a "w", set the write mode
|
||||
if (modeString.contains("w"))
|
||||
modeFlags |= QIODevice::WriteOnly;
|
||||
|
||||
// if the mode contains a "a", set the append mode
|
||||
if (modeString.contains("a"))
|
||||
modeFlags |= QIODevice::Append;
|
||||
|
||||
return modeFlags;
|
||||
}
|
11
source/utils/qt/fileOpenMode.hpp
Normal file
11
source/utils/qt/fileOpenMode.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <QIODevice>
|
||||
|
||||
|
||||
/**
|
||||
* convert a string representing a file mode to the corresponding Qt flags.
|
||||
* @param modeString the mode as a string
|
||||
* @return the mode as a flag
|
||||
*/
|
||||
QIODevice::OpenMode fileModeFromString(const QString& modeString);
|
Loading…
Reference in a new issue