iOS: Refactoring

Enabled ARC for iOS.
Weakify/Strongify macros for objc blocks.
Removed old version checks.
Specific types for ObjC++ modules to exclude unneeded bridging.
Separate DeviceMetrics class for device specific data.
Replaced old/deprecated functionality.
This commit is contained in:
Sergey Minakov 2020-10-01 22:18:39 +03:00
parent 19f72beebb
commit 3cd1cb53a0
24 changed files with 323 additions and 353 deletions

View file

@ -386,7 +386,7 @@
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -416,7 +416,7 @@
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View file

@ -44,6 +44,15 @@
// forward declaration for some needed objects
class ARKitShader;
#ifdef __OBJC__
typedef ARAnchor GodotARAnchor;
#else
typedef void GodotARAnchor;
#endif
class ARKitInterface : public XRInterface {
GDCLASS(ARKitInterface, XRInterface);
@ -115,8 +124,8 @@ public:
virtual void process() override;
// called by delegate (void * because C++ and Obj-C don't always mix, should really change all platform/iphone/*.cpp files to .mm)
void _add_or_update_anchor(void *p_anchor);
void _remove_anchor(void *p_anchor);
void _add_or_update_anchor(GodotARAnchor *p_anchor);
void _remove_anchor(GodotARAnchor *p_anchor);
ARKitInterface();
~ARKitInterface();

View file

@ -306,12 +306,10 @@ void ARKitInterface::uninitialize() {
remove_all_anchors();
if (@available(iOS 11.0, *)) {
[ar_session release];
ar_session = NULL;
ar_session = nil;
}
[ar_delegate release];
ar_delegate = NULL;
ar_delegate = nil;
initialized = false;
session_was_started = false;
}
@ -687,7 +685,7 @@ void ARKitInterface::process() {
}
}
void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
void ARKitInterface::_add_or_update_anchor(GodotARAnchor *p_anchor) {
// _THREAD_SAFE_METHOD_
if (@available(iOS 11.0, *)) {
@ -749,7 +747,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
}
}
void ARKitInterface::_remove_anchor(void *p_anchor) {
void ARKitInterface::_remove_anchor(GodotARAnchor *p_anchor) {
// _THREAD_SAFE_METHOD_
if (@available(iOS 11.0, *)) {
@ -768,7 +766,7 @@ ARKitInterface::ARKitInterface() {
plane_detection_is_enabled = false;
light_estimation_is_enabled = false;
if (@available(iOS 11.0, *)) {
ar_session = NULL;
ar_session = nil;
}
z_near = 0.01;
z_far = 1000.0;

View file

@ -124,18 +124,12 @@
if (output) {
[self removeOutput:output];
[output setSampleBufferDelegate:nil queue:NULL];
[output release];
output = nil;
}
[self commitConfiguration];
}
- (void)dealloc {
// bye bye
[super dealloc];
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
// This gets called every time our camera has a new image for us to process.
// May need to investigate in a way to throttle this if we get more images then we're rendering frames..
@ -272,7 +266,6 @@ CameraFeedIOS::CameraFeedIOS() {
void CameraFeedIOS::set_device(AVCaptureDevice *p_device) {
device = p_device;
[device retain];
// get some info
NSString *device_name = p_device.localizedName;
@ -286,14 +279,12 @@ void CameraFeedIOS::set_device(AVCaptureDevice *p_device) {
};
CameraFeedIOS::~CameraFeedIOS() {
if (capture_session != NULL) {
[capture_session release];
capture_session = NULL;
if (capture_session) {
capture_session = nil;
};
if (device != NULL) {
[device release];
device = NULL;
if (device) {
device = nil;
};
};
@ -312,8 +303,7 @@ void CameraFeedIOS::deactivate_feed() {
// end camera capture if we have one
if (capture_session) {
[capture_session cleanup];
[capture_session release];
capture_session = NULL;
capture_session = nil;
};
};
@ -347,8 +337,6 @@ void CameraFeedIOS::deactivate_feed() {
// remove notifications
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil];
[super dealloc];
}
@end
@ -453,5 +441,5 @@ CameraIOS::CameraIOS() {
};
CameraIOS::~CameraIOS() {
[device_notifications release];
device_notifications = nil;
};

View file

@ -131,8 +131,7 @@ GD_PINVOKE_EXPORT void *xamarin_timezone_get_data(const char *p_name, uint32_t *
NSTimeZone *tz = nil;
if (p_name) {
NSString *n = [[NSString alloc] initWithUTF8String:p_name];
tz = [[[NSTimeZone alloc] initWithName:n] autorelease];
[n release];
tz = [[NSTimeZone alloc] initWithName:n];
} else {
tz = [NSTimeZone localTimeZone];
}

View file

@ -19,6 +19,7 @@ iphone_lib = [
"display_layer.mm",
"godot_view_renderer.mm",
"godot_view_gesture_recognizer.mm",
"device_metrics.m",
]
env_ios = env.Clone()

View file

@ -62,7 +62,7 @@ static ViewController *mainViewController = nil;
CGRect windowBounds = [[UIScreen mainScreen] bounds];
// Create a full-screen window
self.window = [[[UIWindow alloc] initWithFrame:windowBounds] autorelease];
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
@ -140,7 +140,6 @@ static ViewController *mainViewController = nil;
- (void)dealloc {
self.window = nil;
[super dealloc];
}
@end

View file

@ -129,7 +129,7 @@ def configure(env):
detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing"
"-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
" -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb"
' "-DIBOutlet=__attribute__((iboutlet))"'
@ -141,7 +141,7 @@ def configure(env):
detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
"-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
" -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=11.0"
" -isysroot $IPHONESDK".split()

View file

@ -0,0 +1,37 @@
/*************************************************************************/
/* device_metrics.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#import <Foundation/Foundation.h>
@interface GodotDeviceMetrics : NSObject
@property(nonatomic, class, readonly, strong) NSDictionary<NSArray *, NSNumber *> *dpiList;
@end

View file

@ -0,0 +1,152 @@
/*************************************************************************/
/* device_metrics.m */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#import "device_metrics.h"
@implementation GodotDeviceMetrics
+ (NSDictionary *)dpiList {
return @{
@[
@"iPad1,1",
@"iPad2,1",
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",
] : @132,
@[
@"iPhone1,1",
@"iPhone1,2",
@"iPhone2,1",
@"iPad2,5",
@"iPad2,6",
@"iPad2,7",
@"iPod1,1",
@"iPod2,1",
@"iPod3,1",
] : @163,
@[
@"iPad3,1",
@"iPad3,2",
@"iPad3,3",
@"iPad3,4",
@"iPad3,5",
@"iPad3,6",
@"iPad4,1",
@"iPad4,2",
@"iPad4,3",
@"iPad5,3",
@"iPad5,4",
@"iPad6,3",
@"iPad6,4",
@"iPad6,7",
@"iPad6,8",
@"iPad6,11",
@"iPad6,12",
@"iPad7,1",
@"iPad7,2",
@"iPad7,3",
@"iPad7,4",
@"iPad7,5",
@"iPad7,6",
@"iPad7,11",
@"iPad7,12",
@"iPad8,1",
@"iPad8,2",
@"iPad8,3",
@"iPad8,4",
@"iPad8,5",
@"iPad8,6",
@"iPad8,7",
@"iPad8,8",
@"iPad8,9",
@"iPad8,10",
@"iPad8,11",
@"iPad8,12",
@"iPad11,3",
@"iPad11,4",
] : @264,
@[
@"iPhone3,1",
@"iPhone3,2",
@"iPhone3,3",
@"iPhone4,1",
@"iPhone5,1",
@"iPhone5,2",
@"iPhone5,3",
@"iPhone5,4",
@"iPhone6,1",
@"iPhone6,2",
@"iPhone7,2",
@"iPhone8,1",
@"iPhone8,4",
@"iPhone9,1",
@"iPhone9,3",
@"iPhone10,1",
@"iPhone10,4",
@"iPhone11,8",
@"iPhone12,1",
@"iPhone12,8",
@"iPad4,4",
@"iPad4,5",
@"iPad4,6",
@"iPad4,7",
@"iPad4,8",
@"iPad4,9",
@"iPad5,1",
@"iPad5,2",
@"iPad11,1",
@"iPad11,2",
@"iPod4,1",
@"iPod5,1",
@"iPod7,1",
@"iPod9,1",
] : @326,
@[
@"iPhone7,1",
@"iPhone8,2",
@"iPhone9,2",
@"iPhone9,4",
@"iPhone10,2",
@"iPhone10,5",
] : @401,
@[
@"iPhone10,3",
@"iPhone10,6",
@"iPhone11,2",
@"iPhone11,4",
@"iPhone11,6",
@"iPhone12,3",
@"iPhone12,5",
] : @458,
};
}
@end

View file

@ -124,11 +124,8 @@
}
if (context) {
[context release];
context = nil;
}
[super dealloc];
}
- (BOOL)createFramebuffer {

View file

@ -32,6 +32,7 @@
#import "app_delegate.h"
#include "core/io/file_access_pack.h"
#include "core/project_settings.h"
#import "device_metrics.h"
#import "godot_view.h"
#include "ios.h"
#include "os_iphone.h"
@ -41,120 +42,6 @@
#import <sys/utsname.h>
static const float kDisplayServerIPhoneAcceleration = 1;
static NSDictionary *iOSModelToDPI = @{
@[
@"iPad1,1",
@"iPad2,1",
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",
] : @132,
@[
@"iPhone1,1",
@"iPhone1,2",
@"iPhone2,1",
@"iPad2,5",
@"iPad2,6",
@"iPad2,7",
@"iPod1,1",
@"iPod2,1",
@"iPod3,1",
] : @163,
@[
@"iPad3,1",
@"iPad3,2",
@"iPad3,3",
@"iPad3,4",
@"iPad3,5",
@"iPad3,6",
@"iPad4,1",
@"iPad4,2",
@"iPad4,3",
@"iPad5,3",
@"iPad5,4",
@"iPad6,3",
@"iPad6,4",
@"iPad6,7",
@"iPad6,8",
@"iPad6,11",
@"iPad6,12",
@"iPad7,1",
@"iPad7,2",
@"iPad7,3",
@"iPad7,4",
@"iPad7,5",
@"iPad7,6",
@"iPad7,11",
@"iPad7,12",
@"iPad8,1",
@"iPad8,2",
@"iPad8,3",
@"iPad8,4",
@"iPad8,5",
@"iPad8,6",
@"iPad8,7",
@"iPad8,8",
@"iPad8,9",
@"iPad8,10",
@"iPad8,11",
@"iPad8,12",
@"iPad11,3",
@"iPad11,4",
] : @264,
@[
@"iPhone3,1",
@"iPhone3,2",
@"iPhone3,3",
@"iPhone4,1",
@"iPhone5,1",
@"iPhone5,2",
@"iPhone5,3",
@"iPhone5,4",
@"iPhone6,1",
@"iPhone6,2",
@"iPhone7,2",
@"iPhone8,1",
@"iPhone8,4",
@"iPhone9,1",
@"iPhone9,3",
@"iPhone10,1",
@"iPhone10,4",
@"iPhone11,8",
@"iPhone12,1",
@"iPhone12,8",
@"iPad4,4",
@"iPad4,5",
@"iPad4,6",
@"iPad4,7",
@"iPad4,8",
@"iPad4,9",
@"iPad5,1",
@"iPad5,2",
@"iPad11,1",
@"iPad11,2",
@"iPod4,1",
@"iPod5,1",
@"iPod7,1",
@"iPod9,1",
] : @326,
@[
@"iPhone7,1",
@"iPhone8,2",
@"iPhone9,2",
@"iPhone9,4",
@"iPhone10,2",
@"iPhone10,5",
] : @401,
@[
@"iPhone10,3",
@"iPhone10,6",
@"iPhone11,2",
@"iPhone11,4",
@"iPhone11,6",
@"iPhone12,3",
@"iPhone12,5",
] : @458,
};
DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
return (DisplayServerIPhone *)DisplayServer::get_singleton();
@ -383,8 +270,7 @@ void DisplayServerIPhone::update_gravity(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_gravity(Vector3(p_x, p_y, p_z));
};
void DisplayServerIPhone::update_accelerometer(float p_x, float p_y,
float p_z) {
void DisplayServerIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
// Found out the Z should not be negated! Pass as is!
Vector3 v_accelerometer = Vector3(
p_x / kDisplayServerIPhoneAcceleration,
@ -392,39 +278,6 @@ void DisplayServerIPhone::update_accelerometer(float p_x, float p_y,
p_z / kDisplayServerIPhoneAcceleration);
Input::get_singleton()->set_accelerometer(v_accelerometer);
/*
if (p_x != last_accel.x) {
//printf("updating accel x %f\n", p_x);
InputEvent ev;
ev.type = InputEvent::JOYPAD_MOTION;
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_0;
ev.joy_motion.axis_value = (p_x / (float)ACCEL_RANGE);
last_accel.x = p_x;
queue_event(ev);
};
if (p_y != last_accel.y) {
//printf("updating accel y %f\n", p_y);
InputEvent ev;
ev.type = InputEvent::JOYPAD_MOTION;
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_1;
ev.joy_motion.axis_value = (p_y / (float)ACCEL_RANGE);
last_accel.y = p_y;
queue_event(ev);
};
if (p_z != last_accel.z) {
//printf("updating accel z %f\n", p_z);
InputEvent ev;
ev.type = InputEvent::JOYPAD_MOTION;
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_2;
ev.joy_motion.axis_value = ( (1.0 - p_z) / (float)ACCEL_RANGE);
last_accel.z = p_z;
queue_event(ev);
};
*/
};
void DisplayServerIPhone::update_magnetometer(float p_x, float p_y, float p_z) {
@ -516,6 +369,8 @@ int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
NSString *string = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
NSDictionary *iOSModelToDPI = [GodotDeviceMetrics dpiList];
for (NSArray *keyArray in iOSModelToDPI) {
if ([keyArray containsObject:string]) {
NSNumber *value = iOSModelToDPI[keyArray];
@ -523,7 +378,26 @@ int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
}
}
return 163;
// If device wasn't found in dictionary
// make a best guess from device metrics.
CGFloat scale = [UIScreen mainScreen].scale;
UIUserInterfaceIdiom idiom = [UIDevice currentDevice].userInterfaceIdiom;
switch (idiom) {
case UIUserInterfaceIdiomPad:
return scale == 2 ? 264 : 132;
case UIUserInterfaceIdiomPhone: {
if (scale == 3) {
CGFloat nativeScale = [UIScreen mainScreen].nativeScale;
return nativeScale == 3 ? 458 : 401;
}
return 326;
}
default:
return 72;
}
}
float DisplayServerIPhone::screen_get_scale(int p_screen) const {
@ -716,7 +590,7 @@ Error DisplayServerIPhone::native_video_play(String p_path, float p_volume, Stri
String file_path = ProjectSettings::get_singleton()->globalize_path(p_path);
NSString *filePath = [[[NSString alloc] initWithUTF8String:file_path.utf8().get_data()] autorelease];
NSString *filePath = [[NSString alloc] initWithUTF8String:file_path.utf8().get_data()];
NSString *audioTrack = [NSString stringWithUTF8String:p_audio_track.utf8()];
NSString *subtitleTrack = [NSString stringWithUTF8String:p_subtitle_track.utf8()];

View file

@ -83,7 +83,12 @@ Error GameCenter::authenticate() {
// after the view is cancelled or the user logs in. Or if the user's already logged in, it's
// called just once to confirm they're authenticated. This is why no result needs to be specified
// in the presentViewController phase. In this case, more calls to this function will follow.
_weakify(root_controller);
_weakify(player);
player.authenticateHandler = (^(UIViewController *controller, NSError *error) {
_strongify(root_controller);
_strongify(player);
if (controller) {
[root_controller presentViewController:controller animated:YES completion:nil];
} else {
@ -123,8 +128,8 @@ Error GameCenter::post_score(Dictionary p_score) {
float score = p_score["score"];
String category = p_score["category"];
NSString *cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease];
GKScore *reporter = [[[GKScore alloc] initWithLeaderboardIdentifier:cat_str] autorelease];
NSString *cat_str = [[NSString alloc] initWithUTF8String:category.utf8().get_data()];
GKScore *reporter = [[GKScore alloc] initWithLeaderboardIdentifier:cat_str];
reporter.value = score;
ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE);
@ -152,8 +157,8 @@ Error GameCenter::award_achievement(Dictionary p_params) {
String name = p_params["name"];
float progress = p_params["progress"];
NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier:name_str] autorelease];
NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()];
GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:name_str];
ERR_FAIL_COND_V(!achievement, FAILED);
ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE);
@ -297,7 +302,7 @@ Error GameCenter::show_game_center(Dictionary p_params) {
}
}
GKGameCenterViewController *controller = [[[GKGameCenterViewController alloc] init] autorelease];
GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init];
ERR_FAIL_COND_V(!controller, FAILED);
ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
@ -309,7 +314,7 @@ Error GameCenter::show_game_center(Dictionary p_params) {
controller.leaderboardIdentifier = nil;
if (p_params.has("leaderboard_name")) {
String name = p_params["leaderboard_name"];
NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()];
controller.leaderboardIdentifier = name_str;
}
}

View file

@ -49,10 +49,8 @@ int add_path(int p_argc, char **p_args) {
}
p_args[p_argc++] = (char *)"--path";
[str retain]; // memory leak lol (maybe make it static here and delete it in ViewController destructor? @todo
p_args[p_argc++] = (char *)[str cStringUsingEncoding:NSUTF8StringEncoding];
p_args[p_argc] = NULL;
[str release];
return p_argc;
};
@ -68,9 +66,7 @@ int add_cmdline(int p_argc, char **p_args) {
if (!str) {
continue;
}
[str retain]; // @todo delete these at some point
p_args[p_argc++] = (char *)[str cStringUsingEncoding:NSUTF8StringEncoding];
[str release];
};
p_args[p_argc] = NULL;

View file

@ -145,8 +145,6 @@ static const int max_touches = 8;
if (self.delayGestureRecognizer) {
self.delayGestureRecognizer = nil;
}
[super dealloc];
}
- (void)godot_commonInit {
@ -156,7 +154,7 @@ static const int max_touches = 8;
// Configure and start accelerometer
if (!self.motionManager) {
self.motionManager = [[[CMMotionManager alloc] init] autorelease];
self.motionManager = [[CMMotionManager alloc] init];
if (self.motionManager.deviceMotionAvailable) {
self.motionManager.deviceMotionUpdateInterval = 1.0 / 70.0;
[self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
@ -169,7 +167,6 @@ static const int max_touches = 8;
GodotViewGestureRecognizer *gestureRecognizer = [[GodotViewGestureRecognizer alloc] init];
self.delayGestureRecognizer = gestureRecognizer;
[self addGestureRecognizer:self.delayGestureRecognizer];
[gestureRecognizer release];
}
- (void)stopRendering {
@ -204,14 +201,11 @@ static const int max_touches = 8;
if (self.useCADisplayLink) {
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
// if (@available(iOS 10, *)) {
self.displayLink.preferredFramesPerSecond = (NSInteger)(1.0 / self.renderingInterval);
// } else {
// // Approximate frame rate
// // assumes device refreshes at 60 fps
// int frameInterval = (int)floor(self.renderingInterval * 60.0f);
// [self.displayLink setFrameInterval:frameInterval];
// }
// Approximate frame rate
// assumes device refreshes at 60 fps
int displayFPS = (NSInteger)(1.0 / self.renderingInterval);
self.displayLink.preferredFramesPerSecond = displayFPS;
// Setup DisplayLink in main thread
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

View file

@ -83,8 +83,6 @@ const CGFloat kGLGestureMovementDistance = 0.5;
if (self.delayedEvent) {
self.delayedEvent = nil;
}
[super dealloc];
}
- (void)delayTouches:(NSSet *)touches andEvent:(UIEvent *)event {
@ -116,7 +114,6 @@ const CGFloat kGLGestureMovementDistance = 0.5;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseBegan];
[self delayTouches:cleared andEvent:event];
[cleared release];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
@ -137,17 +134,14 @@ const CGFloat kGLGestureMovementDistance = 0.5;
if (distance > kGLGestureMovementDistance) {
[self.delayTimer fire];
[self.view touchesMoved:cleared withEvent:event];
[cleared release];
return;
}
}
[cleared release];
return;
}
[self.view touchesMoved:cleared withEvent:event];
[cleared release];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
@ -155,7 +149,6 @@ const CGFloat kGLGestureMovementDistance = 0.5;
NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseEnded];
[self.view touchesEnded:cleared withEvent:event];
[cleared release];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {

View file

@ -150,7 +150,7 @@ Variant nsobject_to_variant(NSObject *object) {
NSObject *variant_to_nsobject(Variant v) {
if (v.get_type() == Variant::STRING) {
return [[[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()] autorelease];
return [[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()];
} else if (v.get_type() == Variant::FLOAT) {
return [NSNumber numberWithDouble:(double)v];
} else if (v.get_type() == Variant::INT) {
@ -158,11 +158,11 @@ NSObject *variant_to_nsobject(Variant v) {
} else if (v.get_type() == Variant::BOOL) {
return [NSNumber numberWithBool:BOOL((bool)v)];
} else if (v.get_type() == Variant::DICTIONARY) {
NSMutableDictionary *result = [[[NSMutableDictionary alloc] init] autorelease];
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
Dictionary dic = v;
Array keys = dic.keys();
for (int i = 0; i < keys.size(); ++i) {
NSString *key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease];
NSString *key = [[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()];
NSObject *value = variant_to_nsobject(dic[keys[i]]);
if (key == NULL || value == NULL) {
@ -173,7 +173,7 @@ NSObject *variant_to_nsobject(Variant v) {
}
return result;
} else if (v.get_type() == Variant::ARRAY) {
NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *result = [[NSMutableArray alloc] init];
Array arr = v;
for (int i = 0; i < arr.size(); ++i) {
NSObject *value = variant_to_nsobject(arr[i]);
@ -195,7 +195,7 @@ NSObject *variant_to_nsobject(Variant v) {
}
Error ICloud::remove_key(String p_param) {
NSString *key = [[[NSString alloc] initWithUTF8String:p_param.utf8().get_data()] autorelease];
NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()];
NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
@ -217,7 +217,7 @@ Array ICloud::set_key_values(Dictionary p_params) {
String variant_key = keys[i];
Variant variant_value = p_params[variant_key];
NSString *key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease];
NSString *key = [[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()];
if (key == NULL) {
error_keys.push_back(variant_key);
continue;
@ -238,7 +238,7 @@ Array ICloud::set_key_values(Dictionary p_params) {
}
Variant ICloud::get_key_value(String p_param) {
NSString *key = [[[NSString alloc] initWithUTF8String:p_param.utf8().get_data()] autorelease];
NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()];
NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
if (![[store dictionaryRepresentation] objectForKey:key]) {

View file

@ -56,7 +56,6 @@ static NSArray *latestProducts;
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:self.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:self.price];
[numberFormatter release];
return formattedString;
}
@ -124,8 +123,6 @@ void InAppStore::_bind_methods() {
ret["invalid_ids"] = invalid_ids;
InAppStore::get_singleton()->_post_event(ret);
[request release];
};
@end
@ -136,14 +133,14 @@ Error InAppStore::request_product_info(Dictionary p_params) {
PackedStringArray pids = p_params["product_ids"];
printf("************ request product info! %i\n", pids.size());
NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease];
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:pids.size()];
for (int i = 0; i < pids.size(); i++) {
printf("******** adding %s to product list\n", pids[i].utf8().get_data());
NSString *pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease];
NSString *pid = [[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()];
[array addObject:pid];
};
NSSet *products = [[[NSSet alloc] initWithArray:array] autorelease];
NSSet *products = [[NSSet alloc] initWithArray:array];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:products];
ProductsDelegate *delegate = [[ProductsDelegate alloc] init];
@ -183,30 +180,14 @@ Error InAppStore::restore_purchases() {
ret["transaction_id"] = transactionId;
NSData *receipt = nil;
int sdk_version = 6;
int sdk_version = [[[UIDevice currentDevice] systemVersion] intValue];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
NSURL *receiptFileURL = nil;
NSBundle *bundle = [NSBundle mainBundle];
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) {
// Get the transaction receipt file path location in the app bundle.
receiptFileURL = [bundle appStoreReceiptURL];
NSBundle *bundle = [NSBundle mainBundle];
// Get the transaction receipt file path location in the app bundle.
NSURL *receiptFileURL = [bundle appStoreReceiptURL];
// Read in the contents of the transaction file.
receipt = [NSData dataWithContentsOfURL:receiptFileURL];
sdk_version = 7;
} else {
// Fall back to deprecated transaction receipt,
// which is still available in iOS 7.
// Use SKPaymentTransaction's transactionReceipt.
receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
}
} else {
receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
}
// Read in the contents of the transaction file.
receipt = [NSData dataWithContentsOfURL:receiptFileURL];
NSString *receipt_to_send = nil;
if (receipt != nil) {
@ -265,7 +246,7 @@ Error InAppStore::purchase(Dictionary p_params) {
printf("purchasing!\n");
ERR_FAIL_COND_V(!p_params.has("product_id"), ERR_INVALID_PARAMETER);
NSString *pid = [[[NSString alloc] initWithUTF8String:String(p_params["product_id"]).utf8().get_data()] autorelease];
NSString *pid = [[NSString alloc] initWithUTF8String:String(p_params["product_id"]).utf8().get_data()];
SKProduct *product = nil;
@ -307,7 +288,7 @@ void InAppStore::_post_event(Variant p_event) {
void InAppStore::_record_purchase(String product_id) {
String skey = "purchased/" + product_id;
NSString *key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease];
NSString *key = [[NSString alloc] initWithUTF8String:skey.utf8().get_data()];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
};

View file

@ -30,6 +30,7 @@
#include "ios.h"
#import "app_delegate.h"
#import "view_controller.h"
#import <UIKit/UIKit.h>
#include <sys/sysctl.h>
@ -68,23 +69,9 @@ String iOS::get_model() const {
}
String iOS::get_rate_url(int p_app_id) const {
String templ = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
String templ_iOS7 = "itms-apps://itunes.apple.com/app/idAPP_ID";
String templ_iOS8 = "itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software";
String app_url_path = "itms-apps://itunes.apple.com/app/idAPP_ID";
//ios7 before
String ret = templ;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7.1) {
// iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131
ret = templ_iOS7;
} else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
// iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182
ret = templ_iOS8;
}
// ios7 for everything?
ret = templ_iOS7.replace("APP_ID", String::num(p_app_id));
String ret = app_url_path.replace("APP_ID", String::num(p_app_id));
printf("returning rate url %s\n", ret.utf8().get_data());
return ret;

View file

@ -131,8 +131,6 @@ void JoypadIPhone::start_processing() {
- (void)dealloc {
[self finishObserving];
[super dealloc];
}
- (int)getJoyIdForController:(GCController *)controller {
@ -251,8 +249,13 @@ void JoypadIPhone::start_processing() {
// The extended gamepad profile has all the input you could possibly find on
// a gamepad but will only be active if your gamepad actually has all of
// these...
controller.extendedGamepad.valueChangedHandler = ^(
GCExtendedGamepad *gamepad, GCControllerElement *element) {
_weakify(self);
_weakify(controller);
controller.extendedGamepad.valueChangedHandler = ^(GCExtendedGamepad *gamepad, GCControllerElement *element) {
_strongify(self);
_strongify(controller);
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
@ -304,71 +307,33 @@ void JoypadIPhone::start_processing() {
Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_TRIGGER_RIGHT, jx);
};
};
} else if (controller.microGamepad != nil) {
// micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
_weakify(self);
_weakify(controller);
controller.microGamepad.valueChangedHandler = ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
_strongify(self);
_strongify(controller);
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonX) {
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.dpad) {
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
gamepad.dpad.up.isPressed);
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
gamepad.dpad.down.isPressed);
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT, gamepad.dpad.left.isPressed);
Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT, gamepad.dpad.right.isPressed);
};
};
}
// else if (controller.gamepad != nil) {
// // gamepad is the standard profile with 4 buttons, shoulder buttons and a
// // D-pad
// controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad,
// GCControllerElement *element) {
// int joy_id = [self getJoyIdForController:controller];
//
// if (element == gamepad.buttonA) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
// gamepad.buttonA.isPressed);
// } else if (element == gamepad.buttonB) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_B,
// gamepad.buttonB.isPressed);
// } else if (element == gamepad.buttonX) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
// gamepad.buttonX.isPressed);
// } else if (element == gamepad.buttonY) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_Y,
// gamepad.buttonY.isPressed);
// } else if (element == gamepad.leftShoulder) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_LEFT_SHOULDER,
// gamepad.leftShoulder.isPressed);
// } else if (element == gamepad.rightShoulder) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_RIGHT_SHOULDER,
// gamepad.rightShoulder.isPressed);
// } else if (element == gamepad.dpad) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
// gamepad.dpad.up.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
// gamepad.dpad.down.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
// gamepad.dpad.left.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
// gamepad.dpad.right.isPressed);
// };
// };
//#ifdef ADD_MICRO_GAMEPAD // disabling this for now, only available on iOS 9+,
// // while we are setting that as the minimum, seems our
// // build environment doesn't like it
// } else if (controller.microGamepad != nil) {
// // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
// controller.microGamepad.valueChangedHandler =
// ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
// int joy_id = [self getJoyIdForController:controller];
//
// if (element == gamepad.buttonA) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
// gamepad.buttonA.isPressed);
// } else if (element == gamepad.buttonX) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
// gamepad.buttonX.isPressed);
// } else if (element == gamepad.dpad) {
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
// gamepad.dpad.up.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
// gamepad.dpad.down.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
// gamepad.dpad.left.isPressed);
// Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
// gamepad.dpad.right.isPressed);
// };
// };
//#endif
// };
///@TODO need to add support for controller.motion which gives us access to
/// the orientation of the device (if supported)

View file

@ -271,7 +271,6 @@ String OSIPhone::get_model_name() const {
Error OSIPhone::shell_open(String p_uri) {
NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
NSURL *url = [NSURL URLWithString:urlPath];
[urlPath release];
if (![[UIApplication sharedApplication] canOpenURL:url]) {
return ERR_CANT_OPEN;
@ -279,11 +278,7 @@ Error OSIPhone::shell_open(String p_uri) {
printf("opening url %s\n", p_uri.utf8().get_data());
// if (@available(iOS 10, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
// } else {
// [[UIApplication sharedApplication] openURL:url];
// }
return OK;
};

View file

@ -33,3 +33,10 @@
#define PLATFORM_REFCOUNT
#define PTHREAD_RENAME_SELF
#define _weakify(var) __weak typeof(var) GDWeak_##var = var;
#define _strongify(var) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
__strong typeof(var) var = GDWeak_##var; \
_Pragma("clang diagnostic pop")

View file

@ -67,9 +67,6 @@
self.view = view;
view.renderer = self.renderer;
[renderer release];
[view release];
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@ -153,8 +150,6 @@
self.renderer = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
// MARK: Orientation

View file

@ -35,14 +35,12 @@ const char *VulkanContextIPhone::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id,
CALayer *p_metal_layer, int p_width,
int p_height) {
Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.pView = p_metal_layer;
createInfo.pView = (__bridge const void *)p_metal_layer;
VkSurfaceKHR surface;
VkResult err =