Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Is there a more elegant way to code saving and restoring of values?

Discussion in 'Scripting' started by Rowlan, Sep 24, 2023.

  1. Rowlan

    Rowlan

    Joined:
    Aug 4, 2016
    Posts:
    3,810
    I have eg this which conditionally disables a button:

    Code (CSharp):
    1.  
    2.    bool prevGuiEnabled = GUI.enabled;
    3.    GUI.enabled = CanPerformAction();
    4.    {
    5.        if (GUILayout.Button("Action"))
    6.        {
    7.            PerformAction();
    8.        }
    9.    }
    10.    GUI.enabled = prevGuiEnabled;
    11.  
    Which can of course stack and escalate with nested functionality. And clutter the code. Is there a more elegant way for something like this? It's same with eg RenderTexture.active.

    Basically store previous value, do something, restore original value.
     
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,104
    You can use structs that implement IDisposable. They can first save the previous state and then apply the temporary state change in their constructor, and then restore the previous state when their Dispose method is called.

    This can then be combined with the using statement to create code that is quite readable, and safer as well, since it restores the value even in the case of an exception.

    Example:
    Code (CSharp):
    1. public static GUIScope
    2. {
    3.     public static bool Enabled(bool enabled) => new GUIEnabledScope(enabled);
    4. }
    5.  
    6. public readonly struct GUIEnabledScope : IDisposable
    7. {
    8.     private readonly bool wasEnabled;
    9.  
    10.     public GUIEnabledScope(bool enabled)
    11.     {
    12.         wasEnabled = GUI.enabled;
    13.         GUI.enabled = enabled;
    14.     }
    15.  
    16.     public void Dispose() => GUI.enabled = wasEnabled;
    17. }
    Code (CSharp):
    1. using(GUIScope.Enabled(CanPerformAction()))
    2. {
    3.     if(GUILayout.Button("Action"))
    4.     {
    5.         PerformAction();
    6.     }
    7. }
    Unity actually already defines a couple of these structures in the EditorGUI class:
     
    CodeSmile, samana1407 and Rowlan like this.
  3. Rowlan

    Rowlan

    Joined:
    Aug 4, 2016
    Posts:
    3,810
    That's awesome! Thank you very much! :)
     
    SisusCo likes this.