Skip to content

Commit 4bc54c2

Browse files
committed
Remove verify method to remove vtable on components
1 parent b9b804d commit 4bc54c2

File tree

9 files changed

+93
-62
lines changed

9 files changed

+93
-62
lines changed

include/Ashley/core/Component.hpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,14 @@ namespace ashley {
3333
*/
3434
class Component {
3535
public:
36-
Component() {
36+
explicit Component() {
3737
}
3838

39-
virtual ~Component() = default;
39+
~Component() = default;
4040
Component(const Component &other) = default;
4141
Component(Component &&other) = default;
4242
Component& operator=(const Component &other) = default;
4343
Component& operator=(Component &&other) = default;
44-
45-
virtual std::type_index identify() const {
46-
return std::type_index(typeid(*this));
47-
}
4844
};
4945
}
5046

include/Ashley/core/Engine.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ class Engine {
250250
virtual ~EngineOperationHandler() {
251251
}
252252

253-
virtual void add(ashley::Entity * const entity, std::unique_ptr<Component> &component)
253+
virtual void add(ashley::Entity * const entity, std::unique_ptr<Component> &&component, const std::type_index typeIndex)
254254
override;
255255
virtual void remove(ashley::Entity * const entity, const std::type_index typeIndex)
256256
override;

include/Ashley/core/Entity.hpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright 2014 See AUTHORS file.
2+
* Copyright 2014, 2015 See AUTHORS file.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,21 +14,23 @@
1414
* limitations under the License.
1515
******************************************************************************/
1616

17-
#ifndef ENTITY_HPP_
18-
#define ENTITY_HPP_
17+
#ifndef ACPP_ENTITY_HPP_
18+
#define ACPP_ENTITY_HPP_
1919

2020
#include <bitset>
2121
#include <cstdint>
2222
#include <memory>
2323
#include <typeindex>
2424
#include <unordered_map>
2525
#include <vector>
26+
#include <type_traits>
2627

2728
#include "Ashley/AshleyConstants.hpp"
2829
#include "Ashley/core/Component.hpp"
2930
#include "Ashley/core/ComponentType.hpp"
30-
#include "Ashley/internal/ComponentOperations.hpp"
3131
#include "Ashley/signals/Signal.hpp"
32+
#include "Ashley/internal/ComponentOperations.hpp"
33+
#include "Ashley/internal/Helper.hpp"
3234

3335
namespace ashley {
3436

@@ -77,7 +79,19 @@ class Entity {
7779
* @param component the component to add.
7880
* @return this {@link Entity} for chaining.
7981
*/
80-
Entity &add(std::unique_ptr<Component> &&component);
82+
template<typename C> Entity &add(std::unique_ptr<C> &&component) {
83+
internal::verify_component_type<C>();
84+
85+
auto typeIndex = std::type_index(typeid(C));
86+
87+
if (operationHandler != nullptr) {
88+
operationHandler->add(this, std::move(component), typeIndex);
89+
} else {
90+
addInternal(std::move(component), typeIndex);
91+
}
92+
93+
return *this;
94+
}
8195

8296
/**
8397
* <p>Constructs a new object of type C (subclassing ashley::Component) using <em>args...</em> for construction.</p>
@@ -87,15 +101,20 @@ class Entity {
87101
* @return This {@link Entity} for easy chaining
88102
*/
89103
template<typename C, typename ...Args> Entity &add(Args&&... args) {
90-
auto mapPtr = std::unique_ptr<Component>(new C(args...));
104+
internal::verify_component_type<C>();
91105

92-
if (operationHandler != nullptr) {
93-
operationHandler->add(this, mapPtr);
106+
const auto typeIndex = std::type_index(typeid(C));
107+
auto component = std::unique_ptr<Component>(new C(args...));
108+
109+
if(operationHandler != nullptr) {
110+
operationHandler->add(this, std::move(component), typeIndex);
94111
} else {
95-
addInternal(mapPtr);
112+
addInternal(std::move(component), typeIndex);
96113
}
97114

98115
return *this;
116+
117+
// return add<C>(std::unique_ptr<C>(new C(args...)));
99118
}
100119

101120
/**
@@ -106,14 +125,6 @@ class Entity {
106125
*/
107126
std::unique_ptr<Component> remove(const std::type_index typeIndex);
108127

109-
/**
110-
* <p>Removes the given {@link Component}, if it's found attached to this {@link Entity}.
111-
* @param component the {@link Component} to remove.
112-
* @return the removed {@link Component}'s unique_ptr if the component was removed straight away; or nullptr if not
113-
* found or if the removal has been delayed (e.g. when we're already in update() and need to wait to the end)
114-
*/
115-
std::unique_ptr<Component> remove(Component * const component);
116-
117128
/**
118129
* <p>Removes the {@link Component} of the specified type. Since there is only ever one component of one type, we
119130
* don't need an instance, just the type.</p>
@@ -160,6 +171,8 @@ class Entity {
160171
* no such component.
161172
*/
162173
template<typename C> C* getComponent() {
174+
internal::verify_component_type<C>();
175+
163176
auto type = std::type_index(typeid(C));
164177
auto id = ashley::ComponentType::getIndexFor(type);
165178

@@ -255,7 +268,7 @@ class Entity {
255268

256269
ComponentOperationHandler *operationHandler = nullptr, *operationHandlerTemp = nullptr;
257270

258-
void addInternal(std::unique_ptr<Component> &component);
271+
void addInternal(std::unique_ptr<Component> &&component, std::type_index type);
259272

260273
std::unique_ptr<Component> removeImpl(std::type_index typeIndex);
261274

include/Ashley/internal/ComponentOperations.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* limitations under the License.
1515
******************************************************************************/
1616

17-
#ifndef COMPONENTOPERATIONS_HPP_
18-
#define COMPONENTOPERATIONS_HPP_
17+
#ifndef ACPP_COMPONENTOPERATIONS_HPP_
18+
#define ACPP_COMPONENTOPERATIONS_HPP_
1919

2020
#include <memory>
2121

@@ -35,7 +35,7 @@ class ComponentOperationHandler {
3535
virtual ~ComponentOperationHandler() {
3636
}
3737

38-
virtual void add(ashley::Entity * const entity, std::unique_ptr<Component> &component) = 0;
38+
virtual void add(ashley::Entity * const entity, std::unique_ptr<Component> &&component, const std::type_index typeIndex) = 0;
3939
virtual void remove(ashley::Entity * const entity, const std::type_index typeIndex) = 0;
4040
};
4141

@@ -62,11 +62,14 @@ struct ComponentOperation : public ashley::Poolable {
6262
virtual ~ComponentOperation() {
6363
}
6464

65-
inline void makeAdd(ashley::Entity *entity, std::unique_ptr<Component> &component) {
65+
// TODO: Remove use of "new" here
66+
67+
inline void makeAdd(ashley::Entity *entity, std::unique_ptr<Component> &&component, const std::type_index typeIndex) {
6668
this->type = Type::ADD;
6769

6870
this->entity = entity;
6971
this->component = std::move(component);
72+
this->typeIndex = std::unique_ptr<std::type_index>(new std::type_index(typeIndex));
7073
}
7174

7275
inline void makeRemove(ashley::Entity *entity, const std::type_index typeIndex) {

include/Ashley/internal/Helper.hpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*******************************************************************************
2+
* Copyright 2014, 2015 See AUTHORS file.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
******************************************************************************/
16+
17+
#ifndef INCLUDE_ASHLEY_INTERNAL_HELPER_HPP_
18+
#define INCLUDE_ASHLEY_INTERNAL_HELPER_HPP_
19+
20+
#include <typeinfo>
21+
#include <typeindex>
22+
#include <type_traits>
23+
24+
#include "Ashley/core/Component.hpp"
25+
26+
namespace ashley {
27+
namespace internal {
28+
29+
template<typename C> const char *get_friendly_type_name() {
30+
return std::type_index(typeid(C)).name();
31+
}
32+
33+
template<typename C> inline void verify_component_type() {
34+
static_assert(std::is_base_of<ashley::Component, C>(), "Component verification failed.");
35+
}
36+
37+
}
38+
}
39+
40+
#endif /* INCLUDE_ASHLEY_INTERNAL_HELPER_HPP_ */

src/Engine.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ void ashley::Engine::processComponentOperations() {
238238

239239
switch (operation->type) {
240240
case ComponentOperation::Type::ADD: {
241-
operation->entity->addInternal(operation->component);
241+
operation->entity->addInternal(std::move(operation->component), *(operation->typeIndex));
242242
break;
243243
}
244244

@@ -247,9 +247,9 @@ void ashley::Engine::processComponentOperations() {
247247
break;
248248
}
249249

250-
default: {
251-
throw std::bad_function_call();
252-
return;
250+
case ComponentOperation::Type::NONE: {
251+
assert(false);
252+
break;
253253
}
254254
}
255255

@@ -327,15 +327,14 @@ void ashley::Engine::removeEntityInternal(Entity * const entity) {
327327
}
328328

329329
void ashley::Engine::EngineOperationHandler::add(ashley::Entity * const entity,
330-
std::unique_ptr<Component> &component) {
330+
std::unique_ptr<Component> &&component, const std::type_index typeIndex) {
331331
if (engine->updating) {
332332
auto operation = engine->operationPool.obtain();
333-
operation->makeAdd(entity, component);
333+
operation->makeAdd(entity, std::move(component), typeIndex);
334334
engine->operationVector.push_back(operation);
335335
} else {
336-
entity->addInternal(component);
336+
entity->addInternal(std::move(component), typeIndex);
337337
}
338-
339338
}
340339

341340
void ashley::Engine::EngineOperationHandler::remove(ashley::Entity * const entity,

src/Entity.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,12 @@ ashley::Entity::Entity() :
3535
index(nextIndex++) {
3636
}
3737

38-
ashley::Entity &ashley::Entity::add(std::unique_ptr<Component> &&component) {
39-
if (operationHandler != nullptr) {
40-
operationHandler->add(this, component);
41-
} else {
42-
addInternal(component);
43-
}
44-
45-
return *this;
46-
}
47-
4838
std::unique_ptr<ashley::Component> ashley::Entity::remove(const std::type_index typeIndex) {
4939
try {
5040
return removeImpl(typeIndex);
5141
} catch (std::out_of_range &oor) {
5242
return std::unique_ptr<Component> { nullptr };
5343
}
54-
55-
}
56-
57-
std::unique_ptr<ashley::Component> ashley::Entity::remove(Component * const component) {
58-
return remove(component->identify());
5944
}
6045

6146
void ashley::Entity::removeAll() {
@@ -79,8 +64,7 @@ const ashley::BitsType &ashley::Entity::getComponentBits() const {
7964
return componentBits;
8065
}
8166

82-
void ashley::Entity::addInternal(std::unique_ptr<Component> &component) {
83-
auto type = component->identify();
67+
void ashley::Entity::addInternal(std::unique_ptr<Component> &&component, std::type_index type) {
8468
auto typeID = ashley::ComponentType::getIndexFor(type);
8569

8670
if (componentBits[typeID]) {

test/AshleyTestCommon.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class PositionComponent : public ashley::Component {
3333
int64_t x;
3434
int64_t y;
3535

36-
PositionComponent() :
36+
explicit PositionComponent() :
3737
PositionComponent(0, 0) {
3838
}
3939

40-
PositionComponent(int64_t x, int64_t y) :
40+
explicit PositionComponent(int64_t x, int64_t y) :
4141
x(x), y(y) {
4242
}
4343
};
@@ -50,11 +50,11 @@ class VelocityComponent : public ashley::Component {
5050
int64_t x;
5151
int64_t y;
5252

53-
VelocityComponent() :
53+
explicit VelocityComponent() :
5454
VelocityComponent(0, 0) {
5555
}
5656

57-
VelocityComponent(int64_t x, int64_t y) :
57+
explicit VelocityComponent(int64_t x, int64_t y) :
5858
x(x), y(y) {
5959
}
6060
};

test/core/ComponentTypeTest.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
// Ensures a valid type is returned when a call is made to the various getFor() functions, and that this type is the same in the various functions.
2626
// Note that this covers both the validComponentType and sameComponentType tests in the Java version
2727
TEST(ComponentTypeTest, ValidComponentTypes) {
28-
auto pos = ashley::test::PositionComponent(5, 2);
29-
3028
auto type1 = ashley::ComponentType::getFor(typeid(ashley::test::PositionComponent)); // std::type_info
3129
auto type2 = ashley::ComponentType::getFor(
3230
std::type_index(typeid(ashley::test::PositionComponent))); // std::type_index
@@ -38,8 +36,6 @@ TEST(ComponentTypeTest, ValidComponentTypes) {
3836

3937
// Ensures a valid and consistent index is returned when a call is made to the various getIndexFor() functions
4038
TEST(ComponentTypeTest, ValidComponentIndexTypes) {
41-
auto pos = ashley::test::PositionComponent(5, 2);
42-
4339
auto id1 = ashley::ComponentType::getIndexFor(typeid(ashley::test::PositionComponent));
4440
auto id2 = ashley::ComponentType::getIndexFor(
4541
std::type_index(typeid(ashley::test::PositionComponent)));

0 commit comments

Comments
 (0)