using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace SkyHook
{
public class SkyHookManager : MonoBehaviour
{
private static SkyHookManager _instance;
private static bool _isFocused;
///
/// Whether or not the event will be received only if the game window is focused.
///
// ReSharper disable once MemberCanBePrivate.Global
// ReSharper disable once FieldCanBeMadeReadOnly.Global
public static bool RequireFocus = true;
private bool _started;
///
/// The key updated event data
///
// ReSharper disable once MemberCanBePrivate.Global
public static readonly UnityEvent KeyUpdated = new();
///
/// The instance of sky hook manager. The instance will be crated if it does not exist
///
// ReSharper disable once MemberCanBePrivate.Global
public static SkyHookManager Instance
{
get
{
if (_instance) return _instance;
var obj = new GameObject("SkyHook Manager");
_instance = obj.AddComponent();
DontDestroyOnLoad(_instance);
return _instance;
}
}
private void HookCallback(SkyHookEvent ev)
{
if (RequireFocus && !_isFocused)
{
return;
}
KeyUpdated.Invoke(ev);
}
private void _StartHook()
{
var started = false;
Exception exception = null;
new Thread(() =>
{
if (_started) return;
var result = SkyHookNative.StartHook(HookCallback);
if (result != null)
{
exception = new SkyHookException(result);
}
_started = true;
started = true;
while (_started)
{
}
}).Start();
while (!started && exception == null)
{
}
if (exception != null)
{
throw exception;
}
}
private void _StopHook()
{
if (!_started) return;
var result = SkyHookNative.StopHook();
if (result != null)
{
throw new SkyHookException(result);
}
_started = false;
}
public static void StartHook()
{
Instance._StartHook();
}
public static void StopHook()
{
Instance._StopHook();
}
private void OnDestroy()
{
_StopHook();
}
private void Update()
{
if (RequireFocus)
{
_isFocused = Application.isFocused;
}
}
}
}