Beispiel #1
0
        /// <summary>
        /// Invoke the scorable calling protocol against a single scorable.
        /// </summary>
        public static async Task <bool> TryPostAsync <Item, Score>(this IScorable <Item, Score> scorable, Item item, CancellationToken token)
        {
            var state = await scorable.PrepareAsync(item, token);

            if (scorable.HasScore(item, state))
            {
                var score = scorable.GetScore(item, state);
                await scorable.PostAsync(item, state, token);

                return(true);
            }

            return(false);
        }
Beispiel #2
0
        public override async Task PostAsync <T>(T item, CancellationToken cancellationToken = default(CancellationToken))
        {
            Score             maximumScore    = default(Score);
            object            maximumState    = null;
            IScorable <Score> maximumScorable = null;

            Func <IScorable <Score>, Delegate, Task <bool> > UpdateAsync = async(scorable, frame) =>
            {
                var state = await scorable.PrepareAsync(item, frame);

                Score score;
                if (scorable.TryScore(state, out score))
                {
                    if (this.comparer.Compare(score, this.traits.Minimum) < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(score));
                    }

                    if (this.comparer.Compare(score, this.traits.Maximum) > 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(score));
                    }

                    var compare = this.comparer.Compare(score, maximumScore);
                    if (maximumScorable == null || compare > 0)
                    {
                        maximumScore    = score;
                        maximumState    = state;
                        maximumScorable = scorable;

                        if (this.comparer.Compare(score, this.traits.Maximum) == 0)
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            };

            bool more = true;

            foreach (var frame in this.Frames)
            {
                var scorable = frame.Target as IScorable <Score>;
                if (scorable != null)
                {
                    more = await UpdateAsync(scorable, frame);

                    if (!more)
                    {
                        break;
                    }
                }
            }

            if (more)
            {
                foreach (var scorable in this.scorables)
                {
                    more = await UpdateAsync(scorable, null);

                    if (!more)
                    {
                        break;
                    }
                }
            }

            if (maximumScorable != null)
            {
                await maximumScorable.PostAsync <T>(this.inner, item, maximumState);

                await base.PollAsync();
            }
            else
            {
                await base.PostAsync <T>(item, cancellationToken);
            }
        }