using System; using System.Diagnostics; using System.Runtime.InteropServices; using Unity.Collections.LowLevel.Unsafe; namespace Unity.Burst { /// /// Base interface for a function pointer. /// public interface IFunctionPointer { /// /// Converts a pointer to a function pointer. /// /// The native pointer. /// An instance of this interface. [Obsolete("This method will be removed in a future version of Burst")] IFunctionPointer FromIntPtr(IntPtr ptr); } /// /// A function pointer that can be used from a Burst Job or from regular C#. /// It needs to be compiled through /// /// Type of the delegate of this function pointer public readonly struct FunctionPointer : IFunctionPointer { // DOTSPLAYER's shim package relies on Burst for it's jobs code // so Burst does not see the DOTSPLAYER definition of this attribute #if !UNITY_DOTSPLAYER [NativeDisableUnsafePtrRestriction] #endif private readonly IntPtr _ptr; /// /// Creates a new instance of this function pointer with the following native pointer. /// /// public FunctionPointer(IntPtr ptr) { _ptr = ptr; } /// /// Gets the underlying pointer. /// public IntPtr Value => _ptr; [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] private void CheckIsCreated() { if (!IsCreated) { throw new NullReferenceException("Object reference not set to an instance of an object"); } } /// /// Gets the delegate associated to this function pointer in order to call the function pointer. /// This delegate can be called from a Burst Job or from regular C#. /// If calling from regular C#, it is recommended to cache the returned delegate of this property /// instead of using this property every time you need to call the delegate. /// public T Invoke { get { CheckIsCreated(); return Marshal.GetDelegateForFunctionPointer(_ptr); } } /// /// Whether the function pointer is valid. /// public bool IsCreated => _ptr != IntPtr.Zero; /// /// Converts a pointer to a function pointer. /// /// The native pointer. /// An instance of this interface. IFunctionPointer IFunctionPointer.FromIntPtr(IntPtr ptr) => new FunctionPointer(ptr); } }