Lua: Allow creation of commands
This commit is contained in:
parent
089602bd77
commit
3f493d24d1
3 changed files with 112 additions and 2 deletions
25
manual.lyx
25
manual.lyx
|
@ -1155,6 +1155,31 @@ To create press/release commands, use aliases +foo and -foo .
|
|||
Keep the returned object around.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
create_command(string name, function a[, function b])
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Return object representing a command (pair).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
If b is NIL, the command is level-sensitive, a is callback.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
If b is function, the function is edge-sensitive, a is positive edge callback
|
||||
and b is negative edge callback.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
All callbacks get single argument: The parameters passed.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Keep the returned object around.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Table bit:
|
||||
\end_layout
|
||||
|
|
13
manual.txt
13
manual.txt
|
@ -555,6 +555,19 @@ and specified command.
|
|||
|
||||
• Keep the returned object around.
|
||||
|
||||
7.1.13 create_command(string name, function a[, function b])
|
||||
|
||||
Return object representing a command (pair).
|
||||
|
||||
• If b is NIL, the command is level-sensitive, a is callback.
|
||||
|
||||
• If b is function, the function is edge-sensitive, a is positive
|
||||
edge callback and b is negative edge callback.
|
||||
|
||||
• All callbacks get single argument: The parameters passed.
|
||||
|
||||
• Keep the returned object around.
|
||||
|
||||
7.2 Table bit:
|
||||
|
||||
Bitwise logical functions and related.
|
||||
|
|
|
@ -6,16 +6,76 @@
|
|||
class lua_inverse_bind
|
||||
{
|
||||
public:
|
||||
lua_inverse_bind(const std::string name, const std::string cmd);
|
||||
lua_inverse_bind(const std::string& name, const std::string& cmd);
|
||||
private:
|
||||
inverse_bind ikey;
|
||||
};
|
||||
|
||||
lua_inverse_bind::lua_inverse_bind(const std::string name, const std::string cmd)
|
||||
class lua_command_binding : public command
|
||||
{
|
||||
public:
|
||||
lua_command_binding(lua_state& _L, const std::string& cmd, int idx)
|
||||
: command(lsnes_cmd, cmd), L(_L)
|
||||
{
|
||||
L.pushlightuserdata(this);
|
||||
L.pushvalue(idx);
|
||||
L.rawset(LUA_REGISTRYINDEX);
|
||||
}
|
||||
void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
L.pushlightuserdata(this);
|
||||
L.rawget(LUA_REGISTRYINDEX);
|
||||
L.pushstring(arguments.c_str());
|
||||
int r = L.pcall(1, 0, 0);
|
||||
std::string err;
|
||||
if(r == LUA_ERRRUN)
|
||||
err = L.get_string(-1, "Lua command callback");
|
||||
else if(r == LUA_ERRMEM)
|
||||
err = "Out of memory";
|
||||
else if(r == LUA_ERRERR)
|
||||
err = "Double fault";
|
||||
else
|
||||
err = "Unknown error";
|
||||
if(r) {
|
||||
messages << "Error running lua command hook: " << err << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
lua_state& L;
|
||||
};
|
||||
|
||||
class lua_command_bind
|
||||
{
|
||||
public:
|
||||
lua_command_bind(lua_state* L, const std::string& cmd, int idx1, int idx2);
|
||||
~lua_command_bind();
|
||||
private:
|
||||
lua_command_binding* a;
|
||||
lua_command_binding* b;
|
||||
};
|
||||
|
||||
lua_inverse_bind::lua_inverse_bind(const std::string& name, const std::string& cmd)
|
||||
: ikey(lsnes_mapper, cmd, "Lua‣" + name)
|
||||
{
|
||||
}
|
||||
|
||||
lua_command_bind::lua_command_bind(lua_state* L, const std::string& cmd, int idx1, int idx2)
|
||||
{
|
||||
if(L->type(idx2) == LUA_TFUNCTION) {
|
||||
a = new lua_command_binding(*L, "+" + cmd, idx1);
|
||||
b = new lua_command_binding(*L, "-" + cmd, idx2);
|
||||
} else {
|
||||
a = new lua_command_binding(*L, cmd, idx1);
|
||||
b = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lua_command_bind::~lua_command_bind()
|
||||
{
|
||||
delete a;
|
||||
delete b;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
function_ptr_luafun input_bindings(LS, "list_bindings", [](lua_state& L, const std::string& fname) -> int {
|
||||
|
@ -73,6 +133,18 @@ namespace
|
|||
lua_inverse_bind* b = lua_class<lua_inverse_bind>::create(L, name, command);
|
||||
return 1;
|
||||
});
|
||||
|
||||
function_ptr_luafun create_cmd(LS, "create_command", [](lua_state& L, const std::string& fname) -> int {
|
||||
if(L.type(2) != LUA_TFUNCTION)
|
||||
throw std::runtime_error("Argument 2 of create_command must be function");
|
||||
if(L.type(3) != LUA_TFUNCTION && L.type(3) != LUA_TNIL && L.type(3) != LUA_TNONE)
|
||||
throw std::runtime_error("Argument 2 of create_command must be function or nil");
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
lua_command_bind* b = lua_class<lua_command_bind>::create(L, &L, name, 2, 3);
|
||||
return 1;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
DECLARE_LUACLASS(lua_inverse_bind, "INVERSEBIND");
|
||||
DECLARE_LUACLASS(lua_command_bind, "COMMANDBIND");
|
||||
|
|
Loading…
Add table
Reference in a new issue