SFML community forums

Bindings - other languages => Python => Topic started by: bastien on November 04, 2010, 05:59:52 pm

Title: Python binding generation tools
Post by: bastien on November 04, 2010, 05:59:52 pm
We were having a discussion about what tool we should use for the next Python binding: http://www.sfml-dev.org/forum/viewtopic.php?t=3451
Since this discussion is off-topic, I felt it would be better to create a new topic.

So I've played with Cython and made the hello world example work for 1.6, all the code is here with the example:https://bitbucket.org/bastienleonard/pysfml-cython/src

So basically it involves writing declarations for all the SFML methods and attributes, and then you write the wrapper classes in a language similar to Python. It should be pretty fast since it compiles to pure C++ code, and you can customize the wrappers in any way you want since you write them yourself. I guess the downside is that you need to write all this code, but it's fairly compact and I guess that fully automated generation wouldn't allow to tweak the end result as easily.
Title: Python binding generation tools
Post by: Laurent on November 04, 2010, 07:34:36 pm
Looks good. I like the idea of being able to fully customize the resulting API.

Have you made some performance tests?
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 12:15:56 am
Quote from: "Laurent"
Looks good. I like the idea of being able to fully customize the resulting API.

Have you made some performance tests?


No, I can't display anything except text currently, and I'd rather let Tank test it first, since he also tested SWIG and others.
Title: Python binding generation tools
Post by: Tank on November 05, 2010, 01:24:36 am
Interesting, looks very good so far. Didn't know Cython (god, it's hard as hell to write that, or is it only me?) is able to do such things.

However there's one thing I'm skeptical about, which isn't really related to Cython but a Python naming convention that's being discussed about a lot: Properties. The claim of many Python programmers is that public attributes and getters and setters are pure evil. Public attributes mostly are evil because of side-effects or wrong usage, but getters and setters are only annoying to write and bloat up the code. Python's properties circumvent that "problem" by giving the developer the possibility to firstly create public properties and encapsulate those into getters and setters later without breaking the public API.

To be honest, I think that's a very bad idea, since assignments are treated similar in most programming languages: When I do "a = 5", I expect that 5 is in a, and when I do "person.firstname = 'john'", I expect the same. But a developer may decide that all firstnames must be capitalized, so they throw in a property and define a setter which capitalizes the new value. So when I do "person.firstname = 'john'", it ends up being "John". In my opinion this can lead to critical and hard to find bugs and may also cause confusion.

To summarize: At a first glance Cython looks very promising and I think we should prepare a binding for SFML 1.6 that's able to open an sf::RenderWindow, load an sf::Image to use in an sf::Sprite to be able to benchmark and compare it with the other two working options (Python C API and Boost.Python). On the other hand we need to discuss about conventions. :)

Thanks for pointing it out, bastien.


Edit: Ah, I forgot to answer the SWIG thing: My SWIG binding builds but is NOT working because of a threading issue I can't really localize. Honestly I'd prefer other code generators over SWIG if we decided to use one to purely wrap C++ classes and methods (for example with pybindgen). But I think Cython is a cool and flexible approach here, we just have to make sure that speed won't be an issue; unfortunately this has been a show-stopper for at least one great option, namely Boost.Python.
Edit²: Here are my pybindgen results so far: https://github.com/TankOs/SFML2/tree/pybindgen . Keep in mind it's mostly a wrapper generator, not as flexible as Cython. I put it in here just for the case of interest. ;)
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 02:04:10 am
About getters/setters:
A public attribute isn't wrong, because you can make it a property later if needed. But in our case we can't use them anyway, since we want to map attribute access to methods calls.

Personally I became a huge fan of properties after using GUI toolkits with code like:
Code: [Select]
window.title = 'Title'
window.width = 640


instead of:

Code: [Select]
window.set_title('Title')
window.set_width(640)


Here you really don't care whether title and width are real attributes or their access needs to execute some code, you precisely use a GUI toolkit to abstract this kind of stuff and their retrieval is probably nearly as costly as a direct attribute access.

So in my opinion we should use properties every time the user doesn't care how the value is used internally and simply wants to able to get and set it. Normally all SFML get/set methods are used in this way.
We should avoid creating properties that a) have a non-obvious behavior or b) have an expensive behavior (because the user expects attribute access to be fast).

It does raise some questions though. For example, sf::RenderWindow has getWidth(), getHeight() and setSize(). It seems inconsistent to me, but it didn't seem to be a problem in C++.
However, in Python, as long as width and height are properties, I feel I should write setters as well as it's much more intuitive. And width should probably be available as well since the C++ documentation will probably be used by most PySFML users and they will expect an equivalent for it. But it's totally redundant, and it's not a property. (Although we could make it a property if we pass a single argument, i.e. a tuple.)
Title: Python binding generation tools
Post by: Tank on November 05, 2010, 03:40:03 am
Like I said, most developers expect a copy only when writing an assignment. I would not expect that an assignment does anything else than assigning value a to value b, and Python properties may do it differently. There're even cases when it's dangerous, because assignments (better: the underlying setter of the property) may throw an exception and I bet not many users would expect that.

What happens when I do the following?
Code: [Select]
window.width = -1

The pure possibility to write such code propagates that it's possible to directly modify member data, however this is not true because internally the assignment is redirected to a setter method. But how would I, as the user, know that? When using literals like above, I may recognize the dumb stuff I wrote ;), but you don't always have literals, so the assignment may throw an exception, for example, because width = -1 is invalid. Personally I would not surround assignments with exception handling, it's just weird.

Another point is one you already mentioned: SFML API compliance. I fully agree with that a Python binding for any library should be as much Pythonish as possible, but I've never touched properties often in the past and I guess it's not a very well-known and used convention. More importantly things like Python lists, tuples, dicts, yielding etc. should be used to accomplish a Python-like binding style. However, in my opinion the best solution would be to stick to the original SFML API as close as possible, without moving too much to the C++ side.
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 04:31:44 am
Quote from: "Tank"
What happens when I do the following?
Code: [Select]
window.width = -1


Why would you do this if -1 is invalid? Python isn't a language where you try to forbid your users from doing anything potentially wrong, e.g. there is no private attribute. It's part of the design of the language.

Quote from: "Tank"
The pure possibility to write such code propagates that it's possible to directly modify member data, however this is not true because internally the assignment is redirected to a setter method.


As I said, setters should be semantically similar to attribute writing, i.e. it should just quickly change the state of the object without doing anything long or non-obvious.

Quote from: "Tank"
But how would I, as the user, know that? When using literals like above, I may recognize the dumb stuff I wrote ;), but you don't always have literals, so the assignment may throw an exception, for example, because width = -1 is invalid. Personally I would not surround assignments with exception handling, it's just weird.


How is that different from set_width()? In both cases you can get problems by setting invalid values. What would help you in this case is that the API throws an exception with a helpful message.

Quote from: "Tank"
Another point is one you already mentioned: SFML API compliance. I fully agree with that a Python binding for any library should be as much Pythonish as possible, but I've never touched properties often in the past and I guess it's not a very well-known and used convention. More importantly things like Python lists, tuples, dicts, yielding etc. should be used to accomplish a Python-like binding style. However, in my opinion the best solution would be to stick to the original SFML API as close as possible, without moving too much to the C++ side.


It's not used everywhere because it's quite recent (2.5 I think). For example, the threading module uses properties, although it uses Java conventions (which don't include properties, since Java doesn't support them). wxPython and PyGTK also use properties.
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 05:05:25 am
Now supports basic sprites:
(http://imgur.com/wLDoss.jpg) (http://i.imgur.com/wLDos.png)

By the way, I'm not sure what is best for constants like sf::Style::Fullscreen.
Currently I just define top-level values like STYLE_FULLSCREEN. It could be placed inside a dummy class sf.Style as well.
Title: Python binding generation tools
Post by: Kaoron on November 05, 2010, 08:16:06 am
Quote
But how would I, as the user, know that?

Try. Fail. Accept the new convention. ???. Profit.

Edit : One thing I've been stuck onto with cython is wrapping existing C++ instances (like one returned by a function/method). bastien, did you try to implement a method such as VideoMode::GetMode ?

Edit : Oh, and - care : your indentation is done with 5 spaces instead of 4. Baaad. :P
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 10:32:52 am
Quote from: "Kaoron"
Edit : One thing I've been stuck onto with cython is wrapping existing C++ instances (like one returned by a function/method). bastien, did you try to implement a method such as VideoMode::GetMode ?


I guess an ugly way to do it would be to create a dummy Python instance, delete its C++ instance and replace it with the one returned by GetMode(). There's probably a better way, but I don't know enough about the C API and how Cython interacts with it to do something more clever.
But currently I can't get to call GetMode(), I thought I'd declare it this way, since static methods apparently aren't directly supported:

Code: [Select]
cdef extern from "SFML/Graphics.hpp" namespace "sf::VideoMode":
    VideoMode GetMode(unsigned long Index)


But I get “Function argument cannot have C name specification”.

Quote from: "Kaoron"
Edit : Oh, and - care : your indentation is done with 5 spaces instead of 4. Baaad. :P


Mmh yeah, weird. I don't know why all python-mode decides to use 5 spaces with these files.






I just tried a simple benchmark:

Code: [Select]
#! /usr/bin/env python2
# -*- coding: utf-8 -*-

import sf


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

    for i in xrange(100):
        window.clear()
        window.draw(sprite)
        window.display()

    window.close()


if __name__ == '__main__':
    main()


Cython:
Code: [Select]
$ time ./benchnew.py

real 0m2.236s
user 0m0.413s
sys 0m0.087s


Current binding:
Code: [Select]
$ time ./benchold.py

real 0m2.219s
user 0m0.423s
sys 0m0.087s


C++ (GCC, -O3):
Code: [Select]
$ time ./essai

real 0m1.908s
user 0m0.120s
sys 0m0.060s


Apparently the program spends more time waiting than anything else, so I'm not sure it means anything. But it seems to suggest that PySFML itself wouldn't be a bottleneck.
Title: Python binding generation tools
Post by: Laurent on November 05, 2010, 11:30:36 am
Guys, I think you should have a look at how I write the .Net binding. I answered all the questions that you're currently asking, such as using properties and returning instances -- maybe some of my solutions are not the best, but maybe it can help you.
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 12:45:57 pm
Apparently there's a bug when calling C++ static methods: http://groups.google.com/group/cython-users/browse_thread/thread/78dda025a24a651b

That's why I can't call GetMode(). Heh, I've never used it anyway. :P

Quote from: "Laurent"
Guys, I think you should have a look at how I write the .Net binding. I answered all the questions that you're currently asking, such as using properties and returning instances -- maybe some of my solutions are not the best, but maybe it can help you.


Python doesn't directly support method overloading, so providing multiple constructors is messy (it only clutters the binding itself though, so it can still be considered).
Personally I really prefer factory methods, but then we must decide if there should still be a default constructor for some reason.
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 01:13:50 pm
Well wouldn't it be much easier to bind CSFML actually?
Title: Python binding generation tools
Post by: Laurent on November 05, 2010, 02:07:31 pm
Quote
Python doesn't directly support method overloading, so providing multiple constructors is messy (it only clutters the binding itself though, so it can still be considered).

Do you mean that we could write specific code in the binding to work around that? Can you show me an example?

Quote
Well wouldn't it be much easier to bind CSFML actually?

I don't know if binding a C API is easier than a C++ one, but it would at least have one drawback: SFML can be linked statically, whereas CSFML must be linked dynamically. This doesn't matter on Unix systems, but on Windows it's not a bad thing to have the binding as a self-contained binary.
Title: Python binding generation tools
Post by: bastien on November 05, 2010, 03:10:19 pm
Quote from: "Laurent"
Quote
Python doesn't directly support method overloading, so providing multiple constructors is messy (it only clutters the binding itself though, so it can still be considered).

Do you mean that we could write specific code in the binding to work around that? Can you show me an example?


We can inspect the number of arguments and their types at runtime and decide what to do based on that.
In pure Python it looks something like that, should be pretty similar in Cython:

Code: [Select]
class Image(object):
    def __init__(self, width=None, height=None, color=None, pixels=None, filename=None, memory_file=None):
        # Check that not too many parameters have been supplied

        if width is not None and height is not None:
            # ...
        elif pixels is not None:
            # ...
        # And so on


And you would use it like this:

Code: [Select]
Image(640, 480, sf.Color(0, 0, 0))
Image(pixels=[])
Image(filename='filename')


You could also not require keywords arguments and deduce what to do based on their types, but then it gets even more complicated for no reason in my opinion.
On the other hand static methods would have an obvious meaning.
Title: Python binding generation tools
Post by: Laurent on November 05, 2010, 03:38:37 pm
I totally agree, this looks like a hack rather than a clean solution.
Title: Python binding generation tools
Post by: bastien 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:
Title: Python binding generation tools
Post by: Laurent 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 :)
Title: Python binding generation tools
Post by: bastien 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?
Title: Python binding generation tools
Post by: Groogy 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();
Title: Python binding generation tools
Post by: bastien 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?
Title: Python binding generation tools
Post by: Groogy 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?
Title: Python binding generation tools
Post by: Kaoron 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.
Title: Python binding generation tools
Post by: Laurent 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
Title: Python binding generation tools
Post by: bastien 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.
Title: Python binding generation tools
Post by: bastien 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.
Title: Python binding generation tools
Post by: bastien 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?
Title: Python binding generation tools
Post by: Laurent 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.
Title: Python binding generation tools
Post by: bastien 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?
Title: Python binding generation tools
Post by: Groogy 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.
Title: Python binding generation tools
Post by: Laurent on February 19, 2011, 03:17:31 pm
Quote
It's enough for the developer, but do you expect the end-user to execute the game in a console?

End users can redirect sf::Err() to a file or to nothing.

Quote
Anyway, why do you need to throw an exception?

In languages where exceptions *are* the standard way to handle errors, you should use them. I don't know about Ruby, but for example in SFML.Net I use them. It goes well with the fact that the LoadXxx functions are transformed to constructors.
Title: Python binding generation tools
Post by: Groogy on February 19, 2011, 03:27:06 pm
Quote from: "Laurent"
In languages where exceptions *are* the standard way to handle errors, you should use them. I don't know about Ruby, but for example in SFML.Net I use them. It goes well with the fact that the LoadXxx functions are transformed to constructors.


That's a hard one for Ruby I think... Some do some don't. The "constructors" in Ruby can simply return nil instead of throwing an exception. From my experience, most of the time exceptions are used to describe developer errors like invalid syntax, incompatible arguments(since Ruby uses Duck-typing I call it incompatible), undefined local variable or method and similar situations. I'll have to think a bit to see if I should add a SFML::Error exception.

Also more to topic, so the sf::Err isn't made for the developer that makes use of SFML? Redirect it to a stream we can read from and pass the error messages to an exception?
Title: Python binding generation tools
Post by: Laurent on February 19, 2011, 03:34:39 pm
Quote
Also more to topic, so the sf::Err isn't made for the developer that makes use of SFML? Redirect it to a stream we can read from and pass the error messages to an exception?

No, it's more like an error log, it's not supposed to be reinjected into something else.
But I don't see anything against using to to retrieve the error message in a string/exception/whatever, if that works well with the language.
Title: Python binding generation tools
Post by: Groogy on February 19, 2011, 04:06:44 pm
So something like:
Code: [Select]

SFML::Image.new("image/dont/exist.png") # Returns nil
SFML::Err # Now has the standard SFML failed to load error message
SFML.use_exceptions = true
SFML::Image.new("image/dont/exist.png") # Generates a SFML::LoadError with message from the latest SFML::Err line
SFML::Err # Contains the whole log of errors, not affected by the use of exceptions.


Maybe something for you too bastien?
Title: Python binding generation tools
Post by: bastien on March 10, 2011, 12:24:04 am
I tried to make it easy to retrieve the last error message.
This code appears to work:

Code: [Select]
const char* last_message = NULL;
std::size_t last_message_size = 0;

class MyBuff : public std::streambuf
{
    std::streamsize xsputn(const char* s, std::streamsize n)
    {
        last_message = s;
        last_message_size = n;

        return n;
    }
};

MyBuff my_buff;
sf::Err().rdbuf(&my_buff);


I'm worried about not overriding all that is needed, and that the method might be called several times for the same message if it's long.
Aslo, is there a simpler way?
Title: Python binding generation tools
Post by: bastien on March 10, 2011, 07:13:50 am
I uploaded a source release: https://bitbucket.org/bastienleonard/pysfml2-cython/downloads/PySFML%202-0.0.1.zip

I think the main features are there, but there's probably a lot of bugs lurking around.

The generated documentation is there (unfinished also, of course): http://bastien-leonard.alwaysdata.net/pysfml/doc/index.html (for some reason, index.html has to be in the URL)
Title: Python binding generation tools
Post by: bastien on March 25, 2011, 11:02:17 am
Anyone wants to test it? I uploaded a snapshot that doesn't require Cython to compile: https://bitbucket.org/bastienleonard/pysfml2-cython/downloads

I tried to test it on Windows, but I get a strange error when compiling SFML 2 with VC++ 2008 (I'll probably post that in another topic).
Title: Python binding generation tools
Post by: danman on March 25, 2011, 10:33:34 pm
I don't have so much time at the moment but maybe i'll try sunday or wednesday ;) . I was waiting for PySFML2.
Title: Python binding generation tools
Post by: Beliar on April 09, 2011, 11:14:12 am
There where some recent changes to sfml2 that made the binding incompatible but i managed to fix that locally and compile it using MinGW.

I only tested the examples so far but it seems i can finally switch to sfml2, even though, as you wrote, the binding may contain bugs.
Title: Python binding generation tools
Post by: bastien on April 12, 2011, 07:53:35 pm
With SFML 2's move to Github, I've decided to move the binding to Github as well, although I'm not a huge fan of Git. The new URL is: https://github.com/bastienleonard/pysfml2-cython

I've updated the binding so that it works with the latest SFML 2 snapshot.
I'm also going to start a clean topic one of these days, since this one is supposed to be about the various way to generate Python bindings.

As usual, you can download a snapshot of the source at Github, which won't require that you install Cython.
Title: Python binding generation tools
Post by: BLU3 L30PARD on April 16, 2011, 07:19:27 pm
I can't build the Snapshot :(
I put the "SFML" folder from the "include" folder of the latest sfml2 release from github into the "PySFML 2-0.0.1" Folder and set USE_CYTHON to False.
Then I opened the command line and typed "python setup.py build_ext --inplace". But I get the following output:
Code: [Select]

running build_ext
building 'sf' extension
creating build
creating build\temp.win32-2.7
creating build\temp.win32-2.7\Release
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe /c /nologo /Ox /MD /
W3 /GS- /DNDEBUG -IC:\Development\Python27\include -IC:\Development\Python27\PC
/Tpsf.cpp /Fobuild\temp.win32-2.7\Release\sf.obj
sf.cpp
c:\users\niklas\desktop\pysfml 2-0.0.1\SFML/Graphics.hpp(32) : fatal error C1083
: Datei (Include) kann nicht geöffnet werden: "SFML/Window.hpp": No such file or
 directory
error: command '"C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe"' f
ailed with exit status 2

Sorry, that's German, but I think you'll understand it ;)
Please, tell me what I did wrong!
Title: Python binding generation tools
Post by: Beliar on April 16, 2011, 10:00:14 pm
Hmm, that is strange, it seems like its trying to find "SFML/Window.hpp" in "c:\users\niklas\desktop\pysfml 2-0.0.1\SFML" which it, of course, can't find.

I don't know much about the vc compiler so i can't help though.
Title: Python binding generation tools
Post by: bastien on April 17, 2011, 01:13:23 am
Apparently he moved the SFML headers in the PySFML directory. What is strange is that apparently Graphics.hpp was found, but not Window.hpp.

Anyway, you should install the SFML headers (include/*) and libraries (lib/*) in the appropriate directories so that Visual Studio automatically recognizes them.
Apparently, the makefile generated by Cmake has an “install” target, so maybe you can use that, i.e. type “make install” in the console.
Title: Python binding generation tools
Post by: BLU3 L30PARD on April 17, 2011, 12:48:14 pm
Hm...
I copied the include and the lib folder I compiled before to the VC folder
so the compiler found it, but now I'm getting hundrets of errors:
Code: [Select]

sf.cpp(5370) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5371) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5372) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5373) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5374) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5375) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5379) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5380) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5381) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5382) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5383) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5384) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5385) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5386) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5387) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5752) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5758) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5893) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(5900) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(7633) : warning C4018: '<': Konflikt zwischen 'signed' und 'unsigned'
sf.cpp(8397) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8410) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8439) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8440) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8467) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8480) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8493) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8526) : warning C4800: 'int': Variable wird auf booleschen Wert ('True' o
der 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(8619) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8793) : warning C4800: 'int': Variable wird auf booleschen Wert ('True' o
der 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(8854) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(8931) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9008) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9161) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9162) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9163) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9252) : warning C4800: 'int': Variable wird auf booleschen Wert ('True' o
der 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(9353) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9579) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9752) : warning C4800: 'int': Variable wird auf booleschen Wert ('True' o
der 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(9813) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9890) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(9967) : warning C4244: '=': Konvertierung von 'double' in 'float', möglic
her Datenverlust
sf.cpp(10120) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(10121) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(10122) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(10211) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(10352) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(12833) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(13558) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(14454) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(15655) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15838) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15920) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15987) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15988) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15992) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(15993) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16113) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16114) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16118) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16119) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16234) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16235) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16239) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16240) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16280) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16343) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16344) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16348) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(16349) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(17534) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(17571) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(18213) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(18251) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(18298) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(18299) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(18303) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(18304) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(18400) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(19817) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(19915) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20193) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20440) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20441) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20445) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20446) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20520) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(20558) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21042) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21058) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21111) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21133) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21134) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21147) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21148) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(21149) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(22196) : error C2039: 'PollEvent': Ist kein Element von 'sf::RenderWindow
'
        C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\SFML/Graphics/R
enderWindow.hpp(43): Siehe Deklaration von 'sf::RenderWindow'
sf.cpp(22268) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(22611) : warning C4244: 'Argument': Konvertierung von 'int' in 'float', m
öglicher Datenverlust
sf.cpp(22648) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(22853) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(24101) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(24400) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(24624) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(25089) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(25437) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(25474) : warning C4800: 'int': Variable wird auf booleschen Wert ('True'
oder 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
sf.cpp(25535) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25695) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25696) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25697) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25698) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25699) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25702) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25714) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25717) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25718) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25719) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25720) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25721) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25894) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25895) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25896) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25897) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25900) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25912) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25915) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25916) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25917) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(25918) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26083) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26084) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26085) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26088) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26100) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26103) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26104) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26105) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26253) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26254) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26282) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26283) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26778) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26779) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26784) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
sf.cpp(26785) : warning C4244: '=': Konvertierung von 'double' in 'float', mögli
cher Datenverlust
error: command '"C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe"' f
ailed with exit status 2
C:\Users\Niklas\Desktop\PySFML 2-0.0.1>

That are the last lines the command line has shown, there're much more ;)
I'll download MinGW next time, hoping it will compile with that Toolchain...[/quote]
Title: Python binding generation tools
Post by: Beliar on April 17, 2011, 12:59:40 pm
Quote
sf.cpp(22196) : error C2039: 'PollEvent': Ist kein Element von 'sf::RenderWindow
'

(Means something like "'PollEvent': Is no Element of sf::RenderWindow)

It seems like you don't have the newest pysfml2 AND sfml2

The other things are warnings, not nice, i don't like if they come from third party libraries, but you can to ignore them.
Title: Python binding generation tools
Post by: bastien on April 17, 2011, 07:46:38 pm
Beliar is probably right, the renaming of GetEvent() to PollEvent() in SFML is very recent. Try getting a new SFML 2 snapshot, or update your repo if you're using Git.

It's “normal” that the code generates a lot of warnings, I used to activate them with GCC on this project, but I always got the same warnings and I couldn't do much about it since the code is generated by Cython.
However, I guess you didn't activate all warnings and VS only shows the most important ones, and the most recurring is this conversion from double to float, so I'll see if there's something I can fix. Still, I think it's probably not a big deal since SFML uses floats for almost everything.
Title: Python binding generation tools
Post by: BLU3 L30PARD on April 17, 2011, 10:22:14 pm
It seems that it's only possible to compile with MinGW (gcc)...
I tried it again with VC, but I get the output that a manifest file is missing.
But when I compiled PySFML2 with MinGW (without Cython!), it worked :)
I'll try to create a small game with your lib ;)
Title: Python binding generation tools
Post by: bastien on April 18, 2011, 03:26:40 pm
Visual Studio reports a strange manifest for me as well, but it happens when I compile SFML. Maybe I'll give MinGW a try.
Good luck for your game. ;)
Title: Python binding generation tools
Post by: BLU3 L30PARD on May 03, 2011, 07:36:20 pm
My game crashes when I try to display a string...
The .NET Binding had the same problem, but I thought
it is fixed since sfml2... please (try) to fix that! ;)
Title: Python binding generation tools
Post by: bastien on May 04, 2011, 03:29:16 pm
Can you run the text.py example? It works fine on my system.
Title: Python binding generation tools
Post by: BLU3 L30PARD on May 07, 2011, 04:04:22 pm
Yes that works, but when the App was closed I'm getting this
Message from Windows....

I'm using Windows 7 Home Premium (x86 | 32bit) and
Python 2.7.1
Title: Python binding generation tools
Post by: Chèvre on May 09, 2011, 06:27:28 pm
Hi,

First of all thanks for your hard work on this refreshing binding. I have just ported a sizeable chunk of my code that used the official PySFML 1.6 to this new binding and it does feel cleaner.

However, get_joystick_axis() (from sf.Input) seems to be broken, which kind of renders the joystick unusable.

Here is the incriminating code (where "glob.win" is an sf.RenderWindow):
Code: [Select]
jx = glob.win.get_input().get_joystick_axis(0, 0) / 100.
Which yields:
Code: [Select]
Traceback (most recent call last):
              <...snip...>
  File "/home/lapin/Desktop/ANTCURR/st_jeu.py", line 291, in update
    jx = glob.win.get_input().get_joystick_axis(0, 0) / 100.
  File "sf.pyx", line 1111, in sf.Input.get_joystick_axis (sf.cpp:11965)
AttributeError: 'sf.Input' object has no attribute 'GetJoystickAxis'


Out of curiosity I opened sf.pyx and here is the portion that seems to be wrong:
Code: [Select]
cdef class Input:
             <...snip...>
    def get_joystick_axis(self, unsigned int joy_id, int axis):
        return self.GetJoystickAxis(joy_id, axis)


I use the latest SFML 2 snapshot from Git (as of May 9th 2011) and the latest snapshot of the new binding.

EDIT 2: I guess a "p_this" is missing in there.
So if I change line #1111 of sf.pyx to:
Code: [Select]
       return self.p_this.GetJoystickAxis(joy_id, axis)
I get the following error when compiling sf.cpp after having being cythoned from sf.pyx:
Code: [Select]
sf.cpp: In function ‘PyObject* __pyx_pf_2sf_5Input_1get_joystick_axis(PyObject*, PyObject*, PyObject*)’:
sf.cpp:11962:132: error: invalid conversion from ‘int’ to ‘sf::Joy::Axis’ [-fpermissive]
/usr/include/SFML/Window/Input.hpp:120:11: error:   initializing argument 2 of ‘float sf::Input::GetJoystickAxis(unsigned int, sf::Joy::Axis) const’ [-fpermissive]

My guess here is that the API has changed and now uses a "sf::Joy::Axis" instead of a simple int (as in the current .pyx file)

EDIT 3: (Sorry for the long long post) For those who want to get the job done quickly, modify line #1111 of sf.pyx as shown above, run setup.py build, which will generate the huge C++ file. gcc will fail, but don't worry about it right now. Open the huge C++ file named sf.cpp, and head down to line #11962 (I guess the exact line number is subject to change in the near future, but anyway, this is a temporary fix.)
Change it from this:
Code: [Select]
 __pyx_t_1 = PyFloat_FromDouble(((struct __pyx_obj_2sf_Input *)__pyx_v_self)->p_this->GetJoystickAxis(__pyx_v_joy_id, __pyx_v_axis)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
to this:
Code: [Select]
 __pyx_t_1 = PyFloat_FromDouble(((struct __pyx_obj_2sf_Input *)__pyx_v_self)->p_this->GetJoystickAxis(__pyx_v_joy_id, static_cast<sf::Joy::Axis>(__pyx_v_axis))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
We're just casting the integer as a sf::Joy::Axis. It's dirty but it does the trick for now, because I don't know how to fix the cython files yet. Then of course run setup.py build again, then setup.py install.
Title: Python binding generation tools
Post by: bastien on May 21, 2011, 03:11:53 am
Thanks for reporting the bug, I fixed it.
Title: Python binding generation tools
Post by: bastien on May 21, 2011, 04:29:26 pm
Quote from: "BLU3 L30PARD"
Yes that works, but when the App was closed I'm getting this
Message from Windows....

I'm using Windows 7 Home Premium (x86 | 32bit) and
Python 2.7.1


Does this happen with every PySFML program?
I've built it on Windows, so I'll try to do some tests.
Title: Python binding generation tools
Post by: Chèvre on May 22, 2011, 05:55:28 pm
Quote from: "bastien"
Quote from: "BLU3 L30PARD"
Yes that works, but when the App was closed I'm getting this
Message from Windows....

I'm using Windows 7 Home Premium (x86 | 32bit) and
Python 2.7.1


Does this happen with every PySFML program?
I've built it on Windows, so I'll try to do some tests.


Bastien, I also ran into this bug, that is, a crash when quitting Python on Windows (doesn't seem to happen for me on Linux). I don't mind because the rest of the program runs flawlessly. But it may be intimidating to an end user.

I traced it back to loading sound buffers into memory from a file, or opening a music file.

For example, this two-line program will crash:
Code: [Select]
import sf
sbuf = sf.SoundBuffer.load_from_file('data/clear.ogg')

load_from_file itself does not crash, that is, you can make a Sound out of sbuf and it'll play just fine; it rather seems to me there's a destructor that went wrong somewhere.

Interestingly, it doesn't crash immediately after sbuf goes out of scope; for example:
Code: [Select]
import sf
def foo():
sbuf = sf.SoundBuffer.load_from_file('data/clear.ogg')
foo()
foo()
foo()
print "Yay"

This program gets to "Yay" allright, and then crashes on exit.

Music similarly gets Python to crash on exit:
Code: [Select]
music = sf.Music.open_from_file('data/maf-shroomy.ogg')

Hope this helps. And btw, great job fixing the joystick bug and converting time to integers! I have to test it out. (after porting my program to use millisecs)

EDIT: the 'pong' example is, of course, affected by this bug. It also uses a wav file, while I have used oggs, so the crash may not be file format-specific.
Title: Python binding generation tools
Post by: Chèvre on May 22, 2011, 06:42:48 pm
Hold on-- this problem actually appears with C++ SFML 2 programs. The 'sound' C++ example crashes on exit.

EDIT: ran examples through gdb, found out alcCloseDevice() from openal32.dll is the culprit. This seems to be a known bug, see https://github.com/SFML/SFML/issues/30
Title: Python binding generation tools
Post by: Chèvre on May 27, 2011, 07:14:37 am
Hi Bastien,
I suggest you add this to sf.pyx within the 'wrap_event_instance' cdef, so as to make the TEXT_ENTERED event useful. So far you couldn't get which Unicode character was typed in.
I put that at line 1082 in sf.pyx. I tested it and it works fine.
Code: [Select]
   elif p_cpp_instance.Type == declevent.TextEntered:
        ret.unicode = p_cpp_instance.Text.Unicode

Then, the Unicode value of the character can be retrieved within a Python program with the unichr() built-in function (unichr(event.unicode))
Title: Python binding generation tools
Post by: bastien on July 11, 2011, 08:16:09 am
Thanks for the suggestion, I didn't remember this one wasn't implemented.
But instead of giving the plain integer, I convert it to a real Unicode object directly. It seems more logical.