refactor: A little bit more similar iOS & MacOS

This commit is contained in:
Carlos Aragones 2020-05-17 21:22:12 +02:00
parent ed0afc6b22
commit 1c3054d320
2 changed files with 232 additions and 230 deletions

View File

@ -1,11 +1,12 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include <mach/mach_time.h> #include <mach/mach_time.h>
#include <MiniFB.h>
#include "MiniFB_internal.h"
#include "WindowData.h"
#include "WindowData_IOS.h"
#include "iOSViewController.h" #include "iOSViewController.h"
#include "WindowData_IOS.h"
#include <MiniFB.h>
#include <MiniFB_internal.h>
#include <WindowData.h>
//------------------------------------- //-------------------------------------
SWindowData * SWindowData *
@ -27,9 +28,9 @@ create_window_data(unsigned width, unsigned height) {
} }
memset((void *) window_data_ios, 0, sizeof(SWindowData_IOS)); memset((void *) window_data_ios, 0, sizeof(SWindowData_IOS));
float scale = [UIScreen mainScreen].scale; window_data->specific = window_data_ios;
window_data->specific = window_data_ios; float scale = [UIScreen mainScreen].scale;
window_data->window_width = [UIScreen mainScreen].bounds.size.width * scale; window_data->window_width = [UIScreen mainScreen].bounds.size.width * scale;
window_data->window_height = [UIScreen mainScreen].bounds.size.height * scale; window_data->window_height = [UIScreen mainScreen].bounds.size.height * scale;
@ -43,8 +44,8 @@ create_window_data(unsigned width, unsigned height) {
window_data->draw_buffer = malloc(width * height * 4); window_data->draw_buffer = malloc(width * height * 4);
if (!window_data->draw_buffer) { if (!window_data->draw_buffer) {
free(window_data);
free(window_data_ios); free(window_data_ios);
free(window_data);
NSLog(@"Unable to create draw buffer"); NSLog(@"Unable to create draw buffer");
return 0x0; return 0x0;
} }
@ -68,38 +69,40 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
kUnused(title); kUnused(title);
kUnused(flags); kUnused(flags);
SWindowData *window_data = create_window_data(width, height); @autoreleasepool {
if (window_data == 0x0) { SWindowData *window_data = create_window_data(width, height);
return 0x0; if (window_data == 0x0) {
} return 0x0;
}
windows = [[UIApplication sharedApplication] windows]; windows = [[UIApplication sharedApplication] windows];
numWindows = [windows count]; numWindows = [windows count];
if(numWindows > 0) { if(numWindows > 0) {
window = [windows objectAtIndex:0]; window = [windows objectAtIndex:0];
} }
else { else {
// Notice that you need to set "Launch Screen File" in: // Notice that you need to set "Launch Screen File" in:
// project > executable > general // project > executable > general
// to get the real size with [UIScreen mainScreen].bounds]. // to get the real size with [UIScreen mainScreen].bounds].
window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
NSLog(@"UIApplication has no window. We create one (%f, %f).", [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); NSLog(@"UIApplication has no window. We create one (%f, %f).", [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
} }
if([window.rootViewController isKindOfClass:[iOSViewController class]] == false) { if([window.rootViewController isKindOfClass:[iOSViewController class]] == false) {
iOSViewController *controller = [[iOSViewController alloc] initWithWindowData:window_data]; iOSViewController *controller = [[iOSViewController alloc] initWithWindowData:window_data];
[window setRootViewController:controller]; [window setRootViewController:controller];
#if !__has_feature(objc_arc) #if !__has_feature(objc_arc)
[controller release]; [controller release];
#endif #endif
controller = (iOSViewController *) window.rootViewController; controller = (iOSViewController *) window.rootViewController;
} }
else { else {
((iOSViewController *) window.rootViewController)->window_data = window_data; ((iOSViewController *) window.rootViewController)->window_data = window_data;
} }
[window makeKeyAndVisible]; [window makeKeyAndVisible];
return (struct mfb_window *) window_data; return (struct mfb_window *) window_data;
}
} }
//------------------------------------- //-------------------------------------
@ -144,7 +147,10 @@ mfb_update(struct mfb_window *window, void *buffer) {
//------------------------------------- //-------------------------------------
mfb_update_state mfb_update_state
mfb_update_events(struct mfb_window *window) { mfb_update_events(struct mfb_window *window) {
kUnused(window); if(window == 0x0) {
return STATE_INVALID_WINDOW;
}
return STATE_OK; return STATE_OK;
} }
@ -153,13 +159,20 @@ extern double g_time_for_frame;
bool bool
mfb_wait_sync(struct mfb_window *window) { mfb_wait_sync(struct mfb_window *window) {
kUnused(window); if(window == 0x0) {
return false;
}
return true; return true;
} }
//------------------------------------- //-------------------------------------
bool bool
mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) {
if(window == 0x0) {
return false;
}
SWindowData *window_data = (SWindowData *) window; SWindowData *window_data = (SWindowData *) window;
if(offset_x + width > window_data->window_width) { if(offset_x + width > window_data->window_width) {

View File

@ -1,10 +1,3 @@
#include "OSXWindow.h"
#include "OSXView.h"
#include "OSXViewDelegate.h"
#include "WindowData_OSX.h"
#include <MiniFB.h>
#include <MiniFB_enums.h>
#include <MiniFB_internal.h>
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#if defined(USE_METAL_API) #if defined(USE_METAL_API)
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
@ -14,20 +7,22 @@
#include <sched.h> #include <sched.h>
#include <mach/mach_time.h> #include <mach/mach_time.h>
#include "OSXWindow.h"
#include "OSXView.h"
#include "OSXViewDelegate.h"
#include "WindowData_OSX.h"
#include <MiniFB.h>
#include <MiniFB_internal.h>
#include <MiniFB_enums.h>
void init_keycodes(); void init_keycodes();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
struct mfb_window *
mfb_open(const char *title, unsigned width, unsigned height) {
return mfb_open_ex(title, width, height, 0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SWindowData * SWindowData *
create_window_data(unsigned width, unsigned height) { create_window_data(unsigned width, unsigned height) {
SWindowData *window_data = malloc(sizeof(SWindowData)); SWindowData *window_data;
window_data = malloc(sizeof(SWindowData));
if(window_data == 0x0) { if(window_data == 0x0) {
NSLog(@"Cannot allocate window data"); NSLog(@"Cannot allocate window data");
return 0x0; return 0x0;
@ -42,7 +37,7 @@ create_window_data(unsigned width, unsigned height) {
} }
memset(window_data_osx, 0, sizeof(SWindowData_OSX)); memset(window_data_osx, 0, sizeof(SWindowData_OSX));
window_data->specific = window_data_osx; window_data->specific = window_data_osx;
window_data->dst_width = width; window_data->dst_width = width;
window_data->dst_height = height; window_data->dst_height = height;
@ -64,162 +59,161 @@ create_window_data(unsigned width, unsigned height) {
return window_data; return window_data;
} }
//-------------------------------------
struct mfb_window * struct mfb_window *
mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) { mfb_open(const char *title, unsigned width, unsigned height) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; return mfb_open_ex(title, width, height, 0);
SWindowData *window_data = create_window_data(width, height);
if (window_data == 0x0) {
return 0x0;
}
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
init_keycodes();
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
NSRect rectangle, frameRect;
NSWindowStyleMask styles = 0;
if (flags & WF_BORDERLESS) {
styles |= NSWindowStyleMaskBorderless;
}
else {
styles |= NSWindowStyleMaskClosable | NSWindowStyleMaskTitled;
}
if (flags & WF_RESIZABLE)
styles |= NSWindowStyleMaskResizable;
if (flags & WF_FULLSCREEN) {
styles = NSWindowStyleMaskFullScreen;
NSScreen *mainScreen = [NSScreen mainScreen];
NSRect screenRect = [mainScreen frame];
window_data->window_width = screenRect.size.width;
window_data->window_height = screenRect.size.height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = rectangle;
}
else if (flags & WF_FULLSCREEN_DESKTOP) {
NSScreen *mainScreen = [NSScreen mainScreen];
NSRect screenRect = [mainScreen visibleFrame];
window_data->window_width = screenRect.size.width;
window_data->window_height = screenRect.size.height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = rectangle;
}
else {
window_data->window_width = width;
window_data->window_height = height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = [NSWindow frameRectForContentRect:rectangle styleMask:styles];
}
window_data_osx->window = [[OSXWindow alloc] initWithContentRect:frameRect styleMask:styles backing:NSBackingStoreBuffered defer:NO windowData:window_data];
if (!window_data_osx->window) {
NSLog(@"Cannot create window");
if(window_data->draw_buffer != 0x0) {
free(window_data->draw_buffer);
window_data->draw_buffer = 0x0;
}
free(window_data_osx);
free(window_data);
return 0x0;
}
#if defined(USE_METAL_API)
OSXViewDelegate *viewController = [[OSXViewDelegate alloc] initWithWindowData:window_data];
MTKView* view = [[MTKView alloc] initWithFrame:rectangle];
view.device = viewController->metal_device;
view.delegate = viewController;
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[window_data_osx->window.contentView addSubview:view];
//[window_data->window updateSize];
#endif
[window_data_osx->window setTitle:[NSString stringWithUTF8String:title]];
[window_data_osx->window setReleasedWhenClosed:NO];
[window_data_osx->window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:YES];
[window_data_osx->window setAcceptsMouseMovedEvents:YES];
[window_data_osx->window center];
window_data_osx->timer = mfb_timer_create();
[NSApp activateIgnoringOtherApps:YES];
#if defined(USE_METAL_API)
[NSApp finishLaunching];
#endif
mfb_set_keyboard_callback((struct mfb_window *) window_data, keyboard_default);
#if defined(USE_METAL_API)
NSLog(@"Window created using Metal API");
#else
NSLog(@"Window created using Cocoa API");
#endif
[pool drain];
return (struct mfb_window *) window_data;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
struct mfb_window *
mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) {
@autoreleasepool {
SWindowData *window_data = create_window_data(width, height);
if (window_data == 0x0) {
return 0x0;
}
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
init_keycodes();
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
NSRect rectangle, frameRect;
NSWindowStyleMask styles = 0;
if (flags & WF_BORDERLESS) {
styles |= NSWindowStyleMaskBorderless;
}
else {
styles |= NSWindowStyleMaskClosable | NSWindowStyleMaskTitled;
}
if (flags & WF_RESIZABLE)
styles |= NSWindowStyleMaskResizable;
if (flags & WF_FULLSCREEN) {
styles = NSWindowStyleMaskFullScreen;
NSScreen *mainScreen = [NSScreen mainScreen];
NSRect screenRect = [mainScreen frame];
window_data->window_width = screenRect.size.width;
window_data->window_height = screenRect.size.height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = rectangle;
}
else if (flags & WF_FULLSCREEN_DESKTOP) {
NSScreen *mainScreen = [NSScreen mainScreen];
NSRect screenRect = [mainScreen visibleFrame];
window_data->window_width = screenRect.size.width;
window_data->window_height = screenRect.size.height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = rectangle;
}
else {
window_data->window_width = width;
window_data->window_height = height;
rectangle = NSMakeRect(0, 0, window_data->window_width, window_data->window_height);
frameRect = [NSWindow frameRectForContentRect:rectangle styleMask:styles];
}
window_data_osx->window = [[OSXWindow alloc] initWithContentRect:frameRect styleMask:styles backing:NSBackingStoreBuffered defer:NO windowData:window_data];
if (!window_data_osx->window) {
NSLog(@"Cannot create window");
if(window_data->draw_buffer != 0x0) {
free(window_data->draw_buffer);
window_data->draw_buffer = 0x0;
}
free(window_data_osx);
free(window_data);
return 0x0;
}
#if defined(USE_METAL_API)
OSXViewDelegate *viewController = [[OSXViewDelegate alloc] initWithWindowData:window_data];
MTKView* view = [[MTKView alloc] initWithFrame:rectangle];
view.device = viewController->metal_device;
view.delegate = viewController;
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[window_data_osx->window.contentView addSubview:view];
//[window_data->window updateSize];
#endif
[window_data_osx->window setTitle:[NSString stringWithUTF8String:title]];
[window_data_osx->window setReleasedWhenClosed:NO];
[window_data_osx->window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:YES];
[window_data_osx->window setAcceptsMouseMovedEvents:YES];
[window_data_osx->window center];
window_data_osx->timer = mfb_timer_create();
[NSApp activateIgnoringOtherApps:YES];
#if defined(USE_METAL_API)
[NSApp finishLaunching];
#endif
mfb_set_keyboard_callback((struct mfb_window *) window_data, keyboard_default);
#if defined(USE_METAL_API)
NSLog(@"Window created using Metal API");
#else
NSLog(@"Window created using Cocoa API");
#endif
return (struct mfb_window *) window_data;
}
}
//-------------------------------------
static void static void
destroy_window_data(SWindowData *window_data) { destroy_window_data(SWindowData *window_data) {
if(window_data == 0x0) if(window_data == 0x0)
return; return;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
if(window_data_osx != 0x0) {
OSXWindow *window = window_data_osx->window;
[window removeWindowData];
[window performClose:nil];
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific; mfb_timer_destroy(window_data_osx->timer);
if(window_data_osx != 0x0) {
OSXWindow *window = window_data_osx->window;
[window removeWindowData];
[window performClose:nil];
mfb_timer_destroy(window_data_osx->timer); memset(window_data_osx, 0, sizeof(SWindowData_OSX));
free(window_data_osx);
memset(window_data_osx, 0, sizeof(SWindowData_OSX)); }
free(window_data_osx);
}
#if defined(USE_METAL_API) #if defined(USE_METAL_API)
if(window_data->draw_buffer != 0x0) { if(window_data->draw_buffer != 0x0) {
free(window_data->draw_buffer); free(window_data->draw_buffer);
window_data->draw_buffer = 0x0; window_data->draw_buffer = 0x0;
} }
#endif #endif
memset(window_data, 0, sizeof(SWindowData)); memset(window_data, 0, sizeof(SWindowData));
free(window_data); free(window_data);
}
[pool drain];
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
static void static void
update_events(SWindowData *window_data) { update_events(SWindowData *window_data) {
NSEvent* event; NSEvent* event;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
do { do {
event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event) { if (event) {
[NSApp sendEvent:event]; [NSApp sendEvent:event];
} }
} while ((window_data->close == false) && event); } while ((window_data->close == false) && event);
}
[pool release];
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
mfb_update_state mfb_update_state
mfb_update(struct mfb_window *window, void *buffer) { mfb_update(struct mfb_window *window, void *buffer) {
if(window == 0x0) { if(window == 0x0) {
@ -254,8 +248,7 @@ mfb_update(struct mfb_window *window, void *buffer) {
return STATE_OK; return STATE_OK;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
mfb_update_state mfb_update_state
mfb_update_events(struct mfb_window *window) { mfb_update_events(struct mfb_window *window) {
if(window == 0x0) { if(window == 0x0) {
@ -280,8 +273,7 @@ mfb_update_events(struct mfb_window *window) {
return STATE_OK; return STATE_OK;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
extern double g_time_for_frame; extern double g_time_for_frame;
bool bool
@ -289,7 +281,7 @@ mfb_wait_sync(struct mfb_window *window) {
NSEvent* event; NSEvent* event;
if(window == 0x0) { if(window == 0x0) {
return STATE_INVALID_WINDOW; return false;
} }
SWindowData *window_data = (SWindowData *) window; SWindowData *window_data = (SWindowData *) window;
@ -298,46 +290,43 @@ mfb_wait_sync(struct mfb_window *window) {
return false; return false;
} }
//NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific; if(window_data_osx == 0x0) {
if(window_data_osx == 0x0) {
return false;
}
double current;
uint32_t millis = 1;
while(1) {
event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event) {
[NSApp sendEvent:event];
}
if(window_data->close) {
destroy_window_data(window_data);
return false; return false;
} }
current = mfb_timer_now(window_data_osx->timer); double current;
if (current >= g_time_for_frame) { uint32_t millis = 1;
mfb_timer_reset(window_data_osx->timer); while(1) {
return true; event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
} if (event) {
else if(current >= g_time_for_frame * 0.8) { [NSApp sendEvent:event];
millis = 0; }
}
usleep(millis * 1000); if(window_data->close) {
//sched_yield(); destroy_window_data(window_data);
return false;
}
current = mfb_timer_now(window_data_osx->timer);
if (current >= g_time_for_frame) {
mfb_timer_reset(window_data_osx->timer);
return true;
}
else if(current >= g_time_for_frame * 0.8) {
millis = 0;
}
usleep(millis * 1000);
//sched_yield();
}
} }
//[pool release];
return true; return true;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
bool bool
mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) {
if(window == 0x0) { if(window == 0x0) {
@ -382,8 +371,7 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y
return true; return true;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
extern short int g_keycodes[512]; extern short int g_keycodes[512];
void void
@ -508,8 +496,7 @@ init_keycodes() {
g_keycodes[0x4E] = KB_KEY_KP_SUBTRACT; g_keycodes[0x4E] = KB_KEY_KP_SUBTRACT;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------
extern double g_timer_frequency; extern double g_timer_frequency;
extern double g_timer_resolution; extern double g_timer_resolution;
@ -534,8 +521,10 @@ mfb_timer_tick() {
return (high << 32) + highRem + low; return (high << 32) + highRem + low;
} }
//-------------------------------------
void void
mfb_timer_init() { mfb_timer_init() {
g_timer_frequency = 1e+9; g_timer_frequency = 1e+9;
g_timer_resolution = 1.0 / g_timer_frequency; g_timer_resolution = 1.0 / g_timer_frequency;
} }