SDL events not working for multiple windows
Summary
Currently all SDL events get blindly dispatched to the window polling the message loop. Instead the events should be dispatched to the window as provided by the event's window id or (if not set) to the window having focus.
Steps to reproduce
- Platform: Desktop
- Framework Version: .NET Core 3
- Add a second window to the basic example in the 2.0 branch
- Prioritize SDL
- See all events getting routed to the window calling DoEvents
Comments
Maybe something like https://github.com/stride3d/stride/blob/master/sources/engine/Stride.Graphics/SDL/Application.cs should be introduced? What would be the proper approach?
Sadly I can't really build the solution. It's complaining about files not being found under C:\Silk.NET\... - once I move everything there, Visual Studio goes completely nuts, eating up all of my memory and in git I see >2000 or more *.gen.cs files. I guess that's not how it's supposed to be?
Ah ok, didn't think that through. By the sounds of things, SdlPlatform will need to keep track of all the SdlViews created and have a method called DoEvents on the platform, which will run the e... woah this will need significant rework for blocking event loops.
Will try to think of something.
Sadly I can't really build the solution. It's complaining about files not being found under C:\Silk.NET... - once I move everything there, Visual Studio goes completely nuts, eating up all of my memory and in git I see >2000 or more *.gen.cs files. I guess that's not how it's supposed to be?
Apparently I forgot to turn off NativeApiGenerator's debug features. You don't need it in C:\Silk.NET, that's just where the source generator dumps files for debugging purposes. As long as the C:\Silk.NET\src\Lab folder exists in some capacity you can put your Silk.NET clone anywhere. Visual Studio will die if it gets its hands on the .gen files as they're hundreds of thousands of lines long.
This unfortunately slipped the latest preview. Will be in Preview 5, which will be released around the same time the ATG begins working on its Stride project.
@Perksey Thanks for working on this. I had a little bit of time looking at your changes but things still don't really work like they should. Here's a little example project creating two windows. It renders into the first window using Skia. When resizing a window events still get mixed up. With Sdl it's even worse, the resize somehow affecting the other window. Closing a window also has no effect anymore. Or maybe I'm not using the API correctly? Without the 2nd window everything works as expected.
We'd like to investigate further. To ensure that licensing is not a problem, can you please pull request your minimal reproduction into the src/Lab folder? I can then work at trying to get this fixed for 2.1.
Dont know if its helpful or feasible, currently i try to do a true multithreaded engine as a hobby i hope i solved it that way (WIP):
one class serving as HOST or app if you want. multiple MODULE classes that use the host and run in their own threads (input, physics, rendering, presenting)
the host "manages" the main thread by only have a simple scheduler which the modules can post actions to. optionlally the module can wait till the posted actions are done this way i currently only have to post the SDL.PollEvents calls to the host, it must be fast and should only create the event list. ( i only do SDL atm ) the event list then is processed in my input module which is other thread and "Tick/Frame based"
this hopefully enables me to have diffrent threads AND diffrent Ticks/Frames (physic needs a fixed timestep, rendering should be dynamic timestep and pretty sure has to interpolate, input and simulationLogicUpdates can choose)
Sounds like we need to show Silk.NET.Windowing.Extensions.WindowManager some love then
which should be the App.WindowManager? :) i need to do my engine for now, just to be sure that what i hope is working, really works & is feasible. but maybe after this i may help
ok it looks like its working, what i needed to do was: (repeater is a mechanism that calls an action/method in a seperate thread in a looping manner)
- Create a scheduler for the mainthread
- Create a "FixedWindowMessagePoll" repeater (fixed or dynamic doesnt matter) in the OnRepetition event of the repeater get "some" of the events by posting an action to the mainthreadsched that action loops some times over Pollevents and adds the messages to a new message queue (locking the new queue)
- Create a "FixedUpdate" repeater (fixed or dynamic doesnt matter) this repeater fast copies and clears the message queue from step 2. ( since it locks too, this will not block step2 too long ) spam the events based on the new new :) queue and clear the queue too.
remarks; so there are 3 threads involved: the main thread, and two additional threads tampering/copying with the message queue i needed this (at least on windows) because if step 2. and 3. is done in one thread then that thread is blocked when grabbing and dragging around an OsWindow, think it was on resize too. since i use this repeater to spam the "FrameUpdate" it wouldnt be cool if its blocked on move of a window especially when coming to networking
Great! Though, Silk.NET's job isn't to put in place things like schedulers ourselves - we just want to be an abstraction not a framework (i.e. window.Initialize maps to SDL_CreateWindow, window.DoEvents roughly maps to SDL_PollEvents, etc)
I don't have the time to look into this, so someone contributing a fix would be much appreciated.
oh sorry, well then ofc this solution doesnt work for you because it needs a seperate thread, and i wasnt able to find another solution to fix that sdl2-MsWindows issue
Got the same problem, the pollevent function seemed to be working well when only one window was created. But when another was created, whatever happened on the window will affect another. And I even tried to get the window ID corresponding to the event, but none of these worked for me. Hope for a real solution.
Contributions welcome in fixing this, but if you're getting this with raw SDL_PollEvent then I have no idea what to do to fix this.