1*96de5490SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*96de5490SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*96de5490SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*96de5490SAndrew Rist * distributed with this work for additional information 6*96de5490SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*96de5490SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*96de5490SAndrew Rist * "License"); you may not use this file except in compliance 9*96de5490SAndrew Rist * with the License. You may obtain a copy of the License at 10*96de5490SAndrew Rist * 11*96de5490SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*96de5490SAndrew Rist * 13*96de5490SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*96de5490SAndrew Rist * software distributed under the License is distributed on an 15*96de5490SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*96de5490SAndrew Rist * KIND, either express or implied. See the License for the 17*96de5490SAndrew Rist * specific language governing permissions and limitations 18*96de5490SAndrew Rist * under the License. 19*96de5490SAndrew Rist * 20*96de5490SAndrew Rist *************************************************************/ 21*96de5490SAndrew Rist 22*96de5490SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_dbaccess.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "progressmixer.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir /** === begin UNO includes === **/ 30cdf0e10cSrcweir /** === end UNO includes === **/ 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <osl/diagnose.h> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <map> 35cdf0e10cSrcweir 36cdf0e10cSrcweir //........................................................................ 37cdf0e10cSrcweir namespace dbmm 38cdf0e10cSrcweir { 39cdf0e10cSrcweir //........................................................................ 40cdf0e10cSrcweir 41cdf0e10cSrcweir /** === begin UNO using === **/ 42cdf0e10cSrcweir /** === end UNO using === **/ 43cdf0e10cSrcweir 44cdf0e10cSrcweir #define OVERALL_RANGE 100000 45cdf0e10cSrcweir 46cdf0e10cSrcweir //==================================================================== 47cdf0e10cSrcweir //= misc types 48cdf0e10cSrcweir //==================================================================== 49cdf0e10cSrcweir struct PhaseData 50cdf0e10cSrcweir { 51cdf0e10cSrcweir // the weight of the phase, relative to all other phases 52cdf0e10cSrcweir PhaseWeight nWeight; 53cdf0e10cSrcweir // the "local" range of the phase 54cdf0e10cSrcweir sal_uInt32 nRange; 55cdf0e10cSrcweir // this is the point in the "overall range" at which this phase starts 56cdf0e10cSrcweir sal_uInt32 nGlobalStart; 57cdf0e10cSrcweir /** the "global" range of the phase, i.e. its range after weighting with all other 58cdf0e10cSrcweir phases 59cdf0e10cSrcweir */ 60cdf0e10cSrcweir sal_uInt32 nGlobalRange; 61cdf0e10cSrcweir PhaseDatadbmm::PhaseData62cdf0e10cSrcweir PhaseData() 63cdf0e10cSrcweir :nWeight(1) 64cdf0e10cSrcweir ,nRange(100) 65cdf0e10cSrcweir ,nGlobalStart(0) 66cdf0e10cSrcweir ,nGlobalRange(100) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir } 69cdf0e10cSrcweir PhaseDatadbmm::PhaseData70cdf0e10cSrcweir PhaseData( const PhaseWeight _nWeight ) 71cdf0e10cSrcweir :nWeight( _nWeight ) 72cdf0e10cSrcweir ,nRange(100) 73cdf0e10cSrcweir ,nGlobalStart(0) 74cdf0e10cSrcweir ,nGlobalRange(100) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir } 77cdf0e10cSrcweir }; 78cdf0e10cSrcweir 79cdf0e10cSrcweir typedef ::std::map< PhaseID, PhaseData > Phases; 80cdf0e10cSrcweir 81cdf0e10cSrcweir //==================================================================== 82cdf0e10cSrcweir //= ProgressMixer_Data 83cdf0e10cSrcweir //==================================================================== 84cdf0e10cSrcweir struct ProgressMixer_Data 85cdf0e10cSrcweir { 86cdf0e10cSrcweir Phases aPhases; 87cdf0e10cSrcweir Phases::iterator pCurrentPhase; 88cdf0e10cSrcweir sal_uInt32 nWeightSum; /// the cached sum of the weights 89cdf0e10cSrcweir double nOverallStretch; 90cdf0e10cSrcweir IProgressConsumer& rConsumer; 91cdf0e10cSrcweir ProgressMixer_Datadbmm::ProgressMixer_Data92cdf0e10cSrcweir ProgressMixer_Data( IProgressConsumer& _rConsumer ) 93cdf0e10cSrcweir :aPhases() 94cdf0e10cSrcweir ,pCurrentPhase( aPhases.end() ) 95cdf0e10cSrcweir ,nWeightSum( 0 ) 96cdf0e10cSrcweir ,nOverallStretch( 0 ) 97cdf0e10cSrcweir ,rConsumer( _rConsumer ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir } 100cdf0e10cSrcweir }; 101cdf0e10cSrcweir 102cdf0e10cSrcweir //-------------------------------------------------------------------- 103cdf0e10cSrcweir namespace 104cdf0e10cSrcweir { 105cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 106cdf0e10cSrcweir //---------------------------------------------------------------- lcl_isRunning(const ProgressMixer_Data & _rData)107cdf0e10cSrcweir bool lcl_isRunning( const ProgressMixer_Data& _rData ) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir return _rData.pCurrentPhase != _rData.aPhases.end(); 110cdf0e10cSrcweir } 111cdf0e10cSrcweir #endif 112cdf0e10cSrcweir //---------------------------------------------------------------- lcl_ensureInitialized(ProgressMixer_Data & _rData)113cdf0e10cSrcweir void lcl_ensureInitialized( ProgressMixer_Data& _rData ) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir OSL_PRECOND( _rData.nWeightSum, "lcl_ensureInitialized: we have no phases, this will crash!" ); 116cdf0e10cSrcweir 117cdf0e10cSrcweir if ( _rData.nOverallStretch ) 118cdf0e10cSrcweir return; 119cdf0e10cSrcweir 120cdf0e10cSrcweir _rData.nOverallStretch = 1.0 * OVERALL_RANGE / _rData.nWeightSum; 121cdf0e10cSrcweir 122cdf0e10cSrcweir // tell the single phases their "overall starting point" 123cdf0e10cSrcweir PhaseWeight nRunningWeight( 0 ); 124cdf0e10cSrcweir for ( Phases::iterator phase = _rData.aPhases.begin(); 125cdf0e10cSrcweir phase != _rData.aPhases.end(); 126cdf0e10cSrcweir ++phase 127cdf0e10cSrcweir ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir phase->second.nGlobalStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch ); 130cdf0e10cSrcweir nRunningWeight += phase->second.nWeight; 131cdf0e10cSrcweir 132cdf0e10cSrcweir sal_uInt32 nNextPhaseStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch ); 133cdf0e10cSrcweir phase->second.nGlobalRange = nNextPhaseStart - phase->second.nGlobalStart; 134cdf0e10cSrcweir } 135cdf0e10cSrcweir 136cdf0e10cSrcweir _rData.rConsumer.start( OVERALL_RANGE ); 137cdf0e10cSrcweir } 138cdf0e10cSrcweir } 139cdf0e10cSrcweir 140cdf0e10cSrcweir //==================================================================== 141cdf0e10cSrcweir //= ProgressMixer 142cdf0e10cSrcweir //==================================================================== 143cdf0e10cSrcweir //-------------------------------------------------------------------- ProgressMixer(IProgressConsumer & _rConsumer)144cdf0e10cSrcweir ProgressMixer::ProgressMixer( IProgressConsumer& _rConsumer ) 145cdf0e10cSrcweir :m_pData( new ProgressMixer_Data( _rConsumer ) ) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir } 148cdf0e10cSrcweir 149cdf0e10cSrcweir //-------------------------------------------------------------------- ~ProgressMixer()150cdf0e10cSrcweir ProgressMixer::~ProgressMixer() 151cdf0e10cSrcweir { 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir //-------------------------------------------------------------------- registerPhase(const PhaseID _nID,const PhaseWeight _nWeight)155cdf0e10cSrcweir void ProgressMixer::registerPhase( const PhaseID _nID, const PhaseWeight _nWeight ) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir OSL_PRECOND( !lcl_isRunning( *m_pData ), "ProgressMixer::registerPhase: already running!" ); 158cdf0e10cSrcweir OSL_ENSURE( m_pData->aPhases.find( _nID ) == m_pData->aPhases.end(), 159cdf0e10cSrcweir "ProgressMixer::registerPhase: ID already used!" ); 160cdf0e10cSrcweir m_pData->aPhases[ _nID ] = PhaseData( _nWeight ); 161cdf0e10cSrcweir m_pData->nWeightSum += _nWeight; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir //-------------------------------------------------------------------- startPhase(const PhaseID _nID,const sal_uInt32 _nPhaseRange)165cdf0e10cSrcweir void ProgressMixer::startPhase( const PhaseID _nID, const sal_uInt32 _nPhaseRange ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir OSL_ENSURE( m_pData->aPhases.find( _nID ) != m_pData->aPhases.end(), 168cdf0e10cSrcweir "ProgresMixer::startPhase: unknown phase!" ); 169cdf0e10cSrcweir 170cdf0e10cSrcweir m_pData->aPhases[ _nID ].nRange = _nPhaseRange; 171cdf0e10cSrcweir m_pData->pCurrentPhase = m_pData->aPhases.find( _nID ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir //-------------------------------------------------------------------- advancePhase(const sal_uInt32 _nPhaseProgress)175cdf0e10cSrcweir void ProgressMixer::advancePhase( const sal_uInt32 _nPhaseProgress ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::advancePhase: not running!" ); 178cdf0e10cSrcweir 179cdf0e10cSrcweir // in case this is the first call, ensure all the ranges/weights are calculated 180cdf0e10cSrcweir // correctly 181cdf0e10cSrcweir lcl_ensureInitialized( *m_pData ); 182cdf0e10cSrcweir 183cdf0e10cSrcweir const PhaseData& rPhase( m_pData->pCurrentPhase->second ); 184cdf0e10cSrcweir 185cdf0e10cSrcweir double nLocalProgress = 1.0 * _nPhaseProgress / rPhase.nRange; 186cdf0e10cSrcweir sal_uInt32 nOverallProgress = (sal_uInt32) 187cdf0e10cSrcweir ( rPhase.nGlobalStart + nLocalProgress * rPhase.nGlobalRange ); 188cdf0e10cSrcweir 189cdf0e10cSrcweir m_pData->rConsumer.advance( nOverallProgress ); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir //-------------------------------------------------------------------- endPhase()193cdf0e10cSrcweir void ProgressMixer::endPhase() 194cdf0e10cSrcweir { 195cdf0e10cSrcweir OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::endPhase: not running!" ); 196cdf0e10cSrcweir 197cdf0e10cSrcweir // in case this is the first call, ensure all the ranges/weights are calculated 198cdf0e10cSrcweir // correctly 199cdf0e10cSrcweir lcl_ensureInitialized( *m_pData ); 200cdf0e10cSrcweir 201cdf0e10cSrcweir // simply assume the phase's complete range is over 202cdf0e10cSrcweir advancePhase( m_pData->pCurrentPhase->second.nRange ); 203cdf0e10cSrcweir 204cdf0e10cSrcweir // if that's the last phase, this is the "global end", too 205cdf0e10cSrcweir Phases::const_iterator pNextPhase( m_pData->pCurrentPhase ); 206cdf0e10cSrcweir ++pNextPhase; 207cdf0e10cSrcweir if ( pNextPhase == m_pData->aPhases.end() ) 208cdf0e10cSrcweir m_pData->rConsumer.end(); 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir //........................................................................ 212cdf0e10cSrcweir } // namespace dbmm 213cdf0e10cSrcweir //........................................................................ 214