mirror of
https://github.com/Hilbis/Hilbish
synced 2025-06-20 19:32:04 +00:00
adds a map (but lets call it a pool) of all running timers. this makes us able to keep track of all running intervals and timeouts. it also means hilbish can wait for them to be done before exiting (it only waits when non interactive). this introduces the `hilbish.timers` interface, documented by `doc timers`. the `hilbish.interval` and `hilbish.timeout` functions return a timer object now.
103 lines
1.8 KiB
Go
103 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"hilbish/util"
|
|
|
|
rt "github.com/arnodel/golua/runtime"
|
|
)
|
|
|
|
var timers *timerHandler
|
|
type timerHandler struct {
|
|
mu *sync.RWMutex
|
|
timers map[int]*timer
|
|
latestID int
|
|
running int
|
|
}
|
|
|
|
func newTimerHandler() *timerHandler {
|
|
return &timerHandler{
|
|
timers: make(map[int]*timer),
|
|
latestID: 0,
|
|
mu: &sync.RWMutex{},
|
|
}
|
|
}
|
|
|
|
func (th *timerHandler) create(typ timerType, dur time.Duration, fun *rt.Closure) *timer {
|
|
th.mu.Lock()
|
|
defer th.mu.Unlock()
|
|
|
|
th.latestID++
|
|
t := &timer{
|
|
typ: typ,
|
|
fun: fun,
|
|
dur: dur,
|
|
channel: make(chan bool, 1),
|
|
th: th,
|
|
id: th.latestID,
|
|
}
|
|
th.timers[th.latestID] = t
|
|
|
|
return t
|
|
}
|
|
|
|
func (th *timerHandler) get(id int) *timer {
|
|
th.mu.RLock()
|
|
defer th.mu.RUnlock()
|
|
|
|
return th.timers[id]
|
|
}
|
|
|
|
func (th *timerHandler) luaCreate(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|
if err := c.CheckNArgs(3); err != nil {
|
|
return nil, err
|
|
}
|
|
timerTypInt, err := c.IntArg(0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ms, err := c.IntArg(1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cb, err := c.ClosureArg(2)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
timerTyp := timerType(timerTypInt)
|
|
tmr := th.create(timerTyp, time.Duration(ms) * time.Millisecond, cb)
|
|
return c.PushingNext1(t.Runtime, tmr.lua()), nil
|
|
}
|
|
|
|
func (th *timerHandler) luaGet(thr *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|
if err := c.Check1Arg(); err != nil {
|
|
return nil, err
|
|
}
|
|
id, err := c.IntArg(0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
t := th.get(int(id))
|
|
if t != nil {
|
|
return c.PushingNext1(thr.Runtime, t.lua()), nil
|
|
}
|
|
|
|
return c.Next(), nil
|
|
}
|
|
|
|
func (th *timerHandler) loader(rtm *rt.Runtime) *rt.Table {
|
|
thExports := map[string]util.LuaExport{
|
|
"create": {th.luaCreate, 3, false},
|
|
"get": {th.luaGet, 1, false},
|
|
}
|
|
|
|
luaTh := rt.NewTable()
|
|
util.SetExports(rtm, luaTh, thExports)
|
|
|
|
return luaTh
|
|
}
|