8 Replies Latest reply on Sep 2, 2011 1:46 AM by ForrestGimp

    callAS() only talks to first Flash-RMA in ressources

    ForrestGimp Level 1

      Hi

       

      I'm using swfs as interfaces for manipulating 3D-annotations. This requires interaction between the RMAs ActionScript and Acrobats JavaScript using the ExternalInterface-Class provided by Flash. When callin an AS-method from JS I use

      this.getAnnotsRichMedia(0)[0].callAS('methodname');

       

      It works fine so far. I can call all methods of a single swf exposed via the ExternalInterface.

       

      But now a more complex situation has come up. It requires me to use several swfs for one 3D-annotation. However, I can only use callAS to call the first swf I have added. If I remove it, the next one will assume its place. I suspect that ressources are handled as an array, and callAS will only ever address the very first flash-element it comes across. Is there any way to address specific swfs in the ressources of an RMA?

       

      I have already tried a kind of call-to-all-broadcasting, giving each swf an AS-method with the same name, but it's still only executed by the first swf (not quite a surprise there).

        • 1. Re: callAS() only talks to first Flash-RMA in ressources
          Dave Merchant MVP & Adobe Community Professional

          You don't make it clear how you're embedding this stuff - are the SWF files added as resources to a type=3D annotation, or are they separate type=RichMedia annotations on the page? If the former, how are you loading them?

           

          getAnnotsRichMedia(pageNum) returns an array, so member [0] is the first RMA on the page, [1] is the second, and so on. The array is in the order they appear in the PDF structure, but you can grab specific ones using getAnnotRichMedia(name) - see the SDK docs.

           

          If you're targeting FlashMovie objects loaded into a 3D scene, you must use the .call() method on the FlashMovie object itself, not the callAS() method on the annotation (which doesn't exist if the annot is 3D). There's a bug in the 3D API, so currently FlashMovie.call() has no return value but it talks to the SWF just fine.

          • 2. Re: callAS() only talks to first Flash-RMA in ressources
            ForrestGimp Level 1

            Thanx for the reply.

             

            What I do is the following:

             

            1. I add a 3D-Annotation using the 3D-tool and a file of type .u3d

            2. rightclick/properties gives me the properties-panel of the 3D-annotation

            3. in the resources-tab I add two separately programmed swfs. They are GUI-elements, say one for displaying and hiding predefined mesh-selections, and one for displaying info-texts in several languages. They are completely independent, but both need to be accessible by document-javaScripts for some of their functionality. They are layed out to have different positions on the screen, so I can add them both as foreground (though the placement foreground/background doesn't seem to make any difference).

            4. By adding the flash-swfs to the resources the 3D-annotation secretly becomes an RMA, thus I can now (only) access it using getAnnotsRichMedia()[].
            5. If there was only one swf in the RMA, I could now just use callAS() to directly run AS-methods of the swf in the ressources of the 3D-RMA. However, there are two.

             

            callAS() still works, but only for running methods of the GUI-swf I have added first. When I try to use callAS to run methods of the swf which was added secondly, I get "undefined" as a returnvalue, and the method doesn't execute. I have found the flashMovie-object in the documentation (and the call()-function), but I couldn't figure out how to access a particular flashMovie-resource (or all of them). Is there some undocumented sceneObjectList for accessing resources?

            • 3. Re: callAS() only talks to first Flash-RMA in ressources
              Dave Merchant MVP & Adobe Community Professional

              Ouch.. OK...

               

              If you set a SWF on the Resources tab to bind the foreground or background, it is not on the sceneObjectList and there's no documented way to reference it via the API, even if you create a second object from the same Resource, the two are references rather than instances.

               

              If you bind your SWF to the background or foreground using JavaScript (create a new FlashMovie object and attach it), each use of the object you create is instanced, so you can talk to the object directly even after it's been childed to the canvas.

               

              For example, suppose there's a 3D scene with a Resource attached "my.swf" - with no binding. Your 3D script can say:

               

               

              fm = new FlashMovie("my.swf");

              scene.background.flashMovie = fm;

              fm.call("doSomething","variable");

               

               

              Note the use of ".flashMovie" rather than ".FlashMovie" - documentation bug in the SDK, sorry.

              1 person found this helpful
              • 4. Re: callAS() only talks to first Flash-RMA in ressources
                ForrestGimp Level 1

                Failed again in asking a question Dave Merchant can't answer.....

                 

                 

                Thanx a lot. It's not ideal, but I can handle it this way. I was about to try some really weird workarounds. Would have made me bite my keyboard, if the weather weren't so nice. Still, I would recommend making resources more accessible in the future. Something like this

                this.getAnnotsRichMedia(0)[0].getResourceByName("mySwf").call('methodname');
                his.getAnnotsRichMedia(0)[0].getResourceByIndex(2).call('methodname');
                or
                this.getAnnotsRichMedia(0)[0].resources[2].call('methodname');

                 

                That would be much more consistent with the rest of the implementation. I think I should post that as a feature-request.

                • 5. Re: callAS() only talks to first Flash-RMA in ressources
                  Dave Merchant MVP & Adobe Community Professional

                  There's actually a reason why Resources aren't accessible until they've been turned into an object - you attach pretty much anything as a Resource (not to put too fine a point on it, the JSAPI methods aren't designed to fail gracefully if the thing being shouted at turns out to be a jpeg), plus there's no ActionScript in memory until your SWF is loaded into the Flash Player runtime (which lurks inside the viewport once it's magically flipped itself into a RichMedia annot). The act of calling "new FlashMovie()" does that loading of code, and the returned object is your JS>AS communication tunnel irrespective of where the SWF ends up being displayed. You don't need to add the FlashMovie object to the Stage (i.e. the 3D canvas), merely creating the object is enough to allow you to communicate - but of course until it's on the Stage it has no timeline and no way to indicate a response. You can even put the same FlashMovie in the scene multiple times, they'll all react as one (if you don't want that to happen, create several FlashMovies from the same Resource).

                   

                  Let's suppose you want to add a SWF to the 3D canvas' foreground plane, send some params before binding it, then some others after. Both will work*..

                   

                  fm = new FlashMovie("my.swf");

                  fm.call("doSomething","with this");

                  scene.addForegroundSprite(fm);

                  fm.call("doAnotherThing","with a puppy");

                   

                  As this is dancing on the smudgy edge of the 3D JSAPI there are some exceptions in terms of what properties of FlashMovie can be changed after the bind event, and some "unexpected behaviors", but in general once the object has a name, it's listening to you. It can't reply yet, but it can be told to do stuff.

                   

                   

                   

                   

                  *(high five to Leonard)

                  1 person found this helpful
                  • 6. Re: callAS() only talks to first Flash-RMA in ressources
                    ForrestGimp Level 1

                    Apparently I will yet have to eat my keyboard after all.

                     

                    call() doesn't work. Neither with two swf-files stuffed into one annotation, nor with one. I'm not sure why, the first part of the procedure gives the expected result.

                    - I add the swfs as resource (I don't asign them any location).

                    - In the script I load them as a resource as pointed out, and assign them to the background (by the way: what about foreground? I tested that as well, and it didn't work).

                    - Once I start the annotation the swfs appear as expected. Checking the variable-references in the console shows they are actually objects of type FlashMovie. However, calling exposed methods using call("methodname") doesn't work. to be clear about what I did:

                     

                    In the annotation-script:

                    this.mySWF = new FlashMovie("test1.swf");

                    scene.background.flashMovie = this.mySWF;

                    console.println( this.mySWF);

                     

                    I added the script and activated the annotation.

                     

                     

                    In the console:

                    Result of the println-command: [object FlashMovie], so it seems to have completely worked as it should.

                     

                    Then I typed

                    this.getAnnotsRichMedia(0)[0].context3D.mySWF.call('update');

                    Result: undefined (which was expected) but no reaction from the exposed AS-method either. It was not executed.

                    The final test: Without changing anything I typed in

                    this.getAnnotsRichMedia(0)[0].callAS('update');

                    Result: Success. It works. So we're back to square one.

                    • 7. Re: callAS() only talks to first Flash-RMA in ressources
                      Dave Merchant MVP & Adobe Community Professional

                      FlashMovie.call() does work, but you HAVE to send it at least one parameter (therefore your AS function has to accept one of a matching type).

                       

                      For example, if the AS3 function exposed by ExternalInterface is

                       

                      function sayHello(_str:String):void {}

                       

                      then in your 3D JS you can call

                       

                      myFlashMovie.call("sayHello","and goodbye");

                       

                      BUT if your AS3 is

                       

                      function sayHello():void {}

                      or

                      function sayHello(_str:String):void {}

                       

                      then a 3D JS call to

                       

                      myFlashMovie.call("sayHello");

                      or

                      myFlashMovie.call("sayHello",true,123);

                       

                      will fail.

                       

                       

                      The return value of the AS3 function doesn't matter - if it's void or not, you'll still see "undefined" in response to a call().

                       

                       

                      Yeah, I should have explained that someplace long ago.. but now you know.

                       

                       

                      If you want to send over any code or discuss in detail, PM me.

                      • 8. Re: callAS() only talks to first Flash-RMA in ressources
                        ForrestGimp Level 1

                        Tons of thanks to you! It works now.