瀏覽代碼

初始化

master
maike 4 年之前
父節點
當前提交
81d90a1d80
共有 37 個檔案被更改,包括 1973 行新增0 行删除
  1. +4
    -0
      .gitignore
  2. +13
    -0
      constDef.go
  3. +75
    -0
      file_util.go
  4. +8
    -0
      go.mod
  5. +18
    -0
      goApis/crypto/README.md
  6. +23
    -0
      goApis/crypto/api.go
  7. +20
    -0
      goApis/crypto/api_test.go
  8. +21
    -0
      goApis/crypto/loader.go
  9. +70
    -0
      goApis/goApilibs.go
  10. +23
    -0
      goApis/json/README.md
  11. +31
    -0
      goApis/json/api.go
  12. +15
    -0
      goApis/json/api_test.go
  13. +21
    -0
      goApis/json/loader.go
  14. +127
    -0
      goApis/json/value.go
  15. +30
    -0
      goApis/strings/README.md
  16. +74
    -0
      goApis/strings/api.go
  17. +15
    -0
      goApis/strings/api_test.go
  18. +26
    -0
      goApis/strings/loader.go
  19. +4
    -0
      goApis/testScript/test_crypto_api.lua
  20. +14
    -0
      goApis/testScript/test_json_api.lua
  21. +26
    -0
      goApis/testScript/test_strings_api.lua
  22. +24
    -0
      goApis/testScript/test_time_api.lua
  23. +28
    -0
      goApis/time/README.md
  24. +62
    -0
      goApis/time/api.go
  25. +15
    -0
      goApis/time/api_test.go
  26. +24
    -0
      goApis/time/loader.go
  27. +199
    -0
      hotfix.go
  28. +136
    -0
      luaScript/bit.lua
  29. +80
    -0
      luaScript/class.lua
  30. +295
    -0
      luaScript/extend.lua
  31. +37
    -0
      luaScript/random.lua
  32. +42
    -0
      luaScript/unilight.lua
  33. +21
    -0
      luaScript/uniregexp.lua
  34. +137
    -0
      luaScript/unitimer.lua
  35. +118
    -0
      luaScript/utf8.lua
  36. +76
    -0
      luaStatePool.go
  37. +21
    -0
      preLoadGo.go

+ 4
- 0
.gitignore 查看文件

@ -11,5 +11,9 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
go.sum
.idea
# Dependency directories (remove the comment below to include it)
# vendor/

+ 13
- 0
constDef.go 查看文件

@ -0,0 +1,13 @@
package luaInGo
import lua "github.com/yuin/gopher-lua"
const (
InitPoolSize = 128
NaxPoolSize = 512
)
//初始化lua LState连接池
var LuaStatePool = &lStatePool{
saved: make([]*lua.LState, 0, InitPoolSize),
}

+ 75
- 0
file_util.go 查看文件

@ -0,0 +1,75 @@
package luaInGo
import (
"fmt"
"io/ioutil"
"os"
"path"
)
// LuaFile lua文件
type LuaFile struct {
FileName string
}
// LuaFileExist 判断某lua脚本是否存在
func LuaFileExist(fileName string) bool {
fileList := GetAllLuaFile()
for _, file := range fileList {
if file.FileName == fileName {
return true
}
}
return false
}
// GetAllLuaFile 获取所有文件
func GetAllLuaFile() []LuaFile {
// 声明一个文件列表切片
var fileList []LuaFile
rd, err := ioutil.ReadDir("luafile")
if err != nil {
fmt.Println("GetAllLuaFile error", err)
return fileList
}
for _, fi := range rd {
fileList = append(fileList, LuaFile{fi.Name()})
}
return fileList
}
// DeleteLuaFile 删除文件
func DeleteLuaFile(fileName string) bool {
err := os.Remove("luafile/" + fileName)
if err != nil {
fmt.Println("DeleteLuaFile error", err)
return false
}
return true
}
func ListLuaFile(folder string, luas []string) {
files, _ := ioutil.ReadDir(folder)
for _, file := range files {
if file.IsDir() {
ListLuaFile(folder+"/"+file.Name(), luas)
} else {
var filenameWithSuffix string = path.Base(file.Name()) //获取文件名带后缀
var fileSuffix string = path.Ext(filenameWithSuffix) //获取文件后缀
if fileSuffix == ".lua" {
filePath := fmt.Sprintf("%s%s%s", folder, "/", file.Name())
luas = append(luas, filePath)
}
}
}
}
func GetFileModtime(file string) (int64, error) {
stat, err := os.Stat(file)
if err != nil {
fmt.Printf("stat fail, file=%v err=%v", file, err)
return 0, err
}
return stat.ModTime().Unix(), nil
}

+ 8
- 0
go.mod 查看文件

@ -0,0 +1,8 @@
module luaInGo
go 1.14
require (
github.com/vadv/gopher-lua-libs v0.1.0
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e
)

+ 18
- 0
goApis/crypto/README.md 查看文件

@ -0,0 +1,18 @@
## Usage
origin code: https://github.com/vadv/gopher-lua-libs/tree/master/crypto
```lua
local crypto = require("crypto")
-- md5
if not(crypto.md5("1\n") == "b026324c6904b2a9cb4b88d6d61c81d1") then
error("md5")
end
-- sha256
if not(crypto.sha256("1\n") == "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865") then
error("sha256")
end
```

+ 23
- 0
goApis/crypto/api.go 查看文件

@ -0,0 +1,23 @@
package crypto
import (
"crypto/md5"
"crypto/sha256"
"fmt"
lua "github.com/yuin/gopher-lua"
)
func MD5(L *lua.LState) int {
str := L.CheckString(1)
hash := md5.Sum([]byte(str))
L.Push(lua.LString(fmt.Sprintf("%x", hash)))
return 1
}
func SHA256(L *lua.LState) int {
str := L.CheckString(1)
hash := sha256.Sum256([]byte(str))
L.Push(lua.LString(fmt.Sprintf("%x", hash)))
return 1
}

+ 20
- 0
goApis/crypto/api_test.go 查看文件

@ -0,0 +1,20 @@
package crypto
import (
"io/ioutil"
"testing"
lua "github.com/yuin/gopher-lua"
)
func TestApi(t *testing.T) {
data, err := ioutil.ReadFile("../testScript/test_crypto_api.lua")
if err != nil {
t.Fatalf("%s\n", err.Error())
}
state := lua.NewState()
PreLoadGo(state)
if err := state.DoString(string(data)); err != nil {
t.Fatalf("execute test: %s\n", err.Error())
}
}

+ 21
- 0
goApis/crypto/loader.go 查看文件

@ -0,0 +1,21 @@
package crypto
import (
lua "github.com/yuin/gopher-lua"
)
func PreLoadGo(L *lua.LState) {
L.PreloadModule("crypto", Loader)
}
func Loader(L *lua.LState) int {
t := L.NewTable()
L.SetFuncs(t, api)
L.Push(t)
return 1
}
var api = map[string]lua.LGFunction{
"md5": MD5,
"sha256": SHA256,
}

+ 70
- 0
goApis/goApilibs.go 查看文件

@ -0,0 +1,70 @@
package goApis
import (
lua "github.com/yuin/gopher-lua"
cloudwatch "github.com/vadv/gopher-lua-libs/aws/cloudwatch"
cert_util "github.com/vadv/gopher-lua-libs/cert_util"
chef "github.com/vadv/gopher-lua-libs/chef"
cmd "github.com/vadv/gopher-lua-libs/cmd"
crypto "github.com/vadv/gopher-lua-libs/crypto"
db "github.com/vadv/gopher-lua-libs/db"
filepath "github.com/vadv/gopher-lua-libs/filepath"
goos "github.com/vadv/gopher-lua-libs/goos"
http "github.com/vadv/gopher-lua-libs/http"
humanize "github.com/vadv/gopher-lua-libs/humanize"
inspect "github.com/vadv/gopher-lua-libs/inspect"
ioutil "github.com/vadv/gopher-lua-libs/ioutil"
json "github.com/vadv/gopher-lua-libs/json"
log "github.com/vadv/gopher-lua-libs/log"
plugin "github.com/vadv/gopher-lua-libs/plugin"
pprof "github.com/vadv/gopher-lua-libs/pprof"
prometheus "github.com/vadv/gopher-lua-libs/prometheus/client"
regexp "github.com/vadv/gopher-lua-libs/regexp"
runtime "github.com/vadv/gopher-lua-libs/runtime"
"github.com/vadv/gopher-lua-libs/stats"
storage "github.com/vadv/gopher-lua-libs/storage"
strings "github.com/vadv/gopher-lua-libs/strings"
tac "github.com/vadv/gopher-lua-libs/tac"
tcp "github.com/vadv/gopher-lua-libs/tcp"
telegram "github.com/vadv/gopher-lua-libs/telegram"
template "github.com/vadv/gopher-lua-libs/template"
time "github.com/vadv/gopher-lua-libs/time"
xmlpath "github.com/vadv/gopher-lua-libs/xmlpath"
yaml "github.com/vadv/gopher-lua-libs/yaml"
zabbix "github.com/vadv/gopher-lua-libs/zabbix"
)
// 这里封装一个函数 统一load go中提供给lua调用的函数
func PreLoadLibs(L *lua.LState) {
time.Preload(L)
strings.Preload(L)
filepath.Preload(L)
ioutil.Preload(L)
http.Preload(L)
regexp.Preload(L)
tac.Preload(L)
inspect.Preload(L)
yaml.Preload(L)
plugin.Preload(L)
cmd.Preload(L)
json.Preload(L)
tcp.Preload(L)
xmlpath.Preload(L)
db.Preload(L)
cert_util.Preload(L)
runtime.Preload(L)
telegram.Preload(L)
zabbix.Preload(L)
pprof.Preload(L)
prometheus.Preload(L)
crypto.Preload(L)
goos.Preload(L)
storage.Preload(L)
humanize.Preload(L)
chef.Preload(L)
template.Preload(L)
cloudwatch.Preload(L)
log.Preload(L)
stats.Preload(L)
}

+ 23
- 0
goApis/json/README.md 查看文件

@ -0,0 +1,23 @@
# json
origin code: https://github.com/vadv/gopher-lua-libs/tree/master/json
## Usage
```lua
local json = require("json")
-- json.encode()
local jsonString = [[
{
"a": {"b":1}
}
]]
local result, err = json.decode(jsonString)
if err then error(err) end
-- json.decode()
local table = {a={b=1}}
local result, err = json.encode(table)
if err then error(err) end
```

+ 31
- 0
goApis/json/api.go 查看文件

@ -0,0 +1,31 @@
package json
import (
lua "github.com/yuin/gopher-lua"
)
func Decode(L *lua.LState) int {
str := L.CheckString(1)
value, err := ValueDecode(L, []byte(str))
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString(err.Error()))
return 2
}
L.Push(value)
return 1
}
func Encode(L *lua.LState) int {
value := L.CheckAny(1)
data, err := ValueEncode(value)
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString(err.Error()))
return 2
}
L.Push(lua.LString(string(data)))
return 1
}

+ 15
- 0
goApis/json/api_test.go 查看文件

@ -0,0 +1,15 @@
package json
import (
"testing"
lua "github.com/yuin/gopher-lua"
)
func TestApi(t *testing.T) {
state := lua.NewState()
PreloadGo(state)
if err := state.DoFile("../testScript/test_json_api.lua"); err != nil {
t.Fatalf("execute test: %s\n", err.Error())
}
}

+ 21
- 0
goApis/json/loader.go 查看文件

@ -0,0 +1,21 @@
package json
import (
lua "github.com/yuin/gopher-lua"
)
func PreloadGo(L *lua.LState) {
L.PreloadModule("json", Loader)
}
func Loader(L *lua.LState) int {
t := L.NewTable()
L.SetFuncs(t, api)
L.Push(t)
return 1
}
var api = map[string]lua.LGFunction{
"decode": Decode,
"encode": Encode,
}

+ 127
- 0
goApis/json/value.go 查看文件

@ -0,0 +1,127 @@
package json
import (
"encoding/json"
"errors"
lua "github.com/yuin/gopher-lua"
)
var (
errNested = errors.New("cannot encode recursively nested tables to JSON")
errSparseArray = errors.New("cannot encode sparse array")
errInvalidKeys = errors.New("cannot encode mixed or invalid key types")
)
type invalidTypeError lua.LValueType
func (i invalidTypeError) Error() string {
return `cannot encode ` + lua.LValueType(i).String() + ` to JSON`
}
type jsonValue struct {
lua.LValue
visited map[*lua.LTable]bool
}
func (j jsonValue) MarshalJSON() (data []byte, err error) {
switch converted := j.LValue.(type) {
case lua.LBool:
data, err = json.Marshal(bool(converted))
case lua.LNumber:
data, err = json.Marshal(float64(converted))
case *lua.LNilType:
data = []byte(`null`)
case lua.LString:
data, err = json.Marshal(string(converted))
case *lua.LTable:
if j.visited[converted] {
return nil, errNested
}
j.visited[converted] = true
key, value := converted.Next(lua.LNil)
switch key.Type() {
case lua.LTNil: // empty table
data = []byte(`[]`)
case lua.LTNumber:
arr := make([]jsonValue, 0, converted.Len())
expectedKey := lua.LNumber(1)
for key != lua.LNil {
if key.Type() != lua.LTNumber {
err = errInvalidKeys
return
}
if expectedKey != key {
err = errSparseArray
return
}
arr = append(arr, jsonValue{value, j.visited})
expectedKey++
key, value = converted.Next(key)
}
data, err = json.Marshal(arr)
case lua.LTString:
obj := make(map[string]jsonValue)
for key != lua.LNil {
if key.Type() != lua.LTString {
err = errInvalidKeys
return
}
obj[key.String()] = jsonValue{value, j.visited}
key, value = converted.Next(key)
}
data, err = json.Marshal(obj)
default:
err = errInvalidKeys
}
default:
err = invalidTypeError(j.LValue.Type())
}
return
}
// ValueDecode converts the JSON encoded data to Lua values.
func ValueDecode(L *lua.LState, data []byte) (lua.LValue, error) {
var value interface{}
err := json.Unmarshal(data, &value)
if err != nil {
return nil, err
}
return decode(L, value), nil
}
func decode(L *lua.LState, value interface{}) lua.LValue {
switch converted := value.(type) {
case bool:
return lua.LBool(converted)
case float64:
return lua.LNumber(converted)
case string:
return lua.LString(converted)
case []interface{}:
arr := L.CreateTable(len(converted), 0)
for _, item := range converted {
arr.Append(decode(L, item))
}
return arr
case map[string]interface{}:
tbl := L.CreateTable(0, len(converted))
for key, item := range converted {
tbl.RawSetH(lua.LString(key), decode(L, item))
}
return tbl
case nil:
return lua.LNil
}
panic("unreachable")
}
// ValueEncode returns the JSON encoding of value.
func ValueEncode(value lua.LValue) ([]byte, error) {
return json.Marshal(jsonValue{
LValue: value,
visited: make(map[*lua.LTable]bool),
})
}

+ 30
- 0
goApis/strings/README.md 查看文件

@ -0,0 +1,30 @@
# strings
origin code: https://github.com/vadv/gopher-lua-libs/tree/master/strings
## Usage
```lua
local strings = require("strings")
-- strings.split(string, sep)
local result = strings.split("a b c d", " ")
-- Output: { "a", "b", "c", "d" }
-- strings.has_prefix(string, prefix)
local result = strings.has_prefix("abcd", "a")
-- Output: true
-- strings.has_suffix(string, suffix)
local result = strings.has_suffix("abcd", "d")
-- Output: true
-- strings.trim(string, cutset)
local result = strings.trim("abcd", "d")
-- Output: abc
-- strings.contains(string, substring)
local result = strings.contains("abcd", "d")
-- Output: true
```

+ 74
- 0
goApis/strings/api.go 查看文件

@ -0,0 +1,74 @@
package strings
import (
"strings"
lua "github.com/yuin/gopher-lua"
)
// Split(): lua strings.split(string, sep): port of go string.Split() returns table
func Split(L *lua.LState) int {
str := L.CheckString(1)
delim := L.CheckString(2)
strSlice := strings.Split(str, delim)
result := L.CreateTable(len(strSlice), 0)
for _, str := range strSlice {
result.Append(lua.LString(str))
}
L.Push(result)
return 1
}
// HasPrefix(): lua strings.has_prefix(string, suffix): port of go string.HasPrefix() return bool
func HasPrefix(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.HasPrefix(str1, str2)
L.Push(lua.LBool(result))
return 1
}
// HasSuffix(): lua strings.has_suffix(string, prefix): port of go string.HasSuffix() returns bool
func HasSuffix(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.HasSuffix(str1, str2)
L.Push(lua.LBool(result))
return 1
}
// Trim(): lua strings.trim(string, cutset) Port of go string.Trim() returns string
func Trim(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.Trim(str1, str2)
L.Push(lua.LString(result))
return 1
}
// TrimPrefix(): lua strings.trim_prefix(string, cutset) Port of go string.TrimPrefix() returns string
func TrimPrefix(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.TrimPrefix(str1, str2)
L.Push(lua.LString(result))
return 1
}
// TrimSuffix(): lua strings.trim_suffix(string, cutset) Port of go string.TrimSuffix() returns string
func TrimSuffix(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.TrimSuffix(str1, str2)
L.Push(lua.LString(result))
return 1
}
// Contains(): lua strings.contains(string, cutset) Port of go string.Contains() returns bool
func Contains(L *lua.LState) int {
str1 := L.CheckString(1)
str2 := L.CheckString(2)
result := strings.Contains(str1, str2)
L.Push(lua.LBool(result))
return 1
}

+ 15
- 0
goApis/strings/api_test.go 查看文件

@ -0,0 +1,15 @@
package strings
import (
"testing"
lua "github.com/yuin/gopher-lua"
)
func TestApi(t *testing.T) {
state := lua.NewState()
PreLoadGo(state)
if err := state.DoFile("../testScript/test_strings_api.lua"); err != nil {
t.Fatalf("execute test: %s\n", err.Error())
}
}

+ 26
- 0
goApis/strings/loader.go 查看文件

@ -0,0 +1,26 @@
package strings
import (
lua "github.com/yuin/gopher-lua"
)
func PreLoadGo(L *lua.LState) {
L.PreloadModule("strings", Loader)
}
func Loader(L *lua.LState) int {
t := L.NewTable()
L.SetFuncs(t, api)
L.Push(t)
return 1
}
var api = map[string]lua.LGFunction{
"split": Split,
"trim": Trim,
"trim_prefix": TrimPrefix,
"trim_suffix": TrimSuffix,
"has_prefix": HasPrefix,
"has_suffix": HasSuffix,
"contains": Contains,
}

+ 4
- 0
goApis/testScript/test_crypto_api.lua 查看文件

@ -0,0 +1,4 @@
local crypto = require("crypto")
if not(crypto.md5("1\n") == "b026324c6904b2a9cb4b88d6d61c81d1") then error("md5") end
if not(crypto.sha256("1\n") == "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865") then error("sha256") end

+ 14
- 0
goApis/testScript/test_json_api.lua 查看文件

@ -0,0 +1,14 @@
local json = require("json")
local jsonStringWithNull = [[{"a":{"b":1, "c":null}}]]
local jsonString = [[{"a":{"b":1}}]]
local result, err = json.decode(jsonStringWithNull)
if err then error(err) end
if not(result["a"]["b"] == 1) then error("must be decode") end
print("done: json.decode()")
local result, err = json.encode(result)
if err then error(err) end
if not(result==jsonString) then error("must be encode "..result) end
print("done: json.encode()")

+ 26
- 0
goApis/testScript/test_strings_api.lua 查看文件

@ -0,0 +1,26 @@
local strings = require("strings")
local str = "hello world"
local t = strings.split(str, " ")
local count_t = 0
for k, v in pairs(t) do
count_t = count_t + 1
if k == 1 then if not(v == "hello") then error("strings.split()") end end
if k == 2 then if not(v == "world") then error("strings.split()") end end
end
if not(count_t == 2) then error("string.split()") end
print("done: strings.split()")
if not(strings.has_prefix(str, "hello")) then error("strings.has_prefix()") end
if not(strings.has_suffix(str, "world")) then error("strings.has_suffix()") end
print("done: strings.has_suffix, strings.has_prefix")
if not(strings.trim(str, "world") == "hello ") then error("strings.trim()") end
if not(strings.trim(str, "hello ") == "world") then error("strings.trim()") end
if not(strings.trim_prefix(str, "hello ") == "world") then error("strings.trim()") end
if not(strings.trim_suffix(str, "hello ") == "hello world") then error("strings.trim()") end
print("done: strings.trim()")
if not(strings.contains(str, "hello ") == true) then error("strings.contains()") end
print("done: strings.contains()")

+ 24
- 0
goApis/testScript/test_time_api.lua 查看文件

@ -0,0 +1,24 @@
local time = require("time")
local lua_before = os.clock()
local before = time.unix()
time.sleep(2)
local after = time.unix()
local lua_after = os.clock()
if after - before < 1 then error("time.unix()") end
if lua_after - lua_before < 2 then error("time.sleep()") end
print("done: time.sleep(), time.unix()")
local parse, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006")
if err then error(err) end
if not(parse == 1543721585) then error("time.parse(): 1") end
print("done: time.parse(): 1")
local _, err = time.parse("Dec 32 03:33:05 2018", "Jan 2 15:04:05 2006")
if (err == nil) then error("time.parse(): must be error") end
print("done: time.parse(): 2")
local result, err = time.format(1543721585, "Jan 2 15:04:05 2006", "Europe/Moscow")
if err then error(err) end
if not(result == "Dec 2 06:33:05 2018") then error("time.format()") end
print("done: time.format(): 1")

+ 28
- 0
goApis/time/README.md 查看文件

@ -0,0 +1,28 @@
# time
origin code: https://github.com/vadv/gopher-lua-libs/tree/master/time
## Usage
```lua
local time = require("time")
-- time.unix(), time.sleep()
local begin = time.unix()
time.sleep(1.2)
local stop = time.unix()
local result = stop - begin
result = math.floor(result * 10^2 + 0.5) / 10^2
if not(result == 1) then error("time.sleep()") end
-- time.parse(value, layout)
local result, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006")
if err then error(err) end
if not(result == 1543721585) then error("time.parse()") end
-- time.format(value, layout, location)
local result, err = time.format(1543721585, "Jan 2 15:04:05 2006", "Europe/Moscow")
if err then error(err) end
if not(result == "Dec 2 06:33:05 2018") then error("time.format()") end
```

+ 62
- 0
goApis/time/api.go 查看文件

@ -0,0 +1,62 @@
package time
import (
"time"
lua "github.com/yuin/gopher-lua"
)
func Unix(L *lua.LState) int {
now := float64(time.Now().UnixNano()) / float64(time.Second)
L.Push(lua.LNumber(now))
return 1
}
func UnixNano(L *lua.LState) int {
L.Push(lua.LNumber(time.Now().UnixNano()))
return 1
}
func Sleep(L *lua.LState) int {
val := L.CheckNumber(1)
time.Sleep(time.Duration(val) * time.Second)
return 0
}
func Parse(L *lua.LState) int {
layout, value := L.CheckString(2), L.CheckString(1)
result, err := time.Parse(layout, value)
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString(err.Error()))
return 2
}
resultFloat := float64(result.UTC().UnixNano()) / float64(time.Second)
L.Push(lua.LNumber(resultFloat))
return 1
}
func Format(L *lua.LState) int {
tt := float64(L.CheckNumber(1))
sec := int64(tt)
nsec := int64((tt - float64(sec)) * 1000000000)
result := time.Unix(sec, nsec)
layout := "Mon Jan 2 15:04:05 -0700 MST 2006"
if L.GetTop() > 1 {
layout = L.CheckString(2)
}
if L.GetTop() < 3 {
L.Push(lua.LString(result.Format(layout)))
return 1
}
location := L.CheckString(3)
loc, err := time.LoadLocation(location)
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString(err.Error()))
return 2
}
result = result.In(loc)
L.Push(lua.LString(result.Format(layout)))
return 1
}

+ 15
- 0
goApis/time/api_test.go 查看文件

@ -0,0 +1,15 @@
package time
import (
"testing"
lua "github.com/yuin/gopher-lua"
)
func TestApi(t *testing.T) {
state := lua.NewState()
PreLoadGo(state)
if err := state.DoFile("../testScript/test_time_api.lua"); err != nil {
t.Fatalf("execute test: %s\n", err.Error())
}
}

+ 24
- 0
goApis/time/loader.go 查看文件

@ -0,0 +1,24 @@
package time
import (
lua "github.com/yuin/gopher-lua"
)
func PreLoadGo(L *lua.LState) {
L.PreloadModule("time", Loader)
}
func Loader(L *lua.LState) int {
t := L.NewTable()
L.SetFuncs(t, api)
L.Push(t)
return 1
}
var api = map[string]lua.LGFunction{
"unix": Unix,
"unix_nano": UnixNano,
"sleep": Sleep,
"parse": Parse,
"format": Format,
}

+ 199
- 0
hotfix.go 查看文件

@ -0,0 +1,199 @@
package luaInGo
// import (
// "context"
// "sync"
// "sync/atomic"
// "time"
//
// log "github.com/iglev/ilog"
// )
//
// type hotfixMgr interface {
// reg(file string)
// check(L *LState) *hotfixList
// }
//
// func newHotfixMgr(ctx context.Context, needCoro bool, hotfixTime int64) hotfixMgr {
// var ht hotfixMgr
// if needCoro {
// htco := &hotfixMgrCoro{
// ctx: ctx,
// ch: make(chan *hotfixList, 16),
// hotfixTime: hotfixTime,
// }
// go htco.loop()
// ht = htco
// } else {
// ht = &hotfixMgrLocal{
// mp: make(map[string]int64),
// lasttime: time.Now().Unix(),
// hotfixTime: hotfixTime,
// }
// }
// return ht
// }
//
// type hotfixList struct {
// files []string
// }
//
// func hotfixDoFile(L *LState, ht hotfixMgr, up *hotfixList) {
// size := len(up.files)
// for i := 0; i < size; i++ {
// err := L.L().DoFile(up.files[i])
// if err != nil {
// log.Error("DoFile fail, file=%v err=%v", up.files[i], err)
// } else {
// log.Info("reload file=%v success", up.files[i])
// }
// }
// }
//
// //////////////////////////////////////////////////////////////////
// // hotfixMgrLocal
//
// type hotfixMgrLocal struct {
// mp map[string]int64
// lasttime int64
// hotfixTime int64
// }
//
// func (ht *hotfixMgrLocal) reg(file string) {
// mt, err := getFileModtime(file)
// if err != nil {
// return
// }
// ht.mp[file] = mt
// }
//
// func (ht *hotfixMgrLocal) check(L *LState) *hotfixList {
// curr := time.Now().Unix()
// lasttime := atomic.LoadInt64(&ht.lasttime)
// if curr < (lasttime + ht.hotfixTime) {
// return nil
// }
// atomic.StoreInt64(&ht.lasttime, curr)
// up := ht.getHotfixList()
// if up != nil {
// hotfixDoFile(L, ht, up)
// }
// return up
// }
//
// func (ht *hotfixMgrLocal) getHotfixList() *hotfixList {
// size := len(ht.mp)
// if size <= 0 {
// return nil
// }
// up := &hotfixList{
// files: make([]string, 0, size),
// }
// tmp := make(map[string]int64)
// for k, v := range ht.mp {
// mt, err := getFileModtime(k)
// if err != nil {
// log.Error("getFileModtime fail, file=%v err=%v", k, err)
// continue
// }
// if v != mt {
// up.files = append(up.files, k)
// tmp[k] = mt
// }
// }
// for k, v := range tmp {
// ht.mp[k] = v
// }
// return up
// }
//
// //////////////////////////////////////////////////////////////////
// // hotfixMgrCoro
//
// type hotfixMgrCoro struct {
// ctx context.Context
// mp sync.Map
// ch chan *hotfixList
// hotfixTime int64
// }
//
// func (ht *hotfixMgrCoro) reg(file string) {
// mt, err := getFileModtime(file)
// if err != nil {
// return
// }
// ht.mp.Store(file, mt)
// }
//
// func (ht *hotfixMgrCoro) check(L *LState) *hotfixList {
// up := ht.getHotfixList()
// if up != nil {
// hotfixDoFile(L, ht, up)
// }
// return up
// }
//
// func (ht *hotfixMgrCoro) getHotfixList() *hotfixList {
// select {
// case up := <-ht.ch:
// return up
// default:
// return nil
// }
// }
//
// func (ht *hotfixMgrCoro) loop() {
// timer := time.NewTimer(time.Duration(ht.hotfixTime) * time.Second)
// defer timer.Stop()
// Loop:
// for {
// select {
// case <-timer.C:
// ht.loopCheck()
// timer.Reset(time.Duration(ht.hotfixTime) * time.Second)
// case <-ht.ctx.Done():
// break Loop
// }
// }
// }
//
// func (ht *hotfixMgrCoro) loopCheck() {
// var up *hotfixList
// mp := make(map[string]int64)
// ht.mp.Range(func(k, v interface{}) bool {
// file, ok := k.(string)
// if !ok {
// return false
// }
// oldmt, mtOK := v.(int64)
// if !mtOK {
// return false
// }
// newmt, err := getFileModtime(file)
// if err != nil {
// log.Error("getFileModtime fail, file=%v err=%v", file, err)
// return false
// }
// if newmt != oldmt {
// mp[file] = newmt
// }
// return true
// })
// size := len(mp)
// if size > 0 {
// up = &hotfixList{
// files: make([]string, 0, size),
// }
// for k, v := range mp {
// ht.mp.Store(k, v)
// up.files = append(up.files, k)
// }
// select {
// case ht.ch <- up:
// return
// default:
// log.Error("hotfix send to channel fail, up=%v", up)
// }
// }
// }
//

+ 136
- 0
luaScript/bit.lua 查看文件

@ -0,0 +1,136 @@
require ("math")
module('bit', package.seeall) -- 实现按位运算
--默认按32位
local __bitNum = 32
--设置位数
function setBitNum(bitNum)
__bitNum = bitNum
end
--按位同或
function bxnor(int1, int2)
return __operaByBit(__bitxnor, int1, int2)
end
--按位异或
function bxor(int1, int2)
return __operaByBit(__bitxor, int1, int2)
end
--按位与
function band(int1, int2)
return __operaByBit(__bitand, int1, int2)
end
--按位或
function bor(int1, int2)
return __operaByBit(__bitor, int1, int2)
end
--按位非
function bnot(integer)
return __operaByBit(__bitnot, integer)
end
--按位操作
function __operaByBit(bitFunc, ...)
local bDataLst = {}
for i = 1, select("#", ...) do
local bData = itob(select(i, ...))
table.insert(bDataLst, bData)
end
for _, bData in ipairs(bDataLst) do
for i = #bData + 1, __bitNum do
table.insert(bData, 1, 0)
end
end
local resData = {}
for i = 1, __bitNum do
local args = {}
for _, bData in ipairs(bDataLst) do
table.insert(args, bData[i])
end
table.insert(resData, bitFunc(unpack(args)))
end
return btoi(resData)
end
--按位同或
function __bitxnor(bit1, bit2)
return (bit1 == bit2) and 1 or 0
end
--按位异或
function __bitxor(bit1, bit2)
return (bit1 == bit2) and 0 or 1
end
--按位与
function __bitand(bit1, bit2)
return (bit1 == 1 and bit2 == 1) and 1 or 0
end
--按位或
function __bitor(bit1, bit2)
return (bit1 == 1 or bit2 == 1) and 1 or 0
end
--按位非
function __bitnot(bit)
return 1 - bit
end
--2进制转换成10进制
function btoi(bData)
return __ntoi(bData, 2)
end
--10进制转换成2进制
function itob(integer)
return __iton(integer, 2)
end
--10进制转换成N进制
function __iton(integer, num)
assert(type(integer) == "number")
if integer == 0 then
return {0}
end
local bNeg = integer < 0
local ci = math.abs(integer)
local nData = {}
while ci > 0 do
table.insert(nData, 1, ci % num)
ci = math.floor(ci / num)
end
if bNeg then
for i = #nData + 1, __bitNum do
table.insert(nData, 1, num - 1)
end
end
return nData
end
--N进制转换成10进制
function __ntoi(nData, num)
assert(type(nData) == "table")
local integer = 0
for i, data in ipairs(nData) do
integer = integer + data * math.pow(num, #nData - i)
end
return integer
end

+ 80
- 0
luaScript/class.lua 查看文件

@ -0,0 +1,80 @@
function GetClassName(name)
for k,v in pairs(_G) do
if name==v then
return k
end
end
end
function CreateClass(name,basename)
if _G[name] ~= nil then
unilight.error("CreateClass被意外全局初始化,这里强制重置成类:"..name)
return nil
end
_G[name] = {}
local class = _G[name]
if basename then
local baseclass = _G[basename]
if baseclass then
for k,v in pairs(baseclass) do
class[k] = v
end
else
unilight.error("CreateClass error:" .. tostring(name) .. ":" .. tostring(basename))
end
end
class.__classname = name
function class:New(initclass)
local new = initclass or {}
setmetatable(new, { __index = self})
return new
end
function class:SetClassName(cname)
self.__classname = cname or self.__classname
end
function class:GetLogPrefix()
local id = nil
local name = ""
if self.GetId then
id = self:GetId()
elseif self.id then
id = self.id
elseif self.Id then
id = self.Id
elseif self.tempid then
id = self.tempid
elseif self.Tempid then
id = self.Tempid
end
if self.GetName then
name = self:GetName()
elseif self.name then
name = self.name
elseif self.Name then
name = self.Name
end
local id = id or ""
local name = name or ""
return self.__classname .. "[" .. id .."," ..name.. "] "
end
function class:Debug(...)
unilight.debug(self:GetLogPrefix() .. unpack(arg))
end
function class:Info(...)
unilight.info(self:GetLogPrefix() .. unpack(arg))
end
function class:Warn(...)
unilight.warn(self:GetLogPrefix() .. unpack(arg))
end
function class:Error(...)
unilight.error(self:GetLogPrefix() .. unpack(arg))
end
function class:Stack(...)
unilight.stack(self:GetLogPrefix() .. unpack(arg))
end
return class
end
--Class = CreateClass("Class")
--new = Class:New()
--new:Debug("whj")

+ 295
- 0
luaScript/extend.lua 查看文件

@ -0,0 +1,295 @@
-- 通用lua扩充函数,与任何游戏逻辑无关
-- from http://snippets.luacode.org/?p=snippets/String_to_Hex_String_68
string.tohex = function(str, spacer)
return string.gsub(str,"(.)", function (c) return string.format("%02X%s", string.byte(c), spacer or "") end)
end
string.trim = function(str)
return string.gsub(str, "^%s*(.-)%s*$", "%1")
end
string.trimbegin = function(str)
return string.gsub(str, "^%s*(.-)$", "%1")
end
string.trimend = function(str)
return string.gsub(str, "^(.-)%s*$", "%1")
end
string.padleft = function(str, totalWidth, paddingChar)
local len = #str
if len >= totalWidth then
return str
else
paddingChar = paddingChar or ' '
assert(#paddingChar == 1)
return string.rep(paddingChar, totalWidth - len) .. str
end
end
string.padright = function(str, totalWidth, paddingChar)
local len = #str
if len >= totalWidth then
return str
else
paddingChar = paddingChar or ' '
assert(#paddingChar == 1)
return str .. string.rep(paddingChar, totalWidth - len)
end
end
string.split = function(szFullString, szSeparator)
local FindStartIndex = 1
local SplitArray = {}
while true do
local FindLastIndex = string.find(szFullString, szSeparator, FindStartIndex, true)
if not FindLastIndex then
table.insert(SplitArray, string.sub(szFullString, FindStartIndex, string.len(szFullString)))
break
end
table.insert(SplitArray, string.sub(szFullString, FindStartIndex, FindLastIndex-1))
FindStartIndex = FindLastIndex + string.len(szSeparator)
end
return SplitArray
end
string.isNilOrEmpty = function(str)
if str == nil then
return true, nil
end
if type(str) ~= "string" then
return true, nil
end
local fstr = string.match(str,"%s*(.-)%s*$")
local ret = fstr == ""
if ret == true then
str = nil
end
return ret, fstr
end
table.find = function(this, value)
for k,v in pairs(this) do
if v == value then return k end
end
end
table.omit = function(tbl)
for k,v in pairs(tbl) do
local typ = type(v)
if typ == "table" then
v = table.omit(v)
if v == nil or next(v) == nil then
tbl[k] = nil
end
elseif (typ == "string" and v == "") or (typ == "number" and v == 0) then
tbl[k] = nil
end
end
return tbl
end
table.tostring = function(data, _indent)
local visited = {}
local function dump(data, prefix)
local str = tostring(data)
if table.find(visited, data) ~= nil then return str end
table.insert(visited, data)
local prefix_next = prefix .. " "
str = str .. "\n" .. prefix .. "{"
for k,v in pairs(data) do
if type(k) == "number" then
str = str .. "\n" .. prefix_next .. "[" .. tostring(k) .. "] = "
else
str = str .. "\n" .. prefix_next .. tostring(k) .. " = "
end
if type(v) == "table" then
str = str .. dump(v, prefix_next)
elseif type(v) == "string" then
str = str .. '"' .. v .. '"'
else
str = str .. tostring(v)
end
end
str = str .. "\n" .. prefix .. "}"
return str
end
return dump(data, _indent or "")
end
table.merge = function(base, delta)
if type(delta) ~= "table" then return end
for k,v in pairs(delta) do
base[k] = v
end
end
table.extend = function(base, delta)
if type(delta) ~= "table" then return end
for i,v in ipairs(delta) do
table.insert(base, v)
end
end
table.len = function(tbl)
if type(tbl) ~= "table" then return 0 end
local n = 0
for k,v in pairs(tbl) do n = n + 1 end
return n
end
table.empty = function(tbl)
if tbl == nil then return true end
assert(type(tbl) == "table")
return next(tbl) == nil
--if #tbl > 0 then return false end
--for k,v in pairs(tbl) do return false end
--return true
end
-- http://snippets.luacode.org/?p=snippets/Deep_copy_of_a_Lua_Table_2
table.clone = function(t,deepnum)
if type(t) ~= 'table' then return t end
local mt = getmetatable(t)
local res = {}
if deepnum and deepnum > 0 then
deepnum = deepnum - 1
end
for k,v in pairs(t) do
if type(v) == 'table' then
if not deepnum or deepnum > 0 then
v = table.clone(v, deepnum)
end
end
res[k] = v
end
setmetatable(res,mt)
return res
end
-- http://snippets.luacode.org/?p=snippets/Table_Slice_116
table.slice = function(values,i1,i2)
local res = {}
local n = #values
i1 = i1 or 1
i2 = i2 or n
if i2 < 0 then
i2 = n + i2 + 1
elseif i2 > n then
i2 = n
end
if i1 < 1 or i1 > n then
return {}
end
local k = 1
for i = i1,i2 do
res[k] = values[i]
k = k + 1
end
return res
end
table.reverse = function(tab)
local size = #tab
local newTable = {}
for i,v in ipairs(tab) do
newTable[size+1-i] = v
end
return newTable
end
table.reset = function(t)
for k,v in pairs(t) do
t[k] = nil
end
return t
end
-- math.random({0.7, 0.1, 0.2}, {'A', 'B', 'C'})
math.random = function(m, n)
if type(m) == "table" and #m == #n then
-- 标准化概率表
local sum = 0
for _,v in ipairs(m) do sum = sum + v end
local sm = {}
for k,v in ipairs(m) do sm[k] = v / sum end
-- 得到下标
local r = go.rand.Random()
for k,v in ipairs(sm) do
if r <= v then return n[k]
else r = r - v end
end
assert(false)
end
if m == nil then return go.rand.Random() end
local _random = function(m, n)
m, n = math.min(m, n), math.max(m, n)
local mi, mf = math.modf(m)
local ni, nf = math.modf(n)
if mf == 0 and nf == 0 then
return go.rand.RandBetween(m, n)
else
return m + go.rand.Random() * (n - m)
end
end
if n == nil then return _random(1, m) end
return _random(m, n)
end
-- http://www.cplusplus.com/reference/algorithm/random_shuffle/
-- http://stackoverflow.com/questions/17119804/lua-array-shuffle-not-working
math.shuffle = function(array)
local counter = #array
while counter > 1 do
local index = math.random(counter)
array[index], array[counter] = array[counter], array[index]
counter = counter - 1
end
return array
end
--按table的key排序遍历table e.g. for k, v in pairsByKeys(tab, function(v1,v2) return v1 > v2 end) do print(k, v) end
function pairsByKeys(t, sortfunc)
local kt = {}
local len = 0
for k in pairs(t) do
len = len + 1
kt[len] = k
end
table.sort(kt, sortfunc)
local i = 0
return function()
i = i + 1
return kt[i], t[kt[i]]
end
end
--计算utf8字符串的长度 from quickcocos
function string.utf8len(input)
local len = string.len(input)
local left = len
local cnt = 0
local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
while left ~= 0 do
local tmp = string.byte(input, -left)
local i = #arr
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
cnt = cnt + 1
end
return cnt
end
--检查一个文件是否存在
function file_exists(path)
local file = io.open(path, "rb")
if file then file:close() end
return file ~= nil
end

+ 37
- 0
luaScript/random.lua 查看文件

@ -0,0 +1,37 @@
module('random', package.seeall)
--添加的随机概率函数---------
----小数点概率---
function selectByPoint(value)
if value == nil or value <= 0 then
return false
end
local value = math.ceil(1 / value)
return selectByRegion(1, value)
end
----百分比概率---
function selectByPercent(value)
if value < 1 then
return false
end
return selectByRegion(value, 100)
end
----万分比概率---
function selectByTenTh(value)
if value < 1 then
return false
end
return selectByRegion(value, 10000)
end
function selectByRegion(down, up)
if down >= up then
return true
end
local random = math.random(1, up)
return random <= down
end

+ 42
- 0
luaScript/unilight.lua 查看文件

@ -0,0 +1,42 @@
unilight = unilight or {}
os.time = go.time.luatime()
os.msectime = go.time.Msec
os.nsectime = go.time.Nsec
-- log --
unilight.debug = function(...)
local arg = {...}
go.logging.debug(arg[1], arg[2] or {})
end
unilight.info = function(...)
local arg = {...}
go.logging.info(arg[1], arg[2] or {})
end
unilight.warn = function(...)
print("unilight-warn:" .. tostring(...))
local arg = {...}
go.logging.warning(arg[1], arg[2] or {})
end
unilight.error = function(...)
local arg = {...}
if next(arg) == nil then
unilight.error(debug.traceback())
end
go.logging.error(arg[1], arg[2] or {})
end
unilight.stack = function(...)
local arg = {...}
print("unilight-stack:" .. tostring(...))
end
unilight.tablefiles = function()
return luar.slice2table(go.getLuaFiles(go.tablePath))
end
unilight.scriptfiles = function()
return luar.slice2table(go.getLuaFiles(go.scriptPath))
end

+ 21
- 0
luaScript/uniregexp.lua 查看文件

@ -0,0 +1,21 @@
uniregexp= uniregexp or {}
--[[
exp:
uniregexp.match("foo.*","seafood") => true nil
uniregexp.match("bar.*","seafood") => false nil
uniregexp.match("a(b","seafood") => false error parsing regexp: missing closing ): `a(b`
--]]
uniregexp.match = function(pattern, s)
return go.uniregexp.Match(pattern, s)
end
--[[
exp:
quotemeta(`[foo]`) => `\[foo\]`
--]]
uniregexp.quotemeta = function(s)
return go.uniregexp.QuoteMeta(s)
end
-- 其余api可以调用go.uniregexp.***** 参考go语言 regexp.Regexp类方法

+ 137
- 0
luaScript/unitimer.lua 查看文件

@ -0,0 +1,137 @@
CreateClass("UniTimerClass")
CreateClass("UniEventClass")
function NewUniTimerClass(callback, msec, ...)
local timer = {
nextmsec=unitimer.now,
callback = callback,
tick = msec,
params = arg,
}
UniTimerClass:New(timer)
return timer
end
function NewUniTimerRandomClass(callback, msec, ...)
local timer = {
nextmsec=unitimer.now+math.random(msec/2,msec),
callback = callback,
tick = msec,
params = arg,
}
UniTimerClass:New(timer)
return timer
end
function NewUniEventClass(callback, msec,maxtimes, ...)
local event = {
nextmsec=unitimer.now+msec,
callback = callback,
tick = msec,
maxtimes = maxtimes,
params = arg,
}
UniEventClass:New(event)
return event
end
function UniTimerClass:GetId()
return self.tick
end
function UniTimerClass:GetName()
return self.tick
end
function UniTimerClass:Stop()
self.stop = true
unitimer.removetimer(self)
end
function UniTimerClass:Check(now,force)
if self.nextmsec <= now or force then
--unilight.error("UniEventClass:"..unpack(self.params))
self.nextmsec = now + self.tick --如果callback脚本报错,会悲剧,WHJ,似乎没人用,先提前试试
self.callback(unpack(self.params))
return true
end
--duaration=0
--first=true
--pause=false
--stop=false
return false
end
function UniEventClass:GetId()
return self.tick
end
function UniEventClass:GetName()
return self.maxtimes
end
function UniEventClass:Check(now,force)
--if (self.nextmsec <= now or force) and self.tick > 0 then
if (self.maxtimes > 0 and self.nextmsec <= now) or force then
self.nextmsec = now + self.tick --如果callback脚本报错,会悲剧,WHJ,似乎没人用,先提前试试
self.maxtimes = self.maxtimes - 1 --计数可以提前,时间不能提前,有可能逻辑里要用时间,提前的目的是防止Check报错后就悲剧
self.callback(unpack(self.params))
return true
end
return false
end
function UniEventClass:Stop()
unitimer.removeevent(self)
end
unitimer={
timermap={},
eventmap={},
}
function unitimer.init(msec) --最小精度的定时器
unitimer.now = go.time.Msec()
if unitimer.ticktimer ~= nil then
unilight.error("unitimer.init已经初始化过了:"..unitimer.tickmsec)
return false
end
unitimer.tickmsec = msec --保存最小精度
unitimer.ticktimer = unilight.addtimermsec("unitimer.loop", msec)
return true
end
function unitimer.loop()
local timer = unitimer
timer.now = go.time.Msec()
for k,v in pairs(timer.timermap) do
if v:Check(timer.now) == true then
if v.stop == true then
timer.removetimer(v)
end
end
end
for k,v in pairs(timer.eventmap) do
if v:Check(timer.now) == true then
if v.maxtimes <= 0 then
--v:Debug("事件结束")
v:Stop()
end
end
end
end
function unitimer.addtimermsec(callback, msec, ...)
local timer = NewUniTimerClass(callback, msec, ...)
--timer:Debug("unitimer.addtimermsec:")
unitimer.timermap[timer]=timer
return timer
end
function unitimer.addtimer(callback, msec, ...)
return unitimer.addtimermsec(callback, msec*1000, ...)
end
function unitimer.removetimer(timer)
--timer:Debug("unitimer.removetimer:")
unitimer.timermap[timer] = nil
end
function unitimer.addevent(callback, msec,maxtimes, ...)
return unitimer.addeventmsec(callback, msec*1000,maxtimes, ...)
end
function unitimer.addeventmsec(callback, msec,maxtimes, ...)
maxtime = maxtimes or 1
local event = NewUniEventClass(callback, msec,maxtimes, ...)
--event:Debug("设置事件:"..msec)
unitimer.eventmap[event]=event
return event
end
function unitimer.removeevent(event)
unitimer.eventmap[event] = nil
end

+ 118
- 0
luaScript/utf8.lua 查看文件

@ -0,0 +1,118 @@
local pattern = '[%z\1-\127\194-\244][\128-\191]*'
-- helper function
local posrelat =
function (pos, len)
if pos < 0 then
pos = len + pos + 1
end
return pos
end
utf8 = {}
-- maps f over s's utf8 characters f can accept args: (visual_index, utf8_character, byte_index)
utf8.map =
function (s, f, no_subs)
local i = 0
if no_subs then
for b, e in s:gmatch('()' .. pattern .. '()') do
i = i + 1
local c = e - b
f(i, c, b)
end
else
for b, c in s:gmatch('()(' .. pattern .. ')') do
i = i + 1
f(i, c, b)
end
end
end
-- generator for the above -- to iterate over all utf8 chars
utf8.chars =
function (s, no_subs)
return coroutine.wrap(function () return utf8.map(s, coroutine.yield, no_subs) end)
end
-- returns the number of characters in a UTF-8 string
utf8.len =
function (s)
-- count the number of non-continuing bytes
return select(2, s:gsub('[^\128-\193]', ''))
end
utf8.GetMaxLenString =
function (s, maxlen, symbol)
-- s:待裁剪字符串,maxlen:最大长度,symbol:裁剪后补全符号
symbol = symbol or ""
local len = utf8.len(s)
local dstString = s
-- 超长,裁剪,加symbol
if len > maxlen then
dstString = utf8.sub(s, 1, maxlen)
dstString = dstString..symbol
end
return dstString
end
-- replace all utf8 chars with mapping
utf8.replace =
function (s, map)
return s:gsub(pattern, map)
end
-- reverse a utf8 string
utf8.reverse =
function (s)
-- reverse the individual greater-than-single-byte characters
s = s:gsub(pattern, function (c) return #c > 1 and c:reverse() end)
return s:reverse()
end
-- strip non-ascii characters from a utf8 string
utf8.strip =
function (s)
return s:gsub(pattern, function (c) return #c > 1 and '' end)
end
-- like string.sub() but i, j are utf8 strings
-- a utf8-safe string.sub()
utf8.sub =
function (s, i, j)
local l = utf8.len(s)
i = posrelat(i, l)
j = j and posrelat(j, l) or l
if i < 1 then i = 1 end
if j > l then j = l end
if i > j then return '' end
local diff = j - i
local iter = utf8.chars(s, true)
-- advance up to i
for _ = 1, i - 1 do iter() end
local c, b = select(2, iter())
-- i and j are the same, single-charaacter sub
if diff == 0 then
return string.sub(s, b, b + c - 1)
end
i = b
-- advance up to j
for _ = 1, diff - 1 do iter() end
c, b = select(2, iter())
return string.sub(s, i, b + c - 1)
end

+ 76
- 0
luaStatePool.go 查看文件

@ -0,0 +1,76 @@
package luaInGo
import (
lua "github.com/yuin/gopher-lua"
"strings"
"sync"
)
type lStatePool struct {
m sync.Mutex
saved []*lua.LState
}
// Get 从池中取出一个LState,若池中没有,则新增一个
func (pl *lStatePool) Get() *lua.LState {
pl.m.Lock()
defer pl.m.Unlock()
n := len(pl.saved)
if n == 0 {
return pl.New()
}
x := pl.saved[n-1]
pl.saved = pl.saved[0 : n-1]
return x
}
// Put 用完LState后放回池中
func (pl *lStatePool) Put(L *lua.LState) {
pl.m.Lock()
defer pl.m.Unlock()
if len(pl.saved) > NaxPoolSize {
L.Close()
} else {
// 放回的时候 清理一下 堆栈 确认数据正常
L.SetTop(0)
pl.saved = append(pl.saved, L)
}
}
func (pl *lStatePool) ShutDown() {
for _, L := range pl.saved {
L.Close()
}
}
func (pl *lStatePool) New() *lua.LState {
L := lua.NewState()
//提供全局函数给lua
PreLoadGo(L)
//加载go提供元表给lua
// golua.RegisterPersonType(L)
// 添加lua脚本自动搜索路径
// Tamper package.path according to configuration...
t := L.GetGlobal("package").(*lua.LTable)
// Get "path" from package table
lPath := lua.LString("path")
s := L.RawGet(t, lPath).(lua.LString).String()
// Create list of elements to join for new package path
elems := []string{s}
elems = append(elems, "./luaScript/?.lua")
// Set new package.path
L.RawSet(t, lPath, lua.LString(strings.Join(elems, ";")))
//加载lua脚本 仅仅加载入口函数模块的lua
if err := L.DoFile("./luaScript/main.lua"); err != nil {
println("load the main lua files error")
panic(err)
}
return L
}

+ 21
- 0
preLoadGo.go 查看文件

@ -0,0 +1,21 @@
package luaInGo
import (
lua "github.com/yuin/gopher-lua"
"luaInGo/goApis"
"luaInGo/goApis/crypto"
"luaInGo/goApis/json"
"luaInGo/goApis/strings"
"luaInGo/goApis/time"
)
// 这里封装一个函数 统一load go中提供给lua调用的函数
func PreLoadGo(L *lua.LState) {
// 这里再调用一些子模块的LoadGo()函数
time.PreLoadGo(L)
strings.PreLoadGo(L)
crypto.PreLoadGo(L)
json.PreloadGo(L)
goApis.PreLoadLibs(L)
}

Loading…
取消
儲存