-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathArchetype.cpp
132 lines (118 loc) · 3.55 KB
/
Archetype.cpp
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "Types.h"
#include "Archetype.h"
#include "ErrorHandling.h"
int NextArchID()
{
static int NextID = 1;
return NextID++;
}
Archetype::Archetype(): ID(NextArchID()), Signature({})
{
EntityIDStorage = new VectorStorage<EntityID>();
}
Archetype::Archetype(const ArchSignature& Base): ID(NextArchID())
{
EntityIDStorage = new VectorStorage<EntityID>();
for(const auto Type : Base)
{
Signature.emplace(Type);
CmpToStoreIndex.emplace(Type, CmpStorage.size());
CmpStorage.push_back(MakeStorageForID(Type));
}
}
Archetype::~Archetype()
{
delete EntityIDStorage;
for (auto Store : CmpStorage)
{
delete Store;
}
}
void Archetype::CopyEntity(const EntityID& Entity, const Archetype* Source, ComponentID AddedType, const void* AddedValue)
{
Trace("Copy Entity %d from %d to %d\n", Entity, Source == nullptr? -1 : Source->ID, this->ID);
if(this == Source)
{
Error("Tried to copy entity into same archetype\n");
}
auto FoundEntity = EntityToIndex.find(Entity);
if (FoundEntity != EntityToIndex.end())
{
Error("Attempt to add already present entity %d\n", Entity);
}
auto FoundNewType = CmpToStoreIndex.find(AddedType);
if(AddedType != 0 && FoundNewType == CmpToStoreIndex.end())
{
Error("Added type %d not present in destination\n", AddedType);
}
EntityToIndex.emplace(Entity, EntityIDStorage->GetSize());
EntityIDStorage->AddRawData(&Entity);
if(AddedType > 0)
{
CmpStorage[FoundNewType->second]->AddRawData(AddedValue);
}
for (auto Store : CmpStorage)
{
if(Store->GetTypeID() == AddedType) continue;
Store->AddRawData(Source->GetValue(Entity, Store->GetTypeID()));
}
}
void Archetype::FastDelete(const EntityID& ID)
{
Trace("Delete Entity %d from %d\n", ID, this->ID);
auto Found = EntityToIndex.find(ID);
if (Found == EntityToIndex.end())
{
Error("Failed to find entity to delete %d\n", ID);
}
const int Index = Found->second;
EntityToIndex.erase(ID);
EntityIDStorage->FastDelete(Index);
for (auto Store : CmpStorage)
{
Store->FastDelete(Index);
}
//we swapped the entity ID, so we need to update the index
if (Index != EntityIDStorage->GetSize())
{
EntityID MovedID = *static_cast<EntityID*>(EntityIDStorage->GetRawData(Index));
EntityToIndex[MovedID] = Index;
}
}
void Archetype::SetValue(const EntityID& ID, const ComponentID& CmpID, const void* Data)
{
auto FoundEntity = EntityToIndex.find(ID);
if (FoundEntity == EntityToIndex.end())
{
Error("Failed to find entity to set %d\n", ID);
}
auto FoundCmp = CmpToStoreIndex.find(CmpID);
if (FoundCmp == CmpToStoreIndex.end())
{
Error("Failed to find Component to set %d\n", CmpID);
}
CmpStorage[FoundCmp->second]->SetRawData(FoundEntity->second, Data);
}
void* Archetype::GetValue(const EntityID& ID, const ComponentID& CmpID) const
{
auto FoundEntity = EntityToIndex.find(ID);
if (FoundEntity == EntityToIndex.end())
{
Error("Failed to find entity to set %d\n", ID);
}
auto FoundCmp = CmpToStoreIndex.find(CmpID);
if (FoundCmp == CmpToStoreIndex.end())
{
Error("Failed to find Component to set %d\n", CmpID);
}
return CmpStorage[FoundCmp->second]->GetRawData(FoundEntity->second);
}
const ArchSignature* Archetype::GetSignature() const
{
return &Signature;
}
VectorStorage<EntityID>* Archetype::GetEntityIDs() const
{
return EntityIDStorage;
}