BITKit/Src/Unity/Scripts/BITAppForUnity.cs

226 lines
6.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
using BITKit.UX;
using Microsoft.Extensions.DependencyInjection;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
using Debug = UnityEngine.Debug;
#if !UNITY_EDITOR
using UnityEngine;
using UnityEngine.Rendering;
public class SkipSplash
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
private static void BeforeSplashScreen()
{
#if UNITY_WEBGL
Application.focusChanged += Application_focusChanged;
#else
System.Threading.Tasks.Task.Run(AsyncSkip);
#endif
}
#if UNITY_WEBGL
private static void Application_focusChanged(bool obj)
{
Application.focusChanged -= Application_focusChanged;
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
}
#else
private static void AsyncSkip()
{
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
}
#endif
}
#endif
namespace BITKit
{
public class MouseNotOverGameViewException : System.Exception
{
public MouseNotOverGameViewException()
{
}
}
public class BITAppForUnity : MonoBehaviour
{
[Serializable]
public class OpenUrl
{
[SerializeField] public string url;
[SerializeReference,SubclassSelector] public IReference urlReference;
public virtual void Execute()
{
Application.OpenURL(urlReference is not null?urlReference.Value:url);
}
}
[RuntimeInitializeOnLoadMethod]
public static void Initialize()
{
stopWatcher = new Stopwatch();
stopWatcher.Start();
}
public struct Path
{
public const string Entity = nameof(Entity);
public const string Services = nameof(Services);
public const string Prefabs = nameof(Prefabs);
}
public static bool IsPlaying { get;private set; }
public static bool IsPointerOverUI { get; set; }
public static bool IsEditor
{
get
{
#if UNITY_EDITOR
return Application.isEditor;
#else
return false;
#endif
}
}
public static ValidHandle AllowCursor = new();
public static ValidHandle AllowTouchSupport = new();
public static GameObject GameObject;
private static Stopwatch stopWatcher;
public static void ThrowIfNotPlaying()
{
#if UNITY_EDITOR
if (IsPlaying is false)
{
throw new AppIsNotPlayingException();
}
#endif
}
public static void ThrowIfWindowNotFocus()
{
#if UNITY_EDITOR && ENABLE_INPUT_SYSTEM
switch (Camera.main)
{
case {} camera:
if (camera.pixelRect.Contains(Input.mousePosition) is false)
{
throw new MouseNotOverGameViewException();
}
break;
}
var window = UnityEditor.EditorWindow.focusedWindow;
var windowName = window is not null ? window.ToString() : string.Empty;
switch (windowName)
{
case " (UnityEditor.GameView)":
return;
default:
throw new MouseNotOverGameViewException();
}
#endif
}
[RuntimeInitializeOnLoadMethod]
private static void Reload()
{
IsPlaying = true;
//启动BITApp
BITApp.SynchronizationContext = SynchronizationContext.Current;
BITApp.Start(Application.productName, new BITApp.AppSettings()).Forget();
AllowCursor = new();
AllowTouchSupport = new();
GameObject = new(nameof(BITApp));
GameObject.AddComponent<BITAppForUnity>();
DontDestroyOnLoad(GameObject);
AllowCursor.AddListener(ToggleCursor);
AllowTouchSupport.AddListener(ToggleTouchSupport);
}
private static void ToggleCursor(bool active)
{
Cursor.lockState = active ? CursorLockMode.None : CursorLockMode.Locked;
Cursor.visible = active;
}
private static void ToggleTouchSupport(bool active)
{
#if ENABLE_INPUT_SYSTEM
if (active)
{
UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Enable();
}
else
{
UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Disable();
}
#endif
}
[BITCommand]
public static async void Exit()
{
await BITApp.SwitchToMainThread();
BITApp.Stop();
Data.Clear();
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
[SerializeField, ReadOnly] private bool allowCursor;
private void Start()
{
BIT4Log.Log<BITApp>($"已创建{nameof(BITApp)}");
stopWatcher.Stop();
BIT4Log.Log<BITAppForUnity>($"从初始化到创建{nameof(BITApp)}耗时:{stopWatcher.ElapsedMilliseconds}ms");
}
private void OnDestroy()
{
IsPlaying = false;
Exit();
}
private void Update()
{
BITApp.Time.ElapsedTime = Time.time;
BITApp.Time.DeltaTime = Time.deltaTime;
BITApp.Time.TimeAsDouble = Time.timeAsDouble;
allowCursor = AllowCursor.Allow;
if (Touchscreen.current is not null && Touchscreen.current.IsPressed())
{
AllowCursor.AddElement(int.MaxValue);
}else if (Mouse.current is not null && Mouse.current.IsPressed())
{
AllowCursor.RemoveElement(int.MaxValue);
}
}
public string GetName()
{
return nameof(BITApp);
}
public object GetDiagnostics()
{
return BITApp.State;
}
}
}