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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - dentuk

Pages: [1]
1
Python / Respecting naming conventions & other possible changes
« on: July 22, 2010, 02:44:07 am »
My idea was to handle errors (loading images was just an example) using exceptions rather than return values. The aim is not only to gain a few lines but also to prevent the code from being executed when a problem appears. This way you can handle errors at a higher level (the calling function instead of the called one) if you want to. It also helps debugging since you can explicit the problem in the exception's name and value. As I am used to working with exceptions I find it a lot more convenient, but you may disagree.

2
Python / Respecting naming conventions & other possible changes
« on: July 20, 2010, 05:18:47 pm »
You are right, this is quite far away from the original C++ library.

3
Python / Respecting naming conventions & other possible changes
« on: July 20, 2010, 05:00:00 pm »
And what would you think of including a base class for event-based applications?
Code: [Select]
# inspired by ircbot

import sfml

STR_EVENTS = {sfml.CLOSED: "closed", sfml.RESIZED: "resized",
              sfml.LOST_FOCUS: "lost_focus", sfml.GAINED_FOCUS: "gained_focus",
              sfml.TEXT_ENTERED: "text_entered",
              sfml.KEY_PRESSED: "key_pressed", sfml.KEY_RELEASED: "key_released",
              #...
             }

class StopMainLoop(Exception): pass

class EventManager:
    def __init__(self, window):
        """Initializes self.window object."""
        self.window = window

    def process_queue(self):
        """Processes events in the queue calling self.on_X(event) where X is the event type."""
        for event in self.window.iterevents():
            if hasattr(self, "on_" + STR_EVENTS[event.type]):
                handler = getattr(self, "on_" + STR_EVENTS[event.type])
                handler(event)

    def prepare_frame(self):
        """Use this method to do some stuff before drawing."""
        pass

    def draw(self):
        """Use this method to draw the current frame on the self.window object."""
        pass

    def main_loop(self):
        """Calls self.prepare_frame(), self.draw() and self.process_queue() in a loop."""
        try:
            while True:
                self.prepare_frame()

                self.window.clear()
                self.draw()
                self.window.display()

                self.process_queue()
        except StopMainLoop:
            pass

    def stop(self):
        """Call this method to stop the main loop."""
        if self.window.is_opened():
            self.window.close()
        raise StopMainLoop

Users would not be forced to use it but it could help. An sample code would be:
Code: [Select]
import sfml

MOVE_PIXELS = {sfml.DOWN: (0,1), sfml.LEFT: (-1,0), sfml.UP: (0,1), sfml.RIGHT: (1,0)}

class MyApp(sfml.EventManager):
    def __init__(self, background, player):
        sfml.EventManager.__init__(self, sfml.RenderWindow())

        background_img = sfml.Image(background)
        vm = sfml.VideoMode(background_img.width(), background_img.height(), 32)
        self.window.create(vm, "MyApp")

        self.background = sfml.Sprite(background_img)
        self.player = sfml.Sprite(sfml.Image(background))

    def draw(self):
        self.window.draw(self.background)
        self.window.draw(self.player)

    def on_closed(self, _):
        self.stop()

    def on_key_pressed(self, event):
        if event.key.code == sfml.ESCAPE:
            self.stop()
        elif event.key.code in MOVE_PIXELS:
            self.player.move(*MOVE_PIXELS[event.key.code])

if __name__ == "__main__":
    MyApp("background.png", "player.png").main_loop()

4
Python / Respecting naming conventions & other possible changes
« on: July 20, 2010, 03:18:23 am »
By the way i don't understand the choice of writing:
Code: [Select]
from PySFML import sf
when we could simply write:
Code: [Select]
import sfml
Then there are some other things we could change to be more python-friendly but which may require a PySFML-specific tutorial. I don't know if this would be better. If SFML was difficult to use, it would sure be better, but since SFML is already user-friendly in its C++ implementation...
For example, instead of this:
Code: [Select]
from PySFML import sf

image = sf.Image()

if image.LoadFromFile("tagada.png"):
    window = sf.RenderWindow(sf.VideoMode(800, 600), "PySFML test")
    sprite = sf.Sprite(image)

    while window.IsOpened():
        window.Clear()
        window.Draw(sprite)
        window.Display()

        event = sf.Event()
        while window.GetEvent(event):
            if event.Type == sf.Event.Closed:
                window.Close()

else:
    print "Unable to load tagada.png"

We could have something like that:
Code: [Select]
import sfml

window = sfml.RenderWindow(sfml.VideoMode(800, 600), "PySFML test")
sprite = sfml.Sprite(sfml.Image("tagada.png"))

while window.is_opened():
    window.clear()
    window.draw(sprite)
    window.display()

    for event in window.iterevents():
        if event.type == sfml.CLOSED:
            window.close()

Where sfml.Image.__init__ would raise a user-defined exception if it were unable to load the file.

5
Python / Respecting naming conventions & other possible changes
« on: July 19, 2010, 05:03:59 pm »
Quote from: "Laurent"
I don't know if this is related to naming conventions, but you wrote this:
Code: [Select]
if event.type == "closed"
Is it really better (or more pythonic) to use strings here?
Not really, it was just to give an example of how i would have done it, but it could also be written using constants, for which the convention is:
Quote
Constants are usually declared on a module level and written in all capital letters with underscores separating words.  Examples include MAX_OVERFLOW and TOTAL.

6
Python / Respecting naming conventions & other possible changes
« on: July 19, 2010, 04:29:42 pm »
PySFML follows the C++ SFML implementation's naming conventions instead of the ones defined for Python in the PEP 8 (see http://www.python.org/dev/peps/pep-0008/). While these naming conventions may produce easy-to-read C++ code, it decreases Python code's readability. If I want to use both PySFML and another library then my code will be an ugly mix of two naming conventions - and I shall choose one of them for my own code.

This little example looks more like Python-coded C++ to me than Python code:
Code: [Select]
# Include the PySFML extension
from PySFML import sf

# Create the main window
window = sf.RenderWindow(sf.VideoMode(800, 600), "PySFML test")

# Create a graphical string to display
text = sf.String("Hello SFML")

# Start the game loop
running = True
while running:
    event = sf.Event()
    while window.GetEvent(event):
        if event.Type == sf.Event.Closed:
            running = False

    # Clear screen, draw the text, and update the window
    window.Clear()
    window.Draw(text)
    window.Display()

Whereas something like that would be easier to read and more "Python-oriented":
Code: [Select]
# Include the PySFML extension
from pysfml import sf

# Create the main window
window = sf.RenderWindow(sf.VideoMode(800, 600), "PySFML test")

# Create a graphical string to display
text = sf.String("Hello SFML")

# Start the game loop
running = True
while running:
    event = sf.Event()
    while window.get_event(event):
        if event.type == "closed":
            running = False

    # Clear screen, draw the text, and update the window
    window.clear()
    window.draw(text)
    window.display()

Yet PySFML 1.x has already been used in several projects, and it would would break compatibility to change the naming conventions now. But you should consider this for the PySFML 2 release. I could help if required.

So, what is your opinion on this subject?

Pages: [1]
anything