Search Unity

Question UnityEngine.Object 'destroyCancellationToken'?

Discussion in 'Scripting Dev Blitz Day 2023 - Q&A' started by NotaNaN, Feb 22, 2023.

  1. NotaNaN

    NotaNaN

    Joined:
    Dec 14, 2018
    Posts:
    325
    In 2022.2, the Scripting Team added the fancy MonoBehaviour.destroyCancellationToken.
    Good stuff.
    Unfortunately, this new API was MonoBehaviour-only.
    Sadness.

    Anyway, seeing that this API could potentially be made agnostic to all UnityEngine.Object-derived types, what is the likelihood of that happening? The applications for this type of callback are many. Disposing of our own "unmanaged" data in direct cadence with whenever Unity terminates a uObject would solve more than a few major annoyances for me and my own systems.

    This idea was partially discussed about in the wonderful The Future of Unity and .NET Mega Thread, particularly by the user @TheZombieKiller. I wanted to revive this topic because I wanted to hear the Scripting Team's thoughts about such an addition. @TheZombieKiller theorized that this feature may be low-to-zero cost in regards to the coming changes to .NET — and with this in mind, would it be possible for the Scripting Team to pursue this avenue?
     
    CaseyHofland likes this.
  2. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    68
    Having this property is not totally free unfortunately, so we decided to only have it on MonoBehaviour.
    Something that can be done is to add an empty MonoBehaviour on the GameObject you're interested, and get its cancellation token.
     
  3. NotaNaN

    NotaNaN

    Joined:
    Dec 14, 2018
    Posts:
    325
    Understood. I know you provided a more comprehensive answer here, but in regards to the changes made in .Net 7 does the team have a different stance when it comes to supporting it as an optional feature (if it is indeed possible to do so)?

    This trick only works for GameObjects, sadly. For other cases, such as the one outlined by @TheZombieKiller, a cancellation token would be useful. Is there any way that the feature could be opt-in? Or is this scenario (and scenarios like it) too niche to support directly? Are there any implementations that sacrifice the performance of the feature itself without sacrificing the performance of the majority of cases that do not make use it? Or is that too akin to "having my cake and eating it too"? :p
     
  4. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Yeah, RyuJIT is able to transform static readonly fields of primitive types into "runtime constants". This makes them 'free' from JIT tiers 1 and above, and the BCL itself takes advantage of this to offer feature flags through the AppContext class.

    I'm skeptical that branching to determine whether or not the callback should be invoked is expensive compared to the overhead of the managed <-> native transition (especially under Mono...), but using a static readonly in .NET Core allows you to avoid the overhead (in managed code) regardless. It'd essentially look something like:
    Code (CSharp):
    1. if (s_EnableDestroyCallback)
    2.     DestroyWithCallbackInternal(this);
    3. else
    4.     DestroyInternal(this);
    Where
    DestroyWithCallbackInternal
    and
    DestroyInternal
    represent the engine's C++ APIs. Avoiding the branch when the engine itself destroys something (internally via C++, not Object.Destroy) would be a bit more complicated, but that comes back to my skepticism around its cost.

    Yeah, this is exactly why I find it disappointing -- almost all of my use cases for a destroy callback don't involve GameObjects, they involve textures, fonts, audio clips, etc. You've always been able to get a callback for GameObjects by piggybacking on a component.

    It's possible to brute-force an implementation of a callback by detouring the engine's Destroy method in C++, but that only works on certain platforms and takes a non-trivial amount of effort. Implementing it "the right way" would require a source license, which seems like a bit much just to implement a callback...
     
    NotaNaN likes this.