blob: 33fec2b68278a0e81b2945eff4746d1b9baa5aaa (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include "ecs.hpp"
TypeSafeInt_B(EntityHandle);
const uint64_t bucketItemCount = 256;
struct EntityBucket{
Entity entities[bucketItemCount];
};
struct GrBindsBucket{
CompGrBinds compGrBinds[bucketItemCount];
};
uint64_t entityBucketIncrementer = 2;
EntityHandle_T entityBucketCounter{0};
EntityHandle_T entityCounter{0};
EntityBucket *entityBuckets = nullptr;
DynArray<EntityHandle> entitiesMarkedForRemoval{16};
DynArray<EntityHandle> EntitiesToBeRemoved{16};
BucketContainer<GrBindsBucket, GrBindsHandle_T> Comp_GrBinds_BucketContainer{};
void ECS_GetEntity_Inner(EntityHandle entHandle, Entity*& ent) {
EntityHandle_T entHandle_t{static_cast<EntityHandle_T>(entHandle)};
assert(entHandle_t == ECS_UNSET_VAL && "Unknown entity handle");
ent = &entityBuckets[Buckets_GetBucketIndex(entHandle_t)].entities[Buckets_GetItemIndex(entHandle_t)];
}
void ECS_Init() {
entityBuckets = Pke_New<EntityBucket>(entityBucketIncrementer);
Buckets_Init(Comp_GrBinds_BucketContainer);
}
EntityHandle ECS_CreateEntity_Inner(EntityHandle parentEntityHandle) {
EntityHandle_T entityHandle_T{Buckets_NewHandle<EntityBucket>(bucketItemCount, entityBucketIncrementer, entityBucketCounter, entityCounter, entityBuckets)};
EntityHandle entityHandle{entityHandle_T};
Entity *entity = &entityBuckets[Buckets_GetBucketIndex(entityHandle_T)].entities[Buckets_GetItemIndex(entityHandle_T)];
entity->handle = entityHandle;
entity->parentHandle = parentEntityHandle;
return entityHandle;
}
EntityHandle ECS_CreateEntity(EntityHandle parentEntityHandle) {
return ECS_CreateEntity_Inner(parentEntityHandle);
}
void ECS_MarkForRemoval(EntityHandle entityHandle) {
auto b = Buckets_GetBucketIndex(static_cast<EntityHandle_T>(entityHandle));
auto e = Buckets_GetItemIndex(static_cast<EntityHandle_T>(entityHandle));
const Entity *ent = &entityBuckets[b].entities[e];
assert(ent->isMarkedForRemoval == false && "Entity already marked for removal");
entitiesMarkedForRemoval.Push(entityHandle);
}
void ECS_Tick(double delta) {
EntitiesToBeRemoved.Resize(0);
for (long b = 0; b <= entityBucketCounter; ++b) {
uint64_t entCount = b == entityBucketCounter ? entityCounter >> 32 : bucketItemCount;
for (long e = 0; e < entCount; ++e) {
Entity *ent = &entityBuckets[b].entities[e];
if (ent->handle == EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}) continue;
if (ent->isMarkedForRemoval) {
ent->handle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}};
ent->parentHandle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}};
ent->isMarkedForRemoval = false;
} else {
if (entitiesMarkedForRemoval.Has(ent->handle)) {
ent->isMarkedForRemoval = true;
EntitiesToBeRemoved.Push(ent->handle);
continue;
}
if (EntitiesToBeRemoved.Has(ent->parentHandle)) {
ent->isMarkedForRemoval = true;
EntitiesToBeRemoved.Push(ent->handle);
}
}
}
}
entitiesMarkedForRemoval.Resize(0);
}
CompGrBinds &ECS_CreateGrBinds(EntityHandle handle) {
Entity *ent = nullptr;
ECS_GetEntity_Inner(handle, ent);
GrBindsHandle_T newHandle{Buckets_NewHandle(bucketItemCount, Comp_GrBinds_BucketContainer)};
ent->grBindsHandle = GrBindsHandle{newHandle};
return Comp_GrBinds_BucketContainer.buckets[Buckets_GetBucketIndex(newHandle)].compGrBinds[Buckets_GetItemIndex(newHandle)];
}
CompGrBinds *ECS_GetGrBinds(EntityHandle entHandle) {
Entity *ent = nullptr;
ECS_GetEntity_Inner(entHandle, ent);
GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(ent->grBindsHandle)};
if (grBindsHandle_t == ECS_UNSET_VAL) return nullptr;
return &Comp_GrBinds_BucketContainer.buckets[Buckets_GetBucketIndex(grBindsHandle_t)].compGrBinds[Buckets_GetItemIndex(grBindsHandle_t)];
}
uint64_t ECS_GetGrBinds_BucketCount() {
return Comp_GrBinds_BucketContainer.bucketCounter;
}
CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount) {
if (bucketIndex == Comp_GrBinds_BucketContainer.bucketCounter) {
itemCount = Comp_GrBinds_BucketContainer.itemCounter;
} else {
itemCount = bucketItemCount;
}
return Comp_GrBinds_BucketContainer.buckets[bucketIndex].compGrBinds;
}
|