我正在尝试制作一个玩具实体组件系统,以提高我的c++技能。为此,我有一个ECS_Manager类,它使用模板为我想用作组件的每种数据类型提供多个存储类。
每个组件只是一个结构体与一个int和其他任何我想要的数据。在这个例子中,它包含一个Vector2D对象。没什么特别的。
作为起点,每个组件类型的内部存储类都有自己的vector。我可以很好地存储新数据(如果我这样做,它最终会打印出来)。但是,当我尝试保存新时使用指针解引用(参见下面的Physics_System
)将数据移到vector中的元素,则不保存新值。我不明白为什么。
#include <iostream>
#include <vector>
#include <map>
#include <typeinfo>
#include <memory>
#include <array>
#include "Vector2D.hpp"
#include "./ECS/components/Position_comp.hpp"
class VComponentStorage {
public:
virtual ~VComponentStorage() = default;
};
template <typename T>
class ComponentStorage : public VComponentStorage{
public:
ComponentStorage(){
this->storage_container_index = 0;
}
void add_component(T component){
this->storage_container.push_back(component);
this->storage_container_index++;
}
T *get_component(int entity_id){
T* start_ptr = this->storage_container.data();
return &(start_ptr[entity_id]);
}
size_t get_component_count(){
return 1;
}
private:
std::vector<T> storage_container;
size_t storage_container_index;
};
class ECS_Mananger{
public:
ECS_Mananger(){
}
template<typename T> void register_component(){
const char *type_name = typeid(T).name();
ComponentStorage<T> *comp_storage_ptr = new ComponentStorage<T>;
this->T_to_comp_storage_Map.insert({type_name, comp_storage_ptr});
}
template<typename T>
void add_component(T component){
const char *type_name = typeid(T).name();
std::cout << type_name << std::endl;
ComponentStorage<T>* my_ptr = static_cast<ComponentStorage<T>*>(this->T_to_comp_storage_Map[type_name]);
my_ptr->add_component(component);
}
template<typename T>
T *get_component(int entity_id){
const char *type_name = typeid(T).name();
ComponentStorage<T>* my_ptr = static_cast<ComponentStorage<T>*>(this->T_to_comp_storage_Map[type_name]);
return my_ptr->get_component(entity_id);
}
private:
std::map<std::string, VComponentStorage*> T_to_comp_storage_Map;
};
void Physics_System(ECS_Mananger &world){
Position_Component* my_ptr = world.get_component<Position_Component>(0);
*my_ptr = { 0, Vector2D(5.0, 2.0)};
};
int main() {
//Create Arrays
ECS_Mananger my_world;
my_world.register_component<Position_Component>();
Position_Component init_pos_val = {0, Vector2D(1.0, 2.0)};
my_world.add_component<Position_Component>(init_pos_val);
// Main game loop
while (1) // Detect window close button or ESC key
{
// Update
Physics_System(my_world);
my_world.get_component<Position_Component>(0)->position.print();
}
return 0;
}
在Physics_System
函数中,我希望值被更新。有什么原因吗?我的c++有点生疏了。首先,我是这样做的:'world.get_component
编辑:
Position_Component和Vector2D规范:
#include "Vector2D.hpp"
struct Position_Component {
int entity_id;
Vector2D position;
};
class Vector2D {
public:
double x;
double y;
Vector2D() {
this->x = 0.0;
this->y = 0.0;
}
Vector2D(double x, double y){
this->x = x;
this->y = y;
}
void print(){ std::cout << "(" << this->x << "," << this->y << ")" << std::endl; };
Vector2D operator+(const Vector2D& vec){
Vector2D result;
result.x = this->x + vec.x;
result.y = this->y + vec.y;
return result;
}
Vector2D operator-(const Vector2D& vec){
Vector2D result;
result.x = this->x - vec.x;
result.y = this->y - vec.y;
return result;
}
Vector2D operator=(const Vector2D& vec){
Vector2D result;
result.x = vec.x;
result.y = vec.y;
return result;
}
};
Vector2D operator*(const double& s, Vector2D vec){
Vector2D result;
result.x = s*vec.x;
result.y = s*vec.y;
return result;
}
问题是您的Vector2D
赋值运算符:
Vector2D operator=(const Vector2D& vec){
Vector2D result;
result.x = vec.x;
result.y = vec.y;
return result;
}
赋值操作符应该赋值给this
对象,而不是创建一个新对象。它还应该返回一个对*this
的引用(以允许链式赋值)。
由于这个问题,赋值
*my_ptr = { 0, Vector2D(5.0, 2.0)};
被简单地丢弃,你从来没有真正修改过*my_ptr
。
要解决它,请更改为例如:
Vector2D& operator=(const Vector2D& vec){
x = vec.x;
y = vec.y;
return *this;
}
我建议花点时间阅读重载操作符的规范实现参考。