Esempio n. 1
0
        private static async Task <Transition?> ResolveTransitionAsync(this State state, StateMachineContext context, JToken data)
        {
            Debug.Assert(state != null);
            Debug.Assert(context != null);
            Debug.Assert(data != null);

            if (state.Transitions.Count == 0)
            {
                return(null);
            }

            Transition?transition = state.ResolveImplicitTransition();

            if (transition == null)
            {
                transition = state.ResolveConditionalTransition(context, data);
            }

            if (transition == null)
            {
                transition = await state.ResolveEventTransitionAsync(context, data);
            }

            Debug.Assert(transition != null);

            return(transition);
        }
        public void Previous_LastYear()
        {
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.Previous(new Instant(NodaConstants.UnixEpoch.Ticks + (1 * TicksPerStandardYear)), Offset.Zero, Offset.Zero);
            Transition?expected = new Transition(NodaConstants.UnixEpoch, Offset.Zero, Offset.Zero);

            Assert.AreEqual(expected, actual);
        }
        public void PreviousOrSame_LastYear()
        {
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.PreviousOrSame(Instant.FromUtc(1971, 1, 1, 0, 0) - Duration.Epsilon, Offset.Zero, Offset.Zero);
            Transition?expected = new Transition(NodaConstants.UnixEpoch, Offset.Zero);

            Assert.AreEqual(expected, actual);
        }
        public void PreviousOrSame_AfterLastYear()
        {
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.PreviousOrSame(Instant.MaxValue, Offset.Zero, Offset.Zero);
            Transition?expected = new Transition(Instant.FromUtc(1972, 1, 1, 0, 0), Offset.Zero);

            Assert.AreEqual(expected, actual);
        }
Esempio n. 5
0
 internal Transition(TransitionRegexKind kind, int leaf = 0, S?test = default(S), SymbolicRegexNode <S>?look = null, Transition?first = null, Transition?second = null)
 {
     _kind   = kind;
     _leaf   = leaf;
     _test   = test;
     _look   = look;
     _first  = first;
     _second = second;
 }
        public void Previous_BeforeFirstYear_null()
        {
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.Previous(NodaConstants.UnixEpoch - Duration.Epsilon, Offset.Zero, Offset.Zero);
            Transition?expected = null;

            Assert.AreEqual(expected, actual);
        }
        public void Next_BeforeFirstYear()
        {
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.Next(Instant.MinValue, Offset.Zero, Offset.Zero);
            Transition?expected = new Transition(NodaConstants.UnixEpoch, Offset.Zero, Offset.Zero);

            Assert.AreEqual(expected, actual);
        }
        public void PreviousOrSame_OnFirstYear_null()
        {
            // Transition is on January 2nd, but we're asking for January 1st.
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 2, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.PreviousOrSame(NodaConstants.UnixEpoch, Offset.Zero, Offset.Zero);
            Transition?expected = null;

            Assert.AreEqual(expected, actual);
        }
Esempio n. 9
0
 public StyleValueDeclaration(IDependencyProperty property,
                              StyleSetterType setterType,
                              T value,
                              Transition?transition)
 {
     _value     = value;
     Property   = property;
     SetterType = setterType;
     Transition = transition;
 }
        public void Next_BeyondLastYear_null()
        {
            var        afterRecurrenceEnd   = Instant.FromUtc(1980, 1, 1, 0, 0);
            var        januaryFirstMidnight = new ZoneYearOffset(TransitionMode.Utc, 1, 1, 0, true, LocalTime.Midnight);
            var        recurrence           = new ZoneRecurrence("bob", Offset.Zero, januaryFirstMidnight, 1970, 1972);
            Transition?actual   = recurrence.Next(afterRecurrenceEnd, Offset.Zero, Offset.Zero);
            Transition?expected = null;

            Assert.AreEqual(expected, actual);
        }
Esempio n. 11
0
        /// <summary>
        /// Piggy-backs onto PreviousOrSame, but fails with a descriptive InvalidOperationException if there's no such transition.
        /// </summary>
        internal Transition PreviousOrSameOrFail(Instant instant, Offset standardOffset, Offset previousSavings)
        {
            Transition?previous = PreviousOrSame(instant, standardOffset, previousSavings);

            if (previous is null)
            {
                throw new InvalidOperationException(
                          $"Noda Time bug or bad data: Expected a transition earlier than {instant}; standard offset = {standardOffset}; previousSavings = {previousSavings}; recurrence = {this}");
            }
            return(previous.Value);
        }
Esempio n. 12
0
        /// <summary>
        /// Piggy-backs onto Next, but fails with an InvalidOperationException if there's no such transition.
        /// </summary>
        internal Transition NextOrFail(Instant instant, Offset standardOffset, Offset previousSavings)
        {
            Transition?next = Next(instant, standardOffset, previousSavings);

            if (next is null)
            {
                throw new InvalidOperationException(
                          $"Noda Time bug or bad data: Expected a transition later than {instant}; standard offset = {standardOffset}; previousSavings = {previousSavings}; recurrence = {this}");
            }
            return(next.Value);
        }
Esempio n. 13
0
        /// <summary>
        /// Piggy-backs onto Previous, but fails with a descriptive InvalidOperationException if there's no such transition.
        /// </summary>
        internal Transition PreviousOrFail(Instant instant, Offset standardOffset, Offset previousSavings)
        {
            Transition?previous = Previous(instant, standardOffset, previousSavings);

            if (previous == null)
            {
                throw new InvalidOperationException(
                          string.Format("Noda Time bug or bad data: Expected a transition earlier than {0}; standard offset = {1}; previousSavings = {2}; recurrence = {3}",
                                        instant, standardOffset, previousSavings, this));
            }
            return(previous.Value);
        }
Esempio n. 14
0
            private ZoneTransition GetNext(Instant nextInstant)
            {
                // Find next matching rule.
                ZoneRecurrence nextRule  = null;
                Instant        nextTicks = Instant.MaxValue;

                for (int i = 0; i < rules.Count; i++)
                {
                    ZoneRecurrence rule           = rules[i];
                    Transition?    nextTransition = rule.Next(nextInstant, ruleSet.StandardOffset, savings);
                    Instant?       next           = nextTransition == null ? (Instant?)null : nextTransition.Value.Instant;
                    if (!next.HasValue || next.Value <= nextInstant)
                    {
                        rules.RemoveAt(i);
                        i--;
                        continue;
                    }
                    // Even if next is same as previous next, choose the rule in order for more
                    // recently added rules to override.
                    if (next.Value <= nextTicks)
                    {
                        // Found a better match.
                        nextRule  = rule;
                        nextTicks = next.Value;
                    }
                }

                if (nextRule == null)
                {
                    return(null);
                }

                // Stop precalculating if year reaches some arbitrary limit. We can cheat in the
                // conversion because it is an approximation anyway.
                if (calendar.GetYear(nextTicks.Plus(Offset.Zero)) >= YearLimit)
                {
                    return(null);
                }

                // Check if upper limit reached or passed.
                if (ruleSet.upperYear < Int32.MaxValue)
                {
                    Instant upperTicks = ruleSet.upperYearOffset.MakeInstant(ruleSet.upperYear, ruleSet.StandardOffset, savings);
                    if (nextTicks >= upperTicks)
                    {
                        // At or after upper limit.
                        return(null);
                    }
                }
                return(new ZoneTransition(nextTicks, nextRule.Name, ruleSet.StandardOffset, nextRule.Savings));
            }
Esempio n. 15
0
        public bool MoveNext(TInput input)
        {
            if (!_currentState.HasValue)
            {
                throw new InvalidOperationException("State machine has no current state!");
            }

            var currentState = _currentState.Value.StateValue;

            if (!IsFinished)
            {
                Transition?availableTransition     = null;
                Transition?conditionlessTransition = null;

                foreach (var trans in _transitions[currentState])
                {
                    if (!conditionlessTransition.HasValue && trans.Condition == null)
                    {
                        conditionlessTransition = trans;
                    }
                    else if (trans.CheckCondition(input))
                    {
                        availableTransition = trans;
                        break;
                    }
                }

                var transition = availableTransition ?? conditionlessTransition;

                if (transition is Transition selectedTran)
                {
                    var newStateValue = selectedTran.ToState;
                    var newState      = _states[newStateValue];

                    _currentState.Value.OnLeave?.Invoke(currentState, input);
                    newState.OnEnter?.Invoke(newStateValue, input);
                    _currentState = newState;

                    if (_transitions[newStateValue].Count == 0)
                    {
                        IsFinished = true;
                    }

                    return(true);
                }
            }

            _currentState?.OnTransitionError?.Invoke(currentState, input);

            return(false);
        }
        ///// <summary>
        ///// Set state on a single light
        ///// </summary>
        ///// <param name="light"></param>
        ///// <param name="xy"></param>
        ///// <param name="gamut"></param>
        ///// <param name="brightness"></param>
        ///// <param name="timeSpan"></param>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //public static void SetState(this EntertainmentLight light, CancellationToken cancellationToken, CIE1931Point xy, CIE1931Gamut gamut, double? brightness = null, TimeSpan timeSpan = default)
        //{
        //  var rgb = HueColorConverter.XYToRgb(xy, gamut);

        //  //Create a new transition for this light
        //  Transition transition = new Transition(rgb, brightness, timeSpan);

        //  light.Transition = transition;

        //  //Start the transition
        //  transition.Start(light.State.RGBColor, light.State.Brightness, cancellationToken);
        //}

        //Source: https://github.com/Q42/Q42.HueApi/pull/174
        public static void SetState(this EntertainmentLight light, CancellationToken cancellationToken, RGBColor?rgb = null, TimeSpan rgbTimeSpan = default, double?brightness = null, TimeSpan briTimeSpan = default, bool overwriteExistingTransition = true)
        {
            if (light == null)
            {
                throw new ArgumentNullException(nameof(light));
            }

            // No change in state required.
            if (!rgb.HasValue && !brightness.HasValue)
            {
                return;
            }

            var  currentTransition     = light.Transition;
            bool hasExistingTransition = currentTransition != null && !currentTransition.IsFinished;
            bool canCombineTransitions = hasExistingTransition &&
                                         (!rgb.HasValue || !brightness.HasValue) &&
                                         (!rgb.HasValue || !currentTransition !.IsBrightnessFinished) &&
                                         (!brightness.HasValue || !currentTransition !.IsRgbFinished);

            Transition?transition = null;

            // If we can't combine the existing transition (if there is one) with the new transition, start a fresh transition.
            if (!canCombineTransitions || overwriteExistingTransition)
            {
                if (rgb.HasValue && brightness.HasValue)
                {
                    transition = new Transition(rgb.Value, brightness.Value, rgbTimeSpan, briTimeSpan);
                }
                else if (rgb.HasValue)
                {
                    transition = new Transition(rgb.Value, rgbTimeSpan);
                }
                else if (brightness.HasValue)
                {
                    transition = new Transition(brightness.Value, briTimeSpan);
                }
            }
            else
            {
                // A transition is currently in progress, which we need to combine with the colour or brightness that was specified.
                if (rgb.HasValue && currentTransition !.TargetBri.HasValue)
                {
                    // Combine new colour transition with existing brightness transition.
                    transition = new Transition(rgb.Value, currentTransition !.TargetBri.Value, rgbTimeSpan, currentTransition.BrightnessRemainingTime);
                }
Esempio n. 17
0
        /// <summary>
        /// Changes the state based on one or more transition
        /// </summary>
        internal void ProcessTransitions()
        {
            lock (transitionLock)
            {
                if (Transition == null)
                {
                    return;
                }

                this.State.SetBrightness(Transition.TransitionState.Brightness);
                this.State.SetRGBColor(Transition.TransitionState.RGBColor);

                if (Transition.IsFinished)
                {
                    Transition = null;
                }
            }
        }
Esempio n. 18
0
 public virtual void ChangeAppearance(string appearance, float duration = 0,
                                      EasingType easingType             = default, Transition?transition = default)
 {
     if (!string.IsNullOrEmpty(appearance))
     {
         onAppearanceChanged?.Invoke(appearance);
     }
 }
Esempio n. 19
0
 internal NullableTransitionWrapper(Transition?transition)
 {
     this.transition = transition;
 }
Esempio n. 20
0
            /// <summary>
            /// Recursively builds a complete list of generalized sequences accepted by the simplifiable part of the automaton.
            /// </summary>
            /// <param name="stateIndex">The currently traversed state.</param>
            /// <param name="generalizedTreeNodes">The state labels obtained from <see cref="FindGeneralizedTrees"/>.</param>
            /// <param name="weightedSequences">The sequence list being built.</param>
            /// <param name="currentSequenceElements">The list of elements of the sequence currently being built.</param>
            /// <param name="currentWeight">The weight of the sequence currently being built.</param>
            private void DoBuildAcceptedSequenceList(
                int stateIndex,
                bool[] generalizedTreeNodes,
                List <WeightedSequence> weightedSequences,
                List <GeneralizedElement> currentSequenceElements,
                Weight currentWeight)
            {
                var stack = new Stack <StackItem>();

                stack.Push(new StateWeight(stateIndex, currentWeight));

                while (stack.Count > 0)
                {
                    var stackItem = stack.Pop();

                    if (stackItem is ElementItem elementItem)
                    {
                        if (elementItem.Element != null)
                        {
                            currentSequenceElements.Add(elementItem.Element.Value);
                        }
                        else
                        {
                            currentSequenceElements.RemoveAt(currentSequenceElements.Count - 1);
                        }
                        continue;
                    }

                    var stateAndWeight = stackItem as StateWeight;

                    stateIndex = stateAndWeight.StateIndex;
                    var state = this.builder[stateIndex];
                    currentWeight = stateAndWeight.Weight;

                    // Find a non-epsilon self-loop if there is one
                    Transition?selfLoop = null;
                    for (var iterator = state.TransitionIterator; iterator.Ok; iterator.Next())
                    {
                        var transition = iterator.Value;
                        if (transition.DestinationStateIndex == stateIndex)
                        {
                            Debug.Assert(
                                selfLoop == null,
                                "Multiple self-loops should have been merged by MergeParallelTransitions()");
                            selfLoop = transition;
                        }
                    }

                    // Push the found self-loop to the end of the current sequence
                    if (selfLoop != null)
                    {
                        currentSequenceElements.Add(new GeneralizedElement(
                                                        selfLoop.Value.ElementDistribution, selfLoop.Value.Group, selfLoop.Value.Weight));
                        stack.Push(new ElementItem(null));
                    }

                    // Can this state produce a sequence?
                    if (state.CanEnd && generalizedTreeNodes[stateIndex])
                    {
                        var sequence = new GeneralizedSequence(currentSequenceElements);
                        // TODO: use immutable data structure instead of copying sequences
                        weightedSequences.Add(new WeightedSequence(sequence, Weight.Product(currentWeight, state.EndWeight)));
                    }

                    // Traverse the outgoing transitions
                    for (var iterator = state.TransitionIterator; iterator.Ok; iterator.Next())
                    {
                        var transition = iterator.Value;
                        // Skip self-loops & disallowed states
                        if (transition.DestinationStateIndex == stateIndex ||
                            !generalizedTreeNodes[transition.DestinationStateIndex])
                        {
                            continue;
                        }

                        if (!transition.IsEpsilon)
                        {
                            // Non-epsilon transitions contribute to the sequence
                            stack.Push(new ElementItem(null));
                        }

                        stack.Push(
                            new StateWeight(
                                transition.DestinationStateIndex,
                                Weight.Product(currentWeight, transition.Weight)));

                        if (!transition.IsEpsilon)
                        {
                            stack.Push(
                                new ElementItem(
                                    new GeneralizedElement(transition.ElementDistribution, transition.Group, null)));
                        }
                    }
                }
            }
Esempio n. 21
0
 public UniTask ChangeAppearanceAsync(string appearance, float duration, EasingType easingType = default,
                                      Transition?transition = default, CancellationToken cancellationToken = default) => UniTask.CompletedTask;