SurfacePool.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using ChunkyImageLib.DataHolders;
  2. using System.Collections.Concurrent;
  3. namespace ChunkyImageLib
  4. {
  5. internal class SurfacePool
  6. {
  7. //must be divisible by 8
  8. public const int FullChunkSize = 256;
  9. private static object lockObj = new();
  10. private static SurfacePool? instance;
  11. public static SurfacePool Instance
  12. {
  13. get
  14. {
  15. if (instance is null)
  16. {
  17. lock (lockObj)
  18. {
  19. if (instance is null)
  20. instance = new SurfacePool();
  21. }
  22. }
  23. return instance;
  24. }
  25. }
  26. private readonly ConcurrentBag<Surface> fullSurfaces = new();
  27. private readonly ConcurrentBag<Surface> halfSurfaces = new();
  28. private readonly ConcurrentBag<Surface> quarterSurfaces = new();
  29. private readonly ConcurrentBag<Surface> eighthSurfaces = new();
  30. internal Surface Get(ChunkResolution resolution)
  31. {
  32. if (GetBag(resolution).TryTake(out Surface? item))
  33. return item;
  34. return new Surface(new Vector2i(resolution.PixelSize(), resolution.PixelSize()));
  35. }
  36. private ConcurrentBag<Surface> GetBag(ChunkResolution resolution)
  37. {
  38. return resolution switch
  39. {
  40. ChunkResolution.Full => fullSurfaces,
  41. ChunkResolution.Half => halfSurfaces,
  42. ChunkResolution.Quarter => quarterSurfaces,
  43. ChunkResolution.Eighth => eighthSurfaces,
  44. _ => fullSurfaces
  45. };
  46. }
  47. internal void Push(Surface surface, ChunkResolution resolution)
  48. {
  49. var surfaces = GetBag(resolution);
  50. //a race condition can cause the count to go above 200, but likely not by much
  51. if (surfaces.Count < 200)
  52. surfaces.Add(surface);
  53. else
  54. surface.Dispose();
  55. }
  56. }
  57. }