please skip the explanation if you know how the entity component architecture works!
Explanation:
Okay so I'm trying to create an entity component system, and i'm stuck at a very strange problem, that has never occurred until now, basically i have an Entity class which contains some variables(like name, tag, id), and a pointer vector which keeps track of all the components that get added to the entity, that's the entity class, all the components derive from the Component class, which has a type(char*), and virtual functions such as Start, Update, etc.This is how you create a component:
#pragma once
class printcomponent : public Component {
printcomponent() : Component("printcomponent"){} // the printcomponent constructor derives from the component constructor which takes a char* as parameter, and sets the component's type to that char*
void Start(){
cout << "This is printed on start" << endl;
}
void Update(){
cout << "This gets printed every frame" << endl;
}
~printcomponent();//destructor
}
My Problem:
Okay so my problem occurs only when i try to get the component of type Rigidbody2d, this is "PhysicalObject.cpp", physicalobject is a type of entity which already has some components, like a prefab, so i don't have to always add the same components to an entity type, like a physical object:
#include "stdafx.h"
#include "Public.h" // all the public variables are in here, and declared in Public.cpp
#include "PhysicalObject.h"
PhysicalObject::PhysicalObject(float boxwidth, float boxheight, float gscale, bool fixedr, float nDnsity, float nFricton, string name, string tag, bool isactive, bool isstatic) : Entity(name, tag, isactive, isstatic) // so basically the constructor creates an entity
{
this->AddComponent<Transfrm>(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f)); // i add a transform component
this->AddComponent<RigidBody2D>(gscale, fixedr); // i add a rigidbody2d component, there is no problem when adding components
this->AddComponent<SprtRend>(this); // again spriterenderer component
trans = this->GetComponent<Transfrm>(); // okay so i have 2 variables for easily accessing specific components, i have one trans for transform, and one rigidb for rigidbody2d, basically calling this instead of getting component is much more efficient !
rigidb = this->GetComponent<RigidBody2D>(); // this is the line causing me problems, the previous line doesn't cause any problem, but this causes an Unhandled exception, in the function GetComponent of Entity.h
}
the error points to "entity.h" getcomponent function Entity.h:
// add component, constructor, and other functions.
template <typename T>
T* GetComponent() {
T t; // so basically this function creates a new given type T and loops through all the components until it finds a matching type
for (unsigned i = 0; i < AllComponents.size(); i++) {
if (AllComponents.at(i)->Type == t.Type) { // when debugging in this line, in the 'autos' window, it shows the type as "RigidBody2D", which is fine, but after i continue to the other line, it gives me the unhandled exception and the type of 't' is something like: "/x" and some numbers, which makes no sense, and doesn't occur when getting other components.
return dynamic_cast<T*>(AllComponents.at(i));
break;
}
}
cout << "Entity: " << Name << " Does Not Have Component of Type: " << t.Type << endl;
}
// desctructor
and finally the RigidBody2d.h file, which contains the rigidbody component, which is no different than other components, but still gives an error.
RigidBody2D.h: // I'm going to show all the code, because i'm not sure what might be causing the problem, so i apologize if this post becomes extremely long, also note that i've implemented the box2d library in my engine so there is some variables and functions from that, which i don't think are causing any error.
#pragma once
#include "Component.h"
#include "Transfrm.h" // i need the transform component for the rigidbody because it contains a position, rotation, etc.
class RigidBody2D : public Component
{
public:
b2BodyDef bodyDef;
Transfrm* Trans;
b2Body* Body;
float* GScale; // this pointer needs to point to the gravity scale variable of body
bool* FreezeRot; // this pointer needs to point to the freeze rotation variable of body
bool IsKinematic;
void SetGScale(float newgs){
*GScale = newgs;
}
void SetFreezeRot(bool newfr) {
*FreezeRot = newfr;
}
void SetIsKinetic(bool newisk) {
IsKinematic = newisk;
}
RigidBody2D(float gscale = 1.f, bool fixedr = false); // constructor, before i used 2 constructors one with no parameters, but that caused me errors, because the compilier didn't know which constructor to use since they were the same(didn't require parameters)
~RigidBody2D();
};
and finally RigidBody2D.cpp:
#include "stdafx.h"
#include "Public.h"
#include "RigidBody2D.h"
RigidBody2D::RigidBody2D(float gscale, bool fixedr) : Component("RigidBody2D")
{
Trans = new Transfrm(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f));
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(Trans->Position.x, Trans->Position.y);
bodyDef.gravityScale = gscale;
bodyDef.fixedRotation = fixedr;
GScale = &bodyDef.gravityScale;
FreezeRot = &bodyDef.fixedRotation;
Body = CurrentPhysicsWorld->CreateBody(&bodyDef);
}
RigidBody2D::~RigidBody2D() {
delete Trans;
delete GScale;
delete FreezeRot;
CurrentPhysicsWorld->DestroyBody(Body);
};
I'm extremely sorry for the gigantic post, which took me like 2 hours to write, but I've been searching and debugging like 3 days, and still can't find a solution, because i have never encountered such problem, thanks in advance.
To me this part looks strange:
So it looks to me that you are trying to
delete
something that wasn't created bynew