/// <inheritdoc /> public void AddComponent <T>(IEntity entity, T component, bool overwrite = false) where T : Component { 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."); } var uid = entity.Uid; // 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(uid, type, out var duplicate)) { continue; } if (!overwrite) { throw new InvalidOperationException( $"Component reference type {type} already occupied by {duplicate}"); } // these two components are required on all entities and cannot be overwritten. if (duplicate is ITransformComponent || duplicate is IMetaDataComponent) { throw new InvalidOperationException("Tried to overwrite a protected component."); } RemoveComponentImmediate((Component)duplicate); } // add the component to the grid foreach (var type in reg.References) { _entTraitDict[type].Add(uid, component); _entCompIndex.Add(uid, component); } // add the component to the netId grid if (component.NetID != null) { // the main comp grid keeps this in sync var netId = component.NetID.Value; _entNetIdDict[netId].Add(uid, component); // mark the component as dirty for networking component.Dirty(); ComponentAdded?.Invoke(this, new AddedComponentEventArgs(component)); } component.ExposeData(DefaultValueSerializer.Reader()); component.OnAdd(); if (!entity.Initialized && !entity.Initializing) { return; } component.Initialize(); DebugTools.Assert(component.Initialized, "Component is not initialized after calling Initialize(). " + "Did you forget to call base.Initialize() in an override?"); if (entity.Initialized) { component.Running = true; } }
/// <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}"); } // these two components are required on all entities and cannot be overwritten. if (duplicate is ITransformComponent || duplicate is IMetaDataComponent) { throw new InvalidOperationException("Tried to overwrite a protected component."); } RemoveComponentImmediate((Component)duplicate); } // add the component to the grid foreach (var type in reg.References) { _dictComponents[type].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.ExposeData(DefaultValueSerializer.Reader()); component.OnAdd(); if (entity.Initialized || entity.Initializing) { component.Initialize(); if (entity.Initialized) { component.Running = true; } } }