2016-07-30 3 views
1

を更新してレンダリングするとき:ロックゲームデータIは、Node.jsのゲームをやっている、と私の私のクライアントデータ更新/レンダリングロジックは次のように実装されている

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

    } 

そして、私はのランダムな位置で点滅して画面を見ることができます数秒ごとに私の要素。私はconsole.logのデータとオブジェクトの位置は、彼らは正常に見えます。私は何らかのロックや何か他のものを使うべきですか?私のレンダリングのvarとdata_update varは、データを安全に更新するために使われますか?もう1つ、サーバーは1秒間に60回「更新」を出しています。

+0

すべてのソケットアップデートで新しいレンダラーを開始するつもりですか? 'requestAnimFrame'のために一度開始されたレンダリング関数は、次のソケット更新で再度レンダリングを呼び出し、別のレンダリングを開始します。 'data_update'は、 'data_upodate = true'でレンダリングが呼び出されたときにページ全体をブロックし、それをtrueに設定すると、' game_data 'は必須ではありません。 Javascriptはシングルスレッドであり、同時にアクセス競合が発生することはないため、ロックする必要はありません。 – Blindman67

+0

はいこれは私の意図であり、ioの 'update'コールバックでレンダリングするとすべてうまくレンダリングされますが、スクリーン上に1つのクライアントソケットconectedと少数のオブジェクトがあり、数秒ごとにいくつかの小さな遅れがあります。ですから、私はrequestAnimFramを試してみることにしました。これは、これがpreformanceのレンダリングに適していると読んだからです。私は問題が他の何かによって引き起こされていることを知っているが、なぜ私はrequestAnimFrameを使用しているときにgame_dataのような奇妙な動作が何秒毎にnullになるのか分からず、 – peterSweter

答えて

0

スレッドセーフであるように見えます。必要はありません。

JavaScriptはシングルスレッドです。一度に1つの命令しか実行しません。一度に1つの機能しか実行しません。その機能は中断することはできず、他のイベントはありません。現在の機能が完了するまで他のデータは変更されません。 Javascriptは、それが逐次実行のみであるという事実のためにスレッドセーフで究極のものです。コードの実行中に中断することはできません。 socket.onやrequestAnimationFrameなどのすべてのイベントは、現在の実行が完了するまで待機してから実行する必要があります。

// 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); 
    } 
関連する問題