缓存池 NodePool

来源:互联网 发布:淘宝seo pdf 编辑:程序博客网 时间:2024/05/22 10:22

第1种方式


第2种方式


1.

function OneArmLayer:getPropNodeByDictId(dictId)    local propNode = PropIconNode.GetOrCreate()    PropIconNode.setInfoProp( propNode, dictId )    PropIconNode.showTips( propNode, true )    PropIconNode.setPropNum( propNode, 1 )    PropIconNode.setPropNumLabelVisible(propNode, false)    --    propNode:setScale(0.6)    return propNodeend

2.

-- 按名字获得节点function NodePool:getNode( nodeName )local node_list = self:_getOrCreateNodeList( nodeName )    local size = table.maxn( node_list )    for i = 1, size do        local node = node_list[ i ]if node:getReferenceCount( ) == 1 thenreturn nodeendendreturn self:_createNode( node_list, nodeName )end

3.

function NodePool:_getOrCreateNodeList( nodeName )local node_list = self.pool_list[ nodeName ]if not node_list thennode_list = { }self.pool_list[ nodeName ] = node_listend return node_listend
4.

function NodePool:_createNode( node_list, nodeName )local node = UI.nodeFromCSB( nodeName )if node thennode:retain( )table.insert( node_list, node )endreturn nodeend
5.

function UI.nodeFromCSB( uiname, belongNode )    cclog(" cc.CSLoader:createNode %s", uiname )    local node = cc.CSLoader:createNode( uiname )    node:setAnchorPoint( 0.5,0.5 )    node:setPosition( cc.p( 0, 0 ) )    node:setName( uiname )    if belongNode == nil then        belongNode = node    end    if belongNode ~= nil then        local nodeMap = dyt.Cocos2dUtils:seekBindingNodeList( node )        for name, node in pairs( nodeMap ) do            belongNode[ name ] = node        end    end    return nodeend


第一种方式在addChild之前,引用计数都是1,因此propNode1  propNode2  propNode3指向同一个节点。 

第二种方式:引用计数是2,因此重新缓存起来了,得到的是不同的节点。


-----------------华丽分割线---------------

-- 按名字获得节点function NodePool:getNode( nodeName )local node_list = self:_getOrCreateNodeList( nodeName )    local size = table.maxn( node_list )    for i = 1, size do        local node = node_list[ i ]if node:getReferenceCount( ) == 1 thenreturn nodeendendreturn self:_createNode( node_list, nodeName )end--function NodePool:_getOrCreateNodeList( nodeName )local node_list = self.pool_list[ nodeName ]if not node_list thennode_list = { }self.pool_list[ nodeName ] = node_listend return node_listend--function NodePool:_createNode( node_list, nodeName )local node = UI.nodeFromCSB( nodeName )if node thennode:retain( )table.insert( node_list, node )   --可以看出,同一个nodeName创建出来的node,可在node_list中有多个。endreturn nodeend--使用function PropIconNode.GetOrCreate( )    local propNode =  propNodePool:getNode( propNodeName )    propNode.btn_prop:setSwallowTouches( false )    propNode.btn_prop:addTouchEventListener( function( sender, eventType )  end )    propNode.btn_prop:addTouchEventListenerNaval( function( sender, eventType )  end )    propNode:setPosition( cc.p( 0, 0 ) )    propNode:setScale( 1 )    propNode:setVisible( true )        ...end

缓存池的原理:

A,B都是用nodeName叫: coin.csd 来创建的,当然创建的同时addChild了一下,此时引用计数为2

然后A removeParent后,引用计数为1, B依然为2.

这时候再去用coin.csb去创建节点,那么检测到引用计数为2,这时,就会直接返回这个A节点,不用重新创建对象了。因为创建new个对象,加载csb相对耗时。想下缓存池的意思就是:将已经用过的东西缓存起来,下次再次用到时,不用重复创建。


nodePool.lua

-- 节点池,用来缓存节点NodePool = class( "NodePool" )function NodePool:create( )    local pool = NodePool:new()    pool:init( )    return poolendfunction NodePool:init()self.pool_list = { }endfunction NodePool:releaseAll()for node_name, node_list in pairs( self.pool_list ) dofor _, node in pairs( node_list ) donode:release( )endendself.pool_list = { }end-- 按照UI文件的名字,获取或者创建自动播放的节点名称function NodePool:getAutoremoveTimelineNode( nodeName )local node = self:getNode( nodeName )local action = self:_runTimeLine( node, nodeName, false )    local frameSpeedFactor =  action:getTimeSpeed( ) * 60 --帧率    UI.delayRemove( node, action:getDuration( ) / frameSpeedFactor )return nodeend-- 获得具有动画播放能力的节点function NodePool:getTimelineNode( nodeName )    cclog( "getTimelineNode %s", nodeName )local node = self:getNode( nodeName )    node.__timelineNodeName = nodeName    function node:playDefaultAnimation( )        self.__timelineAction = UI.createTimeline( nodeName )        self:runAction( node.__timelineAction )    end    function node:stopAnimation()        if self.__timelineAction then            self:stopAction( self.__timelineAction )            self.__timelineAction = nil        end    endfunction node:playAnimation( aniName, isLoop, autoRemove )    self:stopAnimation( )        self.__timelineAction = nil        self.__timelineAction = UI.createTimeline( self.__timelineNodeName )        local timeAction = self.__timelineAction        self:runAction( timeAction )timeAction:play( aniName, isLoop )local startFrame = timeAction:getStartFrame( )local endFrame = timeAction:getEndFrame( )local time = ( endFrame - startFrame ) / 60        if autoRemove then            UI.delayRemove( node, time )        endreturn timeend    return nodeendfunction NodePool:getAnimationNode(nodeName)    local node = self:getTimelineNode(nodeName)    node:playDefaultAnimation()    node.__timelineAction:gotoFrameAndPlay(0, true)    return nodeendfunction NodePool:getAnimationNodePlayThenStay(nodeName)local node = self:getTimelineNode(nodeName)node:playDefaultAnimation()node.__timelineAction:gotoFrameAndPlay(0, false)return nodeendfunction NodePool:getAnimationNodePlayOnce(nodeName, parent, callback)    local node = self:getNode(nodeName)    if parent then        parent:addChild(node)    end    local function endCall()        if callback then            callback()        end    end    node.action = UI.createTimeline(nodeName)    node:runAction(node.action)    node.action:gotoFrameAndPlay(0, false)    -- 这个速度是每秒60帧的倍数,每秒20帧则是0.3333    local actionSpeed = node.action:getTimeSpeed( );    local framePerSecond = actionSpeed * 60    local duration = node.action:getDuration()    local actionAutoRemove = cc.Sequence:create(        cc.DelayTime:create( duration / framePerSecond ),        cc.CallFunc:create(endCall),        cc.RemoveSelf:create())    node:runAction(actionAutoRemove)    node.animationDuration = duration                -- 持续帧数    node.animationTime = duration / framePerSecond   -- 持续时间    return nodeend-- 按名字获得节点function NodePool:getNode( nodeName )local node_list = self:_getOrCreateNodeList( nodeName )    local size = table.maxn( node_list )    for i = 1, size do        local node = node_list[ i ]if node:getReferenceCount( ) == 1 thenreturn nodeendendreturn self:_createNode( node_list, nodeName )end-- 按照动画名字创建指定数量的节点function NodePool:createNode( nodeName, count )    local node_list = self:_getOrCreateNodeList( nodeName )for i = 1, count doself:_createNode( node_list, nodeName )endUI.createTimeline( nodeName )end-- 按名称移除节点function NodePool:removeNode( nodeName )local node_list =  self.pool_list[ nodeName ]for _, node in ipairs( node_list ) donode:release()endself.pool_list[ nodeName ] = nilend-- 按名称插入节点function NodePool:insertNode( nodeName, node )    if node then        local node_list = self:_getOrCreateNodeList( nodeName )        node:retain( )        table.insert( node_list, node )    endendfunction NodePool:_runTimeLine( node, nodeName , isLoop )local action = UI.createTimeline( nodeName )    node:runAction( action )    if isLoop then        action:gotoFrameAndPlay( 0, true )    else        action:gotoFrameAndPlay( 0, false )    end    return actionendfunction NodePool:_getOrCreateNodeList( nodeName )local node_list = self.pool_list[ nodeName ]if not node_list thennode_list = { }self.pool_list[ nodeName ] = node_listend return node_listendfunction NodePool:_createNode( node_list, nodeName )local node = UI.nodeFromCSB( nodeName )if node thennode:retain( )table.insert( node_list, node )endreturn nodeendfunction NodePool:showUsage()    cclog("NodePool:showUsage()")    for key, list in pairs(self.pool_list) do        cclog("file: %s count:%d", key, #list)        for _, node in ipairs(list) do            cclog("\t %s %d", tostring(node), node:getReferenceCount())        end    endendfunction NodePool:showUsageOf(file)    cclog("NodePool:showUsageOf %s", file)    local list = self.pool_list[file]    if list then        cclog("file: %s count:%d", file, #list)        for _, node in ipairs(list) do            cclog("\t %s %d", tostring(node), node:getReferenceCount())        end    endend
PropIconNode.lua

local propNodeName = "res/ui/common/new_node_prop.csb"local propNodePool  = NodePool:create( )PropIconNode = PropIconNode or { }PropIconNode.CURRENCY_ICON = {    [dyt.PropIds.Silver] = "ui_ico_gold.png",    [dyt.PropIds.Gold] = "ui_ico_diamond.png",    [dyt.PropIds.Oil] = "ui_ico_ico_oil.png",    [dyt.PropIds.ExpPlayerExp] = "ui_ico_exp.png",    [dyt.PropIds.PVPMerit] = "ui_ico_arena.png",    [dyt.PropIds.CrusadeMerit] = "ui_ico_expedition.png",    [dyt.PropIds.LegionMerit] = "ui_ico_caravan.png",    [dyt.PropIds.ExpPlayerHoner] = "ui_ico_arena2.png",    [dyt.PropIds.Contribution] = "ui_ico_contribution.png",    [dyt.PropIds.MONEY_SOUL] = "ui_ico_soul.png",    [dyt.PropIds.ExpVipExp] = "vipjy.png",    [dyt.PropIds.MONEY_STEEL] = "ui_ico_gangtie.png",    [dyt.PropIds.CrossMoney] = "ui_ico_server.png",    [dyt.PropIds.WARCAMP_POINT] = "ui_ico_zhenying.png",}PropIconNode.CURRENCY_ICON_HD = {    [dyt.PropIds.Silver] = "yb.png",    [dyt.PropIds.Gold] = "jb.png",    [dyt.PropIds.Oil] = "ry.png",    [dyt.PropIds.ExpPlayerExp] = "ui_ico_exp.png",    [dyt.PropIds.PVPMerit] = "ui_ico_arena.png",    [dyt.PropIds.CrusadeMerit] = "ui_ico_expedition.png",    [dyt.PropIds.LegionMerit] = "ui_ico_caravan.png",    [dyt.PropIds.ExpPlayerHoner] = "ui_ico_arena2.png",    [dyt.PropIds.Contribution] = "ui_ico_contribution.png",    [dyt.PropIds.MONEY_SOUL] = "ui_ico_soul.png",    [dyt.PropIds.ExpVipExp] = "vipjy.png",    [dyt.PropIds.MONEY_STEEL] = "ui_ico_gangtie.png",    [dyt.PropIds.CrossMoney] = "ui_ico_server.png",    [dyt.PropIds.WARCAMP_POINT] = "ui_ico_zhenying.png",}PropIconNode.CURRENCY_NAME = {    [dyt.PropIds.Silver] = "银币",    [dyt.PropIds.Gold] = "金币",    [dyt.PropIds.Oil] = "燃油",    [dyt.PropIds.ExpPlayerExp] = "经验值",    [dyt.PropIds.PVPMerit] = "功勋章",    [dyt.PropIds.CrusadeMerit] = "军功章",    [dyt.PropIds.LegionMerit] = "军团服役章",    [dyt.PropIds.ExpPlayerHoner] = "荣誉值",    [dyt.PropIds.Contribution] = "军团贡献值",    [dyt.PropIds.MONEY_SOUL] = "军魂",    [dyt.PropIds.ExpVipExp] = "VIP经验值",    [dyt.PropIds.MONEY_STEEL] = "钢铁值",    [dyt.PropIds.CrossMoney] = "跨服币",    [dyt.PropIds.WARCAMP_POINT] = "阵营战积分",}PropIconNode.CURRENCY_DESC = {    [dyt.PropIds.Silver] = "可以购买道具",    [dyt.PropIds.Gold] = "可以购买道具",    [dyt.PropIds.Oil] = "可以刷副本",    [dyt.PropIds.ExpPlayerExp] = "可以提升玩家等级",    [dyt.PropIds.PVPMerit] = "可在竞技场商店购买道具",    [dyt.PropIds.CrusadeMerit] = "可在远征商店购买道具",    [dyt.PropIds.LegionMerit] = "可在军团商店购买道具",    [dyt.PropIds.ExpPlayerHoner] = "可以增长军衔等阶",    [dyt.PropIds.Contribution] = "可以购买道具",    [dyt.PropIds.MONEY_SOUL] = "升级舰阵/巡航专精的唯一货币",    [dyt.PropIds.ExpVipExp] = "提升你的VIP等级",    [dyt.PropIds.MONEY_STEEL] = "升级高级阵型的唯一货币",    [dyt.PropIds.CrossMoney] = "可在跨服商店购买道具",    [dyt.PropIds.WARCAMP_POINT] = "可以在阵营商城购买道具",}function PropIconNode.GetOrCreate( )    local propNode =  propNodePool:getNode( propNodeName )    propNode.btn_prop:setSwallowTouches( false )    propNode.btn_prop:addTouchEventListener( function( sender, eventType )  end )    propNode.btn_prop:addTouchEventListenerNaval( function( sender, eventType )  end )    propNode:setPosition( cc.p( 0, 0 ) )    propNode:setScale( 1 )    propNode:setVisible( true )        local childInUse = propNode:getChildByTag(99999) --核心装备->使用中label    if childInUse then        propNode:removeChildByTag(99999)    end        local sprExp = propNode:getChildByTag( 111 )    if sprExp then        propNode:removeChild( sprExp )    end        UI.setVisible( propNode.spr_select, false   )    UI.setVisible( propNode.lbl_num, false )    UI.setVisible( propNode.node_ani, false )    UI.setVisible( propNode.spr_chip_flag , false )    UI.setVisible( propNode.spr_type , true )    UI.setVisible( propNode.spr_bg , true )    if  propNode.nameLabel then        propNode.nameLabel:removeFromParent()        propNode.nameLabel = nil    end    return propNodeendfunction PropIconNode.GetOrCreateInParent( nodeRoot  )    if not nodeRoot.node_prop then        nodeRoot.node_prop = PropIconNode.GetOrCreate( )        nodeRoot:addChild( nodeRoot.node_prop )    end    return nodeRoot.node_propendfunction PropIconNode.setInfoProp( propNode, dictIdOrDict )    UI.setVisible( propNode.spr_select, false   )    local dict =  type( dictIdOrDict ) == "table" and dictIdOrDict or PropService:getPropDictById( dictIdOrDict )    propNode.bindType = dyt.PropIconNodeTypes.Prop    propNode.bindData = dict    propNode.propName = dict.name    --    local t = {--        "211310.png",--        "213310.png",--        "214310.png",--        "212310.png",--    }--    rlog("dict.icon:"..dict.icon)--    for i = 1, #t do--        if t[i] == dict.icon then--            dict.icon = "212301.png"--        end--    end            -- 道具图标    UI.buttonLoadTextures( propNode.btn_prop, dict.icon, ccui.TextureResType.plistType )        --品质底框    UI.setVisible( propNode.spr_bg_1, true )    local quality = dict.quality    if dict.quality == nil or (dict.quality < 1 or dict.quality > 5 ) then        quality = 1    end    if  dict.chip then         UI.setSprFrame( propNode.spr_bg, string.format( "ui_bottom_material_%d.png", quality ) )        UI.setSprFrame( propNode.spr_bg_1 , string.format( "icon_bg2_%02d.png", quality ) )        UI.setVisible( propNode.spr_chip_flag , true )    else        UI.setSprFrame( propNode.spr_bg, string.format( "ui_bottom_prop_%d.png", quality ) )        UI.setSprFrame( propNode.spr_bg_1 , string.format( "icon_bg_%02d.png", quality ) )        UI.setVisible( propNode.spr_chip_flag , false )    end        -- 扫光    if  dict.flashOrNot then        UI.nodePlayIntervalAnimation( propNode.node_ani, Res.FileNames.res_ui_develop_ui_saoguang_01_csb, 5 )    else        UI.setVisible( propNode.node_ani, false )    end    --星级图片    if dict.star and dict.star > 0 then        UI.setVisible( propNode.spr_star, true )        UI.setSprFrame( propNode.spr_star , string.format( "icon_st_%02d.png", dict.star ) )    else        UI.setVisible( propNode.spr_star, false )    end        -- 舰船类型    if  not dict.shipType or dict.shipType == 0 then        UI.setVisible( propNode.spr_type, false )    else        UI.setVisible( propNode.spr_type, true )        UI.setSprFrame( propNode.spr_type, string.format( "ui_type_ship_%d_2.png", dict.shipType ) )    end    -- 改造碎片, 会额外显示改造图标    if dict.type == dyt.PropTypes.UpQualityCompoundChip or  dict.type == dyt.PropTypes.UpStarCompoundChip then        UI.setVisible( propNode.spr_bg_2, true )        UI.setSprFrame( propNode.spr_bg_2 , string.format( "icon_tz_%02d.png", quality ) )    elseif dict.type == dyt.PropTypes.UpStarCompoundProp then        UI.setVisible( propNode.spr_bg_2, true )        UI.setSprFrame( propNode.spr_bg_2 , "icon_tz2.png" )    else        UI.setVisible( propNode.spr_bg_2, false )    endendfunction PropIconNode.setInfoMoney( propNode, dictId  )    UI.setSprFrame( propNode.spr_bg, "ui_bottom_prop_1.png" )    UI.setVisible( propNode.spr_bg_1, false )    UI.setVisible( propNode.spr_bg_2, false )    UI.setVisible( propNode.spr_star, false )    UI.setVisible( propNode.spr_select, false )    UI.setVisible( propNode.lbl_num, false )    UI.setVisible( propNode.node_ani, false )    UI.setVisible( propNode.spr_type, false )    UI.setVisible( propNode.spr_chip_flag, false )    propNode.bindType = dyt.PropIconNodeTypes.Money    propNode.bindData = dictId    propNode.propName = PropIconNode.CURRENCY_NAME[dictId] or "神奇货币"    if dictId == dyt.PropIds.ExpPlayerExp then        local sprExp =  UI.spriteWithFrame( PropIconNode.CURRENCY_ICON[dictId] )         sprExp:setScale( 1.5 )        sprExp:setAnchorPoint( cc.p( 0.5, 0.5 ) )        propNode:addChild( sprExp )        sprExp:setTag( 111 )        sprExp:setPosition( cc.p( propNode.btn_prop:getPosition() ) )        UI.buttonLoadTextures( propNode.btn_prop, "ui_board_9.png", ccui.TextureResType.plistType )    else        UI.buttonLoadTextures( propNode.btn_prop, PropIconNode.CURRENCY_ICON[dictId] or "ui_board_9.png" , ccui.TextureResType.plistType )    endendfunction PropIconNode.setInfoDropShip( propNode, dropShipId )    local dropShipDict =  DictManager.getDropShipDict( dropShipId )    if dropShipDict then        local shipInfo = PropService:getShipInfoFromDropShip( dropShipDict )        PropIconNode.setInfoShip( propNode, shipInfo )    endendfunction PropIconNode.setInfoShip( propNode, shipInfo )    local dict = ShipService:getShipDictById( shipInfo.dictId )    propNode.bindType = dyt.PropIconNodeTypes.Ship    propNode.bindData = shipInfo    propNode.propName = dict.ship_name        UI.buttonLoadTextures( propNode.btn_prop, string.format( "ship_icon_%d.png", dict.model_id ), ccui.TextureResType.plistType )    local shipQuality = { 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }    local quality = shipQuality[ shipInfo.ship_quality ]    if quality == nil then        quality = 1    end    UI.setSprFrame( propNode.spr_bg, string.format( "ui_bottom_prop_%d.png", quality ) )    UI.setSprFrame( propNode.spr_type, T( "ui_type_ship_%d_2.png", dict.type ) )    UI.setVisible( propNode.spr_bg_1, false )    UI.setVisible( propNode.spr_bg_2, false )    UI.setVisible( propNode.spr_star, false )    UI.setVisible( propNode.spr_chip_flag, false )endfunction PropIconNode.setInfoByPropChangeId( propNode, dictId   )    if not propNode or not dictId then        return    end    if PropService:propIdIsDropShip( dictId ) then        PropIconNode.setInfoDropShip( propNode, dictId )    elseif PropService:propIdIsProp( dictId )   then        PropIconNode.setInfoProp( propNode,  dictId )    else        PropIconNode.setInfoMoney( propNode, dictId )    endendfunction PropIconNode.selectProp( propNode, isSelected )    UI.setVisible( propNode.spr_select, isSelected )endfunction PropIconNode.setPropNum( propNode, num )     if  not num then        UI.setVisible( propNode.lbl_num, false )    else        UI.setVisible( propNode.lbl_num, true )        UI.setString( propNode.lbl_num, tostring( num ) )            endendfunction PropIconNode.setPropNumLabelVisible(propNode, flag )   UI.setVisible( propNode.lbl_num, flag )endfunction PropIconNode.setPropLv( propNode, num )    if  not num then        UI.setVisible( propNode.lbl_num, false )    else        UI.setVisible( propNode.lbl_num, true )        UI.setString( propNode.lbl_num, tostring( "LV "..num ) )    endendfunction  PropIconNode.showServerNum( propNode  )    if propNode.bindType == dyt.PropIconNodeTypes.Prop and propNode.bindData then        PropIconNode.setPropNum( propNode,  PropService:getPropCount( propNode.bindData.id )   )    endend-- pos: 1 右  2 下function  PropIconNode.showPropName( propNode, dictId, pos )    if not propNode.nameLabel then        local nameLabel =  UI.label( Res.FileNames.res_font_arts_ttf, 20, "" )        if  1 == pos then            nameLabel:setAnchorPoint( cc.p( 0, 0.5 ) )            nameLabel:setPosition( cc.p( propNode.spr_bg:getContentSize().width + 10, propNode.spr_bg:getContentSize().height * 0.5 ) )        elseif 2 == pos then            nameLabel:setAnchorPoint( cc.p( 0.5, 1 ) )            nameLabel:setPosition( cc.p( propNode.spr_bg:getContentSize().width * 0.5, 0 ) )        end        propNode.spr_bg:addChild( nameLabel )        propNode.nameLabel = nameLabel    end    local nameLabel = propNode.nameLabel    if PropService:propIdIsDropShip( dictId )   then        local dropShipDict = DictManager.getDropShipDict( dictId )        if dropShipDict then            local dict = ShipService:getShipDictById( dropShipDict.ship_id )            UI.setString( nameLabel , dict.ship_name )        end    elseif PropService:propIdIsProp( dictId )  then        local dict = PropService:getPropDictById( dictId )        UI.setString( nameLabel , dict.name  )    else        UI.setString( nameLabel , PropIconNode.CURRENCY_NAME[dictId] or "神奇货币" )    endendfunction PropIconNode.setRequiredNumAndServerNum( propNode, requiredNum )endfunction PropIconNode.showTips( propNode, isShow )    if isShow then        propNode.btn_prop:setTouchEnabled( true )        propNode.btn_prop:addTouchEventListener(  GoodsTip.createTouchFunc( propNode, propNode.bindType, propNode.bindData )  )    else        propNode.btn_prop:setTouchEnabled( false )    endend





0 0
原创粉丝点击