private static bool Break(VM vm, RantPattern source, Stringe tagname, Argument[] args) { if (vm.CurrentRepeater == null) { return(false); } vm.CurrentRepeater.Finish(); VM.State state = null; while (!vm.BaseStates.Contains(state = vm.CurrentState)) { vm.PopState(); } vm.BaseStates.Remove(state); return(true); }
public bool Iterate(VM ii, RepeaterBlueprint bp) { while (ii.CurrentRepeater != null && ii.CurrentRepeater.Finished) { ii.PopRepeater(); } if (Finished) { return(false); } // Queue the next iteration on the current state ii.CurrentState.Pre(bp); // Push separator if applicable if (!IsLast && _attribs.Separator != null && _attribs.Separator.Any()) { var sepState = VM.State.CreateSub( ii.CurrentState.Reader.Source, _attribs.Separator, ii, ii.CurrentState.Output); // Make sure that the repeater is not available to the separator pattern sepState.Pre(new DelegateBlueprint(ii, _ => { _allowStats = false; return(false); })); sepState.Post(new DelegateBlueprint(ii, _ => { _allowStats = true; return(false); })); ii.PushState(sepState); } VM.State afterState = null; // Push postfix if applicable if (_attribs.After != null && _attribs.After.Any()) { ii.PushState(afterState = VM.State.CreateSub( ii.CurrentState.Reader.Source, _attribs.After, ii, ii.CurrentState.Output)); } // Push next item var itemState = VM.State.CreateSub(ii.CurrentState.Reader.Source, _attribs.Sync != null ? _block.Items[_attribs.Sync.NextItem(_block.Items.Length)].Item2 : _block.Items.PickWeighted(ii.RNG, _block.WeightTotal, item => item.Item1).Item2, ii, ii.CurrentState.Output); // Apply the Next() call to the last state in the repeater iteration (afterState ?? itemState).Post(new DelegateBlueprint(ii, _ => { Next(); return(false); })); ii.PushState(itemState); // Push prefix if applicable if (_attribs.Before != null && _attribs.Before.Any()) { ii.PushState(VM.State.CreateSub( ii.CurrentState.Reader.Source, _attribs.Before, ii, ii.CurrentState.Output)); } return(true); }