Skip to content

Commit

Permalink
app: [iOS] add support for buildmode exe
Browse files Browse the repository at this point in the history
Up until now, the iOS part has relied on a tool such as gogio to
synthesize a main function. This change adds support for running direcetly
in exe mode, while retaining support for embedded Gio in C programs.

Signed-off-by: Elias Naur <[email protected]>
  • Loading branch information
eliasnaur committed Jun 2, 2024
1 parent 175e134 commit e6da07a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
39 changes: 38 additions & 1 deletion app/os_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package app
#include <UIKit/UIKit.h>
#include <stdint.h>
__attribute__ ((visibility ("hidden"))) int gio_applicationMain(int argc, char *argv[]);
__attribute__ ((visibility ("hidden"))) void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle);
struct drawParams {
Expand Down Expand Up @@ -81,6 +82,7 @@ import "C"
import (
"image"
"io"
"os"
"runtime"
"runtime/cgo"
"runtime/debug"
Expand Down Expand Up @@ -394,12 +396,47 @@ func newWindow(win *callbacks, options []Option) {
<-mainWindow.windows
}

var mainMode = mainModeUndefined

const (
mainModeUndefined = iota
mainModeExe
mainModeLibrary
)

func osMain() {
if !isMainThread() {
panic("app.Main must be run on the main goroutine")
}
switch mainMode {
case mainModeUndefined:
mainMode = mainModeExe
var argv []*C.char
for _, arg := range os.Args {
a := C.CString(arg)
defer C.free(unsafe.Pointer(a))
argv = append(argv, a)
}
C.gio_applicationMain(C.int(len(argv)), unsafe.SliceData(argv))
case mainModeExe:
panic("app.Main may be called only once")
case mainModeLibrary:
// Do nothing, we're embedded as a library.
}
}

//export gio_runMain
func gio_runMain() {
runMain()
if !isMainThread() {
panic("app.Main must be run on the main goroutine")
}
switch mainMode {
case mainModeUndefined:
mainMode = mainModeLibrary
runMain()
case mainModeExe:
// Do nothing, main has already been called.
}
}

func (UIKitViewEvent) implementsViewEvent() {}
Expand Down
20 changes: 20 additions & 0 deletions app/os_ios.m
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,23 @@ void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle) {
GioView *v = (__bridge GioView *)viewRef;
v.handle = handle;
}

@interface _gioAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

@implementation _gioAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
GioViewController *controller = [[GioViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = controller;
[self.window makeKeyAndVisible];
return YES;
}
@end

int gio_applicationMain(int argc, char *argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([_gioAppDelegate class]));
}
}

0 comments on commit e6da07a

Please sign in to comment.