Files
aego/script/bind/handle.go
T
sanspie 0fbf22a090 Stage 9.4a: curves, tween, timers
core/curve with presets, keys, wraps; KindCurve in schema, scenes, prefabs and the inspector curve editor.
modules/tween: tweens and timers in per-world pools, game and unscaled domains, script field targets via contracts/scriptfields.
Host handle types (abi.Handle, bind.Handle, manifest v5), yield on awaitable handles via contracts/scriptwait.
Script modules aego/curve, aego/tween, aego/timer; platformer enemy uses a cooldown and a fade-out tween.
Docs: tween.md, curves.md, language reference; golden for the curve editor.
2026-10-18 21:32:39 +03:00

51 lines
1.2 KiB
Go

package bind
import (
"fmt"
"reflect"
"aego/script/abi"
"aego/script/vm"
)
func Handle[T any](m *Module, name string, await bool, of func(uint64) T, key func(T) uint64, opts ...Option) {
rt := reflect.TypeFor[T]()
switch {
case m.method || m.comp != "" || m.handle != "":
m.valid(name, fmt.Errorf("handle types cannot live in a method module"))
return
case of == nil || key == nil:
m.valid(name, fmt.Errorf("handle type needs its key conversions"))
return
}
if _, dup := m.reg.handles[rt]; dup {
//lint:ignore ST1005 "Go" is a proper noun
m.valid(name, fmt.Errorf("Go type %s is already a script handle", rt))
return
}
q := m.path + "." + name
if !m.valid(name, m.reg.table.AddHandle(abi.HandleDef{Name: q, Await: await})) {
return
}
id := abi.HandleID(q)
m.reg.handles[rt] = codec[T]{
ref: abi.HandleOf(q),
slots: 1,
get: func(_ *vm.Machine, w []vm.Value) T {
if w[0].B != id {
var zero T
return zero
}
return of(w[0].A)
},
put: func(_ *vm.Machine, w []vm.Value, v T) {
if k := key(v); k != 0 {
w[0] = vm.Value{A: k, B: id}
return
}
w[0] = vm.Value{}
},
}
m.valid(name, m.reg.describe(m.path, name, opts, -1))
}