Jump to content
Search Community

keeping only the current playing item in memory

Bose test
Moderator Tag

Recommended Posts

Hi,

 

I am appending some ImageLoader/VideoLoader/SWFLoader to a single LoaderMax object based on the value i specified in xml file.

 

Question 1: Suppose if i am appending 10 items to LoaderMax, will all the 10 occupy  memory space?

Question 2: I need to keep only the current playing item in memory and remove other items, is it possible?

Link to comment
Share on other sites

If you load 10 items, yes all 10 will occupy memory.

 

Each loader type (ImageLoader, SWFLoader, VideoLoader etc) has an unload() method:

http://api.greensock.com/as/com/greensock/loading/core/LoaderCore.html#unload()

 

When you detect that a user is done viewing an asset, you can call unload() on that asset's loader.

 

Even after you unload() a loader, the browser may still store that file temporarily in the browser's cache (hardrive, not memory). Subsequent load()'s should happen very quickly. 

Link to comment
Share on other sites

Hi Carl,

 

Thanks for the quick reply and sorry for delay in responding. I think i have confused myself greatly. I have placed the sample coding below, i had gone off the track somewhere, kindly suggest me the proper way of releasing the memory once an item is completed and starting next item,

var loader:LoaderMax = new LoaderMax({name:"mediaLoader"});
var imageLoader:ImageLoader;
var swfLoader:SWFLoader;
var currVideo:VideoLoader;
for(var count:uint=0;count<xmlArray.length;count++){
    var str:String = xmlArray[count].type
    switch(xmlArray[count].type){
     case "image":
      loader.append(new ImageLoader(.......));
      break;
     case "video":
      loader.append(new VideoLoader(.....));
      break;
     case "swf":
      loader.append(new SWFLoader(........));
      break;
    }
   }
loader.load();

Based on the values given in the xml i am appending the SWF/Image/Video loader to LoaderMax and loading it.

 

 

Then in another function i am loading it one by one with an increment.

 

private function loadMedia():void{
    var currentMedia = loader.getChildAt(increment);
    var str:String = xmlArray[increment].type;
    switchxmlArray[increment].type{
        case "image":
            imageLoader = currentMedia;
            imageLoader.load();
            break;
        case "video":
            currVideo = currentMedia;
            currVideo.load();
            currVideo.playVideo();
            currVideo.addEventListener(VideoLoader.VIDEO_COMPLETE, videoCompleted, false, 0, true);
            break;
        case "swf":
            swfLoader = currentMedia;
            swfLoader.load();
            startTimer();
            currentMedia.rawContent.gotoAndPlay(1);
            break;
    }
}

In the above function i have a timer function which will call the clear function.

 

private function clearContainer():void{
  switch(mediaContent){
     case "image":
      imageLoader.unload();
      break;
     case "video":
      currVideo.unload();
      break;
     case "swf":
      swfLoader.unload();
      break;
    }
}

This will be playing on loop continuously. Is this a correct way of doing it?

i think i had gone wrong somewhere, kindly correct me, i need only the current playing item to be in memory remaining should be removed.

Link to comment
Share on other sites

I'm really not sure what the flow is of your app or where the increment variable is getting set/updated, etc. so it's kinda difficult to troubleshoot this for you. Here's some fake code that might help...

 

var currentMedia:LoaderItem;
var queue:LoaderMax = new LoaderMax({onComplete:completeHandler});
...populate with loaders like you currently do...
queue.load();

function completeHandler(event:LoaderEvent):void {
    queue.unload();
}

//then, when you want to load a particular index number from the queue, use this method...
function loadIndex(index:uint):void {
    if (currentMedia != null) {
        currentMedia.unload();
    }
    currentMedia = queue.getChildAt(index);
    currentMedia.load();
    if (currentMedia is VideoLoader) {
         currentMedia.addEventListener(VideoLoader.VIDEO_COMPLETE, videoCompleted, false, 0, true);
    }
}

 

I hope that helps.

Link to comment
Share on other sites

Hi Jack,

 

Really sorry for the inconvenience caused and thanks for the response. The application is working fine. Suppose if i have 6 items in my xml and loading one by one as you explained above, the memory keeps on increasing untill the 6th item is loaded and then it's somewhat stable at the same level.What i am thinking is for example if the first item takes 20000 k in memory, then on loading the second one that 20000 k of first item should be released and then the second one should be loaded. I have pasted my full coding below, am i still doing something wrong here?

 

here is my coding

package com {
 import flash.utils.Timer;
 import flash.events.Event;
 import flash.net.URLLoader;
 import flash.net.URLRequest;
 import flash.display.Sprite;
 import flash.events.TimerEvent;
 import flash.display.MovieClip;
 
 import com.greensock.*;
 import com.greensock.loading.*;
 import com.greensock.layout.ScaleMode;
 import com.greensock.loading.display.*;
 import com.greensock.events.LoaderEvent;
 import com.greensock.loading.core.LoaderItem;
 
 public dynamic class Screensaver extends Sprite{
  
  private var xmlArray:Array;
  private var mediaHolder:Sprite;
  private var mediaContent:String;
  private var videoDuration:Number;
  private var increment:Number = 0;
  private var timer:Timer = new Timer(1000);


 

  private var currVideo:VideoLoader;
  private var currentMedia:LoaderItem;
  private var imgHolder:ImgHolder = new ImgHolder();
  private var loader:LoaderMax = new LoaderMax({name:"mediaLoader", onComplete:completeHandler});
  
  LoaderMax.activate([VideoLoader, ImageLoader, SWFLoader]);
  
  // constructor function
  public function Screensaver() {
   addChild(imgHolder);
   imgHolder.alpha = 0; 
   mediaHolder = new Sprite();
   imgHolder.addChild(mediaHolder);
   imgHolder.width = stage.stageWidth;
   imgHolder.height = stage.stageHeight;
   imgHolder.scaleX < imgHolder.scaleY ? imgHolder.scaleY = imgHolder.scaleX : imgHolder.scaleX = imgHolder.scaleY;
   dataSource();
  }
  
  private function dataSource():void{
   var xmlLoader:URLLoader = new URLLoader();
   xmlLoader.load(new URLRequest("DB/screensaver.xml"));
   xmlLoader.addEventListener(Event.COMPLETE, xmlHandler, false, 0, true);
  }
  
  // function to parse xml and validate based on from and to date
  private function xmlHandler(e:Event){
   var xml:XML = new XML(e.target.data);
   var currDate:Date = new Date();
   xmlArray = new Array();
   for(var count:uint=0;count<xml.item.length();count++){
    var startDate:String = xml.item[count].attribute("from");
    var endDate:String = xml.item[count].attribute("to");
    if(currDate>=new Date(startDate) && currDate<=new Date(endDate))
     xmlArray.push({type:xml.item[count].attribute("media"),
          source:xml.item[count].attribute("src"),
          delay:xml.item[count].attribute("duration")});
   }
   appendLoaders();
  }
  
  // function to append the filtered media into the LoaderMax object
  private function appendLoaders():void{
   for(var count:uint=0;count<xmlArray.length;count++){
    var str:String = xmlArray[count].type
    switch(str){
     case "image":
      loader.append(new ImageLoader(xmlArray[count].source, {name:"media"+count, scaleMode:"proportionalInside", width:imgHolder.width, height:imgHolder.height, vAlign:"center"}));
      break;
     case "video":
      loader.append(new VideoLoader(xmlArray[count].source, {name:"media"+count, scaleMode:"proportionalInside", autoPlay:false, width:imgHolder.width, height:imgHolder.height}));
      break;
     case "swf":
      loader.append(new SWFLoader(xmlArray[count].source, {name:"media"+count, scaleMode:"proportionalInside", autoPlay:true, width:imgHolder.width, height:imgHolder.height, vAlign:"center"}));
      break;
    }
   }
   loader.load();
  }
  
  // function to load image/video/swf
  private function loadMedia():void{
   clearContainer();
   if (currentMedia != null)
           currentMedia.unload();
   if(currVideo!=null)
    currVideo.unload();
   currentMedia = loader.getChildAt(increment);
   mediaContent = xmlArray[increment].type;
   currentMedia.load();
   if (mediaContent == "video") {
     
    currVideo = loader.getChildAt(increment);
    currVideo.playVideo();
    currVideo.addEventListener(VideoLoader.VIDEO_COMPLETE, videoCompleted, false, 0, true);
   }else{
     startTimer();
   }
   imgHolder.alpha = 1;
   mediaHolder.scaleX = 1/imgHolder.scaleX;
   mediaHolder.scaleY = 1/imgHolder.scaleY;
   imgHolder.x = (stage.stageWidth/2) - (imgHolder.width/2);
   imgHolder.y = (stage.stageHeight/2) - (imgHolder.height/2);
   mediaHolder.addChild(currentMedia.content);
   TweenLite.from(imgHolder, 1, {alpha:0, x:stage.stageWidth+mediaHolder.width});
   (increment==xmlArray.length-1)?increment=0:increment++;
  }
  
  // function called at the end of video completion
  private function videoCompleted(e:Event):void{
   currVideo.pauseVideo();
   currVideo.gotoVideoTime(0);
   loadMedia();
  }
  
  // function triggered when the LoaderMax completes loading
  function completeHandler(event:LoaderEvent):void {
   loader.unload();
   loadMedia();
  }
  
  // function to start the timer
  private function startTimer():void{
   timer.delay = (mediaContent != "video")?Number(xmlArray[increment].delay)*1000:videoDuration*1000;
   timer.start();
   timer.addEventListener(TimerEvent.TIMER, timerControl);
  }
  
  //function to be called when the timer reaches the specified duration
  private function timerControl(e:TimerEvent):void{
   timer.stop();
   TweenLite.to(imgHolder, 1, {alpha:0, x:-mediaHolder.width, onComplete:loadMedia});
  }


 

  // function to clear the container before loading any content
  private function clearContainer():void{
   while(mediaHolder.numChildren>0){
    mediaHolder.removeChildAt(0);
   }
  }
 }
}

Link to comment
Share on other sites

Keep in mind that Flash runs its garbage collection routines arbitrarily, so you shouldn't expect memory usage to immediately decrease after unloading. Have you checked to see if memory never decreases after unloading? Sometimes you need to give it a pretty good chunk of time before Flash decides to sweep away unused objects in memory. Also, if you're subloading swfs, you need to make sure those swfs clean up after themselves because SWFLoader/LoaderMax can't possibly know what code is run within those swfs, so if, for example, they add listeners to the stage or create NetStreams, etc. and never removeEventListeners() or close the NetStreams, it won't allow the swf to be garbage collected properly. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...