建设小GUI引擎:明显的对比的addChild / removeChild之 [英] building small GUI engine: visible vs. addChild/removeChild

查看:226
本文介绍了建设小GUI引擎:明显的对比的addChild / removeChild之的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我尝试用一​​个非常简单的图形用户界面的绘图......引擎(我想你可以称呼它)。它的要点:

  1. 有一个的FrontController,获取用户的请求命中;每个请求有一个 UID
  2. 在每个 UID (读网页)的是它present组件(模块)的声明
  3. 组件的雪碧的子类,本质上说,是唯一

当然,我需要隐藏的方式/显示这些精灵。目前,我有它pretty的很像Flex的默认有它 - 在路上如果我们在一个地方,补偿是可见的,创建它,高速缓存,并每次它再次显示重复使用

现在的问题是 - 这将是隐藏和显示的更适当和有效的方式 - 通过的addChild / removeChild之或切换可见

这样,我看到的是:

  • 可见是快速和肮脏的(第一次测试)
  • 可见不产生连锁冒泡事件,如 Event.ADDED 赛事.REMOVED
  • 在无形成分没有得到鼠标事件

所以 removeChild之会是我会打电话的时候,我敢肯定,该组件将不再需要在屏幕上(或高速缓存太大,例如)

什么stackoverflow'ers / AS3,疯狂的人认为?

更新: 下面是href="http://www.developria.com/2008/11/visible-false-versus-removechi.html" rel="nofollow">好读一个

我会坚持到可见;它似乎适合我的任务好;手册页上的性能优化Flash平台由Adobe。 69让我更加自信。

这里的code段我竖起来测试的东西对于那些有兴趣:

 包
{
进口flash.display.Sprite;
进口的flash.display.Stage;
进口对象类型:flash.events.Event;
进口flash.events.KeyboardEvent;
进口flash.ui.Keyboard;
进口flash.utils.getTimer;

/ **
 *简单的基准测试对于隐藏和显示的替代品
 *的DisplayObject。
 *
 * 使用:
 *< code取代;
 *新的DisplayBM(阶段);
 *< / code取代;
 *
 * 击中:
 *  - 1的addChild(注意打它的2倍是昂贵的,我认为
 *这是因为球员必须检查补偿是否
 *别处使用)
 *  - Q为removeChild之(2次,连续将抛出一个异常)
 *  - 2设置可见真
 *  - W设置可见假
 *
 * @author瓦西Grigorash
 * /
公共类DisplayBM {
    公共职能DisplayBM(阶段:第一阶段){
        超();

        VAR insts对于:UINT = 5000;
        VAR五:矢量<雪碧>。 =新矢量<雪碧>(insts对于);
        变种我:数= v.length,S:雪碧
        当我 - ){
            S =新雪碧;
            s.graphics.beginFill(的Math.random()* 0XFFFFFF);
            s.graphics.drawRect(
                的Math.random()* stage.stageWidth,
                的Math.random()* stage.stageHeight,
                10,
                10
            );
            s.graphics.endFill();
            v [电流] =秒;
        }

        VAR店:对象= {};
        存储[Event.ADDED] = NULL;
        存储[Event.REMOVED] = NULL;
        VAR计数:功能=功能(五:事件):无效{
            店[e.type] ++;
        }
        VAR KEYDOWN:功能=功能(E:的KeyboardEvent):无效{
            VAR键:字符串
            //上次运行清除事件计数
            对(密钥存储){
                店[关键] = 0;
            }

            stage.addEventListener(Event.ADDED,计数);
            stage.addEventListener(Event.REMOVED,计数);

            VAR S0:UINT =的getTimer(),OP:字符串;
            变种我:数= v.length;
            如果(e.key code === Keyboard.NUMBER_1){
                OP ='的addChild';
                当我 - ){
                    stage.addChild(ⅴ[I]);
                }
            }
            如果(e.key code === Keyboard.Q){
                OP ='removeChild之';
                当我 - ){
                    stage.removeChild(ⅴ[I]);
                }
            }
            如果(e.key code === Keyboard.NUMBER_2){
                OP ='visibile';
                当我 - ){
                    v [电流]。可见=真实;
                }
            }
            如果(e.key code === Keyboard.W){
                OP ='invisibile';
                当我 - ){
                    v [电流]。可见=虚假的;
                }
            }
            如果(OP){
                //格式事件
                VAR事件:数组= [];
                对(密钥存储){
                    events.push(键+:+店[关键])
                }

                跟踪(OP +'花'+(的getTimer() -  S0)+''+ events.join(''));
            }

            stage.removeEventListener(Event.ADDED,计数);
            stage.removeEventListener(Event.REMOVED,计数);
        }

        // autodispatch
        stage.addEventListener(KeyboardEvent.KEY_DOWN,KEYDOWN);
    }
}
}
 

解决方案

可见更有意义,我(因为去掉一个孩子表示终局)而这也正是我倾向于在我自己的项目显示/隐藏时使用。

我也想假设的addChild略少高性能,但我没有做任何测试。

编辑:我只是碰到这种Adobe文章的http://help.adobe.com/en_US/as3/mobile/WS5d37564e2b3bb78e5247b9e212ea639b4d7-8000.html其中规定,在使用GPU渲染模式只设置可见=假能有一个性能的影响,因为是有成本的绘制重叠的对象(即使它们不可见)。相反,除去孩子完全建议:

  

避免透支只要有可能。透支是分层多   图形元素,使它们掩盖彼此。使用该软件   渲染器,每个像素被绘制一次。因此,对于软件   渲染,应用程序招致没有性能损失,无论   多少图形元素被相互覆盖该像素   位置。相反,硬件渲染绘制的每个像素的每个   元素是否有其他因素模糊不清的区域或没有。如果两个   矩形彼此重叠,所述硬件渲染绘制   重叠区域两次,而软件渲染器绘制区域   只有一次。

     

因此​​,在桌面上,它使用软件呈现,你   通常不通知透支的性能影响。然而,   许多重叠的形状可在设备性能造成负面影响   使用GPU呈现。最好的做法是用来删除对象   显示列表,而不是隐藏它们。

Currently, i'm experimenting with a very simple GUI drawing ... "engine" (i guess you could call it that). The gist of it:

  1. there is a FrontController that gets hit by user requests; each request has a uid
  2. each uid (read "page") has a declaration of the components ("modules") that are present on it
  3. components are Sprite subclasses and, in essence, are unique

Naturally, i need a way of hiding/showing these sprites. Currently, i have it pretty much like Flex has it by default - in the way "if we are in a place where the comp is visible, create it, cache it and reuse it every time it's visible again".

The question is - which would be the more appropriate and efficient way of hiding and showing - via addChild/removeChild or toggling visible.

The way i see it is that:

  • visible is quick and dirty (on first tests)
  • visible does not create a chain of bubbling events like Event.ADDED or Event.REMOVED
  • invisible components don't get mouse events

So removeChild would be something i'd call when i'm sure, that the component will no longer be necessary on the screen (or the cache is too big, for instance)

What do stackoverflow'ers / AS3-crazed people think?

Update: Here's a good read (forgot about google).

i will be sticking to visible; it seems to suit my task better; the manual "OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORM" by Adobe on p. 69 gave me even more confidence.

here's a code snippet i put up to test things for those that are interested:

package 
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.getTimer;

/**
 * Simple benchmark to test alternatives for hiding and showing
 * DisplayObject.
 * 
 * Use:
 * <code>
 * new DisplayBM(stage);
 * </code>
 * 
 * Hit:
 * - "1" to addChild (note that hitting it 2 times is expensive; i think
 * this is because the player has to check whether or not the comp is
 * used elsewhere)
 * - "q" to removeChild (2 times in a row will throw an exception) 
 * - "2" to set visible to true
 * - "w" to set visible to false
 * 
 * @author Vasi Grigorash
 */    
public class DisplayBM{
    public function DisplayBM(stage:Stage){
        super();

        var insts:uint = 5000;
        var v:Vector.<Sprite> = new Vector.<Sprite>(insts);
        var i:Number = v.length, s:Sprite
        while (i--){
            s = new Sprite;
            s.graphics.beginFill(Math.random() * 0xFFFFFF);
            s.graphics.drawRect(
                Math.random() * stage.stageWidth, 
                Math.random() * stage.stageHeight,
                10, 
                10
            );
            s.graphics.endFill();
            v[i] = s;
        }

        var store:Object = {};
        store[Event.ADDED] = null;
        store[Event.REMOVED] = null;
        var count:Function = function(e:Event):void{
            store[e.type]++;
        }
        var keydown:Function = function (e:KeyboardEvent):void{
            var key:String
            //clear event counts from last run
            for (key in store){
                store[key] = 0;
            }

            stage.addEventListener(Event.ADDED, count);
            stage.addEventListener(Event.REMOVED, count);

            var s0:uint = getTimer(), op:String;
            var i:Number = v.length;
            if (e.keyCode === Keyboard.NUMBER_1){
                op = 'addChild';
                while (i--){
                    stage.addChild(v[i]);
                }
            }
            if (e.keyCode === Keyboard.Q){
                op = 'removeChild';
                while (i--){
                    stage.removeChild(v[i]);
                }
            }
            if (e.keyCode === Keyboard.NUMBER_2){
                op = 'visibile';
                while (i--){
                    v[i].visible = true;
                }
            }
            if (e.keyCode === Keyboard.W){
                op = 'invisibile';
                while (i--){
                    v[i].visible = false;
                }
            }
            if (op){
                //format events
                var events:Array = [];
                for (key in store){
                    events.push(key + ' : ' + store[key])
                }

                trace(op + ' took ' + (getTimer() - s0) + ' ' + events.join(','));
            }

            stage.removeEventListener(Event.ADDED, count);
            stage.removeEventListener(Event.REMOVED, count);
        }

        //autodispatch
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
    }
}
}

解决方案

Visible makes more sense to me (since removing a child indicates a finality) and is what I tend to use in my own projects when showing/hiding.

I'd also assume that addChild is slightly less performant but I haven't done any tests.

EDIT: I just came across this Adobe article http://help.adobe.com/en_US/as3/mobile/WS5d37564e2b3bb78e5247b9e212ea639b4d7-8000.html which specifies that when using GPU rendering mode just setting visible = false can have a performance impact since there is a cost for drawing overlapping objects (even though they are not visible). Instead, removing the child entirely is advised:

Avoid overdrawing whenever possible. Overdrawing is layering multiple graphical elements so that they obscure each other. Using the software renderer, each pixel is drawn only once. Therefore, for software rendering, the application incurs no performance penalty regardless how many graphical elements are covering each other at that pixel location. By contrast, the hardware renderer draws each pixel for each element whether other elements obscure that region or not. If two rectangles overlap each other, the hardware renderer draws the overlapped region twice while the software renderer draws the region only once.

Therefore, on the desktop, which use the software renderer, you typically do not notice a performance impact of overdraw. However, many overlapping shapes can adversely affect performance on devices using GPU rendering. A best practice is to remove objects from the display list rather than hiding them.

这篇关于建设小GUI引擎:明显的对比的addChild / removeChild之的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆