/// <summary> /// This method returns the default draw state for the specified aspect or -1 if none. /// </summary> public int GetDefaultDrawState(SignalAspectState state) { for (int i = 0; i < Aspects.Count; i++) { if (state == Aspects[i].Aspect) { return(DrawStates[Aspects[i].DrawStateName].Index); } } return(-1); }
/// <summary> /// This method returns the least restrictive aspect for this signal type. /// [Rob Roeterdink] added for basic signals without script /// </summary> public SignalAspectState GetLeastRestrictiveAspect() { SignalAspectState targetAspect = SignalAspectState.Stop; for (int i = 0; i < Aspects.Count; i++) { if (Aspects[i].Aspect > targetAspect) { targetAspect = Aspects[i].Aspect; } } return((targetAspect > SignalAspectState.Clear_2) ? SignalAspectState.Clear_2 : targetAspect); }
/// <summary> /// This method returns the most restrictive aspect for this signal type. /// </summary> public SignalAspectState GetMostRestrictiveAspect() { SignalAspectState targetAspect = SignalAspectState.Unknown; for (int i = 0; i < Aspects.Count; i++) { if (Aspects[i].Aspect < targetAspect) { targetAspect = Aspects[i].Aspect; } } return((targetAspect == SignalAspectState.Unknown) ? SignalAspectState.Stop : targetAspect); }
/// <summary> /// Constructor for dummy entries /// </summary> public SignalType(SignalFunction function, SignalAspectState aspect) : this() { FunctionType = function; Name = "UNDEFINED"; Semaphore = false; DrawStates = new Dictionary <string, SignalDrawState> { { "CLEAR", new SignalDrawState("CLEAR", 1) } }; Aspects = new List <SignalAspect> { new SignalAspect(aspect, "CLEAR") }; }
/// <summary> /// This method returns the next least restrictive aspect from the one specified. /// </summary> public SignalAspectState GetNextLeastRestrictiveState(SignalAspectState state) { SignalAspectState targetState = SignalAspectState.Unknown; SignalAspectState leastState = SignalAspectState.Stop; for (int i = 0; i < Aspects.Count; i++) { if (Aspects[i].Aspect > leastState) { leastState = Aspects[i].Aspect; } if (Aspects[i].Aspect > state && Aspects[i].Aspect < targetState) { targetState = Aspects[i].Aspect; } } return((targetState == SignalAspectState.Unknown) ? leastState : targetState); }
/// <summary> /// constructor for dummy entries /// </summary> /// <param name="reqAspect">Requested aspect</param> /// <param name="reqName">Requested drawstate name</param> public SignalAspect(SignalAspectState aspect, string name) { Aspect = aspect; DrawStateName = name; SpeedLimit = -1; }
/// <summary> /// This method returns the lowest speed limit linked to the aspect /// </summary> public float GetSpeedLimit(SignalAspectState aspect) { return(Aspects.First((a) => a.Aspect == aspect)?.SpeedLimit ?? -1); }
//================================================================================================// /// <summary> /// Returns the default draw state for this signal head from the SIGCFG file /// Retruns -1 id no draw state. /// </summary> public int DefaultDrawState(SignalAspectState state) { return(SignalType?.GetDefaultDrawState(state) ?? -1); }
//================================================================================================// /// <summary> /// Returns most restrictive state of signal type A, for all type A upto type B /// Uses Least Restrictive state per signal /// </summary> public SignalAspectState LRSignalMultiOnRoute(int signalType, int signalTypeOther) { SignalAspectState foundState = SignalAspectState.Clear_2; bool foundValid = false; // get signal of type 2 (end signal) int sig2Index = MainSignal.Signalfound[signalTypeOther]; if (sig2Index < 0) // try renewed search with full route { sig2Index = MainSignal.SONextSignal(signalTypeOther); MainSignal.Signalfound[signalTypeOther] = sig2Index; } Signal thisSignal = MainSignal; // ensure next signal of type 1 is located correctly (cannot be done for normal signals searching next normal signal) if (!thisSignal.SignalNormal() || signalType != (int)SignalFunction.Normal) { thisSignal.Signalfound[signalType] = thisSignal.SONextSignal(signalType); } // loop through all available signals of type 1 while (thisSignal.Signalfound[signalType] >= 0) { thisSignal = Simulator.Instance.SignalEnvironment.Signals[thisSignal.Signalfound[signalType]]; SignalAspectState thisState = thisSignal.SignalLRLimited(signalType); // ensure correct next signals are located if (signalType != (int)SignalFunction.Normal || !thisSignal.SignalNormal()) { int sigFound = thisSignal.SONextSignal(signalType); if (sigFound >= 0) { thisSignal.Signalfound[signalType] = thisSignal.SONextSignal(signalType); } } if (signalTypeOther != (int)SignalFunction.Normal || !thisSignal.SignalNormal()) { int sigFound = thisSignal.SONextSignal(signalTypeOther); if (sigFound >= 0) { thisSignal.Signalfound[signalTypeOther] = thisSignal.SONextSignal(signalTypeOther); } } if (sig2Index == thisSignal.Index) // this signal also contains type 2 signal and is therefor valid { return(foundState < thisState ? foundState : thisState); } else if (sig2Index >= 0 && thisSignal.Signalfound[signalTypeOther] != sig2Index) // we are beyond type 2 signal { return(foundValid ? foundState : SignalAspectState.Stop); } foundValid = true; foundState = foundState < thisState ? foundState : thisState; } return(foundValid ? foundState : SignalAspectState.Stop); // no type 2 or running out of signals before finding type 2 }
//================================================================================================// // return function value // Possible functions : see enum SCRExternalFunctions //================================================================================================// private static int FunctionValue(SignalHead head, SignalScripts.SCRScripts.SCRStatTerm term, int[] localFloats) { int result = 0; int parameter1 = 0; int parameter2 = 0; // extract parameters (max. 2) if (term.PartParameter != null) { if (term.PartParameter.Length >= 1) { SignalScripts.SCRScripts.SCRParameterType parameter = term.PartParameter[0]; parameter1 = TermValue(head, parameter, localFloats); } if (term.PartParameter.Length >= 2) { SignalScripts.SCRScripts.SCRParameterType parameter = term.PartParameter[1]; parameter2 = TermValue(head, parameter, localFloats); } } // switch on function switch (term.Function) { // BlockState case SignalScripts.SCRExternalFunctions.BLOCK_STATE: result = (int)head.MainSignal.BlockState(); break; // Route set case SignalScripts.SCRExternalFunctions.ROUTE_SET: result = head.VerifyRouteSet(); break; // next_sig_lr case SignalScripts.SCRExternalFunctions.NEXT_SIG_LR: result = (int)head.NextSignalLR(parameter1); break; // next_sig_mr case SignalScripts.SCRExternalFunctions.NEXT_SIG_MR: result = (int)head.NextSignalMR(parameter1); break; // this_sig_lr case SignalScripts.SCRExternalFunctions.THIS_SIG_LR: SignalAspectState returnState_lr = head.ThisSignalLR(parameter1); result = returnState_lr != SignalAspectState.Unknown ? (int)returnState_lr : -1; break; // this_sig_mr case SignalScripts.SCRExternalFunctions.THIS_SIG_MR: SignalAspectState returnState_mr = head.ThisSignalMR(parameter1); result = returnState_mr != SignalAspectState.Unknown ? (int)returnState_mr : -1; break; // opp_sig_lr case SignalScripts.SCRExternalFunctions.OPP_SIG_LR: result = (int)head.OppositeSignalLR(parameter1); break; // opp_sig_mr case SignalScripts.SCRExternalFunctions.OPP_SIG_MR: result = (int)head.OppositeSignalMR(parameter1); break; // next_nsig_lr case SignalScripts.SCRExternalFunctions.NEXT_NSIG_LR: result = (int)head.NextNthSignalLR(parameter1, parameter2); break; // dist_multi_sig_mr case SignalScripts.SCRExternalFunctions.DIST_MULTI_SIG_MR: result = (int)head.MRSignalMultiOnRoute(parameter1, parameter2); break; // dist_multi_sig_mr_of_lr case SignalScripts.SCRExternalFunctions.DIST_MULTI_SIG_MR_OF_LR: result = (int)head.LRSignalMultiOnRoute(parameter1, parameter2); break; // next_sig_id case SignalScripts.SCRExternalFunctions.NEXT_SIG_ID: result = head.NextSignalId(parameter1); break; // next_nsig_id case SignalScripts.SCRExternalFunctions.NEXT_NSIG_ID: result = head.NextNthSignalId(parameter1, parameter2); break; // opp_sig_id case SignalScripts.SCRExternalFunctions.OPP_SIG_ID: result = head.OppositeSignalId(parameter1); break; // id_sig_enabled case SignalScripts.SCRExternalFunctions.ID_SIG_ENABLED: result = head.SignalEnabledById(parameter1); break; // id_sig_lr case SignalScripts.SCRExternalFunctions.ID_SIG_LR: result = (int)head.SignalLRById(parameter1, parameter2); break; // sig_feature case SignalScripts.SCRExternalFunctions.SIG_FEATURE: result = Convert.ToInt32(head.VerifySignalFeature(parameter1)); break; // allow to clear to partial route case SignalScripts.SCRExternalFunctions.ALLOW_CLEAR_TO_PARTIAL_ROUTE: head.MainSignal.AllowClearPartialRoute(parameter1); break; // approach control position case SignalScripts.SCRExternalFunctions.APPROACH_CONTROL_POSITION: result = Convert.ToInt32(head.MainSignal.ApproachControlPosition(parameter1, false)); break; // approach control position forced case SignalScripts.SCRExternalFunctions.APPROACH_CONTROL_POSITION_FORCED: result = Convert.ToInt32(head.MainSignal.ApproachControlPosition(parameter1, true)); break; // approach control speed case (SignalScripts.SCRExternalFunctions.APPROACH_CONTROL_SPEED): result = Convert.ToInt32(head.MainSignal.ApproachControlSpeed(parameter1, parameter2)); break; // approach control next stop case SignalScripts.SCRExternalFunctions.APPROACH_CONTROL_NEXT_STOP: result = Convert.ToInt32(head.MainSignal.ApproachControlNextStop(parameter1, parameter2)); break; // Lock claim for approach control case SignalScripts.SCRExternalFunctions.APPROACH_CONTROL_LOCK_CLAIM: head.MainSignal.LockClaim(); break; // Activate timing trigger case (SignalScripts.SCRExternalFunctions.ACTIVATE_TIMING_TRIGGER): head.MainSignal.ActivateTimingTrigger(); break; // Check timing trigger case SignalScripts.SCRExternalFunctions.CHECK_TIMING_TRIGGER: result = Convert.ToInt32(head.MainSignal.CheckTimingTrigger(parameter1)); break; // Check for CallOn case SignalScripts.SCRExternalFunctions.TRAINHASCALLON: head.MainSignal.CallOnEnabled = true; result = Convert.ToInt32(head.MainSignal.TrainHasCallOn(true, false)); break; // Check for CallOn Restricted case SignalScripts.SCRExternalFunctions.TRAINHASCALLON_RESTRICTED: head.MainSignal.CallOnEnabled = true; result = Convert.ToInt32(head.MainSignal.TrainHasCallOn(false, false)); break; // Check for CallOn case SignalScripts.SCRExternalFunctions.TRAINHASCALLON_ADVANCED: head.MainSignal.CallOnEnabled = true; result = Convert.ToInt32(head.MainSignal.TrainHasCallOn(true, true)); break; // Check for CallOn Restricted case SignalScripts.SCRExternalFunctions.TRAINHASCALLON_RESTRICTED_ADVANCED: head.MainSignal.CallOnEnabled = true; result = Convert.ToInt32(head.MainSignal.TrainHasCallOn(false, true)); break; // check if train needs next signal case SignalScripts.SCRExternalFunctions.TRAIN_REQUIRES_NEXT_SIGNAL: result = Convert.ToInt32(head.MainSignal.RequiresNextSignal(parameter1, parameter2)); break; case SignalScripts.SCRExternalFunctions.FIND_REQ_NORMAL_SIGNAL: result = head.MainSignal.FindRequiredNormalSignal(parameter1); break; // check if route upto required signal is fully cleared case SignalScripts.SCRExternalFunctions.ROUTE_CLEARED_TO_SIGNAL: result = (int)head.MainSignal.RouteClearedToSignal(parameter1, false); break; // check if route upto required signal is fully cleared, but allow callon case SignalScripts.SCRExternalFunctions.ROUTE_CLEARED_TO_SIGNAL_CALLON: result = (int)head.MainSignal.RouteClearedToSignal(parameter1, true); break; // check if specified head enabled case SignalScripts.SCRExternalFunctions.HASHEAD: result = head.MainSignal.HasHead(parameter1); break; // increase active value of SignalNumClearAhead case SignalScripts.SCRExternalFunctions.INCREASE_SIGNALNUMCLEARAHEAD: head.MainSignal.IncreaseSignalNumClearAhead(parameter1); break; // decrease active value of SignalNumClearAhead case SignalScripts.SCRExternalFunctions.DECREASE_SIGNALNUMCLEARAHEAD: head.MainSignal.DecreaseSignalNumClearAhead(parameter1); break; // set active value of SignalNumClearAhead case SignalScripts.SCRExternalFunctions.SET_SIGNALNUMCLEARAHEAD: head.MainSignal.SetSignalNumClearAhead(parameter1); break; // reset active value of SignalNumClearAhead to default case SignalScripts.SCRExternalFunctions.RESET_SIGNALNUMCLEARAHEAD: head.MainSignal.ResetSignalNumClearAhead(); break; // store_lvar case SignalScripts.SCRExternalFunctions.STORE_LVAR: head.StoreLocalVariable(parameter1, parameter2); break; // this_sig_lvar case SignalScripts.SCRExternalFunctions.THIS_SIG_LVAR: result = head.ThisSignalLocalVariable(parameter1); break; // next_sig_lvar case SignalScripts.SCRExternalFunctions.NEXT_SIG_LVAR: result = head.NextSignalLocalVariable(parameter1, parameter2); break; // id_sig_lvar case SignalScripts.SCRExternalFunctions.ID_SIG_LVAR: result = head.LocalVariableBySignalId(parameter1, parameter2); break; // this_sig_noupdate case SignalScripts.SCRExternalFunctions.THIS_SIG_NOUPDATE: head.MainSignal.Static = true; break; // this_sig_hasnormalsubtype case SignalScripts.SCRExternalFunctions.THIS_SIG_HASNORMALSUBTYPE: result = head.SignalHasNormalSubtype(parameter1); break; // next_sig_hasnormalsubtype case SignalScripts.SCRExternalFunctions.NEXT_SIG_HASNORMALSUBTYPE: result = head.NextSignalHasNormalSubtype(parameter1); break; // next_sig_hasnormalsubtype case SignalScripts.SCRExternalFunctions.ID_SIG_HASNORMALSUBTYPE: result = head.SignalHasNormalSubtypeById(parameter1, parameter2); break; // switchstand case SignalScripts.SCRExternalFunctions.SWITCHSTAND: result = head.Switchstand(parameter1, parameter2); break; // def_draw_state case SignalScripts.SCRExternalFunctions.DEF_DRAW_STATE: result = head.DefaultDrawState((SignalAspectState)parameter1); break; // DEBUG routine : to be implemented later default: break; } // check sign if (term.TermOperator == SignalScripts.SCRTermOperator.MINUS) { result = -result; } return(result); }