Skip to content

Instantly share code, notes, and snippets.

@sonygod
Last active December 16, 2015 09:19
Show Gist options
  • Select an option

  • Save sonygod/5412347 to your computer and use it in GitHub Desktop.

Select an option

Save sonygod/5412347 to your computer and use it in GitHub Desktop.
haxe flash js remoting use async flash---async ---js js----async--flash this version only work on firefox, I don't know why ,maybe haxe Timer ge tsomthing wrong. try to build this ,you need tinkerbell r6388 , hx-async full code and project here https://github.com/sonygod/fj_aync
package ;
import haxe.ds.ObjectMap;
import haxe.ds.StringMap;
import haxe.Timer;
import haxe.remoting.ExternalConnection;
import tink.lang.Cls;
import Format;
/**
* ...
* @author sonygod
*/
class FlashMain {
public function foo(x, y) { trace("outsidecall" + x + y); }
static var js:ExternalConnection = null;
static var hello;
public static var onData: Dynamic;
public static function main() {
var ctx = new haxe.remoting.Context();
ctx.addObject("FlashMain", FlashMain);
js = haxe.remoting.ExternalConnection.jsConnect("default", ctx);
var arr:Array<Int> = [1, 2];
var arr2=arr.slice(0, arr.length - 1);
hello = new Forwarder(js);
hello.sayHello("hi", "god", onCalljs);
}
public static function onCalljs(err, data) {
trace("回来了,靠"+err+data);
}
public static function __onData(args: Array<Dynamic>) {
//trace(args.toString() + "" + Timer.stamp() * 1000);
var recall = args.pop();
trace(args.toString() + "" + Timer.stamp() * 1000);
var xxx:StringMap<CallBackObjWithFun> = js.getcallBackList();
var f :CallBackObjWithFun= xxx.get(recall.id + recall.name);
trace(f.id+f.name+f.callBack);
Reflect.callMethod(FlashMain, f.callBack, args);
}
private static function __init__() : Void {
onData = Reflect.makeVarArgs(__onData);
}
}
class Forwarder implements Cls {
var fields:Hash<Dynamic> = new Hash<Dynamic>();
public var recallFuns:ObjectMap<Caller ,Dynamic>=new ObjectMap<Caller ,Dynamic>();
@:forward(!multiply) var target:ExternalConnection;
@:forward function fwd2(hello:HelloService) {
get: fields.get($name),
set: fields.set($name, param),
call:target.resolve("main").resolve("onData").call($argsRemoting)
}
public function new(target) {
this.target = target;
}
}
typedef Caller = {
id:String,
name:String
}
@sonygod
Copy link
Copy Markdown
Author

sonygod commented Apr 18, 2013

/*

  • Copyright (C)2005-2012 Haxe Foundation
    *
  • Permission is hereby granted, free of charge, to any person obtaining a
  • copy of this software and associated documentation files (the "Software"),
  • to deal in the Software without restriction, including without limitation
  • the rights to use, copy, modify, merge, publish, distribute, sublicense,
  • and/or sell copies of the Software, and to permit persons to whom the
  • Software is furnished to do so, subject to the following conditions:
    *
  • The above copyright notice and this permission notice shall be included in
  • all copies or substantial portions of the Software.
    *
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  • AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  • LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  • DEALINGS IN THE SOFTWARE.
    */
    package haxe.remoting;

/**
Synchronous communications between Flash and Javascript.
**/
@:expose
class ExternalConnection implements Connection implements Dynamic {

var __data : { name : String, ctx : Context, #if js flash : String #end };
var __path : Array<String>;

function new( data, path ) {
    __data = data;
    __path = path;
}

public function resolve(field) : Connection {
    var e = new ExternalConnection(__data,__path.copy());
    e.__path.push(field);
    return e;
}

public function close() {
    connections.remove(__data.name);
}

#if flash9
static function escapeString( s : String ) {
    return s.split("\\").join("\\\\");
}
#elseif flash
static function escapeString( s : String ) {
    return s.split("\\").join("\\\\").split("&").join("&amp;");
}
#else
static inline function escapeString(s) {
    return s;
}
#end


public function call( params : Array<Dynamic> ) : Dynamic {


    #if flash
     var callBackF = params.pop();
     var p:CallBackObj = params[params.length - 1];
     callBackList.set(p.id + p.name, { id:p.id, name:p.name, callBack:callBackF } );
     #end

    var s = new haxe.Serializer();
    s.serialize(params);
    var params = escapeString(s.toString());
    var data = null;
    #if flash
        data = flash.external.ExternalInterface.call("haxe.remoting.ExternalConnection.doCall",__data.name,__path.join("."),params);
    #elseif js
        var fobj : Dynamic = untyped window.document[__data.flash];
        if( fobj == null ) fobj = untyped window.document.getElementById(__data.flash);
        if( fobj == null ) throw "Could not find flash object '"+__data.flash+"'";
        try data = fobj.externalRemotingCall(__data.name,__path.join("."),params) catch( e : Dynamic ) {};
    #end
    if( data == null ) {
        #if js
        var domain, pageDomain;
        try {
            // check that swf in on the same domain
            domain = fobj.src.split("/")[2];
            pageDomain = js.Browser.window.location.host;
        } catch( e : Dynamic ) {
            domain = null;
            pageDomain = null;
        }
        if( domain != pageDomain )
            throw "ExternalConnection call failure : SWF need allowDomain('"+pageDomain+"')";
        #end
        throw "Call failure : ExternalConnection is not " + #if flash "compiled in JS" #else "initialized in Flash" #end;
    }

    return new haxe.Unserializer(data).unserialize();
}

    public function callWithCallBack( params : Array<Dynamic> ) : Dynamic {


        return call(params);
    }

static var connections = new haxe.ds.StringMap<ExternalConnection>();
 static var  callBackList = new haxe.ds.StringMap<CallBackObjWithFun>();

 public function getcallBackList():haxe.ds.StringMap<CallBackObjWithFun> {
    return callBackList; 
 }

@:keep
static function doCall( name : String, path : String, params : String ) : String {
    try {
        var cnx = connections.get(name);
        if( cnx == null ) throw "Unknown connection : "+name;
        if( cnx.__data.ctx == null ) throw "No context shared for the connection "+name;
        var params = new haxe.Unserializer(params).unserialize();
        var ret = cnx.__data.ctx.call(path.split("."),params);
        var s = new haxe.Serializer();
        s.serialize(ret);
        #if flash
        return escapeString(s.toString());
        #else
        return s.toString()+"#";
        #end
    } catch( e : Dynamic ) {
        var s = new haxe.Serializer();
        s.serializeException(e);
        return s.toString();
    }
    #if as3
    return "";
    #end
}

#if flash

public static function jsConnect( name : String, ?ctx : Context ) {
    if( !flash.external.ExternalInterface.available )
        throw "External Interface not available";
    #if flash9
    try flash.external.ExternalInterface.addCallback("externalRemotingCall",doCall) catch( e : Dynamic ) {};
    #else
    flash.external.ExternalInterface.addCallback("externalRemotingCall",null,doCall);
    #end
    var cnx = new ExternalConnection({ name : name, ctx : ctx },[]);
    connections.set(name,cnx);
    return cnx;
}

#elseif js

public static function flashConnect( name : String, flashObjectID : String, ?ctx : Context ) {
    var cnx = new ExternalConnection({ ctx : ctx, name : name, flash : flashObjectID },[]);
    connections.set(name,cnx);
    return cnx;
}

#end

}

typedef CallBackObj = {
id:String,
name:String,

}
typedef CallBackObjWithFun = {
>CallBackObj,
callBack:Dynamic,
}

@sonygod
Copy link
Copy Markdown
Author

sonygod commented Apr 18, 2013

package tink.lang.macros;

import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
import tink.macro.build.Member;
import tink.macro.build.MemberTransformer;

using tink.macro.tools.MacroTools;
using StringTools;
using Lambda;
using tink.core.types.Outcome;

typedef ClassFieldFilter = ClassField->Bool;
typedef ForwardRules = { call:Null, get:Null, set:Null };

class Forward {
static inline var TAG = ":forward";
static public function process(ctx:ClassBuildContext) {
new Forward(ctx.has, ctx.add, ctx.cls.isInterface).processMembers(ctx.members);
}
var hasField:String->Bool;
var addField:Member->?Bool->Member;
var ownerIsInterface:Bool;
function new(hasField, addField, ownerIsInterface) {
this.hasField = hasField;
this.addField = addField;
this.ownerIsInterface = ownerIsInterface;
}
function processMembers(members:Array) {
for (member in members)
switch (member.extractMeta(TAG)) {
case Success(tag):
switch (member.kind) {
case FVar(t, ):
forwardTo(member, t, tag.pos, tag.params);
case FProp(
, _, t, _):
forwardTo(member, t, tag.pos, tag.params);
case FFun(f):
member.excluded = true;
forwardWithFunction(f, tag.pos, tag.params);
}
default:
}

}
function forwardWithFunction(f:Function, pos:Position, params:Array<Expr>) {
    var rules = {
        call: null,
        get: null,
        set: null
    };
    switch (f.expr.expr) {
        case EObjectDecl(fields):
            for (field in fields) 
                switch (field.field) {
                    case 'get':  rules.get = field.expr;
                    case 'set':  rules.set = field.expr;
                    case 'call': rules.call = field.expr;
                }
        default: f.expr.reject();
    }

    var filter = makeFilter(params);
    for (arg in f.args) 
        forwardWith(arg.name, rules, arg.type, pos, filter);
}
function forwardWith(id:String, rules:ForwardRules, t:ComplexType, pos:Position, filter:ClassFieldFilter) {
    var fields = t.toType(pos).sure().getFields().sure();
    for (field in fields) 
        if (field.isPublic && filter(field) && !hasField(field.name)) {
            switch (field.kind) {
                case FVar(read, write):
                    forwardVarWith(id, rules.get, rules.set, isAccessible(read, true), isAccessible(write, false), field.name, field.type.toComplex(), pos);
                case FMethod(_):
                    if (rules.call != null) {
                        switch (Context.follow(field.type)) {
                            case TFun(args, ret):
                                forwardFunctionWith(id, rules.call, pos, field.name, args, ret, field.params);
                            default: 
                                pos.error('wtf?');
                        }                               
                    }
            }
        }
}
function forwardToType(t:Type, included:ClassFieldFilter, target:Expr, pos:Position, bound:Null<Bool>) {
    for (field in t.getFields().sure()) 
        if (field.isPublic && included(field) && !hasField(field.name)) {
            switch (field.kind) {
                case FVar(read, write):
                    forwardVarTo(target, field.name, field.type.toComplex(), read, write, bound);
                case FMethod(_):
                    switch (Context.follow(field.type)) {
                        case TFun(args, ret):
                            forwardFunctionTo(target, field.name, args, ret, field.params, bound);
                        default: 
                            pos.error('wtf?');
                    }
            }
        }       
}
function forwardTo(to:Member, t:ComplexType, pos:Position, params:Array<Expr>) {
    var t = t.toType(pos).sure().reduce(),
        target = ['this', to.name].drill(pos),
        included = makeFilter(params);

    forwardToType(t, included, target, pos, to.isBound);
}
function forwardFunctionWith(id:String, callExpr:Expr, pos:Position, name:String, args:Array<{ name : String, opt : Bool, t : Type }>, ret : Type, params: Array<{ name : String, t : Type }>) {
    //TODO: there's a lot of duplication with forwardFunctionTo here 
    var methodArgs = [],
        callArgs = [];


    for (arg in args) {
        callArgs.push(arg.name.resolve(pos));
        methodArgs.push( { name : arg.name, opt : arg.opt, type : arg.t.toComplex(), value : null } );
    }
    var methodParams = [].toBlock().func().params;//TODO: be less lazy
    for (param in params) 
        methodParams.push( { name : param.name, constraints: [] } );

  var argsRemoting = callArgs.slice(0, callArgs.length - 1);


  argsRemoting.push( { id:id, name:name}.toExpr() );
  argsRemoting.push(  callArgs[callArgs.length - 1] ); 





    var call = callExpr.substitute( { 

        "$argsRemoting":argsRemoting.toArray(),
        "$args": callArgs.toArray(),
        "$id": id.toExpr(),
        "$name": name.toExpr()
    });
    addField(Member.method(name, call.func(methodArgs, methodParams)));
}
function forwardVarWith(id:String, eGet:Null<Expr>, eSet:Null<Expr>, read:Bool, write:Bool, name, t, pos) {
    read = read && eGet != null;
    write = write && eSet != null;

    if (!(read || write)) return;//I hate guard clauses, but I feel very lazy now
    addField(Member.prop(name, t, pos, !read, !write));
    var vars = {
        "$name": name.toExpr(),
        "$id": id.toExpr()
    }
    if (read)
        addField(Member.getter(name, pos, eGet.substitute(vars), t));
    if (write)
        addField(Member.setter(name, pos, eSet.substitute(vars), t));
}
function forwardFunctionTo(target:Expr, name:String, args:Array<{ name : String, opt : Bool, t : Type }>, ret : Type, params: Array<{ name : String, t : Type }>, bound:Null<Bool>) {
    var methodArgs = [],
        callArgs = [],
        pos = target.pos;

    for (arg in args) {
        callArgs.push(arg.name.resolve(target.pos));
        methodArgs.push( { name : arg.name, opt : arg.opt, type : arg.t.toComplex(true), value : null } );
    }
    var methodParams = [].toBlock().func().params;//TODO: be less lazy
    for (param in params) 
        methodParams.push( { name : param.name, constraints: [] } );
    addField(Member.method(name, target.field(name, pos).call(callArgs, pos).func(methodArgs, ret.toComplex(), methodParams))).isBound = bound;
}
function isAccessible(a:VarAccess, read:Bool) {
    return switch(a) {
        case AccNormal, AccCall(_): true;
        case AccInline: read;
        default: false;
    }
}
function forwardVarTo(target:Expr, name:String, t:ComplexType, read:VarAccess, write:VarAccess, bound:Null<Bool>) {
    var pos = target.pos;
    if (!isAccessible(read, true)) 
        pos.error('cannot forward to non-readable field ' + name + ' of ' + t);
    addField(Member.prop(name, t, pos, false, !isAccessible(write, false))).isBound = bound;
    if (!hasField('get_$name'))
        addField(Member.getter(name, pos, target.field(name, pos), t)).isBound = bound;
    if (!hasField('set_$name'))
        if (isAccessible(write, false))
            addField(Member.setter(name, pos, target.field(name, pos).assign('param'.resolve(pos), pos), t));
}
static function and(a, b) {
    return function (c) return a(c) && b(c);
}
static function or(a, b) {
    return function (c) return a(c) || b(c);
}
static function not(a) {
    return function (c) return !a(c);
}
static function one(filters:Iterable<ClassFieldFilter>) {
    return function (c) {
        for (filter in filters)
            if (filter(c)) 
                return true;
        return false;
    }       
}
static function makeFilter(exprs:Array<Expr>) {
    return
        if (exprs.length == 0) 
            function (_) return true;
        else
            one(exprs.map(makeFieldFilter));
}
static function matchRegEx(r:String, opt:String):ClassFieldFilter {
    var r = new EReg(r, opt);
    return function (field) return r.match(field.name);
}
static public function makeFieldFilter(e:Expr):ClassFieldFilter {
    return
        switch (e.expr) {
            case EArrayDecl(exprs): one(exprs.map(makeFieldFilter));
            case EConst(c): 
                switch (c) {
                    case CIdent(s):
                        if (s.startsWith('$')) 
                            switch (s.substr(1)) {
                                case 'var': function (field:ClassField) return field.isVar();
                                case 'function': function (field:ClassField) return !field.isVar();
                                default: e.reject('invalid option');
                            }
                        else 
                            function (field) return field.name == s;
                    case CString(s): 
                        matchRegEx('^' + StringTools.replace(s, '*', '.*') + '$', 'i');
                    case CRegexp(r, opt): 
                        matchRegEx(r, opt);
                    default: e.reject('invalid constant');
                }
            case EBinop(op, e1, e2):
                switch (op) {
                    case OpAnd, OpBoolAnd: and(makeFieldFilter(e1), makeFieldFilter(e2));
                    case OpOr, OpBoolOr: or(makeFieldFilter(e1), makeFieldFilter(e2));
                    default: e.reject('invalid operator');
                }
            case EUnop(op, postfix, arg): 
                if (postfix || op != OpNot) e.reject();
                not(makeFieldFilter(arg));
            case EParenthesis(e): 
                makeFieldFilter(e);
            default: e.reject();
        }
}   

}

@sonygod
Copy link
Copy Markdown
Author

sonygod commented Apr 18, 2013

package ;
import js.Browser;
import haxe.remoting.ExternalConnection;
import Format;

class JsMain {
public static var cnx = null;
static var ctx = null;

public static var onData: Dynamic;
 private static function __init__() : Void {
onData = Reflect.makeVarArgs(__onData);

}

public static function main() {
   ctx = new haxe.remoting.Context();

   ctx.addObject("main",JsMain);
    cnx = ExternalConnection.flashConnect("default", "myFlashObject", ctx);




    }
    //http://www.verydemo.com/demo_c98_i5393.html

    public static function __onData(args: Array<Dynamic>) {



        Browser.window.alert("length=" + args[2].id);


        Test.bubblesort([1, 2, 9, 7, 6, 0.3], function (err, data) { 

             cnx = ExternalConnection.flashConnect("default", "myFlashObject", ctx);
            cnx.FlashMain.onData.call([err,data,args[2]]); 

            } );

    }

}

@sonygod
Copy link
Copy Markdown
Author

sonygod commented Apr 18, 2013

package ;

/**

import async.Build;
import async.Async;
import haxe.Timer;
import org.transition9.async.Step;
using org.transition9.async.AsyncLambda;
class Test implements Build
{

static function asyncGet2<T1, T2>(v1:T1, v2:T2, cb){
cb(null, v1, v2);
}

@async(var ret: Array<Float>) public static function bubblesort(array : Array<Float>)  {


    var swapping = false;
    var temp : Float;
    while (!swapping) {
        swapping = true;
        for (i in 0...array.length) {

            []=delay(1);
            if (array[i] > array[i+1]) {
                temp = array[i+1];
                array[i+1] = array[i];
                array[i] = temp;
                swapping = false;
            }
        }
    }


    return array;
}


@async(var ret: Array<Float>) static function asynchronous(){
  var arry:Array<Float>;

   [ arry] = bubblesort([1337, 1, -465, 3.141592653589793, 789, 69, 789, -132, 3.141592653589793, 465, 789, 0, 27]);




    return arry;

}



static function bubblesortSync(array : Array<Float>)  {


    var swapping = false;
    var temp : Float;
    while (!swapping) {
        swapping = true;
        for (i in 0...array.length) {


            if (array[i] > array[i+1]) {
                temp = array[i+1];
                array[i+1] = array[i];
                array[i] = temp;
                swapping = false;
            }
        }
    }


    return array;
}

public static function getResult(err:NodeErr, data:Array<Float>) {
    trace("end"+(Timer.stamp()*1000-startTime));
    trace(data);


}

 @async(var ret:Bool) public static function doFooParallel(arrayData:Array<Float>) {
    trace(Timer.stamp() * 10000 + "" + arrayData);
return true;
};

//
@async(var ret:Bool) public static function doFooGroup(?arg1:String) {
    trace(Timer.stamp() * 10000 + "doFooGroup" + arg1);
return true;
};

 @async(var ret:Bool)public static function  doSomethingElseAsync(array) {
    trace(Timer.stamp() * 10000 + " doSomethingElseAsync" + array);
return true;
};

 @async(var ret:Int) public static function  doSomethingElseAsync2(element:Int ) {
    trace(element);
    return  element;

};

 @async(var ret:Int,var ret2:String) public static function  doSomethingElseAsync3(element:Int ) {

   return many(element, "1");

};

public static var startTime:Float;
public static function main() {




      var step = new Step();
      step.chain([

           function () {
               bubblesort([2, 1, 4, 7], step.cb);
           },
           function (err, arrayData) {


             doFooParallel(arrayData, step.parallel());
             doFooParallel(arrayData, step.parallel());
             doFooParallel(arrayData, step.parallel());


           }
           ,function (err, ?arg1,?arg2,?arg3) {
              // trace("finish now..."+Timer.stamp()+"arg"+arg1+arg2+arg3);
             doFooGroup("group1", step.group());
              doFooGroup("group1", step.group());
               doFooGroup("group1", step.group());
              }
              ,function (err, args) {
                  trace("finish"+args);
              }

      ]);



     var fromArray = [1, 2, 3, 4];

var onElement = function (element :Int, cb :String->Int->Void) {
platformDelay(100,function () {
cb("Some int=" + element,1);
});

}

var onFinish = function (err :Dynamic, result1:String->Int->Void) {
if (err != null) trace("Oh no: " + err);
trace("result=" + result1);
}

//AsyncLambda.map( fromArray,onElement , onFinish);

  doSomethingElseAsync3(1, function(err:String, e:Int,s:String):Void { trace("e=========="+e); } );



}
static inline function delay(ms:Int, cb){
    platformDelay(ms, function(){ trace(ms+' passed'); cb(null); });
}

static inline function platformDelay(ms:Int, fun){

if (cpp || neko || php) fun(); #else haxe.Timer.delay(fun, ms); #end

}

}

typedef NodeErr = Null;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment