aboutsummaryrefslogtreecommitdiff
path: root/mwe/ecs-homemade/inc/ComponentManager.hpp
blob: a120ab1fa5ce1f14aca8751752437c046a577a7d (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
template <typename T, typename... Args>
T& ComponentManager::AddComponent(std::uint32_t id, Args &&... args) {
	std::type_index type = typeid(
		T); //Determine the type of T (this is used as the key of the unordered_map<>)

	if (mComponents.find(type)
		== mComponents
			   .end()) { //Check if this component type is already in the unordered_map<>
		mComponents[type] = std::vector<std::vector<std::unique_ptr<
			Component>>>(); //If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
	}

	if (id
		>= mComponents[type]
			   .size()) { //Resize the vector<> if the id is greater than the current size
		mComponents[type].resize(
			id
			+ 1); //Initialize new slots to nullptr (resize does automatically init to nullptr)
	}

	mComponents[type][id].push_back(std::make_unique<T>(std::forward<Args>(
		args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<>

	return static_cast<T&>(*mComponents[type][id].back().get());
}

template <typename T>
void ComponentManager::DeleteComponentsById(std::uint32_t id) {
	std::type_index type = typeid(
		T); //Determine the type of T (this is used as the key of the unordered_map<>)

	if (mComponents.find(type)
		!= mComponents.end()) { //Find the type (in the unordered_map<>)
		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray
			= mComponents[type]; //Get the correct vector<>

		if (id
			< componentArray
				  .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<>
			componentArray[id]
				.clear(); //Clear the whole vector<> of this specific type and id
		}
	}
}

template <typename T>
void ComponentManager::DeleteComponents() {
	std::type_index type = typeid(
		T); //Determine the type of T (this is used as the key of the unordered_map<>)

	if (mComponents.find(type)
		!= mComponents.end()) { //Find the type (in the unordered_map<>)
		mComponents[type]
			.clear(); //Clear the whole vector<> of this specific type
	}
}

template <typename T>
std::vector<std::reference_wrapper<T>>
ComponentManager::GetComponentsByID(std::uint32_t id) const {
	std::type_index type = typeid(
		T); //Determine the type of T (this is used as the key of the unordered_map<>)

	std::vector<std::reference_wrapper<T>>
		componentVector; //Create an empty vector<>

	if (mComponents.find(type)
		!= mComponents.end()) { //Find the type (in the unordered_map<>)

		const std::vector<std::vector<std::unique_ptr<Component>>> &
			componentArray
			= mComponents.at(type); //Get the correct vector<>

		if (id
			< componentArray
				  .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<>
			for (const std::unique_ptr<Component> & componentPtr :
				 componentArray[id]) { //Loop trough the whole vector<>
				T * castedComponent = static_cast<T *>(
					componentPtr.get()); //Cast the unique_ptr to a raw pointer

				if (castedComponent) { //Ensure that the cast was successful
					componentVector.push_back(
						*castedComponent); //Add the dereferenced raw pointer to the vector<>
				}
			}
		}
	}

	return componentVector; //Return the vector<>
}

template <typename T>
std::vector<std::reference_wrapper<T>>
ComponentManager::GetComponentsByType() const {
	std::type_index type = typeid(
		T); //Determine the type of T (this is used as the key of the unordered_map<>)

	std::vector<std::reference_wrapper<T>>
		componentVector; //Create an empty vector<>
	//std::uint32_t id = 0;	//Set the id to 0 (the id will also be stored in the returned vector<>)

	if (mComponents.find(type)
		!= mComponents.end()) { //Find the type (in the unordered_map<>)

		const std::vector<std::vector<std::unique_ptr<Component>>> &
			componentArray
			= mComponents.at(type); //Get the correct vector<>

		for (const std::vector<std::unique_ptr<Component>> & component :
			 componentArray) { //Loop through the whole vector<>
			for (const std::unique_ptr<Component> & componentPtr :
				 component) { //Loop trough the whole vector<>
				T * castedComponent = static_cast<T *>(
					componentPtr.get()); //Cast the unique_ptr to a raw pointer

				if (castedComponent) { //Ensure that the cast was successful
					componentVector.emplace_back(std::ref(
						*castedComponent)); //Pair the dereferenced raw pointer and the id and add it to the vector<>
				}
			}

			//++id;	//Increase the id (the id will also be stored in the returned vector<>)
		}
	}

	return componentVector; //Return the vector<>
}