add unit test for paletteSection
This commit is contained in:
@ -50,6 +50,7 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
// If bpb values greater than or equal to 9, use directSection.
|
// If bpb values greater than or equal to 9, use directSection.
|
||||||
// Otherwise use paletteSection.
|
// Otherwise use paletteSection.
|
||||||
var palettes []BlockStatus
|
var palettes []BlockStatus
|
||||||
|
var palettesIndex map[BlockStatus]int
|
||||||
if bpb < 9 {
|
if bpb < 9 {
|
||||||
// read palettes
|
// read palettes
|
||||||
var length pk.VarInt
|
var length pk.VarInt
|
||||||
@ -57,12 +58,14 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
return nil, fmt.Errorf("read palettes length error: %w", err)
|
return nil, fmt.Errorf("read palettes length error: %w", err)
|
||||||
}
|
}
|
||||||
palettes = make([]BlockStatus, length)
|
palettes = make([]BlockStatus, length)
|
||||||
|
palettesIndex = make(map[BlockStatus]int, length)
|
||||||
for i := 0; i < int(length); i++ {
|
for i := 0; i < int(length); i++ {
|
||||||
var v pk.VarInt
|
var v pk.VarInt
|
||||||
if err := v.Decode(data); err != nil {
|
if err := v.Decode(data); err != nil {
|
||||||
return nil, fmt.Errorf("read palettes[%d] error: %w", i, err)
|
return nil, fmt.Errorf("read palettes[%d] error: %w", i, err)
|
||||||
}
|
}
|
||||||
palettes[i] = BlockStatus(v)
|
palettes[i] = BlockStatus(v)
|
||||||
|
palettesIndex[BlockStatus(v)] = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +74,9 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
if err := dataLen.Decode(data); err != nil {
|
if err := dataLen.Decode(data); err != nil {
|
||||||
return nil, fmt.Errorf("read data array length error: %w", err)
|
return nil, fmt.Errorf("read data array length error: %w", err)
|
||||||
}
|
}
|
||||||
|
if int(dataLen) < 16*16*16*int(bpb)/64 {
|
||||||
|
return nil, fmt.Errorf("data length (%d) is not enough of given bpb (%d)", dataLen, bpb)
|
||||||
|
}
|
||||||
dataArray := make([]uint64, dataLen)
|
dataArray := make([]uint64, dataLen)
|
||||||
for i := 0; i < int(dataLen); i++ {
|
for i := 0; i < int(dataLen); i++ {
|
||||||
var v pk.Long
|
var v pk.Long
|
||||||
@ -82,7 +88,11 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
|
|
||||||
sec := directSection{bpb: perBits(byte(bpb)), data: dataArray}
|
sec := directSection{bpb: perBits(byte(bpb)), data: dataArray}
|
||||||
if bpb < 9 {
|
if bpb < 9 {
|
||||||
return &paletteSection{palette: palettes, directSection: sec}, nil
|
return &paletteSection{
|
||||||
|
palette: palettes,
|
||||||
|
palettesIndex: palettesIndex,
|
||||||
|
directSection: sec,
|
||||||
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
return &sec, nil
|
return &sec, nil
|
||||||
}
|
}
|
||||||
@ -119,8 +129,24 @@ func (d *directSection) SetBlock(x, y, z int, s BlockStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *directSection) clone(bpb int) *directSection {
|
||||||
|
newSection := &directSection{
|
||||||
|
bpb: bpb,
|
||||||
|
data: make([]uint64, 16*16*16*bpb/64),
|
||||||
|
}
|
||||||
|
for x := 0; x < 16; x++ {
|
||||||
|
for y := 0; y < 16; y++ {
|
||||||
|
for z := 0; z < 16; z++ {
|
||||||
|
newSection.SetBlock(x, y, z, d.GetBlock(x, y, z))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newSection
|
||||||
|
}
|
||||||
|
|
||||||
type paletteSection struct {
|
type paletteSection struct {
|
||||||
palette []BlockStatus
|
palette []BlockStatus
|
||||||
|
palettesIndex map[BlockStatus]int
|
||||||
directSection
|
directSection
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,12 +156,12 @@ func (p *paletteSection) GetBlock(x, y, z int) BlockStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *paletteSection) SetBlock(x, y, z int, s BlockStatus) {
|
func (p *paletteSection) SetBlock(x, y, z int, s BlockStatus) {
|
||||||
for i := 0; i < len(p.palette); i++ {
|
if i, ok := p.palettesIndex[s]; ok {
|
||||||
if p.palette[i] == s {
|
p.directSection.SetBlock(x, y, z, BlockStatus(i))
|
||||||
p.directSection.SetBlock(x, y, z, BlockStatus(i))
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p.palette = append(p.palette, s) // TODO: Handle bpb overflow
|
i := len(p.palette)
|
||||||
p.directSection.SetBlock(x, y, z, BlockStatus(len(p.palette)+1))
|
p.palette = append(p.palette, s)
|
||||||
|
p.palettesIndex[s] = i
|
||||||
|
p.directSection.SetBlock(x, y, z, BlockStatus(i))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newDirectSection(bpb int) *directSection {
|
func newDirectSection(bpb int) Section {
|
||||||
return &directSection{
|
return &directSection{
|
||||||
bpb: bpb,
|
bpb: bpb,
|
||||||
data: make([]uint64, 16*16*16*bpb/64),
|
data: make([]uint64, 16*16*16*bpb/64),
|
||||||
@ -14,16 +14,26 @@ func newDirectSection(bpb int) *directSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectSection(t *testing.T) {
|
func TestDirectSection(t *testing.T) {
|
||||||
for bpb := 3; bpb <= data.BitsPerBlock; bpb++ {
|
for bpb := 4; bpb < data.BitsPerBlock; bpb++ {
|
||||||
s := newDirectSection(bpb)
|
testSection(t, newDirectSection(bpb), bpb)
|
||||||
for _, dataset := range [][16 * 16 * 16]BlockStatus{secData(bpb), randData(bpb)} {
|
}
|
||||||
for i := 0; i < 16*16*16; i++ {
|
}
|
||||||
s.SetBlock(i%16, i/16%16, i/16/16, dataset[i])
|
|
||||||
}
|
func TestPaletteSection(t *testing.T) {
|
||||||
for i := 0; i < 16*16*16; i++ {
|
testSection(t, &paletteSection{
|
||||||
if s := s.GetBlock(i%16, i/16%16, i/16/16); dataset[i] != s {
|
palettesIndex: make(map[BlockStatus]int),
|
||||||
t.Fatalf("direct section error: want: %v, get %v", dataset[i], s)
|
directSection: *(newDirectSection(7).(*directSection)),
|
||||||
}
|
}, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSection(t *testing.T, s Section, bpb int) {
|
||||||
|
for _, dataset := range [][16 * 16 * 16]BlockStatus{secData(bpb), randData(bpb)} {
|
||||||
|
for i := 0; i < 16*16*16; i++ {
|
||||||
|
s.SetBlock(i%16, i/16%16, i/16/16, dataset[i])
|
||||||
|
}
|
||||||
|
for i := 0; i < 16*16*16; i++ {
|
||||||
|
if s := s.GetBlock(i%16, i/16%16, i/16/16); dataset[i] != s {
|
||||||
|
t.Fatalf("direct section error: want: %v, get %v", dataset[i], s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user