improve cmd
This commit is contained in:
1 parent
3445b18b1f
commit
a51708bb65
9 files changed
+229
-77
No files matched your search
@@ -1,7 +1,44 @@
|
||||
#include "cmdline.h"
|
||||
|
||||
namespace eve
|
||||
#include "cmdline/cmdline.h"
|
||||
#include <iostream>
|
||||
#include <CLI11.hpp>
|
||||
#include <rang.hpp>
|
||||
using namespace std;
|
||||
namespace eve::cmd
|
||||
{
|
||||
|
||||
struct BuildArgs : Handler {
|
||||
string log_path, platform, output_path;
|
||||
bool release = false, debug = false;
|
||||
|
||||
void setup(CLI::App& app, std::shared_ptr<CLI::Formatter> formatter) override {
|
||||
auto build = app.add_subcommand("build", "Build the game under current path");
|
||||
build->allow_extras()->formatter(formatter);
|
||||
build->add_option("-p,--platform", platform, "Build platform (linux, macosx, win32, win32_uwp, ios, android)");
|
||||
build->add_flag("-r,--release", release, "release build (default)");
|
||||
build->add_flag("-d,--debug", debug, "debug build");
|
||||
build->add_option("-l,--log", log_path, "log messages into a file");
|
||||
build->add_option("-o,--output", output_path, "output folder path");
|
||||
}
|
||||
|
||||
int parse(CLI::App& app, Cmdline& cmd) override {
|
||||
auto build = app.get_subcommand("build");
|
||||
if (build->parsed()) {
|
||||
if (debug && release) {
|
||||
cerr << rang::fg::red << "Build type can not be both debug and release" << rang::fg::reset << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (!debug && !release) { release = true; }
|
||||
|
||||
string current_path = cmd.get_remaining(build);
|
||||
return cmd.Build(current_path, output_path, platform);
|
||||
}
|
||||
return -1; // not handle
|
||||
}
|
||||
};
|
||||
|
||||
CMD_REG(BuildArgs);
|
||||
|
||||
|
||||
int Cmdline::Build(std::string path, std::string output, std::string platform) {
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,11 +1,33 @@
|
||||
#include "cmdline.h"
|
||||
#include <filesystem>
|
||||
#include <CLI11.hpp>
|
||||
#include <rang.hpp>
|
||||
|
||||
using namespace std::filesystem;
|
||||
using namespace std;
|
||||
|
||||
namespace eve
|
||||
namespace eve::cmd
|
||||
{
|
||||
|
||||
struct CreateArgs : Handler {
|
||||
void setup(CLI::App& app, std::shared_ptr<CLI::Formatter> formatter) override {
|
||||
auto create = app.add_subcommand("create", "Create a new game from template");
|
||||
create->allow_extras();
|
||||
}
|
||||
|
||||
int parse(CLI::App& app, Cmdline& cmd) override {
|
||||
auto create = app.get_subcommand("create");
|
||||
if (create->parsed()) {
|
||||
string name = cmd.get_remaining(create, "mygame");
|
||||
int res = cmd.Create(".", name);
|
||||
if (res == 0) cout << rang::fg::green << "Created " << name << " in current path" << rang::fg::reset << endl;
|
||||
return res;
|
||||
}
|
||||
return -1; // not handle
|
||||
}
|
||||
};
|
||||
|
||||
CMD_REG(CreateArgs);
|
||||
|
||||
|
||||
// create a new project
|
||||
|
||||
@@ -12,13 +12,22 @@ Cmdline
|
||||
|
||||
其中核心是执行、测试、创建、打包
|
||||
|
||||
执行逻辑:
|
||||
执行逻辑(目录):
|
||||
1. 创建脚本VM
|
||||
2. 查看当前文件夹下是否有启动脚本 boot.nut
|
||||
有: 加载
|
||||
没有: 加载默认boot脚本
|
||||
3. 运行脚本
|
||||
|
||||
执行逻辑(压缩包):
|
||||
1. 加载压缩包内文件系统
|
||||
2. 创建脚本VM
|
||||
3. 查看当前文件夹下是否有启动脚本 boot.nut
|
||||
有: 加载
|
||||
没有: 加载默认boot脚本
|
||||
4. 运行脚本
|
||||
|
||||
|
||||
开发服务器逻辑:
|
||||
1. 创建脚本VM
|
||||
2. 查看当前文件夹下是否有启动脚本
|
||||
|
||||
@@ -3,10 +3,39 @@
|
||||
#include "common/Module.h"
|
||||
|
||||
#include <simplesquirrel/simplesquirrel.hpp>
|
||||
#include <CLI11.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace eve
|
||||
using namespace std;
|
||||
|
||||
namespace eve::cmd
|
||||
{
|
||||
|
||||
struct RunArgs : Handler {
|
||||
string log_path;
|
||||
bool no_window = false, debug = false;
|
||||
|
||||
void setup(CLI::App& app, std::shared_ptr<CLI::Formatter> formatter) override {
|
||||
auto run = app.add_subcommand("run", "Run game under current path");
|
||||
run->allow_extras()->formatter(formatter);
|
||||
run->add_flag("--no-window", no_window, "Run script only, no window mode");
|
||||
run->add_flag("--debug", debug, "debug mode");
|
||||
run->add_option("-l,--log", log_path, "log messages into a file");
|
||||
}
|
||||
|
||||
int parse(CLI::App& app, Cmdline& cmd) override {
|
||||
auto run = app.get_subcommand("run");
|
||||
if (run->parsed() || cmd.getArgc() == 1) {
|
||||
string current_path = cmd.get_remaining(run);
|
||||
return cmd.Run(current_path);
|
||||
}
|
||||
return -1; // not handle
|
||||
}
|
||||
};
|
||||
|
||||
CMD_REG(RunArgs);
|
||||
|
||||
|
||||
// create a new project
|
||||
int Cmdline::Run(std::string path) {
|
||||
ssq::VM vm(2048, ssq::Libs::ALL);
|
||||
|
||||
@@ -1,13 +1,36 @@
|
||||
#include "cmdline.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "common/config.h"
|
||||
#include <simplesquirrel/simplesquirrel.hpp>
|
||||
|
||||
namespace eve
|
||||
#include <CLI11.hpp>
|
||||
#include <iostream>
|
||||
#include <rang.hpp>
|
||||
using namespace std;
|
||||
namespace eve::cmd
|
||||
{
|
||||
|
||||
Module_IMPL(Cmdline, new Cmdline());
|
||||
|
||||
Cmdline::Cmdline() {}
|
||||
std::vector<std::function<Handler*()>>& Cmdline::handers() {
|
||||
static std::vector<std::function<Handler*()>> cmds = {};
|
||||
return cmds;
|
||||
}
|
||||
|
||||
void Cmdline::registerCmd(std::function<Handler*()> handler) {
|
||||
handers().push_back(handler);
|
||||
}
|
||||
|
||||
class MyFormatter : public CLI::Formatter {
|
||||
public:
|
||||
std::string make_usage(const CLI::App *app, std::string name) const override {
|
||||
std::string usage = "Usage: ";
|
||||
usage += name;
|
||||
usage += " [Options] [Root Folder]";
|
||||
return usage;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Cmdline::Cmdline() {}
|
||||
|
||||
void Cmdline::expose(ssq::Table& table) {
|
||||
auto cls = table.addClass(name, Cmdline::create, false);
|
||||
@@ -18,6 +41,56 @@ void Cmdline::expose(ssq::Class& cls) {
|
||||
cls.addFunc("getName", &Cmdline::getName);
|
||||
}
|
||||
|
||||
int Cmdline::runArgs(unsigned argc, char** argv) {
|
||||
CLI::App app{"EVEngine - A Modern Game Engine"};
|
||||
bool version;
|
||||
app.add_flag("-v,--version", version, "Print version string");
|
||||
auto formatter = std::make_shared<MyFormatter>();
|
||||
|
||||
std::vector<Handler*> handles;
|
||||
for (auto cmd : handers()) {
|
||||
auto* p = cmd();
|
||||
handles.push_back(p);
|
||||
p->setup(app, formatter);
|
||||
}
|
||||
|
||||
try {
|
||||
this->argc = argc;
|
||||
this->argv = argv;
|
||||
app.parse(argc, argv);
|
||||
} catch (const CLI::ParseError &e) {
|
||||
for (auto* h : handles) delete h;
|
||||
int res = app.exit(e);
|
||||
return res;
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
for (auto* h : handles) {
|
||||
if (int r = h->parse(app, *this); r != -1) {
|
||||
res = r; break;
|
||||
}
|
||||
}
|
||||
if (version) cout << EVENGINE_VERSION << endl;
|
||||
|
||||
for (auto* h : handles) delete h;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string Cmdline::get_remaining(CLI::App* sub, std::string default_path) {
|
||||
auto paths = sub->remaining();
|
||||
if (paths.size() > 1) {
|
||||
cerr << rang::fg::red << "Unknown remaining arguments: " << rang::fg::reset << paths[1] << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (paths.size() == 0) {
|
||||
return default_path;
|
||||
}
|
||||
return paths[0];
|
||||
}
|
||||
|
||||
|
||||
} // namespace eve
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "common/Module.h"
|
||||
namespace CLI
|
||||
{
|
||||
class App;
|
||||
class Formatter;
|
||||
} // namespace CLI
|
||||
|
||||
namespace eve {
|
||||
|
||||
namespace eve::cmd {
|
||||
|
||||
class Cmdline;
|
||||
class Register;
|
||||
struct Handler {
|
||||
virtual ~Handler() {}
|
||||
virtual void setup(CLI::App&, std::shared_ptr<CLI::Formatter>) = 0;
|
||||
virtual int parse(CLI::App&, Cmdline&) = 0;
|
||||
};
|
||||
|
||||
class Cmdline : public Module {
|
||||
|
||||
public:
|
||||
Module_REG(Cmdline);
|
||||
|
||||
@@ -39,13 +56,35 @@ public:
|
||||
// create a new project
|
||||
int Create(std::string path, std::string name);
|
||||
|
||||
// this will be used in physfs filesystem
|
||||
void setArg0(std::string arg0) { this->arg0 = arg0; }
|
||||
std::string getArg0() { return arg0; }
|
||||
// this will run passed argv by parsing it
|
||||
int runArgs(unsigned argc, char** argv);
|
||||
|
||||
// this will be used in physfs filesystem
|
||||
std::string getArgv(unsigned i) { return argv[i]; }
|
||||
unsigned getArgc() { return argc; }
|
||||
|
||||
static std::string get_remaining(CLI::App* sub, std::string default_path = ".");
|
||||
|
||||
friend Register;
|
||||
protected:
|
||||
Cmdline();
|
||||
std::string arg0;
|
||||
|
||||
unsigned argc;
|
||||
char** argv;
|
||||
|
||||
static std::vector<std::function<Handler*()>>& handers();
|
||||
static void registerCmd(std::function<Handler*()> handler);
|
||||
};
|
||||
|
||||
#define CMD_REG(name) \
|
||||
static eve::cmd::Handler* name##_create() { return new name(); } \
|
||||
Register name##_cmd_reg(name##_create)
|
||||
|
||||
struct Register {
|
||||
Register(std::function<Handler*()> handler) {
|
||||
Cmdline::registerCmd(handler);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace eve
|
||||
+1
-61
@@ -31,65 +31,5 @@ public:
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
string log_path, output_path, current_path, platform;
|
||||
bool version = false, no_window = false, debug = false, release = false;
|
||||
int res = 0;
|
||||
|
||||
CLI::App app{"EVEngine - A Modern Game Engine"};
|
||||
app.add_flag("-v,--version", version, "Print version string");
|
||||
auto formatter = std::make_shared<MyFormatter>();
|
||||
|
||||
auto run = app.add_subcommand("run", "Run game under current path");
|
||||
run->allow_extras()->formatter(formatter);
|
||||
run->add_flag("--no-window", no_window, "Run script only, no window mode");
|
||||
run->add_flag("--debug", debug, "debug mode");
|
||||
run->add_option("-l,--log", log_path, "log messages into a file");
|
||||
|
||||
auto build = app.add_subcommand("build", "Build the game under current path");
|
||||
build->allow_extras()->formatter(formatter);
|
||||
build->add_option("-p,--platform", platform, "Build platform (linux, macosx, win32, win32_uwp, ios, android)");
|
||||
build->add_flag("-r,--release", release, "release build (default)");
|
||||
build->add_flag("-d,--debug", debug, "debug build");
|
||||
build->add_option("-l,--log", log_path, "log messages into a file");
|
||||
|
||||
auto create = app.add_subcommand("create", "Create a new game from template");
|
||||
create->allow_extras();
|
||||
|
||||
|
||||
try {
|
||||
app.parse(argc, argv);
|
||||
} catch (const CLI::ParseError &e) {
|
||||
return app.exit(e);
|
||||
}
|
||||
|
||||
Cmdline* cmd = Cmdline::create();
|
||||
cmd->setArg0(argv[0]);
|
||||
|
||||
if (build->parsed()) {
|
||||
if (debug && release) {
|
||||
cerr << rang::fg::red << "Build type can not be both debug and release" << rang::fg::reset << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (!debug && !release) { release = true; }
|
||||
|
||||
current_path = get_remaining(run);
|
||||
res = cmd->Build(current_path, output_path, platform);
|
||||
}
|
||||
|
||||
if (create->parsed()) {
|
||||
string name = get_remaining(create, "mygame");
|
||||
res = cmd->Create(".", name);
|
||||
cout << rang::fg::green << "Created " << name << " in current path" << rang::fg::reset << endl;
|
||||
}
|
||||
|
||||
if (run->parsed() || argc == 1) {
|
||||
current_path = get_remaining(run);
|
||||
res = cmd->Run(current_path);
|
||||
}
|
||||
|
||||
if (version) {
|
||||
cout << EVENGINE_VERSION << endl;
|
||||
}
|
||||
|
||||
return res;
|
||||
return requireModInst(eve::cmd,Cmdline)->runArgs(argc, argv);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace physfs {
|
||||
Filesystem::Filesystem() : fused(false), fusedSet(false) {
|
||||
requirePath = {"?.lua", "?/init.lua"};
|
||||
cRequirePath = {"??"};
|
||||
if (auto* c = getModInst(eve,Cmdline)) init(c->getArg0().c_str());
|
||||
if (auto* c = getModInst(eve::cmd,Cmdline)) init(c->getArgv(0).c_str());
|
||||
else init(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,5 +35,8 @@ function readDir() {
|
||||
print(p.getName());
|
||||
return false;
|
||||
}
|
||||
p.setIdentity("mygame", true);
|
||||
p.setupWriteDirectory();
|
||||
p.setSource(".");
|
||||
return true;
|
||||
}
|
||||
Reference in new issue
Block a user