In reviewing your comments so more, I think you may be having trouble because 
you are initializing the graphics UI in the init() method. I think that is 
going to make things difficult. You are better off adding a StartUI() - which 
spawns a Go routine that handles all UI communicates (you could spawn this from 
the init() but I think that might make things harder.

You can sync the calls so only a single routine/thread will ever be created.

> On Jan 3, 2020, at 6:04 PM, robert engels <reng...@ix.netcom.com> wrote:
> 
> 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 <mailto: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 
> <mailto: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
>  
> <https://groups.google.com/d/msgid/golang-nuts/F3F3EB37-66C4-43DC-9001-C5139D0BF3E2%40ix.netcom.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/FA205453-655B-42AD-98FD-81102DC0140B%40ix.netcom.com.

Reply via email to