From 06f7a889a368589cad8b3d11d4b275a8042280ba Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Fri, 27 Sep 2019 07:39:53 -0400 Subject: [PATCH] Switch to Entropia File System Watcher from fswatch. Re-add "Reload script" context menu item. --- .gitmodules | 3 -- Makefile | 28 +++++------ README.md | 7 +++ fswatch | 1 - fswatch_mingw_patch.sh | 110 ----------------------------------------- src/Prototype.cpp | 73 ++++++++++++--------------- 6 files changed, 51 insertions(+), 171 deletions(-) delete mode 160000 fswatch delete mode 100644 fswatch_mingw_patch.sh diff --git a/.gitmodules b/.gitmodules index 817d774..1068f94 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "fswatch"] - path = fswatch - url = https://github.com/emcrisostomo/fswatch.git [submodule "QuickJS"] path = QuickJS url = https://github.com/JerrySievert/QuickJS.git diff --git a/Makefile b/Makefile index f7d09a2..fc8844a 100644 --- a/Makefile +++ b/Makefile @@ -13,22 +13,18 @@ DISTRIBUTABLES += $(wildcard LICENSE*) include $(RACK_DIR)/arch.mk -# fswatch -fswatch := dep/lib/libfswatch.a -DEPS += $(fswatch) -OBJECTS += $(fswatch) -ifdef ARCH_WIN - LDFLAGS += -lintl - FSWATCH_CONFIGURE_FLAGS += CFLAGS="-DHAVE_WINDOWS" CXXFLAGS="-DHAVE_WINDOWS" -endif -$(fswatch): -ifdef ARCH_WIN - cd fswatch && MINGWPREFIX=/mingw64 ../fswatch_mingw_patch.sh -endif - cd fswatch && ./autogen.sh - cd fswatch && $(CONFIGURE) $(FSWATCH_CONFIGURE_FLAGS) --enable-shared=no - cd fswatch && $(MAKE) - cd fswatch && $(MAKE) install +# Entropia File System Watcher +efsw := dep/lib/libefsw-static-release.a +DEPS += $(efsw) +OBJECTS += $(efsw) +$(efsw): + cd dep && $(WGET) "https://bitbucket.org/SpartanJ/efsw/get/e6afbec564e2.zip" + cd dep && $(SHA256) e6afbec564e2.zip 8589dbedac7434f1863637af696354a9f1fcc28c6397c37b492a797ae62976be + cd dep && $(UNZIP) e6afbec564e2.zip + cd dep/SpartanJ-efsw-e6afbec564e2 && premake4 gmake + cd dep/SpartanJ-efsw-e6afbec564e2 && $(MAKE) -C make/windows config=release efsw-static-lib + cd dep/SpartanJ-efsw-e6afbec564e2 && cp lib/libefsw-static-release.a $(DEP_PATH)/lib/ + cd dep/SpartanJ-efsw-e6afbec564e2 && cp -R include/efsw $(DEP_PATH)/include/ # QuickJS quickjs := dep/lib/quickjs/libquickjs.a diff --git a/README.md b/README.md index ab10794..3171234 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,13 @@ function process(block) { } ``` +## Build dependencies + +### Windows +``` +pacman -S mingw-w64-x86_64-premake +``` + ## Adding a script engine - Add your scripting language library to the build system so it builds with `make dep`, following the Duktape example in the `Makefile`. diff --git a/fswatch b/fswatch deleted file mode 160000 index d5d2ea8..0000000 --- a/fswatch +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d5d2ea84da1f0b0da23921891965894a86c72c27 diff --git a/fswatch_mingw_patch.sh b/fswatch_mingw_patch.sh deleted file mode 100644 index c32da13..0000000 --- a/fswatch_mingw_patch.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/sh -# fix missing S_ISLNK in libfswatch/src/libfswatch/c++/poll_monitor.cpp -patch -ulbf libfswatch/src/libfswatch/c++/poll_monitor.cpp << EOF -@@ -131,2 +131,3 @@ - -+#ifndef _WIN32 - if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) -@@ -139,2 +140,3 @@ - } -+#endif - -EOF -# fix missing realpath/lstat in libfswatch/src/libfswatch/c++/path_utils.cpp -patch -ulbf libfswatch/src/libfswatch/c++/path_utils.cpp << EOF -@@ -59,2 +59,5 @@ - { -+#ifdef _WIN32 -+ return false; -+#else - char *real_path = realpath(path.c_str(), nullptr); -@@ -66,2 +69,3 @@ - return ret; -+#endif - } -@@ -82,2 +86,6 @@ - { -+#ifdef _WIN32 -+ fsw_logf_perror(_("Cannot lstat %s (not implemented on Windows)"), path.c_str()); -+ return false; -+#else - if (lstat(path.c_str(), &fd_stat) != 0) -@@ -90,2 +98,3 @@ - return true; -+#endif - } -EOF -# fix missing sigaction/realpath in fswatch/src/fswatch.cpp -patch -ulbf fswatch/src/fswatch.cpp << EOF -@@ -36,2 +36,5 @@ - #include "libfswatch/c++/libfswatch_exception.hpp" -+#ifdef _WIN32 -+#define realpath(N,R) _fullpath((R),(N),_MAX_PATH) -+#endif - -@@ -297,2 +300,3 @@ - { -+#ifndef _WIN32 - struct sigaction action; -@@ -328,2 +332,3 @@ - } -+#endif - } -EOF -# fix libfswatch/src/libfswatch/c++/windows/win_paths.cpp -patch -ulbf libfswatch/src/libfswatch/c++/windows/win_paths.cpp << EOF -@@ -16,3 +16,7 @@ - #include "win_paths.hpp" -+#ifdef __CYGWIN__ - #include -+#else -+#include -+#endif - #include "../libfswatch_exception.hpp" -@@ -28,2 +32,3 @@ - { -+#ifdef __CYGWIN__ - void * raw_path = cygwin_create_path(CCP_POSIX_TO_WIN_W, path.c_str()); -@@ -36,2 +41,11 @@ - return win_path; -+#else -+ int pathlen = (int)path.length() + 1; -+ int buflen = MultiByteToWideChar(CP_ACP, 0, path.c_str(), pathlen, 0, 0); -+ wchar_t* buf = new wchar_t[buflen]; -+ MultiByteToWideChar(CP_ACP, 0, path.c_str(), pathlen, buf, buflen); -+ std::wstring result(buf); -+ delete[] buf; -+ return result; -+#endif - } -@@ -40,2 +54,3 @@ - { -+#ifdef __CYGWIN__ - void * raw_path = cygwin_create_path(CCP_WIN_W_TO_POSIX, path.c_str()); -@@ -48,2 +63,11 @@ - return posix_path; -+#else -+ int pathlen = (int)path.length() + 1; -+ int buflen = WideCharToMultiByte(CP_ACP, 0, path.c_str(), pathlen, 0, 0, 0, 0); -+ char* buf = new char[buflen]; -+ WideCharToMultiByte(CP_ACP, 0, path.c_str(), pathlen, buf, buflen, 0, 0); -+ std::string result(buf); -+ delete[] buf; -+ return result; -+#endif - } -EOF -# fix missing file -touch README.illumos -# remove detection of realpath/regcomp/select -mv libfswatch/configure.ac libfswatch/configure.ac.bak && -grep -v "realpath\|regcomp\|select" libfswatch/configure.ac.bak > libfswatch/configure.ac -# remove detection of realpath -mv configure.ac configure.ac.bak2 && -grep -v "realpath" configure.ac.bak2 > configure.ac -# remove detection of realpath -mv configure.ac configure.ac.bak3 && -grep -v "The select function cannot be found." configure.ac.bak3 > configure.ac -# fix for building windows_monitor -mv libfswatch/src/libfswatch/Makefile.am libfswatch/src/libfswatch/Makefile.am.bak && -sed -e "s/USE_CYGWIN/USE_WINDOWS/" libfswatch/src/libfswatch/Makefile.am.bak > libfswatch/src/libfswatch/Makefile.am diff --git a/src/Prototype.cpp b/src/Prototype.cpp index 1746f19..d9142c3 100644 --- a/src/Prototype.cpp +++ b/src/Prototype.cpp @@ -6,7 +6,7 @@ #include #include #include "ScriptEngine.hpp" -#include +#include using namespace rack; @@ -44,8 +44,7 @@ struct Prototype : Module { ScriptEngine::ProcessBlock* block; int bufferIndex = 0; - FSW_SESSION* fsw = NULL; - std::thread watchThread; + efsw_watcher efsw = NULL; Prototype() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); @@ -128,11 +127,9 @@ struct Prototype : Module { void setPath(std::string path) { // Cleanup - if (fsw) { - fsw_stop_monitor(fsw); - fsw_destroy_session(fsw); - watchThread.join(); - fsw = NULL; + if (efsw) { + efsw_release(efsw); + efsw = NULL; } this->path = ""; setScript(""); @@ -147,22 +144,10 @@ struct Prototype : Module { return; // Watch file - FSW_STATUS err = fsw_init_library(); - if (err == FSW_OK) { -#if defined ARCH_LIN - fsw_monitor_type type = inotify_monitor_type; -#elif defined ARCH_MAC - fsw_monitor_type type = fsevents_monitor_type; -#elif defined ARCH_WIN - fsw_monitor_type type = windows_monitor_type; -#endif - fsw = fsw_init_session(type); - fsw_add_path(fsw, this->path.c_str()); - fsw_set_callback(fsw, watchCallback, this); - fsw_set_allow_overflow(fsw, false); - fsw_set_latency(fsw, 0.5); - watchThread = std::thread(watchRun, fsw); - } + std::string dir = string::directory(path); + efsw = efsw_create(false); + efsw_addwatch(efsw, dir.c_str(), watchCallback, false, this); + efsw_watch(efsw); } void loadPath() { @@ -231,23 +216,13 @@ struct Prototype : Module { this->engineName = scriptEngine->getEngineName(); } - static void watchRun(FSW_SESSION* fsw) { - fsw_start_monitor(fsw); - } - - static void watchCallback(fsw_cevent const* const events, const unsigned int event_num, void* data) { - Prototype* that = (Prototype*) data; - if (event_num < 1) - return; - - // Look for flags - for (unsigned i = 0; i < event_num; i++) { - for (unsigned j = 0; j < events[i].flags_num; j++) { - fsw_event_flag flag = events[i].flags[j]; - if (flag == Created || flag == Updated) { - that->loadPath(); - return; - } + static void watchCallback(efsw_watcher watcher, efsw_watchid watchid, const char* dir, const char* filename, enum efsw_action action, const char* old_filename, void* param) { + Prototype* that = (Prototype*) param; + if (action == EFSW_ADD || action == EFSW_DELETE || action == EFSW_MODIFIED || action == EFSW_MOVED) { + // Check filename + std::string pathFilename = string::filename(that->path); + if (pathFilename == filename) { + that->loadPath(); } } } @@ -291,6 +266,10 @@ struct Prototype : Module { setPath(path); } + void reloadScript() { + loadPath(); + } + void saveScriptDialog() { if (script == "") return; @@ -403,6 +382,14 @@ struct LoadScriptItem : MenuItem { }; +struct ReloadScriptItem : MenuItem { + Prototype* module; + void onAction(const event::Action& e) override { + module->reloadScript(); + } +}; + + struct SaveScriptItem : MenuItem { Prototype* module; void onAction(const event::Action& e) override { @@ -475,6 +462,10 @@ struct PrototypeWidget : ModuleWidget { loadScriptItem->module = module; menu->addChild(loadScriptItem); + ReloadScriptItem* reloadScriptItem = createMenuItem("Reload script"); + reloadScriptItem->module = module; + menu->addChild(reloadScriptItem); + SaveScriptItem* saveScriptItem = createMenuItem("Save script as"); saveScriptItem->module = module; menu->addChild(saveScriptItem);