You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gserver/compile.go

83 lines
1.7 KiB
Go

package main
import (
"bufio"
"os"
"sync"
"github.com/fangdingjun/go-log"
lua "github.com/yuin/gopher-lua"
"github.com/yuin/gopher-lua/parse"
)
// from https://github.com/yuin/gophoer-lua
// CompileLua reads the passed lua file from disk and compiles it.
func CompileLua(filePath string) (*lua.FunctionProto, error) {
file, err := os.Open(filePath)
defer file.Close()
if err != nil {
return nil, err
}
reader := bufio.NewReader(file)
chunk, err := parse.Parse(reader, filePath)
if err != nil {
return nil, err
}
proto, err := lua.Compile(chunk, filePath)
if err != nil {
return nil, err
}
return proto, nil
}
// DoCompiledFile takes a FunctionProto, as returned by CompileLua, and runs it in the LState. It is equivalent
// to calling DoFile on the LState with the original source file.
func DoCompiledFile(L *lua.LState, proto *lua.FunctionProto) error {
lfunc := L.NewFunctionFromProto(proto)
L.Push(lfunc)
return L.PCall(0, lua.MultRet, nil)
}
type filecache struct {
filepath string
proto *lua.FunctionProto
lastMod int64
}
var cache = map[string]*filecache{}
var mu = new(sync.Mutex)
func runFile(vm *lua.LState, filepath string) error {
mu.Lock()
c, ok := cache[filepath]
if !ok {
c = &filecache{
filepath: filepath,
lastMod: 0,
}
cache[filepath] = c
}
fi, err := os.Stat(filepath)
if err != nil {
mu.Unlock()
return err
}
t := fi.ModTime().Unix()
if t > c.lastMod {
log.Debugf("file %s changed, reload", filepath)
proto, err := CompileLua(filepath)
if err != nil {
mu.Unlock()
return err
}
c.proto = proto
c.lastMod = t
}
mu.Unlock()
// log.Println(c.proto)
return DoCompiledFile(vm, c.proto)
}