digitalmars.D.learn - Need some technical help an object oriented wrapper I am creating for
- thebluepandabear (182/182) Jan 23 2023 Hello everyone 👋, hope everyone is having a good day.
- thebluepandabear (3/5) Jan 23 2023 Btw I understand this question is extremely complex, don't want
- =?UTF-8?Q?Christian_K=c3=b6stlin?= (6/12) Jan 23 2023 I do not know anything about sfml, but could you try a simpler shape,
- thebluepandabear (6/19) Jan 24 2023 thanks for the reply
- beerboy.22 (7/30) Jan 24 2023 As per
- thebluepandabear (13/16) Jan 24 2023 Ur a legend bro...
- matheus (4/5) Jan 26 2023 How you would do that?
- thebluepandabear (4/9) Jan 26 2023 The forums don't have a delete feature. I am used to most forums
Hello everyone 👋, hope everyone is having a good day. Hopefully I am allowed to ask technical questions here, if not please tell me and I will remove this. 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: ```D 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 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.) ```D 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: ```D 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: ```D 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 for days, because I am not getting what I expected to show up on screen :( Any help with this would be greatly appreciated, Regards, thebluepandabear
Jan 23 2023
Regards, thebluepandabearBtw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited...
Jan 23 2023
On 24.01.23 04:59, thebluepandabear wrote:I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, ChristianRegards, thebluepandabearBtw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited...
Jan 23 2023
On Tuesday, 24 January 2023 at 06:32:35 UTC, Christian Köstlin wrote:On 24.01.23 04:59, thebluepandabear wrote:thanks for the reply That also - unfortunately - doesn't seem to work. I would love to see some proper examples for creating shapes but the docs for bind-bc didn't have any :|I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, ChristianRegards, thebluepandabearBtw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited...
Jan 24 2023
On Tuesday, 24 January 2023 at 08:18:53 UTC, thebluepandabear wrote:On Tuesday, 24 January 2023 at 06:32:35 UTC, Christian Köstlin wrote:As per https://www.sfml-dev.org/tutorials/2.5/graphics-shape.php#custom-shape-types:On 24.01.23 04:59, thebluepandabear wrote:thanks for the reply That also - unfortunately - doesn't seem to work. I would love to see some proper examples for creating shapes but the docs for bind-bc didn't have any :|I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, ChristianRegards, thebluepandabearBtw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited...You must also call the update() protected function whenever any point in your shape changes, so that the base class is informed and can update its internal geometry.The example shows calls to `update()` in the setters and in the constructor. The D method for binding this looks like `void sfShape_update(sfShape* shape);`.
Jan 24 2023
The example shows calls to `update()` in the setters and in the constructor. The D method for binding this looks like `void sfShape_update(sfShape* shape);`.Ur a legend bro... It fixed it... Calling this in the `Rectangle` constructor: ```D class RectangleShape : Shape { this(Vector2f size) { _size = size; setSize(_size); ptr.sfShape_update(); } ``` It is my fault on this one. Thank u sir.
Jan 24 2023
On Tuesday, 24 January 2023 at 03:42:34 UTC, thebluepandabear wrote:... if not please tell me and I will remove this...How you would do that? Matheus.
Jan 26 2023
On Thursday, 26 January 2023 at 11:46:07 UTC, matheus wrote:On Tuesday, 24 January 2023 at 03:42:34 UTC, thebluepandabear wrote:The forums don't have a delete feature. I am used to most forums having a delete feature which is why I said that, I now realize I cannot remove posts on This forum.... if not please tell me and I will remove this...How you would do that? Matheus.
Jan 26 2023