U3d插件——Swarm Object Manager分析(三)SwarmItemManager(未完)

SwarmItemManager 才是重中之重   前面和后面的东西都是小菜一碟 -,-

public class SwarmItemManager : MonoBehaviour
{

  //首先,他通过这个列表类
    protected class PrefabItemLists
    {
        public LinkedList<SwarmItem> activeItems;
       
        public Stack<SwarmItem> inactiveItems;
       
        public int itemCount; 
       
        public float inactivePruneTimeLeft;   栈中存在的时间
       
        public PrefabItemLists ()
        {
            activeItems = new LinkedList<SwarmItem>();
            inactiveItems = new Stack<SwarmItem>();
        }
    }
   
    [Serializable]
    public class PrefabItem
    {
        public GameObject prefab;
       
        public int maxItemCount = 0;  //最大的个数
       
        public float inactiveThreshold = 1.0f;   //门槛? 无效的项目数,如果超过这一比例,则定时器立刻触发,默认是1.0,则所有都用完才会修剪  范围是0-1

        public float inactivePruneTimer = 0.0f;    //在垃圾栈中的板凳时间    还没被删除的存在时间

        public float inactivePrunePercentage = 0.0f; //垃圾栈中所占的项目百分比
    }
    

    private SwarmItem _item;
    private GameObject _go;
    private Transform _transform;
    private Transform _activeParentTransform;
    private Transform _inactiveParentTransform;


    private int _itemCount;

    protected PrefabItemLists [] _prefabItemLists;、、//拿到每一个list的数量
   
    public bool debugEvents;
   
    public PrefabItem [] itemPrefabs;
   
    public virtual void Initialize()
    {
        if (itemPrefabs.Length == 0)  //必须要有list的项目
        {
            Debug.Log("WARNING! No Item Prefabs exists for " + gameObject.name + " -- Errors will occur.");
        }

        foreach (PrefabItem itemPrefab in itemPrefabs)
        {
            itemPrefab.inactiveThreshold = Mathf.Clamp01(itemPrefab.inactiveThreshold);
            itemPrefab.inactivePrunePercentage = Mathf.Clamp01(itemPrefab.inactivePrunePercentage);
        }
       
        _prefabItemLists = new PrefabItemLists[itemPrefabs.Length];
        for (int i=0; i<_prefabItemLists.Length; i++)
        {
            _prefabItemLists[i] = new PrefabItemLists();
            _prefabItemLists[i].itemCount = 0;
            _prefabItemLists[i].inactivePruneTimeLeft = 0;
        }
       
        _go = new GameObject("Active Items");
        _activeParentTransform = _go.transform;
        _activeParentTransform.parent = this.transform;
        _activeParentTransform.localPosition = Vector3.zero;
        _activeParentTransform.localRotation = Quaternion.identity;
        _activeParentTransform.localScale = Vector3.one;

        _go = new GameObject("Inactive Items");
        _inactiveParentTransform = _go.transform;
        _inactiveParentTransform.parent = this.transform;
        _inactiveParentTransform.localPosition = Vector3.zero;
        _inactiveParentTransform.localRotation = Quaternion.identity;
        _inactiveParentTransform.localScale = Vector3.one;
    }
   
    //生成一个新活动项目
    public virtual SwarmItem ActivateItem()
    {
        return ActivateItem(0);
    }

    ///生成一个新活动项目,总的来说较为复杂orz
    public virtual SwarmItem ActivateItem(int itemPrefabIndex)
    {
        if (_prefabItemLists[itemPrefabIndex].activeItems.Count == itemPrefabs[itemPrefabIndex].maxItemCount && itemPrefabs[itemPrefabIndex].maxItemCount > 0)
        {
            if (debugEvents)
                Debug.Log("Could not activate item because the count [" + _prefabItemLists[itemPrefabIndex].activeItems.Count + "] is at the maximum number for this item type at frame: " + Time.frameCount);
            return null;
        }
        
        if (_prefabItemLists[itemPrefabIndex].inactiveItems.Count > 0)
        {
            // there is an inactive item so we recycle it
            // pop off the inactive stack
            _item = _prefabItemLists[itemPrefabIndex].inactiveItems.Pop();
            
            // queue to the end of the active list
            _prefabItemLists[itemPrefabIndex].activeItems.AddLast(_item);
            
            if (debugEvents)
                Debug.Log("Recycled item " + _item.name + " at frame: " + Time.frameCount);
        }
        else
        {
            // no inactive item availble, so create a new one
            
            // instantiate item
            _item = InstantiateItem(itemPrefabIndex);
            
            // queue to the end of the active list
            _prefabItemLists[itemPrefabIndex].activeItems.AddLast(_item);
            
            if (debugEvents)
                Debug.Log("Instantiated a new item " + _go.name + " at frame: " + Time.frameCount);
        }
        
        // move the item to active parent transform.
        // this is mainly just for visual reference in the editor
        SetItemParentTransform(_item, _activeParentTransform);
        
        // set the state to active
        _item.State = SwarmItem.STATE.Active;
        
        // if the prune timer is runnning
        if (_prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft > 0)
        {        
            // if the inactive item count dropped below the threshold
            if (((float)_prefabItemLists[itemPrefabIndex].inactiveItems.Count / (float)_prefabItemLists[itemPrefabIndex].itemCount) < itemPrefabs[itemPrefabIndex].inactiveThreshold)
            {
                if (debugEvents)
                    Debug.Log("Dropped below inactive threshold [" + (itemPrefabs[itemPrefabIndex].inactiveThreshold * 100) + "%] for " + itemPrefabs[itemPrefabIndex].prefab.name + " list before timer expired. Stopping prune timer at frame: " + Time.frameCount);
                
                // turn the prune timer off
                _prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft = 0;
            }
        }
        
        return _item;
    }
   
    /// 把一个 SwarmItem从 激活列表转移到不激活的列表,并改变父对象,超时和超门槛百分比都会白消掉
    public virtual void DeactiveItem(SwarmItem item)
    {
        // remove from the active linked list
        _prefabItemLists[item.PrefabIndex].activeItems.Remove(item);
        // push onto the inactive stack
        _prefabItemLists[item.PrefabIndex].inactiveItems.Push(item);
       
        SetItemParentTransform(item, _inactiveParentTransform);
        
        if (debugEvents)
            Debug.Log("Deactivated " + item.name + " at frame: " + Time.frameCount);

        if (_prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft == 0 && itemPrefabs[item.PrefabIndex].inactivePrunePercentage > 0)
        {
            // if the inactive item count exceeds the threshold
            if (((float)(_prefabItemLists[item.PrefabIndex].inactiveItems.Count) / (float)_prefabItemLists[item.PrefabIndex].itemCount) >= itemPrefabs[item.PrefabIndex].inactiveThreshold)
            {
                if (debugEvents)
                    Debug.Log("Inactive threshold [" + (itemPrefabs[item.PrefabIndex].inactiveThreshold * 100) + "%] reached for " + itemPrefabs[item.PrefabIndex].prefab.name + " list. Starting prune timer [" + itemPrefabs[item.PrefabIndex].inactivePruneTimer + " seconds] at frame: " + Time.frameCount);
                
                // if the prune timer is set to expire immediately
                if (itemPrefabs[item.PrefabIndex].inactivePruneTimer == 0)
                {
                    // don't wait for a countdown, just prune immediately
                    PruneList(item.PrefabIndex, itemPrefabs[item.PrefabIndex].inactivePrunePercentage);
                }
                else
                {
                    // turn the prune timer on
                    _prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft = itemPrefabs[item.PrefabIndex].inactivePruneTimer;
                }
            }
        }
    }
   
   //实例化一个项目
    protected virtual SwarmItem InstantiateItem(int itemPrefabIndex)
    {
        SwarmItem item;
        
        // instantiate
        _go = (GameObject)Instantiate(itemPrefabs[itemPrefabIndex].prefab);
        // change the name of the gameobject with an index and take off the 'Clone' postfix
        _go.name = "[" + _itemCount.ToString("0000") + "] " + _go.name.Replace("(Clone)", "");
        
        // get the SwarmItem component from the gameobject
        item = (SwarmItem)_go.GetComponent(typeof(SwarmItem));
        // initialize the SwarmItem
        item.Initialize(this, itemPrefabIndex, debugEvents);
        
        // increase the item count for this prefab
        _prefabItemLists[itemPrefabIndex].itemCount++;
        
        // increment the total item count for this manager
        _itemCount++;
        
        return item;
    }
   
    // 移动项目的父对象物体
    private void SetItemParentTransform(SwarmItem item, Transform parentTransform)
    {
        // reparent this item's transform
        item.ThisTransform.parent = parentTransform;
        
        // reset the position, rotation, and scale to unit values
        item.ThisTransform.localPosition = Vector3.zero;
        item.ThisTransform.localRotation = Quaternion.identity;
        item.ThisTransform.localScale = Vector3.one;
        
        // if the position, rotation, or scale need to be changed after reparenting, do it in the
        // item's OnSetParentTransform method
        item.OnSetParentTransform();
    }
    
  //帧更新
    public virtual void FrameUpdate()
    {
        // iterate through each SwarmItem type
        for (int i=0; i<_prefabItemLists.Length; i++)
        {
            // only bother if the active list has some items
            if (_prefabItemLists[i].activeItems.Count > 0)
            {
                // we don't iterate through the active list using foreach here
                // because there would be errors if the item was killed in its FrameUpdate method.
                // instead we manually move to the next linkedlist node
                
                LinkedListNode<SwarmItem> item;
                LinkedListNode<SwarmItem> nextItem;
                
                item = _prefabItemLists[i].activeItems.First;
                
                // while there are items left to process
                while (item != null)
                {
                    // cache the next item in case this item is killed in its FrameUpdate
                    nextItem = item.Next;
                    
                    // update and move to the next item
                    item.Value.FrameUpdate();
                    item = nextItem;
                }
            }
            
            // if this list has its prune timer turned on
            if (_prefabItemLists[i].inactivePruneTimeLeft > 0)
            {
                // decrement the prune timer
                _prefabItemLists[i].inactivePruneTimeLeft -= Time.deltaTime;
                
                // if the timer has expired
                if (_prefabItemLists[i].inactivePruneTimeLeft <= 0)
                {
                    // prune the list
                    PruneList(i, itemPrefabs[i].inactivePrunePercentage);
                }
            }
        }
    }
   
    /// Removes inactive items from the list after the inactive item count exceeds a threshold and
    /// no new items are activated from the list before the prune timer countdown expires. Alternatively,
    /// you could call this manually to free up memory at any time.

修剪list列表
    public void PruneList(int itemPrefabIndex, float prunePercentage)
    {
        // turn off the prune timer
        _prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft = 0;
        
        // get the number of items to prune based on the prune percentage.
        // the amount is a percentage of the inactive items, not the total item count for this list
        int pruneCount = Mathf.FloorToInt(prunePercentage * (float)_prefabItemLists[itemPrefabIndex].inactiveItems.Count);
        SwarmItem item;
        
        if (debugEvents)
            Debug.Log("Pruning " + pruneCount + " items [" + (itemPrefabs[itemPrefabIndex].inactivePrunePercentage*100) + "% of " + _prefabItemLists[itemPrefabIndex].inactiveItems.Count + "] from inactive " + itemPrefabs[itemPrefabIndex].prefab.name + " list at frame: " + Time.frameCount);
        
        // prune each item
        while (pruneCount > 0)
        {
            // pop an item from the inactive stack
            item = (SwarmItem)_prefabItemLists[itemPrefabIndex].inactiveItems.Pop();
            
            // call the overloaded PreDestroy function to let the inherited objects
            // free any memory
            item.PreDestroy();
            
            if (debugEvents)
                Debug.Log("Destroyed " + item.name + " at frame: " + Time.frameCount);
            
            // destroy the item
            Destroy(item.gameObject);
            item = null;
            
            // decrement this list's item count and the manager's total item count
            _prefabItemLists[itemPrefabIndex].itemCount--;
            _itemCount--;
            
            // move to the next item to prune
            pruneCount--;
        }        
    }
}


<think>嗯,用户想了解如何在Docker Swarm中加入一个Manager节点的命令。我需要先回忆一下Docker Swarm的相关知识。Swarm是Docker原生的集群管理工具,Manager节点负责集群的管理工作,比如调度服务、维护集群状态等。 首先,用户可能已经初始化了一个Swarm集群,所以第一步应该是确认如何获取加入Manager所需的令牌和命令。记得初始化Swarm后会生成两种令牌,一个是Worker的,另一个是Manager的。用户需要的是Manager的令牌。 接下来,加入Manager节点的命令应该是`docker swarm join-token manager`,运行这个命令会显示具体的加入命令,包括令牌和IP地址。用户需要在要加入的节点上执行这个命令。 不过,我需要确认命令的正确性,避免记错了参数。比如,是否真的是`docker swarm join --token <manager-token> <manager-ip>:<port>`这样的结构。端口默认是2377,所以如果没改过的话可以直接用IP加端口。 还要提醒用户,如果现有的Manager节点有多个,最好选择稳定的节点作为目标,或者考虑高可用性的配置。同时,防火墙设置可能需要开放2377端口,TCP和UDP的7946端口,以及UDP的4789端口,这些是Swarm通信所需的。 另外,用户可能需要知道如何查看当前Swarm的节点列表,可以用`docker node ls`来确认新Manager是否成功加入。这一步也很重要,确保操作成功。 还要注意,加入Manager节点需要具备足够的管理权限,可能需要sudo或者管理员权限。用户可能会遇到权限问题,所以提醒他们使用sudo或者以root用户运行命令。 最后,可能还需要解释一下Manager节点的作用,比如参与Raft一致性算法,需要奇数个Manager节点来避免脑裂问题,所以用户应该根据集群规模合理规划Manager的数量。</think>以下是在Docker Swarm中将节点加入为Manager的详细步骤: ### 步骤1:在已有Manager节点获取加入命令 ```bash # 在现有的Swarm Manager节点执行 docker swarm join-token manager ``` 执行后会显示如下格式的命令: ```bash docker swarm join --token SWMTKN-1-xxxxxx 192.168.1.100:2377 ``` ### 步骤2:在新节点执行加入命令 ```bash # 在要加入的新节点上执行上一步生成的命令 sudo docker swarm join --token SWMTKN-1-xxxxxx 192.168.1.100:2377 ``` ### 验证加入结果 ```bash # 在任意Manager节点查看节点列表 docker node ls # 输出示例(会显示新节点的MANAGER STATUS) ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS abc123 node2 Ready Active Reachable def456 node1 Ready Active Leader ``` ### 关键参数说明 | 参数 | 说明 | |-------------------|---------------------------------------------------------------------| | `--token` | Manager专用令牌(以`SWMTKN-1`开头) | | `:2377` | Swarm管理端口(必须开放TCP) | | `sudo` | 非root用户操作时需要权限提升 | ### 注意事项 1. 建议保持奇数个Manager节点(3/5/7个)以确保Raft共识算法稳定性 2. 新Manager节点需要开放以下端口: - TCP 2377(集群管理通信) - TCP/UDP 7946(节点间通信) - UDP 4789(覆盖网络) 3. Manager节点应分布在不同的物理节点以保证高可用性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值