GlibTimeout.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Avalonia.Gtk3.Interop
  8. {
  9. static class GlibTimeout
  10. {
  11. static bool Handler(IntPtr data)
  12. {
  13. var handle = GCHandle.FromIntPtr(data);
  14. var cb = (Func<bool>) handle.Target;
  15. if (!cb())
  16. {
  17. handle.Free();
  18. return false;
  19. }
  20. return true;
  21. }
  22. private static readonly GCHandle PinnedHandle;
  23. private static readonly Native.D.timeout_callback PinnedHandler;
  24. static GlibTimeout()
  25. {
  26. PinnedHandler = Handler;
  27. }
  28. public static void Add(uint interval, Func<bool> callback)
  29. {
  30. var handle = GCHandle.Alloc(callback);
  31. Native.GTimeoutAdd(interval, PinnedHandler, GCHandle.ToIntPtr(handle));
  32. }
  33. public static void Add(int priority, uint interval, Func<bool> callback)
  34. {
  35. var handle = GCHandle.Alloc(callback);
  36. Native.GTimeoutAddFull(priority, interval, PinnedHandler, GCHandle.ToIntPtr(handle), IntPtr.Zero);
  37. }
  38. class Timer : IDisposable
  39. {
  40. public bool Stopped;
  41. public void Dispose()
  42. {
  43. Stopped = true;
  44. }
  45. }
  46. public static IDisposable StarTimer(uint interval, Action tick)
  47. {
  48. var timer = new Timer ();
  49. GlibTimeout.Add(interval,
  50. () =>
  51. {
  52. if (timer.Stopped)
  53. return false;
  54. tick();
  55. return !timer.Stopped;
  56. });
  57. return timer;
  58. }
  59. }
  60. }