ebiten/ui/cocoa/shared_context.go
2014-01-11 18:07:12 +09:00

122 lines
2.5 KiB
Go

package cocoa
// @class NSOpenGLContext;
//
// NSOpenGLContext* CreateGLContext(NSOpenGLContext* sharedGLContext);
// void UseGLContext(NSOpenGLContext* glContext);
// void UnuseGLContext(void);
//
import "C"
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
"image"
"runtime"
)
type sharedContext struct {
inited chan struct{}
sharedContext *opengl.SharedContext
events chan interface{}
funcs chan func()
funcsDone chan struct{}
gameWindows chan *GameWindow
}
func newSharedContext() *sharedContext {
return &sharedContext{
inited: make(chan struct{}),
funcs: make(chan func()),
funcsDone: make(chan struct{}),
gameWindows: make(chan *GameWindow),
}
}
func (t *sharedContext) run() {
var sharedGLContext *C.NSOpenGLContext
go func() {
runtime.LockOSThread()
t.sharedContext = opengl.Initialize()
sharedGLContext = C.CreateGLContext(nil)
close(t.inited)
t.loop(sharedGLContext)
}()
<-t.inited
go func() {
for w := range t.gameWindows {
w.run(t.sharedContext, sharedGLContext)
}
}()
}
func (t *sharedContext) loop(sharedGLContext *C.NSOpenGLContext) {
for {
select {
case f := <-t.funcs:
C.UseGLContext(sharedGLContext)
f()
C.UnuseGLContext()
t.funcsDone <- struct{}{}
}
}
}
func (t *sharedContext) useGLContext(f func()) {
t.funcs <- f
<-t.funcsDone
}
func (t *sharedContext) createGameWindow(width, height, scale int, title string) *GameWindow {
w := newGameWindow(width, height, scale, title)
go func() {
t.gameWindows <- w
}()
return w
}
func (t *sharedContext) Events() <-chan interface{} {
if t.events != nil {
return t.events
}
t.events = make(chan interface{})
return t.events
}
func (t *sharedContext) CreateTexture(tag interface{}, img image.Image, filter graphics.Filter) {
go func() {
<-t.inited
var id graphics.TextureId
var err error
t.useGLContext(func() {
id, err = t.sharedContext.CreateTexture(img, filter)
})
if t.events == nil {
return
}
t.events <- graphics.TextureCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
}()
}
func (t *sharedContext) CreateRenderTarget(tag interface{}, width, height int, filter graphics.Filter) {
go func() {
<-t.inited
var id graphics.RenderTargetId
var err error
t.useGLContext(func() {
id, err = t.sharedContext.CreateRenderTarget(width, height, filter)
})
if t.events == nil {
return
}
t.events <- graphics.RenderTargetCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
}()
}