'help' command test
This commit is contained in:
parent
abf8d4f796
commit
d0b7dec225
@ -1,23 +1,65 @@
|
||||
local SEPARATOR = "________________"
|
||||
SEPARATOR = SEPARATOR..SEPARATOR..SEPARATOR
|
||||
|
||||
console.add_command(
|
||||
"help name:str=''",
|
||||
"Show help infomation for the specified command",
|
||||
function (args, kwargs)
|
||||
local name = args[1]
|
||||
if #name == 0 then
|
||||
local commands = console.get_commands_list()
|
||||
table.sort(commands)
|
||||
return "available commands: "..
|
||||
table.tostring(commands)..
|
||||
"\nuse 'help [command]'"
|
||||
end
|
||||
local command = console.get_command_info(name)
|
||||
if command == nil then
|
||||
return string.format("command %q not found", name)
|
||||
end
|
||||
local where = ""
|
||||
local str = SEPARATOR.."\n"..command.description.."\n"..name.." "
|
||||
for i,arg in ipairs(command.args) do
|
||||
where = where.."\n "..arg.name.." - "..arg.type
|
||||
if arg.optional then
|
||||
str = str.."["..arg.name.."] "
|
||||
where = where.." (optional)"
|
||||
else
|
||||
str = str.."<"..arg.name.."> "
|
||||
end
|
||||
end
|
||||
if #command.args then
|
||||
str = str.."\nwhere"..where
|
||||
end
|
||||
|
||||
return str.."\n"..SEPARATOR
|
||||
end
|
||||
)
|
||||
|
||||
console.add_command(
|
||||
"tp obj:sel=$obj.id x:num~pos.x y:num~pos.y z:num~pos.z",
|
||||
"Teleport object",
|
||||
function (args, kwargs)
|
||||
player.set_pos(unpack(args))
|
||||
end
|
||||
)
|
||||
console.add_command(
|
||||
"echo value:str",
|
||||
"Print value to the console",
|
||||
function (args, kwargs)
|
||||
return args[1]
|
||||
end
|
||||
)
|
||||
console.add_command(
|
||||
"time.set value:num",
|
||||
"Set day time [0..1] where 0 is midnight, 0.5 is noon",
|
||||
function (args, kwargs)
|
||||
return world.set_day_time(args[1])
|
||||
end
|
||||
)
|
||||
console.add_command(
|
||||
"fill id:str x:num~pos.x y:num~pos.y z:num~pos.z w:int h:int d:int",
|
||||
"blocks.fill id:str x:num~pos.x y:num~pos.y z:num~pos.z w:int h:int d:int",
|
||||
"Fill specified zone with blocks",
|
||||
function (args, kwargs)
|
||||
local name, x, y, z, w, h, d = unpack(args)
|
||||
local id = block.index(name)
|
||||
|
||||
@ -32,22 +32,6 @@ void TextBox::draw(const DrawContext* pctx, Assets* assets) {
|
||||
|
||||
font = assets->getFont(label->getFontName());
|
||||
|
||||
if (autoresize && font) {
|
||||
auto size = getSize();
|
||||
int newy = glm::min(static_cast<int>(parent->getSize().y),
|
||||
static_cast<int>(
|
||||
label->getLinesNumber() *
|
||||
label->getLineInterval() *
|
||||
font->getLineHeight()) + 1
|
||||
);
|
||||
if (newy != static_cast<int>(size.y)) {
|
||||
size.y = newy;
|
||||
setSize(size);
|
||||
if (positionfunc) {
|
||||
pos = positionfunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFocused()) {
|
||||
return;
|
||||
}
|
||||
@ -141,6 +125,24 @@ void TextBox::drawBackground(const DrawContext* pctx, Assets*) {
|
||||
void TextBox::refreshLabel() {
|
||||
label->setColor(glm::vec4(input.empty() ? 0.5f : 1.0f));
|
||||
label->setText(getText());
|
||||
|
||||
if (autoresize && font) {
|
||||
auto size = getSize();
|
||||
int newy = glm::min(static_cast<int>(parent->getSize().y),
|
||||
static_cast<int>(
|
||||
label->getLinesNumber() *
|
||||
label->getLineInterval() *
|
||||
font->getLineHeight()) + 1
|
||||
);
|
||||
if (newy != static_cast<int>(size.y)) {
|
||||
size.y = newy;
|
||||
setSize(size);
|
||||
if (positionfunc) {
|
||||
pos = positionfunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (multiline && font) {
|
||||
setScrollable(true);
|
||||
uint height = label->getLinesNumber() * font->getLineHeight() * label->getLineInterval();
|
||||
|
||||
@ -138,7 +138,7 @@ public:
|
||||
return Argument {name, type, optional, def, origin, enumname};
|
||||
}
|
||||
|
||||
Command parseScheme(executor_func executor) {
|
||||
Command parseScheme(executor_func executor, std::string_view description) {
|
||||
std::string name = parseIdentifier(true);
|
||||
std::vector<Argument> args;
|
||||
std::unordered_map<std::string, Argument> kwargs;
|
||||
@ -154,7 +154,10 @@ public:
|
||||
args.push_back(parseArgument());
|
||||
}
|
||||
}
|
||||
return Command(name, std::move(args), std::move(kwargs), executor);
|
||||
return Command(
|
||||
name, std::move(args), std::move(kwargs),
|
||||
std::string(description), executor
|
||||
);
|
||||
}
|
||||
|
||||
inline parsing_error argumentError(
|
||||
@ -368,18 +371,24 @@ public:
|
||||
while (auto arg = command->getArgument(arg_index++)) {
|
||||
if (!arg->optional) {
|
||||
throw error("missing argument "+util::quote(arg->name));
|
||||
} else {
|
||||
args->put(arg->def);
|
||||
}
|
||||
}
|
||||
return Prompt {command, args, kwargs};
|
||||
}
|
||||
};
|
||||
|
||||
Command Command::create(std::string_view scheme, executor_func executor) {
|
||||
return CommandParser("<string>", scheme).parseScheme(executor);
|
||||
Command Command::create(std::string_view scheme, std::string_view description, executor_func executor) {
|
||||
return CommandParser("<string>", scheme).parseScheme(executor, description);
|
||||
}
|
||||
|
||||
void CommandsRepository::add(std::string_view scheme, executor_func executor) {
|
||||
Command command = Command::create(scheme, executor);
|
||||
void CommandsRepository::add(
|
||||
std::string_view scheme,
|
||||
std::string_view description,
|
||||
executor_func executor
|
||||
) {
|
||||
Command command = Command::create(scheme, description, executor);
|
||||
commands[command.getName()] = command;
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,17 @@ namespace cmd {
|
||||
number, integer, enumvalue, selector, string
|
||||
};
|
||||
|
||||
inline std::string argtype_name(ArgType type) {
|
||||
switch (type) {
|
||||
case ArgType::number: return "number";
|
||||
case ArgType::integer: return "integer";
|
||||
case ArgType::enumvalue: return "enumeration";
|
||||
case ArgType::selector: return "selector";
|
||||
case ArgType::string: return "string";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
struct Argument {
|
||||
std::string name;
|
||||
ArgType type;
|
||||
@ -41,6 +52,7 @@ namespace cmd {
|
||||
std::string name;
|
||||
std::vector<Argument> args;
|
||||
std::unordered_map<std::string, Argument> kwargs;
|
||||
std::string description;
|
||||
executor_func executor;
|
||||
public:
|
||||
Command() {}
|
||||
@ -49,10 +61,12 @@ namespace cmd {
|
||||
std::string name,
|
||||
std::vector<Argument> args,
|
||||
std::unordered_map<std::string, Argument> kwargs,
|
||||
std::string description,
|
||||
executor_func executor
|
||||
) : name(name),
|
||||
args(std::move(args)),
|
||||
kwargs(std::move(kwargs)),
|
||||
) : name(name),
|
||||
args(std::move(args)),
|
||||
kwargs(std::move(kwargs)),
|
||||
description(description),
|
||||
executor(executor) {}
|
||||
|
||||
Argument* getArgument(size_t index) {
|
||||
@ -77,14 +91,38 @@ namespace cmd {
|
||||
return name;
|
||||
}
|
||||
|
||||
static Command create(std::string_view scheme, executor_func);
|
||||
const std::vector<Argument>& getArgs() const {
|
||||
return args;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, Argument>& getKwArgs() const {
|
||||
return kwargs;
|
||||
}
|
||||
|
||||
const std::string& getDescription() const {
|
||||
return description;
|
||||
}
|
||||
|
||||
static Command create(
|
||||
std::string_view scheme,
|
||||
std::string_view description,
|
||||
executor_func
|
||||
);
|
||||
};
|
||||
|
||||
class CommandsRepository {
|
||||
std::unordered_map<std::string, Command> commands;
|
||||
public:
|
||||
void add(std::string_view scheme, executor_func);
|
||||
void add(
|
||||
std::string_view scheme,
|
||||
std::string_view description,
|
||||
executor_func
|
||||
);
|
||||
Command* get(const std::string& name);
|
||||
|
||||
const std::unordered_map<std::string, Command> getCommands() const {
|
||||
return commands;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandsInterpreter {
|
||||
|
||||
@ -15,11 +15,12 @@ using namespace scripting;
|
||||
|
||||
static int l_add_command(lua_State* L) {
|
||||
auto scheme = lua_tostring(L, 1);
|
||||
lua_pushvalue(L, 2);
|
||||
auto description = lua_tostring(L, 2);
|
||||
lua_pushvalue(L, 3);
|
||||
auto func = state->createLambda();
|
||||
try {
|
||||
engine->getCommandsInterpreter()->getRepository()->add(
|
||||
scheme, [func](auto, auto args, auto kwargs) {
|
||||
scheme, description, [func](auto, auto args, auto kwargs) {
|
||||
return func({args, kwargs});
|
||||
}
|
||||
);
|
||||
@ -43,9 +44,74 @@ static int l_set(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_commands_list(lua_State* L) {
|
||||
auto interpreter = engine->getCommandsInterpreter();
|
||||
auto repo = interpreter->getRepository();
|
||||
const auto& commands = repo->getCommands();
|
||||
|
||||
lua_createtable(L, commands.size(), 0);
|
||||
size_t index = 1;
|
||||
for (const auto& entry : commands) {
|
||||
lua_pushstring(L, entry.first.c_str());
|
||||
lua_rawseti(L, -2, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_get_command_info(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
auto interpreter = engine->getCommandsInterpreter();
|
||||
auto repo = interpreter->getRepository();
|
||||
auto command = repo->get(name);
|
||||
const auto& args = command->getArgs();
|
||||
const auto& kwargs = command->getKwArgs();
|
||||
|
||||
lua_createtable(L, 0, 4);
|
||||
|
||||
lua_pushstring(L, name);
|
||||
lua_setfield(L, -2, "name");
|
||||
|
||||
lua_pushstring(L, command->getDescription().c_str());
|
||||
lua_setfield(L, -2, "description");
|
||||
|
||||
lua_createtable(L, args.size(), 0);
|
||||
for (size_t i = 0; i < args.size(); i++) {
|
||||
auto& arg = args.at(i);
|
||||
lua_createtable(L, 0, 2);
|
||||
|
||||
lua_pushstring(L, arg.name.c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
|
||||
lua_pushstring(L, cmd::argtype_name(arg.type).c_str());
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
if (arg.optional) {
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, -2, "optional");
|
||||
}
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
lua_setfield(L, -2, "args");
|
||||
|
||||
lua_createtable(L, 0, kwargs.size());
|
||||
for (auto& entry : kwargs) {
|
||||
auto& arg = entry.second;
|
||||
lua_createtable(L, 0, 1);
|
||||
|
||||
lua_pushstring(L, cmd::argtype_name(arg.type).c_str());
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
lua_setfield(L, -2, arg.name.c_str());
|
||||
}
|
||||
lua_setfield(L, -2, "kwargs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg consolelib [] = {
|
||||
{"add_command", lua_wrap_errors<l_add_command>},
|
||||
{"execute", lua_wrap_errors<l_execute>},
|
||||
{"set", lua_wrap_errors<l_set>},
|
||||
{"get_commands_list", lua_wrap_errors<l_get_commands_list>},
|
||||
{"get_command_info", lua_wrap_errors<l_get_command_info>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user