////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////////////////////////
package mx.effects.effectClasses
{
import flash.events.Event;
import flash.system.ApplicationDomain;
import mx.core.mx_internal;
import mx.effects.EffectInstance;
import mx.effects.IEffectInstance;
import mx.effects.Tween;
import mx.events.EffectEvent;
use namespace mx_internal;
/**
* The CompositeEffectInstance class implements the instance class
* for the CompositeEffect class.
* Flex creates an instance of this class when it plays a CompositeEffect;
* you do not create one yourself.
*
* @see mx.effects.CompositeEffect
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class CompositeEffectInstance extends EffectInstance
{
include "../../core/Version.as";
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @param target This argument is ignored for Composite effects.
* It is included only for consistency with other types of effects.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function CompositeEffectInstance(target:Object)
{
super(target);
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* Internal queue of EffectInstances that are currently playing or waiting to be played.
* Used internally by subclasses.
*/
mx_internal var activeEffectQueue:Array /* of EffectInstance */ = [];
//--------------------------------------------------------------------------
//
// Overridden properties
//
//--------------------------------------------------------------------------
//----------------------------------
// actualDuration
//----------------------------------
/**
* @private
* Used internally to retrieve the actual duration,
* which includes startDelay, repeatCount, and repeatDelay.
*/
override mx_internal function get actualDuration():Number
{
var value:Number = NaN;
if (repeatCount > 0)
{
value = durationWithoutRepeat * repeatCount +
(repeatDelay * (repeatCount - 1)) + startDelay;
}
return value;
}
//----------------------------------
// playheadTime
//----------------------------------
/**
* @private
*/
private var _playheadTime:Number = 0;
/**
* @private
*/
override public function get playheadTime():Number
{
return _playheadTime;
}
/**
* Current time position of the effect.
* This property has a value between 0 and the total duration,
* which includes the Effect's startDelay
,
* repeatCount
, and repeatDelay
.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function set playheadTime(value:Number):void
{
// Subclasses should tell their child effects to seek
// appropriately. This logic just sets the internal time on
// the overall CompositeEffectInstance.
if (timerTween)
timerTween.seek(value);
else
_playheadTime = value;
super.playheadTime = value;
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// childSets
//----------------------------------
/**
* @private
*/
mx_internal var childSets:Array = [];
//----------------------------------
// durationWithoutRepeat
//----------------------------------
/**
* @private
* Used internally to calculate the duration from the children effects
* for one repetition of this effect.
*/
mx_internal function get durationWithoutRepeat():Number
{
return 0;
}
//----------------------------------
// endEffectCalled
//----------------------------------
/**
* @private
*/
mx_internal var endEffectCalled:Boolean;
//----------------------------------
// timerTween
//----------------------------------
/**
* @private
* Used internally to obtain the playheadTime for the composite effect.
*/
mx_internal var timerTween:Tween;
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function play():void
{
timerTween = new Tween(this,0,0,durationWithoutRepeat);
super.play();
}
/**
* @private
*/
override public function pause():void
{
super.pause();
if (timerTween)
timerTween.pause();
}
/**
* @private
*/
override public function stop():void
{
super.stop();
if (timerTween)
timerTween.stop();
}
/**
* @private
*/
override public function end():void
{
super.end();
if (timerTween)
timerTween.endTween();
}
/**
* @private
*/
override public function resume():void
{
super.resume();
if (timerTween)
timerTween.resume();
}
/**
* @private
*/
override public function reverse():void
{
super.reverse();
super.playReversed = !playReversed;
if (timerTween)
timerTween.reverse();
}
/**
* @private
*/
override public function finishEffect():void
{
activeEffectQueue = null;
super.finishEffect();
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Adds a new set of child effects to this Composite effect.
* A Sequence effect plays each child effect set one at a time,
* in the order that it is added.
* A Parallel effect plays all child effect sets simultaneously;
* the order in which they are added doesn't matter.
*
* @param childSet Array of child effects to be added
* to the CompositeEffect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function addChildSet(childSet:Array):void
{
if (childSet)
{
var n:int = childSet.length;
if (n > 0)
{
if (!childSets)
childSets = [ childSet ];
else
childSets.push(childSet);
for (var i:int = 0; i < n; i++)
{
childSet[i].addEventListener(EffectEvent.EFFECT_END,
effectEndHandler);
childSet[i].parentCompositeEffectInstance = this;
}
}
}
}
/**
* @private
* Check if we have a RotateInstance in one of our childSets array elements
*/
mx_internal function hasRotateInstance():Boolean
{
if (childSets)
{
for (var i:int = 0; i < childSets.length; i++)
{
if (childSets[i].length > 0)
{
var compChild:CompositeEffectInstance = childSets[i][0] as CompositeEffectInstance;
if (childSets[i][0] is RotateInstance || (compChild && compChild.hasRotateInstance()))
{
return true;
}
}
}
}
return false;
}
private static var resizeEffectType:Class;
private static var resizeEffectLoaded:Boolean = false;
/**
* @private
* Check if we have a ResizeInstance in one of our childSets array elements
*/
mx_internal function hasResizeInstance():Boolean
{
if (childSets)
{
if (!resizeEffectLoaded)
{
resizeEffectLoaded = true;
if (ApplicationDomain.currentDomain.hasDefinition("spark.effects.supportClasses.ResizeInstance"))
resizeEffectType = Class(ApplicationDomain.currentDomain.
getDefinition("spark.effects.supportClasses.ResizeInstance"));
}
if (resizeEffectType)
for (var i:int = 0; i < childSets.length; i++)
{
if (childSets[i].length > 0)
{
var compChild:CompositeEffectInstance = childSets[i][0] as CompositeEffectInstance;
if (childSets[i][0] is resizeEffectType || (compChild && compChild.hasResizeInstance()))
{
return true;
}
}
}
}
return false;
}
/**
* @private
*/
override mx_internal function playWithNoDuration():void
{
super.playWithNoDuration();
end();
}
/**
* Called each time one of the child effects has finished playing.
* Subclasses must implement this function.
*
* @param The child effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function onEffectEnd(childEffect:IEffectInstance):void
{
// Needs to be overridden
}
/**
* @private
*/
public function onTweenUpdate(value:Object):void
{
_playheadTime = timerTween ?
timerTween.playheadTime :
_playheadTime;
}
/**
* @private
*/
public function onTweenEnd(value:Object):void
{
_playheadTime = timerTween ?
timerTween.playheadTime :
_playheadTime;
}
//--------------------------------------------------------------------------
//
// Overridden event handlers
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function initEffect(event:Event):void
{
super.initEffect(event);
var n:int = childSets.length;
for (var i:int = 0; i < n; i++)
{
var instances:Array = childSets[i];
var m:int = instances.length;
for (var j:int = 0; j < m; j++)
{
instances[j].initEffect(event);
}
}
}
/**
* @private
*/
mx_internal function effectEndHandler(event:EffectEvent):void
{
onEffectEnd(event.effectInstance);
}
}
}