L'occurrence d'un événement provoque l'exécution, ou bien le déclenchement et l'entretien, de processus de changement d'état du système simulé. En conséquence, un système qui ne serait soumis à l'occurrence d'aucun événement resterait dans son état initial. Un événement qui ne comporterait aucune directive sur un processus ne peut être placé dans l'agenda de la simulation.
Les sous-classes d'événements propres au système simulé sont déclarées dans le fichier typiquement nommé UserEvent.h et réalisées dans le fichier UserEvent.cc. Leurs constructeurs contiennent essentiellement l'attribution d'une date d'occurrence, d'un degré de priorité par rapport aux autres événements survenant à cette date, la fabrication de la liste des couples {processus, action\} qui en sont la conséquence, et l'affectation, si besoin est, des méthodes de postconséquence et d'autogénération. Attention ! Plus la valeur du degré de priorité est faible, plus la priorité est forte (un événement de degré 0 est plus prioritaire d'un autre de degré 1). La priorité par défaut est 99.
Les méthodes de postconséquence et d'autogénération sont des instances de la classe EventMethod. Elles sont affectées à l'événement, avec un corps vide, dans le constructeur de base de l'événement. Un corps spécifique leur est ensuite affecté par invocation d'une des méthodes SetPostConsequence, SetGenerateNextEvent, SetUpdateNextEvent et SetDefineNextEventClockTime.
L'utilisateur crée des instances d'événements au moyen d'un constructeur (voir page Constructeurs/Destructeurs) et les range dans l'agenda d'événements. Cette création peut avoir lieu avant le début de la simulation, ou bien pendant la simulation comme partie de l'effet de processus. Le moteur de simulation peut lui-aussi créer des instances de sous-classes de Event, dans trois situations :
En résumé, le cycle de vie d'un événement est le suivant :
- Dans le cas où l'utilisateur a écrit une fonction de génération automatique (par l'une ou l'autre des méthodes SetGenerateNextEvent, SetUpdateNextEvent et SetDefineNextEventClockTime). Le première fonction code, à partir d'un événement, la génération d'un nouvel événement d'une classe différente (dont le nom de classe est renvoyé par NextEventClassName()) ou de la même classe (dans ce dernier cas : obligatoirement par RawCopy appliquée à l'événement d'origine). Les deux autres fonctions sont d'utilisation exclusive l'une de l'autre. L'une ou l'autre opère sur un événement généré par SetGenerateNextEvent, ou bien, par défaut, par le moteur de simulation. Tout cela permet à l'utilisateur de définir un enchaînement d'événements dans le temps, sans avoir à donner explicitement la liste complète des événements. La fonction de génération automatique, si elle est présente, est appelée par le moteur après l'exécution des conséquences (en termes de processus) de l'occurrence de l'événement. Typiquement, cette fonction peut contenir un appel tel que :
RandomInteger(self->MaxDelayNextEvent() - self->MinDelayNextEvent());où self est lié à l'instance de l'événement qui vient de survenir, et RandomInteger est une fonction qui renvoie un nombre entier aléatoire entre 0 et son argument. Ce nombre sert à définir la date du nouvel événement.- Dans le cas où un processus de l'événement a vu sa précondition (d'initialisation ou d'exécution) non satisfaite. Le système crée alors un nouvel événement de la même classe pour un instant ultérieur (mise en attente du processus, voir la méthode SetPrecondition de la classe Process). Si l'événement est doté d'une fonction d'autogénération, celle-ci ne sera invoquée qu'en l'instant où la précondition deviendra satisfaite, et non pas en l'instant d'occurrence initialement programmé (dont la valeur est perdue et ne peut donc pas être exploitée dans la fonction d'autogénération).
- Dans le cas où l'utilisateur a écrit une fonction de postconséquence (par la méthode SetPostConséquence). Le corps d'une telle fonction est libre. Il est donc possible d'y coder l'occurrence d'un événement, mais on préfèrera pour cela utiliser les fonctions présentées plus haut.
- création et insertion dans l'agenda
- dépilement de l'événement lorsqu'il arrive en la position de tête : current
- tentative exécution des directives sur les processus
- si l'événement est différé (précondition non satisfaite)
- création d'un événement new par
- copie des processus de current (en conservant les mêmes méthodes)
- copie de current (en conservant les mêmes méthodes), avec les processus copiés
- suppression des processus de current (sans supprimer les méthodes), et suppression de current par RawCopy (sans supprimer les méthodes, lesquelles sont désormais attachées à new)
- insertion de new dans l'agenda
- si les directives sur les processus sont exécutées (précondition satisfaite)
- exécution de la post-conséquence
- tentative d'autogénération si c'est spécifié
- si un nouvel événement new a été généré
- suppression des processus de current (sans supprimer les méthodes), et suppression de current (sans supprimer les méthodes)
- insertion de new dans l'agenda
- sinon
- suppression des processus de current (et de leurs méthodes), et suppression de current (et de ses méthodes)
- fin cycle