public static void SetBool <T>(this Component c, bool value,
                                       MissingComponentOptions opts = MissingComponentOptions.AddAndWarn) where T : Component, IHasBool
        {
            var hasBool = c.GetComponent <T>();

            if (hasBool != null)
            {
                hasBool.value = value;
                return;
            }

            switch (opts)
            {
            case MissingComponentOptions.Add:
                hasBool       = c.gameObject.AddComponent <T>();
                hasBool.value = value;
                break;

            case MissingComponentOptions.AddAndWarn:
                Debug.LogWarning("Adding missing component of type " + typeof(T).Name + " to " + c.Path());
                hasBool       = c.gameObject.AddComponent <T>();
                hasBool.value = value;
                break;

            case MissingComponentOptions.CancelAndWarn:
                Debug.LogWarning("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
                break;

            case MissingComponentOptions.ThrowException:
                throw new MissingComponentException("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
            }
        }
        public static bool GetBool <T>(this Component c, MissingComponentOptions opts = MissingComponentOptions.AddAndWarn, bool dftVal = false) where T : Component, IHasBool
        {
            var hasBool = c.GetComponent <T>();

            if (hasBool != null)
            {
                return(hasBool.value);
            }

            switch (opts)
            {
            case MissingComponentOptions.Add:
                hasBool = c.gameObject.AddComponent <T>();
                return(hasBool.value);

            case MissingComponentOptions.AddAndWarn:
                Debug.LogWarning("Adding missing component of type " + typeof(T).Name + " to " + c.Path());
                hasBool = c.gameObject.AddComponent <T>();
                return(hasBool.value);

            case MissingComponentOptions.CancelAndWarn:
                Debug.LogWarning("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
                return(dftVal);

            default:             // MissingComponentOptions.ThrowException:
                throw new MissingComponentException("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
            }
        }
        /// <summary>
        /// ext method lets you call a sibling <c>Invocable</c> like this:
        ///
        /// <c>
        /// this.Invoke<MyInvocableComp>();
        /// </c>
        /// </summary>
        public static void Invoke <T>(this Component c,
                                      MissingComponentOptions opts = MissingComponentOptions.AddAndWarn) where T : Component, Invocable
        {
            if (c == null)
            {
                Debug.LogWarning("Invoke " + typeof(T) + " called on null component");
                return;
            }

            var invocable = c.GetComponent <T>();

            if (invocable != null)
            {
                invocable.Invoke();
                return;
            }

            switch (opts)
            {
            case MissingComponentOptions.Add:
                invocable = c.gameObject.AddComponent <T>();
                invocable.Invoke();
                break;

            case MissingComponentOptions.AddAndWarn:
                Debug.LogWarning("Adding missing component of type " + typeof(T).Name + " to " + c.Path());
                invocable = c.gameObject.AddComponent <T>();
                invocable.Invoke();
                break;

            case MissingComponentOptions.CancelAndWarn:
                Debug.LogWarning("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
                break;

            case MissingComponentOptions.ThrowException:
                throw new MissingComponentException("Failed to set property on " + c.Path() + " due to missing component of type " + typeof(T).Name);
            }
        }
 public static bool GetBool <T>(this GameObject go,
                                MissingComponentOptions opts = MissingComponentOptions.AddAndWarn, bool dftVal = false) where T : Component, IHasBool
 {
     return(go.transform.GetBool <T>(opts, dftVal));
 }
 public static void SetBool <T>(this GameObject go, bool value,
                                MissingComponentOptions opts = MissingComponentOptions.AddAndWarn) where T : Component, IHasBool
 {
     go.transform.SetBool <T>(value, opts);
 }
 public static int GetInt <T>(this GameObject go, MissingComponentOptions opts = MissingComponentOptions.AddAndWarn, int dftVal = 0) where T : Component, IHasInt
 {
     return(go.transform.GetInt <T>(opts, dftVal));
 }
 public static void SetFloat <T>(this GameObject go, float value,
                                 MissingComponentOptions opts = MissingComponentOptions.AddAndWarn) where T : Component, IHasFloat
 {
     go.transform.SetFloat <T>(value, opts);
 }