Reputation: 298
Here is a problem:
class DrawingsContainer {
public:
std::vector<std::pair<std::string, std::shared_ptr<Drawing>>> getDrawings() { return drawings; }
private:
std::vector<std::pair<std::string, std::shared_ptr<Drawing>>> drawings;
};
I have a variable
std::vector<std::pair<std::string, std::shared_ptr<Drawing>>> drawings
I'm using std::pair
because I need the items I put into the vector to be in the same order I've placed them so std::map
is a no no. (I use this container to draw everything on the screen).
std::string
is there for search purposes.
class Drawing {
public:
// only one can be active, thus both are initialized as nullptr at the start and one type is overwritten on creation
explicit Drawing(
std::string act,
std::unique_ptr<sf::Text> txt = nullptr,
std::unique_ptr<sf::RectangleShape> rectShape = nullptr
) {
active = std::move(act);
text = std::move(txt);
rect = std::move(rectShape);
}
std::string getActive() { return active; }
std::shared_ptr<sf::Text> getText() { return text; }
std::shared_ptr<sf::RectangleShape> getRect() { return rect; }
private:
std::string active;
std::shared_ptr<sf::Text> text;
std::shared_ptr<sf::RectangleShape> rect;
};
I don't feel like this is a good solution, because what if I use more than sf::Text
and sf::RectangleShape
classes in the structure ? feels dirty.
Ideally I would like to have this kind of structure:
[["arena", sf::RectangleShape], ["optionsButton", sf::Text]].
where sf::RectangleShape
and sf::Text
are derivatives of base class sf::Drawable
, of course they have different methods which I need to call.
here is a nice explanation demonstrating the hierarchy (first picture) - https://www.sfml-dev.org/documentation/2.4.2/classsf_1_1Drawable.php
So I'm wondering if there is a better way to do this.
Upvotes: 1
Views: 181
Reputation: 5166
Use typedef to reduce the long ugly typenames. Since there may be only one instance of the drawing container, singleton pattern may be used like so.
struct node_t
{
sf::Text text;
sf::RectangleShape rect;
};
class Drawing {
private:
std::vector<std::shared_ptr<node_t>> tools_;
};
typedef std::vector<std::pair<std::string, std::shared_ptr<Drawing>>> container_t;
class DrawingsContainer {
public:
static const std::unique_ptr<DrawingsContainer>& GetInstance()
{
static std::unique_ptr<DrawingsContainer> ptr(new DrawingsContainer());
return ptr;
}
private:
DrawingsContainer() {}
container_t drawings_;
};
Upvotes: 1
Reputation: 217448
It seems that you can use regular polymorphism:
struct Drawing
{
std::string name;
std::shared_ptr<sf::Drawable> drawable;
};
So
class DrawingsContainer
{
public:
const std::vector<Drawing>& getDrawings() const { return drawings; }
private:
std::vector<Drawing> drawings;
};
Upvotes: 2