コード例 #1
0
        /// <inheritdoc />
        public void AddComponent(IEntity entity, Component component, bool overwrite = false)
        {
            if (entity == null || !entity.IsValid())
            {
                throw new ArgumentException("Entity is not valid.", nameof(entity));
            }

            if (component == null)
            {
                throw new ArgumentNullException(nameof(component));
            }

            if (component.Owner != entity)
            {
                throw new InvalidOperationException("Component is not owned by entity.");
            }

            // get interface aliases for mapping
            var reg = _componentFactory.GetRegistration(component);

            // Check that there are no overlapping references.
            foreach (var type in reg.References)
            {
                if (!TryGetComponent(entity.Uid, type, out var duplicate))
                {
                    continue;
                }

                if (!overwrite)
                {
                    throw new InvalidOperationException($"Component reference type {type} already occupied by {duplicate}");
                }

                RemoveComponentImmediate((Component)duplicate);
            }

            // add the component to the grid
            foreach (var type in reg.References)
            {
                // new types can be added at any time
                if (!_dictComponents.TryGetValue(type, out var typeDict))
                {
                    typeDict = new Dictionary <EntityUid, Component>(EntityCapacity);
                    _dictComponents.Add(type, typeDict);
                }

                typeDict.Add(entity.Uid, component);
            }

            // add the component to the netId grid
            if (component.NetID != null)
            {
                // the main comp grid keeps this in sync
                if (!_netComponents.TryGetValue(entity.Uid, out var netDict))
                {
                    netDict = new Dictionary <uint, Component>(CompTypeCapacity);
                    _netComponents.Add(entity.Uid, netDict);
                }

                netDict.Add(component.NetID.Value, component);

                // mark the component as dirty for networking
                component.Dirty();

                ComponentAdded?.Invoke(this, new ComponentEventArgs(component));
            }

            component.OnAdd();

            if (entity.Initialized)
            {
                component.Initialize();
                component.Startup();
            }
        }