精华内容
下载资源
问答
  • 对象池lua
    2020-12-30 10:32:57

    local NianGaoNode = requirePack("task.toyboxScripts.NianGaoNode")

    local NianGaoNodePool = class("NianGaoNodePool")

    function NianGaoNodePool:ctor()

        self.nodePoll ={};

        print(" 20 20 20 对象池的 构造 ")

    end

    function NianGaoNodePool:getNianGao() 

        if( #self.nodePoll > 0 ) then 

            local item = table.remove (self.nodePoll,1) --返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起

            print("10 獲取到舊的 前 " ,#self.nodePoll, item:getReferenceCount() )

            --item:release();

           -- print("10 獲取到舊的 後 " , item:getReferenceCount() )

            return item ;

        else 

            local item = NianGaoNode.new();

            return item ; 

        end 

    end

     

    function NianGaoNodePool:huishou(newNode)

           print("22 remove 前 ", newNode:getReferenceCount())

     newNode:removeFromParent();

    print("22 remove 後 ", newNode:getReferenceCount())

           newNode:retain();

           print("22 retain 後 ", newNode:getReferenceCount())

           if(newNode:getReferenceCount() > 2 ) then 

               newNode:release();

               print("22 release 後 ", newNode:getReferenceCount())

           end

           table.insert(self.nodePoll,newNode) ; --table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾.

           print("对象池的 回收之后",#self.nodePoll)

         end

     

    function NianGaoNodePool:clearAll()

        --     this.enemyPool.clear(); // 通过 put 接口放入对象池

        --     YBLog.log( "NodeBgPool","清理之后之后:",this.enemyPool.size() );

        for k,v in ipairs(self.nodePoll) do

           v:removeFromParent();

        end   

        self.nodePoll = {}   

    end

     

    return NianGaoNodePool

     

    更多相关内容
  • 对象池的实现unity/Lua

    2022-02-23 11:23:53
    【为什么要用对象池】 有些对象需要在程序运行或游戏过程中重复的创建销毁,例如子弹、怪和粒子等。每次创建要分配内存,而这个对象生命周期很短,对象很快被销毁,内存要被回收,这会增大GC的压力,同时也会造成...

    【为什么要用对象池】

    有些对象需要在程序运行或游戏过程中重复的创建销毁,例如子弹、怪和粒子等。每次创建要分配内存,而这个对象生命周期很短,对象很快被销毁,内存要被回收,这会增大GC的压力,同时也会造成内存碎片。使用对象池可以解决这些问题。

    对象池预先初始化一系列可重用的对象,循环利用这些对象,有利于提高程序性能和内存使用率。

    【相关概念】

    • 池的大小:初始化n个对象,那么池的大小就是n,具体n取值多少依据具体情况而定
    • 回收模式:指如何在需要的时候从对象池中取出对象,在不需要的时候将对象放回对象池
      • 借用:将对象从对象池中借用出来,借用后在对象池中找不到对象的引用。借用者不需要的时候将对象返回给对象池,借用者不再持有对象的引用。这种方式实现起来简单,大多数对象池都是用这种方实现,本文也采用这种方式实现。
      • 引用计数:用于同时有多个借用者访问同一个对象,只有当所有的借用者都释放了对象引用时,对象才可以被回收。每个对象都持有一个内部计数器和一个指向池的引用。当计数器为 0 时,对象就会返回池中。也即对象需要额外挂载一个脚本。
    • 分配方式:指对象池内的没有可用对象时,有新的请求时,该如何返回一个对象,常见的策略有:
      • 拒绝请求:告知池内没有对象了,拒绝请求,返回空对象
      • 强制回收:强行回收一个已经借出的对象
      • 增大池子:这种方式使用最多,什么时候增大池子呢?有三种触发方式
        • 空池触发:对象池内没有可用对象时,创建一个新对象
        • 水位线触发:空池触发的缺点是,请求对象时可能会因为执行对象分配而中断。为了避免这种情况,可以使用水位线触发。当从池中可用对象小于某个阈值,例如池子大小的十分之一,就触发分配过程。
        • Lease/Return速度:大多数时候,水位线触发已经足够,但有时候可能会需要更高的精度。在这种情况下,可以使用lease和return速度。例如,如果池中有100个对象,每秒有20个对象被取走,但只有10个对象返回,那么9秒后池就空了。开发者可以使用这种信息,提前做好对象分配计划。
    • 增长策略:指如何增大池子
      • 固定增长:每次增长一个或几个
      • 快速增长:根据池子大小的百分比增长
    • 初始化和重置对象:取出对象后,需要对对象做初始化,可以选择在对象池内初始化,可以在借用者获取对象后自己初始化。前者的好处是对象池可以完全封装管理对象,但需要提供很多不同的初始化函数,因为不同的对象初始化的参数不一样。后者更简单的一些,需要记得自己初始化对象,并在返给对象池时重置对象,返回时注意释放引用。
    • 对象内存大小固定:必须保证借用者在使用对象时不会引起对象内存大小的改变,否则新增内存将覆盖到下一个对象的内存中
    • 借出对象列表:如果需要查找借出的对象,需要创建一个借出对象的列表

    下文的代码实现了能存放不同对象的对象池:

    【Unity实现】

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    
    public class ObjectPools : MonoBehaviour
    {
        public static ObjectPools Instance;
    
        [Serializable]//可序列化的,能在Inspector面板上看到,
        public class PoolInfo//对象池的信息   
        {
            public string poolName;//对象池的名字  
            public GameObject prefab;//要实例化的prefab  
            [NonSerialized]
            public int poolSize;//当前对象池的可容纳的最大对象
            public int fixedSize;//初始化时固定的大小
        }
    
        public PoolInfo[] poolInfos;
    
        //用队列,先进先出,循环利用每个对象,不用栈
        private Dictionary<PoolInfo, Queue<GameObject>> allObjects = new Dictionary<PoolInfo, Queue<GameObject>>();
        //每个借出的对象属于哪个对象池
        private Dictionary<GameObject, PoolInfo> lentObjects = new Dictionary<GameObject, PoolInfo>();
    
        private Dictionary<string, PoolInfo> nameToPool = new Dictionary<string, PoolInfo>();
        void Awake()
        {
            if (Instance == null)
            {
                Instance = this;
                DontDestroyOnLoad(gameObject);
            }
            PoolInit();
        }
    
        /// <summary>
        /// 对象池初始化
        /// </summary>
        public void PoolInit()
        {
            foreach (PoolInfo item in poolInfos)
            {
               AddObjPool(item);
            }
        }
    
        /// <summary>
        /// 借出对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public GameObject LendObject(string name)
        {
            GameObject go = null;
            PoolInfo poolInfo;
            if (nameToPool.TryGetValue(name, out poolInfo))
            {
                var queue = allObjects[poolInfo];
                if (queue.Count > 0)
                {
                    go = queue.Dequeue();
                }
                else//空池触发
                {
                    go = Instantiate(poolInfo.prefab, transform);
                    poolInfo.poolSize++;
                }
    
                lentObjects.Add(go, poolInfo);
                go.SetActive(true);
                return go;
            }
            else
            {
                Debug.LogWarning("该对象不存在:" + name);
            }
    
            return go;
        }
    
        /// <summary>
        /// 回收对象
        /// </summary>
        /// <param name="go"></param>
        public void Recycle(GameObject go)
        {
            if (go == null)
            {
                Debug.LogWarning("不是对象池中的对象");
                return;
            }
    
    
            PoolInfo poolInfo = null;
            if (lentObjects.TryGetValue(go, out poolInfo))
            {
                lentObjects.Remove(go);
                go.SetActive(false);
                allObjects[poolInfo].Enqueue(go);
            }
        }
    
        /// <summary>
        /// 清空所有对象池
        /// </summary>
        public void ClearPool()
        {
            lentObjects.Clear();
            allObjects.Clear();
            nameToPool.Clear();
        }
    
        /// <summary>
        /// 添加新的对象池
        /// </summary>
        /// <param name="poolInfo"></param>
        public void AddObjPool(PoolInfo poolInfo)
        {
            var queue = new Queue<GameObject>(poolInfo.fixedSize);//初始化队列大小,要直接把poolInfo.fixedSize传入
    
            if (poolInfo.prefab == null)
            {
                Debug.LogError("欲实例化的物体为空:" + poolInfo.poolName);
                return;
            }
    
            if (string.IsNullOrEmpty(poolInfo.poolName))
                poolInfo.poolName = poolInfo.prefab.name;
    
            if (nameToPool.ContainsKey(poolInfo.poolName))
            {
                Debug.LogWarning("该对象池已存在:"+poolInfo.poolName);
                return;
            }
    
            poolInfo.poolSize = poolInfo.fixedSize;
    
            allObjects.Add(poolInfo, queue);
    
            for (int i = 0; i < poolInfo.fixedSize; i++)
            {
                GameObject go = Instantiate(poolInfo.prefab, transform);
                go.SetActive(false);
                queue.Enqueue(go);
            }
    
            nameToPool.Add(poolInfo.poolName, poolInfo);
        }
    
        /// <summary>
        /// 移出某个对象池
        /// </summary>
        /// <param name="poolName"></param>
        public void RemoveObjPool(string poolName)
        {
            if (nameToPool.ContainsKey(poolName))
            {
                Debug.LogWarning("该对象池不存在:"+poolName);
                return;
            }
            
            PoolInfo poolInfo = nameToPool[poolName];
            nameToPool.Remove(poolName);
            allObjects.Remove(poolInfo);
    
            for (int i = lentObjects.Count-1; i > 0; i--)
            {
                if (lentObjects.ElementAt(i).Value == poolInfo)
                    lentObjects.Remove(lentObjects.ElementAt(i).Key);
            }
    
        }
    }
    

    【Lua实现】

    local Objectpool = {}
    
    
    ---@param poolInfos table 对象池初始化的信息
    function Objectpool:PoolInit(poolInfos)
        self.allObjects = {}
        self.lentObjects = {}
        self.nameToPool = {}
    
        for _,v in pairs(poolInfos) do
            self:AddObjPool(v)
        end
    end
    
    
    ---@param poolName string 对象池的名字
    ---@return GameObject 从对象池中借出的对象
    function Objectpool:LendObject(poolName)
        if self.nameToPool[poolName] == nil then
            print("不存在该对象池")
            return nil
        end
    
        local poolInfo = self.nameToPool[poolName]
        local pool = self.allObjects[poolInfo]
        local obj = nil
        if #pool > 0 then 
            obj = pool:pop()
        else    --空池触发,每次增加1
            obj = CS.UnityEngine.Object.Instantiate(poolInfo.obj)
            poolInfo.poolsize = poolInfo.poolsize+1
        end
    
        self.lentObjects[obj] = poolInfo
    
        return obj
    end
    
    ---
    ---@param obj GameObject 回收的物体
    function Objectpool:Recycle(obj)
        if obj == nil then
            print("回收的物体为空")
            return 
        end
    
        if self.lentObjects[obj] == nil then
            print("不是对象池中的物体:",obj.name)
            return 
        end
    
        self.allObjects[self.lentObjects[obj]]:push(obj)
        self.lentObjects[obj] = nil
    end
    
    ---
    ---@param poolInfo table 添加新的对象池
    function Objectpool:AddObjPool(poolInfo)
        local stack = Array.New()
            if poolInfo.obj == nil then
                print("实例化对象为空")
                return 
            end
    
            if poolInfo.poolName == nil then
                print("对象池名字为空")
                return
            end
    
            local key = poolInfo.poolName
    
            if self.nameToPool[key] ~= nil then
                print("该对象池已存在:",key)
                return
            end
       
    
            poolInfo.poolsize = poolInfo.fixedSize
           
            self.allObjects[poolInfo] = stack
    
            for i = 1, poolInfo.fixedSize do
                local obj = CS.UnityEngine.Object.Instantiate(poolInfo.obj)
                stack:push(obj)
            end
            
            self.nameToPool[key] = poolInfo
    end
    
    ---
    ---@param poolName string 移除某个对象池
    function Objectpool:RemoveObjPool(poolName)
        if self.nameToPool[poolName] == nil then
            print("该对象池不存在:",poolName)
            return
        end
    
        local poolInfo = self.nameToPool[poolName]
        self.allObjects[poolInfo] = nil
        self.nameToPool[poolName] = nil
    
        for k,v in pairs(self.lentObjects) do
            if v == poolInfo then
                self.lentObjects[k] = nil
            end
        end
    end
    
    _G.ObjectPool = Objectpool

    【参考】

    一个广为人知但鲜有人用的技巧:对象池-InfoQ

    对象池模式 · Optimization Patterns · 游戏设计模式 (tkchu.me)

    展开全文
  • -- Lua Class对象池 -- 自己管理好池的清空时机 --------------------------------- ObjectPool = Class( "ObjectPool" ); -- 构造函数,传需实例化的对象 function ObjectPool:Ctor( class ) self.instanceTarget...

    缓存池基本写法

    ---------------------------------
    -- Lua Class对象池
    -- 自己管理好池的清空时机
    ---------------------------------
    ObjectPool = Class( "ObjectPool" );
    
    -- 构造函数,传需实例化的对象
    function ObjectPool:Ctor( class )
        self.instanceTarget = class;
        -- 产出列表
        self.spawnList = {};
        -- 缓存列表
        self.cacheList = {};
    end
    
    -- 拿一个对象,传构造参数
    function ObjectPool:Spawn(...)
        local obj;
        if #self.cacheList > 0 then
            -- 如果不是预加载,缓存里还存在,直接拿
            obj = self.cacheList[1];
            table.remove( self.cacheList, 1 );
            -- 调初始化方法
            obj:Ctor(...);
        else
            -- 缓存里不存在,新建
            obj = self.instanceTarget.New(...);
        end
    
        -- 压入产出列表
        table.insert( self.spawnList, obj );
        return obj;
    end
    
    -- 回收一个对象 
    function ObjectPool:Despawn( obj )
        -- 从产出列表中删除
        local found = false;
        for i, v in ipairs( self.spawnList ) do
            if v == obj then
                table.remove( self.spawnList, i );
                table.insert( self.cacheList, obj );
                break;
            end
        end
    end
    
    -- 回收所有
    function ObjectPool:DespawnAll()
        for i, obj in ipairs( self.spawnList ) do
            table.insert( self.cacheList, obj );
        end
        self.spawnList = {};
    end
    
    -- 销毁所有
    function ObjectPool:Clear()
        self.spawnList = {};
        self.cacheList = {};
    end
    
    -- 所有产出列表中的调析构,并置空
    function ObjectPool:Destroy()
        local destoryList = {};    
        for i = 1, #self.spawnList do
            table.insert( destoryList, self.spawnList[i] );
        end
    
        for i = 1, #destoryList do
            local obj = destoryList[i];
            if obj.Destroy ~= nil then
                obj:Destroy();
            end
        end
        self:Clear();
    end
    
    
    ---------------------------------
    -- GameObject对象池
    -- 自己管理好池的清空时机
    ---------------------------------
    GameObjectPool = Class( "GameObjectPool" );
    
    -- 回收GameObject的地方
    local _cacheRoot = nil;
    
    -- 构造函数,传需实例化的对象, instFunc可以为空,如果不为空,就调用该方法,对实例化对象进行获取组件的一些操作
    -- isInsertCache:当instanceTarget是已实例化的对象时,isInsertCache必须为True,否则为false。即通过ResManager.instance.LoadPrefab出来的未实例化对象isInsertCache为false。
    function GameObjectPool:Ctor( instanceTarget, isInsertCache, instFunc )
        if _cacheRoot == nil then
            _cacheRoot = GameObject.Find( "PoolCacheRoot" ).transform;
        end
    
        -- 产出列表
        self.spawnList = {};
        -- 缓存列表
        self.cacheList = {};
    
        --是否需要缓存table对象
        if instFunc ~= nil then
            self.isInstFunc = true;
            self.instFunc = instFunc;
        end
    
        self.instanceTarget = instanceTarget;
        
        if isInsertCache then
            instanceTarget:SetActive( false );
            instanceTarget.transform:SetParent( _cacheRoot );
            if self.isInstFunc then
                local tableObj = instFunc(instanceTarget);
                tableObj.inst = instanceTarget;
                table.insert( self.cacheList,  tableObj );
            else
                table.insert( self.cacheList, instanceTarget );
            end
        end
    end
    
    -- 拿一个对象
    function GameObjectPool:Spawn( isPreSpawn )
        local go;
        if not isPreSpawn and #self.cacheList > 0 then
            -- 如果不是预加载,缓存里还存在,直接拿
            go = self.cacheList[1];
            table.remove( self.cacheList, 1 );
            if self.isInstFunc then
                go.inst:SetActive(true);
            else
                go:SetActive( true );
            end
            -- 压入产出列表
            table.insert( self.spawnList, go );
            return go;
        else
            -- 缓存里不存在,新建
            go = GameObject.Instantiate( self.instanceTarget );
            go.name = self.instanceTarget.name .. "_" .. ( #self.cacheList + #self.spawnList + 1 );
        end
    
        if isPreSpawn then
            -- 如果是预加载直接
            go.transform:SetParent( _cacheRoot );
            go:SetActive( false );
            -- 如果有初始化方法,对产生的新对象进行初始化
            if self.isInstFunc then
                local tableObj = self.instFunc(go);
                tableObj.inst = go;
                go = tableObj;
            end
            -- 缓存
            table.insert( self.cacheList, go );
        else
            -- 初始化
            go:SetActive( true );
            -- 如果有初始化方法,对产生的新对象进行初始化
            if self.isInstFunc then
                local tableObj = self.instFunc(go);
                tableObj.inst = go;
                go = tableObj;
            end
            -- 压入产出列表
            table.insert( self.spawnList, go );
        end
        return go;
    end
    
    -- 回收一个对象,如果是isInstFunc,传.inst
    function GameObjectPool:Despawn( go )
        -- 从产出列表中删除
        for i, v in ipairs( self.spawnList ) do
            local realObj = v;
            -- 有初始化方法情况下,v.inst才是真正的实例化的GameObject
            if self.isInstFunc then
                realObj = v.inst;
            end
    
            if realObj == go then
                table.remove( self.spawnList, i );
                if IsNilOrNull(realObj) then return; end
                -- 重置
                realObj.transform:SetParent( _cacheRoot );
                realObj:SetActive( false );
    
                -- 压入缓存列表
                table.insert( self.cacheList, v );
                return;
            end
        end
    end
    function GameObjectPool:GetPoolList()
      return  TableUtil.GetLen( self.spawnList)
    end
    
    
    -- 回收所有
    function GameObjectPool:DespawnAll()
        if IsNilOrNull( _cacheRoot ) then return end;
        for i, v in ipairs( self.spawnList ) do
            local realObj = v;
            -- 有初始化方法情况下,v.inst才是真正的实例化的GameObject
            if self.isInstFunc then
                realObj = v.inst;
            end
            if not IsNilOrNull( realObj ) then
                realObj.transform:SetParent( _cacheRoot );
                realObj:SetActive( false );
    
                table.insert( self.cacheList, v );
            end
        end
        self.spawnList = {};
    end
    
    -- 检测GO是否已经被回收
    function GameObjectPool:IsDespawn( gameObject )
        for i = 1, #self.cacheList, 1 do
            if gameObject == self.cacheList[i]  then
               return true;
            end
        end
        return false;
    end
    
    -- 销毁所有
    function GameObjectPool:Clear()
        for i, v in ipairs( self.spawnList ) do
            -- 有初始化方法情况下,v.inst才是真正的实例化的GameObject        
            local realObj = v;
            if self.isInstFunc then
                realObj = v.inst;
            end
    
            if not IsNilOrNull( realObj ) then
                GameObject.Destroy( realObj );
            end
        end
        for i, v in ipairs( self.cacheList ) do
            -- 有初始化方法情况下,v.inst才是真正的实例化的GameObject
            local realObj = v;
            if self.isInstFunc then
                realObj = v.inst;
            end
    
            if not IsNilOrNull( realObj ) then
                GameObject.Destroy( realObj );
            end
        end
        self.spawnList = {};
        self.cacheList = {};
    end
    
    -- 获得缓存池Root
    function GameObjectPool.GetCacheRoot()    
        if _cacheRoot == nil then
            _cacheRoot = GameObject.Find( "PoolCacheRoot" ).transform;
        end
        return _cacheRoot;
    end
    

    实际例子

    --------------------------------------------
    -- 时间管理器:集中生成,集中销毁
    --------------------------------------------
    TimerManager = {};
    
    local _moduleList = {};
    
    local _timerPool = ObjectPool.New(Timer);
    
    -- 新建一个Timer
    function TimerManager.SpawnTimer( moduleName, func, dura, loop, unscaled, finishFunc)
        -- 没有模块,创建一个
        if _moduleList[moduleName] == nil then
            _moduleList[moduleName] = {};
        end
    
        local timer = _timerPool:Spawn(func, dura, loop, unscaled, finishFunc);
        _moduleList[moduleName][timer] = timer;
    
        --单次的计时器,自动销毁
        if not loop or loop  == 1 then
            timer.func = function()
              func();
    
                if _moduleList[moduleName] == nil then return end
                _moduleList[moduleName][timer] = nil
                _timerPool:Despawn(timer)
            end
        end
        timer:Start()
        return timer
    end
    
    -- 销毁指定的timer
    function TimerManager.DespawnTimer( moduleName, timer )
        if _moduleList[moduleName] == nil then
            return;
        end  
        local safeTimer = _moduleList[moduleName][timer];
        if safeTimer then
            if safeTimer.running then
                safeTimer:Stop();
            end
            _moduleList[moduleName][safeTimer] = nil;
             _timerPool:Despawn(safeTimer);
        end 
    end
    
    -- 销毁指定模块的timer
    function TimerManager.DespawnModule( moduleName )
        if _moduleList[moduleName] == nil then
            return;
        end    
        for i, timer in pairs( _moduleList[moduleName] ) do
            if timer.running then
                timer:Stop();
            end
            _timerPool:Despawn(timer);
        end
        _moduleList[moduleName] = nil;
    end
    
    -- 清空所有
    function TimerManager.DespawnAll()
        for i, moduleList in pairs( _moduleList ) do
            for i, timer in pairs( moduleList ) do
                if timer.running then
                    timer:Stop();
                end
                _timerPool:Despawn(timer);
            end
        end  
        _moduleList = {};  
    end
    
    展开全文
  • lua 对象池

    千次阅读 2018-12-02 23:13:47
    对象池主代码 require("Util/FunctionsEx") require("Util/Queue") require("Util/List") LuaPool = class("LuaPool") function LuaPool:ctor(prefab, count, po...

    是的我又在造轮子了  为什么要造轮子 因为我找不到现成的 那没办法了 只能硬着头皮造了 造起来吧董小姐

    对象池主代码

    require("Util/FunctionsEx")
    require("Util/Queue")
    require("Util/List")

    LuaPool = class("LuaPool")

    function LuaPool:ctor(prefab, count, position, parent, rotation)

        -- 存放未使用的go
        self.queue = Queue.new()
        -- 存放已使用的go
        self.list = List.new()
        self.count = count
        self.prefab = prefab
        self.parent = parent
        self.position = position
        self.rotation = rotation
    end


    function LuaPool:Prewarm()
        for i = 1, self.count do
            local go = LoadTest(self.prefab, self.position, self.parent)
            go.transform.name = i
            self.list:Add(go)
            self:Put(go)
        end
    end


    function LuaPool:Put(go)
      --  print("回收是否为真", self.list:Contains(go))
        if self.list:Contains(go) == true then
            self.list:Remove(go)
            go:SetActive(false)
            self.queue:Enqueue(go)
        else
            print("对象池回收出错")
        end


    end


    function LuaPool:Get()
        local go = nil
        if self.queue:Count() == 0 then
            go = LoadTest(self.prefab, self.position,self.parent)
        else
            go = self.queue:Dequeue()
        end
        self.list:Add(go)
        go:SetActive(true)

        return go
    end

     

     

    再把list和queue的发了吧 省得又是找到半个

    require("Util/FunctionsEx")
    List = class("List")
    function List:ctor()
        self.items = { }
    end

    function List:Add(item)
        table.insert(self.items, self:Count() + 1, item)
    end

    function List:Count()
        return #self.items
    end

    function List:Contains(item)
        local isExist = false
        for k, v in pairs(self.items) do
          --  print("contains", item:GetInstanceID(), v:GetInstanceID())
            if v:GetInstanceID() == item:GetInstanceID() then
                isExist = true
                break
            end
        end
        return isExist
    end

    function List:Remove(item)
        if not self:Contains(item) then return false end
        for i = 1, self:Count() do
            if self.items[i]:GetInstanceID() == item:GetInstanceID() then
                table.remove(self.items, i)
                break
            end
        end
    end

    function List:RemoveAt(index)
        if not self:Contains(self.items[index]) then return false end
        table.remove(self.items, index)
    end

     

     

    require("Util/FunctionsEx")
    Queue = class("Queue")

    function Queue:ctor()
        self.items = { }
    end

    function Queue:Peek()
        return self.items[1]
    end

    function Queue:Enqueue(item)
        table.insert(self.items, self:Count() + 1, item)
    end

    function Queue:Dequeue()
        local item = self:Peek()
        table.remove(self.items, 1)
        return item
    end

    function Queue:Count()
        return #self.items
    end

    function Queue:Clear()
        self.items = { }
    end

    先把要初始的prefab地址 初始的数目传进来  具体设置自己定

    然后就测试对象池    的get和put方法了

     

    ok今天到这 最近估计要研究pbc这块了  如果有些感悟就写点这方面的东西 下次见

     

    展开全文
  • Lua实现的对象池,Unity

    千次阅读 2017-08-17 17:41:49
    -- 从对象池中获取一个对象,若池为空的,则从Prefab创建一个新的 -- 当对象到达池上限时,会把最早使用的对象回收并作为新对象返回 function PrefabObjectPool:Get() local obj = nil if self.queue.Count == 0 ...
  • 对象池技术---免费

    2012-08-09 14:40:08
    对象池技术---免费
  • 在文章开始之前首先要思考的问题是为什么要建立对象池。这和.NET垃圾回收机制有关,正如下面引用所说,内存不是无限的,垃圾回收器最终要回收对象,释放内存。尽管.NET为垃圾回收已经进行了大量优化,例如将托管堆...
  • 它没有提供完善的对象池方案; 它只是保留了一堆可以推送/弹出的表。 安装 将Stable.lua克隆/下载到您的项目中,并按以下要求进行操作: local Stable = require ( " Stable " ) ( Pool可能是更好的别名) 用法 ...
  • U3D性能优化之对象池(Object Pooling)

    千次阅读 2022-02-07 10:56:22
    一共两个脚本(lua):CachePrefabManager和CachePrefab require "Game.CommonPrefab.Lua.CachePrefab" CachePrefabManager = {} ...-- 动态缓存对象 local dt_cache_map = {} function CachePrefabManag
  • C# 这边 new 了一个GameObject 对象并发给Lua那边, 这时C# 这边在通过GC释放掉这个对象lua 那边会报错;遇到这种问题的两种方式解决方案: 1.lua一个 sprite对象如果被引擎释放了,那引用它的变量怎么不是nil 每...
  • 本文分享Unity中的资源管理-对象池技术(2) 在上一篇文章中, 我们一起学习了普通类的对象池, 这种实现有一定的特点和适用范围: 只能存放相同类型的对象 所有对象都一视同仁, 在产生和回收后都需要额外的操作, 比如...
  • Cocos2d-x实现潜艇大战——简单工厂模式,对象池,源代码及分析类图
  • 看懂Xlua——从宏观到微观(1)传递c#对象Lua我们要解决什么问题?c#传递对象lua 我们要解决什么问题? 为了使基于unity开发的应用在移动平台能够热更新,我们嵌入了Lua虚拟机,将需要热更新的逻辑用lua实现。c#...
  • lua 的协程写法

    千次阅读 2019-03-04 15:39:30
    闲来,写了一个协程 目标是能实现写成复用,而不需要反复去生成新的协程 具体见代码注释 代码如下: local co_running = assert(coroutine.running) local co_create = assert(coroutine.create) local co_yield =...
  • Lua源码学习笔记

    2022-06-25 14:58:30
    介绍lua实现统一表达各种数据结构的方式,以及Table部分插入key时解决冲突和rehash的实现
  • 在游戏开发中,我们常常遇到在一帧中需要创建大量的对象。比如飞行设计游戏中的子弹,和刷新出来的敌机,这些对象我们需要在一帧中大量创建,而对象不使用时需要大量的销毁操作。而在一帧中大量的创建和销毁操作不仅...
  • lua 链接 redis

    千次阅读 2021-09-07 09:40:51
    lua 代码中使用
  • 1.什么是lua数据结构原理 2.为什么要有lua数据结构原理 3.如何使用lua数据结构原理,使用lua数据结构原理的不同方案比较 4.lua数据结构源码实现 5.lua数据结构关键点,重要节点,疑难杂症场景 引用 如何...
  • nata:Lua的实体管理

    2021-05-26 22:10:33
    它允许您创建实体,实体是容纳游戏中所有对象(如几何体,角色和收藏品)的容器。 最简单的说,包含实体,并允许您在其上调用函数,但是它们还为实体组件系统组织提供了最小的结构。 要查看运行中的Nata,请...
  • lua

    2021-02-07 01:48:45
    你知道为什么新建一个不添加任何属性的对象为何能调用toString方法吗?你知道如何让拥有相同构造函数的不同对象都具备相同的行为吗?你知道instanceof关键字判断对象类型的依据是什么吗? ...»liujingjiu2021-02-06...
  • C# 这边 new 了一个GameObject 对象并发给Lua那边, 这时C# 这边在通过GC释放掉这个对象lua 那边会报错;遇到这种问题的两种方式 解决方案: 1.lua一个 sprite对象如果被引擎释放了,那引用它的变量怎么不是...
  • Lua与Unity的内存优化技术

    千次阅读 2019-09-28 16:27:04
    现在使用Unity开发,有许多Lua插件供选择:ulua,slua,xlua等等。开发使用Lua的目的是为了热更新,换句话说就是将游戏中可变的资源和逻辑一起进行更新。Lua作为一种脚本非常适合做这种事情,但是使用Lua并不像表面...
  • lua 性能优化

    2022-07-05 16:40:45
    lua 性能优化的一些实用技巧
  • "Lua") if not ok then return print(ok, msg) end print("当前language的总数为:", msg) 问题排查 最后, 让我们用Redis自带的命令行工具查看是否真实写入了数据. [candy@MacBookPro:~] $ redis-cli 127.0.0.1:6379...
  • nginx使用lua实战

    2022-05-30 15:17:20
    目录一、介绍二、安装1、apt安装2、测试hello world3、命令模式三、lua语法1、数据类型2、变量3、拼接字符串..4、循环5、函数6、条件控制 一、介绍 lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放...
  • 对象池模式是一种创建性模式,在对象池中包含了已经经过初始化并可以使用的对象,在用户需要时可以从对象池中获得对象并进行操作,当用户不需要时归还给对象池而非销毁对象。在实践中,我们通过一个简单的射击场景来...
  • 使用C语言作为胶水语言,打破Go语言调用Lua的天然障碍,并通过LuaJit技术,支持高效运行Lua语言,并且支持跨平台运行。
  • lua环境中使用protobuf

    千次阅读 2018-06-20 18:28:50
    最近在cocos2dx的项目中,需要在LUA脚本层使用protobuf协议。官方已经推出了很多种语言的版本。但唯独LUA版本不全。于是开始研究protobuf在LUA下的实现,将完整的过程记录了下来,希望对其它人能有所帮助。1、下载...
  • ios使用lua详解

    千次阅读 2020-11-21 17:10:21
    脚本语言中运行速度最快的是 Lualua是基于寄存器的虚拟机实现(更简单,更高效),python是基于堆栈的,都是动态数据类型 python有自己的库,是基于自身独立开发的,lua离开c/c++的话没法开发,lua更类似是一层...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,217
精华内容 2,886
关键字:

对象池lua