diff --git a/app/os_ios.go b/app/os_ios.go index 0adfab29..b2f9fabd 100644 --- a/app/os_ios.go +++ b/app/os_ios.go @@ -12,6 +12,8 @@ package app #include #include +__attribute__ ((visibility ("hidden"))) void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle); + struct drawParams { CGFloat dpi, sdpi; CGFloat width, height; @@ -74,6 +76,7 @@ import ( "image" "io" "runtime" + "runtime/cgo" "runtime/debug" "strings" "time" @@ -110,8 +113,6 @@ type window struct { var mainWindow = newWindowRendezvous() -var views = make(map[C.CFTypeRef]*window) - func init() { // Darwin requires UI operations happen on the main thread only. runtime.LockOSThread() @@ -135,15 +136,19 @@ func onCreate(view, controller C.CFTypeRef) { return } w.displayLink = dl - views[view] = w + C.gio_viewSetHandle(view, C.uintptr_t(cgo.NewHandle(w))) w.Configure(wopts.options) w.ProcessEvent(StageEvent{Stage: StageRunning}) w.ProcessEvent(ViewEvent{ViewController: uintptr(controller)}) } +func viewFor(h C.uintptr_t) *window { + return cgo.Handle(h).Value().(*window) +} + //export gio_onDraw -func gio_onDraw(view C.CFTypeRef) { - w := views[view] +func gio_onDraw(h C.uintptr_t) { + w := viewFor(h) w.draw(true) } @@ -181,34 +186,34 @@ func (w *window) draw(sync bool) { } //export onStop -func onStop(view C.CFTypeRef) { - w := views[view] +func onStop(h C.uintptr_t) { + w := viewFor(h) w.hidden = true w.ProcessEvent(StageEvent{Stage: StagePaused}) } //export onStart -func onStart(view C.CFTypeRef) { - w := views[view] +func onStart(h C.uintptr_t) { + w := viewFor(h) w.hidden = false w.ProcessEvent(StageEvent{Stage: StageRunning}) w.draw(true) } //export onDestroy -func onDestroy(view C.CFTypeRef) { - w := views[view] +func onDestroy(h C.uintptr_t) { + w := viewFor(h) w.ProcessEvent(ViewEvent{}) w.ProcessEvent(DestroyEvent{}) w.displayLink.Close() w.displayLink = nil - delete(views, view) + cgo.Handle(h).Delete() w.view = 0 } //export onFocus -func onFocus(view C.CFTypeRef, focus int) { - w := views[view] +func onFocus(h C.uintptr_t, focus int) { + w := viewFor(h) w.ProcessEvent(key.FocusEvent{Focus: focus != 0}) } @@ -219,38 +224,38 @@ func onLowMemory() { } //export onUpArrow -func onUpArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameUpArrow) +func onUpArrow(h C.uintptr_t) { + viewFor(h).onKeyCommand(key.NameUpArrow) } //export onDownArrow -func onDownArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameDownArrow) +func onDownArrow(h C.uintptr_t) { + viewFor(h).onKeyCommand(key.NameDownArrow) } //export onLeftArrow -func onLeftArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameLeftArrow) +func onLeftArrow(h C.uintptr_t) { + viewFor(h).onKeyCommand(key.NameLeftArrow) } //export onRightArrow -func onRightArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameRightArrow) +func onRightArrow(h C.uintptr_t) { + viewFor(h).onKeyCommand(key.NameRightArrow) } //export onDeleteBackward -func onDeleteBackward(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameDeleteBackward) +func onDeleteBackward(h C.uintptr_t) { + viewFor(h).onKeyCommand(key.NameDeleteBackward) } //export onText -func onText(view, str C.CFTypeRef) { - w := views[view] +func onText(h C.uintptr_t, str C.CFTypeRef) { + w := viewFor(h) w.w.EditorInsert(nsstringToString(str)) } //export onTouch -func onTouch(last C.int, view, touchRef C.CFTypeRef, phase C.NSInteger, x, y C.CGFloat, ti C.double) { +func onTouch(h C.uintptr_t, last C.int, touchRef C.CFTypeRef, phase C.NSInteger, x, y C.CGFloat, ti C.double) { var kind pointer.Kind switch phase { case C.UITouchPhaseBegan: @@ -264,7 +269,7 @@ func onTouch(last C.int, view, touchRef C.CFTypeRef, phase C.NSInteger, x, y C.C default: return } - w := views[view] + w := viewFor(h) t := time.Duration(float64(ti) * float64(time.Second)) p := f32.Point{X: float32(x), Y: float32(y)} w.ProcessEvent(pointer.Event{ diff --git a/app/os_ios.m b/app/os_ios.m index c185a431..1c3fe58f 100644 --- a/app/os_ios.m +++ b/app/os_ios.m @@ -11,6 +11,7 @@ __attribute__ ((visibility ("hidden"))) Class gio_layerClass(void); @interface GioView: UIView +@property uintptr_t handle; @end @implementation GioViewController @@ -54,33 +55,33 @@ CGFloat _keyboardHeight; } - (void)applicationWillEnterForeground:(UIApplication *)application { - UIView *drawView = self.view.subviews[0]; - if (drawView != nil) { - onStart((__bridge CFTypeRef)drawView); + GioView *view = (GioView *)self.view.subviews[0]; + if (view != nil) { + onStart(view.handle); } } - (void)applicationDidEnterBackground:(UIApplication *)application { - UIView *drawView = self.view.subviews[0]; - if (drawView != nil) { - onStop((__bridge CFTypeRef)drawView); + GioView *view = (GioView *)self.view.subviews[0]; + if (view != nil) { + onStop(view.handle); } } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; - CFTypeRef viewRef = (__bridge CFTypeRef)self.view.subviews[0]; - onDestroy(viewRef); + GioView *view = (GioView *)self.view.subviews[0]; + onDestroy(view.handle); } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; - UIView *view = self.view.subviews[0]; + GioView *view = (GioView *)self.view.subviews[0]; CGRect frame = self.view.bounds; // Adjust view bounds to make room for the keyboard. frame.size.height -= _keyboardHeight; view.frame = frame; - gio_onDraw((__bridge CFTypeRef)view); + gio_onDraw(view.handle); } - (void)didReceiveMemoryWarning { @@ -101,11 +102,10 @@ CGFloat _keyboardHeight; } @end -static void handleTouches(int last, UIView *view, NSSet *touches, UIEvent *event) { +static void handleTouches(int last, GioView *view, NSSet *touches, UIEvent *event) { CGFloat scale = view.contentScaleFactor; NSUInteger i = 0; NSUInteger n = [touches count]; - CFTypeRef viewRef = (__bridge CFTypeRef)view; for (UITouch *touch in touches) { CFTypeRef touchRef = (__bridge CFTypeRef)touch; i++; @@ -116,7 +116,7 @@ static void handleTouches(int last, UIView *view, NSSet *touches, UIE CGPoint loc = [coalescedTouch locationInView:view]; j++; int lastTouch = last && i == n && j == m; - onTouch(lastTouch, viewRef, touchRef, touch.phase, loc.x*scale, loc.y*scale, [coalescedTouch timestamp]); + onTouch(view.handle, lastTouch, touchRef, touch.phase, loc.x*scale, loc.y*scale, [coalescedTouch timestamp]); } } } @@ -151,13 +151,13 @@ NSArray *_keyCommands; - (void)onWindowDidBecomeKey:(NSNotification *)note { if (self.isFirstResponder) { - onFocus((__bridge CFTypeRef)self, YES); + onFocus(self.handle, YES); } } - (void)onWindowDidResignKey:(NSNotification *)note { if (self.isFirstResponder) { - onFocus((__bridge CFTypeRef)self, NO); + onFocus(self.handle, NO); } } @@ -178,7 +178,7 @@ NSArray *_keyCommands; } - (void)insertText:(NSString *)text { - onText((__bridge CFTypeRef)self, (__bridge CFTypeRef)text); + onText(self.handle, (__bridge CFTypeRef)text); } - (BOOL)canBecomeFirstResponder { @@ -190,23 +190,23 @@ NSArray *_keyCommands; } - (void)deleteBackward { - onDeleteBackward((__bridge CFTypeRef)self); + onDeleteBackward(self.handle); } - (void)onUpArrow { - onUpArrow((__bridge CFTypeRef)self); + onUpArrow(self.handle); } - (void)onDownArrow { - onDownArrow((__bridge CFTypeRef)self); + onDownArrow(self.handle); } - (void)onLeftArrow { - onLeftArrow((__bridge CFTypeRef)self); + onLeftArrow(self.handle); } - (void)onRightArrow { - onRightArrow((__bridge CFTypeRef)self); + onRightArrow(self.handle); } - (NSArray *)keyCommands { @@ -271,3 +271,8 @@ void gio_showCursor() { void gio_setCursor(NSUInteger curID) { // Not supported. } + +void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle) { + GioView *v = (__bridge GioView *)viewRef; + v.handle = handle; +}