• Hi Robin
    Thanks for the feedback. It triggered me into exploring workarounds. I am surprised that you say also that "wifi.on('connected',function)" is made for only one listner. I find that there is everything to work with multiple listner, but maybe not with a removal from within the listener.

    For example, here is the structure of the callback memory section of wifi module :

    E.getSizeOf(global["\xFF"].modules.Wifi,­ 2)
    =[
      {
        "name": "#onconnected",
        "size": 20,
        "more": [
          {
            "name": "0",
            "size": 20 },
          {
            "name": "1",
            "size": 20 }
         ]
       }
     ]
    

    In this example, we can see there is an array with "#onconnected" element with 2 callbacks in it. From there I was able to find a hacky solution to directly change the content of this hidden variable :

    function removeWifiListener(ev,fu) {
        var i=global["\xFF"].modules.Wifi["#on"+ev].­indexOf(fu);
        if(i!=-1) global["\xFF"].modules.Wifi["#on"+ev][i]­="";
      
        if(!global["\xFF"].modules.Wifi["#on"+ev­].some(function(e){return (e!=="");})) require("Wifi").removeAllListener(ev);
    }
    
    

    That's my best solution so far, nearest in behaviour to the original removeListener(e,f). I tried splicing this table, but of course if you do it from within the callback that is part of the table, it has the exact same problem than the original wifi.removeListener(e,f) I posted in the beginning.

    So my final guess is it was not designed to be changed from within the callback, because to do so, the array must be changed after iterating or a copy of the array is iterated and the original is modified. For those who like less hacky solutions, I explored these 2 options, but that are not as practical as my hacky solutions :

    // Solution 1 : Very near to what wifi module could be doing. The problem is that all calls must be centralized.
    
    
    var callbacks=new Array();
    function onWifiConnected(f) {
    	if(callbacks.length==0) require("Wifi").on("connected",wifiConne­cted);
    	callbacks.push(f);
    }
    
    function removeWifiListener(f) {
    	var i=callbacks.indexOf(f);
    	if(i!=-1) callbacks.splice(i, 1);
    	if(callbacks.length==0) require("Wifi").removeAllListeners("conn­ected");
    }
    
    function wifiConnected(d) {
    	callbacks.clone().forEach(function(f){f(­d);});
    }
    
    
    function start (){
    
    	var f1=function(){
    		print("connected1 " );
    		removeWifiListener(f1);
    	};
    	var f2=function(){
    		print("connected2 " );
    		removeWifiListener(f2);
    	};
    	var f3=function(){
    		print("connected3 " );
    //		removeWifiListener(f3);
    	};
    	var f4=function(){
    		print("connected4 " );
    		removeWifiListener(f4);
    	};
    
    	var wifi=require("Wifi");
    
    	onWifiConnected(f1);
    	onWifiConnected(f2);
    	onWifiConnected(f3);
    	onWifiConnected(f4);
    }
    
    E.on("init",start);
    save();
    
    // Solution 2 : not centralized, but using global vars and function redefinition. It does not remove the callback, but save the memory of the long code function t.
    
    function start (){
    	var i1=true;
    	var i2=true;
    	var i3=true;
    	var i4=true;
    
    	var t1=function(){
    		print("connected 1 " );
    		i1=false;
    	};
    	var t2=function(){
    		print("connected 2 " );
    		i2=false;
    	};
    
    	var t3=function(){
    		print("connected 3 " );
    //		i3=false;
    	};
    	var t4=function(){
    		print("connected 4 " );
    		i4=false;
    	};  
    
    	var wifi=require("Wifi");
    	wifi.on("connected",function(){
    		if(i1) {t1();if(!i1) t1="";}
    	});
    	wifi.on("connected",function(){
    		if(i2) {t2();if(!i2) t2="";}
    	});
    	wifi.on("connected",function(){
    		if(i3) {t3();if(!i3) t3="";}
    	});
    	wifi.on("connected",function(){
    		if(i4) {t4();if(!i4) t4="";}
    	});
    
    }
    E.on("init",start);
    save();
    
About

Avatar for Polypod @Polypod started