Contenido del fichero sigscr.dat

 

 Formato del fichero de Script de señales 

Los scripts se cargan desde ficheros de script, los cuales contienen una colección de scripts nominales. Todas las líneas se consideran parte de un script, excepto las líneas de descripción (cabecera) del script, las cuales pueden ser una de las siguientes:

SCRIPT <script_name> Inicio de un script de nombre script_name
REM SCRIPT <script_name> Deshabilitación de todo un script (comentado)

Un script abarca desde la cabecera del script hasta la siguiente cabecera de script, o hasta el final del fichero. Las líneas anteriores a la primera cabecera de script se ignoran. Los nombres de los script sólo pueden contener caracteres alfanuméricos y el caracter "_" (underscore). Nótese que la carga del fichero de scripts asume que el código es siempre ASCII (no Unicode).

El nombre de un script de señal debe ser idéntico al nombre de SignalType en el archivo de configuración de señales (sigcfg.dat) al que corresponda. Si se requiere más de un script para un mismo tipo de señal, se deberá crear una entrada SignalType diferente que refiera a un script diferente.

El nombre del archivo de scripts se especifica en la sección SriptFiles del archivo de configuración de señales.

Este es el formato general de un archivo de scripts.

// Comentarios
SCRIPT Script_Name1
<Código del Script 1>

REM SCRIPT Script_Name2
<Código del Script 2>

SCRIPT Script3
<Código del Script 3>

 

 Sistema de Scripts en MSTS 

Este documento pretende ser únicamente una referencia rápida sobre el sistema de Scripts en MSTS para el funcionamiento de señales.

El lenguaje de scripting es como una versión reducida del lenguaje C. La disposición del código dentro de una escritura es igual que en C. Debajo están las descripciones de los tipos de datos, de los operadores, etc, que están soportados.

Estructura del código

Es la misma que en lenguaje C. P.e. las siguientes dos piezas de código tienen la misma funcionalidad, la única diferencia es cuan facil son de leer.

for(x=I = 0;i< 4; i++)x +=i;

for (x = i = 0; i < 4; i++)
    x += i;

Tipos de datos

Actualmente, el único tipo de dato soportado es ‘float’ (número con decimales). Los tipos 'pointer' (punteros) no están soportados.

Operadores

A continuación se describe el conjunto de operadores soportados. Cada uno tiene el mismo uso que en C a menos que se indique lo contrario. Aquellos que poseen alguna diferencia tienen su explicación remarcada en cursiva.

Comentarios  
// El resto de la línea es un comentario
/* */ Inicio y final de comentario
   
Control de Programa  
if, else, else if Condicional
? : Condicional
for Bucle "for"
while Bucle "while"
do, while Bucle "do/while"
break Salida de un bucle
return Salida del script con un valor de retorno
{ } Marcadores de bloque (llaves)
( ) Marcadores de expresiones (paréntesis)
   
Operadores Lógicos  
and, && AND lógico
or, || OR lógico
eor, ^ OR exclusivo lógico
not, ! NOT lógico, negación
   
Operadores de asignación  
+= Asignación de suma
-= Asignación de resta
*= Asignación de multiplicación
/= Asignación de división
/#= División entera. Redondea los valores de las expresiones al entero más cercano, realiza la división entera (redondeando al valor más bajo), y asigna el resultado
%= Asignación de módulo
   
Operadores relacionales  
== Igual
!= No igual
==# Redondea el valor resultante de cada expresión al entero más cercano y compara si son iguales
!=# Redondea el valor resultante de cada expresión al entero más cercano y compara si son no iguales
<= Menor que o igual
>= Mayor que o igual
< Menor que
> Mayor que
<=# Redondea el valor resultante de cada expresión al entero más cercano y compara si es menor que o igual
>=# Redondea el valor resultante de cada expresión al entero más cercano y compara si es mayor que o igual
<# Redondea el valor resultante de cada expresión al entero más cercano y compara si es menor que
># Redondea el valor resultante de cada expresión al entero más cercano y compara si es mayor que
   
Otros operadores  
= Asignación
#= Redondea el valor a la derecha al entero más cercano y asigna
+ Suma
- Resta
* Multiplicación
/ División
div, /# División entera. Redondea el valor resultante de cada expresión al entero más cercano realiza una división entera redondeando el resultado al entero menor
mod, % Módulo
++ Incrementa en uno
-- Decrementa en uno
# Redondea el valor al entero más cercano

Precedencia de Operadores y Asociaciones

Igual que en ‘C’. Para detalles dirigirse a la alguna referencia del lenguaje ‘C’.

Llamadas a Funciones

Los scripts no pueden llamar directamente a otros scripts, ni se pueden declarar funciones dentro de un script. Los scripts pueden, no obstante, hacer llamadas a funciones ‘C’, relacionadas con las señales y el desarrollo de las actividades, que están disponibles al sistema de scripting (‘script functions’).

No existe comprobación previa de los parámetros, y cualquier número de parámetros puede ser pasado a una función, sin que la carga del script produzca ningún error. Todos los valores son pasados a la función "por referencia", incluso las constantes, por tanto la función puede modificar dichos valores. No se usa el signo ‘&’ para indicar ésto. Se debe tener cuidado en suministrar el número correcto de argumentos, así como evitar pasar constantes a una función que está documentada como que modificará dicho argumento.

Las funciones devuelven siempre un sólo valor, el cual es siempre de tipo "float".

Ejemplo:

    return_val = test_fn (a, 2);

Aquí se llama a la función test_fn con una referencia a la variable ‘a’ y una referencia a la constante 2. Devuelve un valor que se almacena en la variable ‘return_val’. La función puede estar codificada para actualizar también el valor de la variable ‘a’.

Funciones y declaración de Variables

Todas las variables y funciones referenciadas por un script deben estar declaradas al principio de disho script. Las variables externas (aquellas proveidas por el código ‘C’ que llama al script) deben ser declaradas usando el parámetro ‘extern’, como si fueran funciones. La lista de argumentos de las funciones externas no se especifican en las declaraciones de las funciones.

 

 Variables y Funciones específicas de los Script de señales 

Nótese que los valores de las funciones en los script incluyen el prefijo de la categoría del valor (al contrario que en el archivo de configuración de la señal)

Por un 'conjunto' de señales se entiende el grupo de cabezas o brazos de una señal que comparten la misma posición en la vía (están en el mismo objeto de señal) y orientadas en la misma dirección.

Estas variables y funciones proporcionan los valores que actúan de interfase para los scripts de señales.

No es necesario comparar el valor de una función o variable con TRUE o FALSE, basta preguntar por la propia función o variable en la forma ‘if (enabled)’ o ‘if (!enabled)’, que representan, respectivamente, comparaciones con los valores TRUE o FALSE.

Si se usa el valor retornado por una función varias veces en un script, se puede mejorar el rendimiento del script asignando la función a una variable local del script y evaluando el contenido de dicha variable en lugar de la propia función (como se haría en 'C').

state Estado o indicación de la señal.
  Devuelve un valor SIGASP:
    SIGASP_STOP
    SIGASP_STOP_AND_PROCEED
    SIGASP_RESTRICTING
    SIGASP_APPROACH_1
    SIGASP_APPROACH_2
    SIGASP_APPROACH_3
    SIGASP_CLEAR_1
    SIGASP_CLEAR_2
  Esta variable es tanto de entrada como de salida.
   
draw_state Cambia el estado de una señal al valor que se le asigna.
  Los valores permitidos son aquellos especificados en el SignalType del archivo de configuración como índice del estado o indicación de la señal.
  Esta variable es tanto de entrada como de salida.
   
enabled Muestra si la señal está operativa.
  Contiene TRUE (diferente de cero) si la señal está operativa o puede mostrar su estado, en caso contrario contiene FALSE.
  Esta variable es sólo de entrada.
   
block_state () Recupera el estado del sector siguiente a la señal.
  Devuelve un valor BLOCK:
    BLOCK_CLEAR El sector siguiente está libre
    BLOCK_OCCUPIED El sector siguiente está ocupado por algún vagón o locomotora
    BLOCK_JN_OBSTRUCTED El sector siguiente no está accesible por la disposición de las agujas
   
route_set () Determina si la ruta siguiente está seleccionada para una dirección.
  Devuelve TRUE si las agujas siguientes están en una posición que permite a un tren que pase la señal alcanzar la dirección especificada (en Route Editor), en caso contrario devuelve FALSE. Devuelve TRUE si la cabeza o brazo no está definida como "junction link".
   
next_sig_mr (fn_type)
next_sig_lr (fn_type)
Devuelve el estado o indicación más restrictivo "mr" o menos restrictivo "lr" (valor SIGASP) de la siguiente señal de un tipo determinado (valor SIGFN).
  Obtiene el estado de la siguiente señal del tipo indicado y devuelve su valor más restrictivo "mr" o menos restrictivo "lr". Devuelve SIGASP_STOP si no hay a continuación ninguna señal del tipo especificado.
   
opp_sig_mr (fn_type)
opp_sig_lr (fn_type)
Devuelve el estado o indicación más restrictivo "mr" o menos restrictivo "lr" (valor SIGASP) de la siguiente señal opuesta de un tipo determinado (valor SIGFN).
  Obtiene el estado de la siguiente señal del tipo indicado en dirección opuesta a la actula (p.e. la señal de entrada en el lado contrario al sector que propeje la señal actual) y devuelve su valor más restrictivo "mr" o menos restrictivo "lr". Devuelve SIGASP_STOP si no hay a continuación ninguna señal del tipo especificado.
   
this_sig_mr (fn_type)
this_sig_lr (fn_type)
Devuelve el estado o indicación menos restrictivo "mr" o menos restrictivo "lr" (valor SIGASP) de la siguiente señal opuesta de un tipo determinado (valor SIGFN).
  Obtiene el estado de la cabeza situada en la misma señal del tipo indicado y en la misma dirección que la actula (p.e. múltiples brazos en una misma señal de diferentes tipos) y devuelve su valor menos restrictivo "mr" o menos restrictivo "lr". Devuelve -1 si no hay a ninguna cabeza en la señal del tipo especificado.
Nota: Esta función sólo tiene sentido para consultar el estado de una cabeza de tipo SIGFN_NORMAL, desde el script de una cabeza de otro tipo diferente , dado que las cabezas SIGFN_NORMAL se actualizan en primer lugar y el resto despúes, y la operación contraria consultaría el estado de una cabeza que aún no ha sido actualizada por el juego. Como ejemplo podemos poner la actualización de la posición de un brazo auxiliar en virtud de la indicación del brazo principal de la misma señal.
   
dist_multi_sig_mr
    (fn_type, end_type)
Devuelve el valor más restrictivo de las cabezas analizadas entre una de tipo fn_type y otra de tipo end_type en la ruta que sigue a la señal.
  Busca a lo largo de la ruta que sigue a la señal una cabeza o brazo de tipo fn_type hasta encontrar otra señal con cabeza o brazo de tipo end_type, o hasta que las agujas conduzcan a una vía muerta. Se incluyen las cabezas del tipo fn_type de la primera y última señales así encontradas. Si alguna de estas tiene definida (linked) una ruta, se analiza si está accesible (ver route_set para detalles) y si no lo está se ignora ésta. Finalmente devuelve el valor más restrictivo de las cabezas analizadas. Devuelve SIGASP_STOP si no hay a continuación ninguna señal del tipo end_type.
Esta función está diseñada para encontrar el estado de antiguas señales de distancia europeas, pasando como argumentos SIGFN_NORMAL y SIGFN_DISTANCE respectivamente.
   
sig_feature
    (feature_num)
Devuelve TRUE si el valor SIGFEAT está presente, en caso contrario devuleve FALSE.
  Mira si la señal actual tiene especificado uno de los valores SIGFEAT en el momento de situar la señal en el Route Editor. Los valores posibles son:
SIGFEAT_NUMBER_PLATE Placa de número
SIGFEAT_GRADIENT_PLATE Placa de pendiente
SIGFEAT_USER1 -
SIGFEAT_USER4
Definido por el usuario

Cuando la función se ejecuta comprueba si existe algún sub-objeto en la señal, con la misma orientación que la cabeza actual, cuyo sub-tipo (valor SIGSUBT ver archivo de configuración) coincida con el valor SIGFEAT especificado.

   
def_draw_state
    (sig_state)
Devuelve el índice del estado sig_state definido para la señal.
  Convierte un valor SIGASP en el índice del estado definido en el archivo de configuración para la señal actual. Se usa para asignar éste índice a la variable draw_state, la cual requiere un valor númerico de estado para la señal.
   
debug_header () Escribe un encabezamiento de depuración en el archivo de log de scripting.
   
debug_out (n)
debug_out2 (n1, n2)
Escribe uno o dos valores numéricos en el archivo de log de scripting.

 

Pere Comas. pere_comas@hotmail.com
Copyright Agrupament Ferroviari de Barcelona © 2002.