-
-
Notifications
You must be signed in to change notification settings - Fork 424
Add batch event processing in lime/sdl #1319
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
base: develop
Are you sure you want to change the base?
Changes from all commits
2c25791
5cf919b
42588f4
f8a24e9
39655f2
7da63d6
a0cafe6
7642af1
7096a62
29e7ef0
738620e
52e5533
2062e67
de8ce02
7da7b20
eb46c60
1ed381b
6e3eb7a
06787bd
927c3d2
5370b0e
25f7e1f
1536841
554c5b1
3828a3c
aae3e87
5a0086c
4fdb0da
7214637
7aa5d66
e13b739
d7714b3
c8a9091
070ccd6
34ce82b
cc584e2
41161ce
d115773
a392a96
08580e6
89ebb52
63af378
6d4b16e
0155599
bcfb730
b998562
70d850a
0d94959
04fb1e0
f088e44
74c1fd4
982c990
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,11 @@ namespace lime { | |
| lastUpdate = 0; | ||
| nextUpdate = 0; | ||
|
|
||
| eventQueue = NULL; | ||
| queueLength = 0; | ||
| queueMaxLength = 0; | ||
| isGCBlocking = false; | ||
|
|
||
| ApplicationEvent applicationEvent; | ||
| ClipboardEvent clipboardEvent; | ||
| DropEvent dropEvent; | ||
|
|
@@ -80,7 +85,12 @@ namespace lime { | |
|
|
||
| SDLApplication::~SDLApplication () { | ||
|
|
||
|
|
||
| if (NULL != eventQueue) { | ||
| SDL_free (eventQueue); | ||
| eventQueue = NULL; | ||
| queueMaxLength = 0; | ||
| queueLength = 0; | ||
| } | ||
|
|
||
| } | ||
|
|
||
|
|
@@ -332,6 +342,8 @@ namespace lime { | |
| lastUpdate = SDL_GetTicks (); | ||
| nextUpdate = lastUpdate; | ||
|
|
||
| while (20 == BatchUpdate(20)); | ||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
@@ -827,7 +839,6 @@ namespace lime { | |
|
|
||
| static SDL_TimerID timerID = 0; | ||
| bool timerActive = false; | ||
| bool firstTime = true; | ||
|
|
||
| Uint32 OnTimer (Uint32 interval, void *) { | ||
|
|
||
|
|
@@ -857,9 +868,7 @@ namespace lime { | |
|
|
||
| #if (!defined (IPHONE) && !defined (EMSCRIPTEN)) | ||
|
|
||
| if (active && (firstTime || WaitEvent (&event))) { | ||
|
|
||
| firstTime = false; | ||
| if (active && WaitEvent (&event)) { | ||
|
|
||
| HandleEvent (&event); | ||
| event.type = -1; | ||
|
|
@@ -912,6 +921,83 @@ namespace lime { | |
| } | ||
|
|
||
|
|
||
| int SDLApplication::BatchUpdate (int numEvents) { | ||
|
|
||
| SDL_Event* mouseMoved = NULL; | ||
|
|
||
| if (!active) { | ||
| return -1; | ||
| } | ||
|
|
||
| queueLength = numEvents; | ||
|
|
||
| if (queueLength > queueMaxLength) { | ||
|
|
||
| if (NULL != eventQueue) { | ||
| SDL_free (eventQueue); | ||
| } | ||
|
|
||
| eventQueue = reinterpret_cast<SDL_Event*> (SDL_malloc (queueLength * sizeof (SDL_Event))); | ||
| if (NULL == eventQueue) { | ||
| queueLength = 0; | ||
| queueMaxLength = 0; | ||
| } else { | ||
| queueMaxLength = queueLength; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like Actually, what is the |
||
| } | ||
| } | ||
|
|
||
| int numPending = GetPendingEvents (eventQueue, queueLength); | ||
|
|
||
| // only allow GC free objects while we're handling events | ||
| if (isGCBlocking) System::GCExitBlocking (); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said elsewhere, this seems disruptive. Maybe it's appropriate, but the comment doesn't do a good job of explaining why. |
||
| isGCBlocking = false; | ||
|
|
||
| int nextEvent; | ||
| for (nextEvent = 0; nextEvent < numPending; ++nextEvent) { | ||
|
|
||
| if (SDL_MOUSEMOTION == eventQueue[nextEvent].type) { | ||
| // we'll only handle the last motion event in the batch | ||
| mouseMoved = &eventQueue[nextEvent]; | ||
| } else { | ||
| HandleEvent (&eventQueue[nextEvent]); | ||
| eventQueue[nextEvent].type = -1; | ||
| if (!active) { | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // handle the mouse motion event if there is one this batch | ||
| if (NULL != mouseMoved) { | ||
| HandleEvent (mouseMoved); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said elsewhere, I'm not a fan of doing this out of order. It could get skipped if the above loop returns. Another approach would be to add a second loop above the first: for (nextEvent = 0; nextEvent < numPending; ++nextEvent) {
if (eventQueue[nextEvent].type == SDL_MOUSEMOTION) {
if (mouseMoved != NULL) mouseMoved->type = -1;
mouseMoved = &eventQueue[nextEvent];
}
}This will set all but the final mouse moved event's type to -1. Then the main loop would skip over those events, and execute all >= 0 events in the right order. |
||
| mouseMoved->type = -1; | ||
| } | ||
|
|
||
| currentUpdate = SDL_GetTicks (); | ||
|
|
||
| #if (!defined (IPHONE) && !defined (EMSCRIPTEN)) | ||
|
|
||
| if (currentUpdate >= nextUpdate) { | ||
|
|
||
| SDL_RemoveTimer (timerID); | ||
| OnTimer (0, 0); | ||
|
|
||
| } else if (!timerActive) { | ||
|
|
||
| timerActive = true; | ||
| timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0); | ||
|
|
||
| } | ||
|
|
||
| if (!isGCBlocking) System::GCEnterBlocking (); | ||
| isGCBlocking = true; | ||
|
|
||
| #endif | ||
|
|
||
| return nextEvent; | ||
| } | ||
|
|
||
|
|
||
| void SDLApplication::UpdateFrame () { | ||
|
|
||
| #ifdef EMSCRIPTEN | ||
|
|
@@ -978,6 +1064,16 @@ namespace lime { | |
|
|
||
| } | ||
|
|
||
|
|
||
| int SDLApplication::GetPendingEvents (SDL_Event* events, int maxEvents) | ||
| { | ||
| SDL_PumpEvents (); | ||
|
|
||
| int numEvents = SDL_PeepEvents (events, maxEvents, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); | ||
|
|
||
| return numEvents; | ||
| } | ||
|
|
||
|
|
||
| Application* CreateApplication () { | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,7 @@ namespace lime { | |
| virtual int Quit (); | ||
| virtual void SetFrameRate (double frameRate); | ||
| virtual bool Update (); | ||
| virtual int BatchUpdate(int numEvents); | ||
|
|
||
| void RegisterWindow (SDLWindow *window); | ||
|
|
||
|
|
@@ -51,13 +52,18 @@ namespace lime { | |
| void ProcessTouchEvent (SDL_Event* event); | ||
| void ProcessWindowEvent (SDL_Event* event); | ||
| int WaitEvent (SDL_Event* event); | ||
| int GetPendingEvents (SDL_Event* event, int NumEvents); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the argument be |
||
|
|
||
| static void UpdateFrame (); | ||
| static void UpdateFrame (void*); | ||
|
|
||
| static SDLApplication* currentApplication; | ||
|
|
||
| bool active; | ||
| SDL_Event* eventQueue; | ||
| int queueLength; | ||
| int queueMaxLength; | ||
| bool isGCBlocking; | ||
| ApplicationEvent applicationEvent; | ||
| ClipboardEvent clipboardEvent; | ||
| Uint32 currentUpdate; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well move this down to where it's used.