diff options
author | Sergey Minakov <naithar@icloud.com> | 2020-08-13 18:24:39 +0300 |
---|---|---|
committer | Sergey Minakov <naithar@icloud.com> | 2020-11-10 16:28:29 +0300 |
commit | 30783d57ccf6f368f21a84e408f56b86d05cba2b (patch) | |
tree | 7af4591c589b1393a31599cbad19490893fcc5f1 | |
parent | 03ae26bb74c0b713fe2132c5b003ae41e366746c (diff) |
iOS Modules: separate main platform code from modules
Moved previously builtin modules 'GameCenter', 'AppStore', 'iCloud' to separate modules to be represented as plugin.
Modified 'ARKit' and 'Camera' to not be builtin into engine and work as plugin.
Changed platform code so it's not affected by the move.
Modified Xcode project file to remove parameters that doesn't make any effect.
Added basic '.gdip' plugin config file.
45 files changed, 594 insertions, 224 deletions
diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index d8da520ed7..c46f64834a 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -153,81 +153,6 @@ DevelopmentTeam = $team_id; ProvisioningStyle = Automatic; SystemCapabilities = { - com.apple.AccessWiFi = { - enabled = $access_wifi; - }; - com.apple.ApplePay = { - enabled = 0; - }; - com.apple.ApplicationGroups.iOS = { - enabled = 0; - }; - com.apple.AutoFillCredentialProvider = { - enabled = 0; - }; - com.apple.BackgroundModes = { - enabled = 0; - }; - com.apple.ClassKit = { - enabled = 0; - }; - com.apple.DataProtection = { - enabled = 0; - }; - com.apple.GameCenter.iOS = { - enabled = $game_center; - }; - com.apple.HealthKit = { - enabled = 0; - }; - com.apple.HomeKit = { - enabled = 0; - }; - com.apple.HotspotConfiguration = { - enabled = 0; - }; - com.apple.InAppPurchase = { - enabled = $in_app_purchases; - }; - com.apple.InterAppAudio = { - enabled = 0; - }; - com.apple.Keychain = { - enabled = 0; - }; - com.apple.Maps.iOS = { - enabled = 0; - }; - com.apple.Multipath = { - enabled = 0; - }; - com.apple.NearFieldCommunicationTagReading = { - enabled = 0; - }; - com.apple.NetworkExtensions.iOS = { - enabled = 0; - }; - com.apple.Push = { - enabled = $push_notifications; - }; - com.apple.SafariKeychain = { - enabled = 0; - }; - com.apple.Siri = { - enabled = 0; - }; - com.apple.VPNLite = { - enabled = 0; - }; - com.apple.WAC = { - enabled = 0; - }; - com.apple.Wallet = { - enabled = 0; - }; - com.apple.iCloud = { - enabled = 0; - }; }; }; }; diff --git a/modules/SCsub b/modules/SCsub index edfc4ed9c6..24598f4b28 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -47,7 +47,14 @@ for name, path in env.module_list.items(): # Some modules are not linked automatically but can be enabled optionally # on iOS, so we handle those specially. - if env["platform"] == "iphone" and name in ["arkit", "camera"]: + if env["platform"] == "iphone" and name in [ + "arkit", + "camera", + "camera_iphone", + "gamecenter", + "inappstore", + "icloud", + ]: continue lib = env_modules.add_library("module_%s" % name, env.modules_sources) diff --git a/modules/arkit/arkit.gdip b/modules/arkit/arkit.gdip new file mode 100644 index 0000000000..22c0a07e26 --- /dev/null +++ b/modules/arkit/arkit.gdip @@ -0,0 +1,18 @@ +[config] +name="ARKit" +binary="arkit_lib.a" + +initialization="register_arkit_types" +deinitialization="unregister_arkit_types" + +[dependencies] +linked=[] +embedded=[] +system=["AVFoundation.framework", "ARKit.framework"] + +capabilities=["arkit"] + +files=[] + +[plist] +NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/arkit/register_types.cpp b/modules/arkit/arkit_module.cpp index 91069ab364..87ee3b87a5 100644 --- a/modules/arkit/register_types.cpp +++ b/modules/arkit/arkit_module.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.cpp */ +/* arkit_module.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "register_types.h" +#include "arkit_module.h" #include "arkit_interface.h" diff --git a/modules/arkit/register_types.h b/modules/arkit/arkit_module.h index f8939a1e3f..8aa8175ed5 100644 --- a/modules/arkit/register_types.h +++ b/modules/arkit/arkit_module.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.h */ +/* arkit_module.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/camera/SCsub b/modules/camera/SCsub index 631a65bde2..de97724d09 100644 --- a/modules/camera/SCsub +++ b/modules/camera/SCsub @@ -5,17 +5,7 @@ Import("env_modules") env_camera = env_modules.Clone() -if env["platform"] == "iphone": - # (iOS) Enable module support - env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - - # (iOS) Build as separate static library - modules_sources = [] - env_camera.add_source_files(modules_sources, "register_types.cpp") - env_camera.add_source_files(modules_sources, "camera_ios.mm") - mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources) - -elif env["platform"] == "windows": +if env["platform"] == "windows": env_camera.add_source_files(env.modules_sources, "register_types.cpp") env_camera.add_source_files(env.modules_sources, "camera_win.cpp") diff --git a/modules/camera/config.py b/modules/camera/config.py index 87d7542741..8a22751aa7 100644 --- a/modules/camera/config.py +++ b/modules/camera/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return platform == "iphone" or platform == "osx" or platform == "windows" + return platform == "osx" or platform == "windows" def configure(env): diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp index 3b6c916914..9479310a13 100644 --- a/modules/camera/register_types.cpp +++ b/modules/camera/register_types.cpp @@ -33,9 +33,6 @@ #if defined(WINDOWS_ENABLED) #include "camera_win.h" #endif -#if defined(IPHONE_ENABLED) -#include "camera_ios.h" -#endif #if defined(OSX_ENABLED) #include "camera_osx.h" #endif @@ -44,9 +41,6 @@ void register_camera_types() { #if defined(WINDOWS_ENABLED) CameraServer::make_default<CameraWindows>(); #endif -#if defined(IPHONE_ENABLED) - CameraServer::make_default<CameraIOS>(); -#endif #if defined(OSX_ENABLED) CameraServer::make_default<CameraOSX>(); #endif diff --git a/modules/camera_iphone/SCsub b/modules/camera_iphone/SCsub new file mode 100644 index 0000000000..0a37d9a6f5 --- /dev/null +++ b/modules/camera_iphone/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_camera = env_modules.Clone() + +# (iOS) Enable module support +env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_camera.add_source_files(modules_sources, "*.cpp") +env_camera.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/camera_iphone/camera.gdip b/modules/camera_iphone/camera.gdip new file mode 100644 index 0000000000..09017b8d27 --- /dev/null +++ b/modules/camera_iphone/camera.gdip @@ -0,0 +1,18 @@ +[config] +name="Camera" +binary="camera_lib.a" + +initialization="register_camera_types" +deinitialization="unregister_camera_types" + +[dependencies] +linked=[] +embedded=[] +system=["AVFoundation.framework"] + +capabilities=[] + +files=[] + +[plist] +NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/camera/camera_ios.h b/modules/camera_iphone/camera_ios.h index 7da43e4851..7da43e4851 100644 --- a/modules/camera/camera_ios.h +++ b/modules/camera_iphone/camera_ios.h diff --git a/modules/camera/camera_ios.mm b/modules/camera_iphone/camera_ios.mm index e4cb928805..e4cb928805 100644 --- a/modules/camera/camera_ios.mm +++ b/modules/camera_iphone/camera_ios.mm diff --git a/modules/camera_iphone/camera_module.cpp b/modules/camera_iphone/camera_module.cpp new file mode 100644 index 0000000000..f3d00be204 --- /dev/null +++ b/modules/camera_iphone/camera_module.cpp @@ -0,0 +1,40 @@ +/*************************************************************************/ +/* camera_module.cpp */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "camera_module.h" + +#include "camera_ios.h" + +void register_camera_types() { + CameraServer::make_default<CameraIOS>(); +} + +void unregister_camera_types() { +} diff --git a/modules/camera_iphone/camera_module.h b/modules/camera_iphone/camera_module.h new file mode 100644 index 0000000000..d123071a70 --- /dev/null +++ b/modules/camera_iphone/camera_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* camera_module.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. */ +/*************************************************************************/ + +void register_camera_types(); +void unregister_camera_types(); diff --git a/modules/camera_iphone/config.py b/modules/camera_iphone/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/camera_iphone/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/modules/gamecenter/SCsub b/modules/gamecenter/SCsub new file mode 100644 index 0000000000..72fbf7ab0e --- /dev/null +++ b/modules/gamecenter/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_gamecenter = env_modules.Clone() + +# (iOS) Enable module support +env_gamecenter.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_gamecenter.add_source_files(modules_sources, "*.cpp") +env_gamecenter.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_gamecenter_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/gamecenter/config.py b/modules/gamecenter/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/gamecenter/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/platform/iphone/game_center.h b/modules/gamecenter/game_center.h index cbfd616e56..76fd295460 100644 --- a/platform/iphone/game_center.h +++ b/modules/gamecenter/game_center.h @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef GAME_CENTER_ENABLED - #ifndef GAME_CENTER_H #define GAME_CENTER_H @@ -71,5 +69,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/game_center.mm b/modules/gamecenter/game_center.mm index 0f8c0100c3..114f639a32 100644 --- a/platform/iphone/game_center.mm +++ b/modules/gamecenter/game_center.mm @@ -28,28 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef GAME_CENTER_ENABLED - #include "game_center.h" +#import "platform/iphone/app_delegate.h" -#ifdef __IPHONE_9_0 - -#import <GameKit/GameKit.h> -extern "C" { - -#else - -extern "C" { +#import "game_center_delegate.h" +#import "platform/iphone/view_controller.h" #import <GameKit/GameKit.h> -#endif - -#import "app_delegate.h" -}; - -#import "view_controller.h" - GameCenter *GameCenter::instance = NULL; +GodotGameCenterDelegate *gameCenterDelegate = nil; void GameCenter::_bind_methods() { ClassDB::bind_method(D_METHOD("authenticate"), &GameCenter::authenticate); @@ -76,7 +63,7 @@ Error GameCenter::authenticate() { GKLocalPlayer *player = [GKLocalPlayer localPlayer]; ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE); - ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); // This handler is called several times. First when the view needs to be shown, then again @@ -305,10 +292,10 @@ Error GameCenter::show_game_center(Dictionary p_params) { GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init]; ERR_FAIL_COND_V(!controller, FAILED); - ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); - controller.gameCenterDelegate = root_controller; + controller.gameCenterDelegate = gameCenterDelegate; controller.viewState = view_state; if (view_state == GKGameCenterViewControllerStateLeaderboards) { controller.leaderboardIdentifier = nil; @@ -382,8 +369,12 @@ GameCenter::GameCenter() { ERR_FAIL_COND(instance != NULL); instance = this; authenticated = false; -}; -GameCenter::~GameCenter() {} + gameCenterDelegate = [[GodotGameCenterDelegate alloc] init]; +}; -#endif +GameCenter::~GameCenter() { + if (gameCenterDelegate) { + gameCenterDelegate = nil; + } +} diff --git a/modules/gamecenter/game_center_delegate.h b/modules/gamecenter/game_center_delegate.h new file mode 100644 index 0000000000..1b7025f915 --- /dev/null +++ b/modules/gamecenter/game_center_delegate.h @@ -0,0 +1,35 @@ +/*************************************************************************/ +/* game_center_delegate.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 <GameKit/GameKit.h> + +@interface GodotGameCenterDelegate : NSObject <GKGameCenterControllerDelegate> + +@end diff --git a/modules/gamecenter/game_center_delegate.mm b/modules/gamecenter/game_center_delegate.mm new file mode 100644 index 0000000000..9a10c439c6 --- /dev/null +++ b/modules/gamecenter/game_center_delegate.mm @@ -0,0 +1,45 @@ +/*************************************************************************/ +/* game_center_delegate.mm */ +/*************************************************************************/ +/* 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 "game_center_delegate.h" + +#include "game_center.h" + +@implementation GodotGameCenterDelegate + +- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { + //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone + if (GameCenter::get_singleton()) { + GameCenter::get_singleton()->game_center_closed(); + } + [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/modules/gamecenter/game_center_module.cpp b/modules/gamecenter/game_center_module.cpp new file mode 100644 index 0000000000..6c5157345f --- /dev/null +++ b/modules/gamecenter/game_center_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* game_center_module.cpp */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "game_center_module.h" + +#include "core/config/engine.h" + +#include "game_center.h" + +GameCenter *game_center; + +void register_gamecenter_types() { + game_center = memnew(GameCenter); + Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); +} + +void unregister_gamecenter_types() { + if (game_center) { + memdelete(game_center); + } +} diff --git a/modules/gamecenter/game_center_module.h b/modules/gamecenter/game_center_module.h new file mode 100644 index 0000000000..8da3ae02ee --- /dev/null +++ b/modules/gamecenter/game_center_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* game_center_module.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. */ +/*************************************************************************/ + +void register_gamecenter_types(); +void unregister_gamecenter_types(); diff --git a/modules/gamecenter/gamecenter.gdip b/modules/gamecenter/gamecenter.gdip new file mode 100644 index 0000000000..eb44effbdd --- /dev/null +++ b/modules/gamecenter/gamecenter.gdip @@ -0,0 +1,17 @@ +[config] +name="GameCenter" +binary="gamecenter_lib.a" + +initialization="register_gamecenter_types" +deinitialization="unregister_gamecenter_types" + +[dependencies] +linked=[] +embedded=[] +system=["GameKit.framework"] + +capabilities=["gamekit"] + +files=[] + +[plist] diff --git a/modules/icloud/SCsub b/modules/icloud/SCsub new file mode 100644 index 0000000000..805a484600 --- /dev/null +++ b/modules/icloud/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_icloud = env_modules.Clone() + +# (iOS) Enable module support +env_icloud.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_icloud.add_source_files(modules_sources, "*.cpp") +env_icloud.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_icloud_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/icloud/config.py b/modules/icloud/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/icloud/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/modules/icloud/icloud.gdip b/modules/icloud/icloud.gdip new file mode 100644 index 0000000000..9f81be8a34 --- /dev/null +++ b/modules/icloud/icloud.gdip @@ -0,0 +1,17 @@ +[config] +name="iCloud" +binary="icloud_lib.a" + +initialization="register_icloud_types" +deinitialization="unregister_icloud_types" + +[dependencies] +linked=[] +embedded=[] +system=[] + +capabilities=[] + +files=[] + +[plist] diff --git a/platform/iphone/icloud.h b/modules/icloud/icloud.h index 5f59abdfc0..35eede0bf9 100644 --- a/platform/iphone/icloud.h +++ b/modules/icloud/icloud.h @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef ICLOUD_ENABLED - #ifndef ICLOUD_H #define ICLOUD_H @@ -60,5 +58,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/icloud.mm b/modules/icloud/icloud.mm index 3d81349883..8a8ddbefe9 100644 --- a/platform/iphone/icloud.mm +++ b/modules/icloud/icloud.mm @@ -28,22 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef ICLOUD_ENABLED - #include "icloud.h" -#ifndef __IPHONE_9_0 -extern "C" { -#endif - -#import "app_delegate.h" +#import "platform/iphone/app_delegate.h" #import <Foundation/Foundation.h> -#ifndef __IPHONE_9_0 -}; -#endif - ICloud *ICloud::instance = NULL; void ICloud::_bind_methods() { @@ -353,5 +343,3 @@ ICloud::ICloud() { } ICloud::~ICloud() {} - -#endif diff --git a/modules/icloud/icloud_module.cpp b/modules/icloud/icloud_module.cpp new file mode 100644 index 0000000000..43fdc7d45e --- /dev/null +++ b/modules/icloud/icloud_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* icloud_module.cpp */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "icloud_module.h" + +#include "core/config/engine.h" + +#include "icloud.h" + +ICloud *icloud; + +void register_icloud_types() { + icloud = memnew(ICloud); + Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); +} + +void unregister_icloud_types() { + if (icloud) { + memdelete(icloud); + } +} diff --git a/modules/icloud/icloud_module.h b/modules/icloud/icloud_module.h new file mode 100644 index 0000000000..7fd057525e --- /dev/null +++ b/modules/icloud/icloud_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* icloud_module.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. */ +/*************************************************************************/ + +void register_icloud_types(); +void unregister_icloud_types(); diff --git a/modules/inappstore/SCsub b/modules/inappstore/SCsub new file mode 100644 index 0000000000..cee6a256d5 --- /dev/null +++ b/modules/inappstore/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_inappstore = env_modules.Clone() + +# (iOS) Enable module support +env_inappstore.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_inappstore.add_source_files(modules_sources, "*.cpp") +env_inappstore.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_inappstore_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/inappstore/config.py b/modules/inappstore/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/inappstore/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/platform/iphone/in_app_store.h b/modules/inappstore/in_app_store.h index 85075e4e20..c8e5d17cec 100644 --- a/platform/iphone/in_app_store.h +++ b/modules/inappstore/in_app_store.h @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef STOREKIT_ENABLED - #ifndef IN_APP_STORE_H #define IN_APP_STORE_H @@ -77,5 +75,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/in_app_store.mm b/modules/inappstore/in_app_store.mm index 3eec9dae69..62977318c1 100644 --- a/platform/iphone/in_app_store.mm +++ b/modules/inappstore/in_app_store.mm @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef STOREKIT_ENABLED - #include "in_app_store.h" #import <Foundation/Foundation.h> @@ -411,5 +409,3 @@ InAppStore::~InAppStore() { [[SKPaymentQueue defaultQueue] removeTransactionObserver:transactions_observer]; transactions_observer = nil; } - -#endif diff --git a/modules/inappstore/in_app_store_module.cpp b/modules/inappstore/in_app_store_module.cpp new file mode 100644 index 0000000000..039bdd4f83 --- /dev/null +++ b/modules/inappstore/in_app_store_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* in_app_store_module.cpp */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "in_app_store_module.h" + +#include "core/config/engine.h" + +#include "in_app_store.h" + +InAppStore *store_kit; + +void register_inappstore_types() { + store_kit = memnew(InAppStore); + Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit)); +} + +void unregister_inappstore_types() { + if (store_kit) { + memdelete(store_kit); + } +} diff --git a/modules/inappstore/in_app_store_module.h b/modules/inappstore/in_app_store_module.h new file mode 100644 index 0000000000..44673e58bc --- /dev/null +++ b/modules/inappstore/in_app_store_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* in_app_store_module.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. */ +/*************************************************************************/ + +void register_inappstore_types(); +void unregister_inappstore_types(); diff --git a/modules/inappstore/inappstore.gdip b/modules/inappstore/inappstore.gdip new file mode 100644 index 0000000000..7a5efb8ad3 --- /dev/null +++ b/modules/inappstore/inappstore.gdip @@ -0,0 +1,17 @@ +[config] +name="InAppStore" +binary="inappstore_lib.a" + +initialization="register_inappstore_types" +deinitialization="unregister_inappstore_types" + +[dependencies] +linked=[] +embedded=[] +system=["StoreKit.framework"] + +capabilities=[] + +files=[] + +[plist] diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 1dd37dabe5..0a558f8e3d 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -8,9 +8,6 @@ iphone_lib = [ "main.m", "app_delegate.mm", "view_controller.mm", - "game_center.mm", - "in_app_store.mm", - "icloud.mm", "ios.mm", "vulkan_context_iphone.mm", "display_server_iphone.mm", diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index c9891309fe..c1942e77dd 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -36,6 +36,7 @@ #include "os_iphone.h" #import "view_controller.h" +#import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> #define kRenderingFrequency 60 diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index ab453c353f..0456458326 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -35,9 +35,6 @@ def get_opts(): " validation layers)", False, ), - BoolVariable("game_center", "Support for game center", True), - BoolVariable("store_kit", "Support for in-app store", True), - BoolVariable("icloud", "Support for iCloud", True), BoolVariable("ios_exceptions", "Enable exceptions", False), ("ios_triple", "Triple for ios toolchain", ""), ] @@ -222,18 +219,6 @@ def configure(env): ] ) - # Feature options - if env["game_center"]: - env.Append(CPPDEFINES=["GAME_CENTER_ENABLED"]) - env.Append(LINKFLAGS=["-framework", "GameKit"]) - - if env["store_kit"]: - env.Append(CPPDEFINES=["STOREKIT_ENABLED"]) - env.Append(LINKFLAGS=["-framework", "StoreKit"]) - - if env["icloud"]: - env.Append(CPPDEFINES=["ICLOUD_ENABLED"]) - env.Prepend( CPPPATH=[ "$IPHONESDK/usr/include", diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index c6f95869ee..f0854cf98b 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -35,9 +35,6 @@ #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" -#include "game_center.h" -#include "icloud.h" -#include "in_app_store.h" #include "ios.h" #include "joypad_iphone.h" #include "servers/audio_server.h" @@ -55,15 +52,6 @@ private: AudioDriverCoreAudio audio_driver; -#ifdef GAME_CENTER_ENABLED - GameCenter *game_center; -#endif -#ifdef STOREKIT_ENABLED - InAppStore *store_kit; -#endif -#ifdef ICLOUD_ENABLED - ICloud *icloud; -#endif iOS *ios; JoypadIPhone *joypad_iphone; diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index 32e9dda92b..a749ac7e06 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -125,21 +125,6 @@ void OSIPhone::initialize() { } void OSIPhone::initialize_modules() { -#ifdef GAME_CENTER_ENABLED - game_center = memnew(GameCenter); - Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); -#endif - -#ifdef STOREKIT_ENABLED - store_kit = memnew(InAppStore); - Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit)); -#endif - -#ifdef ICLOUD_ENABLED - icloud = memnew(ICloud); - Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); -#endif - ios = memnew(iOS); Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios)); @@ -154,24 +139,6 @@ void OSIPhone::deinitialize_modules() { if (ios) { memdelete(ios); } - -#ifdef GAME_CENTER_ENABLED - if (game_center) { - memdelete(game_center); - } -#endif - -#ifdef STOREKIT_ENABLED - if (store_kit) { - memdelete(store_kit); - } -#endif - -#ifdef ICLOUD_ENABLED - if (icloud) { - memdelete(icloud); - } -#endif } void OSIPhone::set_main_loop(MainLoop *p_main_loop) { diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index b0b31ae377..2cc4e4c388 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -28,13 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import <GameKit/GameKit.h> #import <UIKit/UIKit.h> @class GodotView; @class GodotNativeVideoView; -@interface ViewController : UIViewController <GKGameCenterControllerDelegate> +@interface ViewController : UIViewController @property(nonatomic, readonly, strong) GodotView *godotView; @property(nonatomic, readonly, strong) GodotNativeVideoView *videoView; diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index e11eff423b..5d18a72be1 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -36,6 +36,7 @@ #import "native_video_view.h" #include "os_iphone.h" +#import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> @interface ViewController () @@ -214,14 +215,4 @@ } } -// MARK: Delegates - -#ifdef GAME_CENTER_ENABLED -- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { - //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone - GameCenter::get_singleton()->game_center_closed(); - [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; -} -#endif - @end |