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

View File

@ -1,13 +1,13 @@
package cocoa
// #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Cocoa -framework OpenGL -framework QuartzCore
//
// #cgo LDFLAGS: -framework Cocoa -framework OpenGL
//
// #include <stdlib.h>
// #include "input.h"
//
// void Start(size_t width, size_t height, size_t scale, const char* title);
// void WaitEvents(void);
// void PollEvents(void);
// void BeginDrawing(void);
// void EndDrawing(void);
//
@ -18,7 +18,6 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
"runtime"
"sync"
"time"
"unsafe"
)
@ -45,16 +44,13 @@ func (context *GameContext) InputState() ebiten.InputState {
}
type UI struct {
screenWidth int
screenHeight int
screenScale int
title string
updating chan struct{}
updated chan struct{}
input chan ebiten.InputState
graphicsDevice *opengl.Device
lock sync.Mutex
gameContext *GameContext
screenWidth int
screenHeight int
screenScale int
title string
graphicsDevice *opengl.Device
lock sync.Mutex
gameContext *GameContext
}
var currentUI *UI
@ -64,13 +60,10 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
panic("UI can't be duplicated.")
}
ui := &UI{
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
title: title,
updating: make(chan struct{}),
updated: make(chan struct{}),
input: make(chan ebiten.InputState),
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
title: title,
gameContext: &GameContext{
screenWidth: screenWidth,
screenHeight: screenHeight,
@ -81,24 +74,7 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
return ui
}
func (ui *UI) gameMainLoop(game ebiten.Game) {
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)
func (ui *UI) Start() {
cTitle := C.CString(ui.title)
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.screenScale),
cTitle)
C.WaitEvents()
C.PollEvents()
}
func (ui *UI) WaitEvents() {
C.WaitEvents()
func (ui *UI) PollEvents() {
C.PollEvents()
}
func (ui *UI) InitTextures(game ebiten.Game) {
func (ui *UI) InitTextures(f func(graphics.TextureFactory)) {
C.BeginDrawing()
game.InitTextures(ui.graphicsDevice.TextureFactory())
f(ui.graphicsDevice.TextureFactory())
C.EndDrawing()
}
func (ui *UI) Update(f func(ebiten.GameContext)) {
f(ui.gameContext)
}
func (ui *UI) Draw(f func(graphics.Context)) {
C.BeginDrawing()
ui.graphicsDevice.Update(f)
@ -136,14 +116,10 @@ func ebiten_EbitenOpenGLView_Initialized() {
currentUI.screenScale)
}
//export ebiten_EbitenOpenGLView_Updating
func ebiten_EbitenOpenGLView_Updating() {
}
//export ebiten_EbitenOpenGLView_InputUpdated
func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) {
if inputType == C.InputTypeMouseUp {
currentUI.input <- ebiten.InputState{-1, -1}
currentUI.gameContext.inputState = ebiten.InputState{-1, -1}
return
}
@ -160,5 +136,5 @@ func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) {
} else if currentUI.screenHeight <= y {
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 <QuartzCore/QuartzCore.h>
@interface EbitenOpenGLView : NSOpenGLView
//- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
@interface EbitenContentView : NSView
@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>
#import "ebiten_opengl_view.h"
#import "ebiten_content_view.h"
void ebiten_EbitenOpenGLView_Initialized(void);
@ -38,14 +38,10 @@ void ebiten_EbitenOpenGLView_Initialized(void);
[self setDocumentEdited:YES];
NSRect rect = NSMakeRect(0, 0, size.width, size.height);
NSView* contentView = [[NSView alloc] initWithFrame:rect];
NSView* contentView = [[EbitenContentView alloc] initWithFrame:rect];
[self setContentView:contentView];
return self;
/*EbitenOpenGLView* contentView =
[[EbitenOpenGLView alloc] initWithFrame:rect
pixelFormat:format];*/
}
- (NSOpenGLContext*)glContext {

View File

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