mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
add setting to control app launch type: launcher or game
- removes custom AppDelegate - now starting launcher using qt_main_wrapper - when starting SDL from launcher, SDLUIKitDelegate is created and assigned as app delegate fix kambala-decapitator/vcmi#33
This commit is contained in:
parent
89f14ea586
commit
fab3216df0
@ -148,14 +148,12 @@ set(client_HEADERS
|
||||
if(APPLE_IOS)
|
||||
set(client_SRCS ${client_SRCS}
|
||||
CFocusableHelper.cpp
|
||||
ios/AppDelegate.mm
|
||||
ios/GameChatKeyboardHanlder.m
|
||||
ios/main.m
|
||||
ios/startSDL.mm
|
||||
)
|
||||
set(client_HEADERS ${client_HEADERS}
|
||||
CFocusableHelper.h
|
||||
ios/AppDelegate.h
|
||||
ios/GameChatKeyboardHanlder.h
|
||||
ios/startSDL.h
|
||||
)
|
||||
@ -217,15 +215,19 @@ elseif(APPLE_IOS)
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon
|
||||
)
|
||||
|
||||
target_sources(vcmiclient PRIVATE ios/LaunchScreen.storyboard)
|
||||
set_source_files_properties(ios/LaunchScreen.storyboard PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
# workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0")
|
||||
set_source_files_properties(ios/LaunchScreen.storyboard PROPERTIES LANGUAGE CXX)
|
||||
endif()
|
||||
foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle)
|
||||
set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE})
|
||||
target_sources(vcmiclient PRIVATE ${XCODE_RESOURCE_PATH})
|
||||
set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
target_sources(vcmiclient PRIVATE ios/Images.xcassets)
|
||||
set_source_files_properties(ios/Images.xcassets PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
# workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag
|
||||
# add max version condition when https://gitlab.kitware.com/cmake/cmake/-/issues/23821 is fixed
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0")
|
||||
set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main")
|
||||
endif()
|
||||
|
||||
if(BUILD_SINGLE_APP)
|
||||
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* AppDelegate.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* AppDelegate.mm, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#include "startSDL.h"
|
||||
#include "../launcher/main.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
||||
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||
self.window.rootViewController = [UIViewController new];
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[NSNotificationCenter.defaultCenter addObserverForName:@"StartGame" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||
[self startMainFunc:startSDL];
|
||||
}];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self startMainFunc:qt_main];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)startMainFunc:(int(*)(int argc, char * argv[]))mainPtr {
|
||||
auto args = NSProcessInfo.processInfo.arguments;
|
||||
std::vector<char *> argv;
|
||||
argv.reserve(args.count);
|
||||
for (NSString *arg in args)
|
||||
argv.push_back(const_cast<char *>(arg.UTF8String));
|
||||
|
||||
mainPtr(argv.size(), argv.data());
|
||||
}
|
||||
|
||||
@end
|
31
client/ios/Settings.bundle/Root.plist
Normal file
31
client/ios/Settings.bundle/Root.plist
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>StringsTable</key>
|
||||
<string>Root</string>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Type</key>
|
||||
<string>PSRadioGroupSpecifier</string>
|
||||
<key>Title</key>
|
||||
<string>LaunchType</string>
|
||||
<key>Key</key>
|
||||
<string>LaunchType</string>
|
||||
<key>DefaultValue</key>
|
||||
<integer>0</integer>
|
||||
<key>Values</key>
|
||||
<array>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</array>
|
||||
<key>Titles</key>
|
||||
<array>
|
||||
<string>Launcher</string>
|
||||
<string>Game</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
3
client/ios/Settings.bundle/en.lproj/Root.strings
Normal file
3
client/ios/Settings.bundle/en.lproj/Root.strings
Normal file
@ -0,0 +1,3 @@
|
||||
"LaunchType" = "App start type";
|
||||
"Launcher" = "Launcher";
|
||||
"Game" = "Game";
|
3
client/ios/Settings.bundle/ru.lproj/Root.strings
Normal file
3
client/ios/Settings.bundle/ru.lproj/Root.strings
Normal file
@ -0,0 +1,3 @@
|
||||
"LaunchType" = "Тип запуска приложения";
|
||||
"Launcher" = "Конфигурация (лаунчер)";
|
||||
"Game" = "Игра";
|
@ -7,11 +7,44 @@
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#import "AppDelegate.h"
|
||||
#import "startSDL.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static void startSDLManually(int argc, char * argv[])
|
||||
{
|
||||
id<UIApplicationDelegate> appDelegate;
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
__auto_type sdlAppDelegateClass = NSClassFromString(@"SDLUIKitDelegate");
|
||||
NSCAssert(sdlAppDelegateClass != nil, @"SDL AppDelegate class doesn't exist");
|
||||
NSCAssert(class_conformsToProtocol(sdlAppDelegateClass, @protocol(UIApplicationDelegate)), @"SDL AppDelegate doesn't conform to UIApplicationDelegate");
|
||||
appDelegate = [sdlAppDelegateClass new];
|
||||
}
|
||||
UIApplication.sharedApplication.delegate = appDelegate;
|
||||
|
||||
int result = startSDL(argc, argv, YES);
|
||||
exit(result);
|
||||
}
|
||||
|
||||
int qt_main_wrapper(int argc, char * argv[]);
|
||||
|
||||
int client_main(int argc, char * argv[])
|
||||
{
|
||||
NSInteger launchType;
|
||||
@autoreleasepool {
|
||||
launchType = [NSUserDefaults.standardUserDefaults integerForKey:@"LaunchType"];
|
||||
}
|
||||
if (launchType == 1)
|
||||
return startSDL(argc, argv, NO);
|
||||
|
||||
@autoreleasepool {
|
||||
id __block startGameObserver = [NSNotificationCenter.defaultCenter addObserverForName:@"StartGame" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:startGameObserver];
|
||||
startGameObserver = nil;
|
||||
startSDLManually(argc, argv);
|
||||
}];
|
||||
return qt_main_wrapper(argc, argv);
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,11 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
int startSDL(int argc, char * argv[]);
|
||||
#ifdef __OBJC__
|
||||
#include <objc/objc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int startSDL(int argc, char * argv[], BOOL startManually);
|
||||
|
@ -7,18 +7,18 @@
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include <SDL_main.h>
|
||||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_system.h>
|
||||
#import "startSDL.h"
|
||||
#import "GameChatKeyboardHanlder.h"
|
||||
|
||||
#include "../Global.h"
|
||||
#include "CMT.h"
|
||||
#include "CServerHandler.h"
|
||||
#include "CFocusableHelper.h"
|
||||
|
||||
#import "GameChatKeyboardHanlder.h"
|
||||
#include <SDL_main.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_system.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@ -122,7 +122,7 @@ double ios_screenScale() { return UIScreen.mainScreen.nativeScale; }
|
||||
@end
|
||||
|
||||
|
||||
int startSDL(int argc, char * argv[])
|
||||
int startSDL(int argc, char * argv[], BOOL startManually)
|
||||
{
|
||||
@autoreleasepool {
|
||||
auto observer = [SDLViewObserver new];
|
||||
@ -134,6 +134,9 @@ int startSDL(int argc, char * argv[])
|
||||
removeFocusFromActiveInput();
|
||||
}];
|
||||
|
||||
if (!startManually)
|
||||
return SDL_UIKitRunApp(argc, argv, SDL_main);
|
||||
|
||||
// copied from -[SDLUIKitDelegate postFinishLaunch]
|
||||
SDL_SetMainReady();
|
||||
SDL_iOSSetEventPump(SDL_TRUE);
|
||||
|
@ -56,7 +56,7 @@ set(launcher_FORMS
|
||||
|
||||
if(APPLE_IOS)
|
||||
list(APPEND launcher_SRCS
|
||||
ios/mainwindow_moc.mm
|
||||
ios/main.m
|
||||
)
|
||||
endif()
|
||||
|
||||
|
28
launcher/ios/main.m
Normal file
28
launcher/ios/main.m
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* main.m, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
void launchGame(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
__auto_type app = UIApplication.sharedApplication;
|
||||
__auto_type qtNativeWindowIndex = [app.windows indexOfObjectPassingTest:^BOOL(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
return [NSStringFromClass([window class]) isEqualToString:@"QUIWindow"];
|
||||
}];
|
||||
NSCAssert(qtNativeWindowIndex != NSNotFound, @"Qt native window doesn't exist");
|
||||
|
||||
__auto_type qtNativeWindow = app.windows[qtNativeWindowIndex];
|
||||
qtNativeWindow.hidden = YES;
|
||||
[qtNativeWindow.rootViewController.view removeFromSuperview];
|
||||
qtNativeWindow.rootViewController = nil;
|
||||
if (@available(iOS 13.0, *))
|
||||
qtNativeWindow.windowScene = nil;
|
||||
}
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:@"StartGame" object:nil];
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* mainwindow_moc.mm, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../mainwindow_moc.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QWindow>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
void MainWindow::startExecutable(QString /*name*/)
|
||||
{
|
||||
qApp->quit();
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:@"StartGame" object:nil];
|
||||
}
|
||||
|
||||
void showQtWindow()
|
||||
{
|
||||
auto app = UIApplication.sharedApplication;
|
||||
auto qtNativeWindowIndex = [app.windows indexOfObjectPassingTest:^BOOL(__kindof UIWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
return [NSStringFromClass([window class]) isEqualToString:@"QUIWindow"];
|
||||
}];
|
||||
Q_ASSERT(qtNativeWindowIndex != NSNotFound);
|
||||
|
||||
auto qtWindow = qApp->topLevelWindows()[0];
|
||||
auto qtWindowNativeView = (__bridge UIView*)reinterpret_cast<void*>(qtWindow->winId());
|
||||
|
||||
auto qtNativeWindow = app.windows[qtNativeWindowIndex];
|
||||
[qtNativeWindow.rootViewController.view addSubview:qtWindowNativeView];
|
||||
[qtNativeWindow makeKeyAndVisible];
|
||||
}
|
@ -7,18 +7,25 @@
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include <QApplication>
|
||||
#include "StdInc.h"
|
||||
#include "mainwindow_moc.h"
|
||||
#include "main.h"
|
||||
#include "mainwindow_moc.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int result;
|
||||
#ifdef VCMI_IOS
|
||||
{
|
||||
#endif
|
||||
QApplication vcmilauncher(argc, argv);
|
||||
MainWindow mainWindow;
|
||||
mainWindow.show();
|
||||
#ifdef Q_OS_IOS
|
||||
showQtWindow();
|
||||
result = vcmilauncher.exec();
|
||||
#ifdef VCMI_IOS
|
||||
}
|
||||
if (result == 0)
|
||||
launchGame(argc, argv);
|
||||
#endif
|
||||
return vcmilauncher.exec();
|
||||
return result;
|
||||
}
|
||||
|
@ -9,11 +9,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
void showQtWindow();
|
||||
|
||||
#define main qt_main
|
||||
#ifdef VCMI_IOS
|
||||
extern "C" void launchGame(int argc, char * argv[]);
|
||||
#endif
|
||||
int main(int argc, char * argv[]);
|
||||
|
@ -103,7 +103,11 @@ MainWindow::~MainWindow()
|
||||
|
||||
void MainWindow::on_startGameButton_clicked()
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
qApp->quit();
|
||||
#else
|
||||
startExecutable(pathToQString(VCMIDirs::get().clientPath()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
|
@ -27,7 +27,9 @@ class MainWindow : public QMainWindow
|
||||
private:
|
||||
Ui::MainWindow * ui;
|
||||
void load();
|
||||
#ifndef Q_OS_IOS
|
||||
void startExecutable(QString name);
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget * parent = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user