diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AsyncEventLoop.cpp | 33 | ||||
| -rw-r--r-- | src/AsyncEventLoop.hpp | 3 | ||||
| -rw-r--r-- | src/LuaRuntime.cpp | 103 | ||||
| -rw-r--r-- | src/LuaRuntime.hpp | 14 | ||||
| -rw-r--r-- | src/widgets/MainWindow.cpp | 18 | ||||
| -rw-r--r-- | src/widgets/MainWindow.hpp | 1 |
6 files changed, 78 insertions, 94 deletions
diff --git a/src/AsyncEventLoop.cpp b/src/AsyncEventLoop.cpp index 6c9b42d..6c6333f 100644 --- a/src/AsyncEventLoop.cpp +++ b/src/AsyncEventLoop.cpp @@ -3,8 +3,6 @@ #include <mutex> #include <queue> #include <thread> -#include <utility> -#include <uv.h> #include "AsyncEventLoop.hpp" @@ -23,6 +21,8 @@ AsyncEventLoop::AsyncEventLoop() { std::this_thread::sleep_for(std::chrono::milliseconds(50)); } +void AsyncEventLoop::wake() { uv_async_send(&asyncHandle); } + void AsyncEventLoop::processTasks() { std::queue<std::function<void()>> tasks; @@ -41,10 +41,9 @@ void AsyncEventLoop::processTasks() { void AsyncEventLoop::runLoop() { isLoopRunning = true; while (isLoopRunning) { - /* int _result = */ uv_run(loop, UV_RUN_NOWAIT); - // qDebug() << "Tasks handled:" << result; - // uv_print_active_handles(loop, stdout); - // if (result == 0) + // qDebug() << "loop iteration" << uv_loop_alive(loop); + uv_run(loop, UV_RUN_NOWAIT); + // qDebug() << "uv_run() returned: " << result; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } @@ -54,33 +53,28 @@ AsyncEventLoop::~AsyncEventLoop() { return; isLoopRunning = false; - // Clear the tasks queue + // Wake it up. Stab it to death. (clear async queue) + wake(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); { std::lock_guard<std::mutex> lock(tasksQueueMutex); std::queue<std::function<void()>>().swap(tasksQueue); } - - // Wake it up. Stab it to death. - uv_async_send(&asyncHandle); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); uv_stop(loop); // Close all handles AsyncEventLoop::closeHandle(reinterpret_cast<uv_handle_t *>(&asyncHandle)); uv_walk(loop, AsyncEventLoop::closeHandle, nullptr); - while (uv_run(loop, UV_RUN_ONCE) != 0) - ; + while (uv_run(loop, UV_RUN_NOWAIT) != 0) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // TODO: Fix pending handler case (setTimeout(100) wait(20) close() -> error) - qDebug() << "join start"; if (loopThread.joinable()) loopThread.join(); - qDebug() << "join done"; - while (uv_loop_close(loop) == UV_EBUSY) { - uv_walk(loop, AsyncEventLoop::closeHandle, nullptr); - uv_run(loop, UV_RUN_NOWAIT); - } + while (uv_loop_close(loop)) + uv_run(loop, UV_RUN_DEFAULT); + free(loop); loop = nullptr; } @@ -93,5 +87,6 @@ void AsyncEventLoop::asyncHandleCallback(uv_async_t *handle) { void AsyncEventLoop::closeHandle(uv_handle_t *handle, void *) { if (!uv_is_closing(handle)) { uv_close(handle, [](uv_handle_t *h) { h->data = nullptr; }); + uv_unref(handle); } } diff --git a/src/AsyncEventLoop.hpp b/src/AsyncEventLoop.hpp index 29c2958..5718909 100644 --- a/src/AsyncEventLoop.hpp +++ b/src/AsyncEventLoop.hpp @@ -15,6 +15,7 @@ public: AsyncEventLoop(); ~AsyncEventLoop(); + void wake(); DEFINE_GETTER(getUVLoop, loop) template <typename F> void queueTask(F &&task) { @@ -22,7 +23,7 @@ public: std::lock_guard<std::mutex> lock(tasksQueueMutex); tasksQueue.push(std::forward<F>(task)); } - uv_async_send(&asyncHandle); + wake(); } protected: diff --git a/src/LuaRuntime.cpp b/src/LuaRuntime.cpp index cdf95b0..274ec29 100644 --- a/src/LuaRuntime.cpp +++ b/src/LuaRuntime.cpp @@ -13,23 +13,7 @@ const char *web_global_name = "web"; LuaRuntime::LuaRuntime() { state = luaL_newstate(); luaL_openlibs(state); - - // Load `web` - luaL_Reg weblib[] = { - {"open", &LuaRuntime::lua_onUrlOpen}, - {"tabopen", &LuaRuntime::lua_onUrlTabOpen}, - {nullptr, nullptr}, - }; - luaL_newlib(state, weblib); - lua_setglobal(state, web_global_name); - - lua_getglobal(state, web_global_name); - luaL_Reg keymaplib[] = { - {"set", &LuaRuntime::lua_addKeymap}, - }; - luaL_newlib(state, keymaplib); - lua_setfield(state, -2, "keymap"); - lua_pop(state, 1); + preserveTop(state, { initWebLib(); }) } void LuaRuntime::startEventLoop() { @@ -46,10 +30,10 @@ void LuaRuntime::startEventLoop() { } void LuaRuntime::stopEventLoop() { - if (eventLoop == nullptr) - return; - delete eventLoop; - eventLoop = nullptr; + if (eventLoop != nullptr) { + delete eventLoop; + eventLoop = nullptr; + } // Clear the uv global lua_pushnil(state); @@ -59,28 +43,26 @@ void LuaRuntime::stopEventLoop() { void LuaRuntime::evaluate(QString code) { eventLoop->queueTask([this, code]() { - if (luaL_dostring(state, code.toStdString().c_str()) != LUA_OK) { - const char *value = lua_tostring(state, -1); - lua_pop(state, 1); - - qDebug() << "Lua Error: " << value; - emit evaluationFailed(value); - } else { - QVariant value = getValue(-1); - lua_pop(state, 1); - - qDebug() << "result: " << value; - emit evaluationCompleted(value); - } + preserveTop(state, { + if (luaL_dostring(state, code.toStdString().c_str()) != LUA_OK) { + const char *value = lua_tostring(state, -1); + qDebug() << "Lua Error: " << value; + emit evaluationFailed(value); + } else { + QVariant value = getLuaValue(-1); + qDebug() << "result: " << value; + emit evaluationCompleted(value); + } + }) }); } QVariant LuaRuntime::evaluateSync(QString code) { luaL_dostring(state, code.toStdString().c_str()); - return getValue(-1); // TODO: error handling + return getLuaValue(-1); // TODO: error handling } -QVariant LuaRuntime::getValue(int idx) { +QVariant LuaRuntime::getLuaValue(int idx) { if (lua_isstring(state, idx)) return lua_tostring(state, idx); @@ -117,15 +99,13 @@ int LuaRuntime::lua_addKeymap(lua_State *state) { lua_pushvalue(state, 3); int functionRef = luaL_ref(state, LUA_REGISTRYINDEX); auto action = [state, functionRef]() { - qDebug() << "key action"; - - lua_rawgeti(state, LUA_REGISTRYINDEX, functionRef); - if (lua_pcall(state, 0, 0, 0) != LUA_OK) { - const char *error = lua_tostring(state, -1); - qDebug() << "Error calling Lua function:" << error; - lua_pop(state, 1); - } - lua_pop(state, 1); + preserveTop(state, { + lua_rawgeti(state, LUA_REGISTRYINDEX, functionRef); + if (lua_pcall(state, 0, 0, 0) != LUA_OK) { + const char *error = lua_tostring(state, -1); + qDebug() << "Error calling Lua function:" << error; + } + }) }; // TODO: Cleanup function ref on after keymap clear @@ -136,11 +116,34 @@ int LuaRuntime::lua_addKeymap(lua_State *state) { } void LuaRuntime::loadFile(QString path) { - qDebug() << "Loading: " << path; - if (luaL_dofile(state, path.toStdString().c_str()) != LUA_OK) { - qDebug() << "Load file error:" << lua_tostring(state, -1); - lua_pop(state, 1); - } + queueTask([this, path]() { + preserveTop(state, { + qDebug() << "Loading: " << path; + if (luaL_dofile(state, path.toStdString().c_str()) != LUA_OK) { + qDebug() << "Load file error:" << lua_tostring(state, -1); + } + }) + }); +} + +void LuaRuntime::initWebLib() { + // web + luaL_Reg weblib[] = { + {"open", &LuaRuntime::lua_onUrlOpen}, + {"tabopen", &LuaRuntime::lua_onUrlTabOpen}, + {nullptr, nullptr}, + }; + luaL_newlib(state, weblib); + lua_setglobal(state, web_global_name); + + // web.keymap + lua_getglobal(state, web_global_name); + luaL_Reg keymaplib[] = { + {"set", &LuaRuntime::lua_addKeymap}, + }; + luaL_newlib(state, keymaplib); + lua_setfield(state, -2, "keymap"); + // lua_pop(state, 1); } LuaRuntime::~LuaRuntime() { diff --git a/src/LuaRuntime.hpp b/src/LuaRuntime.hpp index 9f672e9..3d44282 100644 --- a/src/LuaRuntime.hpp +++ b/src/LuaRuntime.hpp @@ -7,6 +7,11 @@ #include "AsyncEventLoop.hpp" #include "widgets/WebViewStack.hpp" +#define preserveTop(STATE, BODY) \ + int __top = lua_gettop(STATE); \ + BODY; \ + lua_settop(STATE, __top); + class LuaRuntime : public QObject { Q_OBJECT @@ -17,16 +22,14 @@ public: } void evaluate(QString code); - QVariant evaluateSync(QString code); - void loadFile(QString path); + QVariant evaluateSync(QString code); void stopEventLoop(); void startEventLoop(); - - QVariant getValue(int idx); - DELEGATE(eventLoop, queueTask, queueTask) + + QVariant getLuaValue(int idx); DEFINE_GETTER(getState, state) signals: @@ -39,6 +42,7 @@ signals: protected: LuaRuntime(); ~LuaRuntime(); + void initWebLib(); static int lua_onUrlOpen(lua_State *state); static int lua_onUrlTabOpen(lua_State *state); static int lua_addKeymap(lua_State *state); diff --git a/src/widgets/MainWindow.cpp b/src/widgets/MainWindow.cpp index ce03bce..df8da53 100644 --- a/src/widgets/MainWindow.cpp +++ b/src/widgets/MainWindow.cpp @@ -51,26 +51,8 @@ MainWindow::MainWindow() { keymapEvaluator->addKeymap(KeyMode::Insert, "<esc>", [keymapEvaluator]() { keymapEvaluator->setCurrentMode(KeyMode::Normal); }); - keymapEvaluator->addKeymap(KeyMode::Normal, "<c-t>a", []() { qDebug() << "Stuff"; }); - keymapEvaluator->addKeymap(KeyMode::Normal, "<c-t>b", - []() { qDebug() << "Else"; }); -} - -void MainWindow::keyPressEvent(QKeyEvent *event) { - auto combo = event->keyCombination(); - - if (combo.key() == Qt::Key_J && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->nextWebView(); - } else if (combo.key() == Qt::Key_K && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->previousWebView(); - } else if (combo.key() == Qt::Key_W && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->closeCurrentWebView(); - } } bool MainWindow::eventFilter(QObject *, QEvent *event) { diff --git a/src/widgets/MainWindow.hpp b/src/widgets/MainWindow.hpp index 2bbc42e..c3118fc 100644 --- a/src/widgets/MainWindow.hpp +++ b/src/widgets/MainWindow.hpp @@ -10,7 +10,6 @@ public: MainWindow(); private: - void keyPressEvent(QKeyEvent *event) override; bool eventFilter(QObject *object, QEvent *event) override; private: |
