예제 #1
0
        ///<summary>Combines two souls by using a custom function to combine their phases.</summary>
        public static ISoul Combine(this ISoul soul1, ISoul soul2, Func <Phase, Phase, Phase> phaseCombiner)
        {
            Func <Phase> getPhase = () => phaseCombiner(soul1.Phase, soul2.Phase);

            return(new AnonymousSoul(
                       getPhase,
                       action => {
                Func <bool> tryComplete = () => {
                    var hasPhase = getPhase() != Phase.Mortal;
                    if (hasPhase)
                    {
                        action();
                    }
                    return hasPhase;
                };
                return soul1.InterdependentRegister(tryComplete, soul2, tryComplete);
            }));
        }
예제 #2
0
        ///<summary>Registers a callback to the dependent soul that only occurs if the necessary soul doesn't die first, ensuring everything is cleaned up properly.</summary>
        public static RegistrationRemover DependentRegister(this ISoul soul, Action action, ISoul necessarySoul)
        {
            if (soul == null)
            {
                throw new ArgumentNullException("soul");
            }
            if (action == null)
            {
                throw new ArgumentNullException("action");
            }
            if (necessarySoul == null)
            {
                throw new ArgumentNullException("necessarySoul");
            }

            // when the necessary soul is the same soul as the dependent soul, assume the callback invocation will beat the registration removal
            if (ReferenceEquals(soul, necessarySoul))
            {
                necessarySoul = ImmortalSoul.Instance;
            }

            // avoid wrapping when possible
            if (necessarySoul.Phase == Phase.Dead)
            {
                return(EmptyRemover);
            }
            if (soul.Phase != Phase.Mortal)
            {
                action();
                return(EmptyRemover);
            }
            if (necessarySoul.Phase == Phase.Immortal)
            {
                return(soul.Register(action));
            }

            return(soul.InterdependentRegister(
                       () => {
                action();
                return true;
            },
                       necessarySoul,
                       () => necessarySoul.Phase == Phase.Dead));
        }