Are you experiencing performance problems now?
Not yet, it's precisely what I want to avoid.
My class BulletPlacer has this fields:
class BulletPlacer : public sf::Drawable
{
private:
unsigned Amount, Min;
enum Patterns {Circular = 1, Flower, Spiral, Wave }; ///More to come. Each shape has many ways to be shot.
std::vector<Bullet> ShotVec;
std::vector<PolarVector> PolVecV;
TextureHolder& T; ///A reference to my texture container.
BulletTypes B; ///An enum field
Color C; ///Another enum field.
Patterns P; ///By now you can surely guess. ;)
///Control stuff.
Chronometer CT;
sf::Time Tick;
bool first, timecheck, paint;
static bool control;
};
As it can be seen the object is as big as it had bullets. My uses can be from something as simple as 5 bullets to even 500 (could be more, that's just an estimate maximum), it pretty much depends on the bullet patterns I require for my game. This is a sort of "primitive" class that is used by my class spell.
class Spell
{
protected:
Difficulty DifLevel; ///Enum field.
sf::Vector2f XPos;
std::vector<BulletPlacer> BP;
};
Which acts as a base class for FinalSpell and CommonSpell, FinalSpell being complex patterns and CommonSpell working as a smaller type of wrapper for small and repeatable stuff.
I use Polar Vectors for position calculation of spirals, flowers and almost any nice polar function that can be used for my bullet hell shooter, I even use them for linear movement. I calculate everything in polar and then convert to positioning coordinates.
I have the choice of adding another std::vector with common 2D vectors (starting positions of bullets) to my BulletPlacer class.
Under normal circumstances I will have only one FinalSpell instance that gets reused often and a bunch of CommonSpells for easy stuff.
My other choice is to just use my PolarVector convert functions to calculate the 2D start vectors whenever I need them (I don't always need the starting positions) instead of having them there whether I need them or not.
I am fond with the latter. The problem is that it might cause time issues with bigger BulletPlacers that get calculated in run-time(of course I can and will use threads, but I still want to avoid any possible problems). So in the end to pick one is to sacrifice the other. If I go for the memory-saving solution I might get time issues, and if I go for the time-saving solutions I will sometimes have unnecessarily big copies.
Summarized it's a question of Time and Performance vs Efficiency in memory management.
I haven't tested either approach because either would make me go through some serious refactoring in some functions. I want to finish refactoring it once and for all and worry not about having to remake one of the cores of my engine.