app: darwin/arm{,64} event model implementation
Change-Id: Ie04a58ac090d8916463586b5fadb14c5539a21dd Reviewed-on: https://go-review.googlesource.com/11640 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
parent
9ed16d2774
commit
20f0df5da5
@ -24,6 +24,7 @@ import "C"
|
||||
import (
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
@ -46,79 +47,59 @@ func init() {
|
||||
initThreadID = uint64(C.threadID())
|
||||
}
|
||||
|
||||
func run(cbs []Callbacks) {
|
||||
func main(f func(App)) {
|
||||
if tid := uint64(C.threadID()); tid != initThreadID {
|
||||
log.Fatalf("app.Run called on thread %d, but app.init ran on %d", tid, initThreadID)
|
||||
}
|
||||
close(mainCalled)
|
||||
callbacks = cbs
|
||||
|
||||
go func() {
|
||||
f(app{})
|
||||
// TODO(crawshaw): trigger runApp to return
|
||||
}()
|
||||
C.runApp()
|
||||
panic("unexpected return from app.runApp")
|
||||
}
|
||||
|
||||
// TODO(crawshaw): determine minimum iOS version and remove irrelevant devices.
|
||||
var machinePPI = map[string]int{
|
||||
"i386": 163, // simulator
|
||||
"x86_64": 163, // simulator
|
||||
"iPod1,1": 163, // iPod Touch gen1
|
||||
"iPod2,1": 163, // iPod Touch gen2
|
||||
"iPod3,1": 163, // iPod Touch gen3
|
||||
"iPod4,1": 326, // iPod Touch gen4
|
||||
"iPod5,1": 326, // iPod Touch gen5
|
||||
"iPhone1,1": 163, // iPhone
|
||||
"iPhone1,2": 163, // iPhone 3G
|
||||
"iPhone2,1": 163, // iPhone 3GS
|
||||
"iPad1,1": 132, // iPad gen1
|
||||
"iPad2,1": 132, // iPad gen2
|
||||
"iPad2,2": 132, // iPad gen2 GSM
|
||||
"iPad2,3": 132, // iPad gen2 CDMA
|
||||
"iPad2,4": 132, // iPad gen2
|
||||
"iPad2,5": 163, // iPad Mini gen1
|
||||
"iPad2,6": 163, // iPad Mini gen1 AT&T
|
||||
"iPad2,7": 163, // iPad Mini gen1 VZ
|
||||
"iPad3,1": 264, // iPad gen3
|
||||
"iPad3,2": 264, // iPad gen3 VZ
|
||||
"iPad3,3": 264, // iPad gen3 AT&T
|
||||
"iPad3,4": 264, // iPad gen4
|
||||
"iPad3,5": 264, // iPad gen4 AT&T
|
||||
"iPad3,6": 264, // iPad gen4 VZ
|
||||
"iPad4,1": 264, // iPad Air wifi
|
||||
"iPad4,2": 264, // iPad Air LTE
|
||||
"iPad4,3": 264, // iPad Air LTE China
|
||||
"iPad4,4": 326, // iPad Mini gen2 wifi
|
||||
"iPad4,5": 326, // iPad Mini gen2 LTE
|
||||
"iPad4,6": 326, // iPad Mini 3
|
||||
"iPad4,7": 326, // iPad Mini 3
|
||||
"iPhone3,1": 326, // iPhone 4
|
||||
"iPhone4,1": 326, // iPhone 4S
|
||||
"iPhone5,1": 326, // iPhone 5
|
||||
"iPhone5,2": 326, // iPhone 5
|
||||
"iPhone5,3": 326, // iPhone 5c
|
||||
"iPhone5,4": 326, // iPhone 5c
|
||||
"iPhone6,1": 326, // iPhone 5s
|
||||
"iPhone6,2": 326, // iPhone 5s
|
||||
"iPhone7,1": 401, // iPhone 6 Plus
|
||||
"iPhone7,2": 326, // iPhone 6
|
||||
}
|
||||
var screenScale int // [UIScreen mainScreen].scale, either 1, 2, or 3.
|
||||
|
||||
func ppi() int {
|
||||
//export setScreen
|
||||
func setScreen(scale int) {
|
||||
C.uname(&C.sysInfo)
|
||||
name := C.GoString(&C.sysInfo.machine[0])
|
||||
v, ok := machinePPI[name]
|
||||
if !ok {
|
||||
|
||||
var v float32
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(name, "iPhone"):
|
||||
v = 163
|
||||
case strings.HasPrefix(name, "iPad"):
|
||||
// TODO: is there a better way to distinguish the iPad Mini?
|
||||
switch name {
|
||||
case "iPad2,5", "iPad2,6", "iPad2,7", "iPad4,4", "iPad4,5", "iPad4,6", "iPad4,7":
|
||||
v = 163 // iPad Mini
|
||||
default:
|
||||
v = 132
|
||||
}
|
||||
default:
|
||||
v = 163 // names like i386 and x86_64 are the simulator
|
||||
}
|
||||
|
||||
if v == 0 {
|
||||
log.Printf("unknown machine: %s", name)
|
||||
v = 163 // emergency fallback
|
||||
}
|
||||
return v
|
||||
|
||||
pixelsPerPt = v * float32(scale) / 72
|
||||
screenScale = scale
|
||||
}
|
||||
|
||||
//export setGeom
|
||||
func setGeom(width, height int) {
|
||||
if geom.PixelsPerPt == 0 {
|
||||
geom.PixelsPerPt = float32(ppi()) / 72
|
||||
//export updateConfig
|
||||
func updateConfig(width, height int) {
|
||||
eventsIn <- event.Config{
|
||||
Width: geom.Pt(float32(screenScale*width) / pixelsPerPt),
|
||||
Height: geom.Pt(float32(screenScale*height) / pixelsPerPt),
|
||||
PixelsPerPt: pixelsPerPt,
|
||||
}
|
||||
configAlt.Width = geom.Pt(float32(width) / geom.PixelsPerPt)
|
||||
configAlt.Height = geom.Pt(float32(height) / geom.PixelsPerPt)
|
||||
configSwap(callbacks)
|
||||
}
|
||||
|
||||
var startedgl = false
|
||||
@ -162,43 +143,33 @@ func sendTouch(touch uintptr, touchType int, x, y float32) {
|
||||
touchIDs[id] = 0
|
||||
}
|
||||
|
||||
touchEvents.Lock()
|
||||
touchEvents.pending = append(touchEvents.pending, event.Touch{
|
||||
eventsIn <- event.Touch{
|
||||
ID: event.TouchSequenceID(id),
|
||||
Type: ty,
|
||||
Loc: geom.Point{
|
||||
X: geom.Pt(x / geom.PixelsPerPt),
|
||||
Y: geom.Pt(y / geom.PixelsPerPt),
|
||||
X: geom.Pt(x / pixelsPerPt),
|
||||
Y: geom.Pt(y / pixelsPerPt),
|
||||
},
|
||||
})
|
||||
touchEvents.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
//export drawgl
|
||||
func drawgl(ctx uintptr) {
|
||||
if !startedgl {
|
||||
startedgl = true
|
||||
go gl.Start(func() {
|
||||
C.setContext(unsafe.Pointer(ctx))
|
||||
})
|
||||
stateStart(callbacks)
|
||||
C.setContext(unsafe.Pointer(ctx))
|
||||
// TODO(crawshaw): not just on process start.
|
||||
sendLifecycle(event.LifecycleStageFocused)
|
||||
}
|
||||
|
||||
touchEvents.Lock()
|
||||
pending := touchEvents.pending
|
||||
touchEvents.pending = nil
|
||||
touchEvents.Unlock()
|
||||
for _, cb := range callbacks {
|
||||
if cb.Touch != nil {
|
||||
for _, e := range pending {
|
||||
cb.Touch(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
eventsIn <- event.Draw{}
|
||||
|
||||
for _, cb := range callbacks {
|
||||
if cb.Draw != nil {
|
||||
cb.Draw()
|
||||
for {
|
||||
select {
|
||||
case <-gl.WorkAvailable:
|
||||
gl.DoWork()
|
||||
case <-endDraw:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
struct utsname sysInfo;
|
||||
|
||||
@interface GoAppAppController : GLKViewController
|
||||
@interface GoAppAppController : GLKViewController<UIContentContainer>
|
||||
@end
|
||||
|
||||
@interface GoAppAppDelegate : UIResponder<UIApplicationDelegate>
|
||||
@ -40,19 +40,28 @@ struct utsname sysInfo;
|
||||
@implementation GoAppAppController
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.preferredFramesPerSecond = 60;
|
||||
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
view.context = self.context;
|
||||
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
||||
view.multipleTouchEnabled = true; // TODO expose setting to user.
|
||||
|
||||
int scale = 1;
|
||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)]) {
|
||||
scale = (int)[UIScreen mainScreen].scale; // either 1.0, 2.0, or 3.0.
|
||||
}
|
||||
setScreen(scale);
|
||||
|
||||
CGSize size = [UIScreen mainScreen].bounds.size;
|
||||
updateConfig((int)size.width, (int)size.height);
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
updateConfig((int)size.width, (int)size.height);
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
int w = [view drawableWidth];
|
||||
int h = [view drawableHeight];
|
||||
setGeom(w, h);
|
||||
|
||||
drawgl((GoUintptr)self.context);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user