Browse Source

Switch to Entropia File System Watcher from fswatch. Re-add "Reload

script" context menu item.
tags/v1.1.1
Andrew Belt 5 years ago
parent
commit
06f7a889a3
6 changed files with 51 additions and 171 deletions
  1. +0
    -3
      .gitmodules
  2. +12
    -16
      Makefile
  3. +7
    -0
      README.md
  4. +0
    -1
      fswatch
  5. +0
    -110
      fswatch_mingw_patch.sh
  6. +32
    -41
      src/Prototype.cpp

+ 0
- 3
.gitmodules View File

@@ -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

+ 12
- 16
Makefile View File

@@ -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


+ 7
- 0
README.md View File

@@ -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`.


+ 0
- 1
fswatch

@@ -1 +0,0 @@
Subproject commit d5d2ea84da1f0b0da23921891965894a86c72c27

+ 0
- 110
fswatch_mingw_patch.sh View File

@@ -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 <sys/cygwin.h>
+#else
+#include <windows.h>
+#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

+ 32
- 41
src/Prototype.cpp View File

@@ -6,7 +6,7 @@
#include <mutex>
#include <thread>
#include "ScriptEngine.hpp"
#include <libfswatch/c/libfswatch.h>
#include <efsw/efsw.h>


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<ReloadScriptItem>("Reload script");
reloadScriptItem->module = module;
menu->addChild(reloadScriptItem);

SaveScriptItem* saveScriptItem = createMenuItem<SaveScriptItem>("Save script as");
saveScriptItem->module = module;
menu->addChild(saveScriptItem);


Loading…
Cancel
Save