Operating on ActionScript objects in C++

FlasCC allows you to create a SWC file from a C++ library. This is useful if you have an existing ActionScript project and want to add some logic that is already written in C++. This post demonstrates how you can operate on ActionScript objects that were passed as parameters into functions of a C++ library.

This post assumes you already know how to compile a SWC in FlasCC. If you do not know how see the samples/05_SWC sample application that ships with the FlasCC SDK.

The AS3++.h library exposes some functions to make it easier to operate on ActionScript objects within C++.

Getting a property

Getting the value of a property of an ActionScript object is pretty straightforward by using the getproperty() function.

In the sample code below the getDelta() C++ function demonstrates this.

Setting a property

Setting the value of a property is also straightforward by using the setproperty() function.

In the sample code below the setDelta() C++ function demonstrates this.

Calling a method

Calling a method is slightly more involved as you need to first use getproperty() on the name of the method to get a Function var that represents that method. Then pass that object into the call() or call_v() functions.

In the sample code below the getString() C++ function demonstrates this.

Sample Code

Here is a sample C++ library that demonstrates how to do each of these operations.

When compiling this library using g++ remember to set the -lAS3++ flag as described in the AS3++ documentation.

#include <stdio.h>
#include "AS3/AS3.h"
#include "AS3/AS3++.h"
 
 
////
//
// Get a property of an ActionScript object in C++
//
////
 
void getDelta() __attribute__((used,
    annotate("as3import:flash.events.MouseEvent"),
    annotate("as3sig:public function getDelta(m:MouseEvent):int"),
    annotate("as3package:MyLibrary")));
 
void getDelta()
{
    // marshall the AS3 parameter into a C++ variable
    AS3::local::var mouseEvent;
    AS3_GetVarxxFromVar(mouseEvent, m);
 
    // now that we have it in C++ let's get a property on that object
    AS3::local::var propertyName = AS3::local::internal::new_String("delta");
    AS3::local::var outputValue = AS3::local::internal::getproperty(mouseEvent, propertyName);
 
    // convert the var to a scalar
    int output = AS3::local::internal::int_valueOf(outputValue);
 
    // return that scalar value
    AS3_Return(output);
}
 
 
////
//
// Set a property on an ActionScript object in C++
//
////
 
void setDelta() __attribute__((used,
    annotate("as3import:flash.events.MouseEvent"),
    annotate("as3sig:public function setDelta(m:MouseEvent):void"),
    annotate("as3package:MyLibrary")));
 
void setDelta()
{
    // marshall the AS3 parameter into a C++ variable
    AS3::local::var mouseEvent;
    AS3_GetVarxxFromVar(mouseEvent, m);
 
    // now that we have it in C++ let's set a property on that object
    AS3::local::var propertyName = AS3::local::internal::new_String("delta");
    AS3::local::var newValue = AS3::local::internal::new_int(5);
    AS3::local::internal::setproperty(mouseEvent, propertyName, newValue);
}
 
 
////
//
// Call a method of an ActionScript object in C++
//
////
 
void getString() __attribute__((used,
    annotate("as3import:flash.events.MouseEvent"),
    annotate("as3sig:public function getString(m:MouseEvent):String"),
    annotate("as3package:MyLibrary")));
 
void getString()
{
    // marshall the AS3 parameter into a C++ variable
    AS3::local::var mouseEvent;
    AS3_GetVarxxFromVar(mouseEvent, m);
 
    // demonstrate how to call a function of that object from C++
    AS3::local::var functionName = AS3::local::internal::new_String("toString");
    // first get the property of the object called "toString" which is a Function var
    AS3::local::var function = AS3::local::internal::getproperty(mouseEvent, functionName);
 
    // then call that Function object (in this case it takes no parameters)
    AS3::local::var output = AS3::local::internal::call(function, AS3::local::internal::_null, 0, NULL);
 
    // Since AS3_Return (as shown in getDelta()) can only accept a scalar value we need
    // to marshall this C++ object into an ActionScript String and return it using AS3_ReturnVar
    AS3_DeclareVar(asOutputString, String);
    AS3_CopyVarxxToVar(asOutputString, output);
    AS3_ReturnAS3Var(asOutputString);
}
 
int main()
{
    // The SWC still needs a main() function.  
    // See the code comments in samples/05_SWC for more details.
    AS3_GoAsync();
}

And here is a sample ActionScript application that demonstrates how to call the methods in the SWC generated from that C++ library:

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import MyLibrary.CModule;
 
    public class demo extends Sprite {
        public function demo() {
            addEventListener(Event.ADDED_TO_STAGE, initCode);
        }
 
        private function initCode(e:Event):void {
            var tf:TextField = new TextField();
            addChild(tf);
 
            // start the FlasCC library
            MyLibrary.CModule.startAsync(this);
 
            // a sample ActionScript object
            var me:MouseEvent = new MouseEvent("click");
 
            //
            // Get a property
            //
            tf.appendText("delta=" + MyLibrary.getDelta(me) + "\n");
 
            //
            // Set a property
            //
            MyLibrary.setDelta(me);
            tf.appendText("delta=" + me.delta + "\n");
 
            //
            // Call a method
            //
            tf.appendText("toString=" + MyLibrary.getString(me) + "\n");
 
        }
    }
}