Skip to content

Commit 92ee53e

Browse files
committed
-
1 parent 517d186 commit 92ee53e

17 files changed

+144
-61
lines changed

src/Entity.cpp

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,53 +7,66 @@ Entity::Entity()
77
: mDebugColor(Color32_Green)
88
, mComponents()
99
{
10-
// add automatically transform component
10+
// automatically add transform component
1111
AddComponent<TransformComponent>();
1212
}
1313

1414
Entity::~Entity()
1515
{
16-
DeleteAllComponents();
16+
RemoveAllComponents();
1717
}
1818

19-
void Entity::UpdateFrame(float deltaTime)
19+
void Entity::UpdateComponents(float deltaTime)
2020
{
21+
bool pendingDeletion = false;
2122
for (EntityComponent* currComponent: mComponents)
2223
{
24+
if (currComponent->IsComponentDeleted())
25+
{
26+
pendingDeletion = true;
27+
continue;
28+
}
29+
2330
if (currComponent->IsComponentActive())
2431
{
2532
currComponent->UpdateComponent(deltaTime);
2633
}
2734
}
35+
36+
if (pendingDeletion)
37+
{
38+
for (auto curr_iterator = mComponents.begin(); curr_iterator != mComponents.end(); )
39+
{
40+
EntityComponent* currComponent = *curr_iterator;
41+
if (currComponent->IsComponentDeleted())
42+
{
43+
curr_iterator = mComponents.erase(curr_iterator);
44+
currComponent->DestroyComponent();
45+
continue;
46+
}
47+
++curr_iterator;
48+
}
49+
}
2850
}
2951

3052
void Entity::SetActive(bool isActive)
3153
{
3254
for (EntityComponent* currComponent: mComponents)
3355
{
56+
if (currComponent->IsComponentDeleted())
57+
continue;
58+
3459
currComponent->EnableComponent(isActive);
3560
}
3661
}
3762

3863
void Entity::UpdateComponentsCache()
3964
{
4065
// cache transform component
41-
mTransform = nullptr;
42-
for (EntityComponent* currComponent: mComponents)
43-
{
44-
mTransform = cxx::rtti_cast<TransformComponent>(currComponent);
45-
if (mTransform)
46-
break;
47-
}
48-
66+
mTransform = GetComponent<TransformComponent>();
67+
4968
// cache renderable component
50-
mRenderable = nullptr;
51-
for (EntityComponent* currComponent: mComponents)
52-
{
53-
mRenderable = cxx::rtti_cast<RenderableComponent>(currComponent);
54-
if (mRenderable)
55-
break;
56-
}
69+
mRenderable = GetComponent<RenderableComponent>();
5770
}
5871

5972
void Entity::AttachComponent(EntityComponent* component)
@@ -66,23 +79,23 @@ void Entity::AttachComponent(EntityComponent* component)
6679
component->AwakeComponent();
6780
}
6881

69-
void Entity::DeleteComponent(EntityComponent* component)
82+
void Entity::RemoveComponent(EntityComponent* component)
7083
{
7184
if (component)
7285
{
7386
cxx::erase_elements(mComponents, component);
74-
component->DeleteComponent();
87+
component->DestroyComponent();
7588

7689
UpdateComponentsCache();
7790
}
7891
debug_assert(component);
7992
}
8093

81-
void Entity::DeleteAllComponents()
94+
void Entity::RemoveAllComponents()
8295
{
8396
for (EntityComponent* currComponent: mComponents)
8497
{
85-
currComponent->DeleteComponent();
98+
currComponent->DestroyComponent();
8699
}
87100
mComponents.clear();
88101
UpdateComponentsCache();
@@ -92,9 +105,17 @@ bool Entity::IsActive() const
92105
{
93106
for (EntityComponent* currComponent: mComponents)
94107
{
108+
if (currComponent->IsComponentDeleted())
109+
continue;
110+
95111
if (currComponent->IsComponentActive())
96112
return true;
97113
}
98114

99115
return false;
100-
}
116+
}
117+
118+
void Entity::SetController(EntityController* controller)
119+
{
120+
mController = controller;
121+
}

src/Entity.h

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,36 @@
22

33
#include "EntityComponent.h"
44
#include "GameDefs.h"
5+
#include "SceneDefs.h"
6+
#include "EntityController.h"
57

6-
class Entity: public cxx::noncopyable
8+
// scene entity is components container
9+
class Entity final: public cxx::noncopyable
710
{
811
public:
912
Color32 mDebugColor; // color used for debug draw
1013

1114
float mDistanceToCameraSquared; // this value gets updated during scene rendition
1215

16+
// readonly
17+
1318
// components cache
1419
TransformComponent* mTransform = nullptr;
1520
RenderableComponent* mRenderable = nullptr;
1621

22+
// entity owner can control and listen entity components
23+
EntityController* mController = nullptr;
24+
1725
public:
1826
Entity();
1927
~Entity();
2028

21-
// process update frame
29+
// update active entity components
2230
// @param deltaTime: Time since last update
23-
void UpdateFrame(float deltaTime);
31+
void UpdateComponents(float deltaTime);
32+
33+
// assign new or clear current controller if nullptr specified
34+
void SetController(EntityController* controller);
2435

2536
// add or remove object component, object takes ownership on pointer
2637
// @param component: Component instance
@@ -32,26 +43,29 @@ class Entity: public cxx::noncopyable
3243
return newComponent;
3344
}
3445

35-
void DeleteComponent(EntityComponent* component);
46+
// immediately destroy specific component
47+
void RemoveComponent(EntityComponent* component);
3648

49+
// immediately destroy component of specific type
3750
template<typename TComponent>
38-
inline void DeleteComponent()
51+
inline void RemoveComponent()
3952
{
40-
EntityComponent* componentWithType = nullptr;
53+
TComponent* componentWithType = nullptr;
4154
for (EntityComponent* currComponent: mComponents)
4255
{
43-
if (cxx::rtti_cast<TComponent>(currComponent))
44-
{
45-
componentWithType = currComponent;
56+
componentWithType = entity_component_cast<TComponent>(currComponent);
57+
if (componentWithType)
4658
break;
47-
}
4859
}
4960
if (componentWithType)
5061
{
51-
DeleteComponent(componentWithType);
62+
RemoveComponent(componentWithType);
5263
}
5364
}
5465

66+
// immediately destroy all components including transform
67+
void RemoveAllComponents();
68+
5569
// iterate all components
5670
template<typename TProc>
5771
inline void ForEachComponent(TProc proc) const
@@ -62,16 +76,14 @@ class Entity: public cxx::noncopyable
6276
}
6377
}
6478

65-
// destroy all components including transform
66-
void DeleteAllComponents();
67-
6879
// get component by type
6980
template<typename TComponent>
7081
inline TComponent* GetComponent() const
7182
{
7283
for (EntityComponent* currComponent: mComponents)
7384
{
74-
if (TComponent* componentWithType = cxx::rtti_cast<TComponent>(currComponent))
85+
TComponent* componentWithType = entity_component_cast<TComponent>(currComponent);
86+
if (componentWithType)
7587
return componentWithType;
7688
}
7789
return nullptr;

src/EntityComponent.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ void EntityComponent::EnableComponent(bool isEnable)
1818
}
1919
}
2020

21+
void EntityComponent::Delete()
22+
{
23+
mComponentDeleted = true;
24+
}
25+
2126
void EntityComponent::OnComponentEnabled()
2227
{
2328
// do nothing

src/EntityComponent.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,28 @@ class EntityComponent: public cxx::noncopyable
1010
Entity* mParentEntity;
1111

1212
public:
13-
// try to cast base component type to derived
14-
template<typename TComponent>
15-
inline TComponent* CastComponent()
16-
{
17-
return cxx::rtti_cast<TComponent>(this);
18-
}
19-
2013
// enable or disable component
2114
// @param isEnable: New enable state
2215
void EnableComponent(bool isEnable);
16+
2317
// test whether component is enabled
2418
inline bool IsComponentActive() const { return mComponentEnabled; }
2519

20+
// queue for deletion, component will be deleted next frame
21+
void Delete();
22+
23+
// test whether component must be deleted
24+
inline bool IsComponentDeleted() const { return mComponentDeleted; }
25+
2626
// handle update frame
2727
// @param deltaTime: Time since last update
2828
virtual void UpdateComponent(float deltaTime) = 0;
29+
2930
// component is attached to entity
3031
virtual void AwakeComponent() = 0;
32+
3133
// destroy component instance
32-
virtual void DeleteComponent() = 0;
34+
virtual void DestroyComponent() = 0;
3335

3436
protected:
3537
// base component does not meant to be instantiated directly
@@ -49,4 +51,5 @@ class EntityComponent: public cxx::noncopyable
4951

5052
protected:
5153
bool mComponentEnabled = true; // initially enabled
54+
bool mComponentDeleted = false; // mark for deletion
5255
};

src/EntityController.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "pch.h"
2+
#include "EntityController.h"
3+
#include "Entity.h"
4+
5+
EntityController::~EntityController()
6+
{
7+
}

src/EntityController.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
// base class of entity controllers
4+
class EntityController: public cxx::noncopyable
5+
{
6+
decl_rtti_base(EntityController)
7+
8+
public:
9+
virtual ~EntityController();
10+
11+
};

src/EntityManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void EntityManager::UpdateFrame()
4040
doCleanup = true;
4141
continue;
4242
}
43-
currEntity->UpdateFrame(deltaTime);
43+
currEntity->UpdateComponents(deltaTime);
4444
}
4545

4646
if (doCleanup)

src/GameDefs.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@
88
// forwards
99
class GameMap;
1010
class TerrainTile;
11-
class Entity;
12-
class EntityComponent;
13-
class RenderableComponent;
14-
class TransformComponent;
15-
class AnimatingMeshComponent;
16-
class TerrainMeshComponent;
17-
class StaticMeshComponent;
18-
class WaterLavaMeshComponent;
1911

2012
// terrain type identifier
2113
enum TerrainTypeID: unsigned int

src/GrimLandsKeeper.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@
181181
<ClInclude Include="AABBTree.h" />
182182
<ClInclude Include="CreatureDefs.h" />
183183
<ClInclude Include="DungeonHeartRoom.h" />
184+
<ClInclude Include="EntityController.h" />
184185
<ClInclude Include="TerrainHeightField.h" />
185186
<ClInclude Include="TerrainTilesCursor.h" />
186187
<ClInclude Include="Shaders.h" />
@@ -324,6 +325,7 @@
324325
<ClCompile Include="ConsoleVariable.cpp" />
325326
<ClCompile Include="DungeonHeartRoom.cpp" />
326327
<ClCompile Include="EntityComponent.cpp" />
328+
<ClCompile Include="EntityController.cpp" />
327329
<ClCompile Include="TerrainHeightField.cpp" />
328330
<ClCompile Include="TerrainTilesCursor.cpp" />
329331
<ClCompile Include="Shaders.cpp" />

src/GrimLandsKeeper.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@
522522
<ClInclude Include="EntityManager.h">
523523
<Filter>Game\Entity</Filter>
524524
</ClInclude>
525+
<ClInclude Include="EntityController.h">
526+
<Filter>Game\Entity</Filter>
527+
</ClInclude>
525528
</ItemGroup>
526529
<ItemGroup>
527530
<ClCompile Include="pch.cpp">
@@ -826,6 +829,9 @@
826829
<ClCompile Include="EntityComponent.cpp">
827830
<Filter>Game\Entity</Filter>
828831
</ClCompile>
832+
<ClCompile Include="EntityController.cpp">
833+
<Filter>Game\Entity</Filter>
834+
</ClCompile>
829835
</ItemGroup>
830836
<ItemGroup>
831837
<Text Include="..\docs\creatures_anims.txt">

0 commit comments

Comments
 (0)