• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark / 13604663297

01 Mar 2025 12:16PM CUT coverage: 94.752% (-2.3%) from 97.025%
13604663297

Pull #83

github

web-flow
Merge ca5080db9 into 3013a616a
Pull Request #83: Add functionality required for (de)-serialization

19 of 112 new or added lines in 4 files covered. (16.96%)

3737 of 3944 relevant lines covered (94.75%)

47657.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.47
/ecs/world.go
1
package ecs
2

3
import "unsafe"
4

5
// World is the central type holding entity and component data, as well as resources.
6
type World struct {
7
        storage   storage
8
        resources Resources
9
        locks     lock
10
}
11

12
// NewWorld creates a new [World].
13
func NewWorld(initialCapacity uint32) World {
110✔
14
        return World{
110✔
15
                storage:   newStorage(initialCapacity),
110✔
16
                resources: newResources(),
110✔
17
                locks:     lock{},
110✔
18
        }
110✔
19
}
110✔
20

21
// NewEntity creates a new [Entity].
22
func (w *World) NewEntity() Entity {
321✔
23
        w.checkLocked()
321✔
24

321✔
25
        entity, _ := w.storage.createEntity(0)
321✔
26
        return entity
321✔
27
}
321✔
28

29
// Alive return whether the given entity is alive.
30
func (w *World) Alive(entity Entity) bool {
506,856✔
31
        return w.storage.entityPool.Alive(entity)
506,856✔
32
}
506,856✔
33

34
// RemoveEntity removes the given entity from the world.
35
func (w *World) RemoveEntity(entity Entity) {
503,834✔
36
        w.checkLocked()
503,834✔
37
        w.storage.RemoveEntity(entity)
503,834✔
38
}
503,834✔
39

40
// IsLocked returns whether the world is locked by any queries.
41
func (w *World) IsLocked() bool {
1,010,935✔
42
        return w.locks.IsLocked()
1,010,935✔
43
}
1,010,935✔
44

45
// Resources of the world.
46
//
47
// Resources are component-like data that is not associated to an entity, but unique to the world.
48
func (w *World) Resources() *Resources {
12✔
49
        return &w.resources
12✔
50
}
12✔
51

52
// Unsafe provides access to Ark's unsafe, ID-based API.
53
func (w *World) Unsafe() Unsafe {
9✔
54
        return Unsafe{
9✔
55
                world: w,
9✔
56
        }
9✔
57
}
9✔
58

59
// DumpEntities dumps entity information into an [EntityDump] object.
60
// This dump can be used with [World.LoadEntities] to set the World's entity state.
61
//
62
// For world serialization with components and resources, see module [github.com/mlange-42/arche-serde].
NEW
63
func (w *World) DumpEntities() EntityDump {
×
NEW
64
        u := w.Unsafe()
×
NEW
65
        alive := []uint32{}
×
NEW
66

×
NEW
67
        filter := NewFilter()
×
NEW
68
        query := u.Query(filter)
×
NEW
69
        for query.Next() {
×
NEW
70
                alive = append(alive, uint32(query.Entity().id))
×
NEW
71
        }
×
72

NEW
73
        data := EntityDump{
×
NEW
74
                Entities:  append([]Entity{}, w.storage.entityPool.entities...),
×
NEW
75
                Alive:     alive,
×
NEW
76
                Next:      uint32(w.storage.entityPool.next),
×
NEW
77
                Available: w.storage.entityPool.available,
×
NEW
78
        }
×
NEW
79

×
NEW
80
        return data
×
81
}
82

83
// LoadEntities resets all entities to the state saved with [World.DumpEntities].
84
//
85
// Use this only on an empty world! Can be used after [World.Reset].
86
//
87
// The resulting world will have the same entities (in terms of ID, generation and alive state)
88
// as the original world. This is necessary for proper serialization of entity relations.
89
// However, the entities will not have any components.
90
//
91
// Panics if the world has any dead or alive entities.
92
//
93
// For world serialization with components and resources, see module [github.com/mlange-42/arche-serde].
NEW
94
func (w *World) LoadEntities(data *EntityDump) {
×
NEW
95
        w.checkLocked()
×
NEW
96

×
NEW
97
        if len(w.storage.entityPool.entities) > 2 || w.storage.entityPool.available > 0 {
×
NEW
98
                panic("can set entity data only on a fresh or reset world")
×
99
        }
100

NEW
101
        capacity := len(data.Entities)
×
NEW
102

×
NEW
103
        entities := make([]Entity, 0, capacity)
×
NEW
104
        entities = append(entities, data.Entities...)
×
NEW
105

×
NEW
106
        w.storage.entityPool.entities = entities
×
NEW
107
        w.storage.entityPool.next = entityID(data.Next)
×
NEW
108
        w.storage.entityPool.available = data.Available
×
NEW
109
        w.storage.entityPool.pointer = unsafe.Pointer(&w.storage.entityPool.entities[0])
×
NEW
110
        w.storage.entityPool.reserved = entityID(reservedEntities)
×
NEW
111

×
NEW
112
        w.storage.entities = make([]entityIndex, len(data.Entities), capacity)
×
NEW
113
        w.storage.isTarget = make([]bool, 0, capacity)
×
NEW
114

×
NEW
115
        table := w.storage.tables[0]
×
NEW
116
        for _, idx := range data.Alive {
×
NEW
117
                entity := w.storage.entityPool.entities[idx]
×
NEW
118
                tableIdx := table.Add(entity)
×
NEW
119
                w.storage.entities[entity.id] = entityIndex{table: table.id, row: tableIdx}
×
NEW
120
        }
×
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc