github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/physicscompress/physics/state.go (about) 1 package physics 2 3 import ( 4 "encoding/gob" 5 "io" 6 7 "github.com/egonelbre/exp/bit" 8 ) 9 10 const HistorySize = 16 11 12 type State struct { 13 History [HistorySize]*Frame 14 FrameIndex int 15 } 16 17 type Frame struct { 18 Cubes []Cube 19 } 20 21 type Cube struct { 22 Largest int32 23 A, B, C int32 24 X, Y, Z int32 25 Interacting int32 26 } 27 28 func NewFrame(size int) *Frame { return &Frame{make([]Cube, size)} } 29 30 func (frame *Frame) Assign(other *Frame) { 31 frame.Cubes = append([]Cube{}, other.Cubes...) 32 } 33 34 func (frame *Frame) ReadFrom(r io.Reader) error { 35 for i := range frame.Cubes { 36 if err := frame.Cubes[i].ReadFrom(r); err != nil { 37 return err 38 } 39 } 40 return nil 41 } 42 43 func (frame *Frame) WriteTo(w io.Writer) error { 44 for i := range frame.Cubes { 45 if err := frame.Cubes[i].WriteTo(w); err != nil { 46 return err 47 } 48 } 49 return nil 50 } 51 52 func (a *Frame) Equals(b *Frame) bool { 53 if len(a.Cubes) != len(b.Cubes) { 54 return false 55 } 56 for i, ax := range a.Cubes { 57 if ax != b.Cubes[i] { 58 return false 59 } 60 } 61 return true 62 } 63 64 // Cube utilities 65 func (cube *Cube) ReadFrom(r io.Reader) error { 66 return bit.Read(r, 67 &cube.Largest, 68 &cube.A, &cube.B, &cube.C, 69 &cube.X, &cube.Y, &cube.Z, 70 &cube.Interacting, 71 ) 72 } 73 74 func (cube *Cube) WriteTo(w io.Writer) error { 75 return bit.Write(w, 76 &cube.Largest, 77 &cube.A, &cube.B, &cube.C, 78 &cube.X, &cube.Y, &cube.Z, 79 &cube.Interacting, 80 ) 81 } 82 83 func NewState(size int) *State { 84 s := &State{} 85 for i := range s.History { 86 s.History[i] = NewFrame(size) 87 } 88 s.FrameIndex = -1 89 return s 90 } 91 92 func (s *State) IncFrame() { 93 s.FrameIndex += 1 94 } 95 96 func (s *State) ReadNext(r io.Reader) error { 97 s.FrameIndex += 1 98 return s.Current().ReadFrom(r) 99 } 100 101 func (s *State) Current() *Frame { return s.Prev(0) } 102 func (s *State) Baseline() *Frame { return s.Prev(6) } 103 func (s *State) Historic() *Frame { return s.Prev(8) } 104 105 func (s *State) Prev(i int) *Frame { 106 return s.History[(s.FrameIndex-i+HistorySize)%HistorySize] 107 } 108 109 func init() { 110 gob.Register([]Cube{}) 111 }