pygame-ce
pygame-ce copied to clipboard
Events as types
Closes #2759
- [x] implement logic
- [x] documentation
- [x] tests
- [x] stubs
This seems to work in my testing, per the original issue:
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 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.cis 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 betweenpygame._eventandpygame.eventis 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.
@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?
@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.
Events as types in python is ready for review (#3121).