aboutsummaryrefslogblamecommitdiffstats
path: root/src/js/imc.js
blob: 98f2bdb9591259f4e0766af77f45213bc34a871e (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11



                                        
                         

                                       



                                 






                                                    

                                                          







                                                 
                        
                                   
                                
                               

                              
                                                                                          
                  



                              
                     
 




                                                            
              

                                  

                                               





                                                            
                                     
                                                                             







                                                                                             
                      
                                                               
                    
                  



                                                            
 

                                                                                      


             




                                                
                                        


             









                                                                                         
 
                                               

                                               









































                                                                                               



                                               

                                            





























                                                          




                                                                               



                                                           

          

                                   
                                  



      
                                                     
                                                                      
 
                                                

                                                           
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); 
}