This commit is contained in:
Hajime Hoshi 2013-11-23 18:10:15 +09:00
parent 170ed689fa
commit 75a362d5b1
7 changed files with 82 additions and 178 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/hajimehoshi/go-ebiten/ui/cocoa" "github.com/hajimehoshi/go-ebiten/ui/cocoa"
"os" "os"
"runtime" "runtime"
"time"
) )
func main() { func main() {
@ -47,10 +48,18 @@ func main() {
const screenScale = 2 const screenScale = 2
const title = "Ebiten Demo" const title = "Ebiten Demo"
ui := cocoa.New(screenWidth, screenHeight, screenScale, title) ui := cocoa.New(screenWidth, screenHeight, screenScale, title)
ui.Start(game) ui.Start()
ui.InitTextures(game) ui.InitTextures(game.InitTextures)
frameTime := time.Duration(int64(time.Second) / int64(ebiten.FPS))
tick := time.Tick(frameTime)
for { for {
ui.WaitEvents() ui.PollEvents()
select {
case <-tick:
ui.Update(game.Update)
default:
}
ui.Draw(game.Draw) ui.Draw(game.Draw)
} }
} }

View File

@ -1,13 +1,13 @@
package cocoa package cocoa
// #cgo CFLAGS: -x objective-c // #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Cocoa -framework OpenGL -framework QuartzCore // #cgo LDFLAGS: -framework Cocoa -framework OpenGL
// //
// #include <stdlib.h> // #include <stdlib.h>
// #include "input.h" // #include "input.h"
// //
// void Start(size_t width, size_t height, size_t scale, const char* title); // void Start(size_t width, size_t height, size_t scale, const char* title);
// void WaitEvents(void); // void PollEvents(void);
// void BeginDrawing(void); // void BeginDrawing(void);
// void EndDrawing(void); // void EndDrawing(void);
// //
@ -18,7 +18,6 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics/opengl" "github.com/hajimehoshi/go-ebiten/graphics/opengl"
"runtime" "runtime"
"sync" "sync"
"time"
"unsafe" "unsafe"
) )
@ -45,16 +44,13 @@ func (context *GameContext) InputState() ebiten.InputState {
} }
type UI struct { type UI struct {
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
title string title string
updating chan struct{} graphicsDevice *opengl.Device
updated chan struct{} lock sync.Mutex
input chan ebiten.InputState gameContext *GameContext
graphicsDevice *opengl.Device
lock sync.Mutex
gameContext *GameContext
} }
var currentUI *UI var currentUI *UI
@ -64,13 +60,10 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
panic("UI can't be duplicated.") panic("UI can't be duplicated.")
} }
ui := &UI{ ui := &UI{
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
title: title, title: title,
updating: make(chan struct{}),
updated: make(chan struct{}),
input: make(chan ebiten.InputState),
gameContext: &GameContext{ gameContext: &GameContext{
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
@ -81,24 +74,7 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
return ui return ui
} }
func (ui *UI) gameMainLoop(game ebiten.Game) { func (ui *UI) Start() {
frameTime := time.Duration(int64(time.Second) / int64(ebiten.FPS))
tick := time.Tick(frameTime)
for {
select {
case ui.gameContext.inputState = <-ui.input:
case <-tick:
game.Update(ui.gameContext)
case ui.updating <- struct{}{}:
//ui.DrawGame(game)
<-ui.updated
}
}
}
func (ui *UI) Start(game ebiten.Game) {
go ui.gameMainLoop(game)
cTitle := C.CString(ui.title) cTitle := C.CString(ui.title)
defer C.free(unsafe.Pointer(cTitle)) defer C.free(unsafe.Pointer(cTitle))
@ -106,19 +82,23 @@ func (ui *UI) Start(game ebiten.Game) {
C.size_t(ui.screenHeight), C.size_t(ui.screenHeight),
C.size_t(ui.screenScale), C.size_t(ui.screenScale),
cTitle) cTitle)
C.WaitEvents() C.PollEvents()
} }
func (ui *UI) WaitEvents() { func (ui *UI) PollEvents() {
C.WaitEvents() C.PollEvents()
} }
func (ui *UI) InitTextures(game ebiten.Game) { func (ui *UI) InitTextures(f func(graphics.TextureFactory)) {
C.BeginDrawing() C.BeginDrawing()
game.InitTextures(ui.graphicsDevice.TextureFactory()) f(ui.graphicsDevice.TextureFactory())
C.EndDrawing() C.EndDrawing()
} }
func (ui *UI) Update(f func(ebiten.GameContext)) {
f(ui.gameContext)
}
func (ui *UI) Draw(f func(graphics.Context)) { func (ui *UI) Draw(f func(graphics.Context)) {
C.BeginDrawing() C.BeginDrawing()
ui.graphicsDevice.Update(f) ui.graphicsDevice.Update(f)
@ -136,14 +116,10 @@ func ebiten_EbitenOpenGLView_Initialized() {
currentUI.screenScale) currentUI.screenScale)
} }
//export ebiten_EbitenOpenGLView_Updating
func ebiten_EbitenOpenGLView_Updating() {
}
//export ebiten_EbitenOpenGLView_InputUpdated //export ebiten_EbitenOpenGLView_InputUpdated
func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) { func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) {
if inputType == C.InputTypeMouseUp { if inputType == C.InputTypeMouseUp {
currentUI.input <- ebiten.InputState{-1, -1} currentUI.gameContext.inputState = ebiten.InputState{-1, -1}
return return
} }
@ -160,5 +136,5 @@ func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) {
} else if currentUI.screenHeight <= y { } else if currentUI.screenHeight <= y {
y = currentUI.screenHeight - 1 y = currentUI.screenHeight - 1
} }
currentUI.input <- ebiten.InputState{x, y} currentUI.gameContext.inputState = ebiten.InputState{x, y}
} }

View File

@ -0,0 +1,40 @@
// -*- objc -*-
#include "ebiten_content_view.h"
#include "input.h"
void ebiten_EbitenOpenGLView_InputUpdated(InputType inputType, int x, int y);
@implementation EbitenContentView {
}
- (BOOL)isFlipped {
return YES;
}
- (void)mouseDown:(NSEvent*)theEvent {
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseDown, x, y);
}
- (void)mouseUp:(NSEvent*)theEvent {
(void)theEvent;
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseUp, x, y);
}
- (void)mouseDragged:(NSEvent*)theEvent {
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseDragged, x, y);
}
@end

View File

@ -6,9 +6,7 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
@interface EbitenOpenGLView : NSOpenGLView @interface EbitenContentView : NSView
//- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
@end @end

View File

@ -1,115 +0,0 @@
// -*- objc -*-
#include "ebiten_opengl_view.h"
#include "input.h"
void ebiten_EbitenOpenGLView_Initialized(void);
void ebiten_EbitenOpenGLView_Updating(void);
void ebiten_EbitenOpenGLView_InputUpdated(InputType inputType, int x, int y);
// Reference:
// http://developer.apple.com/library/mac/#qa/qa1385/_index.html
// http://www.alecjacobson.com/weblog/?p=2185
// TODO: Use NSViewController?
/*static CVReturn
EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
CVTimeStamp const* now,
CVTimeStamp const* outputTime,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* displayLinkContext) {
(void)displayLink;
(void)now;
(void)flagsIn;
(void)flagsOut;
@autoreleasepool {
EbitenOpenGLView* view = (__bridge EbitenOpenGLView*)displayLinkContext;
return [view getFrameForTime:outputTime];
}
}*/
@implementation EbitenOpenGLView {
/*@private
CVDisplayLinkRef displayLink_;*/
}
/*- (void)dealloc {
CVDisplayLinkRelease(self->displayLink_);
#if !__has_feature(objc_arc)
[super dealloc];
#endif
}*/
/*- (void)prepareOpenGL {
[super prepareOpenGL];
ebiten_EbitenOpenGLView_Initialized();
}*/
/*- (void)prepareOpenGL {
[super prepareOpenGL];
NSOpenGLContext* openGLContext = [self openGLContext];
assert(openGLContext != nil);
GLint swapInterval = 1;
[openGLContext setValues:&swapInterval
forParameter:NSOpenGLCPSwapInterval];
CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink_);
CVDisplayLinkSetOutputCallback(self->displayLink_,
&EbitenDisplayLinkCallback,
(__bridge void*)self);
CGLContextObj cglContext = (CGLContextObj)[openGLContext CGLContextObj];
CGLPixelFormatObj cglPixelFormat =
(CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink_,
cglContext,
cglPixelFormat);
CVDisplayLinkStart(self->displayLink_);
ebiten_EbitenOpenGLView_Initialized();
}*/
/*- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime {
(void)outputTime;
NSOpenGLContext* context = [self openGLContext];
assert(context != nil);
[context makeCurrentContext];
{
CGLLockContext((CGLContextObj)[context CGLContextObj]);
ebiten_EbitenOpenGLView_Updating();
[context flushBuffer];
CGLUnlockContext((CGLContextObj)[context CGLContextObj]);
}
return kCVReturnSuccess;
}*/
- (BOOL)isFlipped {
return YES;
}
- (void)mouseDown:(NSEvent*)theEvent {
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseDown, x, y);
}
- (void)mouseUp:(NSEvent*)theEvent {
(void)theEvent;
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseUp, x, y);
}
- (void)mouseDragged:(NSEvent*)theEvent {
NSPoint location = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
int x = location.x;
int y = location.y;
ebiten_EbitenOpenGLView_InputUpdated(InputTypeMouseDragged, x, y);
}
@end

View File

@ -4,7 +4,7 @@
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#import "ebiten_opengl_view.h" #import "ebiten_content_view.h"
void ebiten_EbitenOpenGLView_Initialized(void); void ebiten_EbitenOpenGLView_Initialized(void);
@ -38,14 +38,10 @@ void ebiten_EbitenOpenGLView_Initialized(void);
[self setDocumentEdited:YES]; [self setDocumentEdited:YES];
NSRect rect = NSMakeRect(0, 0, size.width, size.height); NSRect rect = NSMakeRect(0, 0, size.width, size.height);
NSView* contentView = [[NSView alloc] initWithFrame:rect]; NSView* contentView = [[EbitenContentView alloc] initWithFrame:rect];
[self setContentView:contentView]; [self setContentView:contentView];
return self; return self;
/*EbitenOpenGLView* contentView =
[[EbitenOpenGLView alloc] initWithFrame:rect
pixelFormat:format];*/
} }
- (NSOpenGLContext*)glContext { - (NSOpenGLContext*)glContext {

View File

@ -23,7 +23,7 @@ void Start(size_t width, size_t height, size_t scale, const char* title) {
currentWindow = window; currentWindow = window;
} }
void WaitEvents(void) { void PollEvents(void) {
for (;;) { for (;;) {
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast] untilDate:[NSDate distantPast]