Почему updateDisplayList перестает происходить во Flex? - PullRequest
1 голос
/ 30 июля 2010

Награда: Заявлено.

Обзор: Код, дающий мне проблему, размещен здесь: http://www.johnuckele.com/MastersOfTime.html

ПроблемаЯ сталкиваюсь с тем, что определенная последовательность действий (я не до конца понимаю, как и почему) приводит к тому, что мои вызовы invalidateDisplayList не производят последующий вызов updateDisplayList.Что я знаю, так это то, что в течение этого периода некоторые другие визуальные эффекты будут отсутствовать (например, изменение ширины компонента или добавление нового дочернего элемента).

Пример: Программа ниже рисует два столбца горизонтальных линий.Столбец слева рисуется во время commitProperties, столбец справа рисуется во время updateDisplayList.Определенная последовательность действий может привести к тому, что правый столбец прекратит обновление.

Чтобы вызвать эту ошибку: Сначала добавьте новый элемент.Теперь нажмите кнопку запуска, и бар начнет заполняться.Если вы нажмете кнопку «Добавить строку», правый столбец и строка заполнения перестанут расти.Левая колонка продолжается без ограничений.Дополнительный компонент не появится, пока последняя строка оператора if в TEComputeRow.tick () не будет выполнена для фрейма.Нажмите кнопку «Стоп», чтобы остановить выполнение блока внутри оператора if в TEComputeRow.tick (), и все вернется в норму.

Вопрос: Что здесь происходит?

Теперь я могу заставить его вести себя, используя команду validate, но это не решает проблему, а просто закрывает ее для кадра.Это также похоже на действительно неаккуратный хак.Есть ли лучший способ справиться с потерей updateDisplayList, чем использовать validateNow?Есть ли способы точно определить состояние мира?

MastersOfTime.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    backgroundColor="white"
    backgroundGradientAlphas="[1,1]"
    initialize="init()"
    enterFrame="tick()"
    creationComplete="addComputeArray()">
    <mx:Script>
        <![CDATA[
            import mx.containers.HBox;
            import mx.controls.Button;
            import mx.containers.VBox;
            import flash.utils.getTimer;
            private var global:int = 0;

            private function addComputeArray():void
            {
                var addButton:Button = new Button;
                addButton.label = "Add Row Item";
                addButton.addEventListener(MouseEvent.CLICK, addComputeBox);
                box.addChild(addButton);
            }

            private function addComputeBox(a:* = null):void
            {
                box.addChild(new TEComputeRow());
            }

            private function init():void
            {
                box.clipContent = false;
                box.graphics.lineStyle(1);
            }

            private function tick():void
            {
                global++;
                this.invalidateDisplayList();
                this.invalidateProperties();
                //this.validateNow();
            }
            protected override function commitProperties():void
            {
                super.commitProperties();
                box.graphics.moveTo(100, (global*3)%800);
                box.graphics.lineTo(200, (global*3)%800);
            }
            protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
            {
                super.updateDisplayList(unscaledWidth, unscaledHeight);
                box.graphics.moveTo(200, (global*3)%800);
                box.graphics.lineTo(300, (global*3)%800);
            }
        ]]>
    </mx:Script>
    <mx:VBox id="box"/>
</mx:Application>

TEComputeRow.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    height="60"
    width="352"
    verticalGap="0"
    borderStyle="solid"
    enterFrame="tick()">
    <mx:Script>
        <![CDATA[
            public var doStuff:Boolean = false;
            private var parameter:Number = 0;

            private function tick(e:Event = null):void
            {
                var value:*;
                if(doStuff)
                {
                    parameter = parameter+1;

                    value = parameter;

                    fill.width = value;
                }
            }
        ]]>
    </mx:Script>
    <mx:Button label="turn on" click="{doStuff = true;}" height="20"/>
    <mx:Container id="fill" x="7" width="0" height="20" backgroundColor="0x8888AA"/>
    <mx:Button label="turn off" click="{doStuff = false;}" height="20"/>
</mx:VBox>

Ответы [ 2 ]

5 голосов
/ 30 июля 2010

Ну, для начала, вы ужасно злоупотребляете жизненным циклом Flex и делаете то, чего не должны делать ... Изменение ширины заливки в галочке строки запускает другой цикл аннулирования, который сразу выскакивает. Если вы управляете вещами через таймер, а не через enterFrame, вам сразу будет лучше.

Я предполагаю, что вы тратите так много времени на кадр, повторно аннулируя свойства (изменение ширины приведет к аннулированию свойств), игрок никогда не помещается в updateDisplayList.

Читайте как на эластичной гоночной трассе , так и на презентации Дипы о жизненном цикле Flex 3.

0 голосов
/ 03 августа 2010

Использование .width вызывает эту проблему. Если я заменю .width на .setActualSize, проблема остановится. Эти фрагменты кода проходят через отдельные пути, и .width и .height, по-видимому, способны пропускать часть цикла кадра (часть updateDisplayList).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...