Skip to content

Commit

Permalink
新增脚本模块,重构解释器类,优化资源预加载功能,更新 CMake 配置以支持新模块,改进 YAML 转 JSON 的异常处理
Browse files Browse the repository at this point in the history
  • Loading branch information
AstroAir committed Nov 21, 2024
1 parent 522ebc0 commit ffcbdfb
Show file tree
Hide file tree
Showing 16 changed files with 950 additions and 893 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ add_subdirectory(${lithium_src_dir}/addon)
add_subdirectory(${lithium_src_dir}/client)
add_subdirectory(${lithium_src_dir}/target)
add_subdirectory(${lithium_src_dir}/device)
add_subdirectory(${lithium_src_dir}/script)
add_subdirectory(tests)

# Set source files
Expand Down
2 changes: 1 addition & 1 deletion libs
127 changes: 59 additions & 68 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ Description: Main Entry
**************************************************/

#include "LithiumApp.hpp"

#include "preload.hpp"

#include "config/configor.hpp"

#include "atom/error/exception.hpp"
#include "atom/function/concept.hpp"
#include "atom/function/global_ptr.hpp"
#include "atom/function/invoke.hpp"
#include "atom/log/loguru.hpp"
#include "atom/system/crash.hpp"
#include "atom/web/utils.hpp"
Expand All @@ -43,7 +47,7 @@ using namespace lithium::debug;
#ifdef _WIN32
#include <Windows.h>
#else
#include <signal.h>
#include <csignal>
#endif

#include "atom/utils/argsview.hpp"
Expand All @@ -55,16 +59,27 @@ using namespace std::literals;
* @note This is called in main function
*/
void setupLogFile() {
std::filesystem::path logsFolder = std::filesystem::current_path() / "logs";
if (!std::filesystem::exists(logsFolder)) {
std::filesystem::create_directory(logsFolder);
using namespace std::chrono;
using namespace std::filesystem;

path logsFolder = current_path() / "logs";
if (!exists(logsFolder)) {
create_directory(logsFolder);
}
auto now = std::chrono::system_clock::now();
auto nowTimeT = std::chrono::system_clock::to_time_t(now);
std::tm *localTime = std::localtime(&nowTimeT);
char filename[100];
std::strftime(filename, sizeof(filename), "%Y%m%d_%H%M%S.log", localTime);
std::filesystem::path logFilePath = logsFolder / filename;

auto now = system_clock::now();
auto nowTimeT = system_clock::to_time_t(now);
std::tm localTime;
#ifdef _WIN32
localtime_s(&localTime, &nowTimeT);
#else
localtime_r(&nowTimeT, &localTime);
#endif

std::ostringstream filenameStream;
filenameStream << std::put_time(&localTime, "%Y%m%d_%H%M%S.log");
path logFilePath = logsFolder / filenameStream.str();

loguru::add_file(logFilePath.string().c_str(), loguru::Append,
loguru::Verbosity_MAX);

Expand All @@ -74,6 +89,15 @@ void setupLogFile() {
});
}

auto convertArgs(int argc, char **argv) -> std::vector<std::string> {
std::vector<std::string> args;
args.reserve(argc);
for (int i = 0; i < argc; ++i) {
args.emplace_back(argv[i]);
}
return args;
}

/**
* @brief main function
* @param argc number of arguments
Expand Down Expand Up @@ -125,70 +149,37 @@ auto main(int argc, char *argv[]) -> int {
program.addDescription("Lithium Command Line Interface:");
program.addEpilog("End.");

program.parse(argc, argv);
program.parse(argc, convertArgs(argc, argv));

lithium::initLithiumApp(argc, argv);
// Create shared instance
lithium::myApp = lithium::LithiumApp::createShared();
// Parse arguments
try {
auto cmdHost = program.get<std::string>("host");
auto cmdPort = program.get<int>("port");
auto cmdConfigPath = program.get<std::string>("config");
auto cmdModulePath = program.get<std::string>("module-path");
auto cmdWebPanel = program.get<bool>("web-panel");
auto cmdDebug = program.get<bool>("debug");

// TODO: We need a new way to handle command line arguments.
// Maybe we will generate a json object or a map and then given to the
// lithiumapp for initialization.
/*
if (!cmd_host.empty()) {
lithium::MyApp->SetConfig(
{{"key", "config/server/host"}, {"value", cmd_host}});
DLOG_F(INFO, "Set server host to {}", cmd_host);
}
if (cmd_port != 8000) {
DLOG_F(INFO, "Command line server port : {}", cmd_port);
auto port = lithium::MyApp->GetConfig("config/server")
.value<int>("port", 8000);
if (port != cmd_port) {
lithium::MyApp->SetConfig(
{{"key", "config/server/port"}, {"value", cmd_port}});
DLOG_F(INFO, "Set server port to {}", cmd_port);
}
}
if (!cmd_config_path.empty()) {
lithium::MyApp->SetConfig({{"key", "config/server/configpath"},
{"value", cmd_config_path}});
DLOG_F(INFO, "Set server config path to {}", cmd_config_path);
}
if (!cmd_module_path.empty()) {
lithium::MyApp->SetConfig({{"key", "config/server/modulepath"},
{"value", cmd_module_path}});
DLOG_F(INFO, "Set server module path to {}", cmd_module_path);
}
if (!cmd_web_panel) {
if (lithium::MyApp->GetConfig("config/server/web").get<bool>()) {
lithium::MyApp->SetConfig(
{{"key", "config/server/web"}, {"value", false}});
DLOG_F(INFO, "Disable web panel");
}
}
if (cmd_debug) {
if (!lithium::MyApp->GetConfig("config/server/debug").get<bool>()) {
lithium::MyApp->SetConfig(
{{"key", "config/server/debug"}, {"value", true}});
auto setConfig = []<typename T>(const std::string &key, T value)
requires IsBuiltIn<T>
{
if (!key.empty()) {
lithium::myApp->setValue(key, value);
} else {
THROW_INVALID_ARGUMENT("Invalid key: " + key);
}
} else {
lithium::MyApp->SetConfig(
{{"key", "config/server/debug"}, {"value", false}});
DLOG_F(INFO, "Disable debug mode");
}
*/
};

setConfig("/lithium/server/host"_valid,
program.get<std::string>("host").value());
setConfig("/lithium/server/port"_valid,
program.get<int>("port").value());
setConfig("/lithium/server/configpath"_valid,
program.get<std::string>("config").value());
setConfig("/lithium/server/modulepath"_valid,
program.get<std::string>("module-path").value());
setConfig("/lithium/server/web"_valid,
program.get<bool>("web-panel").value());
setConfig("/lithium/server/debug"_valid,
program.get<bool>("debug").value());
setConfig("/lithium/server/logfile"_valid,
program.get<std::string>("log-file").value());

} catch (const std::bad_any_cast &e) {
LOG_F(ERROR, "Invalid args format! Error: {}", e.what());
Expand Down
100 changes: 32 additions & 68 deletions src/LithiumApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,23 @@ Description: Lithium App Enter

#include "LithiumApp.hpp"

#include "components/component.hpp"
#include "config.h"

#include "addon/addons.hpp"
#include "addon/loader.hpp"
#include "addon/manager.hpp"

#include "config/configor.hpp"

#include "device/manager.hpp"

#include "task/container.hpp"
#include "task/generator.hpp"
#include "task/loader.hpp"
#include "task/manager.hpp"

#include "script/manager.hpp"

#include "atom/components/component.hpp"
#include "atom/components/dispatch.hpp"
#include "atom/error/exception.hpp"
#include "atom/function/global_ptr.hpp"
#include "atom/log/loguru.hpp"
#include "atom/system/env.hpp"
#include "atom/system/process.hpp"
#include "atom/utils/time.hpp"

#include "utils/constant.hpp"
#include "utils/marco.hpp"
Expand Down Expand Up @@ -96,8 +88,7 @@ LithiumApp::LithiumApp() : Component("lithium.main") {
CHECK_WEAK_PTR_EXPIRED(m_messagebus_,
"load message bus from gpm: lithium.bus");

m_task_interpreter_ =
GetWeakPtr<TaskInterpreter>("lithium.task.manager");
m_task_interpreter_ = GetWeakPtr<Interpreter>("lithium.task.manager");
CHECK_WEAK_PTR_EXPIRED(
m_task_interpreter_,
"load task manager from gpm: lithium.task.manager");
Expand Down Expand Up @@ -133,17 +124,11 @@ LithiumApp::LithiumApp() : Component("lithium.main") {
"Get a list of all components");

def("load_script", &LithiumApp::loadScript, "script", "Load a script");
def("unload_script", &LithiumApp::unloadScript, "script",
"Unload a script");
def("has_script", &LithiumApp::hasScript, "script",
"Check if a script is ");
def("get_script", &LithiumApp::getScript, "script", "Get a script");

DLOG_F(INFO, "Lithium App Initialized");
}

LithiumApp::~LithiumApp() {
}
LithiumApp::~LithiumApp() {}

auto LithiumApp::createShared() -> std::shared_ptr<LithiumApp> {
return std::make_shared<LithiumApp>();
Expand Down Expand Up @@ -195,82 +180,61 @@ auto LithiumApp::getComponentList() -> std::vector<std::string> {
return m_component_manager_.lock()->getComponentList();
}

void LithiumApp::loadScript(const std::string &name, const json &script) {
m_task_interpreter_.lock()->loadScript(name, script);
auto LithiumApp::getValue(const std::string &key_path) const
-> std::optional<nlohmann::json> {
return m_config_manager_.lock()->getValue(key_path);
}

void LithiumApp::unloadScript(const std::string &name) {
m_task_interpreter_.lock()->unloadScript(name);
auto LithiumApp::setValue(const std::string &key_path,
const json &value) -> bool {
return m_config_manager_.lock()->setValue(key_path, value);
}

auto LithiumApp::hasScript(const std::string &name) const -> bool {
return m_task_interpreter_.lock()->hasScript(name);
auto LithiumApp::appendValue(const std::string &key_path,
const json &value) -> bool {
return m_config_manager_.lock()->appendValue(key_path, value);
}

auto LithiumApp::getScript(const std::string &name) const
-> std::optional<json> {
return m_task_interpreter_.lock()->getScript(name);
auto LithiumApp::deleteValue(const std::string &key_path) -> bool {
return m_config_manager_.lock()->deleteValue(key_path);
}

void LithiumApp::registerFunction(const std::string &name,
std::function<json(const json &)> func) {
m_task_interpreter_.lock()->registerFunction(name, func);
auto LithiumApp::hasValue(const std::string &key_path) const -> bool {
return m_config_manager_.lock()->hasValue(key_path);
}

void LithiumApp::registerExceptionHandler(
const std::string &name,
std::function<void(const std::exception &)> handler) {
m_task_interpreter_.lock()->registerExceptionHandler(name, handler);
auto LithiumApp::loadFromFile(const fs::path &path) -> bool {
return m_config_manager_.lock()->loadFromFile(path);
}

void LithiumApp::setVariable(const std::string &name, const json &value) {
m_task_interpreter_.lock()->setVariable(name, value, determineType(value));
auto LithiumApp::loadFromDir(const fs::path &dir_path, bool recursive) -> bool {
return m_config_manager_.lock()->loadFromDir(dir_path, recursive);
}

auto LithiumApp::getVariable(const std::string &name) -> json {
return m_task_interpreter_.lock()->getVariable(name);
auto LithiumApp::saveToFile(const fs::path &file_path) const -> bool {
return m_config_manager_.lock()->saveToFile(file_path);
}

void LithiumApp::parseLabels(const json &script) {
m_task_interpreter_.lock()->parseLabels(script);
auto LithiumApp::getKeys() const -> std::vector<std::string> {
return m_config_manager_.lock()->getKeys();
}

void LithiumApp::execute(const std::string &scriptName) {
m_task_interpreter_.lock()->execute(scriptName);
auto LithiumApp::listPaths() const -> std::vector<std::string> {
return m_config_manager_.lock()->listPaths();
}

void LithiumApp::stop() { m_task_interpreter_.lock()->stop(); }
void LithiumApp::tidyConfig() { m_config_manager_.lock()->tidyConfig(); }

void LithiumApp::pause() { m_task_interpreter_.lock()->pause(); }
void LithiumApp::clearConfig() { m_config_manager_.lock()->clearConfig(); }

void LithiumApp::resume() { m_task_interpreter_.lock()->resume(); }

void LithiumApp::queueEvent(const std::string &eventName,
const json &eventData) {
m_task_interpreter_.lock()->queueEvent(eventName, eventData);
void LithiumApp::mergeConfig(const json &src) {
m_config_manager_.lock()->mergeConfig(src);
}

auto LithiumApp::getValue(const std::string &key_path) const
-> std::optional<nlohmann::json> {}
auto LithiumApp::setValue(const std::string &key_path,
const nlohmann::json &value) -> bool {}

auto LithiumApp::appendValue(const std::string &key_path,
const nlohmann::json &value) -> bool {}
auto LithiumApp::deleteValue(const std::string &key_path) -> bool {}
auto LithiumApp::hasValue(const std::string &key_path) const -> bool {}
auto LithiumApp::loadFromFile(const fs::path &path) -> bool {}
auto LithiumApp::loadFromDir(const fs::path &dir_path,
bool recursive) -> bool {}
auto LithiumApp::saveToFile(const fs::path &file_path) const -> bool {}
void LithiumApp::tidyConfig() {}
void LithiumApp::clearConfig() {}
void LithiumApp::mergeConfig(const nlohmann::json &src) {}

void initLithiumApp(int argc, char **argv) {
LOG_F(INFO, "Init Lithium App");
// Message Bus
AddPtr("lithium.bus", atom::async::MessageBus::createShared());
// AddPtr("lithium.bus", atom::async::MessageBus::createShared());
// AddPtr("ModuleLoader", ModuleLoader::createShared());
// AddPtr("lithium.async.thread",
// Atom::Async::ThreadManager::createShared(GetIntConfig("config/server/maxthread")));
Expand All @@ -289,7 +253,7 @@ void initLithiumApp(int argc, char **argv) {
AddPtr("lithium.task.container", TaskContainer::createShared());
AddPtr("lithiun.task.generator", TaskGenerator::createShared());
AddPtr("lithium.task.loader", TaskLoader::createShared());
AddPtr("lithium.task.manager", TaskInterpreter::createShared());
AddPtr("lithium.task.manager", Interpreter::createShared());

AddPtr("lithium.utils.env", atom::utils::Env::createShared(argc, argv));

Expand Down
Loading

0 comments on commit ffcbdfb

Please sign in to comment.