I'm trying to map some structs to some other instances, like this:
template <typename T>
class Component {
public:
typedef std::map<EntityID, T> instances_map;
instances_map instances;
Component() {};
T add(EntityID id) {
T* t = new T();
instances[id] = *t;
return *t;
};
};
Then I use it like this:
struct UnitInfos {
int owner_id;
int health;
float x, y;
};
class LogicComponent : public Component<UnitInfos> {};
The problem is that when it later retrieve data later on, like this:
comp.instance[id];
I get a breand new object with properties initialized at default values.
Is there something inherently wrong with this piece of code, or am I leaving out information about the problem?
As per @aaa suggestion, i change the code to
typedef std::map<EntityID, T> instances_map;
instances_map instances;
T& add(EntityID id) {
instances[id] = T();
return instances[id];
};
but when I access it
UnitInfos &info = logic_c.instances[id];
the value of info.x is still 0. Any pointers?
The problem was how I stored the reference to LogicComponent in another class. using LogicComponent logic_c;
instead of LogicComponent& logic_c;
. It now works, but I'm storing pointers in the map (instead of @aaa's suggestion). Is this a bad idea?
Clarify the operations you want to perform on LogicComponent. Assuming you are trying to achieve something like this:
Step 1: Add a new entry to the map:
LogicComponent comp;
EntityID id = 99;
UnitInfos info = comp.add(id);
Step 2: Initialize the info:
info.x = 10.0;
info.y = 11.0
// etc
Step 3: Get the info object again:
UnitInfos info2 = comp.instances[id]; // this is uninitialized.
Then, a few code comments are in order:
The info object returned by comp.add is a COPY of the object you added to the map. By modifying it, you are not modifying what is in the map.
The simplest fix is to create a map of pointers to the object instead of the object itself.
typedef std::map<EntityID, T*> pinstances_map;
T * add(EntityID id) {
T* t = new T();
instances[id] = t;
return t;
};
// initialize as
UnitInfo *info = comp.add(id);
info->x = 10.0;
info->y = 11.0;
// retrieve as
UnitInfos *info = comp.instances[id];
Also, do use an accessor method to get the mapped value, instead of exposing the map object as public. Make the instances variable protected, and add a public get() method.
Edit: This code works fine for me:
#include <map>
#include <iostream>
using namespace std;
template<typename T>
class Component
{
public:
typedef map<long, T*> pinstances_map;
pinstances_map instances;
T * add(long id)
{
T *t = new T();
instances[id] = t;
return t;
}
};
struct UnitInfo
{
float x, y;
};
class LogicComponent: public Component<UnitInfo> {};
int main()
{
LogicComponent comp;
UnitInfo *info = comp.add(99);
info->x = 10.0;
info->y = 11.0;
UnitInfo *info2 = comp.instances[99];
cout << info2->x << " " << info2->y;
return 0;
}
might be that
T add(EntityID id) {
T* t = new T();
instances[id] = *t;
return *t; // return value and map instance are not the same anymore
};
should be
T& add(EntityID id) {
instances[id] = T();
return instances[id];
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With