| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_slideshow.hxx" |
| |
| #include <canvas/debug.hxx> |
| #include <canvas/verbosetrace.hxx> |
| |
| #include "delayevent.hxx" |
| #include "eventqueue.hxx" |
| #include "usereventqueue.hxx" |
| #include "sequentialtimecontainer.hxx" |
| #include "tools.hxx" |
| |
| #include <boost/bind.hpp> |
| #include <algorithm> |
| |
| namespace slideshow { |
| namespace internal { |
| |
| void SequentialTimeContainer::activate_st() |
| { |
| // resolve first possible child, ignore |
| for ( ; mnFinishedChildren < maChildren.size(); ++mnFinishedChildren ) { |
| if (resolveChild( maChildren[mnFinishedChildren] )) |
| break; |
| else { |
| // node still UNRESOLVED, no need to deactivate or end... |
| OSL_ENSURE( false, "### resolving child failed!" ); |
| } |
| } |
| |
| if (isDurationIndefinite() && |
| (maChildren.empty() || mnFinishedChildren >= maChildren.size())) |
| { |
| // deactivate ASAP: |
| scheduleDeactivationEvent( |
| makeEvent( |
| boost::bind< void >( boost::mem_fn( &AnimationNode::deactivate ), getSelf() ), |
| "SequentialTimeContainer::deactivate") ); |
| } |
| else // use default |
| scheduleDeactivationEvent(); |
| } |
| |
| void SequentialTimeContainer::dispose() |
| { |
| BaseContainerNode::dispose(); |
| if (mpCurrentSkipEvent) { |
| mpCurrentSkipEvent->dispose(); |
| mpCurrentSkipEvent.reset(); |
| } |
| if (mpCurrentRewindEvent) { |
| mpCurrentRewindEvent->dispose(); |
| mpCurrentRewindEvent.reset(); |
| } |
| } |
| |
| void SequentialTimeContainer::skipEffect( |
| AnimationNodeSharedPtr const& pChildNode ) |
| { |
| if (isChildNode(pChildNode)) { |
| // empty all events ignoring timings => until next effect |
| getContext().mrEventQueue.forceEmpty(); |
| getContext().mrEventQueue.addEvent( |
| makeEvent( |
| boost::bind<void>( boost::mem_fn( &AnimationNode::deactivate ), pChildNode ), |
| "SequentialTimeContainer::deactivate, skipEffect with delay") ); |
| } |
| else |
| OSL_ENSURE( false, "unknown notifier!" ); |
| } |
| |
| void SequentialTimeContainer::rewindEffect( |
| AnimationNodeSharedPtr const& /*pChildNode*/ ) |
| { |
| // xxx todo: ... |
| } |
| |
| bool SequentialTimeContainer::resolveChild( |
| AnimationNodeSharedPtr const& pChildNode ) |
| { |
| bool const bResolved = pChildNode->resolve(); |
| if (bResolved && isMainSequenceRootNode()) { |
| // discharge events: |
| if (mpCurrentSkipEvent) |
| mpCurrentSkipEvent->dispose(); |
| if (mpCurrentRewindEvent) |
| mpCurrentRewindEvent->dispose(); |
| |
| // event that will deactivate the resolved/running child: |
| mpCurrentSkipEvent = makeEvent( |
| boost::bind( &SequentialTimeContainer::skipEffect, |
| boost::dynamic_pointer_cast<SequentialTimeContainer>( getSelf() ), |
| pChildNode ), |
| "SequentialTimeContainer::skipEffect, resolveChild"); |
| // event that will reresolve the resolved/activated child: |
| mpCurrentRewindEvent = makeEvent( |
| boost::bind( &SequentialTimeContainer::rewindEffect, |
| boost::dynamic_pointer_cast<SequentialTimeContainer>( getSelf() ), |
| pChildNode ), |
| "SequentialTimeContainer::rewindEffect, resolveChild"); |
| |
| // deactivate child node when skip event occurs: |
| getContext().mrUserEventQueue.registerSkipEffectEvent( |
| mpCurrentSkipEvent, |
| mnFinishedChildren+1<maChildren.size()); |
| // rewind to previous child: |
| getContext().mrUserEventQueue.registerRewindEffectEvent( |
| mpCurrentRewindEvent ); |
| } |
| return bResolved; |
| } |
| |
| void SequentialTimeContainer::notifyDeactivating( |
| AnimationNodeSharedPtr const& rNotifier ) |
| { |
| if (notifyDeactivatedChild( rNotifier )) |
| return; |
| |
| OSL_ASSERT( mnFinishedChildren < maChildren.size() ); |
| AnimationNodeSharedPtr const& pNextChild = maChildren[mnFinishedChildren]; |
| OSL_ASSERT( pNextChild->getState() == UNRESOLVED ); |
| |
| if (! resolveChild( pNextChild )) { |
| // could not resolve child - since we risk to |
| // stall the chain of events here, play it safe |
| // and deactivate this node (only if we have |
| // indefinite duration - otherwise, we'll get a |
| // deactivation event, anyways). |
| deactivate(); |
| } |
| } |
| |
| } // namespace internal |
| } // namespace slideshow |
| |