sammyette 2023-12-18 23:54:12 +00:00 committed by GitHub
commit e834fce721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 153 additions and 0 deletions

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/blackfireio/osinfo v1.0.3
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036
github.com/pborman/getopt v1.1.0
github.com/rjeczalik/notify v0.9.3
github.com/sahilm/fuzzy v0.1.0
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171

3
go.sum
View File

@ -38,6 +38,8 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY=
github.com/rjeczalik/notify v0.9.3/go.mod h1:gF3zSOrafR9DQEWSE8TjfI9NkooDxbyT4UgRGKZA0lc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 h1:d1PiN4RxzIFXCJTvRkvSkKqwtRAl5ZV4lATKtQI0B7I=
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
@ -46,6 +48,7 @@ github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -17,12 +17,39 @@ import (
"github.com/arnodel/golua/lib/packagelib"
)
var rtmm *rt.Runtime
var watcherMetaKey = rt.StringValue("hshwatcher")
var Loader = packagelib.Loader{
Load: loaderFunc,
Name: "fs",
}
func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
rtmm = rtm
watcherMethods := rt.NewTable()
watcherFuncs := map[string]util.LuaExport{
"start": {watcherStart, 1, false},
"stop": {watcherStop, 1, false},
}
util.SetExports(rtm, watcherMethods, watcherFuncs)
watcherMeta := rt.NewTable()
watcherIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
//ti, _ := watcherArg(c, 0)
arg := c.Arg(1)
val := watcherMethods.Get(arg)
if val != rt.NilValue {
return c.PushingNext1(t.Runtime, val), nil
}
return c.PushingNext1(t.Runtime, val), nil
}
watcherMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(watcherIndex, "__index", 2, false)))
rtm.SetRegistry(watcherMetaKey, rt.TableValue(watcherMeta))
exports := map[string]util.LuaExport{
"cd": util.LuaExport{fcd, 1, false},
"mkdir": util.LuaExport{fmkdir, 2, false},
@ -33,6 +60,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
"dir": util.LuaExport{fdir, 1, false},
"glob": util.LuaExport{fglob, 1, false},
"join": util.LuaExport{fjoin, 0, true},
"watch": util.LuaExport{fwatch, 2, false},
}
mod := rt.NewTable()
util.SetExports(rtm, mod, exports)
@ -250,3 +278,23 @@ func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext(t.Runtime, rt.StringValue(res)), nil
}
func fwatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(2); err != nil {
return nil, err
}
dir, err := c.StringArg(0)
if err != nil {
return nil, err
}
watcher, err := c.ClosureArg(1)
if err != nil {
return nil, err
}
dw := newWatcher(dir, watcher)
return c.PushingNext1(t.Runtime, rt.UserDataValue(dw.ud)), nil
}

View File

@ -0,0 +1,101 @@
package fs
import (
"fmt"
"github.com/rjeczalik/notify"
rt "github.com/arnodel/golua/runtime"
)
type pathWatcher struct{
path string
callback *rt.Closure
paused bool
started bool
ud *rt.UserData
notifyChan chan notify.EventInfo
}
func (w *pathWatcher) start() {
if w.callback == nil || w.started {
return
}
w.started = true
w.notifyChan = make(chan notify.EventInfo)
notify.Watch(w.path, w.notifyChan, notify.All)
go func() {
for notif := range w.notifyChan {
ev := notif.Event().String()
path := notif.Path()
_, err := rt.Call1(rtmm.MainThread(), rt.FunctionValue(w.callback), rt.StringValue(ev), rt.StringValue(path))
if err != nil {
// TODO: throw error
}
}
}()
}
func (w *pathWatcher) stop() {
w.started = false
notify.Stop(w.notifyChan)
}
func watcherStart(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
pw, err := watcherArg(c, 0)
if err != nil {
return nil, err
}
pw.start()
return c.Next(), nil
}
func watcherStop(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
pw, err := watcherArg(c, 0)
if err != nil {
return nil, err
}
pw.stop()
return c.Next(), nil
}
func newWatcher(path string, callback *rt.Closure) *pathWatcher {
pw := &pathWatcher{
path: path,
callback: callback,
}
pw.ud = watcherUserData(pw)
pw.start()
return pw
}
func watcherArg(c *rt.GoCont, arg int) (*pathWatcher, error) {
j, ok := valueToWatcher(c.Arg(arg))
if !ok {
return nil, fmt.Errorf("#%d must be a watcher", arg + 1)
}
return j, nil
}
func valueToWatcher(val rt.Value) (*pathWatcher, bool) {
u, ok := val.TryUserData()
if !ok {
return nil, false
}
j, ok := u.Value().(*pathWatcher)
return j, ok
}
func watcherUserData(j *pathWatcher) *rt.UserData {
watcherMeta := rtmm.Registry(watcherMetaKey)
return rt.NewUserData(j, watcherMeta.AsTable())
}