0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / LibCtl / LibCtl_Library.gxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //#include <LibCtl_Library.ixx>
16 #include <Standard_NoSuchObject.hxx>
17
18
19 //  Liste Globale des Modules, dans laquelle on va se servir
20
21 static Handle(LibCtl_GlobalNode) theglobal;
22
23 //  Donnees pour optimisation (dernier Protocole demande)
24
25 static Handle(TheProtocol) theprotocol;
26 static Handle(LibCtl_Node) thelast;
27
28
29 //  Alimentation de la liste globale
30 //  ATTENTION : SetGlobal fait de la substitution, c-a-d que c est le dernier
31 //   qui a raison pour un Protocol donne
32     void LibCtl_Library::SetGlobal
33   (const Handle(TheModule)& amodule, const Handle(TheProtocol)& aprotocol)
34 {
35   if (theglobal.IsNull()) theglobal = new LibCtl_GlobalNode;
36   theglobal->Add(amodule,aprotocol);
37 }
38
39 // Constructeur d apres Protocole
40     LibCtl_Library::LibCtl_Library (const Handle(TheProtocol)& aprotocol)
41 {
42   Standard_Boolean last = Standard_False;
43   if (aprotocol.IsNull()) return;    // PAS de protocole = Lib VIDE
44   if (!theprotocol.IsNull()) last =
45     (theprotocol == aprotocol);
46
47   if (last) thelist = thelast;
48 //  Si Pas d optimisation disponible : construire la liste
49   else {
50     AddProtocol(aprotocol);
51 //  Ceci definit l optimisation (pour la fois suivante)
52     thelast     = thelist;
53     theprotocol = aprotocol;
54   }
55 }
56
57 //  Constructeur vide
58     LibCtl_Library::LibCtl_Library ()    {  }
59
60
61 //  Ajout d un Protocol : attention, desoptimise (sinon risque de confusion !)
62     void LibCtl_Library::AddProtocol
63   (const Handle(Standard_Transient)& aprotocol)
64 {
65 //  DownCast car Protocol->Resources, meme redefini et utilise dans d autres
66 //  librairies, doit toujours renvoyer le type le plus haut
67   Handle(TheProtocol) aproto = Handle(TheProtocol)::DownCast(aprotocol);
68   if (aproto.IsNull()) return;
69
70 //  D abord, ajouter celui-ci a la liste : chercher le Node
71   Handle(LibCtl_GlobalNode) curr;
72   for (curr = theglobal; !curr.IsNull(); ) {        // curr->Next : plus loin
73     const Handle(TheProtocol)& protocol = curr->Protocol();
74     if (!protocol.IsNull()) {
75 //  Match Protocol ?
76       if (protocol->DynamicType() == aprotocol->DynamicType()) {
77         if (thelist.IsNull()) thelist = new LibCtl_Node;
78         thelist->AddNode(curr);
79         break;  // UN SEUL MODULE PAR PROTOCOLE
80       }
81     }
82     curr = curr->Next();  // cette formule est refusee dans "for"
83   }
84 //  Ensuite, Traiter les ressources
85   Standard_Integer nb = aproto->NbResources();
86   for (Standard_Integer i = 1; i <= nb; i ++) {
87     AddProtocol (aproto->Resource(i));
88   }
89 //  Ne pas oublier de desoptimiser
90   theprotocol.Nullify();
91   thelast.Nullify();
92 }
93
94     void LibCtl_Library::Clear ()
95       {  thelist = new LibCtl_Node;  }
96
97     void LibCtl_Library::SetComplete ()
98 {
99   thelist = new LibCtl_Node;
100 //    On prend chacun des Protocoles de la Liste Globale et on l ajoute
101   Handle(LibCtl_GlobalNode) curr;
102   for (curr = theglobal; !curr.IsNull(); ) {        // curr->Next : plus loin
103     const Handle(TheProtocol)& protocol = curr->Protocol();
104 //    Comme on prend tout tout tout, on ne se preoccupe pas des Ressources !
105     if (!protocol.IsNull()) thelist->AddNode(curr);
106     curr = curr->Next();  // cette formule est refusee dans "for"
107   }
108 }
109
110
111 //  Selection : Tres fort, on retourne le Module correspondant a un Type
112 //  (ainsi que le CaseNumber retourne par le protocole correspondant)
113
114     Standard_Boolean LibCtl_Library::Select
115   (const TheObject& obj,
116    Handle(TheModule)& module, Standard_Integer& CN) const
117 {
118   module.Nullify();  CN = 0;    // Reponse "pas trouve"
119   if (thelist.IsNull()) return Standard_False;
120   Handle(LibCtl_Node) curr = thelist;
121   for (curr = thelist; !curr.IsNull(); ) {        // curr->Next : plus loin
122     const Handle(TheProtocol)& protocol = curr->Protocol();
123     if (!protocol.IsNull()) {
124       CN = protocol->CaseNumber(obj);
125       if (CN > 0) {
126         module = curr->Module();
127         return Standard_True;
128       }
129     }
130     curr = curr->Next();        // cette formule est refusee dans "for"
131   }
132   return Standard_False;        // ici, pas trouce
133 }
134
135
136 //  ....                        Iteration                        ....
137
138     void LibCtl_Library::Start ()
139       {  thecurr = thelist;  }
140
141     Standard_Boolean LibCtl_Library::More () const
142       {  return (!thecurr.IsNull());  }
143
144     void LibCtl_Library::Next ()
145       {  if (!thecurr.IsNull()) thecurr = thecurr->Next();  }
146
147     const Handle(TheModule)& LibCtl_Library::Module () const
148 {
149   if (thecurr.IsNull()) throw Standard_NoSuchObject("Library from LibCtl");
150   return thecurr->Module();
151 }
152
153     const Handle(TheProtocol)& LibCtl_Library::Protocol () const
154 {
155   if (thecurr.IsNull()) throw Standard_NoSuchObject("Library from LibCtl");
156   return thecurr->Protocol();
157 }