예제 #1
0
        private void AddComponentLazy(ModSessionComponent component, Ob_ModSessionComponent config)
        {
            foreach (var dep in component.Dependencies)
            {
                if (m_dependencySatisfyingComponents.ContainsKey(dep))
                {
                    continue;
                }
                ModSessionComponentRegistry.CreateComponent factory;
                if (!_factories.TryGetValue(dep, out factory))
                {
                    throw new ArgumentException("Can't add " + component.GetType() +
                                                " since we don't have dependency " + dep + " loaded or a factory for it");
                }
                AddComponentLazy(factory(), null);
            }
            // Safe to add to the end of the ordered list.
            var item = new RuntimeSessionComponent(component, config);

            foreach (var dep in component.Dependencies)
            {
                var depRes = m_dependencySatisfyingComponents[dep];
                depRes.Dependents.Add(item);
                item.Dependencies.Add(item);
                item.Component.SatisfyDependency(depRes.Component);
            }
            Insert(item);
            m_orderedComponentList.Add(item);
            if (item.Config != null)
            {
                item.Component.LoadConfiguration(item.Config);
            }
            item.Component.Attached(this);
            ComponentAttached?.Invoke(item.Component);
        }
예제 #2
0
 public void Unregister(ModSessionComponent component)
 {
     if (!m_attached)
     {
         Remove(component);
         return;
     }
     m_componentsToModify.Enqueue(new RemoveOrAdd(component, true));
 }
예제 #3
0
        private void ReadComponent(MemoryStream stream, out ModSessionComponent com, out Ob_ModSessionComponent ob)
        {
            var code = stream.ReadInt32();
            var desc = ModSessionComponentRegistry.Get(stream.ReadUInt64());

            ob  = desc.SerializeFromXml.Invoke(stream.ReadString());
            com = desc.Activator.Invoke();
            m_hashCodeToComponent.Add(code, com);
            Manager.FallbackLogger.Log(MyLogSeverity.Debug, "Read component of type {0} from bootstrapper. ID={1}", com.GetType().Name, code);
        }
예제 #4
0
        private void WriteComponent(ModSessionComponent component, MemoryStream stream)
        {
            var code = CreateIdentifier(component);

            m_hashCodeToComponent[code] = component;
            stream.Write(code);
            var desc = ModSessionComponentRegistry.Get(component.GetType());

            stream.Write(desc.TypeKey);
            stream.Write(MyAPIGateway.Utilities.SerializeToXML(component.SaveConfiguration()));
            Manager.FallbackLogger.Log(MyLogSeverity.Debug, "Wrote component of type {0} for bootstrapper. ID={1}", component.GetType().Name, code);
        }
예제 #5
0
 private byte[] CreateSingleConfig(ModSessionComponent k)
 {
     Manager.FallbackLogger.Log(MyLogSeverity.Debug, "Create add module packet");
     using (Manager.FallbackLogger.IndentUsing())
     {
         var stream = MemoryStream.CreateEmptyStream(512);
         stream.Write(PacketAddModule);
         WriteComponent(k, stream);
         var copy = new byte[stream.WriteHead];
         Array.Copy(stream.Backing, 0, copy, 0, copy.Length);
         stream.Dispose();
         return(copy);
     }
 }
예제 #6
0
        private void Remove(ModSessionComponent component)
        {
            var myType = component.GetType();
            List <RuntimeSessionComponent> list;

            if (m_componentDictionary.TryGetValue(myType, out list))
            {
                for (var i = 0; i < list.Count; i++)
                {
                    if (list[i].Component != component)
                    {
                        continue;
                    }
                    if (list[i].Dependents.Count > 0)
                    {
                        FallbackLogger.Log(MyLogSeverity.Critical, "Unable to remove {0} because it still has {1} dependents", component.GetType(), list[i].Dependents.Count);
                        using (FallbackLogger.IndentUsing())
                            foreach (var dep in list[i].Dependents)
                            {
                                FallbackLogger.Log(MyLogSeverity.Critical, "Dependent: {0}", dep.Component.GetType());
                            }
                        throw new ArgumentException("Can't remove " + component.GetType() + " because it still has dependents");
                    }
                    foreach (var dep in list[i].Dependencies)
                    {
                        dep.Dependents.Remove(list[i]);
                    }
                    list.RemoveAtFast(i);
                    break;
                }
                if (list.Count == 0)
                {
                    m_componentDictionary.Remove(myType);
                }
            }
            foreach (var dep in component.SuppliedComponents)
            {
                m_dependencySatisfyingComponents.Remove(dep);
            }
            for (var i = 0; i < m_orderedComponentList.Count; i++)
            {
                if (m_orderedComponentList[i].Component == component)
                {
                    m_orderedComponentList.RemoveAt(i);
                    break;
                }
            }
            component.Detached();
            ComponentDetached?.Invoke(component);
        }
예제 #7
0
 private void OnComponentRemoved(ModSessionComponent k)
 {
     if (!k.SaveToStorage)
     {
         return;
     }
     if (MyAPIGateway.Players.Count == 0)
     {
         return;
     }
     if (!MyAPIGateway.Multiplayer.SendMessageToOthers(MessageChannel, CreateRemoveConfig(k)))
     {
         Manager.FallbackLogger.Log(MyLogSeverity.Critical, "Failed to send single component removed packet");
     }
 }
예제 #8
0
 private byte[] CreateRemoveConfig(ModSessionComponent k)
 {
     Manager.FallbackLogger.Log(MyLogSeverity.Debug, "Create remove module packet");
     using (Manager.FallbackLogger.IndentUsing())
     {
         var stream = MemoryStream.CreateEmptyStream(5);
         stream.Write(PacketRemoveModule);
         stream.Write(CreateIdentifier(k));
         Manager.FallbackLogger.Log(MyLogSeverity.Debug, "Wrote module remove for component of type {0}", k.GetType().Name);
         var copy = new byte[stream.WriteHead];
         Array.Copy(stream.Backing, 0, copy, 0, copy.Length);
         stream.Dispose();
         return(copy);
     }
 }
예제 #9
0
        public void Register(ModSessionComponent component, Ob_ModSessionComponent config = null)
        {
            foreach (var sat in component.SuppliedComponents)
            {
                if (m_dependencySatisfyingComponents.ContainsKey(sat))
                {
                    throw new ArgumentException("We already have a component satisfying the " + sat + " dependency; we can't have two.");
                }
            }

            if (!m_attached)
            {
                var rsc = new RuntimeSessionComponent(component, config);
                Insert(rsc);
                return;
            }
            m_componentsToModify.Enqueue(new RemoveOrAdd(component, false, config));
        }
예제 #10
0
        public void SatisfyDependency(ModSessionComponent c)
        {
            var hit = false;

            foreach (var type in c.SuppliedComponents)
            {
                DependencyResolver resolver;
                if (!m_dependencies.TryGetValue(type, out resolver))
                {
                    continue;
                }
                hit = true;
                resolver(c);
            }
            if (!hit)
            {
                throw new ArgumentException("Can't use component " + c.GetType() + " to satisfy any of " + string.Join(", ", m_dependencies.Keys));
            }
        }
예제 #11
0
 // ReSharper disable once MemberCanBeMadeStatic.Local
 private int CreateIdentifier(ModSessionComponent component)
 {
     return(RuntimeHelpers.GetHashCode(component));
 }
예제 #12
0
 public RemoveOrAdd(ModSessionComponent c, bool r, Ob_ModSessionComponent cfg = null)
 {
     Component = c;
     Remove    = r;
     Config    = cfg;
 }
예제 #13
0
 public RuntimeSessionComponent(ModSessionComponent c, Ob_ModSessionComponent cfg)
 {
     Component = c;
     Config    = cfg;
 }