var __extend__ = function(child,parent){ child.prototype.__super__ = parent; }; var imc = new function(){ this.Connection = function(linkid){ var that = this; that.link_linkidmap = {}; that.close_callback = []; that.linkid = linkid; that.send_msg = function(data){}; that.start_recv = function(recv_callback){}; that.close = function(){ var i; for(i = 0;i < that.close_callback.length;i++){ that.close_callback[i](that); } }; }; this.Proxy = function(linkid,connect_linkid){ var MSGTYPE_CALL = 'call'; var MSGTYPE_RET = 'ret'; var that = this; var caller_retid_count = 0; var conn_linkidmap = {}; var conn_retidmap = {}; var call_pathmap = {}; var route_call = function(caller_retid,timeout,iden,dst,func_name,param,callback){ var i; var part; var dst_linkid; var dst_path; var caller_linkid; var func; var _add_wait_caller = function(conn_linkid){ conn_retidmap[conn_linkid][caller_retid] = { 'timeout':timeout, 'callback':callback } }; part = dst.split('/'); dst_linkid = part[2]; dst_path = part.slice(3).join('/'); caller_linkid = iden.linkid if(caller_retid.split('/')[0] != caller_linkid){ return false; } if(dst_linkid == linkid){ if((func = call_pathmap[dst_path + func_name]) != undefined){ _add_wait_caller(linkid); func(param,function(data){ if(linkid in conn_retidmap && caller_retid in conn_retidmap[linkid]){ delete conn_retidmap[linkid][caller_retid]; callback({'stat':true,'data':data}); } }); }else{ callback({'stat':true,'data':'Enoexist'}); } }else{ that.request_conn(dst_linkid,function(conn){ if(caller_linkid == linkid){ _add_wait_caller(conn.linkid); } send_msg_call(conn,caller_retid,timeout,iden,dst,func_name,param); }); } }; var recv_dispatch = function(conn,data){ msgo = JSON.parse(data); if(msgo.type == MSGTYPE_CALL){ recv_msg_call(conn,msgo); }else if(msgo.type == MSGTYPE_RET){ recv_msg_ret(conn,msgo); } }; var send_msg_call = function(conn,caller_retid,timeout,iden,dst,func_name,param){ msg = { 'type':MSGTYPE_CALL, 'caller_retid':caller_retid, 'timeout':timeout, 'iden':iden, 'dst':dst, 'func_name':func_name, 'param':param }; conn.send_msg(JSON.stringify(msg)); }; var recv_msg_call = function(conn,msg){ var caller_retid = msg.caller_retid; var timeout = msg.timeout; var iden = msg.iden; var dst = msg.dst; var func_name = msg.func_name; var param = msg.param; var caller_linkid = iden.linkid; route_call(caller_retid,timeout,iden,dst,func_name,param,function(result){ that.request_conn(caller_retid,function(conn){ send_msg_ret(conn,caller_linkid,caller_retid,result); }); }); }; var send_msg_ret = function(conn,caller_linkid,caller_retid,result){ msg = { 'type':MSGTYPE_RET, 'caller_linkid':caller_linkid, 'caller_retid':caller_retid, 'result':result }; conn.send_msg(JSON.stringify(msg)); }; var recv_msg_ret = function(conn,msg){ var caller_linkid = msg['caller_linkid']; var caller_retid = msg['caller_retid']; var result = msg['result']; if(caller_linkid == linkid){ if(conn.linkid in conn_retidmap && caller_retid in conn_retidmap[conn.linkid]){ wait = conn_retidmap[conn.linkid][caller_retid]; delete conn_retidmap[conn.linkid][caller_retid]; wait.callback(result); } }else{ request_conn(caller_linkid,function(conn){ send_msg_ret(conn,caller_linkid,caller_retid,result); }); } }; that.add_conn = function(conn){ conn_linkidmap[conn.linkid] = conn; conn_retidmap[conn.linkid] = {}; conn.start_recv(recv_dispatch); }; that.link_conn = function(linkid,conn){ conn.link_linkidmap[linkid] = true; conn_linkidmap[linkid] = conn; }; that.unlink_conn = function(linkid){ conn = conn_linkidmap[linkid]; delete conn_linkidmap[linkid]; delete conn.link_linkidmap[linkid]; }; that.del_conn = function(conn){ delete conn_linkidmap[conn.linkid]; }; that.request_conn = function(linkid,callback){ var _conn_cb = function(conn){ if(conn != null && conn.linkid != linkid){ that.link_conn(linkid,conn); } callback(conn); }; conn = conn_linkidmap[linkid]; if(conn != undefined){ _conn_cb(conn); }else{ connect_linkid(linkid,_conn_cb); } }; that.call = function(iden,timeout,dst,func_name,param,callback){ caller_retid = linkid + '/' + caller_retid_count; caller_retid_count += 1; route_call(caller_retid,timeout,iden,dst,func_name,param,callback); }; that.register_call = function(path,func_name,func){ call_pathmap[path + func_name] = func; }; conn_retidmap[linkid] = {}; imc.Proxy.instance = that; }; }; function imc_call(iden,dst,func_name,param,callback){ imc.Proxy.instance.call(iden,10000,dst,func_name,param,callback); } function imc_register_call(path,func_name,func){ imc.Proxy.instance.register_call(path,func_name,func); }