I don’t really have any problems with the way I’m rendering now, but I don’t feel like it’s a very good way of handling rendering. I’m using SDL.
It boils down to this I have some abstract class
class Renderable
With two functions.
virtual void update() = 0;
virtual void doRender(SDL_Surface* surface) = 0;
I have another class
class RenderManager
With 1 std::vector
std::vector<Renderable*> _world;
and 2 std::queue
std::queue<Renderable*> _addQueue;
std::queue<Renderable*> _delQueue;
The two queues hold the renderables that need to be added in the next tick and the ones that need to be removed. Doing everything in one shot gave me problems and now that I think about it, it makes sense (at least the way I did it).
Renderables can add and remove themselves from the RenderManager statically.
Here’s more or less the function handling everything.
void renderAll() {
std::vector<Renderable*>::iterator begin, end;
begin = _world.begin();
end = _world.end();
for (;begin != end; ++begin) {
(*begin)->update();
(*begin)->doRender(_mainWindow); // _mainWindow is the screen of course
}
begin = world.begin();
if (_delQueue.size() > 0) {
for (unsigned int i = 0; i < _delQueue.size(); i++) {
std::vector<Renderable*>::iterator del;
del = std::find(begin, end, _delQueue.front());
if (del != end) {
delete *del;
_world.erase(del);
}
_delQueue.pop();
}
}
if (_addQueue.size() > 0) {
for (unsigned int i = 0; i < _addQueue.size(); i++) {
Renderable* front = _addQueue.front();
// _placement is a property of Renderable calculated by RenderManager
// where they can choose the level they want to be rendered on.
_world.insert(begin + front->_placement, front);
_addQueue.pop();
}
}
}
I’m kinda sorta newish to C++, but I think I know my way around it on an average scale at least. I’m even newer to SDL, but it seems pretty simple and easy to learn. I’m concerned because I have 3 big loops together. I tried one shotting it but I was having problems with _world resizing during the loop causing massive amounts of destruction. But I’m not claiming I did it right! 🙂
I was thinking maybe something involving threads?
EDIT:
Ahh, sorry for the ambiguity. By “cleaner” I mean more efficient. Also there is no “problem” with my approach, I just feel there’s a more efficient way.
Firstly, I’d say don’t fix something which isn’t broken. Are you experiencing performance issues? Unless you’re adding and removing ‘renderables’ in huge quantities every frame, I can’t see a huge problem with what you have. Of course, in terms of an overall application it could be a clumsy design, but you haven’t stated what sort of application this is for, so it’s hard, if not impossible to judge.
However, I can guess and say that because you’re using SDL, there’s a chance you’re developing a game. Personally I’ve always rendered game objects by having a render method for each active object and use an object manager to cycle through pointers to each object every tick and call this render method. Because constantly removing an item from the middle of a vector can cause slowdowns due to internal copying of memory (vectors guarantee contiguous memory), you could have a flag in every object which is set when it is meant to be removed, and periodically the object manager performs ‘garbage collection’, removing all objects with this flag set at the same time, hence reducing the amount of copying that needs to be done. In the mean time before garbage collection occurs, the manager simply ignores the flagged object, not calling its render method each tick – it’s as if it has gone. It’s actually not too dissimilar to what you have here with your queue system, in fact if game objects are derived from your ‘renderable’ class it could be deemed the same.
By the way is there any reason you’re querying the queue sizes before accessing their elements? If size() is 0, the for loops won’t operate anyway.