protected void InvokeRootSequence() { switch (SequenceInvokationList.Count) { case 0: Debug.Assert(FieldList.Count == 0, "FieldList.Count > 0 when no sequence invokations"); rootSequenceInvokation = SequenceInvokationList.New(rootSequence, 0); for (int i = 0; i < rootSequenceInvokation.FieldCount; i++) { FieldList.Add(rootSequenceInvokation.GetField(i)); } break; case 1: // if 1, then root is only invoked sequence ResetAllFieldValues(); break; default: FtSequenceInvokation secondInvokation = SequenceInvokationList[1]; fieldList.Trim(secondInvokation.StartFieldIndex); bool fieldsWereSidelined = secondInvokation.StartFieldIndex != RootFieldCount; SequenceInvokationList.PredictTrim(1); ResetAllFieldValues(); if (fieldsWereSidelined) { // Root sequence was redirected before its end. Some fields will be sidelined and field indexes may not be correct for (int i = rootSequenceInvokation.FieldsSidelinedFromIndex; i < rootSequenceInvokation.FieldCount; i++) { fieldList.Add(rootSequenceInvokation.GetField(i)); } rootSequenceInvokation.UnsidelineFields(); } break; } }
// remove all sequences after that which contains unRedirecting Field protected void Unredirect(FtField unredirectingField, out int fieldsAffectedFromIndex) { FtSequenceInvokation unredirectingInvokation = unredirectingField.SequenceInvokation; int unredirectingInvokationIndex = unredirectingInvokation.Index; if (unredirectingInvokationIndex >= SequenceInvokationList.Count - 1) { // unRedirectingInvokationIndex is last. Nothing to do. (should never happen) fieldsAffectedFromIndex = FtField.NoFieldsAffectedIndex; } else { int nextInvokationIndex = unredirectingInvokationIndex + 1; SequenceInvokationList.PredictTrim(nextInvokationIndex); fieldsAffectedFromIndex = unredirectingInvokation.StartFieldIndex + unredirectingInvokation.FieldsSidelinedFromIndex; fieldList.Trim(fieldsAffectedFromIndex); for (int i = unredirectingInvokation.FieldsSidelinedFromIndex; i < unredirectingInvokation.FieldCount; i++) { fieldList.Add(unredirectingInvokation.GetField(i)); } unredirectingInvokation.UnsidelineFields(); } }
protected void Redirect(FtField redirectingField, FtSequence invokedSequence, FtSequenceInvokationDelay invokationDelay, out int fieldsAffectedFromIndex) { FtSequenceInvokation redirectingInvokation = redirectingField.SequenceInvokation; int newInvokationIndex = redirectingInvokation.Index + 1; int newInvokationStartFieldIndex; switch (invokationDelay) { case FtSequenceInvokationDelay.ftikAfterField: newInvokationStartFieldIndex = redirectingField.Index + 1; break; case FtSequenceInvokationDelay.ftikAfterSequence: newInvokationStartFieldIndex = redirectingInvokation.StartFieldIndex + redirectingInvokation.FieldCount; break; default: throw FtInternalException.Create(InternalError.Core_InvokeSequences_UnsupportedInvokationDelay, invokationDelay.ToString()); } // check if redirect does not cause any change bool changeRequired; if (newInvokationIndex >= sequenceInvokationList.Count) { changeRequired = true; } else { FtSequenceInvokation nextExistingInvokation = sequenceInvokationList[newInvokationIndex]; changeRequired = (nextExistingInvokation.Sequence != invokedSequence || nextExistingInvokation.StartFieldIndex != newInvokationStartFieldIndex); } if (!changeRequired) { fieldsAffectedFromIndex = FtField.NoFieldsAffectedIndex; } else { FtField existingRedirectingField = redirectingInvokation.RedirectingField; int unredirectfieldsAffectedFromIndex; if (existingRedirectingField == null) { unredirectfieldsAffectedFromIndex = redirectingInvokation.StartFieldIndex + redirectingInvokation.FieldCount; } else { Unredirect(existingRedirectingField, out unredirectfieldsAffectedFromIndex); if (unredirectfieldsAffectedFromIndex < 0) { // if not affected, set to value which will be higher than new invokation affects fields index unredirectfieldsAffectedFromIndex = redirectingInvokation.StartFieldIndex + redirectingInvokation.FieldCount; } } FtSequenceInvokation newInvokation = SequenceInvokationList.TryPredictedNew(newInvokationIndex, invokedSequence, newInvokationStartFieldIndex); if (newInvokation == null) { SequenceInvokationList.Trim(newInvokationIndex); newInvokation = SequenceInvokationList.New(invokedSequence, newInvokationStartFieldIndex); } FieldList.Trim(newInvokationStartFieldIndex); for (int i = 0; i < newInvokation.FieldCount; i++) { FieldList.Add(newInvokation.GetField(i)); } if (newInvokationStartFieldIndex < redirectingInvokation.StartFieldIndex + redirectingInvokation.FieldCount) { redirectingInvokation.SidelineFields(newInvokationStartFieldIndex); } if (unredirectfieldsAffectedFromIndex < newInvokationStartFieldIndex) { fieldsAffectedFromIndex = unredirectfieldsAffectedFromIndex; } else { fieldsAffectedFromIndex = newInvokationStartFieldIndex; } if (!seeking) { OnSequenceRedirected(redirectingField, fieldsAffectedFromIndex); } } }