2009-12-29 2 views
0

Я рисую моделирование клеточного автомата на холсте Flex. Я чередую вычисления состояния автомата с обновлением графики на панели. Тем не менее, обновление Панели, похоже, не «не отстает» от обновления состояния ЦС.Flex Panel не обновляется

Мне интересно, не делаю ли я что-то не так с моей обработкой графического кода. Код ниже. Извините, это так много, но я не думаю, что проблема будет происходить с чем-нибудь более простым (ну, наверное, будет, но я не уверен, что хочу потратить время, чтобы найти его).

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init();"> 
    <mx:Script> 
     <![CDATA[ 
     private static const universeRadius:uint = 8; 

     private var universes:Array = new Array(); 
     private var currentUniverse:uint = 0; 
     private var squareHeight:uint; 
     private var squareWidth:uint; 

     private function init():void { 
      squareHeight = myCanvas.height/universeRadius; 
      squareWidth = myCanvas.width/universeRadius; 
      initUniverses(); 

      while (true) { 
       trace("Calling draw()"); 
       draw(); 
       trace("Calling updateUniverse()"); 
       updateUniverse(); 
      } 
     } 

     private function initUniverses():void { 
      var universe0:Array = new Array(); 
      var universe1:Array = new Array(); 

      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var universe0Row:Array = new Array(); 
       var universe1Row:Array = new Array(); 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        if (Math.random() < 0.5) { 
         universe0Row[j] = 0; 
        } else { 
         universe0Row[j] = 1; 
        } 
        universe1Row[j] = 0; 
       } 
       universe0[i] = universe0Row; 
       universe1[i] = universe1Row; 
      } 

      universes[0] = universe0; 
      universes[1] = universe1; 
     } 

     private function normalize(pos:int):int { 
      return (pos + universeRadius) % universeRadius; 
     } 

     private function updateUniverse():void { 
      var newUniverse:int = 1 - currentUniverse; 
      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        var dx:int; 
        var dy:int; 
        var count:int = 0; 
        for (dx = -1; dx <= 1; dx++) { 
         var neighborX:int = normalize(i + dx); 
         for (dy = -1; dy <= 1; dy++) { 
          var neighborY:int = normalize(j + dy); 
          if ((dx != 0 || dy != 0) && 
           universes[currentUniverse][neighborX][neighborY] == 1) { 
            count++; 
           } 
         } 
        } 
        var currentCell:int = universes[currentUniverse][i][j]; 
        if (currentCell == 1) { 
         // 1. Any live cell with fewer than two live neighbours 
         // dies, as if caused by underpopulation. 
         if (count < 2) { 
          universes[newUniverse][i][j] = 0; 
         } 
         // 2. Any live cell with more than three live neighbours 
         // dies, as if by overcrowding. 
         else if (count > 3) { 
          universes[newUniverse][i][j] = 0; 
         } 
         // 3. Any live cell with two or three live neighbours 
         // lives on to the next generation. 
         else { 
          universes[newUniverse][i][j] = 1; 
         } 
        } else { 
         // 4. Any dead cell with exactly three live neighbours 
         // becomes a live cell. 
         if (count == 3) { 
          universes[newUniverse][i][j] = 1; 
         } else { 
          universes[newUniverse][i][j] = 0; 
         } 
        } 
       } 
      } 

      currentUniverse = newUniverse; 
     } 

     private function draw():void { 
      myCanvas.graphics.clear(); 
      myCanvas.graphics.beginFill(0xFFFFFF, 1.0); 
      myCanvas.graphics.drawRect(0, 0, myCanvas.width, myCanvas.height); 
      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        if (universes[currentUniverse][i][j] == "1") { 
         myCanvas.graphics.beginFill(0x000000, 1.0); 
         myCanvas.graphics.drawRect(
          j * squareWidth, i * squareHeight, squareWidth, squareHeight) 
        } 
       } 
      } 
      myCanvas.graphics.endFill(); 
     } 
     ]]> 
    </mx:Script> 
    <mx:Panel title="Life" height="95%" width="95%" 
     paddingTop="5" paddingLeft="5" paddingRight="5" paddingBottom="5"> 

     <mx:Canvas id="myCanvas" borderStyle="solid" height="100%" width="100%"> 
     </mx:Canvas> 
    </mx:Panel> 
</mx:Application> 

ответ

1

Scary:

while (true) { 

Flex является однопоточным, так что я думаю, что вы никогда не давая UIComponents возможность полностью обновить.

Альтернативами было бы запустить методы рисования и обновления на таймере или запустить их на событии ENTER_FRAME. Любой из них позволит обновления списка отображения происходят между вашим

private function cycleUniverse(event:Event):void { 
    updateUniverse(); 
    draw(); 
} 

, а затем либо из

private var t:Timer; 

private function init():void { 
    t = new Timer(500); // every 500 ms 
    t.addEventListener(TimerEvent.Timer, cycleUniverse); 
    t.start(); 
} 

или

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" enterFrame="cycleUniverse(event)"> 
+0

я в конечном итоге положить обновления на событие таймера и работает отлично. Я знаю, что «пока (правда)» страшно, но это ранняя версия кода, и я планировал изменить это позже. Спасибо! –

+0

Только страшно из-за однопоточности Flex. В другом месте, пока (правда). –

Смежные вопросы