/// <summary> /// Releases the component at the given index. /// </summary> /// <param name="index"> /// The component index. /// </param> /// <returns> /// The released component or null if index is out of range. /// </returns> public MiComponent ReleaseComponent(int index) { if (index < 0 || index >= ComponentCount) { return(null); } List <string> rem = new(); for (int i = 0; i < ComponentCount; i++) { if (i != index && m_components[i].Requires(m_components[index].TypeName)) { rem.Add(m_components[i].TypeName); } } MiComponent result = m_components[index]; result.UnsubscribeEvents(); result.OnRemove(); m_components.RemoveAt(index); for (int i = 0; i < rem.Count; i++) { RemoveComponent(rem[i]); } result.Parent = null; return(result); }
/// <summary> /// Moves a component from one position to another in the list. /// </summary> /// <param name="from"> /// The index of the component to move. /// </param> /// <param name="to"> /// The destination to move the component. If >= <see cref="ComponentCount"/>, it will be /// added onto the end. /// </param> /// <returns> /// True if from and to are within range and the move was successful, otherwise false. /// </returns> public bool MoveComponent(int from, int to) { if (from < 0 || from >= ComponentCount || to < 0) { return(false); } if (from == to) { return(true); } MiComponent c = GetComponent(from); if (to >= ComponentCount) { m_components.Add(c); } else { m_components.Insert(to, c); } m_components.RemoveAt(from); return(true); }
/// <summary> /// Attempts to deserialize the object from the stream. /// </summary> /// <param name="sr"> /// Stream reader. /// </param> /// <returns> /// True if deserialization succeeded and false otherwise. /// </returns> public override bool LoadFromStream(BinaryReader sr) { if (!base.LoadFromStream(sr)) { return(false); } try { int count = sr.ReadInt32(); m_components = new List <MiComponent>(count); for (int i = 0; i < count; i++) { string type = sr.ReadString(); if (!ComponentRegister.Manager.Registered(type)) { return(Logger.LogReturn($"Failed loading MiEntity: Saved object contains unregistered component name { type }.", false, LogType.Error)); } if (HasComponent(type)) { if (!GetComponent(type).LoadFromStream(sr)) { return(Logger.LogReturn($"Failed loading MiEntity: Unable to load component { type } from stream.", false, LogType.Error)); } } else { MiComponent c = ComponentRegister.Manager.Create(type); if (!c.LoadFromStream(sr)) { return(Logger.LogReturn($"Failed loading MiEntity: Unable to load component { type } from stream.", false, LogType.Error)); } if (!AddComponent(c)) { return(Logger.LogReturn($"Failed loading MiEntity: Unable to add component { type } loaded from stream.", false, LogType.Error)); } } } } catch (Exception e) { return(Logger.LogReturn($"Failed loading MiEntity from stream: { e.Message }", false, LogType.Error)); } return(true); }
/// <summary> /// Checks if a given component and its required components are compatible with the /// current components. /// </summary> /// <param name="comp"> /// The component. /// </param> /// <returns> /// True if the component and its requirements are registered, compatible and can be /// added, otherwise false. /// </returns> public bool IsCompatible(MiComponent comp) { if (comp is null || !IsCompatible(comp.TypeName)) { return(false); } for (int i = 0; i < comp.RequiredComponents.Length; i++) { if (!IsCompatible(comp.RequiredComponents[i])) { return(false); } } return(true); }
/// <summary> /// Attempts to load the object from the xml element. /// </summary> /// <param name="element"> /// The xml element. /// </param> /// <returns> /// True if the object loaded successfully or false on failure. /// </returns> public override bool LoadFromXml(XmlElement element) { if (!base.LoadFromXml(element)) { return(false); } ClearComponents(); XmlNodeList comps = element.ChildNodes; for (int i = 0; i < comps.Count; i++) { if (comps[i].NodeType != XmlNodeType.Element) { continue; } XmlElement e = (XmlElement)comps[i]; if (!ComponentRegister.Manager.Registered(e.Name)) { continue; } MiComponent c = ComponentRegister.Manager.Create(e.Name); if (c is null) { return(Logger.LogReturn($"Unable to load MiEntity: Failed creating component { e.Name }.", false, LogType.Error)); } if (!c.LoadFromXml(e)) { return(Logger.LogReturn($"Unable to load MiEntity: Failed parsing component { e.Name }.", false, LogType.Error)); } if (!AddComponent(c)) { return(Logger.LogReturn($"Unable to load MiEntity: Failed adding component { e.Name }.", false, LogType.Error)); } } return(true); }
/// <summary> /// Adds a component to the stack. /// </summary> /// <param name="comp"> /// The component to add. /// </param> /// <param name="replace"> /// If an already existing component should be replaced. /// </param> /// <returns> /// True if the component was added successfully, otherwise false. /// </returns> public bool AddComponent(MiComponent comp, bool replace = false) { if (m_components.Contains(comp)) { return(true); } if (!IsCompatible(comp)) { return(false); } if (HasComponent(comp.TypeName)) { if (!replace) { return(false); } RemoveComponent(comp.TypeName); } List <string> added = new(); comp.Parent = this; if (Window is not null) { comp.SubscribeEvents(); } m_components.Add(comp); added.Add(comp.TypeName); bool result = true; for (int i = 0; i < comp.RequiredComponents.Length; i++) { if (!HasComponent(comp.RequiredComponents[i])) { if (!AddComponent(ComponentRegister.Manager.Create(comp.RequiredComponents[i]))) { result = false; break; } added.Add(comp.RequiredComponents[i]); } else { MoveComponent(ComponentIndex(comp.RequiredComponents[i]), ComponentCount); } } if (!result) { for (int r = 0; r < added.Count; r++) { RemoveComponent(added[r]); } } else { comp.OnAdd(); } return(result); }