views:

223

answers:

3

I have two classes, call them A and B. They both contain a Loader object. In class A I load content into the Loader object.

public class A {
    var loader:Loader;

    public function A():void {
        loader = new Loader();
        this.addChild(loader);
        loader.load(...);
    }
}

public class B() {
    var loader:Loader;

    public function B():void {
        loader = new Loader(); 
        this.addChild(loader);
    }
}

I need to now assign A's Loader to B's Loader (after the load is complete).

In some other class I have an instance of A and B. Doing a direct assignment of the loader values doesn't seem to work (when showing B, A's loader content is not displayed).

var b:B = new B();
var a:A = new A();

// ... I wait for a's loader to be loaded ...
// ... then ... 
b.loader = a.loader;
addChild(b);
// A's Loader is not shown ...

If I do the following, it works:

b.addChild(a.loader);

But that's not what I want. I don't want to manage a bunch of children when I know I only have one child but just want to change its content.

Is there a way to copy/assign a Loader directly? I tried assigning to 'content' but that's read-only. Is there another way I can do this? Basically I have an array of Loader objects that all get loaded with images. I then have a single Loader that's on the stage and I want to assign to it images (Loaders) from my array.

Thanks.

A: 

I did something like this for fun:

var a:Loader = new Loader();
a.contentLoaderInfo.addEventListener(Event.COMPLETE, aLoaded);
a.load(new URLRequest('A.swf'));
addChild(a);

var b:Loader = new Loader();
b.contentLoaderInfo.addEventListener(Event.COMPLETE, bLoaded);
addChild(b);


function aLoaded(event:Event):void {
    trace('a loaded');
    event.currentTarget.removeEventListener(Event.COMPLETE, aLoaded);
    b.loadBytes(a.loaderInfo.bytes);
}
function bLoaded(event:Event):void {
    event.currentTarget.removeEventListener(Event.COMPLETE, bLoaded);
    trace('b loaded');
}

using loader's loadBytes and loaderInfo's bytes I create an endless loop where a loads a, loads b, loads a, load b, loads a, loads b...and loop wholes start to appear.

DON'T DO THAT!

That is not what you need, you're working with images, so the loader content should be a Bitmap. You can access and clone the bitmapData, given you have permission to access the pixels(e.g. crossdomain policy and a new LoaderContext(true) as the second parameter in the load() call).

So your answer should be as simple as:

var a:Loader = new Loader();
a.contentLoaderInfo.addEventListener(Event.COMPLETE, aLoaded);
a.load(new URLRequest('app_image.jpg'));
addChild(a);

function aLoaded(event:Event):void {
    if(a.content is Bitmap){//check if it's actually an image, not a swf
        var clonedData:Bitmap = Bitmap(a.content).bitmapData.clone();
        //do whatever you need with the clone
        //e.g. var dolly:Bitmap = new Bitmap(clonedData);//etc
    }
}

It's not the OOP code, it's just something minimal so you can easily get the picture :)

George Profenza
Hey, thanks for the reply. I know I said I'm loading images right now but I realized that I might need to support swfs down the line. I ended up just doing removeChildAt(0) and addChildAt(loader,0). It's working so far ...
Nebs
A: 

I ended up swapping the children to get the same effect. It's less complicated than I thought it would be.

So basically in B I did:

this.setChildIndex(loader,0);

This is to make sure the loader is at index 0. (It can be any fixed index but in my case I needed it to appear at the bottom). It's not necessary to have a loader in B initially but I just put it there to make sure there's something fixed at index 0 (so I don't accidentally remove some other child).

Then when setting A's loader to B I'd just swap out the child at index 0.

b.removeChildAt(0);  
b.addChildAt(a.loader,0);

It's not exactly the solution I wanted but it's working well so far.

Nebs
A: 

hello! From what I understand you want to create a setLoader method for your b class. something like

public class B() {
    var loader:Loader;

    public function B():void {
      // nothing here, unless you really
      // want a b.loader before stting it from outside
    }

    public function setLoader(_l:Loader){
      if(loader) removeChild(loader);
      loader = _l;
      addChild(_l);
    }
}

you can then, when a is loaded, call

b.setLoader(a.loader);

be aware that a.loader will not be a child of a anymore (if you display a, it will be empty), but you will still be able to access it with both a.loader AND b.loader.

tell me if this helps.

Boris