Add iOS view linkage for Metal rendering and invoke window resizing properly on a main thread

This commit is contained in:
Wojtek Figat
2023-06-01 01:05:06 +02:00
parent a2e2ef51be
commit 40f5032898
2 changed files with 63 additions and 43 deletions

View File

@@ -31,8 +31,42 @@ Guid DeviceId;
FlaxView* MainView = nullptr;
FlaxViewController* MainViewController = nullptr;
iOSWindow* MainWindow = nullptr;
CriticalSection UIThreadFuncLocker;
Array<Function<void()>> UIThreadFuncList;
struct MessagePipeline
{
CriticalSection Locker;
Array<Function<void()>> List;
void Add(const Function<void()>& func, bool wait)
{
Locker.Lock();
List.Add(func);
Locker.Unlock();
// TODO: use atomic counters for more optimized waiting
while (wait)
{
Platform::Sleep(1);
Locker.Lock();
wait = List.HasItems();
Locker.Unlock();
}
}
void Run()
{
Locker.Lock();
for (const auto& func : List)
{
func();
}
List.Clear();
Locker.Unlock();
}
};
MessagePipeline UIThreadPipeline;
MessagePipeline MainThreadPipeline;
@implementation FlaxView
@@ -44,7 +78,9 @@ Array<Function<void()>> UIThreadFuncList;
if (!MainWindow)
return;
float scale = [[UIScreen mainScreen] scale];
MainWindow->CheckForResize((float)frame.size.width * scale, (float)frame.size.height * scale);
float width = (float)frame.size.width * scale;
float height = (float)frame.size.height * scale;
iOSPlatform::RunOnMainThread([width, height]() { MainWindow->CheckForResize(width, height); });
}
@end
@@ -66,16 +102,6 @@ Array<Function<void()>> UIThreadFuncList;
return UIStatusBarAnimationSlide;
}
- (void)loadView
{
[super loadView];
UILabel *label = [[UILabel alloc] initWithFrame:self.view.bounds];
[label setText:@"Hello World from Flax"];
[label setBackgroundColor:[UIColor systemBackgroundColor]];
[label setTextAlignment:NSTextAlignmentCenter];
self.view = label;
}
@end
@interface FlaxAppDelegate()
@@ -86,7 +112,7 @@ Array<Function<void()>> UIThreadFuncList;
@implementation FlaxAppDelegate
-(void)GameThreadMain:(NSDictionary*)launchOptions
-(void)MainThreadMain:(NSDictionary*)launchOptions
{
// Run engine on a separate game thread
Engine::Main(TEXT(""));
@@ -95,13 +121,7 @@ Array<Function<void()>> UIThreadFuncList;
-(void)UIThreadMain
{
// Invoke callbacks
UIThreadFuncLocker.Lock();
for (const auto& func : UIThreadFuncList)
{
func();
}
UIThreadFuncList.Clear();
UIThreadFuncLocker.Unlock();
UIThreadPipeline.Run();
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
@@ -110,10 +130,6 @@ Array<Function<void()>> UIThreadFuncList;
CGRect frame = [[UIScreen mainScreen] bounds];
self.window = [[UIWindow alloc] initWithFrame:frame];
// Create view controller
self.viewController = [[FlaxViewController alloc] init];
MainViewController = self.viewController;
// Create view
self.view = [[FlaxView alloc] initWithFrame:frame];
[self.view resignFirstResponder];
@@ -123,6 +139,13 @@ Array<Function<void()>> UIThreadFuncList;
self.view.backgroundColor = [UIColor clearColor];
MainView = self.view;
// Create view controller
self.viewController = [[FlaxViewController alloc] init];
[self.viewController setView:self.view];
[self.viewController setNeedsUpdateOfHomeIndicatorAutoHidden];
[self.viewController setNeedsStatusBarAppearanceUpdate];
MainViewController = self.viewController;
// Create navigation controller
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window setRootViewController:navController];
@@ -133,15 +156,15 @@ Array<Function<void()>> UIThreadFuncList;
self.displayLink.preferredFramesPerSecond = 30;
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
// Run engine on a separate game thread
NSThread* gameThread = [[NSThread alloc] initWithTarget:self selector:@selector(GameThreadMain:) object:launchOptions];
// Run engine on a separate main thread
NSThread* mainThread = [[NSThread alloc] initWithTarget:self selector:@selector(MainThreadMain:) object:launchOptions];
#if BUILD_DEBUG
const int32 gameThreadStackSize = 4 * 1024 * 1024; // 4 MB
const int32 mainThreadStackSize = 4 * 1024 * 1024; // 4 MB
#else
const int32 gameThreadStackSize = 2 * 1024 * 1024; // 2 MB
const int32 mainThreadStackSize = 2 * 1024 * 1024; // 2 MB
#endif
[gameThread setStackSize:gameThreadStackSize];
[gameThread start];
[mainThread setStackSize:mainThreadStackSize];
[mainThread start];
return YES;
}
@@ -285,18 +308,12 @@ bool iOSFileSystem::IsReadOnly(const StringView& path)
void iOSPlatform::RunOnUIThread(const Function<void()>& func, bool wait)
{
UIThreadFuncLocker.Lock();
UIThreadFuncList.Add(func);
UIThreadFuncLocker.Unlock();
UIThreadPipeline.Add(func, wait);
}
// TODO: use atomic counters for more optimized waiting
while (wait)
{
Platform::Sleep(1);
UIThreadFuncLocker.Lock();
wait = UIThreadFuncList.HasItems();
UIThreadFuncLocker.Unlock();
}
void iOSPlatform::RunOnMainThread(const Function<void()>& func, bool wait)
{
MainThreadPipeline.Add(func, wait);
}
bool iOSPlatform::Init()
@@ -330,7 +347,8 @@ void iOSPlatform::LogInfo()
void iOSPlatform::Tick()
{
// TODO: get events from UI Thread
// Invoke callbacks
MainThreadPipeline.Run();
ApplePlatform::Tick();
}

View File

@@ -14,6 +14,8 @@ class FLAXENGINE_API iOSPlatform : public ApplePlatform
public:
// Runs the callback on a main UI thread (from iOS). Can optionally wait for execution end to sync.
static void RunOnUIThread(const Function<void()>& func, bool wait = false);
// Runs the callback on a main thread (from Flax). Can optionally wait for execution end to sync.
static void RunOnMainThread(const Function<void()>& func, bool wait = false);
public: