Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Window.cs
浏览该文件的文档.
1#if ANDROID
2#pragma warning disable CA1416
3using Android.Content;
4using Android.OS;
5using Android.Views;
6using Org.Libsdl.App;
7#elif BROWSER
9using System.Runtime.InteropServices;
10#elif !IOS
11using System.Diagnostics;
12using System.Reflection;
13using System.Runtime.CompilerServices;
14using Silk.NET.Core;
15using Silk.NET.GLFW;
16using SixLabors.ImageSharp;
17using SixLabors.ImageSharp.PixelFormats;
18using Silk.NET.Input;
19using Monitor = Silk.NET.Windowing.Monitor;
20#if WINDOWS
21using System.Runtime.InteropServices;
22#endif
23#endif
24#if !BROWSER
25using Silk.NET.Windowing;
26#endif
27using Engine.Audio;
28using Engine.Graphics;
29using Engine.Input;
30using Silk.NET.Core.Contexts;
31using Silk.NET.Maths;
33using Environment = System.Environment;
34
35namespace Engine {
36 public static class Window {
42
43 static State m_state;
44#if BROWSER
45 //public static string HostedHref;
46#else
47 public static IView m_view;
48#endif
49
50#if ANDROID
51 public static EngineActivity Activity => EngineActivity.m_activity;
52
53 public static SDLSurface m_surface;
54#elif !IOS && !BROWSER
55 public static IWindow m_gameWindow;
56
57 public static IInputContext m_inputContext;
58#endif
59
60 static bool m_closing;
61 static bool m_closingRequested;
62 static bool m_restarting;
63#pragma warning disable CS0169
64 static int? m_swapInterval;
65#pragma warning restore CS0169
66 public static string m_titlePrefix = string.Empty;
67
68 public static string m_titleSuffix = string.Empty;
69
70 public static float m_lastRenderDelta;
71
72 public static Point2 ScreenSize {
73 get {
74#if MOBILE
75 return new Point2(m_view.Size.X, m_view.Size.Y);
76#elif BROWSER
77 return Size;
78#else
79 IMonitor monitor = m_gameWindow?.Monitor;
80 if (monitor == null) {
81 try {
82 monitor = Monitor.GetMainMonitor(null);
83 }
84 catch (Exception e) {
85 if (e is PlatformNotSupportedException) {
86#if WINDOWS
87 string str =
88 "GLFW Window Platform is not applicable. Please install Microsoft Visual C++ Redistributable. Click \"OK\" to open download page.\nGLFW 窗口平台无法使用。请安装 Microsoft Visual C++ Redistributable,点击\"确定\"来打开下载页面。";
89 const string downloadLink =
90 "https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version";
91 Log.Error($"GLFW Window Platform is not applicable. Please install Microsoft Visual C++ Redistributable. GLFW 窗口平台无法使用。请安装 Microsoft Visual C++ Redistributable。\nDownload page 下载页: {downloadLink}\nException details: {e}");
92 new Thread(() => {
93 if (MessageBox(IntPtr.Zero, str, null, 0x11u) == 1) {
94 Process.Start(
95 new ProcessStartInfo(
96 downloadLink
97 ) { UseShellExecute = true }
98 );
99 }
100 }
101 ).Start();
102#else
103 if (OperatingSystem.IsLinux()) {
104 const string str =
105 "GLFW Window Platform is not applicable. Please check: https://dotnet.github.io/Silk.NET/docs/hlu/troubleshooting.html";
106 Process.Start("notify-send", $"-a \"Survivalcraft API\" -u critical \"Error\" \"{str}\"");
107 Log.Error(str);
108 }
109#endif
110 }
111 else {
112 Log.Error($"Get screen size failed.\n{e}");
113 }
114 return Point2.Zero;
115 }
116 }
117 Vector2D<int> size = monitor.Bounds.Size;
118 return new Point2(size.X, size.Y);
119#endif
120 }
121 }
122
123 public static WindowMode WindowMode {
124 get {
125#if MOBILE
126 return WindowMode.Fullscreen;
127#elif BROWSER
129#else
131 return m_gameWindow.WindowState == WindowState.Fullscreen ? WindowMode.Fullscreen :
132 m_gameWindow.WindowBorder != 0 ? WindowMode.Fixed : WindowMode.Resizable;
133#endif
134 }
135 // ReSharper disable ValueParameterNotUsed
136 set
137 // ReSharper restore ValueParameterNotUsed
138 {
139#if BROWSER
140 if (value == WindowMode.Fullscreen) {
143 }
144 }
145 else if (InputBridge.IsFullscreen) {
147 }
148#elif !MOBILE
149 if (!IsWindowOpened()) {
150 return;
151 }
152 switch (value) {
153 case WindowMode.Fixed:
154 m_gameWindow.WindowBorder = WindowBorder.Fixed;
155 if (m_gameWindow.WindowState != WindowState.Normal) {
156 m_gameWindow.WindowState = WindowState.Normal;
157 }
158 break;
159 case WindowMode.Resizable:
160 m_gameWindow.WindowBorder = WindowBorder.Resizable;
161 if (m_gameWindow.WindowState != WindowState.Normal) {
162 m_gameWindow.WindowState = WindowState.Normal;
163 }
164 break;
165 case WindowMode.Borderless:
166 m_gameWindow.WindowBorder = WindowBorder.Hidden;
167 if (m_gameWindow.WindowState != WindowState.Normal) {
168 m_gameWindow.WindowState = WindowState.Normal;
169 }
170 break;
171 case WindowMode.Fullscreen:
172 m_gameWindow.WindowBorder = WindowBorder.Resizable;
173 m_gameWindow.WindowState = WindowState.Normal;
174 m_gameWindow.WindowState = WindowState.Fullscreen;
175 break;
176 }
177#endif
178 }
179 }
180
181 public static Point2 Position {
182 get {
184#if MOBILE || BROWSER
185 return Point2.Zero;
186#else
187 return new Point2(m_gameWindow.Position.X, m_gameWindow.Position.Y);
188#endif
189 }
190 // ReSharper disable ValueParameterNotUsed
191 set
192 // ReSharper restore ValueParameterNotUsed
193 {
194#if !MOBILE && !BROWSER
195 if (!IsWindowOpened()) {
196 return;
197 }
198 m_gameWindow.Position = new Vector2D<int>(value.X, value.Y);
199#endif
200 }
201 }
202
203 public static Point2 Size {
204 get {
206#if BROWSER
207 return InputBridge.CanvasSize;
208#else
209 return new Point2(m_view.FramebufferSize.X, m_view.FramebufferSize.Y);
210#endif
211 }
212 // ReSharper disable ValueParameterNotUsed
213 set
214 // ReSharper restore ValueParameterNotUsed
215 {
216#if !MOBILE && !BROWSER
217 if (!IsWindowOpened()) {
218 return;
219 }
220 m_gameWindow.Size = new Vector2D<int>(value.X, value.Y);
221#endif
222 }
223 }
224
225 public static bool HasWideNotch { get; set; }
226
230 public static Vector4 DisplayCutoutInsets { get; set; } = Vector4.Zero;
231
232 public static string TitlePrefix {
233 get {
235 return m_titlePrefix;
236 }
237 // ReSharper disable ValueParameterNotUsed
238 set
239 // ReSharper restore ValueParameterNotUsed
240 {
241#if !MOBILE
242 if (!IsWindowOpened()) {
243 return;
244 }
245 m_titlePrefix = value;
246 string newTitle = $"{m_titlePrefix}{m_titleSuffix}";
247#if BROWSER
248 BrowserInterop.SetTitle(newTitle);
249#else
250 m_gameWindow.Title = newTitle;
251#endif
252#endif
253 }
254 }
255
256 public static string TitleSuffix {
257 get {
259 return m_titleSuffix;
260 }
261 // ReSharper disable ValueParameterNotUsed
262 set
263 // ReSharper restore ValueParameterNotUsed
264 {
265#if !MOBILE
266 if (!IsWindowOpened()) {
267 return;
268 }
269 m_titleSuffix = value;
270 string newTitle = $"{m_titlePrefix}{m_titleSuffix}";
271#if BROWSER
272 BrowserInterop.SetTitle(newTitle);
273#else
274 m_gameWindow.Title = newTitle;
275#endif
276#endif
277 }
278 }
279
280 public static string Title {
281 get {
282#if MOBILE
283 return string.Empty;
284#elif BROWSER
285 return BrowserInterop.GetTitle();
286#else
288 return m_gameWindow.Title;
289#endif
290 }
291 // ReSharper disable ValueParameterNotUsed
292 set
293 // ReSharper restore ValueParameterNotUsed
294 {
295#if !MOBILE
296 if (!IsWindowOpened()) {
297 return;
298 }
299 m_titlePrefix = value;
300 m_titleSuffix = string.Empty;
301#if BROWSER
303#else
304 m_gameWindow.Title = value;
305#endif
306#endif
307 }
308 }
309
310 public static int PresentationInterval {
311 #if IOS || BROWSER
312 get => 1;
313 set { }
314#else
315 get {
317 m_swapInterval ??= m_view.VSync ? 1 : 0;
318 return m_swapInterval.Value;
319 }
320 set {
321 if (!IsWindowOpened()) {
322 return;
323 }
324 value = Math.Clamp(value, 0, 4);
325 if (value != PresentationInterval) {
326#if ANGLE
327 Egl.SwapInterval(GLWrapper.m_eglDisplay, value);
328#else
329 m_view.GLContext?.SwapInterval(value);
330#endif
331 m_swapInterval = value;
332 }
333 }
334#endif
335 }
336
337 public static IntPtr Handle {
338 get {
339#if !BROWSER
340 INativeWindow native = m_view.Native;
341 if (native != null) {
342 NativeWindowFlags kind = native.Kind;
343 if (kind.HasFlag(NativeWindowFlags.Win32)) {
344 return native.Win32?.Hwnd ?? IntPtr.Zero;
345 }
346 if (kind.HasFlag(NativeWindowFlags.Android)) {
347 return native.Android?.Window ?? IntPtr.Zero;
348 }
349 if (kind.HasFlag(NativeWindowFlags.X11)) {
350 return (IntPtr)(native.X11?.Window.ToUInt64() ?? 0UL);
351 }
352 if (kind.HasFlag(NativeWindowFlags.Wayland)) {
353 return native.Wayland?.Surface ?? IntPtr.Zero;
354 }
355 }
356#endif
357 return IntPtr.Zero;
358 }
359 }
360
361 public static bool IsCreated => m_state != State.Uncreated;
362 public static bool IsActive => m_state == State.Active;
363
364 public static event Action Created;
365
366 public static event Action Resized;
367
368 public static event Action<Vector4, bool> DisplayCutoutInsetsChanged;
369
370 public static event Action Activated;
371
372 public static event Action Deactivated;
373
374 public static event Action Closed;
375
376 public static event Action ToRestart;
377
378 public static event Action Frame;
379
380 public static event Action<UnhandledExceptionInfo> UnhandledException;
381
382 public static event Action<Uri> HandleUri;
383
384 public static event Action LowMemory;
385
386 public static event Action<List<(Stream stream, string fileName)>> FileDropped;
387
388#if MOBILE
389 public const string WindowingLibrary = "Silk.NET.Windowing.Sdl";
390#elif !BROWSER
391 public const string WindowingLibrary = "Silk.NET.Windowing.Glfw";
392 public const string InputLibrary = "Silk.NET.Input.Glfw";
393#endif
394
395 public static void Run(int width = 0, int height = 0, WindowMode windowMode = WindowMode.Resizable, string title = "") {
396#if !BROWSER
397 if (m_view != null) {
398 throw new InvalidOperationException("Window is already opened.");
399 }
400#endif
401 width = Math.Max(width, 0);
402 height = Math.Max(height, 0);
403 if (width > 0
404 && height <= 0) {
405 throw new ArgumentOutOfRangeException(nameof(height));
406 }
407 if (width <= 0
408 && height > 0) {
409 throw new ArgumentOutOfRangeException(nameof(width));
410 }
411 AppDomain.CurrentDomain.UnhandledException += delegate(object _, UnhandledExceptionEventArgs args) {
412 Exception ex = args.ExceptionObject as Exception;
413 ex ??= new Exception($"Unknown exception. Additional information: {args.ExceptionObject}");
414 UnhandledExceptionInfo unhandledExceptionInfo = new(ex);
415 UnhandledException?.Invoke(unhandledExceptionInfo);
416 if (!unhandledExceptionInfo.IsHandled) {
417 Log.Error("Application terminating due to unhandled exception {0}", unhandledExceptionInfo.Exception);
418 Environment.Exit(1);
419 }
420 };
421#if !BROWSER
422 Silk.NET.Windowing.Window.ShouldLoadFirstPartyPlatforms(false);
423 Silk.NET.Windowing.Window.TryAdd(WindowingLibrary);
424#endif
425#if DIRECT3D11 || ANGLE
426 GraphicsAPI api = GraphicsAPI.None;
427#elif IOS
428 GraphicsAPI api = new(ContextAPI.OpenGLES, ContextProfile.Core, ContextFlags.Default, new APIVersion(3, 0));
429#elif BROWSER
430#elif DEBUG
431 GraphicsAPI api = new(ContextAPI.OpenGLES, ContextProfile.Compatability, ContextFlags.Debug, new APIVersion(3, 2));
432#elif ANDROID
433 Activity.GetGlEsVersion(out int major, out int minor);
434 GraphicsAPI api = new(ContextAPI.OpenGLES, new APIVersion(major, minor));
435#else
436 GraphicsAPI api = new(ContextAPI.OpenGLES, new APIVersion(3, 2));
437#endif
438#if ANDROID
439 Log.Information($"Android.OS.Build.Display: {Build.Display}");
440 Log.Information($"Android.OS.Build.Device: {Build.Device}");
441 Log.Information($"Android.OS.Build.Hardware: {Build.Hardware}");
442 Log.Information($"Android.OS.Build.Manufacturer: {Build.Manufacturer}");
443 Log.Information($"Android.OS.Build.Model: {Build.Model}");
444 Log.Information($"Android.OS.Build.Product: {Build.Product}");
445 Log.Information($"Android.OS.Build.Brand: {Build.Brand}");
446 Log.Information($"Android.OS.Build.VERSION.SdkInt: {(int)Build.VERSION.SdkInt}");
447 ViewOptions options = ViewOptions.Default with { API = api };
448 m_view = Silk.NET.Windowing.Window.GetView(options);
449 Activity.Paused += PausedHandler;
450 Activity.Resumed += ResumedHandler;
451 Activity.Destroyed += DestroyedHandler;
452 Activity.NewIntent += NewIntentHandler;
453#elif IOS
454 ViewOptions options = ViewOptions.Default with { API = api };
455 m_view = Silk.NET.Windowing.Window.GetView(options);
456#elif BROWSER
457 Title = title;
458#else
459 Point2 screenSize = ScreenSize;
460 if (screenSize.X == 0
461 && screenSize.Y == 0) {
462 return;
463 }
464 width = width == 0 ? screenSize.X * 4 / 5 : width;
465 height = height == 0 ? screenSize.Y * 4 / 5 : height;
466 WindowOptions windowOptions = WindowOptions.Default with {
467 Title = title, PreferredDepthBufferBits = 24, PreferredStencilBufferBits = 8, API = api, Size = new Vector2D<int>(width, height)
468 };
469 m_gameWindow = Silk.NET.Windowing.Window.Create(windowOptions);
471 m_titlePrefix = title;
472 Position = new Point2(Math.Max((screenSize.X - m_gameWindow.Size.X) / 2, 0), Math.Max((screenSize.Y - m_gameWindow.Size.Y) / 2, 0));
473 WindowMode = windowMode;
474#endif
475#if BROWSER
476 LoadHandler();
477#else
478 m_view.ShouldSwapAutomatically = false;
479 m_view.Load += LoadHandler;
480 try {
481 m_view.Run(); //会阻塞,不要放置在前边
482 }
483#if !MOBILE
484 catch (GlfwException e) {
485 if (e.ErrorCode == ErrorCode.VersionUnavailable) {
486 const string str =
487 "Your graphics card driver does not support the graphics API used by the current program. Please try updating your graphics card driver or using the compatible patch.\n你的显卡驱动不支持当前程序使用的图形API,请尝试更新显卡驱动,或使用兼容补丁。";
488 Log.Error($"str\n{e}");
489#if WINDOWS
490 new Thread(() => { MessageBox(IntPtr.Zero, str, null, 0x10u); }).Start();
491#else
492 if (OperatingSystem.IsLinux()) {
493 Process.Start("notify-send", $"-a \"Survivalcraft API\" -u critical \"Error\" \"{str}\"");
494 }
495#endif
496 }
497 else {
498 Log.Error($"Unhandled exception.\n{e}");
499 }
500 }
501#endif // !MOBILE
502 finally {
503#if !DIRECT3D11
504 GLWrapper.GL?.Dispose();
505#endif
506 m_view?.Dispose();
507 }
508#endif // !BROWSER
509 }
510
511 public static void Close() {
513 m_closing = true;
514 }
515
516 public static void Restart() {
518 m_closing = true;
519 m_restarting = true;
520 }
521
522 static void LoadHandler() {
525 m_state = State.Inactive;
526 Created?.Invoke();
527 if (m_state == State.Inactive) {
528 m_state = State.Active;
529 Activated?.Invoke();
530 }
531 }
532
533 internal static void FocusedChangedHandler(bool focused) {
534 if (focused) {
535 if (m_state == State.Inactive) {
536 m_state = State.Active;
537 Activated?.Invoke();
538 }
539 return;
540 }
541 if (m_state == State.Active) {
542 m_state = State.Inactive;
543 Deactivated?.Invoke();
544 }
545 Keyboard.Clear();
546 Mouse.Clear();
547 Touch.Clear();
548 }
549
550 static void ClosedHandler() {
551 if (m_state == State.Active) {
552 m_state = State.Inactive;
553 Deactivated?.Invoke();
554 }
555 if (m_state == State.Inactive) {
556 m_state = State.Uncreated;
557 Closed?.Invoke();
558 }
560 DisposeAll();
561 }
562
563 internal static void ResizeHandler(Vector2D<int> _) {
564#if MOBILE
565 if (m_state != State.Uncreated) {
566 Display.Resize();
567 Resized?.Invoke();
568 }
569#else
570 Display.Resize();
571 Resized?.Invoke();
572#endif
573 }
574#if BROWSER
575 internal static void FileDropHandler(Stream stream, string fileName) => FileDropped?.Invoke([(stream, fileName)]);
576#elif !MOBILE
577 static void FileDropHandler(string[] paths) {
578 List<(Stream stream, string fileName)> results = new(paths.Length);
579 foreach (string path in paths) {
580 try {
581 Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
582 results.Add((stream, Storage.GetFileName(path)));
583 }
584 catch (Exception e) {
585 Log.Error($"{e}");
586 }
587 }
588 FileDropped?.Invoke(results);
589 }
590#endif
591 public static void DisplayCutoutInsetsChangedHandler(Vector4 insets, bool hasWideNotch) {
592 if (HasWideNotch == hasWideNotch && DisplayCutoutInsets == insets) {
593 return;
594 }
595 HasWideNotch = hasWideNotch;
596 DisplayCutoutInsets = insets;
597 DisplayCutoutInsetsChanged?.Invoke(insets, hasWideNotch);
598 }
599
600#if BROWSER
601 [UnmanagedCallersOnly]
602 public static int BrowserRenderFrameHandler(double time, nint userData) {
603 RenderFrameHandler(time);
604 return 1;
605 }
606#endif
607
608 static void RenderFrameHandler(double lastRenderDelta) {
609 m_lastRenderDelta = (float)lastRenderDelta;
611 Frame?.Invoke();
613
614 if (!m_closing) {
615#if DIRECT3D11
617#elif ANGLE
618 Egl.SwapBuffers(GLWrapper.m_eglDisplay, GLWrapper.m_eglSurface);
619#elif !BROWSER
620 m_view.SwapBuffers();
621#endif
622 }
623 else if(!m_closingRequested){
624 m_closingRequested = true;
626#if ANDROID
627 if (Build.VERSION.SdkInt >= (BuildVersionCodes)21) {
628 Activity.FinishAndRemoveTask();
629 }
630 else {
631 Activity.FinishAffinity();
632 }
633#endif
634#if BROWSER
635 if (m_restarting) {
637 }
638 else {
640 }
641#else
642 m_view.Close();
643 if (m_restarting) {
644 ToRestart?.Invoke();
645 }
646#endif
647 }
648 }
649
650#if ANDROID
651 public static void PausedHandler() {
652 if (m_state == State.Active) {
653 m_state = State.Inactive;
654 Keyboard.Clear();
655 Deactivated?.Invoke();
656 }
657 }
658
659 public static void ResumedHandler() {
660 if (m_state == State.Inactive) {
661 m_state = State.Active;
662 Activity.EnableImmersiveMode();
663 if ((m_swapInterval ?? 1) == 0) {
664 Time.QueueFrameIndexDelayedExecution(10, () => { m_view.GLContext?.SwapInterval(0); });
665 }
666 Activated?.Invoke();
667 }
668 }
669
670 public static void DestroyedHandler() {
671 if (m_state == State.Active) {
672 m_state = State.Inactive;
673 Deactivated?.Invoke();
674 }
675 m_state = State.Uncreated;
676 Closed?.Invoke();
677 DisposeAll();
678 }
679
680 public static void NewIntentHandler(Intent intent) {
681 if (HandleUri != null
682 && intent != null) {
683 Uri uriFromIntent = GetUriFromIntent(intent);
684 if (uriFromIntent != null) {
685 HandleUri(uriFromIntent);
686 }
687 }
688 }
689
690 public static Uri GetUriFromIntent(Intent intent) {
691 Uri result = null;
692 if (!string.IsNullOrEmpty(intent.DataString)) {
693 Uri.TryCreate(intent.DataString, UriKind.RelativeOrAbsolute, out result);
694 }
695 return result;
696 }
697#endif
698
699 static void VerifyWindowOpened() {
700#if !BROWSER
701 if (m_view == null) {
702 throw new InvalidOperationException("Window is not opened.");
703 }
704#endif
705 }
706
707#if BROWSER
708 static bool IsWindowOpened() => true;
709#else
710 static bool IsWindowOpened() => m_view != null;
711#endif
712
713 static void SubscribeToEvents() {
714#if BROWSER
715 unsafe {
716 Emscripten.RequestAnimationFrameLoop((delegate* unmanaged<double, nint, int>)&BrowserRenderFrameHandler, nint.Zero);
717 }
718#else
719 m_view.FocusChanged += FocusedChangedHandler;
720 m_view.Closing += ClosedHandler;
721 m_view.Resize += ResizeHandler;
722 m_view.Render += RenderFrameHandler;
723#if !MOBILE && !BROWSER
724 m_gameWindow.FileDrop += FileDropHandler;
725#endif
726#endif
727 }
728
729 static void UnsubscribeFromEvents() {
730#if !BROWSER
731 m_view.FocusChanged -= FocusedChangedHandler;
732 m_view.Closing -= ClosedHandler;
733 m_view.Resize -= ResizeHandler;
734 m_view.Render -= RenderFrameHandler;
735#if !MOBILE
736 m_gameWindow.FileDrop -= FileDropHandler;
737#endif
738#endif
739 }
740
741 static void InitializeAll() {
742 try {
743#if ANDROID
744 if (SDLActivity.ContentView is ViewGroup viewGroup
745 && viewGroup.ChildCount >= 1
746 && viewGroup.GetChildAt(0) is SDLSurface surface) {
747 m_surface = surface;
748 }
749#elif !IOS && !BROWSER
750 using (Stream iconStream = typeof(Window).GetTypeInfo().Assembly.GetManifestResourceStream("Engine.Resources.icon.png")) {
751 if (iconStream != null) {
752 Image<Rgba32> image = SixLabors.ImageSharp.Image.Load<Rgba32>(Media.Image.DefaultImageSharpDecoderOptions, iconStream);
753 byte[] pixelBytes = new byte[image.Width * image.Height * Unsafe.SizeOf<Rgba32>()];
754 image.CopyPixelDataTo(pixelBytes);
755 m_gameWindow.SetWindowIcon([new RawImage(image.Width, image.Height, pixelBytes)]);
756 }
757 }
758 InputWindowExtensions.ShouldLoadFirstPartyPlatforms(false);
759 InputWindowExtensions.TryAdd(InputLibrary);
760 m_inputContext = m_view.CreateInput();
761#endif
764#if BROWSER
766#endif
772 }
773 catch (Exception ex) {
774 Log.Error($"Error occupies in InitializeAll: {ex}");
775 }
776 }
777
778 static void DisposeAll() {
781 Mouse.Dispose();
782 Touch.Dispose();
784 Mixer.Dispose();
785 Log.Dispose();
786 }
787
788 static void BeforeFrameAll() {
791#if BROWSER
793#endif
800 }
801
812
813#if WINDOWS
814 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
815 public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
816#endif
817 }
818}
Android.Net.Uri Uri
unsafe
定义 Main.cs:15
Engine.Media.Image Image
Silk.NET.Windowing.Monitor Monitor
System.Environment Environment
static void Initialize()
static void Dispose()
static void AfterFrame()
static void BeforeFrame()
static partial void SetTitle(string title)
static partial void SetFullscreen(bool fullscreen)
static partial string GetTitle()
static partial void Reload()
static partial void Close()
static partial void Initialize(IntPtr sharedInputMemoryPtr)
static unsafe void RequestAnimationFrameLoop(void *f, nint userDataPtr)
static void AfterFrame()
static void BeforeFrame()
static void Initialize()
static void Present(int presentationInterval)
static bool SwapInterval(IntPtr dpy, int interval)
static bool SwapBuffers(IntPtr dpy, IntPtr surface)
static void BeforeFrame()
static void Dispose()
static void AfterFrame()
static void Initialize()
static void BeforeFrame()
static void BeforeFrame()
static void Initialize()
static void Clear()
static void AfterFrame()
static void Dispose()
static void Clear()
static void AfterFrame()
static void Dispose()
static void BeforeFrame()
static void Initialize()
static void Error(object message)
定义 Log.cs:80
static void Dispose()
定义 Log.cs:130
static void Information(object message)
定义 Log.cs:56
static DecoderOptions DefaultImageSharpDecoderOptions
static string GetFileName(string path)
static void BeforeFrame()
定义 Time.cs:77
static void AfterFrame()
static Action Created
static string m_titleSuffix
static void UnsubscribeFromEvents()
static void InitializeAll()
static bool m_restarting
static Action Closed
static string TitleSuffix
static bool IsCreated
static bool m_closingRequested
static Point2 ScreenSize
static bool HasWideNotch
static float m_lastRenderDelta
const string WindowingLibrary
static string TitlePrefix
static bool m_closing
static bool IsActive
static void Run(int width=0, int height=0, WindowMode windowMode=WindowMode.Resizable, string title="")
static void DisplayCutoutInsetsChangedHandler(Vector4 insets, bool hasWideNotch)
static State m_state
static Action ToRestart
static Point2 Size
static void Close()
static Action Frame
static void VerifyWindowOpened()
static void FocusedChangedHandler(bool focused)
static Action Activated
static Point2 Position
static string m_titlePrefix
static Action Deactivated
static IInputContext m_inputContext
static Action< UnhandledExceptionInfo > UnhandledException
static string Title
static Action< Vector4, bool > DisplayCutoutInsetsChanged
static IWindow m_gameWindow
static void FileDropHandler(string[] paths)
static ? int m_swapInterval
static Action Resized
static IntPtr Handle
static Action< Uri > HandleUri
static WindowMode WindowMode
static void Restart()
static void BeforeFrameAll()
static void SubscribeToEvents()
static int PresentationInterval
static Action< List<(Stream stream, string fileName)> > FileDropped
static void ClosedHandler()
static Action LowMemory
static void LoadHandler()
static void ResizeHandler(Vector2D< int > _)
static bool IsWindowOpened()
const string InputLibrary
static IView m_view
static Vector4 DisplayCutoutInsets
刘海/水滴/挖孔在屏幕边缘的宽度。X: 左边,Y: 顶部,Z: 右边,W: 底部
static void DisposeAll()
static void AfterFrameAll()
static void RenderFrameHandler(double lastRenderDelta)
static readonly Point2 Zero
static readonly Vector4 Zero