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