Files
aego/modules/input/keyframe.go
T

115 lines
2.6 KiB
Go

package input
import (
"unsafe"
"aego/core/rewind"
raw "aego/platform/input"
)
var _ rewind.Keyframer = (*Service)(nil)
type inputKey struct {
states []state
stack []int
order []int
inj []injection
devs [MaxPlayers]uint8
device [MaxPlayers]int8
padsOn [raw.MaxPads]bool
rebind rebind
clock Clock
frame uint64
next int
changed bool
fixed bool
}
func (k *inputKey) Size() int {
return int(unsafe.Sizeof(*k)) + len(k.states)*int(unsafe.Sizeof(state{})) + 8*(len(k.stack)+len(k.order)) +
len(k.inj)*int(unsafe.Sizeof(injection{}))
}
func (s *Service) Capture(reuse rewind.Key) rewind.Key {
k, _ := reuse.(*inputKey)
if k == nil {
k = &inputKey{}
}
k.states = append(k.states[:0], s.states...)
k.stack = append(k.stack[:0], s.stack...)
k.order = append(k.order[:0], s.order...)
k.inj = append(k.inj[:0], s.inj...)
k.devs, k.device, k.padsOn = s.devs, s.device, s.padsOn
k.rebind, k.clock, k.frame = s.rebind, s.clock, s.frame
k.changed, k.fixed = s.changed, s.fixed
k.next = 0
if s.play != nil {
k.next = s.play.next
}
return k
}
func (s *Service) Restore(key rewind.Key) {
k := key.(*inputKey)
s.states = append(s.states[:0], k.states...)
s.stack = append(s.stack[:0], k.stack...)
s.order = append(s.order[:0], k.order...)
s.inj = append(s.inj[:0], k.inj...)
s.devs, s.device, s.padsOn = k.devs, k.device, k.padsOn
s.rebind, s.clock, s.frame = k.rebind, k.clock, k.frame
s.changed, s.fixed = k.changed, k.fixed
s.rec = nil
if s.play != nil {
s.play.next = k.next
}
}
func hashVec(h *rewind.Hasher, x, y float32) {
h.F32(x)
h.F32(y)
}
func (s *Service) Hash(h *rewind.Hasher) {
h.String("input")
h.Int(len(s.states))
for i := range s.states {
st := &s.states[i]
hashVec(h, st.value.X, st.value.Y)
hashVec(h, st.fValue.X, st.fValue.Y)
hashVec(h, st.injVal.X, st.injVal.Y)
for _, b := range [...]bool{st.down, st.pressed, st.released, st.fDown, st.fPressed, st.fReleased, st.consumed, st.fConsumed,
st.active, st.release, st.rawPrev, st.latch, st.bufLive, st.inj} {
h.Bool(b)
}
h.U32(uint32(st.pend[0]) | uint32(st.pend[1])<<8 | uint32(st.npend)<<16)
h.I64(int64(st.blockedBy))
h.I64(int64(st.via))
h.I64(int64(st.why))
h.U64(st.visit)
h.F64(st.heldFor)
h.F64(st.pressAt)
h.F64(st.bufAt)
}
h.Int(len(s.stack))
for _, c := range s.stack {
h.Int(c)
}
for p := range s.devs {
h.U32(uint32(s.devs[p]))
h.I64(int64(s.device[p]))
}
for _, on := range s.padsOn {
h.Bool(on)
}
h.Int(len(s.inj))
for _, x := range s.inj {
h.U64(x.tick)
h.Int(x.player)
h.Int(x.action)
hashVec(h, x.value.X, x.value.Y)
}
h.U64(s.frame)
h.Bool(s.changed)
h.Bool(s.fixed)
}