/// <summary> /// Tries to retrieve entity definition of the entity owning this container, check if the definition has some DefaultComponents, /// tries to retrieve these components definitions, create these components instances and add them /// /// TODO: This should be ideally a behavior of the MyEntityComponentContainer when it is initialized (deserialized).. or by the factory, for now, this is an extension method /// </summary> public static void InitComponents(this MyComponentContainer container, MyObjectBuilderType type, MyStringHash subtypeName, MyObjectBuilder_ComponentContainer builder) { if (MyDefinitionManager.Static != null) { MyContainerDefinition definition = null; bool IsFirstInit = builder == null; if (TryGetContainerDefinition(type, subtypeName, out definition)) { container.Init(definition); if (definition.DefaultComponents != null) { foreach (var component in definition.DefaultComponents) { MyComponentDefinitionBase componentDefinition = null; MyObjectBuilder_ComponentBase componentBuilder = FindComponentBuilder(component, builder); bool IsComponentSerialized = componentBuilder != null; Type componentType = null; MyComponentBase componentInstance = null; var componentSubtype = subtypeName; if (component.SubtypeId.HasValue) { componentSubtype = component.SubtypeId.Value; } // Create component instance if (TryGetComponentDefinition(component.BuilderType, componentSubtype, out componentDefinition)) { componentInstance = MyComponentFactory.CreateInstanceByTypeId(componentDefinition.Id.TypeId); componentInstance.Init(componentDefinition); } else if (component.IsValid()) { if (!component.BuilderType.IsNull) { componentInstance = MyComponentFactory.CreateInstanceByTypeId(component.BuilderType); } else { componentInstance = MyComponentFactory.CreateInstanceByType(component.InstanceType); } } // Check component type from attributes. if (componentInstance != null) { var componentTypeFromAttr = MyComponentTypeFactory.GetComponentType(componentInstance.GetType()); if (componentTypeFromAttr != null) { componentType = componentTypeFromAttr; } else { if (componentDefinition != null) System.Diagnostics.Debug.Fail("Unknown component type - component type attribute not specified for component class: " + componentInstance.GetType()); } } //TODO: this should be avoided! Component type MUST be set via MyComponentType attribute. if (componentType == null && componentInstance != null) { componentType = componentInstance.GetType(); } // If everything passed, go on.. if (componentInstance != null && componentType != null) { bool componentShouldBeAdded = IsFirstInit || IsComponentSerialized || component.ForceCreate; if (componentShouldBeAdded) { if (componentBuilder != null) { componentInstance.Deserialize(componentBuilder); } // Add only fully initialized component.. container.Add(componentType, componentInstance); } } else { System.Diagnostics.Debug.Fail("Component instance wasn't created or it's base type couldn't been determined!"); } } } else { System.Diagnostics.Debug.Fail("Got definition for container, but DefaultComponents is null!"); } } // This may rewrite already once deserialized data, but will also add missing components in definition container.Deserialize(builder); } else { System.Diagnostics.Debug.Fail("Trying to init enabled components on entity, but definition manager is null"); } }
public static MyObjectBuilder_ComponentBase FindComponentBuilder(MyContainerDefinition.DefaultComponent component, MyObjectBuilder_ComponentContainer builder) { MyObjectBuilder_ComponentBase componentBuilder = null; if (builder != null && component.IsValid()) { MyObjectBuilderType componentObType = null; if (!component.BuilderType.IsNull) { var componentData = builder.Components.Find(x => x.Component.TypeId == component.BuilderType); if (componentData != null) { componentBuilder = componentData.Component; } } } return componentBuilder; }