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.