2 Replies Latest reply on Jan 8, 2010 6:51 AM by paul.reiners

    Flex Panel not being updated

    paul.reiners

      I am drawing a cellular automaton simulation on a Flex Canvas. I alternate computing the state of the automaton with updating the graphics on the Panel. However, the updating of the Panel does not seem to be "keeping up" with the update of the CA state.

       

      I'm wondering whether I am doing something wrong with my handling of the graphics code. The code is below. Sorry it's so lengthy, but I don't think the problem will happen with anything simpler (well, it probably will, but I'm not certain I want to take the time to find it).

       

      <?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. Re: Flex Panel not being updated
          Jason Szeto Level 3

          Paul,

           

          In the future, simplying your use case will improve your chances of getting an answer. I ran your app and ran into an infinite loop here:

           

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

           

          The Flash Player is single-threaded. So it will not render anything while it is in the middle of a function stack. You need to truigger your updating logic with a Timer in order to see anything rendered.

           

          Jason

          • 2. Re: Flex Panel not being updated
            paul.reiners Level 1

            Jason,

             

            Thanks!  Yes, I did finally figure that out and that fixed it.

             

            Paul