// Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include static Interface_STAT statvoid(""); static Interface_STAT statact (""); static Standard_CString voidname = ""; Interface_STAT::Interface_STAT (const Standard_CString title) { thetitle = new TCollection_HAsciiString(title); thetotal = 1.; } Interface_STAT::Interface_STAT (const Interface_STAT& other) { other.Internals (thetitle,thetotal, thephnam,thephw, thephdeb,thephfin, thestw); } void Interface_STAT::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) const { tit = thetitle; total = thetotal; phn = thephnam; phw = thephw; phdeb = thephdeb; phfin = thephfin; stw = thestw; } void Interface_STAT::AddPhase (const Standard_Real weight, const Standard_CString name) { if (thephw.IsNull()) { // 1re fois : vider les steps deja notees thetotal = 0.; thephnam = new TColStd_HSequenceOfAsciiString(); thephw = new TColStd_HSequenceOfReal(); thephdeb = new TColStd_HSequenceOfInteger(); thephfin = new TColStd_HSequenceOfInteger(); thestw = new TColStd_HSequenceOfReal(); } thetotal += weight; thephnam->Append (TCollection_AsciiString (name)); thephw->Append (weight); thephdeb->Append (thestw->Length()+1); thephfin->Append (0); thestw->Append (0.); } void Interface_STAT::AddStep (const Standard_Real weight) { if (thephdeb.IsNull()) { // 1re fois : pour default phase, au moins creer receptacle des steps thephdeb = new TColStd_HSequenceOfInteger(); thephfin = new TColStd_HSequenceOfInteger(); thestw = new TColStd_HSequenceOfReal(); thephdeb->Append (thestw->Length()+1); thephfin->Append (1); thestw->Append (0.); } // A present, ajouter cette etape Standard_Integer n0 = thephdeb->Value (thephdeb->Length()); // Ceci donne dans thestw le numero du cumul des etapes thestw->ChangeValue (n0) += weight; thestw->Append (weight); // on ajoute cette etape thephfin->ChangeValue (thephfin->Length()) ++; } void Interface_STAT::Description (Standard_Integer& nbphases, Standard_Real& total, Standard_CString& title) const { nbphases = (thephw.IsNull() ? 1 : thephw->Length()); total = thetotal; title = thetitle->ToCString(); } void Interface_STAT::Phase (const Standard_Integer num, Standard_Integer& n0step, Standard_Integer& nbstep, Standard_Real& weight, Standard_CString& name) const { if (thephdeb.IsNull()) { // Pas de phase, pas d etape ... donc une seule ... n0step = -1; nbstep = 1; weight = 1.; name = voidname; } if (thephw.IsNull()) { // Pas de phase mais des etapes weight = 1.; name = voidname; } else if (num < 1 || num > thephdeb->Length()) return; else { // Phase weight = thephw->Value(num); name = thephnam->Value(num).ToCString(); n0step = thephdeb->Value(num); nbstep = thephfin->Value(num); } // Voyons pour cette phase } Standard_Real Interface_STAT::Step (const Standard_Integer num) const { if (thestw.IsNull()) return 1.; if (num < 1 || num > thestw->Length()) return 1.; return thestw->Value(num); } // ############### COMPTAGE ################ // Le comptage se fait sur la base suivante : // TOTAL : total des poids des phases par rapport auquel calculer // PHASES : poids des phases passees et poids de la phase en cours // Ces poids sont a ramener au TOTAL // PHASE COURANTE : nb d items et nb de cycles declares // Nb d items deja passes (cycle complet) // CYCLE COURANT : nb d items de ce cycle, total des poids des etapes // Poids des etapes deja passees, de l etape en cours, n0 etape en cours // ETAPE COURANTE : nb d items deja passes static struct zestat { Standard_CString itle, name; Standard_Real otal, // total des poids des phases oldph, // poids des phases deja passes phw, // poids de la phase en cours otph, // poids des etapes de la phase en cours (cycle en cours) oldst, // poids des etapes deja passees (cycle en cours) stw; // poids etape en cours Standard_Integer nbph, // total nb de phases numph, // n0 phase en cours n0, n1, // n0 et nb etapes dans phase en cours nbitp, // nb items total phase nbcyc, // nb cycles total phase olditp, // nb items deja passes (cycles passes) / phase numcyc, // n0 cycle en cours / phase nbitc, // nb items cycle en cours numst, // n0 etape en cours / cycle numitem; // nb items deja passes / etape courante } TheStat; void Interface_STAT::Start (const Standard_Integer items, const Standard_Integer cycles) const { statact = *this; statact.Description (TheStat.nbph, TheStat.otal, TheStat.itle); TheStat.oldph = TheStat.phw = 0.; TheStat.numph = 0; NextPhase (items,cycles); } void Interface_STAT::StartCount (const Standard_Integer items, const Standard_CString name) { Interface_STAT statcount(name); statcount.Start (items); } void Interface_STAT::NextPhase (const Standard_Integer items, const Standard_Integer cycles) { // On cumule la phase precedente au total, on efface les donnees "locales" TheStat.numcyc = TheStat.numst = TheStat.olditp = 0; TheStat.oldst = TheStat.stw = 0.; if (TheStat.numph >= TheStat.nbph) { End(); return; } TheStat.numph ++; TheStat.oldph += TheStat.phw; // cumule sur cette phase TheStat.nbitp = items; TheStat.nbcyc = cycles; statact.Phase(TheStat.numph, TheStat.n0, TheStat.n1, TheStat.phw, TheStat.name); TheStat.otph = (TheStat.n1 > 1 ? statact.Step (TheStat.n0) : 1.); // si un seul cycle, on le demarre; sinon, attendre NextCycle TheStat.nbitc = 0; if (cycles == 1) NextCycle (items); } void Interface_STAT::SetPhase (const Standard_Integer items, const Standard_Integer cycles) { TheStat.nbitp = items; TheStat.nbcyc = cycles; } void Interface_STAT::NextCycle (const Standard_Integer items) { // cumul de ce cycle sur les cycles deja passes, raz etapes TheStat.numcyc ++; TheStat.olditp += TheStat.nbitc; // if (stat.olditem > stat.nbitp) return; TheStat.numst = 1; TheStat.oldst = 0.; TheStat.stw = (TheStat.n1 > 1 ? statact.Step(TheStat.n0 + 1) : TheStat.otph); TheStat.nbitc = items; TheStat.numitem = 0; } void Interface_STAT::NextStep () { if (TheStat.numst >= TheStat.n1) return; TheStat.numst ++; TheStat.oldst += TheStat.stw; TheStat.numitem = 0; TheStat.stw = statact.Step (TheStat.n0 + TheStat.numst); } void Interface_STAT::NextItem (const Standard_Integer nbitems) { TheStat.numitem += nbitems; } void Interface_STAT::End () { TheStat.oldph = TheStat.otal; TheStat.phw = TheStat.stw = 0.; TheStat.itle = TheStat.name = voidname; } // ########### QUERY ############ Standard_CString Interface_STAT::Where (const Standard_Boolean phase) { return (phase ? TheStat.name : TheStat.itle); } Standard_Integer Interface_STAT::Percent (const Standard_Boolean phase) { if (TheStat.numitem > TheStat.nbitc) TheStat.numitem = TheStat.nbitc; // on compte les items deja passes Standard_Real enphase = TheStat.olditp * TheStat.otph + // cycles complets passes TheStat.nbitc * TheStat.oldst + // cycle courant, etapes completes passees TheStat.numitem * TheStat.stw; // etape courante // proportion pour cette phase Standard_Real prophase = enphase / (TheStat.nbitp * TheStat.otph); Standard_Integer res = Standard_Integer (prophase*100.); if (phase) return res; // voila pour cette phase // comptage dans les phases Standard_Real encours = (TheStat.oldph + TheStat.phw * prophase) / TheStat.otal; res = Standard_Integer (encours * 100.); return res; }