2
0

UrhoSurface.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Runtime.InteropServices;
  4. using CoreGraphics;
  5. using UIKit;
  6. using Foundation;
  7. using System.ComponentModel;
  8. using System.Threading;
  9. namespace Urho.iOS
  10. {
  11. [Register("UrhoSurface"), DesignTimeVisible(true)]
  12. public class UrhoSurface : UIView
  13. {
  14. [DllImport(Consts.NativeImport, CallingConvention = CallingConvention.Cdecl)]
  15. static extern void SDL_SetExternalViewPlaceholder(IntPtr viewPtr, IntPtr windowPtr);
  16. [DllImport(Consts.NativeImport, CallingConvention = CallingConvention.Cdecl)]
  17. static extern void UIKit_StopRenderLoop(IntPtr window);
  18. static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
  19. static readonly SemaphoreSlim ExitSemaphore = new SemaphoreSlim(1);
  20. TaskCompletionSource<bool> waitWhileSuperviewIsNullTaskSource = new TaskCompletionSource<bool>();
  21. bool paused;
  22. public UrhoSurface() { }
  23. public UrhoSurface(IntPtr handle) : base(handle) { }
  24. public override void AwakeFromNib()
  25. {
  26. base.AwakeFromNib();
  27. }
  28. public UrhoSurface(CGRect frame) : base(frame)
  29. {
  30. UrhoPlatformInitializer.DefaultInit();
  31. }
  32. public static void Pause()
  33. {
  34. if (!Application.HasCurrent) return;
  35. Application.Current.Input.Enabled = false;
  36. Application.Current.Engine.PauseMinimized = true;
  37. Sdl.SendWindowEvent(SdlWindowEvent.SDL_WINDOWEVENT_FOCUS_LOST);
  38. Sdl.SendWindowEvent(SdlWindowEvent.SDL_WINDOWEVENT_MINIMIZED);
  39. Urho.Application.HandlePause();
  40. }
  41. public static void Resume()
  42. {
  43. if (!Application.HasCurrent) return;
  44. Application.Current.Input.Enabled = true;
  45. Application.Current.Engine.PauseMinimized = false;
  46. Sdl.SendWindowEvent(SdlWindowEvent.SDL_WINDOWEVENT_FOCUS_GAINED);
  47. Sdl.SendWindowEvent(SdlWindowEvent.SDL_WINDOWEVENT_RESTORED);
  48. Urho.Application.HandleResume();
  49. }
  50. public Application Application { get; private set; }
  51. public bool Paused
  52. {
  53. get { return paused; }
  54. set
  55. {
  56. if (!value)
  57. Resume();
  58. else
  59. Pause();
  60. paused = value;
  61. }
  62. }
  63. public async Task<TApplication> Show<TApplication>(ApplicationOptions opts = null) where TApplication : Application
  64. {
  65. return (TApplication)(await Show(typeof(TApplication), opts));
  66. }
  67. public async Task<Application> Show(Type appType, ApplicationOptions opts = null)
  68. {
  69. LogSharp.Debug("UrhoSurface: Show.");
  70. await waitWhileSuperviewIsNullTaskSource.Task;
  71. UrhoPlatformInitializer.DefaultInit();
  72. await Task.Yield();
  73. paused = false;
  74. opts = opts ?? new ApplicationOptions();
  75. LogSharp.Debug("UrhoSurface: Show. Wait semaphore.");
  76. await Semaphore.WaitAsync();
  77. //await Stop();
  78. if (Application.HasCurrent)
  79. await Application.Current.Exit();
  80. await Task.Yield();
  81. SDL_SetExternalViewPlaceholder(Handle, Window.Handle);
  82. Hidden = true;
  83. var app = Application.CreateInstance(appType, opts);
  84. Application = app;
  85. app.Run();
  86. Semaphore.Release();
  87. Urho.Application.CurrentSurface = new WeakReference(this);
  88. Urho.Application.CurrentWindow = new WeakReference(Window);
  89. if (!opts.DelayedStart)
  90. await Application.ToMainThreadAsync();
  91. InvokeOnMainThread(() => Hidden = false);
  92. LogSharp.Debug("UrhoSurface: Finished.");
  93. return app;
  94. }
  95. public static void StopRendering(Application app)
  96. {
  97. LogSharp.Debug("UrhoSurface: StopRendering.");
  98. Resume();
  99. if (Application.HasCurrent && Application.Current.Graphics?.IsDeleted != true)
  100. {
  101. var window = Application.Current.Graphics.SdlWindow;
  102. if (window != IntPtr.Zero)
  103. {
  104. LogSharp.Debug("UrhoSurface: UIKit_StopRenderLoop.");
  105. UIKit_StopRenderLoop(window);
  106. }
  107. }
  108. LogSharp.Debug("UrhoSurface: Finished.");
  109. }
  110. public async Task Stop()
  111. {
  112. LogSharp.Debug("UrhoSurface: Stop.");
  113. if (Application == null || !Application.IsActive)
  114. return;
  115. LogSharp.Debug("UrhoSurface: Stop. Wait semaphore.");
  116. await ExitSemaphore.WaitAsync();
  117. LogSharp.Debug("UrhoSurface: Stop. Exiting...");
  118. await Application.Exit();
  119. LogSharp.Debug("UrhoSurface: Stop. Removing subviews...");
  120. foreach (var view in Subviews)
  121. {
  122. view.RemoveFromSuperview();
  123. }
  124. ExitSemaphore.Release();
  125. LogSharp.Debug("UrhoSurface: Stop. Finished.");
  126. }
  127. public override void RemoveFromSuperview()
  128. {
  129. base.RemoveFromSuperview();
  130. waitWhileSuperviewIsNullTaskSource = new TaskCompletionSource<bool>();
  131. }
  132. public override async void WillMoveToWindow(UIWindow window)
  133. {
  134. base.WillMoveToWindow(window);
  135. await Task.Yield();
  136. waitWhileSuperviewIsNullTaskSource.TrySetResult(true);
  137. }
  138. }
  139. }