2012-10-19 45 views
0

我使用開關作爲我的XNA遊戲的狀態管理器。交換機是主要更新方法的一部分,所以它每幀都運行。有時候我需要設置一個計時器值,並且每個方法調用只能設置一次。有多種方法設置每個案例的計時器,所以它不能使用當前和以前的狀態編號來檢查是否可以覆蓋以前的時間。如何在循環中只運行一次方法?

case "state 34": { 
SetTime(theTime); // should run only once 
// other things 
if (TheTimeisRight(time)) // runs every call 
    { 
     SetTime(theTime); // should run only once 
     if (TheTimeisRight(time)) 
     { /* some methods */ } 
    } 
break; } 

我怎樣才能使這項工作,還是有更好的方法來做到這一點沒有開關外面去? (改變SetTime方法是好的,但我不想用附加代碼混亂開關)

+2

你可以添加完整的開關代碼,並解釋更多關於它 – andy

+0

@Anandkumar什麼是不清楚的開關?我已經給出了一個在問題中切換的例子,每種情況大致就像你在那裏看到的一樣,只有檢查,方法和參數是不同的。 – user1306322

+0

它是每個方法調用,每幀? IE每幀一次? – Alan

回答

0

我已經求助於使用HashSet<int>來檢查當前的SetTime(time, num)方法是否尚未在if (!hashSet.Contains(num))之前調用過。

void SetTime(int time, int num) 
{ 
    if (!hashSet.Contains(num)) 
     { 
      theTime = time; 
      hashSet.Add(num); 
     } 
} 

當然不看太爽了,但工作和不損害方法調用過多(視覺),所以交換機的可讀性被保存。

0

把呼叫放到循環之外。
您可能需要一個單獨的條件語句來確定它是否應該運行,但這要比試圖使用標誌和/或各種其他惡臭代碼方法來控制重複調用要好得多。

編輯:

這裏是我的意思,將其置於一個地方外開關:

if (someCondition && someOtherCondition && yetAnotherCondition) 
    setTime(theTime); // just one call, in one place, gets executed once 

switch(someValue) 
{ 
    case "state 34": { 
     //SetTime(theTime); // no longer necessary 
     // other things 
     if (TheTimeisRight(time)) // runs every call 
     { 
      //SetTime(theTime); // no longer necessary 
      if (TheTimeisRight(time)) 
      { /* some methods */ } 
     } 
     break; 

    ...etc... 
} 

一句忠告:使用枚舉爲交換機值,而比一個字符串。

要說實話,這就像任何人都可以在沒有看到更完整的代碼示例的情況下實際地幫助你一樣(我認爲你給我們的樣本有些人爲設計,並且對於你所擁有的樣本不太準確)。 。有可能解決這個問題的最好方法是解構switch語句並重新開始,因爲維護一個狀態機不是處理這種情況的最佳方式,或者您需要引入其他一些狀態。

+0

我想把所有東西放在一個地方,但我想這不是一個簡單的方法。 – user1306322

+0

@ user1306322但它並不是真的「都在同一個地方」,因爲你有多個地方被調用。把它放在'switch'之外肯定會把它放在一個地方。 – slugster

+0

我不明白'把外部'和'保持在一個地方'是如何...嗯,這對我來說沒有意義:) – user1306322

0

如果你不想亂用布爾變量ala hasSetTimeAlready,你總是可以引入另一個調用該方法的狀態,然後進入原始狀態。

+0

我寧願不使用另一個狀態,已經有足夠的地球半徑長開關。 – user1306322

+0

如果您的交換機已經太長,您應該爲您的狀態使用類。導致小類爆炸,但保持代碼可讀。 – lbruder

+0

你能提供一些關於這方面信息的鏈接嗎? – user1306322

1

另一種方法:介紹你要隨時待命,方法的包裝:

public sealed class RunOnceAction 
    { 
     private readonly Action F; 
     private bool hasRun; 

     public RunOnceAction(Action f) 
     { 
      F = f; 
     } 

     public void run() 
     { 
      if (hasRun) return; 
      F(); 
      hasRun = true; 
     } 
    } 

switch語句之前,然後創建var setTimeOnce = new RunOnceAction(() => SetTime(theTime));,並調用那裏setTimeOnce.run()。根據需要調整參數/返回值。