AS3 using Workers - actionscript-3

IDE: FLASH CS6 Professional
SDK: AIR 18 for Android
I'm trying to use Workers for my app.
The problem is, it doesn't work that it suppose to be.
public class Main extends Sprite {
private var worker:Worker;
public function Main() {
var ba:ByteArray = this.loaderInfo.bytes;
if(Worker.current.isPrimordial){
worker = WorkerDomain.current.createWorker(ba);
worker.start();
trace("Created Main");
}else{
trace("Created Worker");
}
}
}
It should output
Created Main
Created Worker
but i'm only getting
[SWF] Test.swf - 2831 bytes after decompression
Created Main
[UnloadSWF] Test.swf
Test Movie terminated.
EDIT:
Ok i tried to publish the app and ran it. It works like it should be. But why doesn't it work when i try to ran it with Adobe Debug Launcher ?
This is what it looks like on Android Debug Launcher (ADL)
ADL
This is what it looks like when Published.
Published
EDIT 2:
Tried it with Flash Professional CC 2015. Upgraded to AIR SDK 19.0.0.213.
Still the same result. What a pain Adobe.

It should work, but Flash Pro CS6 doesn't show the worker's trace statements. Check flashlog.txt or send messages from the worker to the main SWF over a MessageChannel.

I made a lib to support use of Workers, if you want use you can check it in GitHub, it is open source project.. hope help ASWorker Link
The implementation is like this
package
{
import com.tavernari.asworker.ASWorker;
import com.tavernari.asworker.notification.NotificationCenter;
import com.tavernari.asworker.notification.NotificationCenterEvent;
import flash.display.Sprite;
public class ASWorkerDemo extends Sprite
{
private var asWorker:ASWorker;
//BOTH AREA
public function ASWorkerDemo()
{
//important know, all class start here will be replicated in all works.
asWorker = new ASWorker(this.stage, uiWorkerStartedHandler, backWorkerStartedHandler);
}
//BOTH AREA END
//UI AREA START
private function uiWorkerStartedHandler():void{
//implement all class or calls for your UI
NotificationCenter.addEventListener("FROM_BACK_EVENT_MESSAGE", onFromBackEventMessageHandler );
}
private function onFromBackEventMessageHandler(e:NotificationCenterEvent):void
{
trace(e.data);
if(e.data == "completed job"){
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("NEXT_MESSAGE") );
}
}
//UI AREA END
//BACK AREA START
private function backWorkerStartedHandler():void{
//implement all class or calls for your BACK operations
NotificationCenter.addEventListener("NEXT_MESSAGE", uiCallForNextMessageHandler );
}
private function uiCallForNextMessageHandler():void
{
for(var i:int = 0; i < 15; ++i){
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("FROM_BACK_EVENT_MESSAGE", false, i) );
}
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("FROM_BACK_EVENT_MESSAGE", false, "completed job") );
}
// BACK AREA END
}
}
Good luck with Workers

Air 20.0.0.204 ADL is also not enjoying anything worker related (from my limited experimentation), however the desktop Flash Player seems to work just fine. This makes debugging convoluted and problematic when you are using Air specific libraries in your project and prefer not to wildcard variable types.

At the moment, workers are only supported on desktop platform. This Adobe developer's guide page specifically mentions "for desktop platforms".
Meanwhile, there is an AS3-Worker-Compat library by Jeff Ward that enables you to write code with Workers that will still work correctly in an environment that doesn't support Workers (of course, in this case your code will run in single-threaded mode).
I think many people are waiting for Adobe to implement workers for mobile, hopefully it will come in the future.

Related

GameInput.DEVICE_ADDED not triggering at application startup

I'm posting this question because i'm having a little problem with the GameInput API in an adobe AIR desktop app.
I tested the API in a test app and it worked just fine. However, when i added it to my real app (a game), it doesn't trigger anymore at startup.
Everything else works, and if i disconnect/reconnect the controller, everything works fine. However, the initial trigger of the callback function isn't working anymore.
Any idea why ?
Here's what i do:
if (GameInput.isSupported) //GAMEPADS SUPPORT
{
gameInput = new GameInput();
gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, controllerAdded);
gameInput.addEventListener(GameInputEvent.DEVICE_REMOVED, controllerRemoved);
gameInput.addEventListener(GameInputEvent.DEVICE_UNUSABLE, controllerProblem);
} //GAMEPAD SUPPORT
public function controllerAdded(e:GameInputEvent):void
{
var vec:Vector.<String> = new Vector.<String>();
gamepad = GameInput.getDeviceAt(0);
vec[0] = gamepad.getControlAt(0).id;
gamepad.enabled = true;
gamepad.sampleInterval = 10;
gamepad.startCachingSamples(5, vec); // numSamples = 5
for (var i:int = 0; i < gamepad.numControls; ++i)
gamepad.getControlAt(i).addEventListener(Event.CHANGE, handleChangeEvent);
}
I am guessing it could be a focus issue or something related but i really don't see why this would be happening.
My app looks like this:
Core (class called from swf and manages the whole app)
Screens (different classes that inherit movieclip but have logic inside, such as game, optionscreen, etc.)
The Gameinput api intialization is done in the core, after the instanciation of the object (using Event.ADDED_TO_STAGE).
The GameInputEvent class represents an event that is dispatched when a game input device has either been added or removed from the application platform
So if you launch the app and allready have a device, no event will be triggered which sounds like your issue. Why don't you just check devices during intialization and then work with them at that point?
if (GameInput.isSupported) //GAMEPADS SUPPORT
{
gameInput = new GameInput();
gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, controllerAdded);
gameInput.addEventListener(GameInputEvent.DEVICE_REMOVED, controllerRemoved);
gameInput.addEventListener(GameInputEvent.DEVICE_UNUSABLE, controllerProblem);
if(GameInput.numDevices > 0) {
/*enter code here/*
}
}
Well it seems the GameInput API by Adobe is too unstable.
I've decided to use AirControl instead and it works much better...
I'm therefore closing this question.

Worker getting null when retrieving shared property

For some reason, when I try to receive a shared property from a Worker (in AS3), the result is always null. That is, I send a value to a Worker using setSharedProperty(), when I retrieve it using getSharedProperty(), it always returns undefined/null.
Here's a simple test I set up:
package
{
import flash.display.Sprite;
import flash.system.Worker;
import flash.system.WorkerDomain;
public class Main extends Sprite
{
private var _worker:Worker;
public function Main():void
{
if (Worker.current.isPrimordial)
{
initMain();
}
else
{
initWorker();
}
}
private function initMain():void
{
_worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes);
_worker.setSharedProperty("message", "test");
_worker.start();
}
private function initWorker():void
{
_worker = Worker.current;
var message:String = _worker.getSharedProperty("message");
trace(message);
}
}
}
When I trace message, the result is null. Although my main goal is to make an AIR app, I get the same result whether I'm compiling for AIR (3.7) or Flash Player (11.6, for some reason 11.7 doesn't recognise flash.system.Worker as a valid class).
I'm compiling using the Flex SDK, through FlashDevelop. Does anybody know what's wrong, maybe I've missed something in my code?
FlashDevelop now seems to have complete support for debugging workers which really wasn't the case on older versions (you could neither break, or trace inside workers). AIR SDK workers support has also progressed (I remember things working in release would break in debug version)
I just recompiled your sample with AIR SDK 14 release (14.0.0.110)
air14_sdk_win/bin/mxmlc -swf-version=25 -debug=true Main.as
and debugged it with Shockwave Flash Debugger 14,0,0,125 and FlashDevelop 4.6.1.30 and got the expected result:
[Starting debug session with FDB]
Created Worker 2
test
Beware that any element not up-to-date in your debugging chain (sdk/player/debugger) could result in problems for debugging workers

Pulling up to 12 RTMP streams

I am VERY new to this site! I have been reading the codes for the past few nights! From Publishing a flash project with network access so it can contact the internet to RTMP applications and streaming. But I have hit a wall and I do not want to go off the wrong path as most of my work is bits and pieces of helpful information on this site. And please appologize I'm not the boss of a company, so I do not do much of the coding any more and i have surely forgotten most of my PHP coding background, Please do not smite me for dumb or"noob". But since I have made it this far with the flash and actionscripts3 programming I thought it would not hurt if I asked a few questions from much smarter people!
Currently I am working on a single windowed flash project that will allow me to pull up to 12 live RTMP streams. Currently with everything i have been able to do, I have a working code so far to JUST pull a single RTMP string. Took me 3 days of code that was pulled off the internet, to get it to work. i have been successful in getting one stream with action script
package com.endseven {
import flash.events.NetStatusEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import com.endseven.RTMPStream;
public class Downstream extends RTMPStream {
/* the constructor. */
public function Downstream():void {
trace("Downstream object has been created."); // debug trace..
this.oVideo = new Video(640, 480);
this.oConnection = new NetConnection();
this.oConnection.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oConnection.connect(this.sMediaServerURL);
}
/* triggered when a net status event is received. */
private function eNetStatus(oEvent1:NetStatusEvent) {
trace("NetStatusEvent: " + oEvent1.info.code); // debug trace..
switch (oEvent1.info.code) {
case "NetConnection.Connect.Success":
// create a stream for the connection..
this.oNetStream = new NetStream(oConnection);
this.oNetStream.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oNetStream.bufferTime = 5; // set this to whatever is comfortable..
// listen for meta data..
this.oMetaData.onMetaData = eMetaDataReceived;
this.oNetStream.client = this.oMetaData;
// attach the stream to the stage..
this.oVideo.attachNetStream(oNetStream);
this.oNetStream.play(sStreamName);
this.addChildAt(this.oVideo, 0);
trace("Connected to the RTMP server."); // debug trace..
break;
case "NetConnection.Connect.Closed":
trace("Disconnected from the RTMP server."); // debug trace..
break;
case "NetStream.Play.StreamNotFound":
trace("This stream is currently unavailable."); // debug trace..
break;
}
}
}
}
This is the actionscript3 code that is the only code i have gotten to work. But this only pulls in a single stream on a single display. I mean I could work with this and just have twelve of them. But that seems to be a waste. What is the best method to get this to work. I am very new so this next question seems even dumb to me! But cant i just create 12 flash files and import them and arrange them in a single project?

AS3 SecurityPanel not showing when hardware acceleration is used

If I publish Windows Projector (.exe) with no hardware acceleration, everything works fine, but if I select direct or gpu harware acceleration I will not get the security panel to show up at all. Anyone else have this same issue, or is it just me?
Basically I would like to publish a stand-alone webcam game, but if I try to use getCamera(), the user will not see the security question at all, and I will not get the camera initialized.Does anyone know a workaround for this? I would love to get HW acceleration to my game.
import flash.system.Security;
import flash.system.SecurityPanel;
//import flash.media.Camera;
Security.showSettings(SecurityPanel.CAMERA);
//var camera:Camera=Camera.getCamera();
I got this to work, but I created a projector through the stand alone and the "Create Projector" menu, not through the Flash IDE. I was able to get the panel to show up using the latest flash.
compiler settings: -swf-version=16 -use-gpu=true
// test showing stage3D + panel
final public class Test extends Sprite {
private var cam:Camera;
private var video:Video = new Video();
public function Test():void {
var stage3D:Stage3D = stage.stage3Ds[0];
stage3D.addEventListener(Event.CONTEXT3D_CREATE, handleContext);
stage3D.requestContext3D();
trace(cam.name);
}
/**
* #private
*/
private function handleContext(e:Event):void {
var stage3D:Stage3D = stage.stage3Ds[0];
var context:Context3D = stage3D.context3D;
context.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0, true);
context.clear(0,0,0,1);
context.present();
Security.showSettings(SecurityPanel.CAMERA);
cam = Camera.getCamera();
cam.setMode(640,360,30);
video.attachCamera(cam);
// change to upload via texture instead
addChild(video);
}
In my experience, hardware acceleration gains are only very minimal without using specific gpu apis. Camera in my experience instead accelerated, only specific types of video decompression. If you're not using Stage3D, you probably won't get any visible gains.

Flash SecurityDomain, P2P settings and multiply swfs

I have two swfs:
application swf
p2p client swf that allows to load data using rtmfp replication
technology (through cirrus service)
The main idea is to have one p2p loader on the certain domain that will able to work in p2p network without asking many times for permission for each domain, so for instance:
application 1 (http://domain1.com/app.swf) |
application 2 (http://domain2.com/app.swf) | <--> p2p data loader (http://domainp2p.com/p2pcli.swf)
application N (http://domainN.com/app.swf) |
The p2p client loads binary data by request, content really does not matter I believe.
So, I load p2pclient swf using following class (app.swf)
public class ClientLoader {
// .. some code
public function load(cb:Function, err:Function):void
{
_cb = cb;
_err = err;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaded);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _onIoError);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _onSecurityError);
// note that context has neither application domain nor security domain
loader.load(new URLRequest(_url), new LoaderContext());
}
private function _onLoaded(e:Event):void
{
trace("Loaded. Connecting to the p2p network...");
_client = e.target.content;
_client.addEventListener(Event.CONNECT, _onClientReady);
_client.connect();
}
private function _onClientReady(e:Event):void
{
_cb(_client);
}
}
}
The p2pclient itself (p2pcli.swf):
public class P2P extends Sprite
{
public function SqP2P() {
Security.allowDomain("*");
}
public function connect():void
{
_connection = new NetConnection();
_connection.addEventListener(NetStatusEvent.NET_STATUS, _netStatus);
_connection.connect(CIRRUS_ADDRESS, CIRRUS_KEY);
// after successful connect this method called
_loadGroup();
}
private method _loadGroup():void
{
var spec:GroupSpecifier = new GroupSpecifier(_name);
spec.serverChannelEnabled = true;
spec.objectReplicationEnabled = true;
_group = new NetGroup(connection, spec.groupspecWithAuthorizations());
_group.addEventListener(NetStatusEvent.NET_STATUS, _netStatus);
}
private function _netStatus(event:NetStatusEvent):void
{
trace("NetStatusEvent:", event.info.code);
}
}
But it looks like that Flash Player ignores the security session and is trying to save the pop-up settings for the domain that app.swf belongs to, but not for the p2pcli.swf domain. Why?!
I have absolutely same code, but p2pcli.swf replaced with swf that stores data in Local Shared Object and all the domain1-2-N.com has access to it.
Any ideas?
I know, my English is crap :(
I really am not totally sure, but I'll throw my answer out there in case it is helpful.
Based on the general purpose of such security messages, I'm not entirely sure you CAN keep that dialog from showing up. In some cases, I'm certain Peer Assisted Networking can be a security risk for some people (and anyway, it is using their bandwidth.) The settings for turning on and off that notification are user-side, in the Flash settings dialog (Control Panel in Windows 7...), thus that hints that it is inherently hardwired into the Flash platform.
Of course, since I'm more of an Adobe AIR specialist, I could be completely wrong...for your project's sake, I'm sincerely hoping I AM!
And, for the record, your English was almost perfect. I tweaked one paragraph for clarity, but otherwise, spot on. :D