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 #ifndef INCLUDED_SLIDESHOW_INTERRUPTABLEDELAYEVENT_HXX 29 #define INCLUDED_SLIDESHOW_INTERRUPTABLEDELAYEVENT_HXX 30 31 #include "delayevent.hxx" 32 33 namespace slideshow 34 { 35 namespace internal 36 { 37 /** Event, which delays calling passed Event's fire() method 38 the given amount of time. 39 40 This is actually a facade around the passed event object, 41 that passes on all calls to that object, and the sole 42 contribution of itself is the delay. 43 */ 44 class DelayFacade : public Event 45 { 46 public: 47 DelayFacade( const EventSharedPtr& rEvent, 48 double nTimeout ) : 49 #if OSL_DEBUG_LEVEL > 1 50 Event(::rtl::OUString::createFromAscii("DelayFacade")), 51 #endif 52 mpEvent( rEvent ), 53 mnTimeout( nTimeout ) 54 { 55 } 56 57 virtual bool fire() 58 { 59 if( mpEvent && isCharged() ) 60 { 61 // pass on directly - we're supposed to be called 62 // from EventQueue here, anyway - and if not, 63 // we're only keeping that incorrect transitively. 64 return mpEvent->fire(); 65 } 66 67 return false; 68 } 69 70 virtual bool isCharged() const 71 { 72 // pass on to wrappee - this ensures that we return 73 // false on isCharged(), even if the other event has 74 // been fired outside our own fire() method 75 return !mpEvent ? false : mpEvent->isCharged(); 76 } 77 78 virtual double getActivationTime( double nCurrentTime ) const 79 { 80 // enforce _our_ timeout to our clients (this 81 // overrides any timeout possibly set at the wrappee!) 82 return nCurrentTime + mnTimeout; 83 } 84 85 virtual void dispose() 86 { 87 mpEvent.reset(); 88 } 89 90 private: 91 EventSharedPtr mpEvent; 92 double mnTimeout; 93 }; 94 95 /// Return value for makeInterruptableDelay() 96 struct InterruptableEventPair 97 { 98 /** This member contains a pointer to the timeout 99 event. When enqueued, this event will fire the 100 requested action only after the specified timeout. 101 */ 102 EventSharedPtr mpTimeoutEvent; 103 104 /** This member contains a pointer to the interruption 105 event. When enqueued, this event will fire 106 immediately, interrupting a potentially waiting 107 timeout event. 108 */ 109 EventSharedPtr mpImmediateEvent; 110 }; 111 112 /** Generate an interruptable delay event. 113 114 This function generates a pair of events, that are 115 especially tailored to achieve the following behaviour: By 116 default, the given functor is called after the specified 117 timeout (after insertion of the event into the EventQueue, 118 of course). But optionally, when the interruption event 119 InterruptableEventPair::mpImmediateEvent is fired, the 120 given functor is called <em>at once</em>, and the delay is 121 ignored (that means, the given functor is guaranteed to be 122 called at utmost once, and never twice. Furthermore, it is 123 ensured that both events return false on isCharged(), once 124 anyone of them has been fired already). 125 126 @param rFunctor 127 Functor to call when the event fires. 128 129 @param nTimeout 130 Timeout in seconds, to wait until functor is called. 131 132 @returns a pair of events, where the first one waits the 133 specified amount of time, and the other fires the given 134 functor immediately. 135 */ 136 template< typename Functor > InterruptableEventPair makeInterruptableDelay( const Functor& rFunctor, 137 double nTimeout ) 138 { 139 InterruptableEventPair aRes; 140 141 aRes.mpImmediateEvent = makeEvent( rFunctor, "makeInterruptableDelay"); 142 aRes.mpTimeoutEvent.reset( new DelayFacade( aRes.mpImmediateEvent, 143 nTimeout ) ); 144 145 return aRes; 146 } 147 } 148 } 149 150 #endif /* INCLUDED_SLIDESHOW_INTERRUPTABLEDELAYEVENT_HXX */ 151