Repository: mlange-42/arche
Pull request #40 (2023-02-08 23:15:03)

Release v0.2.0
* Update changelog
* Update readme
* Make `bitMask` not exported


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63a7ee1..e4a5cdf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
 # Changelog
 
-## [[unpublished]](https://github.com/mlange-42/arche/compare/v0.1.4...main)
+## [[unpublished]](https://github.com/mlange-42/arche/compare/v0.2.0...main)
+
+Nothing
+
+## [[v0.2.0]](https://github.com/mlange-42/arche/compare/v0.1.4...v0.2.0)
 
 ### Features
 
diff --git a/README.md b/README.md
index 7f20fbe..8bd0b0b 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ go get github.com/mlange-42/arche
 * Fast random access for components of arbitrary entities. Useful for hierarchies.
 * No systems. Use your own structure.
 * Not thread-safe. On purpose.
+* No dependencies (except for testing and benchmarks).
 
 ## Usage example
 
diff --git a/ecs/archetype.go b/ecs/archetype.go
index 6147cba..c83395e 100644
--- a/ecs/archetype.go
+++ b/ecs/archetype.go
@@ -7,7 +7,7 @@ import (
 
 // archetype represents an ECS archetype
 type archetype struct {
-	mask Mask
+	mask bitMask
 	ids  []ID
 	// Indirection to avoid a fixed-size array of storages
 	// Increases access time by 50-100%
@@ -19,7 +19,7 @@ type archetype struct {
 var entityType = reflect.TypeOf(Entity{})
 
 func (a *archetype) init(capacityIncrement int, components ...componentType) {
-	var mask Mask
+	var mask bitMask
 	a.ids = make([]ID, len(components))
 	comps := make([]storage, len(components))
 
diff --git a/ecs/bitmask.go b/ecs/bitmask.go
index 31bfaf6..abf8da8 100644
--- a/ecs/bitmask.go
+++ b/ecs/bitmask.go
@@ -1,7 +1,7 @@
 package ecs
 
-// Mask is a bitmask.
-type Mask uint64
+// bitMask is a bitmask.
+type bitMask uint64
 
 // MaskTotalBits is the size of Mask in bits.
 //
@@ -10,13 +10,13 @@ const MaskTotalBits = 64
 
 var nibbleToBitsSet = [16]uint{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}
 
-// NewMask creates a new bitmask from a list of IDs.
+// newMask creates a new bitmask from a list of IDs.
 //
 // If any ID is bigger or equal [MaskTotalBits], it'll not be added to the mask.
 //
 // Implementation taken from https://github.com/marioolofo/go-gameengine-ecs.
-func NewMask(ids ...ID) Mask {
-	var mask Mask
+func newMask(ids ...ID) bitMask {
+	var mask bitMask
 	for _, id := range ids {
 		mask.Set(id, true)
 	}
@@ -26,34 +26,34 @@ func NewMask(ids ...ID) Mask {
 // Get reports if bit index defined by ID is true or false.
 //
 // The return will be always false for bit >= [MaskTotalBits].
-func (e Mask) Get(bit ID) bool {
-	mask := Mask(1 << bit)
+func (e bitMask) Get(bit ID) bool {
+	mask := bitMask(1 << bit)
 	return e&mask == mask
 }
 
 // Set sets the state of bit index to true or false.
 //
 // This function has no effect for bit >= [MaskTotalBits].
-func (e *Mask) Set(bit ID, value bool) {
+func (e *bitMask) Set(bit ID, value bool) {
 	if value {
-		*e |= Mask(1 << bit)
+		*e |= bitMask(1 << bit)
 	} else {
-		*e &= Mask(^(1 << bit))
+		*e &= bitMask(^(1 << bit))
 	}
 }
 
 // Reset changes the state of all bits to false.
-func (e *Mask) Reset() {
+func (e *bitMask) Reset() {
 	*e = 0
 }
 
 // Contains reports if other mask is a subset of this mask.
-func (e Mask) Contains(other Mask) bool {
+func (e bitMask) Contains(other bitMask) bool {
 	return e&other == other
 }
 
 // TotalBitsSet returns how many bits are set in this mask.
-func (e Mask) TotalBitsSet() uint {
+func (e bitMask) TotalBitsSet() uint {
 	var count uint
 
 	for e != 0 {
diff --git a/ecs/paged.go b/ecs/paged.go
index 5104e40..648fbb6 100644
--- a/ecs/paged.go
+++ b/ecs/paged.go
@@ -2,14 +2,14 @@ package ecs
 
 const fixedPageSize = 32
 
-// PagedArr32 is a paged collection working with pages of length 32 arrays
-type PagedArr32[T any] struct {
+// pagedArr32 is a paged collection working with pages of length 32 arrays
+type pagedArr32[T any] struct {
 	pages   [][fixedPageSize]T
 	len     int
 	lenLast int
 }
 
-func (p *PagedArr32[T]) Add(value T) {
+func (p *pagedArr32[T]) Add(value T) {
 	if len(p.pages) == 0 || p.lenLast == fixedPageSize {
 		p.pages = append(p.pages, [fixedPageSize]T{})
 		p.lenLast = 0
@@ -19,10 +19,10 @@ func (p *PagedArr32[T]) Add(value T) {
 	p.lenLast++
 }
 
-func (p *PagedArr32[T]) Get(index int) *T {
+func (p *pagedArr32[T]) Get(index int) *T {
 	return &p.pages[index/fixedPageSize][index%fixedPageSize]
 }
 
-func (p *PagedArr32[T]) Len() int {
+func (p *pagedArr32[T]) Len() int {
 	return p.len
 }
diff --git a/ecs/query.go b/ecs/query.go
index 03c970d..7959ad4 100644
--- a/ecs/query.go
+++ b/ecs/query.go
@@ -17,7 +17,7 @@ import (
 //	}
 type Query struct {
 	world     *World
-	mask      Mask
+	mask      bitMask
 	archetype archetypeIter
 	index     int
 	done      bool
@@ -25,7 +25,7 @@ type Query struct {
 }
 
 // newQuery creates a new Query
-func newQuery(world *World, mask Mask, lockBit uint8) Query {
+func newQuery(world *World, mask bitMask, lockBit uint8) Query {
 	return Query{
 		world:   world,
 		mask:    mask,
diff --git a/ecs/types.go b/ecs/types.go
index 83e2bb1..fb5fab1 100644
--- a/ecs/types.go
+++ b/ecs/types.go
@@ -5,7 +5,7 @@ import (
 	"unsafe"
 )
 
-// ID defines the format for the components identifier
+// ID is the component identifier type
 type ID uint32
 
 // Component is a Component ID/Component pointer pair
diff --git a/ecs/world.go b/ecs/world.go
index c5df03e..b9ddc3a 100644
--- a/ecs/world.go
+++ b/ecs/world.go
@@ -20,7 +20,7 @@ func NewWorld() World {
 func FromConfig(conf Config) World {
 	arch := archetype{}
 	arch.init(conf.CapacityIncrement)
-	arches := PagedArr32[archetype]{}
+	arches := pagedArr32[archetype]{}
 	arches.Add(arch)
 	return World{
 		config:     conf,
@@ -29,7 +29,7 @@ func FromConfig(conf Config) World {
 		bitPool:    newBitPool(),
 		registry:   newComponentRegistry(),
 		archetypes: arches,
-		locks:      Mask(0),
+		locks:      bitMask(0),
 	}
 }
 
@@ -37,11 +37,11 @@ func FromConfig(conf Config) World {
 type World struct {
 	config     Config
 	entities   []entityIndex
-	archetypes PagedArr32[archetype]
+	archetypes pagedArr32[archetype]
 	entityPool entityPool
 	bitPool    bitPool
 	registry   componentRegistry
-	locks      Mask
+	locks      bitMask
 }
 
 // NewEntity returns a new or recycled [Entity].
@@ -231,14 +231,14 @@ func (w *World) copyTo(entity Entity, id ID, comp interface{}) unsafe.Pointer {
 	return arch.Set(index.index, id, comp)
 }
 
-func (w *World) findOrCreateArchetype(mask Mask) *archetype {
+func (w *World) findOrCreateArchetype(mask bitMask) *archetype {
 	if arch, ok := w.findArchetype(mask); ok {
 		return arch
 	}
 	return w.createArchetype(mask)
 }
 
-func (w *World) findArchetype(mask Mask) (*archetype, bool) {
+func (w *World) findArchetype(mask bitMask) (*archetype, bool) {
 	length := w.archetypes.Len()
 	for i := 0; i < length; i++ {
 		arch := w.archetypes.Get(i)
@@ -249,7 +249,7 @@ func (w *World) findArchetype(mask Mask) (*archetype, bool) {
 	return nil, false
 }
 
-func (w *World) createArchetype(mask Mask) *archetype {
+func (w *World) createArchetype(mask bitMask) *archetype {
 	count := int(mask.TotalBitsSet())
 	types := make([]componentType, count)
 
@@ -277,7 +277,7 @@ func (w *World) componentID(tp reflect.Type) ID {
 	return w.registry.ComponentID(tp)
 }
 
-func (w *World) nextArchetype(mask Mask, index int) (int, archetypeIter, bool) {
+func (w *World) nextArchetype(mask bitMask, index int) (int, archetypeIter, bool) {
 	len := w.archetypes.Len()
 	if index >= len {
 		panic("exceeded end of query")
@@ -295,7 +295,7 @@ func (w *World) nextArchetype(mask Mask, index int) (int, archetypeIter, bool) {
 //
 // Locks the world to prevent changes to component compositions.
 func (w *World) Query(comps ...ID) Query {
-	mask := NewMask(comps...)
+	mask := newMask(comps...)
 	lock := w.bitPool.Get()
 	w.locks.Set(ID(lock), true)
 	return newQuery(w, mask, lock)


Test patch:
diff --git a/ecs/bitmask_test.go b/ecs/bitmask_test.go
index 042321d..dba25b6 100644
--- a/ecs/bitmask_test.go
+++ b/ecs/bitmask_test.go
@@ -7,7 +7,7 @@ import (
 )
 
 func TestBitMask(t *testing.T) {
-	mask := NewMask(ID(1), ID(2), ID(13), ID(27))
+	mask := newMask(ID(1), ID(2), ID(13), ID(27))
 
 	assert.Equal(t, uint(4), mask.TotalBitsSet())
 
@@ -25,8 +25,8 @@ func TestBitMask(t *testing.T) {
 	assert.True(t, mask.Get(0))
 	assert.False(t, mask.Get(1))
 
-	other1 := NewMask(ID(1), ID(2), ID(32))
-	other2 := NewMask(ID(0), ID(2))
+	other1 := newMask(ID(1), ID(2), ID(32))
+	other2 := newMask(ID(0), ID(2))
 
 	assert.False(t, mask.Contains(other1))
 	assert.True(t, mask.Contains(other2))
diff --git a/ecs/paged_test.go b/ecs/paged_test.go
index 1526554..aa45244 100644
--- a/ecs/paged_test.go
+++ b/ecs/paged_test.go
@@ -7,7 +7,7 @@ import (
 )
 
 func TestPagedArr32(t *testing.T) {
-	a := PagedArr32[int]{}
+	a := pagedArr32[int]{}
 
 	for i := 0; i < 66; i++ {
 		a.Add(i)
diff --git a/ecs/world_test.go b/ecs/world_test.go
index 5539a1a..7d052e2 100644
--- a/ecs/world_test.go
+++ b/ecs/world_test.go
@@ -61,10 +61,10 @@ func TestWorldComponents(t *testing.T) {
 
 	w.Remove(e2, posID)
 
-	maskNone := NewMask()
-	maskPos := NewMask(posID)
-	maskRot := NewMask(rotID)
-	maskPosRot := NewMask(posID, rotID)
+	maskNone := newMask()
+	maskPos := newMask(posID)
+	maskRot := newMask(rotID)
+	maskPosRot := newMask(posID, rotID)
 
 	archNone, ok := w.findArchetype(maskNone)
 	assert.True(t, ok)
@@ -283,7 +283,7 @@ func TestRegisterComponents(t *testing.T) {
 
 func TestTypeSizes(t *testing.T) {
 	printTypeSize[World]()
-	printTypeSizeName[PagedArr32[archetype]]("PagedArr32")
+	printTypeSizeName[pagedArr32[archetype]]("PagedArr32")
 	printTypeSize[archetype]()
 	printTypeSize[storage]()
 	printTypeSize[Query]()