Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Python binding generation tools  (Read 29772 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Python binding generation tools
« Reply #15 on: November 05, 2010, 03:38:37 pm »
I totally agree, this looks like a hack rather than a clean solution.
Laurent Gomila - SFML developer

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #16 on: November 06, 2010, 06:03:28 am »
I have a question about managing C++ instances returned by SFML methods.

For example, I wrap the C++ View returned by RenderWindow.GetDefaultView() in Python instance.
At first I deleted systematically the C++ instance in the Python destructor. But I got runtime errors, presumably because SFML deletes the default view as well.
So I added a “delete_this“ flag which tells whether the C++ instance should be deleted in the Python wrapper code or not, and when I wrap the default view I set this flag to False.

I would like to know if I can safely use this pattern every time SFML returns an object? When I played around with SFML in C++ I didn't really bother about memory management. :roll:
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Python binding generation tools
« Reply #17 on: November 06, 2010, 10:07:58 am »
Indeed, you need to make a difference between objects owned by Python and objects owned by SFML. But this is not easy, you need to study carefully every function that takes or return a SFML object to know that.

Of course I can help you if you need help :)
Laurent Gomila - SFML developer

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #18 on: November 06, 2010, 06:48:09 pm »
I think I just found the solution to a bug I've been looking into for hours.
It boils down to the fact that this code prints two different addresses:

Code: [Select]
sf::View view = window.GetDefaultView();
std::cout << &view << ", " << &window.GetDefaultView() << '\n';


Is this a C++ feature or it's a custom behavior?
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Python binding generation tools
« Reply #19 on: November 06, 2010, 06:52:41 pm »
Quote from: "bastien"
I think I just found the solution to a bug I've been looking into for hours.
It boils down to the fact that this code prints two different addresses:

Code: [Select]
sf::View view = window.GetDefaultView();
std::cout << &view << ", " << &window.GetDefaultView() << '\n';


Is this a C++ feature or it's a custom behavior?


It's very basic.

window.GetDefaultView() returns a reference to the default view instance. But the variable is not declared as a reference so it will copy the instance over to the view variable. So you are actually looking at two different instances. To declare the view variable as a reference variable you'll have to write:
Code: [Select]
sf::View &view = window.GetDefaultView();
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #20 on: November 06, 2010, 07:56:55 pm »
OK, I just realized Cython supports references creation. I added some more classes and methods, here is what the example looks like currently:

Code: [Select]
import sf


def main():
    window = sf.RenderWindow(sf.VideoMode(640, 480), 'Example')
    window.framerate_limit = 10
    image = sf.Image()
    image.load_from_file('python-logo.png')
    sprite = sf.Sprite()
    sprite.image = image
    running = True

    while running:
        for event in window.iter_events():
            if event.type == sf.EVT_CLOSED:
                running = False

        window.clear(sf.Color(255, 255, 255))
        window.draw(sprite)
        window.display()

    window.close()

if __name__ == '__main__':
    main()


You can get a view of the current API here: http://bastien-leonard.alwaysdata.net/doc/index.html
(A lot is missing and there are probably still bugs)
Do you you think I should keep constants this way or place them in namespaces like SFML does?
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Python binding generation tools
« Reply #21 on: November 06, 2010, 08:38:14 pm »
On the ruby bindings, I'm going for copying after SFML exactly and then make it more "Ruby" like.

But yeah, that style is more actually like C if you have EVT_CLOSED. Something like sf.Event.Closed would be better I think. you can have public static constants in classes on Python right?
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Kaoron

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Python binding generation tools
« Reply #22 on: November 07, 2010, 09:01:17 am »
Quote from: "bastien"
Do you you think I should keep constants this way or place them in namespaces like SFML does?


Code: [Select]
python -c "import this" | tail -n 1  :D

Also, what about renaming the module to pysfml ? I never liked the ugly PySFML.sf import, ans as we have import aliases in python, there's no need to abbreviate it's name to sf.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Python binding generation tools
« Reply #23 on: November 07, 2010, 10:26:07 am »
Quote
Also, what about renaming the module to pysfml ? I never liked the ugly PySFML.sf import, ans as we have import aliases in python, there's no need to abbreviate it's name to sf.

+1
Laurent Gomila - SFML developer

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #24 on: February 08, 2011, 08:38:40 am »
Quote from: "Kaoron"
Also, what about renaming the module to pysfml ? I never liked the ugly PySFML.sf import, ans as we have import aliases in python, there's no need to abbreviate it's name to sf.


I don't like this way of importing either, but I thought sf.so could simply be dropped in site-libs/ so that you just need to type “import sf”.

I just use the sf namespace so that it's the same as SFML, and because it's three times shorter to type. Someone who's used to to PySFML can easily rename it with “import sf as pysfml” anyway.
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #25 on: February 08, 2011, 09:15:41 am »
I started working on this project again and just cleaned up some code. My memory is a bit blurry about what was going on so I'd like to get your input about the development.

This is just a test for SFML 1.6. Personally I don't plan to learn SFML 2 before an official release, but at the same time this is just a basic proof of concept so it probably won't be too much of a hassle to port it.
Also I guess some people will disagree with the conventions I use (e.g. with properties instead of get/set methods). Personally I just started this as a personal project so I don't bother about it too much, but if the official binding is ever written with Cython we'll need to agree on the convention. ;)

The source is here: https://bitbucket.org/bastienleonard/pysfml-cython
The current generated documentation can be found here: http://bastien-leonard.alwaysdata.net/doc/index.html

As I said earlier, I don't have any former experience for writing native modules, so it's possible that the way I'm doing things is totally crappy.  :roll:

In the most simple case, I just write a class with a p_this attribute which points to the C++ instance. __cinit__() creates the C++ object, __dealloc__() (destructor) deletes it.

If I need to wrap C++ objects into Python objects arbitrarily, I add a boolean delete_this attribute in the class, which tells __dealloc__() whether or not it should delete the C++ object.
For example, RenderWindow.GetDefaultView() returns a view that doesn't need to be freed, so delete_this must be set to False.
I also need to bypass the default contructor, so I call View.__new__(View) instead.
Previously I did this sort of stuff anywhere needed in the code, but it was error-prone, so now I write wrap_Xxx_instance() functions that do this kind of work. They automatically set delete_this to False, which means that at least we won't get a segmentation fault or similar, but maybe the C++ object won't be freed because SFML didn't free it either. Looking at the code right now I can't tell if it's a problem or not.

For the events union, there's a single attribute in Event containing the “detailed” event (e.g. KeyEvent). It's never used directly by the user, instead he uses properties like key or mouse_move that check that the event parameter is of the right type and raise an exception otherwise. It's probably a bit slower but it will save some bugs (Python programmers won't necessarily directly realize the implications of the C++ attribute being a union).

I guess the next step is to write class/static methods e.g. for loading images instead of creating dummy objects just to initialize them with another method.
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #26 on: February 18, 2011, 08:58:54 am »
I've started working on SFML 2: https://bitbucket.org/bastienleonard/pysfml2-cython
I think most classes are there. I'll probably add Unicode support next, then shaders and audio.
There's a lot of stuff in SFML that I never use, so I'm far from having tested everything.
Some stuff could probably rewritten to be faster, but I wait to get feedback on that as it would generally make the code more complicated or dangerous.

I haven't written any doc yet, I'm waiting until the module is more or less complete.

One problem that I have is that I can't raise any specific exception. For example, if a file can't be loaded, there's no way to know if it's a problem of finding the file or format.
I understand that Laurent doesn't want to use exceptions, but why not use something like errno?
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Python binding generation tools
« Reply #27 on: February 18, 2011, 09:15:04 am »
Quote
One problem that I have is that I can't raise any specific exception. For example, if a file can't be loaded, there's no way to know if it's a problem of finding the file or format.
I understand that Laurent doesn't want to use exceptions, but why not use something like errno?

Because I want to keep things simple.
At coding-time, all you need to know is whether loading succeeded or failed, so a boolean is enough.
At run-time, all you need to know is the reason why it failed, so the error message is enough.

Following this strategy, ou can simply throw a LoadingFailed exception (like I do in SFML.Net), the only drawback is that you can't retrieve the error message into the exception -- at least not easily.
Laurent Gomila - SFML developer

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Python binding generation tools
« Reply #28 on: February 19, 2011, 10:54:08 am »
It's enough for the developer, but do you expect the end-user to execute the game in a console?
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Python binding generation tools
« Reply #29 on: February 19, 2011, 01:53:33 pm »
No he don't, he put it in here: http://www.sfml-dev.org/documentation/2.0/group__system.htm#ga7923f09b85dfb1346b09f58e2eef48f0
for you to retrieve ;)

Anyway, why do you need to throw an exception? I ignored that part in rbSFML and just kept with returning true or false. Though now I think about it, I forgot to wrap sf::Err.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

 

anything