Last active
December 15, 2015 03:29
-
-
Save Niriel/5194870 to your computer and use it in GitHub Desktop.
This is how I lock SDL and OpenGl to the main thread in go.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============== threadlock.go | |
package threadlock | |
import "runtime" | |
// A threadlock contains a queue of functions to execute on a given OS thread. | |
type ThreadLock chan func() | |
// Blocking call that consumes the queue, executing all the functions until the channel is closed. | |
func (self ThreadLock) Lock() { | |
runtime.LockOSThread() // If thread is already locked, does nothing. | |
defer runtime.UnlockOSThread() // Totally unlocks even if the thread was locked several times. | |
// https://codereview.appspot.com/7197050/ about nesting LockOsThread | |
for f := range self { | |
f() | |
} | |
} | |
// Add a function to the queue and block until it is executed. | |
func (self ThreadLock) Run(f func()) { | |
done := make(chan bool, 1) | |
self <- func() { | |
f() | |
done <- true | |
} | |
<-done | |
} | |
//============== main.go | |
func init() { | |
runtime.LockOSThread() | |
} | |
func main() { | |
// Thanks to init, tl will run its functions on the main thread. | |
tl := make(threadlock.ThreadLock) | |
go Everything(tl) | |
tl.Lock() // `Everything` is responsible for closing tl and unblocking this .Lock() call. | |
} | |
func Everything(tl threadlock.ThreadLock) { | |
defer close(tl) | |
// Initializes SDL. | |
tl.Run(func() { | |
if status := sdl.Init(sdl.INIT_VIDEO); status != 0 { | |
panic("Could not initialize SDL: " + sdl.GetError()) | |
} | |
}) | |
defer tl.Run(func() { | |
sdl.Quit() | |
}) | |
// Initialises OpenGl. | |
tl.Run(func() { | |
sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1) | |
sdl.GL_SetAttribute(sdl.GL_DEPTH_SIZE, 16) | |
info := sdl.GetVideoInfo() | |
bpp := int(info.Vfmt.BitsPerPixel) | |
const FLAGS = sdl.OPENGL | |
if screen := sdl.SetVideoMode(640, 480, bpp, FLAGS); screen == nil { | |
panic("Could not open SDL window: " + sdl.GetError()) | |
} | |
if err := gl.Init(); err != nil { | |
panic(err) | |
} | |
}) | |
// etc.. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment