1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_slideshow.hxx" 26 27 // must be first 28 #include <canvas/debug.hxx> 29 #include <canvas/verbosetrace.hxx> 30 31 #include "basecontainernode.hxx" 32 #include "tools.hxx" 33 #include "nodetools.hxx" 34 #include "delayevent.hxx" 35 36 #include <boost/mem_fn.hpp> 37 #include <algorithm> 38 39 using namespace com::sun::star; 40 41 namespace slideshow { 42 namespace internal { 43 44 BaseContainerNode::BaseContainerNode( 45 const uno::Reference< animations::XAnimationNode >& xNode, 46 const BaseContainerNodeSharedPtr& rParent, 47 const NodeContext& rContext ) 48 : BaseNode( xNode, rParent, rContext ), 49 maChildren(), 50 mnFinishedChildren(0), 51 mbDurationIndefinite( isIndefiniteTiming( xNode->getEnd() ) && 52 isIndefiniteTiming( xNode->getDuration() ) ) 53 { 54 } 55 56 void BaseContainerNode::dispose() 57 { 58 forEachChildNode( boost::mem_fn(&Disposable::dispose) ); 59 maChildren.clear(); 60 BaseNode::dispose(); 61 } 62 63 bool BaseContainerNode::init_st() 64 { 65 mnFinishedChildren = 0; 66 // initialize all children 67 return (std::count_if( 68 maChildren.begin(), maChildren.end(), 69 boost::mem_fn(&AnimationNode::init) ) == 70 static_cast<VectorOfNodes::difference_type>(maChildren.size())); 71 } 72 73 void BaseContainerNode::deactivate_st( NodeState eDestState ) 74 { 75 if (eDestState == FROZEN) { 76 // deactivate all children that are not FROZEN or ENDED: 77 forEachChildNode( boost::mem_fn(&AnimationNode::deactivate), 78 ~(FROZEN | ENDED) ); 79 } 80 else { 81 // end all children that are not ENDED: 82 forEachChildNode( boost::mem_fn(&AnimationNode::end), ~ENDED ); 83 } 84 } 85 86 bool BaseContainerNode::hasPendingAnimation() const 87 { 88 // does any of our children returns "true" on 89 // AnimationNode::hasPendingAnimation()? 90 // If yes, we, too, return true 91 VectorOfNodes::const_iterator const iEnd( maChildren.end() ); 92 return (std::find_if( 93 maChildren.begin(), iEnd, 94 boost::mem_fn(&AnimationNode::hasPendingAnimation) ) != iEnd); 95 } 96 97 void BaseContainerNode::appendChildNode( AnimationNodeSharedPtr const& pNode ) 98 { 99 if (! checkValidNode()) 100 return; 101 102 // register derived classes as end listeners at all children. 103 // this is necessary to control the children animation 104 // sequence, and to determine our own end event 105 if (pNode->registerDeactivatingListener( getSelf() )) { 106 maChildren.push_back( pNode ); 107 } 108 } 109 110 bool BaseContainerNode::isChildNode( AnimationNodeSharedPtr const& pNode ) const 111 { 112 // find given notifier in child vector 113 VectorOfNodes::const_iterator const iBegin( maChildren.begin() ); 114 VectorOfNodes::const_iterator const iEnd( maChildren.end() ); 115 VectorOfNodes::const_iterator const iFind( 116 std::find( iBegin, iEnd, pNode ) ); 117 return (iFind != iEnd); 118 } 119 120 bool BaseContainerNode::notifyDeactivatedChild( 121 AnimationNodeSharedPtr const& pChildNode ) 122 { 123 OSL_ASSERT( pChildNode->getState() == FROZEN || 124 pChildNode->getState() == ENDED ); 125 // early exit on invalid nodes 126 OSL_ASSERT( getState() != INVALID ); 127 if( getState() == INVALID ) 128 return false; 129 130 if (! isChildNode(pChildNode)) { 131 OSL_ENSURE( false, "unknown notifier!" ); 132 return false; 133 } 134 135 std::size_t const nSize = maChildren.size(); 136 OSL_ASSERT( mnFinishedChildren < nSize ); 137 ++mnFinishedChildren; 138 bool const bFinished = (mnFinishedChildren >= nSize); 139 140 // all children finished, and we've got indefinite duration? 141 // think of ParallelTimeContainer::notifyDeactivating() 142 // if duration given, we will be deactivated by some end event 143 // @see fillCommonParameters() 144 if (bFinished && isDurationIndefinite()) { 145 deactivate(); 146 } 147 148 return bFinished; 149 } 150 151 #if defined(VERBOSE) && defined(DBG_UTIL) 152 void BaseContainerNode::showState() const 153 { 154 for( std::size_t i=0; i<maChildren.size(); ++i ) 155 { 156 BaseNodeSharedPtr pNode = 157 boost::shared_dynamic_cast<BaseNode>(maChildren[i]); 158 VERBOSE_TRACE( 159 "Node connection: n0x%X -> n0x%X", 160 (const char*)this+debugGetCurrentOffset(), 161 (const char*)pNode.get()+debugGetCurrentOffset() ); 162 pNode->showState(); 163 } 164 165 BaseNode::showState(); 166 } 167 #endif 168 169 } // namespace internal 170 } // namespace slideshow 171 172