/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package com.pivotshare.hls.loader {

    import flash.display.DisplayObject;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.ByteArray;
    import flash.utils.getTimer;
    import flash.utils.Timer;
    import com.pivotshare.hls.loader.FragmentStream;
    import org.mangui.hls.constant.HLSLoaderTypes;
    import org.mangui.hls.demux.Demuxer;
    import org.mangui.hls.demux.DemuxHelper;
    import org.mangui.hls.demux.ID3Tag;
    import org.mangui.hls.event.HLSError;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.event.HLSLoadMetrics;
    import org.mangui.hls.flv.FLVTag;
    import org.mangui.hls.HLS;
    import org.mangui.hls.model.AudioTrack;
    import org.mangui.hls.model.Fragment;
    import org.mangui.hls.model.FragmentData;
    import org.mangui.hls.utils.AES;

    CONFIG::LOGGING {
        import org.mangui.hls.utils.Log;
        import org.mangui.hls.utils.Hex;
    }

    /**
     * HLS Fragment Demuxed Streamer.
     * Tries to parallel URLStream design pattern, but is incomplete.
     *
     * This class encapsulates Demuxing, but in an inefficient way. This is not
     * meant to be performant for sequential Fragments in play.
     *
     * @class    FragmentDemuxedStream
     * @extends  EventDispatcher
     * @author   HGPA
     */
    public class FragmentDemuxedStream extends EventDispatcher {

        /*
         * DisplayObject needed by AES decrypter.
         */
        private var _displayObject : DisplayObject;

        /*
         * Fragment being loaded.
         */
        private var _fragment : Fragment;

        /*
         * URLStream used to download current Fragment.
         */
        private var _fragmentStream : FragmentStream;

        /*
         * Metrics for this stream.
         */
        private var _metrics : HLSLoadMetrics;

        /*
         * Demuxer needed for this Fragment.
         */
        private var _demux : Demuxer;

        /*
         * Options for streaming and demuxing.
         */
        private var _options : Object;

        //
        //
        //
        // Public Methods
        //
        //
        //

        /**
         * Create a FragmentStream.
         *
         * This constructor takes a reference to main DisplayObject, e.g. stage,
         * necessary for AES decryption control.
         *
         * TODO: It would be more appropriate to create a factory that itself
         * takes the DisplayObject (or a more flexible version of AES).
         *
         * @constructor
         * @param  {DisplayObject}  displayObject
         */
        public function FragmentDemuxedStream(displayObject : DisplayObject) : void {
            _displayObject = displayObject;
            _fragment = null;
            _fragmentStream = null;
            _metrics = null;
            _demux = null;
            _options = new Object();
        };

        /*
         * Return FragmentData of Fragment currently being downloaded.
         * Of immediate interest is the `bytes` field.
         *
         * @method getFragment
         * @return  {Fragment}
         */
        public function getFragment() : Fragment {
            return _fragment;
        }

        /*
         * Close the stream.
         *
         * @method  close
         */
        public function close() : void {
            if (_fragmentStream) {
                _fragmentStream.close();
            }

            if (_demux) {
                _demux.cancel();
                _demux = null;
            }
        }

        /**
         * Load a Fragment.
         *
         * This class/methods DOES NOT user reference of parameter. Instead it
         * clones the Fragment and manipulates this internally.
         *
         * @method  load
         * @param   {Fragment}   fragment  -  Fragment with details (cloned)
         * @param   {ByteArray}  key       -  Encryption Key
         * @return  {HLSLoadMetrics}
         */
        public function load(fragment : Fragment, key : ByteArray, options : Object) : HLSLoadMetrics {

            _options = options;

            // Clone Fragment, with new initilizations of deep fields
            // Passing around references is what is causing problems.
            // FragmentData is initialized as part of construction
            _fragment = new Fragment(
                fragment.url,
                fragment.duration,
                fragment.level,
                fragment.seqnum,
                fragment.start_time,
                fragment.continuity,
                fragment.program_date,
                fragment.decrypt_url,
                fragment.decrypt_iv, // We need this reference
                fragment.byterange_start_offset,
                fragment.byterange_end_offset,
                new Vector.<String>()
            )

            _fragmentStream = new FragmentStream(_displayObject);

            _fragmentStream.addEventListener(IOErrorEvent.IO_ERROR, onStreamError);
            _fragmentStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onStreamError);
            _fragmentStream.addEventListener(ProgressEvent.PROGRESS, onStreamProgress);
            _fragmentStream.addEventListener(Event.COMPLETE, onStreamComplete);

            CONFIG::LOGGING {
                var fragmentString : String = "Fragment[" + _fragment.level + "][" + _fragment.seqnum + "]";
                Log.debug("FragmentDemuxedStream#load: " + fragmentString);
            }

            _metrics = _fragmentStream.load(_fragment, key);

            return _metrics;
        }

        //
        //
        //
        // FragmentStream Event Listeners
        //
        //
        //

        /**
         *
         * @method  onFragmentStreamProgress
         * @param   {ProgressEvent}  evt
         */
        private function onStreamProgress(evt : ProgressEvent) : void {

            _fragment = _fragmentStream.getFragment();

            CONFIG::LOGGING {
                var fragmentString : String = "Fragment[" + _fragment.level + "][" + _fragment.seqnum + "]";
                Log.debug("FragmentDemuxedStream#onStreamProgress: " +
                    fragmentString + " Progress - " + evt.bytesLoaded + " of " + evt.bytesTotal);

                Log.debug("FragmentDemuxedStream#onStreamProgress: " +
                    fragmentString + " Fragment status - bytes.position / bytes.length / bytesLoaded " +
                    _fragment.data.bytes.position + " / " +
                    _fragment.data.bytes.length + " / " +
                    _fragment.data.bytesLoaded);
            }

            // If we are loading a partial Fragment then only parse when it has
            // completed loading to desired portion (See onFragmentStreamComplete)
            /*
            if (fragment.byterange_start_offset != -1) {
                return;
            }
            */

            // START PARSING METRICS
            if (_metrics.parsing_begin_time == 0) {
                _metrics.parsing_begin_time = getTimer();
            }

            // Demuxer has not yet been initialized as this is probably first
            // call to onFragmentStreamProgress, but demuxer may also be/remain
            // null due to unknown Fragment type. Probe is synchronous.
            if (_demux == null) {

                // It is possible we have run onFragmentStreamProgress before
                // without having sufficient data to probe
                //bytes.position = bytes.length;
                //bytes.writeBytes(byteArray);
                //byteArray = bytes;
                CONFIG::LOGGING {
                    var fragmentString : String = "Fragment[" + _fragment.level + "][" + _fragment.seqnum + "]";
                    Log.debug("FragmentDemuxedStream#onStreamProgress: Need a Demuxer for " + fragmentString);
                }

                _demux = DemuxHelper.probe(
                    _fragment.data.bytes,
                    null,
                    _onDemuxAudioTrackRequested,
                    _onDemuxProgress,
                    _onDemuxComplete,
                    _onDemuxVideoMetadata,
                    _onDemuxID3TagFound,
                    false
                    );
            }

            if (_demux) {

                // Demuxer expects the ByteArray delta
                var byteArray : ByteArray = new ByteArray();
                _fragment.data.bytes.readBytes(byteArray, 0, _fragment.data.bytes.length - _fragment.data.bytes.position);
                byteArray.position = 0;

                _demux.append(byteArray);
            }
        }

        /**
         * Called when FragmentStream completes.
         *
         * @method  onStreamComplete
         * @param   {Event}  evt
         */
        private function onStreamComplete(evt : Event) : void {

            // If demuxer is still null, then the Fragment type was invalid
            if (_demux == null) {
                CONFIG::LOGGING {
                    Log.error("FragmentDemuxedStream#onStreamComplete: unknown fragment type");
                    _fragment.data.bytes.position = 0;
                    var bytes2 : ByteArray = new ByteArray();
                    _fragment.data.bytes.readBytes(bytes2, 0, 512);
                    Log.debug2("FragmentDemuxedStream#onStreamComplete: frag dump(512 bytes)");
                    Log.debug2(Hex.fromArray(bytes2));
                }

                var err : ErrorEvent = new ErrorEvent(
                    ErrorEvent.ERROR,
                    false,
                    false,
                    "Unknown Fragment Type"
                    );

                dispatchEvent(err);

            } else {
                _demux.notifycomplete();
            }
        }

        /**
         * Called when FragmentStream has errored.
         *
         * @method  onStreamError
         * @param   {ProgressEvent}  evt
         */
        private function onStreamError(evt : ErrorEvent) : void {
            CONFIG::LOGGING {
                Log.error("FragmentDemuxedStream#onStreamError: " + evt.text);
            }
            dispatchEvent(evt);
        }

        //
        //
        //
        // Demuxer Callbacks
        //
        //
        //

        /**
         * Called when Demuxer needs to know which AudioTrack to parse for.
         *
         * FIXME: This callback simply returns the first audio track!
         * We need to pass this class the appropriate callback propogated from
         * UI layer. Yuck.
         *
         * @method  _onDemuxAudioTrackRequested
         * @param   {Vector<AudioTrack}  audioTrackList  -  List of AudioTracks
         * @return  {AudioTrack}  -  AudioTrack to parse
         */
        private function _onDemuxAudioTrackRequested(audioTrackList : Vector.<AudioTrack>) : AudioTrack {
            if (audioTrackList.length > 0) {
                return audioTrackList[0];
            } else {
                return null;
            }
        }

        /**
         * Called when Demuxer parsed portion of Fragment.
         *
         * @method  _onDemuxProgress
         * @param   {Vector<FLVTag}  tags
         */
        private function _onDemuxProgress(tags : Vector.<FLVTag>) : void {
            CONFIG::LOGGING {
                Log.debug("FragmentDemuxedStream#_onDemuxProgress");
            }

            _fragment.data.appendTags(tags);

            // TODO: Options to parse only portion of Fragment

            // FIXME: bytesLoaded and bytesTotal represent stats of the current
            // FragmentStream, not Demuxer, which is no longer bytes-relative.
            // What should we define here?
            var progressEvent : ProgressEvent = new ProgressEvent(
                ProgressEvent.PROGRESS,
                false,
                false,
                _fragment.data.bytes.length, // bytesLoaded
                _fragment.data.bytesTotal    // bytesTotal
                );

            dispatchEvent(progressEvent);
        };

        /**
         * Called when Demuxer has finished parsing Fragment.
         *
         * @method  _onDemuxComplete
         */
        private function _onDemuxComplete() : void {
            CONFIG::LOGGING {
                Log.debug("FragmentDemuxedStream#_onDemuxComplete");
            }

            _metrics.parsing_end_time = getTimer();

            var completeEvent : Event = new ProgressEvent(Event.COMPLETE);
            dispatchEvent(completeEvent);
        };

        /**
         * Called when Video metadata is parsed.
         *
         * Specifically, when Sequence Parameter Set (SPS) is found.
         *
         * @method  _onDemuxVideoMetadata
         * @param   {uint}  width
         * @param   {uint}  height
         */
        private function _onDemuxVideoMetadata(width : uint, height : uint) : void {
            if (_fragment.data.video_width == 0) {
                CONFIG::LOGGING {
                    Log.debug("FragmentDemuxedStream#_onDemuxVideoMetadata: AVC SPS = " + width + "x" + height);
                }
                _fragment.data.video_width = width;
                _fragment.data.video_height = height;
            }
        }

        /**
         * Called when ID3 tags are found.
         *
         * @method  _onDemuxID3TagFound
         * @param   {Vector.<ID3Tag>}  id3_tags  -  ID3 Tags
         */
        private function _onDemuxID3TagFound(id3_tags : Vector.<ID3Tag>) : void {
            _fragment.data.id3_tags = id3_tags;
        }

    }
}

[FragmentDemuxedStream] Add com.pivotshare.hls.loader.FragmentDemuxedStream


package battlecode.world.signals {
    public class TypeChangeSignal implements Signal {
        private var robotID:uint;
        private var type:String;

        public function TypeChangeSignal(robotID:uint, type:String) {
            this.robotID = robotID;
            this.type = type;
        }

        public function getRobotID():uint {
            return robotID;
        }

        public function getType():String {
            return type;
        }

        public function accept(handler:SignalHandler):* {
            return handler.visitTypeChangeSignal(this);
        }

    }

}

add TypeChangeSignal class

add TypeChangeSignal class


/*
Copyright 2009, Matthew Eernisse (mde@fleegix.org) and Slide, Inc.

 Licensed 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 org.windmill {
  import flash.display.Sprite;
  import flash.display.Stage;
  import org.windmill.WMAssert;
  public class TestCase extends Sprite {
    public var asserts:* = WMAssert;
    // Get a reference to the Stage in the base class
    // before the tests actually load so tests can all
    // reference it
    private var fakeStage:Stage = Windmill.getStage();
    override public function get stage():Stage {
      return fakeStage;
    }
  }
}

Test case base class -- all AS test classes extend this.


package unittests
{
	public class TestEquivalence
	{
		[Before]
		public function setUp():void
		{
		}

		[After]
		public function tearDown():void
		{
		}

		[BeforeClass]
		public static function setUpBeforeClass():void
		{
		}

		[AfterClass]
		public static function tearDownAfterClass():void
		{
		}

	}
}

Add stub class for Equivalence class testing


			import flash.events.MouseEvent;
			import com.example.programmingas3.playlist.PlayList;
			import com.example.programmingas3.playlist.Song;
			import com.example.programmingas3.playlist.SortProperty;

			// constants for the different "states" of the song form
			private static const ADD_SONG:uint = 1;
			private static const SONG_DETAIL:uint = 2;

			private var playList:PlayList = new PlayList();

			private function initApp():void
			{
				// set the initial state of the song form, for adding a new song
				setFormState(ADD_SONG);

				// prepopulate the list with a few songs
				playList.addSong(new Song("Nessun Dorma", "Luciano Pavarotti", 1990, "nessundorma.mp3", ["90's", "Opera"]));
				playList.addSong(new Song("Come Undone", "Duran Duran", 1993, "comeundone.mp3", ["90's", "Pop"]));
				playList.addSong(new Song("Think of Me", "Sarah Brightman", 1987, "thinkofme.mp3", ["Showtunes"]));
				playList.addSong(new Song("Unbelievable", "EMF", 1991, "unbelievable.mp3", ["90's", "Pop"]));

				songList.dataProvider = playList.songList;
			}

			private function sortList(sortField:SortProperty):void
			{
				// Make all the sort type buttons enabled.
				// The active one will be grayed-out below
				sortByTitle.selected = false;
				sortByArtist.selected = false;
				sortByYear.selected = false;

				switch (sortField)
				{
					case SortProperty.TITLE:
						sortByTitle.selected = true;
						break;
					case SortProperty.ARTIST:
						sortByArtist.selected = true;
						break;
					case SortProperty.YEAR:
						sortByYear.selected = true;
						break;
				}

				playList.sortList(sortField);

				refreshList();
			}

			private function refreshList():void
			{
				// remember which song was selected
				var selectedSong:Song = Song(songList.selectedItem);

				// re-assign the song list as the dataprovider to get the newly sorted list
				// and force the List control to refresh itself
				songList.dataProvider = playList.songList;

				// reset the song selection
				if (selectedSong != null)
				{
					songList.selectedItem = selectedSong;
				}
			}

			private function songSelectionChange():void
			{
				if (songList.selectedIndex != -1)
				{
					setFormState(SONG_DETAIL);
				}
				else
				{
					setFormState(ADD_SONG);
				}
			}

			private function addNewSong():void
			{
				// gather the values from the form and add the new song
				var title:String = newSongTitle.text;
				var artist:String = newSongArtist.text;
				var year:uint = newSongYear.value;
				var filename:String = newSongFilename.text;
				var genres:Array = newSongGenres.selectedItems;

				playList.addSong(new Song(title, artist, year, filename, genres));

				refreshList();

				// clear out the "add song" form fields
				setFormState(ADD_SONG);
			}

			private function songListLabel(item:Object):String
			{
				return item.toString();
			}

			private function setFormState(state:uint):void
			{
				// set the form title and control state
				switch (state)
				{
					case ADD_SONG:
						formTitle.text = "Add New Song";
						// show the submit button
						submitSongData.visible = true;
						showAddControlsBtn.visible = false;
						// clear the form fields
						newSongTitle.text = "";
						newSongArtist.text = "";
						newSongYear.value = (new Date()).fullYear;
						newSongFilename.text = "";
						newSongGenres.selectedIndex = -1;
						// deselect the currently selected song (if any)
						songList.selectedIndex = -1;
						break;

					case SONG_DETAIL:
						formTitle.text = "Song Details";
						// populate the form with the selected item's data
						var selectedSong:Song = Song(songList.selectedItem);
						newSongTitle.text = selectedSong.title;
						newSongArtist.text = selectedSong.artist;
						newSongYear.value = selectedSong.year;
						newSongFilename.text = selectedSong.filename;
						newSongGenres.selectedItems = selectedSong.genres;
						// hide the submit button
						submitSongData.visible = false;
						showAddControlsBtn.visible = true;
						break;
				}
			}

Add AS3 example.

Add AS3 example.


/*
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed 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 flash.utils {
public final class Endian {
  public static const BIG_ENDIAN: String = "bigEndian";
  public static const LITTLE_ENDIAN: String = "littleEndian";
}
}

Add missing builtin flash.utils.Endian

Add missing builtin flash.utils.Endian


package aerys.minko.render.effect.vertex
{
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.effect.basic.BasicShader;
	import aerys.minko.render.shader.SFloat;
	import aerys.minko.type.stream.format.VertexComponent;

	public class VertexUVShader extends BasicShader
	{

		public function VertexUVShader(target 	: RenderTarget 	= null,
									   priority	: Number		= 0)
		{
			super(target, priority);
		}

		override protected function getPixelColor() : SFloat
		{
			var uv 				: SFloat = getVertexAttribute(VertexComponent.UV);
			var interpolatedUv 	: SFloat = normalize(interpolate(uv));

			return float4(interpolatedUv.x, interpolatedUv.y, 0, 1);
		}

	}
}

Add VertexUvShader (vertex streams must have an uv component)


package battlecode.world.signals {
import battlecode.common.MapLocation;

    public class PartsChangeSignal implements Signal {
        private var loc:MapLocation;
        private var parts:Number;

        public function PartsChangeSignal(loc:MapLocation, parts:Number) {
            this.loc = loc;
            this.parts = parts;
        }

        public function getLocation():MapLocation {
            return loc;
        }

        public function getParts():Number {
            return parts;
        }

        public function accept(handler:SignalHandler):* {
            handler.visitPartsChangeSignal(this);
        }

    }

}

add PartChangeSignal

add PartChangeSignal


Add onara.as

Add onara.as


package dolly.data {

public class NotCopyableSubclass extends CopyableClass {

	public static var staticProperty2:String = "Value of second-level static property.";

	private var _writableField2:String = "Value of second-level writable field.";

	public var property2:String = "Value of second-level public property.";

	public function NotCopyableSubclass() {
		super();
	}

	public function get writableField2():String {
		return _writableField2;
	}

	public function set writableField2(value:String):void {
		_writableField2 = value;
	}

	public function get readOnlyField2():String {
		return "Value of second-level read-only field.";
	}
}
}

Create new data class for testing: NotCopyableSubclass.


package {
  function sortFunction(a, b) {
    return b - a;
  }
  (function sort0() {
    var array = [4, 1, 2, 6, 1, 5];
    array.sort();
    trace("First Sort: " + array);
    array.sort(sortFunction);
    trace("Second Sort: " + array);
  })();
}

Add sort test case.

Add sort test case.


package server {
	import flash.events.EventDispatcher;
	import flash.events.NetStatusEvent;
	import flash.events.Event;
	import flash.net.Responder;

	public class FMSBridge extends EventDispatcher {
		public var connection:FMSConnection;
		public var client:FMSClient;

		public function FMSBridge(rtmpAddress:String = null, ...rest) {
			connection = new FMSConnection();
			connection.client = client = new FMSClient();
			rtmpAddress && connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function connect(rtmpAddress:String, ...rest):void {
			connection.connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function dispose():void {
			connection.dispose();
		}

		public function close():void {
			connection.close();
		}

		public function registerUser(token:String, email:String, player:String):void {
			connection.call('registerUser', null, token, email, player);
		}

		public function signinUser(token:String):void {
			connection.call('signinUser', null, token);
		}

		public function changePlayer(player:uint):void {
			connection.call('changePlayer', null, player);
		}

		public function startGame():void {
			connection.call('startGame', null);
		}
	}
}

Create FMSBridge.as

Create FMSBridge.as


package aerys.minko.scene.node.mesh
{
	import aerys.minko.render.effect.Style;
	import aerys.minko.scene.action.IAction;
	import aerys.minko.scene.action.mesh.MeshAction;
	import aerys.minko.scene.node.AbstractScene;
	import aerys.minko.scene.node.IStyledScene;
	import aerys.minko.type.stream.IVertexStream;
	import aerys.minko.type.stream.IndexStream;
	import aerys.minko.type.stream.VertexStream;

	import flash.utils.getTimer;

	public class KeyframedMesh extends AbstractScene implements IMesh, IStyledScene
	{
		private var _style				: Style;

		private var _startTime			: uint;
		private var _isPlaying			: Boolean;
		private var _playHeadTime		: uint;

		private var _times				: Vector.<uint>;
		private var _duration			: uint;

		private var _indexStream 		: IndexStream;
		private var _vertexStreams		: Vector.<VertexStream>;

		public function get style()			: Style					{ return _style; }
		public function get styleEnabled()	: Boolean				{ return true; }
		public function get version()		: uint					{ return 0; }
		public function get indexStream()	: IndexStream			{ return _indexStream; }
		public function get vertexStreams()	: Vector.<VertexStream>	{ return _vertexStreams; }

		public function get vertexStream()	: IVertexStream
		{
			var playHeadTime : uint = (_isPlaying ? getTimer() - _startTime : _playHeadTime) % _duration;

			var timeCount : uint = _times.length;
			for (var timeId : uint = 0; timeId < timeCount; ++timeId)
				if (_times[timeId] >= playHeadTime)
					break;

			if (timeId == 0)
				return _vertexStreams[0];
			else if (timeId == timeCount)
				return _vertexStreams[timeCount - 1];
			else
			{
//				var lastTime	 : uint = _times[timeId - 1];
//				var nextTime	 : uint = _times[timeId];
//				var ratio		 : uint = (playHeadTime - lastTime) / (nextTime - lastTime);

				return _vertexStreams[timeId - 1];
			}
		}

		public function get playHeadTime():uint
		{
			return _playHeadTime;
		}

		public function set playHeadTime(value:uint):void
		{
			_playHeadTime = value;
		}

		public function KeyframedMesh(vertexStreams : Vector.<VertexStream>,
									  times			: Vector.<uint>,
									  duration		: uint,
									  indexStream	: IndexStream = null)
		{
			super();

			_isPlaying		= false;
			_indexStream	= indexStream;
			_vertexStreams	= vertexStreams;

			_times			= times;
			_duration		= duration;

			// a keyframed mesh is rendered using a the common mesh action.
			// only the shader needs to change
			actions[0]		= MeshAction.meshAction;

			if (!_indexStream)
				_indexStream = new IndexStream(null, vertexStream.length, vertexStream.dynamic);
		}

		public function start() : void
		{
			_startTime = getTimer();
			_isPlaying = true;
		}

		public function stop() : void
		{
			_isPlaying = false;

		}

	}
}

Add a KeyframedMesh class, to handle keyframed animations


package com.dotfold.dotvimstat.tokenreplacement
{
	/**
	 * Package level function - replace tokens utility.
	 *
	 * Finds named tokens in the template String, with the format:
	 * {name} and replaces them with values found in the supplied Object.
	 *
	 * @author jamesmcnamee
	 *
	 */
	public function replacetokens(template:String, data:Object):String
	{
		var pattern:RegExp = new RegExp('{([^}]+)}', 'gi');

		return template.replace(pattern, function(...rest):String { //match:String, $1:Object):String {

			var match:String = rest[0] as String;
			var token:String = rest[1] as String;

			// find the token vlaue in the object
			if (data && data.hasOwnProperty(token)) {
				return data[token];
			}
			// could not replace token, return token as is
			return match;
		});
	}
}

refactor replacetokens to PLF

[feat] refactor replacetokens to PLF

- so other classes can use it


package dolly.data {

[Cloneable]
public class ClassLevelCloneableSubclass extends ClassLevelCloneable {

	private var _writableField2:String;

	public var property4:String;
	public var property5:String;

	public function ClassLevelCloneableSubclass() {
		super();
	}

	public function get writableField2():String {
		return _writableField2;
	}

	public function set writableField2(value:String):void {
		_writableField2 = value;
	}

}
}

Create data class for testing: ClassLevelCloneableSubclass.


package dolly {

import dolly.core.dolly_internal;
import dolly.data.CopyableSubclass;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;

use namespace dolly_internal;

public class CopyingOfCopyableSubclassTest {

	private var copyableSubclass:CopyableSubclass;
	private var copyableSubclassType:Type;

	[Before]
	public function before():void {
		copyableSubclass = new CopyableSubclass();
		copyableSubclass.property1 = "property1 value";
		copyableSubclass.property2 = "property2 value";
		copyableSubclass.writableField1 = "writableField1 value";
		copyableSubclass.writableField2 = "writableField2 value 7";
		copyableSubclassType = Type.forInstance(copyableSubclass);
	}

	[After]
	public function after():void {
		copyableSubclass = null;
		copyableSubclassType = null;
	}

	[Test]
	public function findingAllCopyableFieldsForType():void {
		const copyableFields:Vector.<Field> = Copier.findCopyableFieldsForType(copyableSubclassType);
		assertNotNull(copyableFields);
		assertEquals(4, copyableFields.length);
		assertNotNull(copyableFields[0]);
		assertNotNull(copyableFields[1]);
		assertNotNull(copyableFields[2]);
		assertNotNull(copyableFields[3]);
	}

	[Test]
	public function copyingByCopier():void {
		const copyInstance:CopyableSubclass = Copier.copy(copyableSubclass);
		assertNotNull(copyInstance);
		assertNotNull(copyInstance.property1);
		assertEquals(copyInstance.property1, copyableSubclass.property1);
		assertNotNull(copyInstance.writableField1);
		assertEquals(copyInstance.writableField1, copyableSubclass.writableField1);
		assertNotNull(copyInstance.writableField2);
		assertEquals(copyInstance.writableField2, copyableSubclass.writableField2);
	}

	[Test]
	public function copyingByCopyFunction():void {
		const copyInstance:CopyableSubclass = copy(copyableSubclass);
		assertNotNull(copyInstance);
		assertNotNull(copyInstance.property1);
		assertEquals(copyInstance.property1, copyableSubclass.property1);
		assertNotNull(copyInstance.writableField1);
		assertEquals(copyInstance.writableField1, copyableSubclass.writableField1);
		assertNotNull(copyInstance.writableField2);
		assertEquals(copyInstance.writableField2, copyableSubclass.writableField2);
	}

}
}

Create new test class CopyingOfCopyableSubclassTest for testing of creation copies for CopyableSubclass.


////////////////////////////////////////////////////////////////////////////////
//
//  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 spark.skins.android4.supportClasses
{

	import flash.display.DisplayObject;

	import mx.core.mx_internal;

	import spark.components.supportClasses.StyleableTextField;
	import spark.skins.mobile.supportClasses.MobileSkin;

	use namespace mx_internal;

	/**
	 *  ActionScript-based skin for text input controls in mobile applications that
	 *  uses a StyleableTextField class for the text display.
	 *
	 *  @see spark.components.supportClasses.StyleableTextField
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10
	 *  @playerversion AIR 2.5
	 *  @productversion Flex 4.5
	 */
	public class TextSkinBase extends MobileSkin
	{
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		/**
		 *  Constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 2.5
		 *  @productversion Flex 4.5
		 *
		 */
		public function TextSkinBase()
		{
			super();
		}

		//--------------------------------------------------------------------------
		//
		//  Graphics variables
		//
		//--------------------------------------------------------------------------

		/**
		 *  Defines the border.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 2.5
		 *  @productversion Flex 4.5
		 */

		//--------------------------------------------------------------------------
		//
		//  Layout variables
		//
		//--------------------------------------------------------------------------

		/**
		 *  Defines the corner radius.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 2.5
		 *  @productversion Flex 4.5
		 */

		protected var layoutBorderSize:uint;

		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------

		/**
		 *  @private
		 *
		 *  Instance of the border graphics.
		 */
		protected var border:DisplayObject;

		private var borderVisibleChanged:Boolean = false;

		//--------------------------------------------------------------------------
		//
		//  Skin parts
		//
		//--------------------------------------------------------------------------

		/**
		 *  textDisplay skin part.
		 */
		public var textDisplay:StyleableTextField;

		[Bindable]
		/**
		 *  Bindable promptDisplay skin part. Bindings fire when promptDisplay is
		 *  removed and added for proper updating by the SkinnableTextBase.
		 */
		public var promptDisplay:StyleableTextField;

		//--------------------------------------------------------------------------
		//
		//  Overridden methods
		//
		//--------------------------------------------------------------------------

		/**
		 *  @private
		 */
		override protected function createChildren():void
		{
			super.createChildren();

			if (!textDisplay)
			{
				textDisplay = StyleableTextField(createInFontContext(StyleableTextField));
				textDisplay.styleName = this;
				textDisplay.editable = true;
				textDisplay.useTightTextBounds = false;
				addChild(textDisplay);
			}
		}

		/**
		 *  @private
		 */
		protected function createPromptDisplay():StyleableTextField
		{
			var prompt:StyleableTextField = StyleableTextField(createInFontContext(StyleableTextField));
			prompt.styleName = this;
			prompt.editable = false;
			prompt.mouseEnabled = false;
			prompt.useTightTextBounds = false;
			prompt.focusEnabled = false;
			return prompt;
		}

		/**
		 *  @private
		 */

		override public function styleChanged(styleProp:String):void
		{
			var allStyles:Boolean = !styleProp || styleProp == "styleName";

			if (allStyles || styleProp == "borderVisible")
			{
				borderVisibleChanged = true;
				invalidateProperties();
			}

			if (allStyles || styleProp.indexOf("padding") == 0)
			{
				invalidateDisplayList();
			}

			super.styleChanged(styleProp);
		}

		/**
		 *  @private
		 */
		override protected function commitCurrentState():void
		{
			super.commitCurrentState();

			alpha = currentState.indexOf("disabled") == -1 ? 1 : 0.5;

			var showPrompt:Boolean = currentState.indexOf("WithPrompt") >= 0;

			if (showPrompt && !promptDisplay)
			{
				promptDisplay = createPromptDisplay();
				addChild(promptDisplay);
			}
			else if (!showPrompt && promptDisplay)
			{
				removeChild(promptDisplay);
				promptDisplay = null;
			}

			invalidateDisplayList();
		}
	}
}

Add android4 specific TextSkinBase

Add android4 specific TextSkinBase


////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.staticControls.beads
{
	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IItemRendererClassFactory;

    /**
     * Classes that generate ItemRenderers based on dataProvider contents.
     * These classes use an IItemRendererFactory to generate the actual
     * ItemRenderer instances
     */
	public interface IDataProviderItemRendererMapper extends IBead
	{
        function get itemRendererFactory():IItemRendererClassFactory;
        function set itemRendererFactory(value:IItemRendererClassFactory):void;
	}
}

add other DataGrid classes from examples/DataGridXCompile for cross-compilation


package dolly.utils {
import dolly.core.dolly_internal;

import mx.collections.ArrayCollection;
import mx.collections.ArrayList;

use namespace dolly_internal;

public class PropertyUtilTests {

	private var sourceObj:Object;
	private var targetObj:Object;

	[Before]
	public function before():void {
		sourceObj = {};
		sourceObj.array = [0, 1, 2, 3, 4];
		sourceObj.arrayList = new ArrayList([0, 1, 2, 3, 4]);
		sourceObj.arrayCollection = new ArrayCollection([0, 1, 2, 3, 4]);

		targetObj = {};
	}

	[After]
	public function after():void {
		sourceObj = targetObj = null;
	}
}
}

Add empty test for PropertyUtil class.

Add empty test for PropertyUtil class.


package dolly.data {
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;

[Cloneable]
public class CompositeCloneableClass {

	public var cloneable:CloneableClass = new CloneableClass();

	public var array:Array = [0, 1, 2, 3, 4];

	public var arrayList:ArrayList = new ArrayList([0, 1, 2, 3, 4]);

	public var arrayCollection:ArrayCollection = new ArrayCollection([0, 1, 2, 3, 4]);

	public function CompositeCloneableClass() {
	}
}
}

Add new test data class: CompositeCloneableClass.


////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.html.accessories
{
	import org.apache.flex.core.IBeadModel;
	import org.apache.flex.core.IFormatBead;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.EventDispatcher;
	import org.apache.flex.events.IEventDispatcher;

	/**
	 * The CurrencyFormatter class formats a value in separated groups. The formatter listens
	 * to a property on a model and when the property changes, formats it and dispatches a
	 * formatChanged event.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class CurrencyFormatter extends EventDispatcher implements IFormatBead
	{
		/**
		 *  constructor
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function CurrencyFormatter()
		{
			super();
		}

		private var _strand:IStrand;

		/**
		 *  @copy org.apache.flex.core.IBead#strand
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function set strand(value:IStrand):void
		{
			_strand = value;

			// Listen for the beadsAdded event which signals when all of a strand's
			// beads have been added.
			IEventDispatcher(value).addEventListener("beadsAdded",handleBeadsAdded);
		}

		/**
		 * @private
		 */
		private function handleBeadsAdded(event:Event):void
		{
			// Listen for the change in the model
			var model:IBeadModel = _strand.getBeadByType(IBeadModel) as IBeadModel;
			model.addEventListener(eventName,propertyChangeHandler);
			model.addEventListener(propertyName+"Change",propertyChangeHandler);

			// format the current value of that property
			propertyChangeHandler(null);
		}

		private var _propertyName:String;
		private var _eventName:String;
		private var _formattedResult:String;
		private var _fractionalDigits:Number = 2;
        private var _currencySymbol:String = "$";

		/**
		 *  The name of the property on the model to format.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get propertyName():String
		{
			if (_propertyName == null) {
				return "text";
			}
			return _propertyName;
		}
		public function set propertyName(value:String):void
		{
			_propertyName = value;
		}

		/**
		 *  The event dispatched by the model when the property changes. The
		 *  default is propertyName+"Changed".
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get eventName():String
		{
			if (_eventName == null) {
				return _propertyName+"Changed";
			}
			return _eventName;
		}
		public function set eventName(value:String):void
		{
			_eventName = value;
		}

        /**
		 *  Number of digits after the decimal separator
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get fractionalDigits():int
		{
			return _fractionalDigits;
		}
		public function set fractionalDigits(value:int):void
		{
            _fractionalDigits = value;
		}

        /**
         *  The currency symbol, such as "$"
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function get currencySymbol():String
        {
            return _currencySymbol;
        }
        public function set currencySymbol(value:String):void
        {
            _currencySymbol = value;
        }

        /**
		 *  The formatted string.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get formattedString():String
		{
			return _formattedResult;
		}

		/**
		 * @private
		 */
		private function propertyChangeHandler(event:Event):void
		{
			// When the property changes, fetch it from the model and
			// format it, storing the result in _formattedResult.
			var model:IBeadModel = _strand.getBeadByType(IBeadModel) as IBeadModel;
			var value:Object = model[propertyName];
			_formattedResult = format(value);

			// Dispatch the formatChanged event so any bead that's interested in
			// the formatted string knows to use it.
			var newEvent:Event = new Event("formatChanged");
			this.dispatchEvent(newEvent);
		}

        /**
         *  Computes the formatted string.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function format(value:Object):String
		{
			if (value == null) return "";

			var num:Number = Number(value);
            var source:String = num.toPrecision(fractionalDigits);

			return currencySymbol + source;
		}
	}
}

add CurrencyFormatter

add CurrencyFormatter


Add AS3 example.

Add AS3 example.


package pl.ydp.automation.execution.report.impl.formatters
{
	import mockolate.mock;
	import mockolate.strict;

	import org.flexunit.assertThat;
	import org.hamcrest.object.equalTo;

	import pl.ydp.automation.execution.report.ReportData;

	public class TestLogReportFormatter
	{
		private var logFormatter:LogReportFormatter;
		private var reportData:ReportData;

		private var INPUT_REPORT_XML:XML = new XML(
			<testsuites>
			  <testsuite name="checkCheckbox" errors="0" failures="1" tests="4">
				<testcase classname="checkCheckbox" name="check checkbox button 2">
				  <teststep name="loadLesson" classname="check checkbox button 2" status="passed"/>
				  <teststep name="selectButton" classname="check checkbox button 2" status="failed"/>
				  <failure message="Element not found"/>
				</testcase>
				<testcase classname="checkCheckbox" name="check checkbox button">
				  <teststep name="loadLesson" classname="check checkbox button" status="passed"/>
				  <teststep name="selectButton" classname="check checkbox button" status="passed"/>
				</testcase>
			  </testsuite>
			</testsuites>
		);

		private var OUTPUT_REPORT:String = '' +

			'\n-----REPORT START-----\n\n' +
			'SUITE:\n' +
			'\tFAILED - CASE: check checkbox button 2\n' +
			'\t\tOK - STEP: loadLesson\n' +
			'\t\tFAILED (Element not found) - STEP: selectButton\n' +
			'\tOK - CASE: check checkbox button\n' +
			'\t\tOK - STEP: loadLesson\n' +
			'\t\tOK - STEP: selectButton\n\n' +
			'-----REPORT END-----\n'
		;

		[Before]
		public function setUp():void
		{
			logFormatter = new LogReportFormatter();

			reportData = strict( ReportData, null, [ INPUT_REPORT_XML ,'' ] );
			mock( reportData ).getter( 'reportXML' ).callsSuper();
		}

		[After]
		public function tearDown():void
		{
		}

		[Test]
		public function should_format_reportdata():void
		{
//			when
			var report:String = logFormatter.format( reportData );

//			then
			assertThat( report, equalTo( OUTPUT_REPORT ) );
		}

		[BeforeClass]
		public static function setUpBeforeClass():void
		{
		}

		[AfterClass]
		public static function tearDownAfterClass():void
		{
		}

	}
}

test for bug YPUB-5271

test for bug YPUB-5271

git-svn-id: 4969af7a11582c80b682e8a73ed7b35a57fe0a9c@138479 3e83ccf1-c6ce-0310-9054-8fdb33cf0640


/*
 * FLINT PARTICLE SYSTEM
 * .....................
 *
 * Author: Xor (Adrian Stutz) for Nothing GmbH
 * Copyright (c) Richard Lord 2008-2010
 * http://flintparticles.org
 *
 * Licence Agreement
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.flintparticles.common.displayObjects
{
    import flash.display.Shape;

    /**
     * The Ring class is a DisplayObject with a circle shape that contains a hole.
     * The registration point of this diaplay object is in the center of the Ring.
     */

    public class Ring extends Shape
    {
        private var _outerRadius:Number;
        private var _innerRadius:Number;
        private var _color:uint;

        /**
         * The constructor creates a Ring with the specified inner and outer radius.
         * @param outer Outer radius of the ring
         * @param inner Inner radius of the ring
         * @param color Color of the ring
         * @param bm    Blend mode of the ring
         */
        public function Ring( outer:Number = 0.9, inner:Number = 1.1, color:uint = 0xFFFFFF, bm:String = "normal" )
        {
            _outerRadius = outer;
            _innerRadius = inner;
            _color = color;
            draw();
            blendMode = bm;
        }

        private function draw():void
        {
            graphics.clear();
            graphics.lineStyle( _outerRadius - _innerRadius, _color );
            graphics.drawCircle( 0, 0, (_outerRadius + _innerRadius)/2 );
        }

        public function get outerRadius():Number
        {
            return _outerRadius;
        }
        public function set outerRadius( value:Number ):void
        {
            _outerRadius = value;
            draw();
        }

        public function get innerRadius():Number
        {
            return _innerRadius;
        }
        public function set innerRadius( value:Number ):void
        {
            _innerRadius = value;
            draw();
        }

        public function get color():uint
        {
            return _color;
        }
        public function set color( value:uint ):void
        {
            _color = value;
            draw();
        }
    }
}

Add Ring display object: A Dot with a hole.


package org.hola
{
    import flash.external.ExternalInterface;
    public class ZErr
    {
        public function ZErr()
        {
            super();
        }
        public static function log(msg:String, ...rest:Array):void{
            if (!ExternalInterface.available)
                    return;
            ExternalInterface.call.apply(ExternalInterface,
                ['console.log', msg].concat(rest))
        }
    }
}

Add ZErr.as

Add ZErr.as


package sample
{

	import starling.display.Sprite;
	import starling.events.Event;
	import starling.display.Shape;

	public class Act402 extends Sprite
	{

		private var _shape:Sprite;

		public function Act402()
		{
			super();

			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);

			stage.color = 0x000000;
			drawCircle();
			adjustShape();

		}

		private function drawCircle():void
		{

			_shape = new Sprite();

			var circle:Shape = new Shape();
			circle.graphics.beginFill(0xFF0000);
			circle.graphics.drawCircle(0,0,50);
			circle.graphics.endFill();
			circle.x = 50;
			circle.y = 50;
			_shape.addChild(circle);

			var rect:Shape = new Shape();
			rect.graphics.beginFill(0x00FF00);
			rect.graphics.drawRect(0,100,100,100);
			rect.graphics.endFill();
			_shape.addChild(rect);

			var triangle:Shape = new Shape();
			triangle.graphics.beginFill(0x0000FF,0.2);
			triangle.graphics.moveTo(50,0);
			triangle.graphics.lineTo(0,100);
			triangle.graphics.lineTo(100,100);
			triangle.graphics.lineTo(50,0);
			triangle.graphics.endFill();
			triangle.x = 0;
			triangle.y = 200;
			_shape.addChild(triangle);

		}

		private function adjustShape():void
		{
			_shape.x = (stage.stageWidth - _shape.width) / 2;
			_shape.y = (stage.stageHeight - _shape.height) / 2;
			addChild(_shape);
		}

	}

}

add starling example

add starling example


//
// $Id: $

package flash.geom {

public class Rectangle
{
    public var x :Number;
    public var y :Number;
    public var width :Number;
    public var height :Number;

    public function Rectangle (x :Number = 0, y :Number = 0, width :Number = 0, height :Number = 0)
    {
        this.x = x;
        this.y = y;
        this.width = Math.max(width, 0);
        this.height = Math.max(height, 0);
    }

    public function get bottom () :Number
    {
        return y + height;
    }
    public function set bottom (value :Number) :void
    {
        // TODO: Verify this is what should happen here
        height = Math.max(y, value) - y;
    }

    public function get bottomRight () :Point
    {
        return new Point(right, bottom);
    }
    public function set bottomRight (value :Point) :void
    {
        bottom = value.y;
        right = value.x;
    }

    public function get left () :Number
    {
        return x;
    }
    public function set left (value :Number) :void
    {
        var r :Number = x + width;
        x = Math.min(right, value);
        width = r - x;
    }

    public function get right () :Number
    {
        return x + width;
    }
    public function set right (value :Number) :void
    {
        width = Math.max(0, value - x);
    }

    public function get size () :Point
    {
        return new Point(width, height);
    }
    public function set size (value :Point) :void
    {
        width = value.x;
        height = value.y;
    }

    public function get top () :Number
    {
        return y;
    }
    public function set top (value :Number) :void
    {
        var b :Number = y + height;
        y = Math.min(bottom, value);
        height = b - y;
    }

    public function get topLeft () :Point
    {
        return new Point(x, y);
    }
    public function set topLeft (value :Point) :void
    {
        top = value.x;
        left = value.y;
    }

    public function contains (x :Number, y :Number) :Boolean
    {
        return x >= left && x <= right && y >= top && y <= bottom;
    }

    public function containsPoint (p :Point) :Boolean
    {
        return contains(p.x, p.y);
    }

    public function containsRect(r :Rectangle) :Boolean
    {
        return r.left >= left && r.right <= right && r.top >= top && r.bottom <= bottom;
    }

    public function inflate (dX :Number, dY :Number) :void
    {
        x -= dX;
        width += 2*dX;
        y -= dY;
        height += 2*dY;
    }

    public function inflatePoint (p :Point) :void
    {
        inflate(p.x, p.y);
    }

    public function intersection (rect :Rectangle) :Rectangle
    {
        if (!intersects(rect)) {
            return new Rectangle(0, 0, 0, 0);
        }

        var l :Number = Math.max(left, rect.left);
        var r :Number = Math.min(right, rect.right);
        var t :Number = Math.max(top, rect.top);
        var b :Number = Math.min(bottom, rect.bottom);

        return new Rectangle(l, t, r-l, b-t);
    }

    public function intersects (r :Rectangle) :Boolean
    {
        return r.top <= bottom && r.bottom >= top && r.left <= right && r.right >= left;
    }

    public function isEmpty () :Boolean
    {
        return width <= 0 && height <= 0;
    }

    public function offset (dX :Number, dY :Number) :void
    {
        x += dX;
        y += dY;
    }

    public function offsetPoint (p :Point) :void
    {
        offset(p.x, p.y);
    }

    public function setEmpty () :void
    {
        x = y = width = height = 0;
    }

    public function union (rect :Rectangle) :Rectangle
    {
        var l :Number = Math.min(left, rect.left);
        var r :Number = Math.max(right, rect.right);
        var t :Number = Math.min(top, rect.top);
        var b :Number = Math.max(bottom, rect.bottom);

        return new Rectangle(l, t, r-l, b-t);
    }

    public function clone () :Rectangle
    {
        return new Rectangle(x, y, width, height);
    }

    public function equals (r :Rectangle) :Boolean
    {
        return r.x == x && r.y == y && r.width == width && r.height == height;
    }

    public function toString () :String
    {
        return "(x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + ")";
    }

}
}

Implement flash.geom.Rectangle. Boy, that was mindnumbing. Also I suspect maybe the Flash version allows negative width and height, but I'm not going to think about that just now.


package {
  class A {
    function foo(a: Class, b: A) {
      trace(a);
      trace(b);
    }
  }
  (new A()).foo(A, new A());
}

Add test case.

Add test case.


//
// $Id: ImageUtil.as 189 2007-04-07 00:25:46Z dhoover $
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.flash {

import flash.display.*;
import flash.events.*;
import flash.utils.Timer;

import com.threerings.util.ValueEvent;

/**
 * Dispatched when the jpeg is complete.
 * The 'value' property will contain the received data.
 *
 * @eventType flash.events.Event.COMPLETE
 */
[Event(name="complete", type="com.threerings.util.ValueEvent")]

/**
 * Class that will encode a jpeg in the background and fire an event when it's done.
 */
public class BackgroundJPGEncoder extends EventDispatcher {

    /**
     * Construct a jpeg encoder.  Once started, the encoder will encode a jpeg over the course
     * of multiple frames, generating an event to deliver the finished jpeg when it is done.
     *
     * @param image The bitmap to encode.
     * @param quality The jpeg quality from 1 to 100 which determines the compression level.
     * @param timeSlice The number of milliseconds of processing to do per frame.
     */
	public function BackgroundJPGEncoder (
	    image :BitmapData, quality :Number = 50, timeSlice :int = 100)
	{
	    _timeSlice = timeSlice;
	    _encoder = new JPGEncoder(image, quality, PIXEL_GRANULARITY);
	    _timer = new Timer(1);
	    _timer.addEventListener(TimerEvent.TIMER, timerHandler);
	}

	/**
	 * Start encoding
	 */
	public function start () :void
	{
	    _timer.start();
	}

	/**
	 * Cancel encoding and discard any intermediate results.
	 */
	public function cancel () :void
	{
	    _timer.stop();
	    _timer = null;
	    _encoder = null;
	}

	protected function timerHandler (event :TimerEvent) :void
	{
	    if (_encoder.process(_timeSlice)) {
	        _timer.stop();
	        // The jpeg is ready so we fire an event passing it to the consumer.
	        dispatchEvent(new ValueEvent(Event.COMPLETE, _encoder.getJpeg()));
	    }
	}

	protected var _timeSlice :int;
	protected var _timer :Timer;
	protected var _encoder :JPGEncoder;

	protected const PIXEL_GRANULARITY :int = 100;
}
}

Add a background jpeg encoder which uses the JPGEncoder to spread out encoding over a series of frames.

git-svn-id: b675b909355d5cf946977f44a8ec5a6ceb3782e4@586 ed5b42cb-e716-0410-a449-f6a68f950b19


			import flash.events.MouseEvent;
			import com.example.programmingas3.playlist.PlayList;
			import com.example.programmingas3.playlist.Song;
			import com.example.programmingas3.playlist.SortProperty;

			// constants for the different "states" of the song form
			private static const ADD_SONG:uint = 1;
			private static const SONG_DETAIL:uint = 2;

			private var playList:PlayList = new PlayList();

			private function initApp():void
			{
				// set the initial state of the song form, for adding a new song
				setFormState(ADD_SONG);

				// prepopulate the list with a few songs
				playList.addSong(new Song("Nessun Dorma", "Luciano Pavarotti", 1990, "nessundorma.mp3", ["90's", "Opera"]));
				playList.addSong(new Song("Come Undone", "Duran Duran", 1993, "comeundone.mp3", ["90's", "Pop"]));
				playList.addSong(new Song("Think of Me", "Sarah Brightman", 1987, "thinkofme.mp3", ["Showtunes"]));
				playList.addSong(new Song("Unbelievable", "EMF", 1991, "unbelievable.mp3", ["90's", "Pop"]));

				songList.dataProvider = playList.songList;
			}

			private function sortList(sortField:SortProperty):void
			{
				// Make all the sort type buttons enabled.
				// The active one will be grayed-out below
				sortByTitle.selected = false;
				sortByArtist.selected = false;
				sortByYear.selected = false;

				switch (sortField)
				{
					case SortProperty.TITLE:
						sortByTitle.selected = true;
						break;
					case SortProperty.ARTIST:
						sortByArtist.selected = true;
						break;
					case SortProperty.YEAR:
						sortByYear.selected = true;
						break;
				}

				playList.sortList(sortField);

				refreshList();
			}

			private function refreshList():void
			{
				// remember which song was selected
				var selectedSong:Song = Song(songList.selectedItem);

				// re-assign the song list as the dataprovider to get the newly sorted list
				// and force the List control to refresh itself
				songList.dataProvider = playList.songList;

				// reset the song selection
				if (selectedSong != null)
				{
					songList.selectedItem = selectedSong;
				}
			}

			private function songSelectionChange():void
			{
				if (songList.selectedIndex != -1)
				{
					setFormState(SONG_DETAIL);
				}
				else
				{
					setFormState(ADD_SONG);
				}
			}

			private function addNewSong():void
			{
				// gather the values from the form and add the new song
				var title:String = newSongTitle.text;
				var artist:String = newSongArtist.text;
				var year:uint = newSongYear.value;
				var filename:String = newSongFilename.text;
				var genres:Array = newSongGenres.selectedItems;

				playList.addSong(new Song(title, artist, year, filename, genres));

				refreshList();

				// clear out the "add song" form fields
				setFormState(ADD_SONG);
			}

			private function songListLabel(item:Object):String
			{
				return item.toString();
			}

			private function setFormState(state:uint):void
			{
				// set the form title and control state
				switch (state)
				{
					case ADD_SONG:
						formTitle.text = "Add New Song";
						// show the submit button
						submitSongData.visible = true;
						showAddControlsBtn.visible = false;
						// clear the form fields
						newSongTitle.text = "";
						newSongArtist.text = "";
						newSongYear.value = (new Date()).fullYear;
						newSongFilename.text = "";
						newSongGenres.selectedIndex = -1;
						// deselect the currently selected song (if any)
						songList.selectedIndex = -1;
						break;

					case SONG_DETAIL:
						formTitle.text = "Song Details";
						// populate the form with the selected item's data
						var selectedSong:Song = Song(songList.selectedItem);
						newSongTitle.text = selectedSong.title;
						newSongArtist.text = selectedSong.artist;
						newSongYear.value = selectedSong.year;
						newSongFilename.text = selectedSong.filename;
						newSongGenres.selectedItems = selectedSong.genres;
						// hide the submit button
						submitSongData.visible = false;
						showAddControlsBtn.visible = true;
						break;
				}
			}

Add AS3 example.

Add AS3 example.


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.event {
    import org.mangui.hls.model.Level;

    import flash.events.Event;

    /** Event fired when an error prevents playback. **/
    public class HLSEvent extends Event {
        /** Identifier for a manifest loading event, triggered after a call to hls.load(url) **/
        public static const MANIFEST_LOADING : String = "hlsEventManifestLoading";
        /** Identifier for a manifest parsed event,
         * triggered after main manifest has been retrieved and parsed.
         * hls playlist may not be playable yet, in case of adaptive streaming, start level playlist is not downloaded yet at that stage */
        public static const MANIFEST_PARSED : String = "hlsEventManifestParsed";
        /** Identifier for a manifest loaded event, when this event is received, main manifest and start level has been retrieved */
        public static const MANIFEST_LOADED : String = "hlsEventManifestLoaded";
        /** Identifier for a level loading event  **/
        public static const LEVEL_LOADING : String = "hlsEventLevelLoading";
        /** Identifier for a level loaded event  **/
        public static const LEVEL_LOADED : String = "hlsEventLevelLoaded";
        /** Identifier for a level switch event. **/
        public static const LEVEL_SWITCH : String = "hlsEventLevelSwitch";
        /** Identifier for a level ENDLIST event. **/
        public static const LEVEL_ENDLIST : String = "hlsEventLevelEndList";
        /** Identifier for a fragment loading event. **/
        public static const FRAGMENT_LOADING : String = "hlsEventFragmentLoading";
        /** Identifier for a fragment loaded event. **/
        public static const FRAGMENT_LOADED : String = "hlsEventFragmentLoaded";
        /** Identifier for a fragment playing event. **/
        public static const FRAGMENT_PLAYING : String = "hlsEventFragmentPlaying";
        /** Identifier for a audio tracks list change **/
        public static const AUDIO_TRACKS_LIST_CHANGE : String = "audioTracksListChange";
        /** Identifier for a audio track switch **/
        public static const AUDIO_TRACK_SWITCH : String = "audioTrackSwitch";
        /** Identifier for a audio level loading event  **/
        public static const AUDIO_LEVEL_LOADING : String = "hlsEventAudioLevelLoading";
        /** Identifier for a audio level loaded event  **/
        public static const AUDIO_LEVEL_LOADED : String = "hlsEventAudioLevelLoaded";
        /** Identifier for audio/video TAGS loaded event. **/
        public static const TAGS_LOADED : String = "hlsEventTagsLoaded";
        /** Identifier when last fragment of playlist has been loaded **/
        public static const LAST_VOD_FRAGMENT_LOADED : String = "hlsEventLastFragmentLoaded";
        /** Identifier for a playback error event. **/
        public static const ERROR : String = "hlsEventError";
        /** Identifier for a playback media time change event. **/
        public static const MEDIA_TIME : String = "hlsEventMediaTime";
        /** Identifier for a playback state switch event. **/
        public static const PLAYBACK_STATE : String = "hlsPlaybackState";
        /** Identifier for a seek state switch event. **/
        public static const SEEK_STATE : String = "hlsSeekState";
        /** Identifier for stream type changes: VoD or Live **/
        public static const STREAM_TYPE_DID_CHANGE:String = "hlsEventStreamTypeDidChange";
        /** Identifier for a playback complete event. **/
        public static const PLAYBACK_COMPLETE : String = "hlsEventPlayBackComplete";
        /** Identifier for a Playlist Duration updated event **/
        public static const PLAYLIST_DURATION_UPDATED : String = "hlsPlayListDurationUpdated";
        /** Identifier for a ID3 updated event **/
        public static const ID3_UPDATED : String = "hlsID3Updated";
        /** Identifier for a fps drop event **/
        public static const FPS_DROP : String = "hlsFPSDrop";
        /** Identifier for a fps drop level capping event **/
        public static const FPS_DROP_LEVEL_CAPPING : String = "hlsFPSDropLevelCapping";
        /** Identifier for a fps drop smooth level switch event **/
        public static const FPS_DROP_SMOOTH_LEVEL_SWITCH : String = "hlsFPSDropSmoothLevelSwitch";
        /** Identifier for a live loading stalled event **/
        public static const LIVE_LOADING_STALLED : String = "hlsLiveLoadingStalled";
        /** Identifier for a Stage set event **/
        public static const STAGE_SET : String = "hlsStageSet";

        /** The current url **/
        public var url : String;
        /** The current quality level. **/
        public var level : int;
        /** The current playlist duration. **/
        public var duration : Number;
        /** The list with quality levels. **/
        public var levels : Vector.<Level>;
        /** The error message. **/
        public var error : HLSError;
        /** Load Metrics. **/
        public var loadMetrics : HLSLoadMetrics;
        /** Play Metrics. **/
        public var playMetrics : HLSPlayMetrics;
        /** The time position. **/
        public var mediatime : HLSMediatime;
        /** The new playback state. **/
        public var state : String;
        /** The current audio track **/
        public var audioTrack : int;
        /** a complete ID3 payload from PES, as a hex dump **/
        public var ID3Data : String;

        /** Assign event parameter and dispatch. **/
        public function HLSEvent(type : String, parameter : *=null, parameter2 : *=null) {
            switch(type) {
                case MANIFEST_LOADING:
                case FRAGMENT_LOADING:
                    url = parameter as String;
                    break;
                case ERROR:
                    error = parameter as HLSError;
                    break;
                case TAGS_LOADED:
                case FRAGMENT_LOADED:
                case LEVEL_LOADED:
                case AUDIO_LEVEL_LOADED:
                    loadMetrics = parameter as HLSLoadMetrics;
                    break;
                case MANIFEST_PARSED:
                case MANIFEST_LOADED:
                    levels = parameter as Vector.<Level>;
                    if(parameter2) {
                        loadMetrics = parameter2 as HLSLoadMetrics;
                    }
                    break;
                case MEDIA_TIME:
                    mediatime = parameter as HLSMediatime;
                    break;
                case PLAYBACK_STATE:
                case SEEK_STATE:
                    state = parameter as String;
                    break;
                case LEVEL_LOADING:
                case LEVEL_SWITCH:
                case AUDIO_LEVEL_LOADING:
                case FPS_DROP:
                case FPS_DROP_LEVEL_CAPPING:
                    level = parameter as int;
                    break;
                case PLAYLIST_DURATION_UPDATED:
                    duration = parameter as Number;
                    break;
                case ID3_UPDATED:
                    ID3Data = parameter as String;
                    break;
                case FRAGMENT_PLAYING:
                    playMetrics = parameter as HLSPlayMetrics;
                    break;
                default:
                    break;
            }
            super(type, false, false);
        }
    }
}

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.event {
    import org.mangui.hls.model.Level;

    import flash.events.Event;

    /** Event fired when an error prevents playback. **/
    public class HLSEvent extends Event {
        /** Identifier for a manifest loading event, triggered after a call to hls.load(url) **/
        public static const MANIFEST_LOADING : String = "hlsEventManifestLoading";
        /** Identifier for a manifest parsed event,
         * triggered after main manifest has been retrieved and parsed.
         * hls playlist may not be playable yet, in case of adaptive streaming, start level playlist is not downloaded yet at that stage */
        public static const MANIFEST_PARSED : String = "hlsEventManifestParsed";
        /** Identifier for a manifest loaded event, when this event is received, main manifest and start level has been retrieved */
        public static const MANIFEST_LOADED : String = "hlsEventManifestLoaded";
        /** Identifier for a level loading event  **/
        public static const LEVEL_LOADING : String = "hlsEventLevelLoading";
        /** Identifier for a level loaded event  **/
        public static const LEVEL_LOADED : String = "hlsEventLevelLoaded";
        /** Identifier for a level switch event. **/
        public static const LEVEL_SWITCH : String = "hlsEventLevelSwitch";
        /** Identifier for a level ENDLIST event. **/
        public static const LEVEL_ENDLIST : String = "hlsEventLevelEndList";
        /** Identifier for a fragment loading event. **/
        public static const FRAGMENT_LOADING : String = "hlsEventFragmentLoading";
        /** Identifier for a fragment loaded event. **/
        public static const FRAGMENT_LOADED : String = "hlsEventFragmentLoaded";
        /** Identifier for a fragment playing event. **/
        public static const FRAGMENT_PLAYING : String = "hlsEventFragmentPlaying";
        /** Identifier for a audio tracks list change **/
        public static const AUDIO_TRACKS_LIST_CHANGE : String = "audioTracksListChange";
        /** Identifier for a audio track switch **/
        public static const AUDIO_TRACK_SWITCH : String = "audioTrackSwitch";
        /** Identifier for a audio level loading event  **/
        public static const AUDIO_LEVEL_LOADING : String = "hlsEventAudioLevelLoading";
        /** Identifier for a audio level loaded event  **/
        public static const AUDIO_LEVEL_LOADED : String = "hlsEventAudioLevelLoaded";
        /** Identifier for audio/video TAGS loaded event. **/
        public static const TAGS_LOADED : String = "hlsEventTagsLoaded";
        /** Identifier when last fragment of playlist has been loaded **/
        public static const LAST_VOD_FRAGMENT_LOADED : String = "hlsEventLastFragmentLoaded";
        /** Identifier for a playback error event. **/
        public static const ERROR : String = "hlsEventError";
        /** Identifier for a playback media time change event. **/
        public static const MEDIA_TIME : String = "hlsEventMediaTime";
        /** Identifier for a playback state switch event. **/
        public static const PLAYBACK_STATE : String = "hlsPlaybackState";
        /** Identifier for a seek state switch event. **/
        public static const SEEK_STATE : String = "hlsSeekState";
        /** Identifier for stream type changes: VoD or Live, type will be stored in 'streamType' field **/
        public static const STREAM_TYPE_DID_CHANGE:String = "hlsEventStreamTypeDidChange";
        /** Identifier for a playback complete event. **/
        public static const PLAYBACK_COMPLETE : String = "hlsEventPlayBackComplete";
        /** Identifier for a Playlist Duration updated event **/
        public static const PLAYLIST_DURATION_UPDATED : String = "hlsPlayListDurationUpdated";
        /** Identifier for a ID3 updated event **/
        public static const ID3_UPDATED : String = "hlsID3Updated";
        /** Identifier for a fps drop event **/
        public static const FPS_DROP : String = "hlsFPSDrop";
        /** Identifier for a fps drop level capping event **/
        public static const FPS_DROP_LEVEL_CAPPING : String = "hlsFPSDropLevelCapping";
        /** Identifier for a fps drop smooth level switch event **/
        public static const FPS_DROP_SMOOTH_LEVEL_SWITCH : String = "hlsFPSDropSmoothLevelSwitch";
        /** Identifier for a live loading stalled event **/
        public static const LIVE_LOADING_STALLED : String = "hlsLiveLoadingStalled";
        /** Identifier for a Stage set event **/
        public static const STAGE_SET : String = "hlsStageSet";

        /** The current url **/
        public var url : String;
        /** The current quality level. **/
        public var level : int;
        /** The current playlist duration. **/
        public var duration : Number;
        /** The list with quality levels. **/
        public var levels : Vector.<Level>;
        /** The error message. **/
        public var error : HLSError;
        /** Load Metrics. **/
        public var loadMetrics : HLSLoadMetrics;
        /** Play Metrics. **/
        public var playMetrics : HLSPlayMetrics;
        /** The time position. **/
        public var mediatime : HLSMediatime;
        /** The new playback state. **/
        public var state : String;
        /** The new stream type value **/
        public var streamType: String;
        /** The current audio track **/
        public var audioTrack : int;
        /** a complete ID3 payload from PES, as a hex dump **/
        public var ID3Data : String;

        /** Assign event parameter and dispatch. **/
        public function HLSEvent(type : String, parameter : *=null, parameter2 : *=null) {
            switch(type) {
                case MANIFEST_LOADING:
                case FRAGMENT_LOADING:
                    url = parameter as String;
                    break;
                case ERROR:
                    error = parameter as HLSError;
                    break;
                case TAGS_LOADED:
                case FRAGMENT_LOADED:
                case LEVEL_LOADED:
                case AUDIO_LEVEL_LOADED:
                    loadMetrics = parameter as HLSLoadMetrics;
                    break;
                case MANIFEST_PARSED:
                case MANIFEST_LOADED:
                    levels = parameter as Vector.<Level>;
                    if(parameter2) {
                        loadMetrics = parameter2 as HLSLoadMetrics;
                    }
                    break;
                case MEDIA_TIME:
                    mediatime = parameter as HLSMediatime;
                    break;
                case PLAYBACK_STATE:
                case SEEK_STATE:
                    state = parameter as String;
                    break;
                case LEVEL_LOADING:
                case LEVEL_SWITCH:
                case AUDIO_LEVEL_LOADING:
                case FPS_DROP:
                case FPS_DROP_LEVEL_CAPPING:
                    level = parameter as int;
                    break;
                case PLAYLIST_DURATION_UPDATED:
                    duration = parameter as Number;
                    break;
                case ID3_UPDATED:
                    ID3Data = parameter as String;
                    break;
                case FRAGMENT_PLAYING:
                    playMetrics = parameter as HLSPlayMetrics;
                    break;
                case HLSEvent.STREAM_TYPE_DID_CHANGE:
                    // Stream Type is required
                    streamType = String(parameter);
                    break;
                default:
                    break;
            }
            super(type, false, false);
        }
    }
}

store type in event object

store type in event object


package com.kaltura.delegates.media
{
	import com.kaltura.config.KalturaConfig;
	import com.kaltura.core.KClassFactory;
	import com.kaltura.delegates.WebDelegateBase;
	import com.kaltura.errors.KalturaError;
	import com.kaltura.net.KalturaCall;
	import com.kaltura.net.KalturaFileCall;

	import flash.events.Event;
	import flash.net.URLLoaderDataFormat;
	import flash.utils.getDefinitionByName;

	import mx.utils.UIDUtil;

	import ru.inspirit.net.MultipartURLLoader;
	public class MediaUpdateThumbnailJpegDelegate extends WebDelegateBase
	{
		protected var mrloader:MultipartURLLoader;

		public function MediaUpdateThumbnailJpegDelegate(call:KalturaCall, config:KalturaConfig)
		{
			super(call, config);
		}

		override public function parse( result : XML ) : *
		{
			var cls : Class = getDefinitionByName('com.kaltura.vo.'+ result.result.objectType) as Class;
			var obj : * = (new KClassFactory( cls )).newInstanceFromXML( result.result );
			return obj;
		}

		override protected function sendRequest():void {
			//construct the loader
			createURLLoader();

			//create the service request for normal calls
			var variables:String = decodeURIComponent(call.args.toString());
			var req:String = _config.domain +"/"+_config.srvUrl+"?service="+call.service+"&action="+call.action +'&'+variables;
			mrloader.addFile((call as KalturaFileCall).bytes, UIDUtil.createUID(), 'fileData');

			mrloader.dataFormat = URLLoaderDataFormat.TEXT;
			mrloader.load(req);
		}

		// Event Handlers
		override protected function onDataComplete(event:Event):void {
			try{
				handleResult( XML(event.target.loader.data) );
			}
			catch( e:Error )
			{
				var kErr : KalturaError = new KalturaError();
				kErr.errorCode = String(e.errorID);
				kErr.errorMsg = e.message;
				_call.handleError( kErr );
			}
		}

		override protected function createURLLoader():void {
			mrloader = new MultipartURLLoader();
			mrloader.addEventListener(Event.COMPLETE, onDataComplete);
		}

	}
}

package com.kaltura.delegates.media
{
	import com.kaltura.config.KalturaConfig;
	import com.kaltura.core.KClassFactory;
	import com.kaltura.delegates.WebDelegateBase;
	import com.kaltura.errors.KalturaError;
	import com.kaltura.net.KalturaCall;
	import com.kaltura.net.KalturaFileCall;

	import flash.events.Event;
	import flash.net.URLLoaderDataFormat;
	import flash.utils.getDefinitionByName;

	import mx.utils.UIDUtil;

	import ru.inspirit.net.MultipartURLLoader;
	public class MediaUpdateThumbnailJpegDelegate extends WebDelegateBase
	{
		protected var mrloader:MultipartURLLoader;

		public function MediaUpdateThumbnailJpegDelegate(call:KalturaCall, config:KalturaConfig)
		{
			super(call, config);
		}

		override public function parse( result : XML ) : *
		{
			var cls : Class = getDefinitionByName('com.kaltura.vo.'+ result.result.objectType) as Class;
			var obj : * = (new KClassFactory( cls )).newInstanceFromXML( result.result );
			return obj;
		}

		override protected function sendRequest():void {
			//construct the loader
			createURLLoader();

			//create the service request for normal calls
			var variables:String = decodeURIComponent(call.args.toString());
			var req:String = _config.protocol + _config.domain +"/"+_config.srvUrl+"?service="+call.service+"&action="+call.action +'&'+variables;
			mrloader.addFile((call as KalturaFileCall).bytes, UIDUtil.createUID(), 'fileData');

			mrloader.dataFormat = URLLoaderDataFormat.TEXT;
			mrloader.load(req);
		}

		// Event Handlers
		override protected function onDataComplete(event:Event):void {
			try{
				handleResult( XML(event.target.loader.data) );
			}
			catch( e:Error )
			{
				var kErr : KalturaError = new KalturaError();
				kErr.errorCode = String(e.errorID);
				kErr.errorMsg = e.message;
				_call.handleError( kErr );
			}
		}

		override protected function createURLLoader():void {
			mrloader = new MultipartURLLoader();
			mrloader.addEventListener(Event.COMPLETE, onDataComplete);
		}

	}
}

use client protocol definition

use client protocol definition

git-svn-id: 8a2ccb88241e16c78017770bc38d91d6d5396a5a@51541 6b8eccd3-e8c5-4e7d-8186-e12b5326b719