1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_slideshow.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir // must be first 32*cdf0e10cSrcweir #include <canvas/debug.hxx> 33*cdf0e10cSrcweir #include <canvas/verbosetrace.hxx> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <comphelper/anytostring.hxx> 36*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include "slideshowexceptions.hxx" 39*cdf0e10cSrcweir #include "activity.hxx" 40*cdf0e10cSrcweir #include "activitiesqueue.hxx" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <boost/bind.hpp> 43*cdf0e10cSrcweir #include <algorithm> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir using namespace ::com::sun::star; 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir namespace slideshow 49*cdf0e10cSrcweir { 50*cdf0e10cSrcweir namespace internal 51*cdf0e10cSrcweir { 52*cdf0e10cSrcweir ActivitiesQueue::ActivitiesQueue( 53*cdf0e10cSrcweir const ::boost::shared_ptr< ::canvas::tools::ElapsedTime >& pPresTimer ) : 54*cdf0e10cSrcweir mpTimer( pPresTimer ), 55*cdf0e10cSrcweir maCurrentActivitiesWaiting(), 56*cdf0e10cSrcweir maCurrentActivitiesReinsert(), 57*cdf0e10cSrcweir maDequeuedActivities() 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir } 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir ActivitiesQueue::~ActivitiesQueue() 62*cdf0e10cSrcweir { 63*cdf0e10cSrcweir // dispose all queue entries 64*cdf0e10cSrcweir try 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir std::for_each( maCurrentActivitiesWaiting.begin(), 67*cdf0e10cSrcweir maCurrentActivitiesWaiting.end(), 68*cdf0e10cSrcweir boost::mem_fn( &Disposable::dispose ) ); 69*cdf0e10cSrcweir std::for_each( maCurrentActivitiesReinsert.begin(), 70*cdf0e10cSrcweir maCurrentActivitiesReinsert.end(), 71*cdf0e10cSrcweir boost::mem_fn( &Disposable::dispose ) ); 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir catch (uno::Exception &) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir OSL_ENSURE( false, rtl::OUStringToOString( 76*cdf0e10cSrcweir comphelper::anyToString( 77*cdf0e10cSrcweir cppu::getCaughtException() ), 78*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ).getStr() ); 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir bool ActivitiesQueue::addActivity( const ActivitySharedPtr& pActivity ) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir OSL_ENSURE( pActivity, "ActivitiesQueue::addActivity: activity ptr NULL" ); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir if( !pActivity ) 87*cdf0e10cSrcweir return false; 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir // add entry to waiting list 90*cdf0e10cSrcweir maCurrentActivitiesWaiting.push_back( pActivity ); 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir return true; 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir void ActivitiesQueue::process() 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir VERBOSE_TRACE( "ActivitiesQueue: outer loop heartbeat" ); 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir // accumulate time lag for all activities, and lag time 100*cdf0e10cSrcweir // base if necessary: 101*cdf0e10cSrcweir ActivityQueue::const_iterator iPos( 102*cdf0e10cSrcweir maCurrentActivitiesWaiting.begin() ); 103*cdf0e10cSrcweir const ActivityQueue::const_iterator iEnd( 104*cdf0e10cSrcweir maCurrentActivitiesWaiting.end() ); 105*cdf0e10cSrcweir double fLag = 0.0; 106*cdf0e10cSrcweir for ( ; iPos != iEnd; ++iPos ) 107*cdf0e10cSrcweir fLag = std::max<double>( fLag, (*iPos)->calcTimeLag() ); 108*cdf0e10cSrcweir if (fLag > 0.0) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir mpTimer->adjustTimer( -fLag ); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // process list of activities 114*cdf0e10cSrcweir while( !maCurrentActivitiesWaiting.empty() ) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir // process topmost activity 117*cdf0e10cSrcweir ActivitySharedPtr pActivity( maCurrentActivitiesWaiting.front() ); 118*cdf0e10cSrcweir maCurrentActivitiesWaiting.pop_front(); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir bool bReinsert( false ); 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir try 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir // fire up activity 125*cdf0e10cSrcweir bReinsert = pActivity->perform(); 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir catch( uno::RuntimeException& ) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir throw; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir catch( uno::Exception& ) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir // catch anything here, we don't want 134*cdf0e10cSrcweir // to leave this scope under _any_ 135*cdf0e10cSrcweir // circumstance. Although, do _not_ 136*cdf0e10cSrcweir // reinsert an activity that threw 137*cdf0e10cSrcweir // once. 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir // NOTE: we explicitely don't catch(...) here, 140*cdf0e10cSrcweir // since this will also capture segmentation 141*cdf0e10cSrcweir // violations and the like. In such a case, we 142*cdf0e10cSrcweir // still better let our clients now... 143*cdf0e10cSrcweir OSL_ENSURE( false, 144*cdf0e10cSrcweir rtl::OUStringToOString( 145*cdf0e10cSrcweir comphelper::anyToString( cppu::getCaughtException() ), 146*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ).getStr() ); 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir catch( SlideShowException& ) 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir // catch anything here, we don't want 151*cdf0e10cSrcweir // to leave this scope under _any_ 152*cdf0e10cSrcweir // circumstance. Although, do _not_ 153*cdf0e10cSrcweir // reinsert an activity that threw 154*cdf0e10cSrcweir // once. 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir // NOTE: we explicitely don't catch(...) here, 157*cdf0e10cSrcweir // since this will also capture segmentation 158*cdf0e10cSrcweir // violations and the like. In such a case, we 159*cdf0e10cSrcweir // still better let our clients now... 160*cdf0e10cSrcweir OSL_TRACE( "::presentation::internal::ActivitiesQueue: Activity threw a SlideShowException, removing from ring" ); 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir if( bReinsert ) 164*cdf0e10cSrcweir maCurrentActivitiesReinsert.push_back( pActivity ); 165*cdf0e10cSrcweir else 166*cdf0e10cSrcweir maDequeuedActivities.push_back( pActivity ); 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir VERBOSE_TRACE( "ActivitiesQueue: inner loop heartbeat" ); 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir if( !maCurrentActivitiesReinsert.empty() ) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir // reinsert all processed, but not finished 174*cdf0e10cSrcweir // activities back to waiting queue. With swap(), 175*cdf0e10cSrcweir // we kill two birds with one stone: we reuse the 176*cdf0e10cSrcweir // list nodes, and we clear the 177*cdf0e10cSrcweir // maCurrentActivitiesReinsert list 178*cdf0e10cSrcweir maCurrentActivitiesWaiting.swap( maCurrentActivitiesReinsert ); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir void ActivitiesQueue::processDequeued() 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir // notify all dequeued activities from last round 185*cdf0e10cSrcweir ::std::for_each( maDequeuedActivities.begin(), 186*cdf0e10cSrcweir maDequeuedActivities.end(), 187*cdf0e10cSrcweir ::boost::mem_fn( &Activity::dequeued ) ); 188*cdf0e10cSrcweir maDequeuedActivities.clear(); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir bool ActivitiesQueue::isEmpty() const 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir return maCurrentActivitiesWaiting.empty() && maCurrentActivitiesReinsert.empty(); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir void ActivitiesQueue::clear() 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir // dequeue all entries: 199*cdf0e10cSrcweir std::for_each( maCurrentActivitiesWaiting.begin(), 200*cdf0e10cSrcweir maCurrentActivitiesWaiting.end(), 201*cdf0e10cSrcweir boost::mem_fn( &Activity::dequeued ) ); 202*cdf0e10cSrcweir ActivityQueue().swap( maCurrentActivitiesWaiting ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir std::for_each( maCurrentActivitiesReinsert.begin(), 205*cdf0e10cSrcweir maCurrentActivitiesReinsert.end(), 206*cdf0e10cSrcweir boost::mem_fn( &Activity::dequeued ) ); 207*cdf0e10cSrcweir ActivityQueue().swap( maCurrentActivitiesReinsert ); 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211