home *** CD-ROM | disk | FTP | other *** search
- //==========================================
- //===== REALISATION DE LA CLASSE STATE =====
- //==========================================
-
- //----- composition de la classe
- #include "statelis.hpp" // pour la pile des etats
- #include "stateerr.hpp" // pour les messages d'erreur
- #include "state.hpp" // interface de la classe
- #include "allcodes.cod" // pour NOT_A_STATE et MAX_STATE_SIZE
- // Test des inclusions
- #ifndef STATE_SYSTEME
- #error The variable STATE_SYSTEME must be defined [file STATE.CFG]
- #endif
- #ifndef STATE_COMPILER
- #error The variable STATE_COMPILER must be defined [file STATE.CFG]
- #endif
- //----- fonctions de service
- #if STATE_USE_EXCEPT == 1
- #include <except.h> // pour "terminate"
- #endif
- #include <stdlib.h> // pour "exit"
- //----- conditionnel car affichage
- #if STATE_SYSTEME == STATE_DOS
- #include <iostream.h> // pour les COUT
- #if STATE_COMPILER == STATE_BORLAND
- #include <alloc.h> // pour les tests de memoire
- #endif
- #if STATE_COMPILER == STATE_MICROSOFT
- #include <malloc.h> // pour les tests de memoire
- #endif
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- #if STATE_COMPILER == STATE_BORLAND
- #include <owl\dialog.h>
- #include <owl\controlb.h>
- #else
- #error Windows code is dependant on BORLAND CPP V4.x compilers
- #endif
- #endif
-
-
- // nom de la version liee aux outils de taduction
- const char* State::version = "Version 1.0a";
- //pour eviter les recursions sur les pre/post conditions
- int State::ppConditionInUse = 0;
- #ifdef STATE_DEBUG
- // ===== Comptage des etats crees - detruits =====
- int State::nbAlive = 0;
- // ===== Comptage des etats crees ================
- long State::nbCreated = 0L;
- #endif
-
- // ===== Definition de l'indicateur GLOBAL d'erreur =====
- // = cet indicateur fait office de ERRNO pour les etats =
- // = Il n'est positionne qu'une seule fois afin de =
- // = la cause initiale de l'exception, meme en cas de =
- // = levee d'exeption multiple. =
- int State::globalError = 0;
- //=======================================================
-
- // ======= Definition de l'indicateur de Controle =======
- // = Cet indicateur signale si les etats courants des =
- // = objets doivent etre calcules et si les test d' =
- // = executabilite des methodes executes. =
- // = Les controles sont invalides pendant l'execution =
- // = de methodes constructeurs. =
- int State::nbInvalidated = 0;
- void* State::invalidateCtrl[MAXINVALIDATE] = {0};
- // ======================================================
-
-
- // ====== Definition de la pile des etats courants ======
- StateList* State::pile = new StateList();
- //=======================================================
-
- State::State(State& source)
- {
- #ifdef STATE_DEBUG
- State::nbAlive++;
- State::nbCreated++;
- #endif
-
- if(!source.currentSize)
- {
- if (!State::globalError)
- {
- State::globalError = 11;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(11);
- #else
- State::terminate();
- #endif
- }
- else
- {
- currentSize = source.currentSize;
- /*
- value = new int[MAX_STATE_SIZE];
- for(int i=0;i<currentSize;i++)
- {
- value[i] = source.value[i];
- }
- */
- value = source.value;
- source.value = 0; /* to avoid the destruction */
- }
- }
-
- State::State(int tailleUtile)
- {
- #ifdef STATE_DEBUG
- State::nbAlive++;
- State::nbCreated++;
- #endif
-
- if ( (tailleUtile==0)||(tailleUtile>MAX_STATE_SIZE))
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 1;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(1);
- #else
- State::terminate();
- #endif
- }
- else
- {
- currentSize = tailleUtile;
- value = new int[MAX_STATE_SIZE];
- }
- }
-
- State::~State()
- {
- #ifdef STATE_TRACE
- cout << "State::~State" << endl;
- #endif
- #ifdef STATE_DEBUG
- State::nbAlive--;
- #endif
- if (value)
- {
- #if STATE_OLD_COMPILER == 0
- delete [] value;
- #else
- delete value;
- #endif
- }
- }
-
- #ifdef STATE_DEBUG
- int State::getStackSize()
- {
- return pile->size();
- }
- int State::getNbAlive()
- {
- return State::nbAlive;
- }
- long State::getNbCreated()
- {
- return State::nbCreated;
- }
- #endif
-
- void State::display(char* phrase)
- {
- #if STATE_SYSTEME == STATE_WINDOWS
- char msgTexte[100];
- char tmpBuff [20];
- #endif
-
-
- int i;
- #if STATE_SYSTEME == STATE_DOS
- if (phrase)
- {
- cout << phrase << " ";
- }
- cout << "State value : ";
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- if(phrase)
- {
- strcpy(msgTexte,phrase);
- strcat(msgTexte,"\tState value [ ");
- }
- else
- {
- strcpy(msgTexte,"State value [ ");
- }
- #endif
- for(i=0;i<currentSize;i++)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << value[i];
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- itoa(value[i],tmpBuff,10);
- strcat(msgTexte,tmpBuff);
- #endif
- if (i<currentSize-1)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << " , ";
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- strcat(msgTexte,",");
- #endif
- }
- }
- #if STATE_SYSTEME == STATE_DOS
- cout << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- strcat(msgTexte,"]");
- MessageBox(0,msgTexte,"STATE VALUE",MB_OK);
- #endif
- }
-
- void State::warning(char* message)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << message << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- MessageBox(0,message,"STATE WARNING",MB_OK);
- #endif
- }
-
- void State::set(int rang, int stateCode)
- {
- if ((rang<currentSize)&&(rang>=0))
- {
- value[rang]=stateCode;
- }
- else
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 2;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(2);
- #else
- State::terminate();
- #endif
- }
- }
-
- State* State::estPermise(int classCode,int methodCode,int light)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::estPermise(classCode["<< classCode <<"],methodCode["<< methodCode <<"])" << endl;
- #endif
- #endif
- /* ================================================== */
- /* ===== controle effectif de la permission. ===== */
- /* ===== Le "classCode" est utilise pour savoir ===== */
- /* ===== ou commencer la recherche. ===== */
- /* ================================================== */
-
-
- int rang;
- int etat;
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- int etatSvg;
- #endif
- #endif
- int permi;
- int interdit;
- int rangPermi; /* rang correspond au package */
- int rangInterdit; /* rang correspond au package */
- int statePermi; /* code de l'etat dans la classe */
- int stateInterdit;/* code de l'etat dans la classe*/
- int code;
- int currentClass;
-
- permi = 0;
- interdit = 0;
- #ifdef STATE_TRACE
- this->display();
- #endif
- /* ==================================== */
- /* ===== RECHERCHE SI EST-PERMISE ===== */
- /* ==================================== */
- rang = 0;
- while( (rang<currentSize)&&(!permi) )
- {
- etat = value[rang];
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- etatSvg = etat;
- #endif
- #endif
- /*=== Balayage des champs de l'etat courant ===== */
- while( (etat!=NOT_A_STATE)&&(!permi) )
- {
- int i;
-
- /* === recherche de la classe definissant l'etat === */
- /* === actuellement analyse === */
- /* ===== ANCIENNE VERSION: Heritage simple ===== */
- // currentClass = classCode; /* la recherche commence en bas */
- // while((currentClass>=0)&&
- // State::tabPermise[
- // currentClass*MAX_STATES*MAX_METHOD_BY_STATE*2
- // + etat*MAX_METHOD_BY_STATE*2
- // ] == NOT_DEFINED)
- // {
- // currentClass = State::tabClassAnc[currentClass*MAX_ANC_CLASSES];
- // }
- //
- /* ===== NOUVELLE VERSION ===== */
- currentClass = State::classeDefiniEtatP(classCode,etat);
- /* ============================ */
-
- if (currentClass<0)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << "EstPermise/allowance: No class defines the state " << etat << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- MessageBox(0,"EstPermise/allowance: No class defines the recherched state","STATE EST PERMISE",MB_OK);
- #endif
- exit(1);
- }
-
- /* === balayage des methodes permises === */
- i=0;
- while( (!permi)&&
- (State::tabPermise[
- currentClass*MAX_STATES*MAX_METHOD_BY_STATE*2
- + (etat*MAX_METHOD_BY_STATE+i)*2
- ] != NOT_A_METHOD)
- )
- {
- if (State::tabPermise[
- currentClass*MAX_STATES*MAX_METHOD_BY_STATE*2
- + (etat*MAX_METHOD_BY_STATE+i)*2
- ] == methodCode)
- {
- permi = currentClass+1; /* pour memoriser le niveau d'acceptation dans le package */
- rangPermi = rang; /* et tester si il y a eu redefinition dans le meme pachage */
- statePermi=etat; /* en cas d'etats contradictoires dans la meme classe suite a une fusion */
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "Method accepted in the class : " << currentClass ;
- cout << " in the package : " << rang ;
- cout << " by the state : " << etat << endl;
- #endif
- #endif
- code = State::tabPermise[
- currentClass*MAX_STATES*MAX_METHOD_BY_STATE*2
- + ((etat*MAX_METHOD_BY_STATE+i)*2)+1
- ];
- }
- else
- {
- i++;
- }
- }
- /* passage a la suite ssi ... */
- if(!permi)
- {
- etat = State::tabAncestor[etat];
- }
- }
- rang++;
- } /* fin du while*/
-
- /* ====================================== */
- /* ===== RECHERCHE SI EST-INTERDITE ===== */
- /* ====================================== */
- rang = 0;
- while( (rang<currentSize)&&(!interdit) )
- {
- etat = value[rang];
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- etatSvg = etat;
- #endif
- #endif
- /*=== recherche de l'interdiction de la methode ===== */
- while( (etat!=NOT_A_STATE) && (!interdit) )
- {
- int i;
-
- /* === recherche de la classe definissant l'etat === */
- /* === actuellement analyse === */
- /* ===== ANCIENNE VERSION: HEritage simple ===== */
- // currentClass = classCode; /* la recherche commence en bas */
- // while((currentClass>=0)&&
- // State::tabInterdite[
- // currentClass*MAX_STATES*MAX_METHOD_BY_STATE
- // + etat*MAX_METHOD_BY_STATE
- // ] == NOT_DEFINED)
- // {
- // currentClass = State::tabClassAnc[currentClass*MAX_ANC_CLASSES];
- // }
- /* ===== NOUVELLE VERSION ===== */
- currentClass = State::classeDefiniEtatI(classCode,etat);
- /* ============================ */
-
- if (currentClass<0)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << "EstPermise/refused: No class defines the state " << etat << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- MessageBox(0,"EstPermise/refused: No class defines the recherched state","STATE EST PERMISE",MB_OK);
- #endif
- exit(1);
- }
-
- /* === balayage des methodes interdites === */
- i=0;
- while( (!interdit)&&
- (State::tabInterdite[
- currentClass*MAX_STATES*MAX_METHOD_BY_STATE
- + (etat*MAX_METHOD_BY_STATE+i)
- ] != NOT_A_METHOD)
- )
- {
- if (State::tabInterdite[
- currentClass*MAX_STATES*MAX_METHOD_BY_STATE
- + (etat*MAX_METHOD_BY_STATE+i)
- ] == methodCode)
- {
- interdit = (currentClass+1); /* memoriser le niveau de refus dans le package */
- rangInterdit = rang; /* et tester si il y a eu redefinition dans le meme pachage */
- stateInterdit=etat; /* en cas d'etats contradictoires dans la meme classe suite a une fusion */
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "Methode refused in the class : " << currentClass ;
- cout << " in the package : " << rang;
- cout << " by the state : " << etat << endl;
- #endif
- #endif
- }
- else
- {
- i++;
- }
- }
- /* passage a la suite ssi ... */
- if (!interdit)
- {
- etat = State::tabAncestor[etat];
- }
- }
- rang++;
- } /* fin du while*/
-
- /* ==================== */
- /* ===== RESULTAT ===== */
- /* ==================== */
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "Allowed : " << permi << endl;
- cout << " package : " << rangPermi << endl;
- cout << " state : " << statePermi << endl;
- cout << "Refused : " << interdit << endl;
- cout << " package : " << rangInterdit << endl;
- cout << " state : " << stateInterdit << endl;
- #endif
- #endif
- if ( (!permi)
- ||( interdit /* erreur si interdit et */
- &&(interdit>permi)&&(rangPermi==rangInterdit) /* redef dans le meme package */
- )
- ||( interdit /* erreur si interdit et */
- &&(rangInterdit!=rangPermi) /* permi dans un autre package */
- )
- ||( interdit
- &&(rangInterdit==rangPermi) /* erreur permi et interdi dans*/
- &&(etatDescendDe(stateInterdit,statePermi)) /* le meme package mais interdi*/
- ) /* est fil de permi */
- )
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "ERREUR : Method " << methodCode << " refused in the state " << etatSvg << endl;
- #endif
- #endif
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 6;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateBehaviorError(6);
- #else
- State::terminate();
- #endif
- }
- #if STATE_LIGHT == 0
- if(!light)
- {
- /* ============== memoriser pour "estCorrecte" ============= */
- /* Normalement, quand l'objet temporaire "this" est detruit */
- /* dans la methode qui appelle "estPermise", le destructeur */
- /* "State::~State" n'est pas appelle. De ce fait, le contenu */
- /* du "StateListElem" cree dans "StateList::addLast" n'est */
- /* pas detruit!! */
- State::pile->addLast(new State(*this),code);
- }
- #endif
- return this;
- }
-
- #if STATE_LIGHT == 0
- State* State::estCorrecte()
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::estCorrecte()" << endl;
- #endif
- #endif
-
- /* Tant que le controle n'est pas reactive pour la classe */
- /* des objets consideres, getCurrentState retourne des etats */
- /* invalides qui ne sont pas empiles dans "estPermise". De ce*/
- /* fait, il est inutile de depiler!! */
-
- State* avant = State::pile->getLastState();
- int code = State::pile->getLastCode();
-
- /* == controle effectif de la correction == */
- if (code>=0)
- {
- int rang;
- int etat;
- int i;
- int correct=0;
-
- if (State::tabExitStates[code*MAX_EXIT_STATE]==SAME_STATE)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << " ==> REAL TEST [SAME]" << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- MessageBox(0,"REAL TEST because SAME_STATE","STATE EST CORRECTE",MB_OK);
- #endif
- #endif
- /* l'arite de l'etat ne doit pas avoir changee */
- correct=(currentSize==avant->currentSize);
- /* normalement la facon dont est calcule l'etat reste la meme */
- /* ATTENTION : A verifier si heritage multiple !! */
- /* de ce fait, chaque composant du nouvel etat doit descendre */
- /* de son pendant dans l'etat de depart. */
- for(rang=0;(rang<currentSize)&&(correct);rang++)
- {
- correct = etatDescendDe(value[rang],avant->value[rang]);
- }
- }
- else
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << " ==> REAL TEST [TRANSITION] (" << code << ")" << endl;
- #endif
- #endif
- rang = 0;
- while( (rang<currentSize)&&(!correct) )
- {
- etat = value[rang];
- i = 0;
- while( (State::tabExitStates[code*MAX_EXIT_STATE+i]!=NOT_A_STATE)&&(!correct) )
- {
- if (etatDescendDe(etat,State::tabExitStates[code*MAX_EXIT_STATE+i])) { correct=1; }
- else { i++; }
- }
- rang++;
- }
- }
- if (!correct)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "ERROR : incorrect transition (code = " << code << " )" << endl;
- #endif
- #endif
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 7;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateBehaviorError(7);
- #else
- State::terminate();
- #endif
- }
- }
- else
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 10;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(10);
- #else
- State::terminate();
- #endif
- }
- /* ========== */
- State::pile->removeLast();
- return this;
- }
- #endif
-
- State* State::estInitial(int classCode)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::estInitial" << endl;
- #endif
- #endif
-
- int i,rang,ok;
-
- if (tabInitial[classCode*MAX_INIT_STATE]==NOT_A_STATE)
- {
- return this; /* ok car alors par defaut ils sont TOUS initiaux !! */
- }
-
- for (rang=0;rang<currentSize;rang++)
- {
- i = 0;
- ok = 0;
- while ( (tabInitial[classCode*MAX_INIT_STATE+i]!=NOT_A_STATE)
- &&(i<MAX_INIT_STATE)
- &&(!ok)
- )
- {
- if (value[rang]==tabInitial[classCode*MAX_INIT_STATE+i])
- {
- /* ok l'etat est initial. */
- /* sortie du "while" et passage au "for" suivant */
- ok = 1;
- }
- else
- {
- i++;
- if (i==MAX_INIT_STATE)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 4;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(4);
- #else
- State::terminate();
- #endif
- }
- }
- }
- if (!ok)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 3;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateBehaviorError(3);
- #else
- State::terminate();
- #endif
- }
- }
- return this;
- }
-
- State* State::estFinal(int classCode)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::estFinal" << endl;
- #endif
- #endif
-
- int i,rang,ok;
-
- if (tabFinal[classCode*MAX_FINA_STATE]==NOT_A_STATE)
- {
- return this; /* ok car alors par defaut ils sont TOUS finaux !! */
- }
-
- for (rang=0;rang<currentSize;rang++)
- {
- i = 0;
- ok = 0;
-
- while ( (tabFinal[classCode*MAX_FINA_STATE+i]!=NOT_A_STATE)
- &&(i<MAX_FINA_STATE)
- &&(!ok)
- )
- {
- if (value[rang]==tabFinal[classCode*MAX_FINA_STATE+i])
- {
- /* ok l'etat est initial. */
- /* sortie du "while" et passage au "for" suivant */
- ok = 1;
- }
- else
- {
- i++;
- if (i==MAX_FINA_STATE)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 4;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(4);
- #else
- State::terminate();
- #endif
- }
- }
- }
- if (!ok)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 4;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateBehaviorError(4);
- #else
- State::terminate();
- #endif
- }
- }
- return this;
- }
-
- int State::rang(int etat)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::rang(int etat)" << endl;
- #endif
- #endif
-
- int result=-1;
- int i;
- for(i=0;i<currentSize;i++)
- {
- if (value[i]==etat)
- {
- result=i;
- }
- }
- return result;
- }
-
- int State::etendre()
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::etendre()" << endl;
- #endif
- #endif
-
- if (currentSize == MAX_STATE_SIZE)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 3;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(3);
- #else
- State::terminate();
- #endif
- }
- else
- {
- currentSize++;
- }
- return currentSize-1; // car directement utilise
- }
-
- void State::terminate(void)
- {
- extern char* BehaviorErrorMsg[];
- #if STATE_SYSTEME == STATE_DOS
- cout << "STATE TERMINATE" << endl;
- #if STATE_USE_EXCEPT == 1
- cout << "Error while treating the exception ('stack rollout')" << endl;
- cout << "Initial error:" << endl;
- #endif
- cout << " code = " << State::globalError << endl;
- cout << " texte = " << BehaviorErrorMsg[State::globalError] << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- char texte [512];
- strcpy(texte,"Error while treating the exception ('stack rollout')\n");
- strcat(texte,BehaviorErrorMsg[State::globalError]);
- MessageBox(0,texte,"STATE TERMINATE",MB_OK);
- #endif
- abort();
- }
- #ifdef STATE_DEBUG
- void State::memoryError(void)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << endl << "STATE MEMORY ERROR" << endl;
- State::audit();
- #endif
- #if STATE_SYSTEME == STATE_DOS
- #if STATE_COMPILER == STATE_BORLAND
- cout << "Available memory : " << coreleft() << endl;
- cout << " " << farcoreleft() << endl;
- if(heapcheck()== _HEAPCORRUPT)
- {
- cout << "Heap is corrupted !!!" << endl;
- }
- else
- {
- cout << "Heap is OK" << endl;
- }
- #endif
- #endif
- #if STATE_SYSTEME == STATE_DOS
- cout << "Out of memory program aborted !!" << endl;
- #endif
- #if STATE_SYSTEME == STATE_WINDOWS
- MessageBox(0,"Out of memory program aborted !!","STATE MEMORY",MB_OK);
- #endif
- abort();
- }
- void State::audit(void)
- {
- #if STATE_SYSTEME == STATE_DOS
- cout << endl << "STATE AUDIT" << endl;
- cout << "State stack size : " << State::getStackSize() << endl;
- cout << "Living states : " << nbAlive << endl;
- cout << "Total created states: " << nbCreated << endl;
- #endif
- }
-
- #endif
- void State::invalidateCtrlFor(void* ptrObj)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::invalidateCtrlFor(void* ptrObj)" << endl;
- #endif
- #endif
-
- /* ===== test si possible ===== */
- if (nbInvalidated==MAXINVALIDATE-1)
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 7;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(7);
- #else
- State::terminate();
- #endif
- }
- /* ========================== ajouter ========================== */
- /* Il est inutile de rechercher si deja car il faut memoriser a */
- /* chaque fois pour le cas ou dans un constructeur d'une classe */
- /* FOO, des instances de la classe FOO sont construites (par */
- /* exemple) comme attributs. */
- /* ============================================================= */
- invalidateCtrl[nbInvalidated] = ptrObj;
- nbInvalidated++;
- }
-
- void State::activateCtrlFor(void* ptrObj)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::activateCtrlFor(void* ptrObj)" << endl;
- #endif
- #endif
- int i = 0;
- int trouve = -1;
- /* ========= recherche si effectivement ========== */
- while(i<nbInvalidated)
- {
- if (invalidateCtrl[i]==ptrObj)
- {
- trouve = i;
- break;
- }
- i++;
- }
- if(trouve>-1)
- {
- if (trouve==nbInvalidated-1)
- {
- invalidateCtrl[trouve]=0;
- }
- else
- {
- invalidateCtrl[trouve]=invalidateCtrl[nbInvalidated-1];
- invalidateCtrl[nbInvalidated-1]=0;
- }
- nbInvalidated--;
- }
- else
- {
- if (!State::globalError)
- { /* pour ne pas perdre la cause initiale de l'erreur */
- State::globalError = 9;
- }
- #if STATE_USE_EXCEPT == 1
- throw StateInternalError(9);
- #else
- State::terminate();
- #endif
- }
- }
-
- int State::testActivatedFor(void* ptrObj)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::testActivatedFor(void* ptrObj)" << endl;
- #endif
- #endif
- int i = 0;
- /* ===== recherche si present ===== */
- while(i<nbInvalidated)
- {
- if (invalidateCtrl[i]==ptrObj)
- {
- return 0;
- }
- i++;
- }
- return 1;
- }
- /* Les methodes ci-dessous sont plus des fonctions libres de service que */
- /* de veritables metodes. Cependant, pour qu'elles portent le meme nom */
- /* que les veritables methodes de la classe "State" (pour limiter les */
- /* collisions de noms), elles ont ete declarees en tant que methodes. */
-
- int State::etatDescendDe(int fils, int pere)
- {
- #ifdef STATE_TRACE
- #if STATE_SYSTEME == STATE_DOS
- cout << "State::etatDescendDe(fils(" << fils << "),pere(" << pere << ") )" << endl;
- #endif
- #endif
- while( (fils!=NOT_A_STATE)&&(fils!=pere) )
- {
- fils = State::tabAncestor[fils];
- }
- return (fils!=NOT_A_STATE);
- }
-
- int State::classeDefiniEtatP(int codeClasse, int codeState)
- {
- int classAncetre;
- int result = NOT_A_CLASS;
- /* ==== recherche locale ==== */
- if( (codeClasse>=0)
- && (State::tabPermise[codeClasse*MAX_STATES*MAX_METHOD_BY_STATE*2
- + codeState*MAX_METHOD_BY_STATE*2
- ] != NOT_DEFINED)
- )
- {
- return codeClasse;
- }
- else
- /* ==== recherche parmi les ancetres */
- {
- int i = 0;
- classAncetre = State::tabClassAnc[codeClasse*MAX_ANC_CLASSES+i];
- while(classAncetre!=NOT_A_CLASS)
- {
- result = classeDefiniEtatP(classAncetre,codeState);
- if(result!=NOT_A_CLASS)
- {
- return result;
- }
- else
- {
- i++;
- classAncetre = State::tabClassAnc[codeClasse*MAX_ANC_CLASSES+i];
- }
- }
- }
- return NOT_A_CLASS;
- }
-
- int State::classeDefiniEtatI(int codeClasse, int codeState)
- {
- int classAncetre;
- int result = NOT_A_CLASS;
- /* ==== recherche locale ==== */
- if( (codeClasse>=0)
- && (State::tabInterdite[codeClasse*MAX_STATES*MAX_METHOD_BY_STATE
- + codeState*MAX_METHOD_BY_STATE
- ] != NOT_DEFINED)
- )
- {
- return codeClasse;
- }
- else
- /* ==== recherche parmi les ancetres */
- {
- int i = 0;
- classAncetre = State::tabClassAnc[codeClasse*MAX_ANC_CLASSES+i];
- while(classAncetre!=NOT_A_CLASS)
- {
- result = classeDefiniEtatI(classAncetre,codeState);
- if(result!=NOT_A_CLASS)
- {
- return result;
- }
- else
- {
- i++;
- classAncetre = State::tabClassAnc[codeClasse*MAX_ANC_CLASSES+i];
- }
- }
- }
- return NOT_A_CLASS;
- }
-
-