Wednesday, July 30, 2014

Migrating from Alchemy to CrossBridge/FlasCC - Interop between C/C++ and ActionScript

Part I - Calling C/C++ functions from AS3

For calling C/C++ functions from AS3, one way is use the "as3sig:" annotation to expose some C/C++ functions to AS3. See the CrossBridge Sample 5 SWC and my previous post http://bruce-lab.blogspot.com/2012/12/migrating-from-alchemy-to-flascc.html. Another way is to use "CModule.callI(CModule.getPublicSymbol("youCfunctionname"), args)", see the Sample 4 Animation, where for C++, you will need "extern" declaration before your function definition to prevent the compiler renaming the function.

Part II - Calling AS3 functions from C/C++

To call build-in AS3 functions, you can either use "inline_as3" (see Sample 2 Interop between C/C++ and ActionScript. Actually, asm was also available in Alchemy, although not officially documented) or the API provided by "AS3.h" and "Flash++.h". You can also define local AS3 functions or equivalent C/C++ functions using the two methods in your C/C++ source file. However, if you want to call an AS3 function outside your C/C++ file, e.g., in the "Main.as/Console.as", you may need to pass the reference of your AS3 function or the function host - your main AS3 class to C/C++. There are two different cases depending whether your run the C/C++ code in the background worker.

Case 1 - C/C++ code in UI worker.

If you invoke your C/C++'s main function using "CModule.start()", or "CModule.startAsync()", or just simply call some C/C++ function using the methods in Part I without executing the C/C++ main function, the C/C++ code will run in the UI worker, the same domain as your main AS3 console class. Then things are easy and there are various ways for passing your Main class's reference, see my examples:
https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/nobgcall

Case 2 - C/C++ code in background worker.

If you invoke your C/C++'s main function using "CModule.startBackground()", and want to call some outside AS3 function from your C/C++'s main function, then the thing become a little tricky, because you're not able to share a function reference between workers, i.e., there is no way to pass a function reference from the UI worker - your Main/Console class to the background worker - your C/C++ code, as the class/function reference can't be serialized in AMF3 format. There is one way to circumvent the problem, using MessageChannels:
https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/bgcall

In other situations, you can access your Main UI class's properties from the background worker by the "avm2_ui_thunk" and "CModule.serviceUIRequests" combinations, see http://bruce-lab.blogspot.com/2014/07/crossbridge-quake1-example-simplified.html for details.


Links:
http://forums.adobe.com/message/6002640#6002640

http://www.bytearray.org/?p=4423
http://www.bytearray.org/?p=4423#comment-494548

http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-8000.html
http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-7fff.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Worker.html

http://jacksondunstan.com/articles/tag/workers
http://esdot.ca/site/2012/intro-to-as3-workers-hello-world
http://probertson.com/articles/2012/11/07/as3-concurrency-workers-use-cases-best-practices-links/