added an AngelScript log module
This commit is contained in:
parent
a5b4723ac1
commit
d9ae04886f
15 changed files with 236 additions and 134 deletions
|
@ -7,11 +7,28 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
|
||||||
add_executable(Atlas-Launcher
|
add_executable(Atlas-Launcher
|
||||||
source/main.cpp
|
|
||||||
|
|
||||||
# AngelScript
|
# AngelScript
|
||||||
external/angelscript/add_on/scriptbuilder/scriptbuilder.cpp
|
external/angelscript/add_on/scriptbuilder/scriptbuilder.cpp
|
||||||
external/angelscript/add_on/scriptstdstring/scriptstdstring.cpp
|
external/angelscript/add_on/scriptstdstring/scriptstdstring.cpp
|
||||||
|
external/angelscript/add_on/scriptstdstring/scriptstdstring_utils.cpp
|
||||||
|
external/angelscript/add_on/datetime/datetime.cpp
|
||||||
|
external/angelscript/add_on/scriptany/scriptany.cpp
|
||||||
|
external/angelscript/add_on/scriptarray/scriptarray.cpp
|
||||||
|
external/angelscript/add_on/scriptgrid/scriptgrid.cpp
|
||||||
|
external/angelscript/add_on/scriptdictionary/scriptdictionary.cpp
|
||||||
|
external/angelscript/add_on/scripthandle/scripthandle.cpp
|
||||||
|
external/angelscript/add_on/weakref/weakref.cpp
|
||||||
|
external/angelscript/add_on/scriptmath/scriptmath.cpp
|
||||||
|
external/angelscript/add_on/scripthelper/scripthelper.cpp
|
||||||
|
|
||||||
|
# Source
|
||||||
|
source/main.cpp
|
||||||
|
source/script/module/debug/load.cpp
|
||||||
|
source/script/module/debug/load.hpp
|
||||||
|
source/script/module/debug/log.cpp
|
||||||
|
source/script/module/debug/log.hpp
|
||||||
|
source/script/engine/Engine.cpp
|
||||||
|
source/script/engine/Engine.hpp
|
||||||
)
|
)
|
||||||
target_include_directories(Atlas-Launcher PRIVATE
|
target_include_directories(Atlas-Launcher PRIVATE
|
||||||
source/
|
source/
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#include "AtlasJsEngine.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
AtlasJsEngine::AtlasJsEngine(QObject *parent) : QJSEngine(parent) {
|
|
||||||
// instanciate a new Atlas module
|
|
||||||
this->moduleAtlas = std::make_unique<AtlasJsModule>(this);
|
|
||||||
|
|
||||||
// convert it into a javascript object
|
|
||||||
const QJSValue jsModuleAtlas = this->newQObject(this->moduleAtlas.get());
|
|
||||||
// make it accessible as "atlas" in the javascript code
|
|
||||||
this->globalObject().setProperty("atlas", jsModuleAtlas);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vfs::VirtualFileSystem& AtlasJsEngine::getFileSystem() {
|
|
||||||
return this->fileSystem;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QJSEngine>
|
|
||||||
#include <QTemporaryDir>
|
|
||||||
#include <VirtualFileSystem.hpp>
|
|
||||||
|
|
||||||
#include "javascript/module/AtlasJsModule.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represent a Qt JavaScript engine modified to support the Atlas framework.
|
|
||||||
*/
|
|
||||||
class AtlasJsEngine : public QJSEngine {
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AtlasJsEngine(QObject* parent);
|
|
||||||
|
|
||||||
vfs::VirtualFileSystem& getFileSystem();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
vfs::VirtualFileSystem fileSystem;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<AtlasJsModule> moduleAtlas;
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
#include "DebugJsModule.hpp"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
|
|
||||||
DebugJsModule::DebugJsModule(AtlasJsEngine* engine) : BaseJsModule(engine) {}
|
|
||||||
|
|
||||||
void DebugJsModule::information(const QString& text) {
|
|
||||||
qDebug() << text;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../_base/BaseJsModule.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This module implements useful feature to help with debugging
|
|
||||||
*/
|
|
||||||
class DebugJsModule : public BaseJsModule {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit DebugJsModule(AtlasJsEngine* engine);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print an informational message
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE static void information(const QString& text);
|
|
||||||
};
|
|
|
@ -4,45 +4,35 @@
|
||||||
#include <vfspp/VirtualFileSystem.hpp>
|
#include <vfspp/VirtualFileSystem.hpp>
|
||||||
#include <vfspp/MemoryFileSystem.hpp>
|
#include <vfspp/MemoryFileSystem.hpp>
|
||||||
#include <angelscript.h>
|
#include <angelscript.h>
|
||||||
#include <scriptstdstring/scriptstdstring.h>
|
|
||||||
#include <scriptbuilder/scriptbuilder.h>
|
#include <scriptbuilder/scriptbuilder.h>
|
||||||
|
|
||||||
|
#include "script/engine/Engine.hpp"
|
||||||
void print(const std::string& in) {
|
#include "script/module/debug/load.hpp"
|
||||||
std::cout << in;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
// prepare a virtual file system
|
|
||||||
auto fileSystem = std::make_unique<vfspp::VirtualFileSystem>();
|
|
||||||
|
|
||||||
auto fileSystemTmp = std::make_shared<vfspp::MemoryFileSystem>();
|
|
||||||
fileSystemTmp->Initialize();
|
|
||||||
fileSystem->AddFileSystem("/tmp", fileSystemTmp);
|
|
||||||
|
|
||||||
// engine
|
// engine
|
||||||
asIScriptEngine* engine = asCreateScriptEngine();
|
const auto atlasEngine = std::make_unique<atlas::script::engine::Engine>();
|
||||||
if (engine == nullptr)
|
auto* asEngine = atlasEngine->getAsEngine();
|
||||||
throw std::runtime_error("Could not create the AngelScript Engine.");
|
|
||||||
|
|
||||||
RegisterStdString(engine);
|
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
error = engine->RegisterGlobalFunction("void print(const string& in)", asFUNCTION(print), asCALL_CDECL);
|
atlas::script::module::debug::load(atlasEngine.get());
|
||||||
if (error < 0)
|
|
||||||
throw std::runtime_error("Could not register the print function.");
|
|
||||||
|
|
||||||
// script
|
// script
|
||||||
CScriptBuilder builder;
|
CScriptBuilder builder;
|
||||||
|
|
||||||
error = builder.StartNewModule(engine, "script");
|
error = builder.StartNewModule(asEngine, "script");
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
throw std::runtime_error("Could not start a new module.");
|
throw std::runtime_error("Could not start a new module.");
|
||||||
|
|
||||||
error = builder.AddSectionFromMemory("script", "void main() { print(\"hello world !\"); }");
|
error = builder.AddSectionFromMemory("script", R"(
|
||||||
|
void main() {
|
||||||
|
array<int> data(256);
|
||||||
|
atlas::debug::log("main", "hello world !");
|
||||||
|
}
|
||||||
|
)");
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
throw std::runtime_error("Could not add a section to the module.");
|
throw std::runtime_error("Could not add a section to the module.");
|
||||||
|
|
||||||
|
@ -51,7 +41,7 @@ int main(int argc, char* argv[]) {
|
||||||
throw std::runtime_error("Could not build the module.");
|
throw std::runtime_error("Could not build the module.");
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
asIScriptModule *module = engine->GetModule("script");
|
asIScriptModule *module = asEngine->GetModule("script");
|
||||||
if (module == nullptr)
|
if (module == nullptr)
|
||||||
throw std::runtime_error("Could not get the module.");
|
throw std::runtime_error("Could not get the module.");
|
||||||
|
|
||||||
|
@ -59,7 +49,7 @@ int main(int argc, char* argv[]) {
|
||||||
if (function == nullptr)
|
if (function == nullptr)
|
||||||
throw std::runtime_error("Could not get the main function.");
|
throw std::runtime_error("Could not get the main function.");
|
||||||
|
|
||||||
asIScriptContext *context = engine->CreateContext();
|
asIScriptContext *context = asEngine->CreateContext();
|
||||||
if (context == nullptr)
|
if (context == nullptr)
|
||||||
throw std::runtime_error("Could not create the context.");
|
throw std::runtime_error("Could not create the context.");
|
||||||
|
|
||||||
|
@ -71,7 +61,6 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
context->Release();
|
context->Release();
|
||||||
engine->Release();
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
91
source/script/engine/Engine.cpp
Normal file
91
source/script/engine/Engine.cpp
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#include "Engine.hpp"
|
||||||
|
|
||||||
|
#include <angelscript.h>
|
||||||
|
#include <format>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <datetime/datetime.h>
|
||||||
|
#include <scriptany/scriptany.h>
|
||||||
|
#include <scriptstdstring/scriptstdstring.h>
|
||||||
|
#include <scriptarray/scriptarray.h>
|
||||||
|
#include <scriptdictionary/scriptdictionary.h>
|
||||||
|
#include <scriptgrid/scriptgrid.h>
|
||||||
|
#include <scripthandle/scripthandle.h>
|
||||||
|
#include <scripthelper/scripthelper.h>
|
||||||
|
#include <scriptmath/scriptmath.h>
|
||||||
|
#include <vfspp/MemoryFileSystem.hpp>
|
||||||
|
#include <weakref/weakref.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::engine {
|
||||||
|
|
||||||
|
Engine::Engine() {
|
||||||
|
// create a new AngelScript engine
|
||||||
|
this->asEngine = asCreateScriptEngine();
|
||||||
|
if (this->asEngine == nullptr)
|
||||||
|
throw std::runtime_error("Could not create the AngelScript Engine.");
|
||||||
|
|
||||||
|
this->asEngine->SetMessageCallback(asFUNCTION(this->asCallback), nullptr, asCALL_CDECL);
|
||||||
|
|
||||||
|
// AngelScript standard library
|
||||||
|
RegisterScriptArray(this->asEngine, true);
|
||||||
|
RegisterScriptGrid(this->asEngine);
|
||||||
|
RegisterStdString(this->asEngine);
|
||||||
|
RegisterStdStringUtils(this->asEngine);
|
||||||
|
RegisterScriptDictionary(this->asEngine);
|
||||||
|
RegisterScriptDateTime(this->asEngine);
|
||||||
|
RegisterScriptAny(this->asEngine);
|
||||||
|
RegisterScriptHandle(this->asEngine);
|
||||||
|
RegisterScriptWeakRef(this->asEngine);
|
||||||
|
RegisterExceptionRoutines(this->asEngine);
|
||||||
|
RegisterScriptMath(this->asEngine);
|
||||||
|
|
||||||
|
// initialise the file system
|
||||||
|
this->fileSystem = std::make_unique<vfspp::VirtualFileSystem>();
|
||||||
|
|
||||||
|
// TODO(Faraphel): is the memory fs
|
||||||
|
auto memoryFileSystem = std::make_unique<vfspp::MemoryFileSystem>();
|
||||||
|
memoryFileSystem->Initialize();
|
||||||
|
|
||||||
|
this->fileSystem->AddFileSystem("/tmp", std::move(memoryFileSystem));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::asCallback(const asSMessageInfo *message, void *args) {
|
||||||
|
std::string type = "UNKNOWN";
|
||||||
|
std::ostream* output = &std::cout;
|
||||||
|
|
||||||
|
// get a representation for the message type
|
||||||
|
switch (message->type) {
|
||||||
|
case asMSGTYPE_INFORMATION:
|
||||||
|
type = "INFO";
|
||||||
|
output = &std::cout;
|
||||||
|
case asMSGTYPE_WARNING:
|
||||||
|
type = "WARN";
|
||||||
|
output = &std::cerr;
|
||||||
|
case asMSGTYPE_ERROR:
|
||||||
|
type = "ERROR";
|
||||||
|
output = &std::cerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the message
|
||||||
|
|
||||||
|
|
||||||
|
*output << std::format(
|
||||||
|
"{} ({}, {}) [{}] {}",
|
||||||
|
message->section,
|
||||||
|
message->row,
|
||||||
|
message->col,
|
||||||
|
type,
|
||||||
|
message->message
|
||||||
|
) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::~Engine() {
|
||||||
|
// release the engine
|
||||||
|
this->asEngine->ShutDownAndRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
asIScriptEngine *Engine::getAsEngine() const {
|
||||||
|
return this->asEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
source/script/engine/Engine.hpp
Normal file
36
source/script/engine/Engine.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <angelscript.h>
|
||||||
|
#include <vfspp/VirtualFileSystem.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::engine {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The Atlas script engine
|
||||||
|
* @details a wrapper around the AngelScript engine
|
||||||
|
*/
|
||||||
|
class Engine {
|
||||||
|
public:
|
||||||
|
explicit Engine();
|
||||||
|
~Engine();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The AngelScript message handler
|
||||||
|
* @param message an AngelScript message
|
||||||
|
* @param args additionnal arguments
|
||||||
|
*/
|
||||||
|
static void asCallback(const asSMessageInfo *message, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the AngelScript engine
|
||||||
|
* @return the AngelScript engine
|
||||||
|
*/
|
||||||
|
[[nodiscard]] asIScriptEngine* getAsEngine() const;
|
||||||
|
private:
|
||||||
|
asIScriptEngine* asEngine;
|
||||||
|
std::unique_ptr<vfspp::VirtualFileSystem> fileSystem;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
34
source/script/module/debug/load.cpp
Normal file
34
source/script/module/debug/load.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include "load.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::module::debug {
|
||||||
|
|
||||||
|
void load(const engine::Engine* atlasEngine) {
|
||||||
|
asIScriptEngine* asEngine = atlasEngine->getAsEngine();
|
||||||
|
int error;
|
||||||
|
|
||||||
|
// start namespace
|
||||||
|
error = asEngine->SetDefaultNamespace("atlas::debug");
|
||||||
|
if (error < 0)
|
||||||
|
throw std::runtime_error("Could not enter the \"atlas::debug\" namespace.");
|
||||||
|
|
||||||
|
// functions
|
||||||
|
error = asEngine->RegisterGlobalFunction(
|
||||||
|
"void log(const string& in, const string& in)",
|
||||||
|
asFUNCTION(log),
|
||||||
|
asCALL_CDECL
|
||||||
|
);
|
||||||
|
if (error < 0)
|
||||||
|
throw std::runtime_error("Could not register the \"load\" function.");
|
||||||
|
|
||||||
|
// end namespace
|
||||||
|
error = asEngine->SetDefaultNamespace("");
|
||||||
|
if (error < 0)
|
||||||
|
throw std::runtime_error("Could not reset the namespace.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
source/script/module/debug/load.hpp
Normal file
10
source/script/module/debug/load.hpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "script/engine/Engine.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::module::debug {
|
||||||
|
|
||||||
|
void load(const engine::Engine* atlasEngine);
|
||||||
|
|
||||||
|
}
|
22
source/script/module/debug/log.cpp
Normal file
22
source/script/module/debug/log.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::module::debug {
|
||||||
|
|
||||||
|
void log(const std::string& category, const std::string& message) {
|
||||||
|
// get the current time
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
// display it into the standard output
|
||||||
|
std::cout << std::format(
|
||||||
|
"[{:%Y-%m-%dT%H:%M:%S}] ({}) {}",
|
||||||
|
now,
|
||||||
|
category,
|
||||||
|
message
|
||||||
|
) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
source/script/module/debug/log.hpp
Normal file
10
source/script/module/debug/log.hpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace atlas::script::module::debug {
|
||||||
|
|
||||||
|
void log(const std::string& category, const std::string& message);
|
||||||
|
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
#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