mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-02 09:17:19 -04:00
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
// Package d2thread is a package graciously taken from https://github.com/faiface/mainthread
|
|
package d2thread
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
// CallQueueCap is the capacity of the call queue. This means how many calls to CallNonBlock will not
|
|
// block until some call finishes.
|
|
//
|
|
// The default value is 16 and should be good for 99% usecases.
|
|
var (
|
|
callQueue chan func() //nolint:gochecknoglobals // necessary evil for now
|
|
)
|
|
|
|
func checkRun() {
|
|
if callQueue == nil {
|
|
panic(errors.New("mainthread: did not call Run"))
|
|
}
|
|
}
|
|
|
|
// Run enables mainthread package functionality. To use mainthread package, put your main function
|
|
// code into the run function (the argument to Run) and simply call Run from the real main function.
|
|
//
|
|
// Run returns when run (argument) function finishes.
|
|
func Run(run func()) {
|
|
var CallQueueCap = 16
|
|
|
|
callQueue = make(chan func(), CallQueueCap)
|
|
|
|
done := make(chan struct{})
|
|
|
|
go func() {
|
|
run()
|
|
done <- struct{}{}
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case f := <-callQueue:
|
|
f()
|
|
case <-done:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// CallNonBlock queues function f on the main thread and returns immediately. Does not wait until f
|
|
// finishes.
|
|
func CallNonBlock(f func()) {
|
|
checkRun()
|
|
callQueue <- f
|
|
}
|
|
|
|
// Call queues function f on the main thread and blocks until the function f finishes.
|
|
func Call(f func()) {
|
|
checkRun()
|
|
|
|
done := make(chan struct{})
|
|
callQueue <- func() {
|
|
f()
|
|
done <- struct{}{}
|
|
}
|
|
<-done
|
|
}
|
|
|
|
// CallErr queues function f on the main thread and returns an error returned by f.
|
|
func CallErr(f func() error) error {
|
|
checkRun()
|
|
|
|
errChan := make(chan error)
|
|
callQueue <- func() {
|
|
errChan <- f()
|
|
}
|
|
|
|
return <-errChan
|
|
}
|
|
|
|
// CallVal queues function f on the main thread and returns a value returned by f.
|
|
func CallVal(f func() interface{}) interface{} {
|
|
checkRun()
|
|
|
|
respChan := make(chan interface{})
|
|
callQueue <- func() {
|
|
respChan <- f()
|
|
}
|
|
|
|
return <-respChan
|
|
}
|