2
2
mirror of https://github.com/Hilbis/Hilbish synced 2025-06-20 19:32:04 +00:00
Hilbish/timerhandler.go
TorchedSammy c95ff42dee
feat: add timer pool and api (closes #135)
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.
2022-04-12 19:31:48 -04:00

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
}