Fixing an object oriented wrapper I am creating for bindbc.sfml - sfml

I am trying to create object oriented wrappers around bindbc.sfml, this is because I don't like the C-style syntax of CSFML.
The C-style syntax is not right -- in my opinion -- for an object oriented language. Dealing with pointers all the time is also unsafe.
This is not to say that CSFML isn't good -- it's great, and I've made some apps using bindbc-sfml. I just want to extend it to my liking with object oriented wrappers that can more closely match the C++ SFML syntax.
For the wrappers, I created a Shape class. This Shape class is seen in the original C++ SFML implementation:
class Shape : Transformable, Drawable {
void setTexture(sfTexture* texture, bool resetRect) {
ptr.sfShape_setTexture(texture, resetRect);
}
void setTextureRect(IntRect rect) {
ptr.sfShape_setTextureRect(rect.to_sfIntRect());
}
void setFillColor(Color color) {
ptr.sfShape_setFillColor(color.to_sfColor());
}
void setOutlineColor(Color color) {
ptr.sfShape_setOutlineColor(color.to_sfColor());
}
void setOutlineThickness(float thickness) {
ptr.sfShape_setOutlineThickness(thickness);
}
const(sfTexture)* getTexture() {
return ptr.sfShape_getTexture();
}
IntRect getTextureRect() {
return ptr.sfShape_getTextureRect().toIntRect();
}
Color getFillColor() {
return ptr.sfShape_getFillColor().toColor();
}
Color getOutlineColor() {
return ptr.sfShape_getOutlineColor().toColor();
}
float getOutlineThickness() {
return ptr.sfShape_getOutlineThickness();
}
size_t getPointCount() nothrow {
return ptr.sfShape_getPointCount();
}
Vector2f getPoint(size_t index) nothrow {
return ptr.sfShape_getPoint(index).toVector2f_noThrow();
}
FloatRect getLocalBounds() {
return ptr.sfShape_getLocalBounds().toFloatRect();
}
FloatRect getGlobalBounds() {
return ptr.sfShape_getGlobalBounds().toFloatRect();
}
private sfShape* ptr;
}
The sfShape pointer isn't currently initialized, I'll get to that issue soon.
As you can see, Shape extends the Transformable class and the Drawable interface. This again roughly matches what's seen in SFML. SFML.NET also did a similar wrapper for their CSFML C# bindings. What's great about SFML.NET is that you don't even know that you're using CSFML, this is because it feels just like C++ SFML.
Now, I will create a RectangleShape which will be a subclass of the Shape class:
(Btw I took a lot of inspiration from SFML.NET when it comes to these wrappers.)
class RectangleShape : Shape {
this(Vector2f size) {
_size = size;
setSize(_size);
}
Vector2f getSize() {
return _size;
}
void setSize(Vector2f size) {
_size = size;
}
override {
size_t getPointCount() {
return 4;
}
Vector2f getPoint(size_t index) {
final switch (index) {
case 0:
return Vector2f(0, 0);
case 1:
return Vector2f(_size.x, 0);
case 2:
return Vector2f(_size.x, _size.y);
case 3:
return Vector2f(0, _size.y);
}
}
}
private Vector2f _size;
}
As you can see, the Rectangle class only overrides the getPointCount and getPoint methods.
These are the methods that the superclass - Shape - will use to construct the shape object for it to actually be drawable.
Now, let us add the following code to the Shape class so that we can construct a Shape via these two methods, which we assume that the child provides us a good implementation for:
class Shape : Transformable, Drawable {
this() {
ptr = sfShape_create(&getPointCount, &getPoint, cast(void*)this);
}
extern(C) private static ulong getPointCount(void* data) nothrow {
return (cast(Shape)data).getPointCount();
}
extern(C) private static sfVector2f getPoint(size_t index, void* data) nothrow {
return (cast(Shape)data).getPoint(index).to_sfVector2f_noThrow();
}
I hear you asking, what's going on here?
We are providing two callbacks to the getPointCount and getPoint methods via function pointers, and we're passing in the current object to the data void* pointer. It's kind of hard to understand, but if you read through it carefully you should get a rough idea of what's going on.
Now, when we create a new instance of Rectangle, I will assume that the constructor will be called, the sf_shape ptr will be initialized correctly (as it will be utilizing the crucial getPoint and getPointCount methods) and everything will be OK.
This is the following test code I had:
void main() {
loadSFML();
RectangleShape rectangleShape = new RectangleShape(Vector2f(50, 50));
rectangleShape.setPosition(Vector2f(50, 50));
rectangleShape.setFillColor(Color.Blue);
RenderWindow renderWindow = new RenderWindow(sfVideoMode(500, 500), "Tests", sfWindowStyle.sfDefaultStyle, null);
sfEvent event;
while (renderWindow.isOpen()) {
while (renderWindow.pollEvent(&event)) {
if (event.type == sfEventType.sfEvtClosed) {
renderWindow.close();
}
}
renderWindow.clear(Color.Yellow);
renderWindow.ptr.sfRenderWindow_drawShape(rectangleShape.ptr, null);
renderWindow.display();
}
}
I would read through this line by line to get a good idea of what's going on.
Really, for demonstration purposes, we're using the renderWindow's ptr variable for drawing. When I can get this to work I will create wrapper functions so that it's nicer to use, but for now it's not important.
What I'd expect to pop up on screen is a 50x50 rectangle, filled with a blue color, at the position 50x50 on the screen.
Upon running the application, I don't see anything -- it's just a yellow screen.
I am very confused why this is the case, it seems like I've done everything fine, but I've obviously made a mistake somewhere in my implementation. I don't know specifically if it's an issue on my end, or a bug in bindbc-sfml, but this issue has infuriated me, because I am not getting what I expected to show up on screen.

Fixed it by calling sfShape_update here:
class RectangleShape : Shape {
this(Vector2f size) {
_size = size;
setSize(_size);
ptr.sfShape_update();
}

Related

OOP in C++. How to drop the states

I am writing a simple graphics editor.
There are 3 buttons on the panel, by pressing which I draw a square, circle or line.
There are 3 button handlers that change the state and 3 mouse event handlers in the class responsible for drawing the workspace.
void Cpr111View::OnCirc()
{
state = 1;
}
void Cpr111View::OnLine()
{
state = 2;
}
void Cpr111View::OnRect()
{
state = 3;
}
To shorten the question, I will give only one handler out of 3.
void Cpr111View::OnMouseMove(UINT nFlags, CPoint point)
{
if (state==2)
{
int oldmode;
CClientDC *pDC = new CClientDC(this);
if (nFlags && MK_LBUTTON)
{
oldmode = pDC->GetROP2();
pDC->SetROP2(R2_NOT);
pDC->MoveTo(begin.x, begin.y);
pDC->LineTo(oldmouse.x, oldmouse.y);
pDC->MoveTo(begin.x, begin.y);
pDC->LineTo(point.x, point.y);
oldmouse = point;
pDC->SetROP2(oldmode);
CView::OnMouseMove(nFlags, point);
}
}
if (state == 1)
{
….
}
if (state == 3)
{
….
}
void Cpr111View::OnLButtonUp(UINT nFlags, CPoint point)
{
}
void Cpr111View::OnLButtonDown(UINT nFlags, CPoint point)
{
}
Here is a drawing system.
I want to do it without states. That is, create an abstract class Figure. With three virtual methods per render:
Class Figure
{
public:
void virtual MouseMove()=0;
void virtual ButtonUp()=0;
void virtual ButtonDown()=0;
}
And from him in the classes of figures to override these methods.
Class Recatngle:public Figure
{
public:
void MouceMove() override;
...
}
Then, when the button is clicked, create an object of the corresponding class, then the button handler will look like this:
void Cpr111View::OnRect()
{
figure = new Rectangle();
}
And when drawing, the mouse handler will simply call the method of the corresponding class:
void Cpr111View::OnMouseMove(UINT nFlags, CPoint point)
{
figure - > MouseMove();
}
In order for figure to be available in two different methods, we declare it in the class:
class Cpr111View : public CView
{
public:
Figure figure;
…
}
This is how I want to do it, but the problem is that it can't be done that way. At a minimum, you cannot declare an abstract class variable. Then what type should it be if I am going to write a pointer to different classes into it? How to implement this architecture correctly, or maybe there are better ideas?
Using this way of polymorphic calls in C++ requires to use reference sematics.
I advise to read about it. E.g.: Reference and Value Semantics
So it class Cpr111View, you have to keep your Figure member by pointer, or by refernce.
In order to avoid having to manually manage the object, you should use a smart pointer like std::unique_ptr (or std::shared_ptr if you need to share ownership):
#include <memory> // for std::unique_ptr
class Cpr111View : public CView
{
public:
std::unique_ptr<Figure> figure;
//…
}
Of course you will need to allocate it before using it.
Instead of:
figure = new Rectangle();
use:
figure = std::make_unique<Rectangle>();
The method calls stay the same as in your code, e.g.:
figure->MouseMove();
If you not familiar with smart pointers in C++, I recomend to read about it. E.g.: What is a smart pointer and when should I use one?.

Wrong element is removed after leaving method which used std::erase succesfully

I am working on a graphics engine. The engine has a std::vector of drawables. A Drawable is an object which contains a Model and a DrawableObject, which in turn holds a shader program and a bunch vertices from a 2D or 3D model. Adding new Drawables goes well, the problem occurs when I try to remove a Drawable. The last Drawable will always be removed and the second to last will have its values changed.
Code
Drawable.h
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
Drawable tmp(other);
std::swap(model, other.model);
std::swap(drawableObject, other.drawableObject);
return *this;
}
Drawable(domain::Model& model, DrawableObject& drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model& model;
DrawableObject& drawableObject;
};
game.cpp
void Game::init_game()
{
human = domain::Model(glm::vec3(0, 0, -3));
moveables.push_back(&human);
room = domain::Model(glm::vec3(0, 0, -10));
props.push_back(&room);
cube = domain::Model(glm::vec3(0, 0, 0));
props.push_back(&cube);
}
void Game::init_graphics_engine()
{
// ... load graphics models
// add drawables
graphicsEngine->add(cube, Drawable::CUBE);
graphicsEngine->add(human, Drawable::HUMAN);
graphicsEngine->add(room, Drawable::ROOM);
graphicsEngine->add(topDownScene->cursor, Drawable::MARKER);
}
graphics_engine/engine.cpp
void Engine::add(domain::Model& model, unsigned int object)
{
auto drawableObject = drawableObjects[object];
// make sure not to add a model that already is represented
auto it = std::find_if(drawables.begin(), drawables.end(), [&model](Drawable& drawable) {return &drawable.model == &model;});
if(drawableObject && it == drawables.end())
drawables.push_back(Drawable(model, *drawableObject));
}
void Engine::remove(domain::Model& model)
{
auto predicate = [&model](Drawable& drawable)
{
return &drawable.model == &model;
};
drawables.erase(std::remove_if(drawables.begin(), drawables.end(), predicate), drawables.end());
}
Scenes
This is what the scene looks like when I start the application:
This is what the scene looks like after attempting to erase the small 'human' cube in the middle:
The code removes the last Drawable, which is the white marker, instead of the 'human' cube, and changed the z position of the room. This almost always happens, it removes the last element and changed the z of the second to last. It only works if I add the 'human' cube last in the init method.
Breakpoints
Before removing the object:
After removing the object:
This is correct.
Leaving the remove method and taking a look in the render loop:
Somehow changed.
I changed the class members to pointers. Now it works. The comments were right, I didn't do anything with the tmp variable.
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
this->model = other.model;
this->drawableObject = other.drawableObject;
return *this;
}
Drawable(domain::Model* model, std::shared_ptr<DrawableObject> drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model* model;
std::shared_ptr<DrawableObject> drawableObject;
};

How to pass arguments to draw() method - FLTK

I´m new to FLTK and currently facing the following problem:
I have a class PointModel, which stores points with x- and y-coordinates, a class View, which needs to call update(), everytime the coordinates in the PointModel change (Observer Pattern) and draw them and finally a class MyBox, where the coordinates should be drawn in.
View is derived from Fl_Window. MyBox is derived from Fl_Box and part of View.
Therefore I need to know, how to pass the point coordinates from a member function (void update()) of View to the draw method of MyBox.
I´m trying to typecast the user_data pointer I get to View* in case to be able to get the PointModel, holding the point coordinates. But the window closes after calling the draw() method.
Maybe I only get a NULL-Pointer here? Unfortunately I can´t check it through debugging, because somehow Eclipse doesn´t break at the breakpoints now..
Any solutions, hints what I´m doing wrong or possible alternatives?
Thanks in advance!
Here some pieces of my code:
View.cpp:
class MyBox : public Fl_Box {
void draw() {
Fl_Box::draw();
View *v1 = (View*)this->parent();
if(v1 != NULL) {
int lastX = v1->getPointModel()->getLastX();
int lastY = v1->getPointModel()->getLastY();
int currentX = v1->getPointModel()->getCurrentX();
int currentY = v1->getPointModel()->getCurrentY();
fl_color(FL_WHITE);
fl_line(lastX, lastY, currentX, currentY);
}
}
public:
MyBox(int X,int Y,int W,int H,const char*L=0) : Fl_Box(X,Y,W,H,L) {
box(FL_FLAT_BOX);
}
};
View::View(*arguments*) :Fl_Window(540,650,"View1") {
begin();
MyBox box(20,20,500,500," ");
box.box(FL_UP_BOX);
box.color(0x00000000);
//more widgets
end();
show();
Fl::add_timeout(3.0, Timer_CB, (void*)this);
Fl::run();
}
edit: I updated the code to running version
Well, MyBox.draw() will be called before you call add_timeout(). user_data() will give you NULL most likely... You could add a check for NULL in there. Something like:
void draw() {
Fl_Box::draw();
void* ptr = user_data();
if (ptr) {
// do stuff here...
}
Second possible problem is this->parent()->user_data(); . Parent of your MyBox object is the Fl_Window object (actually, your View object, which is a Fl_Window), and user_data() will always return NULL for it I think...
The easiest way to pass any object to your widget is to use user_data() method:
box.user_data(&myview); // after this box.user_data() will return a View*

Why's my vector element all garbage?

I have a GameLobby class that keeps a list of the currently active games. I want to fetch the active games from a GameLobby (singleton) object, and display these to the user.
(Disclaimer: I'm pretty new to C++, so the following code isn't exactly stellar. Neither is it the complete code, but I feel confident that all the relevant instructions have been included.)
First some definitions
class GamesMenu : public MyGameLayer
{
private:
std::vector<Game*>* _activeGames;
void displayGamesList();
void refreshGamesList();
};
and
class MyGameLayer : public cocos2d::CCLayer
{
private:
GameLobby* _gameLobby;
public:
GameLobby* getGameLobby();
};
and
GameLobby* MyGameLayer::getGameLobby()
{
return _gameLobby;
}
Now to the problem at hand. I want to execute GamesMenu::refreshGamesList() which looks like this:
void GamesMenu::refreshGamesList()
{
GameLobby* gameLobby = getGameLobby();
if (gameLobby) {
_activeGames = gameLobby->getActiveGames();
Game* game = _activeGames->at(0); // For debug purposes only - this game is NOT garbage
}
displayGamesList();
}
where
std::vector<Game*>* GameLobby::getActiveGames()
{
if (_loggedInPlayer) {
refreshActiveGames(_loggedInPlayer->GetPlayerToken());
} else {
refreshActiveGames("");
}
return &_activeGames;
};
and std::vector<Game*> _activeGames is a private member of GameLobby.
However, when execution hits displayGamesList(), things get pretty bad
void GamesMenu::displayGamesList()
{
for (unsigned i = 0; i < _activeGames->size(); i++) {
Game* game = _activeGames->at(i); // The contents of game is garbage. Why?
std::string opponentName = game->GetOpponentName(); // This I don't even want to talk about
};
/* Supressed drawing stuff */
}
When I inspect game in GamesMenu::refreshGamesList, the contents of game seems fine. When I inspect game in GamesMenu::displayGamesList, the contents is all garbage. It is as if the elements of the vector points to the wrong data or something.
Can anyone please help me untangle myself out of this mess? Thanks! :)

Adding virtual functions without modifying the original classes

Let's say we already have a hierarchy of classes, e.g.
class Shape { virtual void get_area() = 0; };
class Square : Shape { ... };
class Circle : Shape { ... };
etc.
Now let's say that I want to (effectively) add a virtual draw() = 0 method to Shape with appropriate definitions in each sub-class. However, let's say I want to do this without modifying those classes (as they are part of a library that I don't want to change).
What would be the best way to go about this?
Whether or not I actually "add" a virtual method or not is not important, I just want polymorphic behaviour given an array of pointers.
My first thought would be to do this:
class IDrawable { virtual void draw() = 0; };
class DrawableSquare : Square, IDrawable { void draw() { ... } };
class DrawableCircle : Circle, IDrawable { void draw() { ... } };
and then just replace all creations of Squares and Circles with DrawableSquares and DrawableCircles, respectively.
Is that the best way to accomplish this, or is there something better (preferably something that leaves the creation of Squares and Circles intact).
Thanks in advance.
(I do propose a solution down further... bear with me...)
One way to (almost) solve your problem is to use a Visitor design pattern. Something like this:
class DrawVisitor
{
public:
void draw(const Shape &shape); // dispatches to correct private method
private:
void visitSquare(const Square &square);
void visitCircle(const Circle &circle);
};
Then instead of this:
Shape &shape = getShape(); // returns some Shape subclass
shape.draw(); // virtual method
You would do:
DrawVisitor dv;
Shape &shape = getShape();
dv.draw(shape);
Normally in a Visitor pattern you would implement the draw method like this:
DrawVisitor::draw(const Shape &shape)
{
shape.accept(*this);
}
But that only works if the Shape hierarchy was designed to be visited: each subclass implements the virtual method accept by calling the appropriate visitXxxx method on the Visitor. Most likely it was not designed for that.
Without being able to modify the class hierarchy to add a virtual accept method to Shape (and all subclasses), you need some other way to dispatch to the correct draw method. One naieve approach is this:
DrawVisitor::draw(const Shape &shape)
{
if (const Square *pSquare = dynamic_cast<const Square *>(&shape))
{
visitSquare(*pSquare);
}
else if (const Circle *pCircle = dynamic_cast<const Circle *>(&shape))
{
visitCircle(*pCircle);
}
// etc.
}
That will work, but there is a performance hit to using dynamic_cast that way. If you can afford that hit, it is a straightforward approach that is easy to understand, debug, maintain, etc.
Suppose there was an enumeration of all shape types:
enum ShapeId { SQUARE, CIRCLE, ... };
and there was a virtual method ShapeId Shape::getId() const = 0; that each subclass would override to return its ShapeId. Then you could do your dispatch using a massive switch statement instead of the if-elsif-elsif of dynamic_casts. Or perhaps instead of a switch use a hashtable. The best case scenario is to put this mapping function in one place, so that you can define multiple visitors without having to repeat the mapping logic each time.
So you probably don't have a getid() method either. Too bad. What's another way to get an ID that is unique for each type of object? RTTI. This is not necessarily elegant or foolproof, but you can create a hashtable of type_info pointers. You can build this hashtable in some initialization code or build it dynamically (or both).
DrawVisitor::init() // static method or ctor
{
typeMap_[&typeid(Square)] = &visitSquare;
typeMap_[&typeid(Circle)] = &visitCircle;
// etc.
}
DrawVisitor::draw(const Shape &shape)
{
type_info *ti = typeid(shape);
typedef void (DrawVisitor::*VisitFun)(const Shape &shape);
VisitFun visit = 0; // or default draw method?
TypeMap::iterator iter = typeMap_.find(ti);
if (iter != typeMap_.end())
{
visit = iter->second;
}
else if (const Square *pSquare = dynamic_cast<const Square *>(&shape))
{
visit = typeMap_[ti] = &visitSquare;
}
else if (const Circle *pCircle = dynamic_cast<const Circle *>(&shape))
{
visit = typeMap_[ti] = &visitCircle;
}
// etc.
if (visit)
{
// will have to do static_cast<> inside the function
((*this).*(visit))(shape);
}
}
Might be some bugs/syntax errors in there, I haven't tried compiling this example. I have done something like this before -- the technique works. I'm not sure if you might run into problems with shared libraries though.
One last thing I'll add: regardless of how you decide to do the dispatch, it probably makes sense to make a visitor base class:
class ShapeVisitor
{
public:
void visit(const Shape &shape); // not virtual
private:
virtual void visitSquare(const Square &square) = 0;
virtual void visitCircle(const Circle &circle) = 0;
};
What you're describing is somewhat like the decorator pattern. Which is very suitable to change runtime behaviour of existing classes.
But I don't really see how to implement your practical example, if shapes have no way to be drawn, then there's no way to change drawing behaviour at runtime either...
But I suppose this is just a very simplified example for stackoverflow? If all the basic building blocks for the desired functionality are available, then implementing the exact runtime behaviour with such a pattern is certainly a decent option.
One 'off the wall' solution you might like to consider, depending on the circumstance, is to use templates to give you compile time polymorphic behaviour. Before you say anything, I know that this will not give you traditional runtime polymorphism so it may well not be useful but depending on the limitations of the environment in which you're working, it can prove useful:
#include <iostream>
using namespace std;
// This bit's a bit like your library.
struct Square{};
struct Circle{};
struct AShape{};
// and this is your extra stuff.
template < class T >
class Drawable { public: void draw() const { cout << "General Shape" << endl; } };
template <> void Drawable< Square >::draw() const { cout << "Square!" << endl; };
template <> void Drawable< Circle >::draw() const { cout << "Circle!" << endl; };
template < class T >
void drawIt( const T& obj )
{
obj.draw();
}
int main( int argc, char* argv[] )
{
Drawable<Square> a;
Drawable<Circle> b;
Drawable<AShape> c;
a.draw(); // prints "Square!"
b.draw(); // prints "Circle!"
c.draw(); // prints "General Shape" as there's no specific specialisation for an Drawable< AShape >
drawIt(a); // prints "Square!"
drawIt(b); // prints "Circle!"
drawIt(c); // prints "General Shape" as there's no specific specialisation for an Drawable< AShape >
}
The drawIt() method is probably the key thing here as it represents generic behaviour for any class meeting the requirement of having a draw() method. Do watch out for code bloat here though as the compiler will instantiate a separate method for each type passed.
This can be useful in situations where you need to write one function to work on many types which have no common base class. I'm aware that this is not the question you asked, but I thought I'd throw it just as an alternative.