You only need a single thread locked to the UI thread.

Use one Go routine locked to the UI thread. Put events onto a channel.

Have another Go routine read from the channel, and the app command channel 
using select.



> On Jan 3, 2020, at 5:28 PM, bucha...@gmail.com wrote:
> 
> Whether the UI thread is on the main thread or a separate thread, a single UI 
> thread needs to process events from two sources: the OS window and from my 
> application. Having one loop process both sources (without support from the 
> Go runtime scheduler) is the part I'm struggling with.
> 
> My latest iteration is something like:
> 
> for {
>   // PollEvent doesn't block/sleep
> 
>   for ev := sdl.PollEvent(); ev != nil; ev = sdl.PollEvent {
>     // handle OS window events
>   }
>   select {
>   case cmd := <-app.commands:
>     // process application command
> 
>     cmd()
>   case <-time.After(10*time.Millisecond):
>     // only wait 10ms for application commands
> 
>   }
> }
> 
> 
> 
> This is an improvement, but I'd still prefer help from the Go runtime. If the 
> runtime supported locking two goroutines to the UI thread, I could split this 
> loop into two separate loops and remove the time.After, I *think*.
> 
> On Friday, January 3, 2020 at 2:59:42 PM UTC-8, robert engels wrote:
> You can definitely run the event loop for a process on a thread other than 
> main. The main thread is the thread created by the OS to begin running the 
> process - the UI thread is the one that initializes the Windowing system. 
> Some OSs even support multiple UI threads (see 
> https://docs.microsoft.com/en-us/cpp/parallel/multithreading-creating-user-interface-threads?view=vs-2019
>  
> <https://docs.microsoft.com/en-us/cpp/parallel/multithreading-creating-user-interface-threads?view=vs-2019>)
> 
> Go doesn’t do any Windowing system initialization by default - the main 
> thread in Go (at least according to the referenced library) is the one that 
> called the package init() - which may not even be the OS main thread since 
> according to the Go docs "Package initialization—variable initialization and 
> the invocation of init functions—happens in a single goroutine, sequentially, 
> one package at a time.” - which makes no claim that this Go routine is 
> running on the “main” OS thread.
> 
> Whatever thread you use to initialize GLFW is the UI thread (or main for 
> GLFW).
> 
> This is pretty standard across windowing/graphics systems.
> 
> 
> 
> 
>> On Jan 3, 2020, at 4:02 PM, buch...@ <>gmail.com <http://gmail.com/> wrote:
>> 
>> I'm pretty sure the OS event loop is required to be on the main thread. 
>> 
>> From the GLFW docs for glfwPollEvents:
>> "This function must only be called from the main thread."
>> 
>> From the SDL docs for SDL_WaitEvent:
>> "you can only call this function in the thread that initialized the video 
>> subsystem."
>> 
>> 
>> On Friday, January 3, 2020 at 1:58:29 PM UTC-8, Robert Engels wrote:
>> Even if you could I don’t think you would want to do it this way. 
>> 
>> Have a go routine sleep on a channel. Post to the channel from the native 
>> code. 
>> 
>> Let your command loop run on any thread and synchronize via a channel the 
>> calls to/from native. 
>> 
>> The os event loop doesn’t need to run on main - it just needs to be locked 
>> to a thread - use a native thread - and post the os events to a channel.  
>> 
>> Probably easiest to export a simple Go postToEventChannel() and have the 
>> native use this. 
>> 
>>> On Jan 3, 2020, at 2:18 PM, buch...@ <>gmail.com <http://gmail.com/> wrote:
>>> 
>>> 
>>> I've been getting by with a version of this that sends commands (closures) 
>>> to a loop on the main thread:
>>> https://github.com/buchanae/ink/blob/2af8781a960a0351b6b6b7ca23d81ae5c43535ec/win/window.go#L55
>>>  
>>> <https://github.com/buchanae/ink/blob/2af8781a960a0351b6b6b7ca23d81ae5c43535ec/win/window.go#L55>
>>> 
>>> And here is where it pops those commands, and also integrates with the OS 
>>> event loop:
>>> https://github.com/buchanae/ink/blob/2af8781a960a0351b6b6b7ca23d81ae5c43535ec/win/window.go#L163
>>>  
>>> <https://github.com/buchanae/ink/blob/2af8781a960a0351b6b6b7ca23d81ae5c43535ec/win/window.go#L163>
>>> 
>>> But, I'm still not satisfied. The solution ties together the scheduling 
>>> (and code) of two separate event loops. In particular, I've found that my 
>>> commands are delayed ~10ms – I think sdl.WaitEvent might be rate limited.
>>> 
>>> What I really want is for the two event loops (OS event loop vs app command 
>>> loop) to be in two separate goroutines, both running on the main thread. 
>>> That way, the OS event loop can react to infrequent window events (mouse 
>>> clicks, etc) without burning lots of CPU, while my app command loop can 
>>> react to commands instantly. 
>>> 
>>> Does that make sense? Is this possible to implement without requiring a 
>>> change to the Go runtime? Is it possible to change the Go runtime to allow 
>>> multiple goroutines to be scheduled only to the main thread?
>>> 
>>> Thanks.
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to golan...@ <>googlegroups.com <http://googlegroups.com/>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/e4e3a04d-0f76-4baf-9760-9992ef38d51f%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/e4e3a04d-0f76-4baf-9760-9992ef38d51f%40googlegroups.com?utm_medium=email&utm_source=footer>.
>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golan...@ <>googlegroups.com <http://googlegroups.com/>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/cbbca787-1dec-4729-b91f-25a7b5725d80%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/cbbca787-1dec-4729-b91f-25a7b5725d80%40googlegroups.com?utm_medium=email&utm_source=footer>.
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/6a32824e-cd50-4fe6-9411-3ecb975718d5%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/6a32824e-cd50-4fe6-9411-3ecb975718d5%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/F3F3EB37-66C4-43DC-9001-C5139D0BF3E2%40ix.netcom.com.

Reply via email to