ICopyable.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. using System;
  3. namespace Animancer
  4. {
  5. /// <summary>An object that can be copied.</summary>
  6. /// https://kybernetik.com.au/animancer/api/Animancer/ICopyable_1
  7. public interface ICopyable<in T>
  8. {
  9. /************************************************************************************************************************/
  10. /// <summary>Copies the contents of `copyFrom` into this object, replacing its previous contents.</summary>
  11. void CopyFrom(T copyFrom, CloneContext context);
  12. /************************************************************************************************************************/
  13. }
  14. /// <summary>Extension methods for <see cref="ICopyable{T}"/>.</summary>
  15. /// https://kybernetik.com.au/animancer/api/Animancer/CopyableExtensions
  16. public static partial class CopyableExtensions
  17. {
  18. /************************************************************************************************************************/
  19. /// <summary>
  20. /// Calls <see cref="ICopyable{T}.CopyFrom"/>
  21. /// using a <see cref="CloneContext"/> from the <see cref="CloneContext.Pool"/>.
  22. /// </summary>
  23. public static void CopyFrom<T>(this T copyTo, T copyFrom)
  24. where T : ICopyable<T>
  25. {
  26. var context = CloneContext.Pool.Instance.Acquire();
  27. copyTo.CopyFrom(copyFrom, context);
  28. CloneContext.Pool.Instance.Release(context);
  29. }
  30. /************************************************************************************************************************/
  31. /// <summary>
  32. /// Creates a new <typeparamref name="T"/> and calls <see cref="ICopyable{T}.CopyFrom"/>.
  33. /// </summary>
  34. public static T CopyableClone<T>(this T original, CloneContext context)
  35. where T : ICopyable<T>
  36. {
  37. if (original == null)
  38. return default;
  39. var clone = (T)Activator.CreateInstance(original.GetType());
  40. clone.CopyFrom(original, context);
  41. return clone;
  42. }
  43. /// <summary>
  44. /// Creates a new <typeparamref name="T"/> and calls <see cref="ICopyable{T}.CopyFrom"/>
  45. /// using a <see cref="CloneContext"/> from the <see cref="CloneContext.Pool"/>.
  46. /// </summary>
  47. public static T CopyableClone<T>(this T original)
  48. where T : ICopyable<T>
  49. {
  50. var context = CloneContext.Pool.Instance.Acquire();
  51. var clone = original.CopyableClone(context);
  52. CloneContext.Pool.Instance.Release(context);
  53. return clone;
  54. }
  55. /************************************************************************************************************************/
  56. /// <summary>Calls <see cref="ICopyable{T}.CopyFrom"/> using the appropriate type.</summary>
  57. public static void CopyFromBase<TChild, TBase>(this TChild copyTo, TBase copyFrom, CloneContext context)
  58. where TChild : ICopyable<TChild>, ICopyable<TBase>
  59. where TBase : ICopyable<TBase>
  60. {
  61. if (copyFrom is TChild copyFromChild)
  62. copyTo.CopyFrom(copyFromChild, context);
  63. else
  64. copyTo.CopyFrom(copyFrom, context);
  65. }
  66. /************************************************************************************************************************/
  67. }
  68. }