2012-03-24 83 views
2

我目前正在編寫nodejs中的遊戲引擎。Nodejs測試。如何避免競爭條件?

我的遊戲有幾個州。我們稱它們爲StateA,StateB,StateC。序列流程是StateA => StateB => StateC。

我想在每個狀態結束時測試我的引擎狀態。我現在有這樣的結構:

function attachEventListeners = function(instance) { 
    instance.on('START_STATE_A', stateA); 
    instance.on('START_STATE_B', stateB); 
    instance.on('START_STATE_C', stateC); 
} 

var stateACallBack = function() {}; 
var stateBCallBack = function() {}; 
var stateCCallBack = function() {}; 

function stateA() { 
    // Do something... 
    stateACallBack(); 
    setTimeout(function() { this.emit('START_STATE_B'); }, 3000) 
} 

function stateB() { 
    // Do something... 
    stateBCallBack(); 
    setTimeout(function() { this.emit('START_STATE_C'); }, 3000) 
} 

function stateC() { 
    // Do something... 
    stateCCallBack(); 
    setTimeout(function() { this.emit('START_STATE_A'); }, 3000) 
} 

所以我目前的做法包括有我的測試用例覆蓋stateXCallback在那些函數來執行測試邏輯。

但是,我看到stateB被激發的競爭狀態之前 stateACallBack已完成執行。因此,stateACallback會看到應該由stateBCallback進行評估的狀態。

我試圖在狀態之間注入延遲時間,但是,這會在我的代碼庫中引入額外的競爭條件錯誤。

有人可以請賜教我一個更好的方法來解決這個問題嗎?

回答

1

以這種抽象的方式討論這件事很難,但在我看來,你所稱的狀態並不是真正的狀態,它們是異步事件。這些事件中的每一個都可能會改變狀態機的內部狀態,但這取決於接收事件的順序。我不確定是否事件B的唯一觸發器是事件A,但我假設不是。 (如果是這樣,那麼爲什麼要將事件分成單獨的事件A,B和C?似乎是任意的和毫無意義的,爲什麼不直接調用每個回調?)。

因此,要實現狀態機,需要一個變量來跟蹤機器當前的狀態。當收到事件時,回調必須決定是否使用事件並使狀態機前進,或者將其放入隊列並等待機器處於不同的狀態。

如果你想要更多的細節或更準確的答案,你將不得不告訴我這些事件是什麼以及觸發它們的是什麼。