Actionscript 3: Event.SOUND_COMPLETE doesn't fire - actionscript-3

Okay, so i was working on my simple actionscript-3 sound player for a website I'm making...
and while doing so it occured to me that the SOUND_COMPLETE event doesn't fire for some reason. So if anyone seems to notice the problem in my code, please respond!
package {
import flash.events.*;
import flash.media.*;
import flash.external.*;
import flash.net.*;
import flash.utils.*;
public class player{
private var soundChannel:SoundChannel;
private var sound:Sound;
private var lastPosition:Number = 0;
public function player():void{
ExternalInterface.addCallback("load", this.load);
ExternalInterface.addCallback("play", this.play);
ExternalInterface.addCallback("stop", this.stop);
ExternalInterface.addCallback("reset", this.reset);
}
/*
javascript from inside actionscript:
ExternalInterface.call("console.log","ipsum");
*/
private function load(url:String):void{
var audio:URLRequest = new URLRequest(url);
try {
this.soundChannel.stop();
} catch(e:Error) {
};
this.sound = new Sound();
this.sound.load(audio);
this.lastPosition = 0;
}
private function play():void{
this.soundChannel = this.sound.play(this.lastPosition);
this.soundChannel.addEventListener(Event.SOUND_COMPLETE,finished);
ExternalInterface.call("console.log","started playing");
}
private function finished():void{
this.lastPosition=0;
this.soundChannel=this.sound.play()
ExternalInterface.call("console.log","finished playing");
}
private function reset():void{
this.lastPosition = 0;
this.soundChannel.stop();
}
private function stop():void{
try {
this.lastPosition = this.soundChannel.position;
this.soundChannel.stop();
} catch(e:Error) {
};
}
}
}//package

I believe the problem is that finished() doesn't accept an event, it should be :
private function finished(e:Event):void{
this.lastPosition=0;
this.soundChannel=this.sound.play()
ExternalInterface.call("console.log","finished playing");
}

Related

MVC AS3 Error: Call to a possibly undefined method through a reference with static type

I'm new to AS3 from Java and was trying to implement a Java style as3 mvc implementation which essentially has two views with an input field and text box which has it's contents changed by buttons.
I keep getting Error: Call to a possibly undefined method handleMouseClick through a reference with static type controller:Controller. and can't understand why. This is for the function handleMouseClick in TextToolsView
Here is my code (sorry for it being so long, I'm not sure how to condense it further without losing my error):
TextModel
package model
{
import flash.events.Event;
import flash.events.EventDispatcher;
public class TextModel extends EventDispatcher
{
private var text:String = new String();
private var initialText:String = new String("Initial Text");
public function TextModel()
{
setText(initialText);
}
public function setText(text:String):void {
this.text = text;
}
public function getText():String {
return this.text;
}
public function updateText(text:String):void {
setText(text);
dispatchEvent(new Event(Event.CHANGE));
}
public function clearText():void {
setText("Text has been cleared");
dispatchEvent(new Event(Event.CHANGE));
}
public function resetText():void {
setText(initialText);
dispatchEvent(new Event(Event.CHANGE));
}
}
}
TextController
package controller
{
import flash.events.MouseEvent;
import model.TextModel;
public class TextController extends AbstractController
{
/**
* Constructor
* #param m model to modify
*/
public function TextController(m:TextModel)
{
super(m);
}
private function updateText(text:String):void {
TextModel(getModel()).updateText(text);
}
private function clearText():void {
TextModel(getModel()).clearText();
}
private function resetText():void {
TextModel(getModel()).resetText();
}
/*override public function update(obj: Object) {
}*/
public function handleMouseClick(event:MouseEvent):void {
switch(event.currentTarget.id) {
case "_updateButton":
updateText("TEXT INPUT TO BE ADDED LATER");//add text input later
break;
case "_clearButton":
clearText();
break;
case "_resetButton":
resetText();
break;
}
}
}
}
AbstractController
package controller
{
import model.TextModel;
import view.View;
/**
* Provides basic services for the "controller" of
* a Model/View/Controller triad.
*
*/
public class AbstractController
{
private var model:TextModel;
private var view:View;
public function AbstractController(m:TextModel)
{
setModel(m);
}
public function setModel(m:TextModel):void
{
model = m;
}
public function getModel():TextModel
{
return model;
}
public function setView(v:View):void
{
view = v;
}
public function getView():View
{
return view;
}
public function update(obj:Object):void {
}
}
}
TextBoxView
package view
{
import controller.Controller;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFormat;
import model.TextModel;
import model.TextUpdate;
/**
* ...
*/
public class TextBoxView extends AbstractView {
private var wrapper:Sprite = new Sprite();
private var textBox:TextField = new TextField();
private var inputField:TextField = new TextField();
public function TextBoxView(m:TextModel, c:Controller, x:int, y:int) {
super(m, c);
textBox.text = "This is a text Panel with lots of text!!!!!!!!!!!!dghsdfghdfghdfghdfghdfghdfghdfghdfghdfghdfghdfghdfghdfgh";
textBox.border = true;
textBox.borderColor = 0x000000;
textBox.multiline = true;
textBox.width = 425;
textBox.height = 115;
textBox.x = 145;
textBox.y = 20;
textBox.wordWrap = true;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0xAA0000;
myFormat.size = 24;
myFormat.italic = true;
//myFormat.align = TextFormatAlign.CENTER
textBox.setTextFormat(myFormat);
addEventListener(Event.CHANGE, this.update);
//inputable text box
inputField.border = true;
inputField.width = 200;
inputField.height = 150;
inputField.x = 200;
inputField.y = 50;
inputField.type = "input";
inputField.multiline = true;
wrapper.addChild(textBox);
wrapper.addChild(inputField);
addChild(wrapper);
}
public function update(event:Event):void {
textBox.text = super.getModel().getText();
}
}
}
TextToolsView
package view
{
import controller.Controller;
import flash.events.Event
import controller.TextController;
import flash.display.Sprite;
import flash.events.MouseEvent;
import model.TextModel;
import model.TextUpdate;
import ui.CustomButton;
public class TextToolsView extends AbstractView
{
private var updateButton:CustomButton;
private var clearButton:CustomButton;
private var resetButton:CustomButton;
private var wrapper:Sprite = new Sprite();
private var textModel:TextModel;
private var textController:TextController;
public function TextToolsView(m:TextModel, c:Controller, x:int, y:int) {
super(m, c);
makeTools(x, y);
}
override public function defaultController (model:TextModel):Controller {
return new TextController(model);
}
private function makeTools(x:int, y:int):void {
updateButton = new CustomButton("update", "_updateButton", 100, 22);
updateButton.x = 0;
updateButton.y = 0;
updateButton.addEventListener(MouseEvent.CLICK, handleMouseClick);
clearButton = new CustomButton("clear", "_clearButton", 100, 22);
clearButton.x = 120;
clearButton.y = 0;
clearButton.addEventListener(MouseEvent.CLICK, handleMouseClick);
resetButton = new CustomButton("reset", "_resetButton", 100, 22);
resetButton.x = 240;
resetButton.y = 0;
resetButton.addEventListener(MouseEvent.CLICK, handleMouseClick);
wrapper.x = x;
wrapper.y = y;
wrapper.addChild(updateButton);
wrapper.addChild(clearButton);
wrapper.addChild(resetButton);
addChild(wrapper);
}
private function handleMouseClick(event:MouseEvent):void {
super.getController().handleMouseClick(event);
}
}
}
Abstract View
package view
{
import controller.Controller;
import flash.display.Sprite;
import model.TextModel;
/**
* Provides basic services for the "view" of
* a Model/View/Controller triad.
*/
public class AbstractView extends Sprite
{
private var model:TextModel;
private var controller:Controller;
public function AbstractView(m:TextModel, c:Controller)
{
setModel(m);
setController(c);
}
/**
* returns the default controller for this view
*/
public function defaultController (model:TextModel):Controller {
return null;
}
/**
* Sets the model this view is observing.
*/
public function setModel (m:TextModel):void {
model = m;
}
/**
* Returns the model this view is observing.
*/
public function getModel ():TextModel {
return model;
}
/**
* Sets the controller for this view.
*/
public function setController (c:Controller):void {
controller = c;
// Tell the controller this object is its view.
getController().setView(this);
}
/**
* Returns this view's controller.
*/
public function getController():Controller {
return controller;
}
}
}
I won't post the custom button because essentially it works fine like any normal button.
and Main
package
{
import controller.TextController;
import flash.display.Sprite;
import flash.events.Event;
import model.TextModel;
import view.TextBoxView;
import view.TextToolsView;
/**
* ...
*/
public class Main extends Sprite
{
private var text_model:TextModel;
private var text_box:TextBoxView;
private var text_tools:TextToolsView;
private var textController:TextController;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
text_model = new TextModel();
textController = new TextController(text_model);
text_box = new TextBoxView(text_model, textController, 0,0);
//text_model.addObserver(text_box);
text_tools = new TextToolsView(text_model, textController, 120, 300);
//text_model.addObserver(text_tools);
addChild(text_box);
addChild(text_tools);
}
}
}
I don't see code of Controller, but I think problem is linked to it.
super.getController().handleMouseClick(event);
In this code getController() method returns Controller instance, but this class doesn't contain method handleMouseClick(). So, I think, you need to cast Controller to TextController like this:
(getController() as TextController).handleMouseClick(event);

addChild/init issue

hey im doing the "Flash Bubbles: Paricle Systems with TimelineMax" from youtube. i got this code:
package
{
import com.greensock.*;
import com.greensock.easing.*;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class main extends Sprite
{
private var BG:bg= new bg;
private var start_btn:start_button= new start_button;
private var tl:TimelineMax= new TimelineMax();
private var bubbleMax:Number = 50;
public function main()
{
stage.addChild(BG);
stage.addChild(start_btn);
BG.y= (stage.stageWidth)/2;
BG.x = (stage.stageWidth)/2;
start_btn.x = (stage.stageWidth)/2;
start_btn.y = (stage.stageHeight)/2;
start_btn.addEventListener(MouseEvent.CLICK,StartGame);
}
private function StartGame(e:Event)
{
stage.removeChild(BG);
stage.removeChild(start_btn);
createBubble();
}
private function createBubble()
{
var Bubble:bubble= new bubble();
Bubble.y=200;
Bubble.x= randomRange(50,1100);
Bubble.alpha= .5;
addChild(Bubble);
}
private function randomRange(min:Number,Max:Number):Number
{
return min + (Math.random() * (Max - min));
}
private function init()
{
for (var count:Number = 0; count<bubbleMax; count++)
{
createBubble();
}
}
init();
}
}
bg, start_button, and bubble are all movie clips made in flash (and been given a as3 class)
I'm aspect to 50 bubbles, but can only see one.. thanks for help!
Change the StartGame function to this:
private function StartGame(e:Event)
{
stage.removeChild(BG);
stage.removeChild(start_btn);
// Your init function is where you're creating all the bubbles. That's what the "for" loop is doing.
init();
}
Also, don't call init(); towards the bottom like you are doing. Your code should look more like this:
package
{
import com.greensock.*;
import com.greensock.easing.*;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class main extends Sprite
{
private var BG:bg= new bg();
private var start_btn:start_button= new start_button();
private var tl:TimelineMax= new TimelineMax();
private var bubbleMax:Number = 50;
public function main()
{
stage.addChild(BG);
stage.addChild(start_btn);
BG.y= (stage.stageWidth)/2;
BG.x = (stage.stageWidth)/2;
start_btn.x = (stage.stageWidth)/2;
start_btn.y = (stage.stageHeight)/2;
start_btn.addEventListener(MouseEvent.CLICK,StartGame);
}
private function StartGame(e:Event)
{
stage.removeChild(BG);
stage.removeChild(start_btn);
init();
}
private function createBubble()
{
var Bubble:bubble= new bubble();
Bubble.y=200;
Bubble.x= randomRange(50,1100);
Bubble.alpha= .5;
addChild(Bubble);
}
private function randomRange(min:Number,Max:Number):Number
{
return min + (Math.random() * (Max - min));
}
private function init()
{
for (var count:Number = 0; count<bubbleMax; count++)
{
createBubble();
}
}
}
}

Facebook abobe as3 api for air for mobile

I am planing a project that involves a cross platform (Android and I.O.S) mobile app that logs in using Facebook. I have no experience with the face book API and cant find any use full material for newbies. I want to use air for its cross platform capabilities so want to avoid multiple solutions for each platform. I have done many searches for help but haven't found much. Can any of you point me to resources you found use full starting off with this sort of thing.
The AS3 Facebook API is all you need. ( http://code.google.com/p/facebook-actionscript-api/ ) Maybe you will have to change a few things (like the JSON methods in there) but otherwise it seems to work alright. You can download several examples from there as well, you can see the usage for different types of environment.
Also, read this article from Tom Krcha http://www.adobe.com/devnet/games/articles/getting-started-with-facebooksdk-actionscript3.html
If you have more specific questions, ask. This one is too generic.
EDIT:
Here is a class I wrote some time ago for a small project
package com.company.social {
import com.facebook.graph.FacebookMobile;
import com.company.AppConst;
import com.company.IDestroyable;
import com.company.Main;
import com.company.displayassets.WebViewCloseStripe;
import com.company.events.FacebookControllerEvent;
import com.company.events.TwitterControllerEvent;
import flash.display.BitmapData;
import flash.display.PNGEncoderOptions;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.utils.ByteArray;
import flash.utils.clearTimeout;
import flash.utils.setTimeout;
public class FacebookController extends EventDispatcher implements IDestroyable {
private static const APP_ID:String = "1234512345"; // Your App ID.
private static const SITE_URL:String = "some_url";
//Extended permission to access other parts of the user's profile that may be private, or if your application needs to publish content to Facebook on a user's behalf.
private var _extendedPermissions:Array = ["publish_stream","user_website","user_status","user_about_me"];
private var _stage:Stage;
private var _webView:StageWebView;
private var _topStripe:WebViewCloseStripe;
private var _activity:String;
private var _timeoutID:uint;
public static const ACTIVITY_LOGIN:String = "login";
public static const ACTIVITY_POST:String = "post";
public function FacebookController(stage:Stage) {
_stage = stage;
init();
}
private function init():void {
_activity = ACTIVITY_LOGIN;
startTimeout();
FacebookMobile.init(APP_ID, onHandleInit, null);
}
private function onHandleInit(response:Object, fail:Object):void {
if (response) {
stopTimeout();
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_COMPLETE));
//FacebookMobile.api("/me", handleUserInfo);
}
else {
/*trace("no response, login -->");
for(var prop in fail["error"]) {
trace(prop+": "+fail["error"][prop]);
}*/
loginUser();
}
}
private function startTimeout():void {
trace("timeout start");
clearTimeout(_timeoutID);
_timeoutID = setTimeout(timeout, AppConst.TIMEOUT_TIME);
}
private function timeout():void {
trace("timed out");
clearTimeout(_timeoutID);
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.TIMEOUT));
}
private function stopTimeout():void {
trace("timeout stop");
clearTimeout(_timeoutID);
}
private function loginUser():void {
stopTimeout();
_topStripe = new WebViewCloseStripe();
_topStripe.getCloseButton().addEventListener(MouseEvent.CLICK, closeClickHandler);
_stage.addChild(_topStripe);
_webView = new StageWebView();
_webView.viewPort = new Rectangle(0, _topStripe.height, _stage.fullScreenWidth, _stage.fullScreenHeight - _topStripe.height);
FacebookMobile.login(handleLogin, _stage, _extendedPermissions, _webView);
}
private function handleLogin(response:Object, fail:Object):void {
if(_topStripe) {
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
}
if(_webView) {
_webView = null;
}
if(response) {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_COMPLETE));
//FacebookMobile.api('/me', handleUserInfo);
}
else {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_ERROR));
}
}
private function closeClickHandler(e:MouseEvent):void {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.CLOSE));
}
private function handleUserInfo(response:Object, fail:Object):void {
if (response) {
for(var prop in response) {
trace(prop+": "+response[prop]);
}
}
}
private function handleUploadImage(result:Object, fail:Object):void {
stopTimeout();
if(result) {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.POST_COMPLETE));
}
else {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.POST_ERROR));
}
}
public function postWithImage(message:String, imageData:BitmapData):void {
_activity = ACTIVITY_POST;
var byteArray:ByteArray = imageData.encode(new Rectangle(0, 0, imageData.width, imageData.height), new PNGEncoderOptions());
var params: Object = new Object;
params.image = byteArray;
params.fileName = "image.png";
params.message = message;
startTimeout();
FacebookMobile.api("/me/photos", handleUploadImage, params, "POST");
}
public function reset():void {
FacebookMobile.logout(handleReset, SITE_URL);
}
public function handleReset(response:Object):void {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.RESET));
}
public function destroy():void {
if(_webView) {
_webView.dispose();
_webView = null;
}
if(_topStripe) {
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
}
_stage = null;
}
}
}
Alternatively you can use a native extension like this:
http://www.milkmangames.com/blog/tools/#iosgv
There are free versions from other publishers available as well.

Record Sound Using AS3 Worker

Hello I am trying to record the user sound using AS3 Worker everything works well when it comes to communication between the worker and the main scene but I think the record functionnality have and issue here I am using the Record Clash from bytearray.org (http://www.bytearray.org/?p=1858)
and here's is my code am I missing something :
package objects
{
import flash.events.Event;
import flash.system.MessageChannel;
import flash.system.Worker;
import flash.system.WorkerDomain;
import flash.utils.ByteArray;
import starling.display.Button;
import starling.display.Image;
import starling.display.Sprite;
import starling.events.Event;
public class RecordComponent extends Sprite
{
private var audioContainer:Image;
private var recButton:Button;
private var playButton:Button;
private var stopButton:Button;
//background thread for recording
private var worker:Worker;
private var wtm:MessageChannel;
private var mtw:MessageChannel;
private var output:ByteArray;
public function RecordComponent()
{
super();
worker = WorkerDomain.current.createWorker(Workers.RecordWorker);
wtm = worker.createMessageChannel(Worker.current);
mtw = Worker.current.createMessageChannel(worker);
worker.setSharedProperty("wtm",wtm);
worker.setSharedProperty("mtw",mtw);
worker.start();
wtm.addEventListener(flash.events.Event.CHANNEL_MESSAGE,onChannelMessage);
this.addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
}
protected function onChannelMessage(event:flash.events.Event):void
{
output = wtm.receive();
}
protected function onAddedToStage(event:starling.events.Event):void
{
this.removeEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
drawScreen();
}
private function drawScreen():void
{
audioContainer = new Image( Assets.getAtlas().getTexture("audioContainer") );
addChild(audioContainer);
//record button
recButton = new Button( Assets.getAtlas().getTexture("recordButton") );
recButton.x=Math.ceil(194/2 - recButton.width/2);
recButton.y=5;
addChild(recButton);
//stop button
stopButton = new Button( Assets.getAtlas().getTexture("stopButton") );
stopButton.x=recButton.x+10;
stopButton.y=10;
stopButton.visible = false;
addChild(stopButton);
//play button
playButton = new Button( Assets.getAtlas().getTexture("playButton") );
playButton.x=Math.ceil(194 - playButton.width)-25;
playButton.y=10;
playButton.visible = false;
addChild(playButton);
this.addEventListener(starling.events.Event.TRIGGERED, buttons_triggeredHandler);
}
private function buttons_triggeredHandler(event:starling.events.Event):void
{
var currentButton:Button = event.target as Button;
switch(currentButton)
{
case recButton:
startRecording();
break;
case stopButton:
stopRecording();
break;
case playButton:
playRecording();
break;
}
}
private function playRecording():void
{
mtw.send("RECORD_PLAY");
}
private function stopRecording():void
{
stopButton.visible = false;
recButton.x = 25;
playButton.visible = true;
recButton.visible = true;
mtw.send("RECORD_STOP");
//
}
private function startRecording():void
{
recButton.visible = false;
stopButton.visible = true;
playButton.visible = false;
mtw.send("RECORD_START");
}
}
}
RecordWorker
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.media.Microphone;
import flash.system.MessageChannel;
import flash.system.Worker;
import org.as3wavsound.WavSound;
import org.bytearray.micrecorder.MicRecorder;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import org.bytearray.micrecorder.events.RecordingEvent;
public class RecordWorker extends Sprite
{
private var wtm:MessageChannel;
private var mtw:MessageChannel;
// volume in the final WAV file will be downsampled to 50%
private var volume:Number = .75;
// we create the WAV encoder to be used by MicRecorder
private var wavEncoder:WaveEncoder = new WaveEncoder( volume );
// we create the MicRecorder object which does the job
private var recorder:MicRecorder = new MicRecorder( wavEncoder,Microphone.getEnhancedMicrophone() );
public function RecordWorker()
{
wtm = Worker.current.getSharedProperty("wtm");
mtw = Worker.current.getSharedProperty("mtw");
mtw.addEventListener(Event.CHANNEL_MESSAGE,command_Handler);
}
//message received from the main component
protected function command_Handler(event:Event):void
{
switch(mtw.receive())
{
case "RECORD_START":
trace("recording.....");
recorder.record();
recorder.addEventListener(RecordingEvent.RECORDING, onRecording);
recorder.addEventListener(flash.events.Event.COMPLETE, onRecordComplete);
break;
case "RECORD_STOP":
trace("record stopped....");
recorder.stop();
break;
case "RECORD_PLAY":
if(recorder.output.length>0)
{
var player:WavSound = new WavSound(recorder.output);
player.play();
}
break;
}
}
private function onRecording(event:RecordingEvent):void
{
trace ( event.time );
}
private function onRecordComplete(event:flash.events.Event):void
{
}
}
}
anny help will be appriciated
Thanks,
Khaled
Looking at this write-up on Adobe's AS3 reference, it seems that because each created worker is "a virtual instance of the Flash runtime", it has no direct connection to any of the core runtime's input or output channels. The Microphone class is one such cut-off interface, which is why it can't reach the system mic inside a worker.

Getting data from custom classes (an OOP question)

How can I get some var / data from a custom classes?
The XML class
package classes
{
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.MovieClip;
public class videoData extends MovieClip
{
private var myXML:XML;
private var myXMList:XMLList;
public function videoData()
{
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("playlist.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
}
private function processXML(e:Event):void
{
myXML = new XML(e.target.data);
myXMList = new XMLList(myXML.children());
}
public function getXML()
{
return myXML;
}
}
}
The class that is calling the XML
package classes
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import classes.videoData;
public class playList extends MovieClip
{
private var vData:videoData = new videoData();
public function playList()
{
trace(vData.getXML())
}
}
}
I would setup an event listener in 'playList' and dispatch an Event from 'videoData' once the XML has finished loading. That way you know when it's finished loading without using ENTER_FRAME (which will use alot more CPU as its checking every frame).
package classes
{
import flash.events.*;
import flash.display.MovieClip;
import classes.VideoData;
public class PlayList extends MovieClip
{
private var vData:VideoData;
public function PlayList()
{
vData = new VideoData();
vData.addEventListener(Event.COMPLETE, onXMLCompleteHandler);
}
private function onXMLCompleteHandler(e:Event):void
{
vData.removeEventListener(Event.COMPLETE, onXMLCompleteHandler);
trace(vData.getXML());
}
}
}
package classes
{
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.MovieClip;
public class VideoData extends MovieClip
{
private var myXML:XML;
private var myXMList:XMLList;
private var myXMLLoader:URLLoader;
public function VideoData()
{
myXMLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("playlist.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
}
private function processXML(e:Event):void
{
myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXML = new XML(e.target.data);
myXMList = new XMLList(myXML.children());
dispatchEvent(e);
}
public function getXML():XML
{
return myXML;
}
}
}
You should also ALWAYS capitalise your class names 'VideoData' not 'videoData'
You will need for the XML data to have been received before getting a value.
Add a private Boolean _xmlLoaded in your videoData class , set it to true in the processXML method.
Create a getter
public function get xmlLoaded():Boolean
{
return _xmlLoaded;
}
Now you can do this:
private var data:videoData = new videoData();
private var xmlData:XML;
private function init():void
{
addEventListener(Event.ENTER_FRAME , xmlLoaded );
}
private function xmlLoaded(event:Event):void
{
if( videoData.xmlLoaded )
{
xmlData = videoData.getXML();
removeEventListener(Event.ENTER_FRAME , xmlLoaded );
}
}
You are already getting your private myXML variable out through the .getXML() method. This is the best way to expose encapsulated data to outside classes.
An alternative would be to make your myXML field public instead of private, but using the get/set accessor methods you are hiding your actual implementation from outside world.
[Edit]
If your getXML() method is returning null, it means that your event handler (the processXML method) has not yet been called.
The problem appears to be in your VideoData constructor:
public function videoData()
{
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("playlist.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
}
The XML file is probably loaded before you attach the event handler, and that is why the event fires right before you start to listen to it. Try to reverse it and see if it works:
public function videoData()
{
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.addEventListener(Event.COMPLETE, processXML); // moved up
myXMLLoader.load(new URLRequest("playlist.xml"));
}