Also, a big hierarchy of classes (valuing inheritance over composition) is not traditional OOP; it's a complete abuse of OOP!
OO teaches that you should prefer composition over inheritance. I'd suggest simply practicing writing OO code using composition first, to get used to how composition based code is structured, before trying to create your own library that's designed to make composition easier somehow.
My bad, I guess I got too used to it!
Anyways, thanks guys, I started my own attempt at ECS, but I'm having troubles connecting things together. This is what I have so far.
Entity.h
#ifndef ENTITY_H
#define ENTITY_H
#include <vector>
#include <string>
#include "Component.h"
class Entity {
public:
Entity();
~Entity();
void AddComponent(Component *component);
Component* GetComponent(std::string name);
void Update();
private:
std::vector<Component*> components;
};
#endif
Entity.cpp
#include "Entity.h"
Entity::Entity()
{
}
Entity::~Entity()
{
}
void Entity::AddComponent(Component *component)
{
components.push_back(component);
}
Component* Entity::GetComponent(std::string name)
{
for (unsigned int i = 0; i < components.size(); i++) {
if (name.compare(components[i]->name) == 0)
return components[i];
}
}
void Entity::Update()
{
for (unsigned int i = 0; i < components.size(); i++) {
components[i]->Update();
}
}
BaseSystem.h
#ifndef BASE_SYSTEM_H
#define BASE_SYSTEM_H
class BaseSystem
{
public:
BaseSystem();
virtual ~BaseSystem();
};
#endif
Component.h
#ifndef COMPONENT_H
#define COMPONENT_H
#include <string>
class Component
{
public:
Component();
virtual ~Component();
std::string name;
virtual void Update();
};
#endif
RenderSystem.h
#ifndef RENDER_SYSTEM_H
#define RENDER_SYSTEM_H
#include <SDL2/SDL.h>
class RenderSystem : public BaseSystem {
public:
void Render(SDL_Renderer* renderer, SDL_Texture* image);
};
#endif
RenderSystem.cpp
#include "RenderSystem.h"
void RenderSystem::Render(SDL_Renderer* renderer, SDL_Texture* image)
{
SDL_RenderCopy(renderer, image, NULL, NULL);
}
RenderComponent.h
#ifndef RENDER_COMPONENT_H
#define RENDER_COMPONENT_H
#include "Component.h"
#include <SDL2/SDL.h>
class RenderComponent : public Component {
public:
RenderComponent();
~RenderComponent();
SDL_Texture* image;
};
#endif
RenderComponent.cpp
#include "RenderComponent.h"
RenderComponent::RenderComponent(){
name = "render";
}
So that's all I have right now, but I don't know if I'm even doing this right or not. Right now, I don't want to complicate anything, and just want a simple entity (background, player, what-have-you) to draw. Once I have that down, I believe I can implement the rest.
I need some help being guided in the right direction, I know my code might look like utter crap right now, but I'm just learning, so please bear with me. When I try creating an entity in my test program, I tried doing this:
Entity background;
background.AddComponent(new RenderComponent());
SDL_Surface *tmp_image = NULL;
tmp_image = IMG_Load("gfx/background.png");
background.GetComponent("render")->image = SDL_CreateTextureFromSurface(renderer, tmp_image);
But it says that "class Component" has no member named "image". Which is obvious, since it's not declared in the class Component, but in RenderComponent. How do I solve this? Or should I NOT be doing this?
Thanks.
EDIT: Basically what I'm asking is, is that how you correctly add a component? If so, then when I get my component, I want to be able to manipulate it, but it doesn't let me due to the class Component having no member named image. The list of components is an array of Components, which means I can't access the image variable. Also, how are systems supposed to work. I've been googling around and it's somewhat confusing. I feel like I'm doing this completely wrong.