1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13 
14 
15 #include <Interface_STAT.hxx>
16 #include <TCollection_AsciiString.hxx>
17 #include <TCollection_HAsciiString.hxx>
18 
19 static Interface_STAT statvoid("");
20 static Interface_STAT statact ("");
21 static Standard_CString voidname = "";
22 
Interface_STAT(const Standard_CString title)23     Interface_STAT::Interface_STAT (const Standard_CString title)
24 {
25   thetitle = new TCollection_HAsciiString(title);
26   thetotal = 1.;
27 }
28 
Interface_STAT(const Interface_STAT & other)29     Interface_STAT::Interface_STAT (const Interface_STAT& other)
30 {  other.Internals (thetitle,thetotal, thephnam,thephw, thephdeb,thephfin, thestw);  }
31 
Internals(Handle (TCollection_HAsciiString)& tit,Standard_Real & total,Handle (TColStd_HSequenceOfAsciiString)& phn,Handle (TColStd_HSequenceOfReal)& phw,Handle (TColStd_HSequenceOfInteger)& phdeb,Handle (TColStd_HSequenceOfInteger)& phfin,Handle (TColStd_HSequenceOfReal)& stw) const32     void  Interface_STAT::Internals
33   (Handle(TCollection_HAsciiString)& tit, Standard_Real& total,
34    Handle(TColStd_HSequenceOfAsciiString)& phn,
35    Handle(TColStd_HSequenceOfReal)& phw,
36    Handle(TColStd_HSequenceOfInteger)& phdeb,
37    Handle(TColStd_HSequenceOfInteger)& phfin,
38    Handle(TColStd_HSequenceOfReal)& stw) const
39 {
40   tit   = thetitle;  total = thetotal;  phn = thephnam;  phw = thephw;
41   phdeb = thephdeb;  phfin = thephfin;  stw = thestw;
42 }
43 
AddPhase(const Standard_Real weight,const Standard_CString name)44     void  Interface_STAT::AddPhase
45   (const Standard_Real weight, const Standard_CString name)
46 {
47   if (thephw.IsNull()) {
48 //  1re fois : vider les steps deja notees
49     thetotal = 0.;
50     thephnam = new TColStd_HSequenceOfAsciiString();
51     thephw    = new TColStd_HSequenceOfReal();
52     thephdeb  = new TColStd_HSequenceOfInteger();
53     thephfin  = new TColStd_HSequenceOfInteger();
54     thestw    = new TColStd_HSequenceOfReal();
55   }
56   thetotal += weight;
57   thephnam->Append (TCollection_AsciiString (name));
58   thephw->Append    (weight);
59   thephdeb->Append (thestw->Length()+1);
60   thephfin->Append (0);
61   thestw->Append   (0.);
62 }
63 
AddStep(const Standard_Real weight)64     void  Interface_STAT::AddStep (const Standard_Real weight)
65 {
66   if (thephdeb.IsNull()) {
67 // 1re fois : pour default phase, au moins creer receptacle des steps
68     thephdeb  = new TColStd_HSequenceOfInteger();
69     thephfin  = new TColStd_HSequenceOfInteger();
70     thestw    = new TColStd_HSequenceOfReal();
71     thephdeb->Append (thestw->Length()+1);
72     thephfin->Append (1);
73     thestw->Append   (0.);
74   }
75 //  A present, ajouter cette etape
76   Standard_Integer n0 = thephdeb->Value (thephdeb->Length());
77 //  Ceci donne dans thestw le numero du cumul des etapes
78   thestw->ChangeValue (n0) += weight;
79   thestw->Append   (weight);  // on ajoute cette etape
80   thephfin->ChangeValue (thephfin->Length()) ++;
81 }
82 
83 
Description(Standard_Integer & nbphases,Standard_Real & total,Standard_CString & title) const84     void  Interface_STAT::Description
85   (Standard_Integer& nbphases,
86    Standard_Real& total, Standard_CString& title) const
87 {
88   nbphases = (thephw.IsNull() ? 1 : thephw->Length());
89   total = thetotal;
90   title = thetitle->ToCString();
91 }
92 
Phase(const Standard_Integer num,Standard_Integer & n0step,Standard_Integer & nbstep,Standard_Real & weight,Standard_CString & name) const93     void  Interface_STAT::Phase
94   (const Standard_Integer num,
95    Standard_Integer& n0step, Standard_Integer& nbstep,
96    Standard_Real& weight, Standard_CString& name) const
97 {
98   if (thephdeb.IsNull()) {
99 //  Pas de phase, pas d etape ... donc une seule ...
100     n0step = -1;  nbstep = 1;  weight = 1.;  name = voidname;
101   }
102   if (thephw.IsNull()) {
103 //  Pas de phase mais des etapes
104     weight = 1.;  name = voidname;
105   } else if (num < 1 || num > thephdeb->Length()) return;
106   else  {
107 //  Phase
108     weight = thephw->Value(num);  name = thephnam->Value(num).ToCString();
109     n0step = thephdeb->Value(num);
110     nbstep = thephfin->Value(num);
111   }
112 
113 //  Voyons pour cette phase
114 }
115 
Step(const Standard_Integer num) const116     Standard_Real  Interface_STAT::Step (const Standard_Integer num) const
117 {
118   if (thestw.IsNull()) return 1.;
119   if (num < 1 || num > thestw->Length()) return 1.;
120   return thestw->Value(num);
121 }
122 
123 //  ###############  COMPTAGE  ################
124 
125 //  Le comptage se fait sur la base suivante :
126 //  TOTAL  : total des poids des phases par rapport auquel calculer
127 //  PHASES : poids des phases passees  et  poids de la phase en cours
128 //    Ces poids sont a ramener au TOTAL
129 //  PHASE COURANTE : nb d items  et  nb de cycles declares
130 //    Nb d items deja passes (cycle complet)
131 //  CYCLE COURANT  : nb d items  de ce cycle, total des poids des etapes
132 //    Poids des etapes deja passees, de l etape en cours, n0 etape en cours
133 //  ETAPE COURANTE : nb d items deja passes
134 
135 static struct zestat {
136  Standard_CString itle, name;
137  Standard_Real otal,  // total des poids des phases
138   oldph,  // poids des phases deja passes
139   phw,    // poids de la phase en cours
140   otph,   // poids des etapes de la phase en cours (cycle en cours)
141   oldst,  // poids des etapes deja passees (cycle en cours)
142   stw;    // poids etape en cours
143  Standard_Integer nbph, // total nb de phases
144   numph,  // n0 phase en cours
145   n0, n1, // n0 et nb etapes dans phase en cours
146   nbitp,  // nb items total phase
147   nbcyc,  // nb cycles total phase
148   olditp, // nb items deja passes (cycles passes) / phase
149   numcyc, // n0 cycle en cours / phase
150   nbitc,  // nb items cycle en cours
151   numst,  // n0 etape en cours / cycle
152   numitem; // nb items deja passes / etape courante
153 } TheStat;
154 
155 
Start(const Standard_Integer items,const Standard_Integer cycles) const156     void  Interface_STAT::Start
157   (const Standard_Integer items, const Standard_Integer cycles) const
158 {
159   statact = *this;
160   statact.Description (TheStat.nbph, TheStat.otal, TheStat.itle);
161   TheStat.oldph = TheStat.phw = 0.;  TheStat.numph = 0;
162   NextPhase (items,cycles);
163 }
164 
StartCount(const Standard_Integer items,const Standard_CString name)165     void  Interface_STAT::StartCount
166   (const Standard_Integer items, const Standard_CString name)
167 {
168   Interface_STAT statcount(name);
169   statcount.Start (items);
170 }
171 
NextPhase(const Standard_Integer items,const Standard_Integer cycles)172     void  Interface_STAT::NextPhase
173   (const Standard_Integer items, const Standard_Integer cycles)
174 {
175 //  On cumule la phase precedente au total, on efface les donnees "locales"
176 	TheStat.numcyc  = TheStat.numst = TheStat.olditp = 0;  TheStat.oldst = TheStat.stw = 0.;
177   if (TheStat.numph >= TheStat.nbph) {  End();  return;  }
178 
179   TheStat.numph ++;  TheStat.oldph += TheStat.phw;   // cumule sur cette phase
180   TheStat.nbitp = items;  TheStat.nbcyc = cycles;
181   statact.Phase(TheStat.numph, TheStat.n0, TheStat.n1, TheStat.phw, TheStat.name);
182   TheStat.otph = (TheStat.n1 > 1 ? statact.Step (TheStat.n0) : 1.);
183 //   si un seul cycle, on le demarre; sinon, attendre NextCycle
184   TheStat.nbitc = 0;
185   if (cycles == 1) NextCycle (items);
186 }
187 
SetPhase(const Standard_Integer items,const Standard_Integer cycles)188     void  Interface_STAT::SetPhase
189   (const Standard_Integer items, const Standard_Integer cycles)
190       {  TheStat.nbitp = items;  TheStat.nbcyc = cycles;  }
191 
NextCycle(const Standard_Integer items)192     void  Interface_STAT::NextCycle (const Standard_Integer items)
193 {
194 //  cumul de ce cycle sur les cycles deja passes, raz etapes
195   TheStat.numcyc ++;  TheStat.olditp += TheStat.nbitc;
196 //  if (stat.olditem > stat.nbitp) return;
197   TheStat.numst = 1;
198   TheStat.oldst = 0.;
199   TheStat.stw   = (TheStat.n1 > 1 ? statact.Step(TheStat.n0 + 1) : TheStat.otph);
200   TheStat.nbitc = items;  TheStat.numitem = 0;
201 }
202 
NextStep()203     void  Interface_STAT::NextStep ()
204 {
205   if (TheStat.numst >= TheStat.n1) return;
206   TheStat.numst ++;  TheStat.oldst += TheStat.stw;
207   TheStat.numitem = 0;
208   TheStat.stw = statact.Step (TheStat.n0 + TheStat.numst);
209 }
210 
NextItem(const Standard_Integer nbitems)211     void  Interface_STAT::NextItem (const Standard_Integer nbitems)
212       {  TheStat.numitem += nbitems;  }
213 
End()214     void  Interface_STAT::End ()
215 {  TheStat.oldph = TheStat.otal;  TheStat.phw = TheStat.stw = 0.;  TheStat.itle = TheStat.name = voidname;  }
216 
217 // ###########  QUERY  ############
218 
Where(const Standard_Boolean phase)219     Standard_CString  Interface_STAT::Where   (const Standard_Boolean phase)
220       {  return (phase ? TheStat.name : TheStat.itle);  }
221 
Percent(const Standard_Boolean phase)222     Standard_Integer  Interface_STAT::Percent (const Standard_Boolean phase)
223 {
224   if (TheStat.numitem > TheStat.nbitc) TheStat.numitem = TheStat.nbitc;
225 //  on compte les items deja passes
226   Standard_Real enphase =
227     TheStat.olditp  * TheStat.otph  +  // cycles complets passes
228     TheStat.nbitc   * TheStat.oldst +  // cycle courant, etapes completes passees
229     TheStat.numitem * TheStat.stw;     // etape courante
230 //  proportion pour cette phase
231   Standard_Real prophase = enphase / (TheStat.nbitp * TheStat.otph);
232   Standard_Integer res = Standard_Integer (prophase*100.);
233   if (phase) return res;
234 
235 //  voila pour cette phase
236 //  comptage dans les phases
237   Standard_Real encours = (TheStat.oldph + TheStat.phw * prophase) / TheStat.otal;
238   res = Standard_Integer (encours * 100.);
239   return res;
240 }
241