Skip to content

Commit dacfba4

Browse files
committed
create a vector wrapper for component array
1 parent a5a7735 commit dacfba4

File tree

8 files changed

+205
-43
lines changed

8 files changed

+205
-43
lines changed

rootex/core/renderer/post_processor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class GodRaysPostProcess : public PostProcess
132132
const PostProcessingDetails& postProcessingDetails = camera->getPostProcessingDetails();
133133
if (postProcessingDetails.isGodRays)
134134
{
135-
Vector<DirectionalLightComponent>& directionalLightComponents = ECSFactory::GetAllDirectionalLightComponent();
135+
ComponentArray<DirectionalLightComponent>& directionalLightComponents = ECSFactory::GetAllDirectionalLightComponent();
136136
if (directionalLightComponents.size() > 0)
137137
{
138138
if (directionalLightComponents.size() > 1)

rootex/framework/component.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Component;
1313
bool Add##Type(Entity& owner, const JSON::json& componentData, bool checks = true); \
1414
bool AddDefault##Type(Entity& owner, bool checks = true); \
1515
bool Remove##Type(Entity& entity); \
16-
Vector<Type>& GetAll##Type(); \
16+
ComponentArray<Type>& GetAll##Type(); \
1717
}
1818

1919
#define DEFINE_COMPONENT(Type) \
@@ -29,7 +29,7 @@ class Component;
2929
{ \
3030
return s_ComponentSets[Type::s_Name]->removeComponent(entity); \
3131
} \
32-
Vector<Type>& ECSFactory::GetAll##Type() \
32+
ComponentArray<Type>& ECSFactory::GetAll##Type() \
3333
{ \
3434
return ((ComponentSet<Type>*)(s_ComponentSets[Type::s_Name].get()))->getAll(); \
3535
}

rootex/framework/ecs_factory.h

+5-26
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "scene.h"
77
#include "entity.h"
88

9-
#define MAX_COMPONENT_ARRAY_SIZE 1000
9+
#include "utility/component_array.h"
1010

1111
typedef unsigned int ComponentID;
1212
class Component;
@@ -25,31 +25,20 @@ class BaseComponentSet
2525
template <class T>
2626
class ComponentSet : public BaseComponentSet
2727
{
28-
Vector<T> m_Instances;
28+
ComponentArray<T> m_Instances;
2929

3030
public:
31-
ComponentSet()
32-
{
33-
m_Instances.reserve(MAX_COMPONENT_ARRAY_SIZE); // To disallow resize if max size is detected later
34-
}
31+
ComponentSet() = default;
3532
ComponentSet(const ComponentSet&) = delete;
3633
ComponentSet& operator=(const ComponentSet&) = delete;
3734

38-
Vector<T>& getAll() { return m_Instances; }
35+
ComponentArray<T>& getAll() { return m_Instances; }
3936

4037
bool addComponent(Entity& owner, const JSON::json& componentData, bool checks) override
4138
{
42-
if (m_Instances.size() == MAX_COMPONENT_ARRAY_SIZE)
43-
{
44-
ERR("Component set for " + T::s_Name + " is full. Reduce component count or increase max size");
45-
}
46-
4739
if (!owner.hasComponent(T::s_ID))
4840
{
4941
m_Instances.emplace_back(owner, componentData);
50-
T& instance = m_Instances.back();
51-
52-
owner.registerComponent(&instance);
5342

5443
if (checks && !owner.onAllComponentsAdded())
5544
{
@@ -73,17 +62,7 @@ class ComponentSet : public BaseComponentSet
7362

7463
bool removeComponent(Entity& entity) override
7564
{
76-
auto& findIt = std::find_if(m_Instances.begin(), m_Instances.end(), [&entity](T& c) {
77-
return c.getOwner().getID() == entity.getID();
78-
});
79-
80-
if (findIt != m_Instances.end())
81-
{
82-
findIt->onRemove();
83-
m_Instances.erase(findIt);
84-
return true;
85-
}
86-
return false;
65+
return m_Instances.erase(entity);
8766
}
8867

8968
const String& getName() const override { return T::s_Name; };

rootex/framework/scene.h

+1
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,6 @@ class Scene
9393
Entity& getEntity() { return m_Entity; }
9494
const String& getName() const { return m_Name; }
9595
const String& getFullName() const { return m_FullName; }
96+
void setFullName(String& name) { m_FullName = name; }
9697
SceneSettings& getSettings() { return m_Settings; }
9798
};

rootex/framework/systems/light_system.cpp

+25-13
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ LightSystem* LightSystem::GetSingleton()
2222
StaticPointLightsInfo LightSystem::getStaticPointLights()
2323
{
2424
StaticPointLightsInfo staticLights;
25-
Vector<StaticPointLightComponent>& staticPointLightComponents = ECSFactory::GetAllStaticPointLightComponent();
25+
ComponentArray<StaticPointLightComponent>& staticPointLightComponents = ECSFactory::GetAllStaticPointLightComponent();
2626

2727
int i = 0;
28-
for (; i < staticPointLightComponents.size() && i < MAX_STATIC_POINT_LIGHTS; i++)
28+
for (auto&& staticLight : staticPointLightComponents)
2929
{
30-
StaticPointLightComponent& staticLight = staticPointLightComponents[i];
3130
Vector3 transformedPosition = staticLight.getAbsoluteTransform().Translation();
3231
const PointLight& pointLight = staticLight.getPointLight();
3332

@@ -39,6 +38,11 @@ StaticPointLightsInfo LightSystem::getStaticPointLights()
3938
staticLights.pointLightInfos[i].attQuad = pointLight.attQuad;
4039
staticLights.pointLightInfos[i].lightPos = transformedPosition;
4140
staticLights.pointLightInfos[i].range = pointLight.range;
41+
i++;
42+
if (i == MAX_STATIC_POINT_LIGHTS)
43+
{
44+
break;
45+
}
4246
}
4347
return staticLights;
4448
}
@@ -56,13 +60,14 @@ LightsInfo LightSystem::getDynamicLights()
5660
return Vector3::DistanceSquared(cameraPos, aa) < Vector3::DistanceSquared(cameraPos, bb);
5761
};
5862

59-
Vector<PointLightComponent>& pointLightComponents = ECSFactory::GetAllPointLightComponent();
60-
sort(pointLightComponents.begin(), pointLightComponents.end(), pointLightSortingLambda);
63+
ComponentArray<PointLightComponent>& pointLightComponents = ECSFactory::GetAllPointLightComponent();
64+
// TODO: Implement sorting. Currently due to raw pointers in components it is not possible to sort without guaranteeing there
65+
// won't be any memory corruption.
66+
//sort(pointLightComponents.begin(), pointLightComponents.end(), pointLightSortingLambda);
6167

6268
int i = 0;
63-
for (; i < pointLightComponents.size() && i < MAX_DYNAMIC_POINT_LIGHTS; i++)
69+
for (auto&& light : pointLightComponents)
6470
{
65-
PointLightComponent& light = pointLightComponents[i];
6671
Vector3 transformedPosition = light.getAbsoluteTransform().Translation();
6772
const PointLight& pointLight = light.getPointLight();
6873

@@ -74,10 +79,15 @@ LightsInfo LightSystem::getDynamicLights()
7479
lights.pointLightInfos[i].attQuad = pointLight.attQuad;
7580
lights.pointLightInfos[i].lightPos = transformedPosition;
7681
lights.pointLightInfos[i].range = pointLight.range;
82+
i++;
83+
if (i == MAX_DYNAMIC_POINT_LIGHTS)
84+
{
85+
break;
86+
}
7787
}
7888
lights.pointLightCount = i;
7989

80-
Vector<DirectionalLightComponent>& directionalLightComponents = ECSFactory::GetAllDirectionalLightComponent();
90+
ComponentArray<DirectionalLightComponent>& directionalLightComponents = ECSFactory::GetAllDirectionalLightComponent();
8191
if (directionalLightComponents.size() > 0)
8292
{
8393
if (directionalLightComponents.size() > 1)
@@ -104,16 +114,18 @@ LightsInfo LightSystem::getDynamicLights()
104114
return Vector3::DistanceSquared(cameraPos, aa) < Vector3::DistanceSquared(cameraPos, bb);
105115
};
106116

107-
Vector<SpotLightComponent>& spotLightComponents = ECSFactory::GetAllSpotLightComponent();
108-
sort(spotLightComponents.begin(), spotLightComponents.end(), spotLightSortingLambda);
117+
ComponentArray<SpotLightComponent>& spotLightComponents = ECSFactory::GetAllSpotLightComponent();
118+
// TODO: Implement sorting. Currently due to raw pointers in components it is not possible to sort without guarrateeing there
119+
// won't be any memory corruption.
120+
//sort(spotLightComponents.begin(), spotLightComponents.end(), spotLightSortingLambda);
109121

110122
i = 0;
111-
for (; i < spotLightComponents.size() && i < MAX_DYNAMIC_SPOT_LIGHTS; i++)
123+
for (auto&& light : spotLightComponents)
112124
{
113-
SpotLightComponent& light = spotLightComponents[i];
114125
Matrix transform = light.getAbsoluteTransform();
115126
const SpotLight& spotLight = light.getSpotLight();
116-
127+
128+
i++;
117129
lights.spotLightInfos[i] = {
118130
spotLight.ambientColor,
119131
spotLight.diffuseColor,

rootex/framework/systems/render_system.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void RenderSystem::update(float deltaMilliseconds)
160160
FogComponent& firstFog = ECSFactory::GetAllFogComponent().front();
161161
clearColor = firstFog.getColor();
162162

163-
for (auto& fog : ECSFactory::GetAllFogComponent())
163+
for (auto&& fog : ECSFactory::GetAllFogComponent())
164164
{
165165
clearColor = Color::Lerp(clearColor, fog.getColor(), 0.5f);
166166
fogStart = fog.getNearDistance();

rootex/utility/component_array.h

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#pragma once
2+
3+
#include "common/types.h"
4+
#include "component_array_iterator.h"
5+
6+
#define MAX_COMPONENT_ARRAY_SIZE 10000
7+
8+
template <typename Component, class A = std::allocator<Component>>
9+
class ComponentArray
10+
{
11+
private:
12+
Vector<Component> m_Data;
13+
Vector<bool> m_IsValid;
14+
size_t m_Curr;
15+
size_t m_ArraySize;
16+
17+
public:
18+
ComponentArray()
19+
{
20+
m_Data.reserve(MAX_COMPONENT_ARRAY_SIZE);
21+
m_IsValid.reserve(MAX_COMPONENT_ARRAY_SIZE);
22+
for (int i = 0; i < MAX_COMPONENT_ARRAY_SIZE; i++)
23+
{
24+
m_IsValid.push_back(true);
25+
}
26+
m_Curr = 0;
27+
m_ArraySize = 0;
28+
}
29+
30+
ComponentArrayIterator<Component> begin()
31+
{
32+
int index = 0;
33+
while (!m_IsValid[index])
34+
{
35+
index++;
36+
}
37+
return ComponentArrayIterator<Component>(m_IsValid, m_Data.begin() + index);
38+
}
39+
40+
ComponentArrayIterator<Component> end() { return ComponentArrayIterator<Component>(m_IsValid, m_Data.begin() + m_Curr); }
41+
42+
void push_back(const Component& item)
43+
{
44+
if (m_ArraySize == MAX_COMPONENT_ARRAY_SIZE)
45+
{
46+
ERR("Component set for " + Component::s_Name + " is full. Reduce component count or increase MAX_COMPONENT_ARRAY_SIZE");
47+
}
48+
for (int i = 0; i < MAX_COMPONENT_ARRAY_SIZE; i++)
49+
{
50+
if (!m_IsValid[i])
51+
{
52+
m_Data[i] = item;
53+
m_IsValid[i] = true;
54+
return;
55+
}
56+
}
57+
m_Data[m_Curr] = item;
58+
m_Curr++;
59+
}
60+
61+
void emplace_back(Entity& owner, const JSON::json& componentData)
62+
{
63+
if (m_ArraySize == MAX_COMPONENT_ARRAY_SIZE)
64+
{
65+
ERR("Component set for " + Component::s_Name + " is full. Reduce component count or increase max MAX_COMPONENT_ARRAY_SIZE");
66+
}
67+
68+
for (int i = 0; i < m_Curr; i++)
69+
{
70+
if (!m_IsValid[i])
71+
{
72+
new (&m_Data[i]) Component(owner, componentData); //Create a new component at m_data[i]
73+
owner.registerComponent(&m_Data[i]);
74+
m_IsValid[i] = true;
75+
m_ArraySize++;
76+
return;
77+
}
78+
}
79+
m_Data.emplace_back(owner, componentData);
80+
owner.registerComponent(&m_Data[m_Curr]);
81+
m_Curr++;
82+
m_ArraySize++;
83+
}
84+
85+
bool erase(Entity& entity)
86+
{
87+
for (int i = 0; i <= m_Curr; i++)
88+
{
89+
if (m_IsValid[i] && (m_Data[i].getOwner().getID() == entity.getID()))
90+
{
91+
m_IsValid[i] = false;
92+
return true;
93+
}
94+
}
95+
return false;
96+
}
97+
98+
Component& ComponentArray::operator[](int index)
99+
{
100+
if (index >= m_Curr)
101+
{
102+
ERR("Array index out of bound");
103+
}
104+
105+
int actualIndex = 0;
106+
int i = 0;
107+
for (i = 0; i < m_ArraySize; i++)
108+
{
109+
if (m_IsValid[i])
110+
{
111+
actualIndex++;
112+
}
113+
if (actualIndex == index)
114+
{
115+
break;
116+
}
117+
}
118+
return m_Data[i];
119+
}
120+
121+
size_t size() const { return m_ArraySize; }
122+
123+
bool empty() const { return m_ArraySize == 0; }
124+
125+
Component front() { return *begin(); }
126+
127+
Component back() { return *end(); }
128+
};
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include "common/types.h"
4+
5+
template <typename DataType>
6+
class ComponentArrayIterator
7+
{
8+
protected:
9+
typename Vector<DataType>::iterator m_Itr;
10+
int m_Index;
11+
Vector<bool>* m_IsValid;
12+
13+
public:
14+
ComponentArrayIterator(Vector<bool>& isValid, typename Vector<DataType>::iterator itr)
15+
{
16+
m_IsValid = &isValid;
17+
m_Itr = itr;
18+
m_Index = 0;
19+
}
20+
ComponentArrayIterator(const ComponentArrayIterator<DataType>& rawIterator) = default; // Copy constructor
21+
~ComponentArrayIterator() { }
22+
23+
ComponentArrayIterator<DataType>& operator=(const ComponentArrayIterator<DataType>& rawIterator) = default;
24+
25+
bool operator==(const ComponentArrayIterator<DataType>& rawIterator) const { return (m_Itr == rawIterator.m_Itr); }
26+
bool operator!=(const ComponentArrayIterator<DataType>& rawIterator) const { return !(m_Itr == rawIterator.m_Itr); }
27+
28+
ComponentArrayIterator<DataType> operator++()
29+
{
30+
while ((*m_IsValid)[m_Index + 1] == false && m_Index + 1 < (*m_IsValid).size())
31+
{
32+
m_Index++;
33+
m_Itr++;
34+
}
35+
m_Index++;
36+
m_Itr++;
37+
return *this;
38+
}
39+
40+
DataType& operator*() { return *m_Itr; }
41+
const DataType& operator*() const { return *m_Itr; }
42+
};

0 commit comments

Comments
 (0)