Dispatcher.cs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System;
  4. using UnityEngine;
  5. namespace Vuplex.WebView.Internal {
  6. /// <summary>
  7. /// Utility class for running code on the main Unity thread.
  8. /// </summary>
  9. /// <remarks>
  10. /// From [this Unity forum post](https://answers.unity.com/questions/305882/how-do-i-invoke-functions-on-the-main-thread.html#answer-1417505).
  11. /// </remarks>
  12. public class Dispatcher : MonoBehaviour {
  13. public static void RunAsync(Action action) {
  14. ThreadPool.QueueUserWorkItem(o => action());
  15. }
  16. public static void RunAsync(Action<object> action, object state) {
  17. ThreadPool.QueueUserWorkItem(o => action(o), state);
  18. }
  19. public static void RunOnMainThread(Action action) {
  20. lock(_backlog) {
  21. _backlog.Add(action);
  22. _queued = true;
  23. }
  24. }
  25. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  26. private static void Initialize() {
  27. if (_instance == null) {
  28. _instance = new GameObject("Dispatcher").AddComponent<Dispatcher>();
  29. DontDestroyOnLoad(_instance.gameObject);
  30. }
  31. }
  32. private void Update() {
  33. if (_queued) {
  34. lock(_backlog) {
  35. var tmp = _actions;
  36. _actions = _backlog;
  37. _backlog = tmp;
  38. _queued = false;
  39. }
  40. foreach (var action in _actions) {
  41. try {
  42. action();
  43. } catch (Exception e) {
  44. WebViewLogger.LogError("An exception occurred while dispatching an action on the main thread: " + e);
  45. }
  46. }
  47. _actions.Clear();
  48. }
  49. }
  50. static Dispatcher _instance;
  51. static volatile bool _queued = false;
  52. static List<Action> _backlog = new List<Action>(8);
  53. static List<Action> _actions = new List<Action>(8);
  54. }
  55. }