cocos-js,内存管理3---查看器

来源:互联网 发布:apache 64位安装版 编辑:程序博客网 时间:2024/06/05 08:17

一、纹理缓存(TextureCache)

纹理缓存是将纹理缓存起来方便之后的绘制工作。每一个缓存的图像的大小,颜色和区域范围都是可以被修改的。这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU。

首先,我们创建一个精灵

Sprite* Sprite::create(const std::string& filename){    Sprite *sprite = new (std::nothrow) Sprite();    if (sprite && sprite->initWithFile(filename))    {        sprite->autorelease();        sprite->setName(filename.c_str());        return sprite;    }    CC_SAFE_DELETE(sprite);    return nullptr;}

然后,继续深入,initWithFile的方法

bool Sprite::initWithFile(const std::string& filename){    CCASSERT(filename.size()>0, "Invalid filename for sprite");    Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);    if (texture)    {        Rect rect = Rect::ZERO;        rect.size = texture->getContentSize();        return initWithTexture(texture, rect);    }    // don't release here.    // when load texture failed, it's better to get a "transparent" sprite then a crashed program    // this->release();    return false;}

最后在TextureCache 的 addImage方法里,我们会先去集合里查找是否之前加载过,如果没有找到,那么我们就会新生成一张纹理,并且添加到集合里。


二、精灵帧缓存(CCSpriteFrameCache)

CCSpriteFrameCache单例是所有精灵帧的缓存。使用spritesheet和与之相关的xml文件,我们可以加载很多的精灵帧到缓存中,那么之后我们就可以从这个缓存中创建精灵对象了。


三、创建内存查看器

在TextureCache中有个getCachedTextureInfo的方法

这个方法可以输出每一张纹理所占用的内存,但是log日志输出查看的话,难免不够直观,查看起来不太方便,所以这里我就想到把所有的这些纹理封装到一个Node里,然后显示在屏幕上。

Node* TextureCache::getCachedTextureNode() const{    std::string buffer;    char buftmp[4096];    unsigned int count = 0;    unsigned int totalBytes = 0;    //    wade    Node* node = Node::create();    int _height = 0;    for( auto it = _textures.begin(); it != _textures.end(); ++it ) {        memset(buftmp,0,sizeof(buftmp));        Texture2D* tex = it->second;        Sprite* _sprite = Sprite::createWithTexture(tex);        if (_sprite) {            _sprite->setAnchorPoint(Point(0,1));            _sprite->setPositionY(-_height);            node->addChild(_sprite);            _height = _height+_sprite->getContentSize().height;        }        unsigned int bpp = tex->getBitsPerPixelForFormat();        // Each texture takes up width * height * bytesPerPixel bytes.        auto bytes = tex->getPixelsWide() * tex->getPixelsHigh() * bpp / 8;        totalBytes += bytes;        count++;        snprintf(buftmp,sizeof(buftmp)-1,"\"%s\" rc=%lu id=%lu %lu x %lu @ %ld bpp => %lu KB\n",                 it->first.c_str(),                 (long)tex->getReferenceCount(),                 (long)tex->getName(),                 (long)tex->getPixelsWide(),                 (long)tex->getPixelsHigh(),                 (long)bpp,                 (long)bytes / 1024);        buffer += buftmp;    }    snprintf(buftmp, sizeof(buftmp)-1, "TextureCache dumpDebugInfo: %ld textures, for %lu KB (%.2f MB)\n", (long)count, (long)totalBytes / 1024, totalBytes / (1024.0f*1024.0f));    buffer += buftmp;    return node;}

接下来就是JS的工作了,至于怎么导出C++接口到JS中,这里就不作介绍了,在JS中我们创建了一个叫MemoryLayer的类,专门用来负责显示缓存。

var MemoryLayer = cc.LayerColor.extend({    node:null,    startPosition:null,    distance:0,    ctor:function(){        this._super(cc.color(0,0,0,200));        this.initTouchEvent();        this.initView();    },    initView:function(){        var _info = cc.TextureCache.getInstance().getCachedTextureInfo()        cc.log("wade MemoryLayer info:"+_info)        node = cc.TextureCache.getInstance().getCachedTextureNode();        node.setPositionY(cc.winSize.height);        node.setScale(0.5);        this.addChild(node);        var closeBtn = new ccui.Button("res/Default/Button_Normal.png");        this.addChild(closeBtn);        var size = cc.director.getWinSize();        closeBtn.setPosition(cc.p(size.width-100,size.height-100));        closeBtn.addTouchEventListener(this.closeBtnListener,this);        cc.log(" MemoryLayer initView success");    },    closeBtnListener:function(_sender,_type){        switch(_type){            case ccui.Widget.TOUCH_ENDED:                this.removeFromParent();                break;        }    },    initTouchEvent : function(){        //对layer添加触摸事件;        var listener = cc.EventListener.create({            event: cc.EventListener.TOUCH_ONE_BY_ONE,            swallowTouches:true,            onTouchBegan:this.onTouchBegan.bind(this),            onTouchMoved:this.onTouchMoved.bind(this),            onTouchEnded:this.onTouchEnded.bind(this)        });        cc.eventManager.addListener(listener,this);    },    onTouchBegan : function(touch,event){        startPosition = touch.getLocation().y;        return true;    },    onTouchMoved : function(touch,event){        var curPosition = touch.getLocation().y;        var dis = (curPosition - startPosition);        startPosition = curPosition;        this.distance = this.distance + dis;        if(this.distance<0){            this.distance = 0;            return;        }        node.setPositionY(node.getPositionY()+dis);    },    onTouchEnded : function(touch,event){        return true;    },})

最后以一张效果图作为本期节目的结束:
这里写图片描述

0 0