/// <summary>
        /// Informs factions that a deed was committed.
        /// </summary>
        /// <param name="actor">FactionMember who committed the deed.</param>
        /// <param name="deed">Deed.</param>
        /// <param name="requiresSight">If `true`, the deed must be seen to be witnessed.</param>
        /// <param name="dimension">The world space dimension to use for radius checks.</param>
        /// <param name="radius">Max distance from position that factions can witness the deed (0=anywhere).</param>
        public void CommitDeed(FactionMember actor, Deed deed, bool requiresSight, Dimension dimension, float radius)
        {
            if (actor == null)
            {
                Debug.LogError("Love/Hate: CommitDeed actor is null", this);
                return;
            }
            if (deed == null)
            {
                Debug.LogError("Love/Hate: CommitDeed deed is null", this);
                return;
            }
            if (debug)
            {
                Debug.Log("Love/Hate: CommitDeed(" + deed.tag + ") actor:" + actor.name + " target:" + GetFaction(deed.targetFactionID).name + " impact:" + deed.impact, this);
            }

            var enumerator = m_members.GetEnumerator(); // Enumerates manually to avoid garbage.

            while (enumerator.MoveNext())
            {
                var members = enumerator.Current.Value;
                for (int i = 0; i < members.Count; i++)
                {
                    var member = members[i];
                    if (IsFactionMemberAwake(member, actor) && IsWitnessInRange(member, actor, dimension, radius))
                    {
                        //---Now queued to distribute across frames: member.WitnessDeed(deed, actor, requiresSight, dimension);
                        m_witnessQueue.Enqueue(WitnessQueueItem.GetNew(deed, member, actor, requiresSight, dimension));
                    }
                }
            }
        }
 public static void Release(WitnessQueueItem item)
 {
     if (item == null)
     {
         return;
     }
     Deed.Release(item.deed);
     pool.Release(item);
 }
        /// <summary>
        /// The Update method processes the queue of deeds waiting to be witnessed.
        /// </summary>
        private void Update()
        {
            if (m_witnessQueue.Count == 0)
            {
                return;
            }
            var count = Mathf.Min(witnessesPerUpdate, m_witnessQueue.Count);

            for (int i = 0; i < count; i++)
            {
                var item = m_witnessQueue.Dequeue();
                if (item == null)
                {
                    return;
                }
                item.witness.WitnessDeed(item.deed, item.actor, item.requiresSight, item.dimension);
                WitnessQueueItem.Release(item);
            }
        }