2016-07-30 7 views
1

ich ein node.js Spiel machte, und meine meine Kundendaten aktualisieren/render Logik wie folgt implementiert:Locking Spieldaten, wenn Aktualisierung und machen

var rendering = false; 
    var waiting_for_data = true; 
    var data_update = false; 

    socket.on('update', function(data){ 

     if(rendering)console.log("rendering"); 

     data_update = true; 
     game_data = data; 
     data_update = false; 

     if(waiting_for_data){ 
     waiting_for_data = false; 
     render(); 
     } 


    }); 

    window.requestAnimFrame = (function(){ 
      return window.requestAnimationFrame  || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame || 
        window.oRequestAnimationFrame  || 
        window.msRequestAnimationFrame  || 
        function(/* function */ callback, /* DOMElement */ element){ 
        window.setTimeout(callback, 1000/60); 
        }; 
    })(); 


    function render(){ 


     while(data_update){ 
     console.log("waiting" + data_update); 
     } 

     if(game_data == null)console.log(game_data); 

     rendering = true; 
     //mapa.draw(context, game_data.player_position); 
     renderer.draw(game_data); 
     rendering = false; 

     window.requestAnimFrame(render); 
    } 

    } 

Und ich kann mit beliebiger Position siehe Bild Blinken meine Elemente alle paar Sekunden. Wenn ich die Daten und die Position von console.log anspreche, sehen sie gut aus. Sollte ich irgendeine Art von Schlössern oder etwas anderes benutzen? Ist mein rendering var und data_update var für das Aktualisieren von Daten gesichert? Eine weitere Sache ist, dass der Server 60 Mal pro Sekunde "update".

+0

Möchten Sie bei jedem Socket-Update einen neuen Renderer starten? Die einmal gestartete Render-Funktion wird wegen des 'requestAnimFrame' fortgesetzt. Beim nächsten Socket-Update rufen Sie erneut Rendering auf und starten ein weiteres Rendering. Jetzt haben Sie zwei, und Sie fügen ein weiteres jedes Update hinzu. Auch das 'while (data_update)' wird die ganze Seite blockieren, wenn das Rendering jemals mit 'data_upodate = true' aufgerufen wird und es auf 'false' gesetzt wird 'ist nicht erforderlich. Javascript ist single-threaded, keine Notwendigkeit zu sperren, da Sie nie gleichzeitige Zugriffskonflikte haben werden. – Blindman67

+0

Ja, das ist meine Absicht, und wenn ich in io "update" -Rückruf rendere, ist alles in Ordnung, aber ich habe ein paar kleine Verzögerungen alle paar Sekunden mit einem Client-Socket verbunden und wenige Objekte auf dem Bildschirm. Also entschied ich mich, AnfrageAnAnimFram zu versuchen, weil ich gelesen habe, dass dies gut für das Rendering von Preformance ist. Ich weiß, dass das Problem durch etwas anderes verursacht wird, aber ich weiß immer noch nicht, warum ich dieses seltsame Verhalten wie game_data alle paar Sekunden zu null mache, wenn ich requestAnimFrame benutze, und ich bin jetzt nur neugierig – peterSweter

Antwort

0

Ihr Code sieht so aus, als ob Sie Thread-sicher sind. Es besteht kein Bedarf.

JavaScript ist single threaded. Es führt immer nur eine Anweisung auf einmal. Es führt immer nur eine Funktion gleichzeitig aus. Diese Funktion kann nicht unterbrochen werden, kein anderes Ereignis, keine anderen Daten werden geändert, bis die aktuelle Funktion beendet ist. Javascript ist das ultimative Thread-Safe, da es nur sequenzielle Ausführung ist. Es kann nicht unterbrochen werden, während Code ausgeführt wird. Alle Ereignisse wie socket.on und requestAnimationFrame müssen auf die aktuelle Ausführung warten, bevor sie ausgeführt werden können.

// var rendering = false; // not needed 
    var waiting_for_data = true; 
    // var data_update = false; // not needed 

    socket.on('update', function (data) { 
     // this will never run if render is running 
     //data_update = true; // nothing will see this 
     game_data = data; // ONLY this will ever happen between the line above and below 
     // data_update = false; // nothing will see this 

     if (waiting_for_data) { 
      waiting_for_data = false; 
      render(); 
     } 

    }); 


    function render() { 
     // if data_updata is true 
     // then the while loop will have no way to exit and nothing 
     // can change data_update while this loop is running except some code in the loop 
     // JavaScript is single threaded and can only do one thing at a time. 
     //while (data_update) { 
     // console.log("waiting" + data_update); 
     //} 

     // again single thread. Only code in this function can run NOTHING else 
     // can do anything until this function has exited all the way out 
     //rendering = true; 
     renderer.draw(game_data); 
     //rendering = false; 

     requestAnimationFrame(render); 
    }