- Directive d'inclusion : #include C_Operation.h
Une opération est une entité qui permet de spécifier la nature et les modalités d'un changement d'état d'un système piloté.
Les classes d'opérations dans un domaine d'application sont des instances d'une seule des trois classes UnitGranulatedOperation, QuantityGranulatedOperation et TimeGranulatedOperation, qui sont elles-mêmes des particularisations de la classe générale Operation.
descripteurs :
Les descripteurs de type int représentent un nombre d'unités de temps simulé, à partir du début de la simulation (voir DIESE : Manuel de l'utilisateur). La valeur par défaut est en dernière colonne.
\noindent
INSTRUCTION_CONTAINER instructionContainer l'instruction 'mère' PrimitiveActivity* OPERATED_ENTITY_ID opEntId symbole de classe int 0 (O_ENTITY) de l'entité opérée STEP step pas de progression de l'effet int 1 PROGRESSION_MODE progMode mode de progression C_ProgressionModeId UNIT SUSPENSION_THRESHOLD suspThreshold seuil de suspension int 100 PRIORITY_DEGREE priorityDegree degre de priorité int 99 (la plus faible) REQUIRED_RESOURCES reqResources ressources requises pEntityTab* NULL ACHIEVEMENT_DEGREE achievementDegree degré de progression float SITUATION situation état de l'opération C_StateId DORMANT BEG_DATE begDate date de début int -9 END_DATE endDate date de fin int -9 LAST_RESTARTING_DATE restartDate date de la dernière reprise int -9 DURATION durée de début à fin int 0 NET_DURATION durée hors suspensions int 0 méthodes :
\noindent
STATE_TRANSITION_PROCEDURE stateTransitionProcedure procédure de transition d'état EntityPredicate FEASIBILITY_CONDITION feasibilityCondition condition de faisabilité EntityPredicate
Le constructeur d'une classe d'opérations dans un domaine d'application doit spécifier le changement d'état du système que provoque l'opération. A cet effet, il doit comporter un appel qui affecte un corps à la méthode de la classe Operation, dite 'procédure de transition d'état' dont le symbole est STATE_TRANSITION_PROCEDURE :
\BTab4 AssignBody(STATE_TRANSITION_PROCEDURE, f);
où f est une fonction écrite par le développeur.
Le corps de f exploite normalement son argument pM, qui est la méthode dont f est le corps. f a donc accès, notamment :
- à l'opération, par le service DescribedEntity, et ainsi à l'activité (valeur du descripteur de symbole INSTRUCTION_CONTAINER)
- à l'entité dont l'opération est censée changer l'état, placée par le moteur dans la liste des arguments de la méthode. f peut alors modifier l'état de cette entité, par exemple de la manière suivante :
\BTab4 bool f (EntityMethod pM) {
\BTab4 Entity* pObj = pM->GetEntityArgValue(OPERATION_TARGET);
\BTab4 float x = pObj->GetFloatValue(TEMPERATURE);
\BTab4 x = x * 1.1;
\BTab4 pObj->SetValue(TEMPERATURE, x);
\BTab4
\BTab4 return TRUE;
\BTab4 \; }
Le corps de la procédure de transition d'état renvoie TRUE dans le cas général. Seulement pour les opérations de transfert (voir le paragraphe dédié), la valeur renvoyée est FALSE pour indiquer que le transfert n'a pas pu être réalisé comme spécifié.
C'est le moteur de simulation qui se charge d'invoquer la procédure de transition d'état ainsi affectée à l'opération. Il le fait à chaque pas de progression de l'opération (voir plus loin la définition du pas). De plus, à chaque pas, le moteur détermine le nombre d'invocations nécessaires et l'entité, valeur de l'argument OPERATION_TARGET, celle dont l'opération change l'état durant ce pas. Cette détermination est faite de manière spécifique à chacune des trois particularisations de la classe Operation, comme décrit ci-après.
Pour chaque instruction dans le jeu choisi (voir ...), la méthode de symbole ACT_INSTRUCTION_LIST de l'OperatingSystem accède à l'instance d'Operation et lui associe un processus continu, instance de la classe prédéfinie ProceedOperation, qui va prendre en charge la progression dans le temps de l'effet de l'opération.
Une fois construit, le processus est lui-même associé à un événement qui peut être de deux classes différentes, prédéfinies dans DIESE :
- ProceedFromCurrentState si l'opération a déjà eu un commencement d'exécution et a été interrompue : le processus est alors associé à une directive PROCEED ;
- SetInitialStateAndProceed dans le cas contraire : il est alors associé à deux directives successives, INIT et PROCEED ;
Enfin, cet événement est placé dans l'agenda de la simulation, à la date courante, pour un début ou une reprise immédiate de l'effet de l'opération.
Dans le constructeur de ProceedOperation, c'est l'opération qui est désignée, par le service ProcessedEntity de DIESE, comme l'entité sur laquelle l'instance de processus va opérer un changement d'état (essentiellement sur la situation, le degré de progression, les dates de début et de fin). Il établit le pas à la valeur du pas de l'opération (renvoyé par le message GetIntValue(STEP) adressé à l'opération). Il contient enfin l'assignation d'un corps standard aux méthodes d'initialisation, de poursuite et d'arrêt. Ceci est réalisé par les services de DIESE :
\BTab4 SetInitialize(f);
\BTab4 SetGoOneStepForward(g);
\BTab4 SetStop(h);
où :
- f est une fonction d'initialisation dont CONTROL DIESE fournit trois versions, chacune adaptée à une particularisation d'Operation. Le constructeur de ProceedOperation choisit la bonne version en fonction du type de l'opération en jeu. Dit de façon sommaire, elles donnent la valeur 0 au descripteur de symbole PROGRESSION_DEGREE de l'opération, la valeur EXECUTING au descripteur de symbole SITUATION de l'opération, la valeur IN_COURSE au descripteur de symbole SITUATION de l'instruction. La date de début de l'opération est valuée avec l'instant courant. Le constructeur établit enfin la liste des entités objets de l'effet de l'opération. Ces entités sont des instances de la classe dont le symbole est la valeur du descripteur OPERATED_ENTITY_ID de l'opération. Plus précisément, ce sont celles qu'on trouve à une profondeur quelconque comme élément des entités objet de l'instruction (voir page dédiée).
- g est une fonction de poursuite du processus dont CONTROL DIESE fournit trois versions. Le constructeur du processus choisit la version correspondant au type de l'opération en jeu.
- UnitGranulatedOperation :
- la version FullEffectOnUnits enchaîne (rappel : à l'intérieur d'un pas) un certain nombre d'invocations (en fait égal à la vitesse n de l'opération) du corps de la méthode de l'opération de symbole STATE_TRANSITION_PROCEDURE. A chaque invocation, une nouvelle entité de la liste créée dans l'initialisation est placée comme valeur de l'argument OPERATION_TARGET de la méthode STATE_TRANSITION_PROCEDURE. On rappelle que le corps de cette méthode reçoit en paramètre la méthode elle-même, ce qui permet d'accéder à l'entité via son argument OPERATION_TARGET.
- QuantityGranulatedOperation :
- la version FullEffectOnQuantity recherche une entité particulière dans la liste des entités objets de l'instruction (voir ci-dessus) : la première telle que la totalité de la valeur d'une certaine dimension n'a pas été opérée. Cette dimension est celle dont le symbole est la valeur du descripteur QUANTITY_DESCRIPTOR_ID. On dénommme 'quantité' une valeur sur cette dimension. Seulement si cette entité n'a pas du tout été opérée, FullEffectOnQuantity invoque le corps de la méthode STATE_TRANSITION_PROCEDURE de l'opération, après avoir désigné l'entité comme valeur de l'argument OPERATION_TARGET. Dans tous les cas, le degré de progression de l'opération est augmenté du rapport entre la vitesse de l'opération et la quantité totale sur les entités objets de l'instruction. Il y a en tête de la liste un nombre d'entités dites totalement opérées tel que le produit du nombre d'invocations de FullEffectOnQuantity (depuis l'initialisation du processus) par la vitesse de l'opération est supérieur ou égal à la somme des quantité sur ce nombre d'entités.
- TimeGranulatedOperation :
- si et sulement si le degré de progression de l'effet est nul, StepEffectOnObject invoque le corps de la méthode STATE_TRANSITION_PROCEDURE de l'opération successivement sur chaque entité objet de l'instruction (voir ci-dessus), après l'avoir désignée comme valeur de l'argument OPERATION_TARGET. Ensuite et à chaque pas, le degré de progression de l'opération est augmenté de la vitesse de l'opération.
- h est une fonction standard d'arrêt du processus, invoquée dans les trois méthodes de poursuite lorsque le degré de progression devient 100. Elle donne la valeur TERMINATED au descripteur SITUATION de l'opération. La date de fin de l'opération est valuée avec l'instant courant. Les autres opérations en cours de progression deviennent SUSPENDED et les processus associés recoivent un message ToBeStopped(TRUE). Enfin est programmé pour l'instant courant un événement C_MakeInstructionListEvent déclenchant le processus C_MakeInstructionListProcess dont la procédure d'exécution invoque le corps de la méthode de symbole MAKE_INSTRUCTION_LIST de l'OperatingSystem. Le message ToBeStopped(TRUE), et non le message Stop() est adressé aux processus correspondant aux opérations suspendues, pour éviter des exécutions superflues de MAKE_INSTRUCTION_LIST.