signal()

signal(<id>, <señal>)

Descripción:

Manda una señal a un proceso (un objeto del juego). Esta función se utiliza principalmente (aunque no sólo) para destruir (matar) a un proceso desde otro, enviándole una señal s_kill.

Si desconoce a qué se hace referencia cuando se habla del proceso padre, hijo, hermano, un proceso huérfano, etc., entonces vea Jerarquías de procesos.

Si desconoce los términos vivo, muerto, dormido, etc., referidos a procesos, vea Estados de un proceso.

Ejemplo:
PROGRAM mi_juego;
PRIVATE id2;
BEGIN
    id2=mi_proceso();
    // ...
    signal(id2, s_kill);
END
PROCESS mi_proceso()
BEGIN
    // ...
    LOOP
        FRAME;
    END
END


Este programa crearía un proceso de tipo mi_proceso y después lo eliminaría con la sentencia signal(id2,s_kill) (id2 es una variable del programa principal que contiene el código identificador del proceso que se va a destruir).

Cualquier proceso puede enviar una señal a otro, siempre que disponga de su código identificador, ver:

  Códigos identificadores de procesos
  Formas de obtener el código identificador de un proceso

No obstante, hay otros tipos de señales que se le pueden enviar a un proceso, y son las siguientes:

s_kill - Orden de matar al proceso, el proceso ya no aparecerá en las siguientes imágenes del juego.

s_sleep - Orden de dormir al proceso, el proceso quedará paralizado sin ejecutar su código y sin visualizarse en pantalla (ni poder ser detectado por el resto de los procesos), como si se hubiera matado. Pero el proceso seguirá existiendo en la memoria del ordenador (ver s_wakeup).

s_freeze - Orden de congelar al proceso, el proceso quedará inmovilizado sin ejecutar su código, pero seguirá visualizándose en pantalla y pudiendo ser detectado (en las colisiones) por el resto de procesos. El proceso seguirá existiendo en la memoria del ordenador a pesar de no ejecutarse su código (ver s_wakeup).

s_wakeup - Orden de despertar al proceso, devuelve a su estado normal un proceso que ha sido dormido o congelado; a partir del momento en que reciba esta señal el proceso volverá a ejecutarse y visualizarse normalmente. No se puede devolver a su estado normal un proceso que ha sido eliminado (matado) pues ya ha dejado de existir en la memoria del ordenador.

Un proceso puede enviarse también estas señales a sí mismo, teniendo en cuenta que el código identificador de un proceso es siempre ID (palabra reservada en el lenguaje para tal fin). La sentencia sería como la siguiente:

signal(id, <señal>)

Auto-eliminar un proceso de esta forma, enviándose una señal s_kill, no destruirá el proceso instantáneamente, sino en la próxima visualización (FRAME). Para eliminar un proceso de forma inmediata se puede utilizar la sentencia RETURN.

Todas las señales enviadas a procesos tendrán efecto justo antes de la próxima visualización del juego, es decir, en la próxima imagen (FRAME) del juego (no instantáneamente).

Además de estas cuatro señales existen otras cuatro que se corresponden directamente con las anteriores y son: s_kill_tree, s_sleep_tree, s_freeze_tree y s_wakeup_tree.

Estas señales se utilizan cuando se quieren enviar, no sólo al proceso indicado, sino, además, a todos los procesos que éste haya creado, es decir, si se envía una señal s_kill_tree a un proceso, se destruirá él y toda su descendencia (hijos, nietos, ...), todos los procesos que haya creado y los que hayan creado estos.

Una excepción a estas últimas cuatro señales es cuando existe un proceso huérfano, esto es, un proceso cuyo padre (el proceso que lo llamó) ya está muerto. Los procesos huérfanos no recibirán la señal cuando se les envíe a un proceso del cual son descendencia, pues al haber desaparecido su padre, éste no podrá transmitir la señal a los procesos que creó.

Programa ejemplo:
PROGRAM ejemplo_signal;
PRIVATE
    id_text;
BEGIN
    load_fpg("help\help.fpg");
    put_screen(0, 1);
    write(0, 0, 0, 0, "1 - crear el proceso");
    write(0, 0, 10, 0, "2 - matar el proceso");
    write(0, 0, 20, 0, "3 - dormir el proceso");
    write(0, 0, 30, 0, "4 - congelar el proceso");
    write(0, 0, 40, 0, "5 - despertar el proceso");
    id_text=write(0, 0, 190, 0, "No hay proceso");
    LOOP
        IF (key(_1) AND NOT son)
            delete_text(id_text);
            mi_proceso();
            id_text=write(0, 0, 190, 0, "Proceso vivo");
        END
        IF (key(_2) AND son)
            delete_text(id_text);
            signal(son, s_kill);
            id_text=write(0, 0, 190, 0, "No hay proceso");
        END
        IF (key(_3) AND son)
            delete_text(id_text);
            signal(son, s_sleep);
            id_text=write(0, 0, 190, 0, "Proceso dormido");
        END
        IF (key(_4) AND son)
            delete_text(id_text);
            signal(son, s_freeze);
            id_text=write(0, 0, 190, 0, "Proceso congelado");
        END
        IF (key(_5) AND son)
            delete_text(id_text);
            signal(son, s_wakeup);
            id_text=write(0, 0, 190, 0, "Proceso vivo");
        END
        FRAME;
    END
END

PROCESS mi_proceso()
BEGIN
    graph=100;
    LOOP
        x=160+get_distx(angle, 140);
        y=100+get_disty(angle, 80);
        angle+=5000;
        FRAME;
    END
END


Este programa creará con la tecla 1 un proceso (mi_proceso) que va dando vueltas a la pantalla; con las teclas 2 a 5 se le enviarán a dicho proceso diferentes señales utilizando esta función. El código identificador de mi_proceso está en la variable local son (hijo) del programa principal por defecto.

Cuando se crea un proceso, el sistema define la variable son del padre con el código identificador del hijo, y la variable father del hijo con el código identificador del padre.


signal(TYPE <nombre de proceso>, <señal>)

Descripción:

Esta segunda acepción de la función signal es similar a la anterior, con la excepción de que, en lugar de enviarle una señal a un proceso a partir de su código identificador, permite enviar una señal a todos los procesos de un tipo determinado o a ellos y su descendencia si se utilizan las señales como s_kill_tree (ver: Tipos de procesos).

Por ejemplo, si en un juego existen, o pueden existir, varios procesos de tipo enemigo y se quiere congelar a dichos procesos (sin congelar a su descendencia) se utilizará la siguiente sentencia:

  signal(TYPE enemigo, s_freeze);

Como se puede observar para enviar una señal a un proceso en concreto se necesita su código identificador y para destruir a un grupo de procesos, que estos sean todos del mismo tipo, que se trate de un proceso y su descendencia, o bien conocer todos sus identificadores (para enviarles la señal uno a uno).

Se puede enviar una señal a un tipo de procesos aun cuando no exista ningún proceso de ese tipo ejecutándose en el juego. Pero si se envía una señal a un proceso que ya ha muerto, con su código identificador (primera acepción de la sentencia signal), se corre el riesgo de que dicho código identificador ahora sea usado por otro proceso, siendo éste el que reciba la señal. Esto es si, por ejemplo, se pretende matar a un proceso que ya está muerto, cabe la posibilidad de que se esté matando a otro.


Nota: Si se quieren eliminar todos los procesos y dejar únicamente al proceso actual, se puede utilizar la función let_me_alone(). Esta función envía una señal s_kill a todos los procesos, excepto al que ejecutó dicha función.


Ver: let_me_alone() - Códigos identificadores - Tipos de procesos