<<< DISK$DATA:[NOTES$LIBRARY]GRAPHIQUE.NOTE;1 >>> -< SIG Applications Graphiques >- ================================================================================ Note 98.0 Alloc. de numeros de segments No replies DECUSF::ROUGERE_F 172 lines 6-AUG-1990 00:11 -------------------------------------------------------------------------------- Voici un petit bout de code FORTRAN sans pretention, mais bien pratique. Je l'utilise systematiquement avant d'ouvrir un nouveau segment GKS (ou structure Phigs), pour me faire allouer un numero. C Pour creer un segment numseg = MGALSG () CALL GOPSG (numseg) .... .... CALL GCLSG C Lorsque le segment est detruit CALL GDSG (numseg) CALL MGFRSG (numseg) J'evite ainsi de coder "en dur" les numeros de segments, ce qui me permet de faire evoluer plus facilement un programme. F. ROUGERIE Routines d'affectation de numeros de segments Les sous-programmes suivants permettent de se faire attribuer des numeros entre 1 et MAXSGN. Le but est d'utiliser ces numeros comme numeros de segments GKS. On evite ainsi de figer les numeros de segments dans le code d'une application. MGINSG : initialisation des tables MGALSG : retourne une valeur entiere entre 1 et MAXSGN, et marque dans les tables que cette valeur est utilisee MGFRSG : signale la fin d'utilisation d'une valeur Toute création d'un nouveau segment doit etre précédée d'une "allo- cation de numéro de segment" réalisée par MGALSG. De meme, une destruction définitive d'un segment doit etre suivie de la "libération du numéro de segment" correspondant (MGFRSG) Les numeros de segments alloues par MGALSG sont geres par l'interme- diaire d'une table SGFREE, telle que SGFREE(i)=FALSE si le segment numero i est en cours d'utilisation. Tant que cela est possible, on utilise les entrees de cette table dans l'ordre croissant. Lorsque un numero de segment est libere, il se cree un "trou" dans la table que l'on ignore. Ce n'est que lorsque toutes les entrees de la table auront ete potentiellement utilisees que l'on cherchera un trou pour satisfaire une nouvelle requete. Lorsque la table est totalement utilisee, une nouvelle requete de numero de segment echoue : MGALSG ne signale pas l'erreur mais retourne un numero de segment nul. On suppose en pratique que le nombre total de numeros de segments utilises par l'application est toujours inferieur au nombre de segments permis par GKS. C------------------------------------------------------------------- C C Bloc COMMON : CCSEGM C INTEGER maxsgn PARAMETER ( maxsgn = 350 ) C INTEGER nbsgal, lastsg LOGICAL sgfree(maxsgn) C COMMON / CCSEGM / nbsgal, lastsg, sgfree C C------------------------------------------------------------------- C C maxsgn Dimension de la table utilisée pour la gestion des C numéros de segments, cad nombre total de segments qu'il C est possible d'ouvrir simultanément C C nbsgal Numéro de segment deja alloue le plus eleve C C lastsg Numéro du dernier segment alloue pour lequel on a comble C un trou de la table; evite de reparcourir une partie de C celle-ci lors de la recherche d'un trou C C sgfree L'element i prend la valeur FALSE si le segment numéro i C est utilisé C C------------------------------------------------------------------- C Initialisation du mecanisme d'allocation de numeros de segments C------------------------------------------------------------------- SUBROUTINE MGINSG () C IMPLICIT NONE C INCLUDE ' CMN$PROJET: CCSEGM.CMN' C INTEGER i C lastsg = -1 nbsgal = 0 DO 10000 i = 1, maxsgn sgfree(i) = .TRUE. 10000 CONTINUE C RETURN END C------------------------------------------------------------------- C Allocation d'un numero de segment utilisable par l'application C------------------------------------------------------------------- INTEGER FUNCTION MGALSG () C IMPLICIT NONE C INCLUDE ' CMN$PROJET: CCSEGM.CMN' C INTEGER seg, i C IF ( nbsgal.LT.maxsgn ) THEN nbsgal = nbsgal + 1 sgfree(nbsgal) = .FALSE. seg = nbsgal ELSE C Il faut rechercher un trou dans la table C seg = 0 DO 10000 i = MAX0(lastsg+1, 1), maxsgn if ( sgfree(i) ) THEN sgfree(i) = .FALSE. lastsg = i seg = i GOTO 10001 ENDIF 10000 CONTINUE GOTO 99999 10001 CONTINUE ENDIF C 99999 CONTINUE C mgalsg = seg C RETURN END C------------------------------------------------------------------- C Liberation d'un numero de segment GKS alloue par MGALSG C------------------------------------------------------------------- SUBROUTINE MGFRSG ( numseg ) C IMPLICIT NONE C INTEGER numseg C INCLUDE ' CMN$PROJET: CCSEGM.CMN' C sgfree(numseg) = .TRUE. if ( numseg.EQ.nbsgal ) THEN nbsgal = nbsgal - 1 ELSE C on note l'emplacement d'un trou C IF ( lastsg.LT.0 ) THEN lastsg = numseg-1 ELSE lastsg = MIN0 (lastsg, numseg-1) ENDIF ENDIF C RETURN END