0

I'm trying to call a function from a AS3 container which should call old AS2 SWF that cannot be edited bacause we are talking about 1000 swf files, does exist some way to call a function inside the AS2 SWF from the AS3 container?

I know a possible way by adding a LocalConnection as written here but as I said I can't edit all the swf files, so I just wonder to know if does exist some alternative.

vitto
  • 19,094
  • 31
  • 91
  • 130

3 Answers3

3

If your container absolutely has to be written in AS3, then you could create another intermediary container in AS2 that can communicate with the 1000 existing SWFs directly, and you can then communicate with that using the LocalConnection technique.

The code below is a simple example of this, but due to an issue with the MovieClipLoader seeming to not fire events when loaded into an AS3 AVM1 object I have had to implement a rather ugly polling system. The question relating to this issue can be found be here: Why do MovieClipLoader events not fire when loaded into an AS3 wrapper?.

child_as2.swf - One of a thousand AS2 files that we are trying to load. It has defined functions on it's root that we want to access when it is loaded:

stop();

function playMovie() {
    play();
}

parent_as2.swf - The intermediary AS2 file that contains LocalConnection code to bridge between the AVM1 and AVM2 runtimes. Due to the events issue noted above, this polls child_as2.swf to detect both when it is loaded and when a known function on the root is available. It is important that the first polling call to checkProgress is disregarded as this will return incorrect progress values as noted here: http://help.adobe.com/en_US/AS2LCR/Flash_10.0/00001380.html

var container:MovieClip = createEmptyMovieClip("container", 10);
var mcLoader:MovieClipLoader = new MovieClipLoader();
var loadStarted:Boolean;
var checkingInt:Number;

function checkProgress() {
    var progObj:Object = mcLoader.getProgress(container);
    if(progObj.bytesLoaded == progObj.bytesTotal && loadStarted) {
        //load complete, wait for loadInit
        if(typeof(container.playMovie) == "function") {
            //loadInit
            clearInterval(checkingInt);
            container.playMovie();
        }
    }
    //ensures the first loop is ignored due to inaccuracy with reporting
    loadStarted = true;
}

//LocalConnection code
var myLC:LocalConnection = new LocalConnection();

myLC.loadChild = function() {
    loadStarted = false;
    mcLoader.loadClip("child_as2.swf", container);
    checkingInt = setInterval(checkProgress,5);
}

myLC.connect("AVM");

parent_as3.swf - The outer AS3 wrapper. This loads parent_as2.swf into an AVM1 object, and communicates with it via LocalConnection.

var myLC:LocalConnection = new LocalConnection();

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT,onLoaded);
loader.load(new URLRequest("parent_as2.swf"));
addChild(loader);


function onLoaded(event:Event):void {
    //setTimeout hack to circumvent #2000 Security context error
    setTimeout(function() {
        myLC.send("AVM", "loadChild");
    },1);
}
Community
  • 1
  • 1
shanethehat
  • 15,460
  • 11
  • 57
  • 87
  • If the army of AS2 SWFs do not have a LocalConnection setup, how is that communication accomplished AS2->AS2? – Aaron Nov 09 '11 at 17:15
  • this could be a solution, I'll take a look soon! – vitto Nov 09 '11 at 17:23
  • @vitto - I've started testing it myself, and come across an issue with MovieClipLoader events in the intermediary container. Might be a deal breaker... – shanethehat Nov 09 '11 at 17:57
  • 2
    @vitto - you can see my test setup and the issue I'm experiencing here: http://stackoverflow.com/questions/8069634/why-do-moviecliploader-events-not-fire-when-loaded-into-an-as3-wrapper – shanethehat Nov 09 '11 at 18:24
  • @vitto - updated answer with (slightly dirty) example. I don't feel that this is an acceptable production solution, but it's a start. – shanethehat Nov 10 '11 at 11:43
0

I do not envy this situation one bit. The only suggestion I have is to decompile the… 1000 SWFs and implement the LocalConnection logic there, perhaps in a shared SWC if architected properly, recompile the SWFs and go from there.

Aaron
  • 4,634
  • 1
  • 27
  • 43
0

You can make a as2 swf to make the localconnections. This swf can call your external as2 files and return responces to as3 file. Example below, hope it helps.

The code block below from a project that i did before. It was using as2 file to connect server. Cut out some block of codes hope you can sort out the solution.

// AS3 FILE
// local connection instance to communicate to AVM1 movie
var AVM_lc:LocalConnection = new LocalConnection();
AVM_lc.client = this;

// loader loads AVM1 movie
var loader:Loader = new Loader();
loader.load(new URLRequest("log2.swf"));
//addChild(loader);
// when AVM1 movie is clicked, call stopPlayback
stage.addEventListener(MouseEvent.CLICK, stopPlayback);

function stopPlayback(event:MouseEvent):void {
    // send login event to "AVM2toAVM1" connection
    AVM_lc.send("AVM2toAVM1", "logIn","test@test.com" , "123123");

}

function resulFunc(a:*){
    trace(a + " *-*-*-*-");
}
AVM_lc.connect("AVM1TO");



// AS2 FILE - log2.swf

var AVM_lc:LocalConnection = new LocalConnection();

AVM_lc.logIn = function(a , b){ 
    trace("login : " , a , " - " , b);

}
AVM_lc.connect("AVM2toAVM1");

function sendDataToAs3():Void{
    AVM_lc.send("AVM1TO", "resulFunc", "test value");
}
ymutlu
  • 6,585
  • 4
  • 35
  • 47