Beispiel #1
0
    private static async Task LeaveCurrentNodeAsync(IBlockIterationState blockState, INavigationContext context)
    {
        if (blockState.CurrentNode is null)
        {
            return;
        }

        await blockState.CurrentNode.LeaveAsync(context);
    }
Beispiel #2
0
    private static INode?GetNextNode(IBlock block, IBlockIterationState blockState)
    {
        var nextIndex = blockState.CurrentNodeIndex.HasValue ? blockState.CurrentNodeIndex.Value + 1 : 0;

        if (nextIndex >= block.Nodes.Count)
        {
            blockState.CurrentNodeIndex = null;
            blockState.CurrentNode      = null;
            return(null);
        }

        var node = block.Nodes[nextIndex];

        blockState.CurrentNodeIndex = nextIndex;
        blockState.CurrentNode      = node;
        return(node);
    }
Beispiel #3
0
    private static INode?GetNextValidNode(IBlock block, INavigationContext context, IBlockIterationState blockState)
    {
        for (; ;)
        {
            var item = GetNextNode(block, blockState);
            if (item == null)
            {
                return(null);
            }

            if (item.When == null || item.When.Evaluate(context.Variables))
            {
                if (item.ChildBlock is null || item.ChildBlock.While is null || item.ChildBlock.While.Evaluate(context.Variables))
                {
                    return(item);
                }
            }

            blockState.BackwardStack.Push(BlockedNode.Instance);
        }
    }
Beispiel #4
0
    private static async Task <INode?> MoveNextAsync(IBlock block, INavigationContext context, IBlockIterationState blockState)
    {
        await LeaveCurrentNodeAsync(blockState, context);

        var item = GetNextValidNode(block, context, blockState);

        if (item is null)
        {
            return(null);
        }

        var reverseState = await item.EnterAsync(context);

        blockState.BackwardStack.Push(reverseState);

        return(item);
    }
Beispiel #5
0
    private static async Task <INode?> MovePreviousAsync(IBlock block, INavigationContext context, IBlockIterationState blockState)
    {
        await LeaveCurrentNodeAsync(blockState, context);

        var index = blockState.CurrentNodeIndex ?? (block.Nodes.Count - 1);

        for (; ;)
        {
            if (!blockState.BackwardStack.TryPop(out var state))
            {
                blockState.CurrentNodeIndex = null;
                blockState.CurrentNode      = null;
                return(null);
            }

            if (state is not BlockedNode)
            {
                var node = block.Nodes[index];

                blockState.CurrentNodeIndex = blockState.CurrentNodeIndex = index > 0 ? index - 1: null;
                blockState.CurrentNode      = node;

                await node.EnterAsync(context, state);

                return(node);
            }

            index--;
        }
    }