Add methods to ui/cocoa/texture_factory.go

This commit is contained in:
Hajime Hoshi 2014-01-07 00:10:46 +09:00
parent 0829299fea
commit 1f1c5cba95
6 changed files with 100 additions and 83 deletions

View File

@ -59,6 +59,8 @@ func main() {
} }
}() }()
//u.MainLoop()
for { for {
u.PollEvents() u.PollEvents()
select { select {

View File

@ -26,31 +26,31 @@ import (
) )
type GameWindow struct { type GameWindow struct {
ui *cocoaUI graphicsDevice *opengl.Device
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
closed bool closed bool
native *C.EbitenGameWindow native *C.EbitenGameWindow
pressedKeys map[ui.Key]struct{} pressedKeys map[ui.Key]struct{}
context *opengl.Context context *opengl.Context
funcs chan func() funcs chan func()
funcsDone chan struct{} funcsDone chan struct{}
events chan interface{} events chan interface{}
} }
var windows = map[*C.EbitenGameWindow]*GameWindow{} var windows = map[*C.EbitenGameWindow]*GameWindow{}
func runGameWindow(cocoaUI *cocoaUI, width, height, scale int, title string, sharedContext *C.NSOpenGLContext) *GameWindow { func runGameWindow(graphicsDevice *opengl.Device, width, height, scale int, title string, sharedContext *C.NSOpenGLContext) *GameWindow {
w := &GameWindow{ w := &GameWindow{
ui: cocoaUI, graphicsDevice: graphicsDevice,
screenWidth: width, screenWidth: width,
screenHeight: height, screenHeight: height,
screenScale: scale, screenScale: scale,
closed: false, closed: false,
pressedKeys: map[ui.Key]struct{}{}, pressedKeys: map[ui.Key]struct{}{},
funcs: make(chan func()), funcs: make(chan func()),
funcsDone: make(chan struct{}), funcsDone: make(chan struct{}),
} }
cTitle := C.CString(title) cTitle := C.CString(title)
@ -70,7 +70,7 @@ func runGameWindow(cocoaUI *cocoaUI, width, height, scale int, title string, sha
}() }()
<-ch <-ch
w.useGLContext(func() { w.useGLContext(func() {
w.context = w.ui.graphicsDevice.CreateContext(width, height, scale) w.context = w.graphicsDevice.CreateContext(width, height, scale)
}) })
return w return w
} }
@ -93,7 +93,7 @@ func (w *GameWindow) Draw(f func(graphics.Context)) {
return return
} }
w.useGLContext(func() { w.useGLContext(func() {
w.ui.graphicsDevice.Update(w.context, f) w.graphicsDevice.Update(w.context, f)
}) })
} }

View File

@ -25,6 +25,15 @@ void initMenu(void) {
keyEquivalent:@"q"]; keyEquivalent:@"q"];
} }
void Run(void) {
NSAutoreleasePool * pool = [NSAutoreleasePool new];
NSApplication* app = [NSApplication sharedApplication];
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
//initMenu();
[app run];
[pool drain];
}
void StartApplication(void) { void StartApplication(void) {
NSApplication* app = [NSApplication sharedApplication]; NSApplication* app = [NSApplication sharedApplication];
[app setActivationPolicy:NSApplicationActivationPolicyRegular]; [app setActivationPolicy:NSApplicationActivationPolicyRegular];

View File

@ -8,13 +8,18 @@ package cocoa
// //
import "C" import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
"image"
"runtime" "runtime"
) )
type textureFactory struct { type textureFactory struct {
sharedContext *C.NSOpenGLContext sharedContext *C.NSOpenGLContext
funcs chan func() graphicsDevice *opengl.Device
funcsDone chan struct{} events chan interface{}
funcs chan func()
funcsDone chan struct{}
} }
func runTextureFactory() *textureFactory { func runTextureFactory() *textureFactory {
@ -30,6 +35,9 @@ func runTextureFactory() *textureFactory {
t.loop() t.loop()
}() }()
<-ch <-ch
t.useGLContext(func() {
t.graphicsDevice = opengl.NewDevice()
})
return t return t
} }
@ -50,6 +58,52 @@ func (t *textureFactory) useGLContext(f func()) {
<-t.funcsDone <-t.funcsDone
} }
func (t *textureFactory) createGameWindow(ui *cocoaUI, width, height, scale int, title string) *GameWindow { func (t *textureFactory) createGameWindow(width, height, scale int, title string) *GameWindow {
return runGameWindow(ui, width, height, scale, title, t.sharedContext) return runGameWindow(t.graphicsDevice, width, height, scale, title, t.sharedContext)
}
func (t *textureFactory) Events() <-chan interface{} {
if t.events != nil {
return t.events
}
t.events = make(chan interface{})
return t.events
}
func (t *textureFactory) CreateTexture(tag interface{}, img image.Image, filter graphics.Filter) {
go func() {
var id graphics.TextureId
var err error
t.useGLContext(func() {
id, err = t.graphicsDevice.CreateTexture(img, filter)
})
if t.events == nil {
return
}
e := graphics.TextureCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
t.events <- e
}()
}
func (t *textureFactory) CreateRenderTarget(tag interface{}, width, height int) {
go func() {
var id graphics.RenderTargetId
var err error
t.useGLContext(func() {
id, err = t.graphicsDevice.CreateRenderTarget(width, height)
})
if t.events == nil {
return
}
e := graphics.RenderTargetCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
t.events <- e
}()
} }

View File

@ -3,21 +3,18 @@ package cocoa
// #cgo CFLAGS: -x objective-c // #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Cocoa -framework OpenGL // #cgo LDFLAGS: -framework Cocoa -framework OpenGL
// //
// void Run(void);
// void StartApplication(void); // void StartApplication(void);
// void PollEvents(void); // void PollEvents(void);
// //
import "C" import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
"github.com/hajimehoshi/go-ebiten/ui" "github.com/hajimehoshi/go-ebiten/ui"
"image"
) )
type cocoaUI struct { type cocoaUI struct {
textureFactory *textureFactory textureFactory *textureFactory
textureFactoryEvents chan interface{}
graphicsDevice *opengl.Device
} }
var currentUI *cocoaUI var currentUI *cocoaUI
@ -32,10 +29,6 @@ func getCurrentUI() *cocoaUI {
C.StartApplication() C.StartApplication()
currentUI.textureFactory = runTextureFactory() currentUI.textureFactory = runTextureFactory()
currentUI.textureFactory.useGLContext(func() {
currentUI.graphicsDevice = opengl.NewDevice()
})
return currentUI return currentUI
} }
@ -44,59 +37,17 @@ func UI() ui.UI {
} }
func TextureFactory() graphics.TextureFactory { func TextureFactory() graphics.TextureFactory {
return getCurrentUI() return getCurrentUI().textureFactory
} }
func (u *cocoaUI) CreateGameWindow(width, height, scale int, title string) ui.GameWindow { func (u *cocoaUI) CreateGameWindow(width, height, scale int, title string) ui.GameWindow {
return u.textureFactory.createGameWindow(u, width, height, scale, title) return u.textureFactory.createGameWindow(width, height, scale, title)
} }
func (u *cocoaUI) PollEvents() { func (u *cocoaUI) PollEvents() {
C.PollEvents() C.PollEvents()
} }
func (u *cocoaUI) Events() <-chan interface{} { func (u *cocoaUI) MainLoop() {
if u.textureFactoryEvents != nil { C.Run()
return u.textureFactoryEvents
}
u.textureFactoryEvents = make(chan interface{})
return u.textureFactoryEvents
}
func (u *cocoaUI) CreateTexture(tag interface{}, img image.Image, filter graphics.Filter) {
go func() {
var id graphics.TextureId
var err error
u.textureFactory.useGLContext(func() {
id, err = u.graphicsDevice.CreateTexture(img, filter)
})
if u.textureFactoryEvents == nil {
return
}
e := graphics.TextureCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
u.textureFactoryEvents <- e
}()
}
func (u *cocoaUI) CreateRenderTarget(tag interface{}, width, height int) {
go func() {
var id graphics.RenderTargetId
var err error
u.textureFactory.useGLContext(func() {
id, err = u.graphicsDevice.CreateRenderTarget(width, height)
})
if u.textureFactoryEvents == nil {
return
}
e := graphics.RenderTargetCreatedEvent{
Tag: tag,
Id: id,
Error: err,
}
u.textureFactoryEvents <- e
}()
} }

View File

@ -35,6 +35,7 @@ type WindowClosedEvent struct {
type UI interface { type UI interface {
PollEvents() PollEvents()
CreateGameWindow(screenWidth, screenHeight, screenScale int, title string) GameWindow CreateGameWindow(screenWidth, screenHeight, screenScale int, title string) GameWindow
MainLoop()
} }
type Window interface { type Window interface {
@ -43,5 +44,5 @@ type Window interface {
type GameWindow interface { type GameWindow interface {
Draw(func(graphics.Context)) Draw(func(graphics.Context))
Events() <-chan interface{} Window
} }