Add logging and add initial lua class

- Able to register and run lua scripts within their own environments
This commit is contained in:
Christopher Williams 2024-07-27 12:28:21 -04:00
parent eb07a89e7c
commit 35bbfac000
10 changed files with 135 additions and 24 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "lib/ydotool"] [submodule "lib/ydotool"]
path = lib/ydotool path = lib/ydotool
url = https://github.com/ReimuNotMoe/ydotool.git url = https://github.com/ReimuNotMoe/ydotool.git
[submodule "lib/spdlog"]
path = lib/spdlog
url = https://github.com/gabime/spdlog.git

View File

@ -8,9 +8,12 @@ import re
def build_ydotool(): def build_ydotool():
os.system("cd lib/ydotool && mkdir -p build && cd build && cmake .. && make") os.system("cd lib/ydotool && mkdir -p build && cd build && cmake .. && make")
def build_spdlog():
os.system("cd lib/spdlog && mkdir -p build && cd build && cmake .. && make -j8")
# Build all the dependencies # Build all the dependencies
print("Building dependencies...") print("Building dependencies...")
build_ydotool() build_spdlog()
env = Environment() env = Environment()
# platform = env["platform"] # platform = env["platform"]
@ -34,16 +37,16 @@ if int(debug):
# - CPPFLAGS are for pre-processor flags # - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines # - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags # - LINKFLAGS are for linking flags
CPPPATH = ["src/", "include/", "lib/", "./lib/ydotool/Client/"] CPPPATH = ["src/", "include/", "lib/", "lib/spdlog/include/"]
CPPDEFINES = [] CPPDEFINES = []
LIBS = ["lua"] LIBPATH = ["lib/spdlog/build/"]
LIBS = ["lua", "spdlog"]
env.Append(CCFLAGS=["-fexceptions"]) env.Append(CCFLAGS=["-fexceptions"])
env.Append(CPPPATH=CPPPATH) env.Append(CPPPATH=CPPPATH)
# env.Append(CPPDEFINES=[CPPDEFINES]) # env.Append(CPPDEFINES=[CPPDEFINES])
env.Append(LIBS=LIBS) env.Append(LIBS=LIBS)
sources = Glob("src/*.cpp") sources = Glob("src/*.cpp")
# sources += Glob("lib/ydotool/Client/*.c")
target = 'autoluakey' target = 'autoluakey'
env.Program(target, sources) env.Program(target, sources)

22
include/autoluakey.hpp Normal file
View File

@ -0,0 +1,22 @@
#ifndef AUTOLUAKEY_HPP
#define AUTOLUAKEY_HPP
#include <sol/sol.hpp>
#include <vector>
class AutoLuaKey {
public:
AutoLuaKey();
int lua_loop();
int one_shot(); // When a script is told to be executed
~AutoLuaKey();
private:
sol::state lua;
std::vector<sol::environment> environments;
void bind_lua_functions();
void bind_ydotool();
void register_lua_script(const std::string& name, const std::string& script_code);
void add_function_to_table(const std::string& script_code);
};
#endif // AUTOLUAKEY_HPP

1
lib/spdlog Submodule

@ -0,0 +1 @@
Subproject commit 5ebfc927306fd7ce551fa22244be801cf2b9fdd9

88
src/autoluakey.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "autoluakey.hpp"
#include "spdlog/spdlog.h"
#include "ydotool.hpp"
#include <iostream>
AutoLuaKey::AutoLuaKey() {
// Load lua libraries
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::io, sol::lib::os, sol::lib::coroutine);
lua.create_named_table("loop_functions");
lua.create_named_table("environments");
bind_lua_functions();
register_lua_script("lua1", R"(
function main()
print('Hello from Lua! 1')
ydotool:uinput_emit(2, 0, 100, true)
os.execute("sleep 0.5")
end
)");
register_lua_script("lua2", R"(
function main()
print('Hello from Lua! 2')
ydotool:uinput_emit(2, 0, -100, true)
os.execute("sleep 0.5")
end
)");
}
void AutoLuaKey::bind_lua_functions() {
bind_ydotool();
}
void AutoLuaKey::bind_ydotool() {
Ydotool* ydotool = new Ydotool();
lua.new_usertype<Ydotool>("Ydotool",
"uinput_emit", &Ydotool::uinput_emit
);
lua["ydotool"] = ydotool;
}
int AutoLuaKey::lua_loop() {
// emit global lua function to execute
std::string lua_code = R"(
function main()
for i = 1, 10 do
-- Execute each environment's main function
for k, v in pairs(environments) do
v.main()
end
end
end
)";
lua.script(lua_code);
sol::protected_function main = lua["main"];
main();
return 0;
}
void AutoLuaKey::add_function_to_table(const std::string& script_code) {
}
// List of scripts that come from somewhere, could be a folder, a file, etc.
// All of them need to have a function called main()
// This function will be called in the lua_loop() function
void AutoLuaKey::register_lua_script(const std::string& name, const std::string& script_code) {
// Need to create separate environments for each script so that they don't interfere with each other
spdlog::debug("Registering script: {}", name);
sol::environment env(lua, sol::create, lua.globals());
lua.script(script_code, env);
lua["environments"][name] = env;
lua.script(R"(
env_size = 0
for k, v in pairs(environments) do
print(k, v)
env_size = env_size + 1
end
print("Environment size: ", env_size)
)");
}
AutoLuaKey::~AutoLuaKey() {
delete lua["ydotool"].get<Ydotool*>();
}

BIN
src/autoluakey.o Normal file

Binary file not shown.

View File

@ -1,29 +1,17 @@
#include "ydotool.hpp" #include "ydotool.hpp"
#include <iostream> #include <iostream>
#include "sol/sol.hpp" #include "spdlog/spdlog.h"
#include "autoluakey.hpp"
void bind_ydotool(sol::state& lua) {
Ydotool* ydotool = new Ydotool();
lua.new_usertype<Ydotool>("Ydotool",
"uinput_emit", &Ydotool::uinput_emit
);
lua["ydotool"] = ydotool;
}
int main() { int main() {
sol::state lua; // Set the log level to debug
spdlog::set_level(spdlog::level::debug);
Ydotool ydotool; Ydotool ydotool;
int x = 0; AutoLuaKey autoluakey;
lua.set_function("beep", [&x]{ ++x; std::cout << "beep" << std::endl;});
lua.script("beep()");
assert(x == 1);
// Test ydotool // Test ydotool
bind_ydotool(lua); autoluakey.lua_loop();
lua.script(R"(
ydotool:uinput_emit(2, 0, -100, false);
ydotool:uinput_emit(2, 1, 100, true);
)");
return 0; return 0;
} }

Binary file not shown.

View File

@ -4,6 +4,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <sys/un.h> #include <sys/un.h>
#include "spdlog/spdlog.h"
Ydotool::Ydotool() { Ydotool::Ydotool() {
fd_daemon_socket = socket(AF_UNIX, SOCK_DGRAM, 0); fd_daemon_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
@ -21,21 +22,25 @@ Ydotool::Ydotool() {
char *env_xrd = getenv("XDG_RUNTIME_DIR"); char *env_xrd = getenv("XDG_RUNTIME_DIR");
if (env_ys) { if (env_ys) {
spdlog::debug("Connecting to socket: {}", env_ys);
snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s", env_ys); snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s", env_ys);
} else if (env_xrd){ } else if (env_xrd){
snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s/.ydotool_socket", env_xrd); snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s/.ydotool_socket", env_xrd);
spdlog::debug("Connecting to socket: {}", sa.sun_path);
} else { } else {
snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s", "/tmp/.ydotool_socket"); snprintf(sa.sun_path, sizeof(sa.sun_path)-1, "%s", "/tmp/.ydotool_socket");
spdlog::debug("Connecting to socket: {}", sa.sun_path);
} }
if (connect(fd_daemon_socket, (const struct sockaddr *) &sa, sizeof(sa))) { if (connect(fd_daemon_socket, (const struct sockaddr *) &sa, sizeof(sa))) {
int err = errno; int err = errno;
printf("failed to connect socket `%s': %s\n", sa.sun_path, strerror(err)); std::cerr << "failed to connect to socket: " << strerror(err) << std::endl;
switch (err) { switch (err) {
case ENOENT: case ENOENT:
case ECONNREFUSED: case ECONNREFUSED:
puts("Please check if ydotoold is running."); puts("Please check if ydotoold is running.");
spdlog::error("Please check if ydotoold is running.");
break; break;
case EACCES: case EACCES:
case EPERM: case EPERM:
@ -48,6 +53,7 @@ Ydotool::Ydotool() {
} }
void Ydotool::uinput_emit(uint16_t type, uint16_t code, int32_t val, bool syn_report) { void Ydotool::uinput_emit(uint16_t type, uint16_t code, int32_t val, bool syn_report) {
spdlog::debug("Emitting event: type: {}, code: {}, val: {}, syn_report: {}", type, code, val, syn_report);
struct input_event ev = { struct input_event ev = {
.type = type, .type = type,
.code = code, .code = code,

Binary file not shown.