Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Events as types #2866

Closed
wants to merge 19 commits into from
Closed

Events as types #2866

wants to merge 19 commits into from

Conversation

gresm
Copy link
Contributor

@gresm gresm commented May 21, 2024

Closes #2759

  • implement logic
  • documentation
  • tests
  • stubs

@gresm gresm force-pushed the events-as-types branch 2 times, most recently from 94fc76b to 1d671de Compare May 22, 2024 08:40
@gresm gresm marked this pull request as ready for review May 26, 2024 07:03
@gresm gresm requested a review from a team as a code owner May 26, 2024 07:03
Comment on lines -27 to -35
option('stripped', type: 'boolean', value: 'false')
option('stripped', type: 'boolean', value: false)

# Controls whether to compile with -Werror (or its msvc equivalent). The default
# behaviour is to not do this by default
option('error_on_warns', type: 'boolean', value: 'false')
option('error_on_warns', type: 'boolean', value: false)

# Controls whether to error on build if generated docs are missing. Defaults to
# false.
option('error_docs_missing', type: 'boolean', value: 'false')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My meson plugin warned that using booleans with quotes is deprecated and I saw that everywhere else no quotes were used, so it's nothing important, should I revert this?

@MyreMylar
Copy link
Member

This seems to work in my testing, per the original issue:

image

docs/reST/ref/event.rst Outdated Show resolved Hide resolved
Comment on lines +901 to +903
// Madeup function, but it works.
static int
_very_bad_hash(const char *str)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me slightly nervous!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to write something like this, but didn't want to add any dependency nor to have any copyright issues with using random hash algorithms taken from the internet, so I opted for coming up with my own "hashing" algorithm, which only requirement was to not create collisions for the existing names.

Copy link
Member

@MyreMylar MyreMylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, it seems to work in my testing without obviously breaking any of the existing ways events are used. I noted a couple of minor things.

@ankith26 should probably look it over as they've spent much more time digging around in event.c than I have.

👍 🎆 🎉

Copy link
Member

@ankith26 ankith26 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello!

This seems like a lot of hard work! I wish you had discussed it more before going ahead and implementing this.

I assumed that the issue is to be tackled in the long term (like, post the SDL3 migration) so I didn't really comment on the issue yet.

I think it would be much simpler to implement as much as possible in pure python code, and having minimal C code changes. event.c is pretty messy as it is, and IMO we should be focused on making it more maintainable by offloading more things to the python side.

So, something like minimal _event.c exporting the core internal functionality provided by SDL, and event.py built on top of that with all the subclassing logic implemented.

@gresm
Copy link
Contributor Author

gresm commented May 29, 2024

I think it would be much simpler to implement as much as possible in pure python code, and having minimal C code changes. event.c is pretty messy as it is, and IMO we should be focused on making it more maintainable by offloading more things to the python side.

@ankith26 I agree that event.c is already messy, but I worry that using pure python implementation for implementing event classes would be too slow (I didn't check this). I think that splitting the logic between pygame._event and pygame.event is a good idea, but something far outside the scope of "Events as types PR" and would require its own pull request.

@Starbuck5
Copy link
Member

I think it would be much simpler to implement as much as possible in pure python code, and having minimal C code changes. event.c is pretty messy as it is, and IMO we should be focused on making it more maintainable by offloading more things to the python side.

@ankith26 I agree that event.c is already messy, but I worry that using pure python implementation for implementing event classes would be too slow (I didn't check this). I think that splitting the logic between pygame._event and pygame.event is a good idea, but something far outside the scope of "Events as types PR" and would require its own pull request.

I think that there will be some opportunities in the future to rewrite things in Python and have them be both easier to maintain as well as faster. As the faster-cpython team gets the interpreter faster, the overhead of going between C and Python will be more significant.

In the below test script, Python is faster than C to implement a pygame API function (in 3.12 but not in 3.9, which are the only versions I tested)

Test script
import pygame
import random
import time

random.seed(36)

use_python = False


class Obj:
    def __init__(self, x, y, w, h):
        self.xa = pygame.Rect(x, y, w, h)


objs = [
    Obj(
        random.randint(-100, -100),
        random.randint(-100, 100),
        random.randint(-100, 100),
        random.randint(-100, 100),
    )
    for _ in range(5000)
]

start = time.time()


class Rect(pygame.Rect):
    def collideobjectsall(r, objects, key):
        colliding_indices = r.collidelistall([key(obj) for obj in objects])
        return [objects[colliding_index] for colliding_index in colliding_indices]


if use_python:
    r = Rect(-20, -20, 100, 100)
    for _ in range(1000):
        colliding_objs = r.collideobjectsall(objs, key=lambda e: e.xa)


else:
    r = pygame.Rect(-20, -20, 100, 100)
    for _ in range(1000):
        colliding_objs = r.collideobjectsall(objs, key=lambda e: e.xa)


print(time.time() - start)

List comprehensions are just too good.

@gresm
Copy link
Contributor Author

gresm commented Jun 3, 2024

@Starbuck5 this looks interesting, but isn't a good measure for speed comparison in this case. I assume that python version could probably have similar speed as this C implementation, in some places probably a bit slower, but I'm not sure if it is worth re-implementing this in python, is there enough interest for it, that it would make sense for me to work on this. Is there enough interest in this for me to go on writing a new implementation, when there is one already?

@yunline yunline added enhancement type hints Type hint checking related tasks event pygame.event labels Jun 11, 2024
Copy link
Member

@ankith26 ankith26 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we cannot make performance claims either way without actual benchmarking or implementation.

But one thing is for certain, event handling is typically orders of magnitude faster than drawing/rendering and updating the display (especially for large displays and software rendering) for each frame, so we aren't exactly in a performance critical area.

What I personally want to prioritize, is the SDL3 porting in this module that comes with its own refactorings. I have a patch or two lying around for this module since like over 2 years, and I've been basically waiting for SDL3 to kinda stabilize in its API.

I do not want to be adding any new API to event till we are sure that the SDL3 API is stable and whatever we introduce must be compatible with it.

@gresm
Copy link
Contributor Author

gresm commented Jun 11, 2024

@ankith26 Understandable, this is another reason why splitting event logic between _event and event would be useful, as it would decrease logic in _event.c and would make transitions easier. That's enough for me to see this worth the effort.

@ankith26 ankith26 marked this pull request as draft June 28, 2024 11:17
@gresm
Copy link
Contributor Author

gresm commented Sep 25, 2024

Events as types in python is ready for review (#3121).

@gresm gresm closed this Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement event pygame.event type hints Type hint checking related tasks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Idea: event types are actual types
5 participants