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  }