mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
* oops
* fixes serialization il
* copytest
* typo & misc fixes
* 139 moment
* boxing
* mesa dum
* stuff
* goodbye bad friend
* last commit before the big (4) rewrite
* adds datanodes
* kills yamlobjserializer in favor of the new system
* adds more serializers, actually implements them & removes most of the last of the old system
* changed yamlfieldattribute namespace
* adds back iselfserialize
* refactors consts&flags
* renames everything to data(field/definition)
* adds afterserialization
* help
* dataclassgen
* fuggen help me mannen
* Fix most errors on content
* Fix engine errors except map loader
* maploader & misc fix
* misc fixes
* thing
* help
* refactors datanodes
* help me mannen
* Separate ITypeSerializer into reader and writer
* Convert all type serializers
* priority
* adds alot
* il fixes
* adds robustgen
* argh
* adds array & enum serialization
* fixes dataclasses
* adds vec2i / misc fixes
* fixes inheritance
* a very notcursed todo
* fixes some custom dataclasses
* push dis
* Remove data classes
* boutta box
* yes
* Add angle and regex serializer tests
* Make TypeSerializerTest abstract
* sets up ioc etc
* remove pushinheritance
* fixes
* Merge fixes, fix yaml hot reloading
* General fixes2
* Make enum serialization ignore case
* Fix the tag not being copied in data nodes
* Fix not properly serializing flag enums
* Fix component serialization on startup
* Implement ValueDataNode ToString
* Serialization IL fixes, fix return and string equality
* Remove async from prototype manager
* Make serializing unsupported node as enum exception more descriptive
* Fix serv3 tryread casting to serializer instead of reader
* Add constructor for invalid node type exception
* Temporary fix for SERV3: Turn populate delegate into regular code
* Fix not copying the data of non primitive types
* Fix not using the data definition found in copying
* Make ISerializationHooks require explicit implementations
* Add test for serialization inheritance
* Improve IsOverridenIn method
* Fix error message when a data definition is null
* Add method to cast a read value in Serv3Manager
* Rename IServ3Manager to ISerializationManager
* Rename usages of serv3manager, add generic copy method
* Fix IL copy method lookup
* Rename old usages of serv3manager
* Add ITypeCopier
* resistance is futile
* we will conquer this codebase
* Add copy method to all serializers
* Make primitive mismatch error message more descriptive
* bing bong im going to freacking heck
* oopsie moment
* hello are you interested in my wares
* does generic serializers under new architecture
* Convert every non generic serializer to the new format, general fixes
* Update usgaes of generic serializers, cleanup
* does some pushinheritance logic
* finishes pushinheritance FRAMEWORK
* shed
* Add box2, color and component registry serializer tests
* Create more deserialized types and store prototypes with their deserialized results
* Fixes and serializer updates
* Add serialization manager extensions
* adds pushinheritance
* Update all prototypes to have a parent and have consistent id/parent properties
* Fix grammar component serialization
* Add generic serializer tests
* thonk
* Add array serializer test
* Replace logger warning calls with exceptions
* fixes
* Move redundant methods to serialization manager extensions, cleanup
* Add array serialization
* fixes context
* more fixes
* argh
* inheritance
* this should do it
* fixes
* adds copiers & fixes some stuff
* copiers use context v1
* finishing copy context
* more context fixes
* Test fixes
* funky maps
* Fix server user interface component serialization
* Fix value tuple serialization
* Add copying for value types and arrays. Fix copy internal for primitives, enums and strings
* fixes
* fixes more stuff
* yes
* Make abstract/interface skips debugs instead of warnings
* Fix typo
* Make some dictionaries readonly
* Add checks for the serialization manager initializing and already being initialized
* Add base type required and usage for MeansDataDefinition and ImplicitDataDefinitionForInheritorsAttribute
* copy by ref
* Fix exception wording
* Update data field required summary with the new forbidden docs
* Use extension in map loader
* wanna erp
* Change serializing to not use il temporarily
* Make writing work with nullable types
* pushing
* check
* cuddling slaps HARD
* Add serialization priority test
* important fix
* a serialization thing
* serializer moment
* Add validation for some type serializers
* adds context
* moar context
* fixes
* Do the thing for appearance
* yoo lmao
* push haha pp
* Temporarily make copy delegate regular c# code
* Create deserialized component registry to handle not inheriting conflicting references
* YAML LINTER BABY
* ayes
* Fix sprite component norot not being default true like in latest master
* Remove redundant todos
* Add summary doc to every ISerializationManager method
* icon fixes
* Add skip hook argument to readers and copiers
* Merge fixes
* Fix ordering of arguments in read and copy reflection call
* Fix user interface components deserialization
* pew pew
* i am going to HECK
* Add MustUseReturnValue to copy-over methods
* Make serialization log calls use the same sawmill
* gamin
* Fix doc errors in ISerializationManager.cs
* goodbye brave soldier
* fixes
* WIP merge fixes and entity serialization
* aaaaaaaaaaaaaaa
* aaaaaaaaaaaaaaa
* adds inheritancebehaviour
* test/datafield fixes
* forgot that one
* adds more verbose validation
* This fixes the YAML hot reloading
* Replace yield break with Enumerable.Empty
* adds copiers
* aaaaaaaaaaaaa
* array fix
priority fix
misc fixes
* fix(?)
* fix.
* funny map serialization (wip)
* funny map serialization (wip)
* Add TODO
* adds proper info the validation
* Make yaml linter 5 times faster (~80% less execution time)
* Improves the error message for missing fields in the linter
* Include component name in unknown component type error node
* adds alwaysrelevant usa
* fixes mapsaving
* moved surpressor to analyzers proj
* warning cleanup & moves surpressor
* removes old msbuild targets
* Revert "Make yaml linter 5 times faster (~80% less execution time)"
This reverts commit 2ee4cc2c26.
* Add serialization to RobustServerSimulation and mock reflection methods
Fixes container tests
* Fix nullability warnings
* Improve yaml linter message feedback
* oops moment
* Add IEquatable, IComparable, ToString and operators to DataPosition
Rename it to NodeMark
Make it a readonly struct
* Remove try catch from enum parsing
* Make dependency management in serialization less bad
* Make dependencies an argument instead of a property on the serialization manager
* Clean up type serializers
* Improve validation messages and resourc epath checking
* Fix sprite error message
* reached perfection
Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: Vera Aguilera Puerto <zddm@outlook.es>
403 lines
13 KiB
C#
403 lines
13 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Players;
|
|
using Robust.Shared.Serialization;
|
|
using Robust.Shared.Serialization.Manager;
|
|
using Robust.Shared.Serialization.Manager.Attributes;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Robust.Shared.Containers
|
|
{
|
|
/// <summary>
|
|
/// Holds data about a set of entity containers on this entity.
|
|
/// </summary>
|
|
[RegisterComponent]
|
|
[ComponentReference(typeof(IContainerManager))]
|
|
public class ContainerManagerComponent : Component, IContainerManager
|
|
{
|
|
[Dependency] private readonly IRobustSerializer _serializer = default!;
|
|
[Dependency] private readonly IDynamicTypeFactoryInternal _dynFactory = default!;
|
|
|
|
[ViewVariables]
|
|
[DataField("containers")]
|
|
private Dictionary<string, IContainer> _containers = new();
|
|
|
|
/// <inheritdoc />
|
|
public sealed override string Name => "ContainerContainer";
|
|
|
|
/// <inheritdoc />
|
|
public sealed override uint? NetID => NetIDs.CONTAINER_MANAGER;
|
|
|
|
/// <inheritdoc />
|
|
public override void OnRemove()
|
|
{
|
|
base.OnRemove();
|
|
|
|
// IContianer.Shutdown modifies the _containers collection
|
|
foreach (var container in _containers.Values.ToArray())
|
|
{
|
|
container.Shutdown();
|
|
}
|
|
|
|
_containers.Clear();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
foreach (var container in _containers)
|
|
{
|
|
var baseContainer = (BaseContainer)container.Value;
|
|
baseContainer.Manager = this;
|
|
baseContainer.ID = container.Key;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
|
{
|
|
if (!(curState is ContainerManagerComponentState cast))
|
|
return;
|
|
|
|
// Delete now-gone containers.
|
|
List<string>? toDelete = null;
|
|
foreach (var (id, container) in _containers)
|
|
{
|
|
if (!cast.ContainerSet.Any(data => data.Id == id))
|
|
{
|
|
container.Shutdown();
|
|
toDelete ??= new List<string>();
|
|
toDelete.Add(id);
|
|
}
|
|
}
|
|
|
|
if (toDelete != null)
|
|
{
|
|
foreach (var dead in toDelete)
|
|
{
|
|
_containers.Remove(dead);
|
|
}
|
|
}
|
|
|
|
// Add new containers and update existing contents.
|
|
|
|
foreach (var (containerType, id, showEnts, occludesLight, entityUids) in cast.ContainerSet)
|
|
{
|
|
if (!_containers.TryGetValue(id, out var container))
|
|
{
|
|
container = ContainerFactory(containerType, id);
|
|
_containers.Add(id, container);
|
|
}
|
|
|
|
// sync show flag
|
|
container.ShowContents = showEnts;
|
|
container.OccludesLight = occludesLight;
|
|
|
|
// Remove gone entities.
|
|
List<IEntity>? toRemove = null;
|
|
foreach (var entity in container.ContainedEntities)
|
|
{
|
|
if (!entityUids.Contains(entity.Uid))
|
|
{
|
|
toRemove ??= new List<IEntity>();
|
|
toRemove.Add(entity);
|
|
}
|
|
}
|
|
|
|
if (toRemove != null)
|
|
{
|
|
foreach (var goner in toRemove)
|
|
{
|
|
container.Remove(goner);
|
|
}
|
|
}
|
|
|
|
// Add new entities.
|
|
foreach (var uid in entityUids)
|
|
{
|
|
var entity = Owner.EntityManager.GetEntity(uid);
|
|
|
|
if (!container.ContainedEntities.Contains(entity)) container.Insert(entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
private IContainer ContainerFactory(string containerType, string id)
|
|
{
|
|
var type = _serializer.FindSerializedType(typeof(IContainer), containerType);
|
|
if (type is null) throw new ArgumentException($"Container of type {containerType} for id {id} cannot be found.");
|
|
|
|
var newContainer = _dynFactory.CreateInstanceUnchecked<BaseContainer>(type);
|
|
newContainer.ID = id;
|
|
newContainer.Manager = this;
|
|
return newContainer;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override ComponentState GetComponentState(ICommonSession player)
|
|
{
|
|
// naive implementation that just sends the full state of the component
|
|
List<ContainerManagerComponentState.ContainerData> containerSet = new();
|
|
|
|
foreach (var container in _containers.Values)
|
|
{
|
|
var uidArr = new EntityUid[container.ContainedEntities.Count];
|
|
|
|
for (var index = 0; index < container.ContainedEntities.Count; index++)
|
|
{
|
|
var iEntity = container.ContainedEntities[index];
|
|
uidArr[index] = iEntity.Uid;
|
|
}
|
|
|
|
var sContainer = new ContainerManagerComponentState.ContainerData(container.ContainerType, container.ID, container.ShowContents, container.OccludesLight, uidArr);
|
|
containerSet.Add(sContainer);
|
|
}
|
|
|
|
return new ContainerManagerComponentState(containerSet);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public T MakeContainer<T>(string id)
|
|
where T : IContainer
|
|
{
|
|
return (T) MakeContainer(id, typeof(T));
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IContainer GetContainer(string id)
|
|
{
|
|
return _containers[id];
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool HasContainer(string id)
|
|
{
|
|
return _containers.ContainsKey(id);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool TryGetContainer(string id, [NotNullWhen(true)] out IContainer? container)
|
|
{
|
|
var ret = _containers.TryGetValue(id, out var cont);
|
|
container = cont!;
|
|
return ret;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool TryGetContainer(IEntity entity, [NotNullWhen(true)] out IContainer? container)
|
|
{
|
|
foreach (var contain in _containers.Values)
|
|
{
|
|
if (!contain.Deleted && contain.Contains(entity))
|
|
{
|
|
container = contain;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
container = default;
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool ContainsEntity(IEntity entity)
|
|
{
|
|
foreach (var container in _containers.Values)
|
|
{
|
|
if (!container.Deleted && container.Contains(entity)) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void ForceRemove(IEntity entity)
|
|
{
|
|
foreach (var container in _containers.Values)
|
|
{
|
|
if (container.Contains(entity)) container.ForceRemove(entity);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void InternalContainerShutdown(IContainer container)
|
|
{
|
|
_containers.Remove(container.ID);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool Remove(IEntity entity)
|
|
{
|
|
foreach (var containers in _containers.Values)
|
|
{
|
|
if (containers.Contains(entity)) return containers.Remove(entity);
|
|
}
|
|
|
|
return true; // If we don't contain the entity, it will always be removed
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void Shutdown()
|
|
{
|
|
base.Shutdown();
|
|
|
|
// On shutdown we won't get to process remove events in the containers so this has to be manually done.
|
|
foreach (var container in _containers.Values)
|
|
{
|
|
foreach (var containerEntity in container.ContainedEntities)
|
|
{
|
|
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local,
|
|
new UpdateContainerOcclusionMessage(containerEntity));
|
|
}
|
|
}
|
|
}
|
|
|
|
private IContainer MakeContainer(string id, Type type)
|
|
{
|
|
if (HasContainer(id)) throw new ArgumentException($"Container with specified ID already exists: '{id}'");
|
|
|
|
var container = _dynFactory.CreateInstanceUnchecked<BaseContainer>(type);
|
|
container.ID = id;
|
|
container.Manager = this;
|
|
|
|
_containers[id] = container;
|
|
Dirty();
|
|
return container;
|
|
}
|
|
|
|
public AllContainersEnumerable GetAllContainers()
|
|
{
|
|
return new(this);
|
|
}
|
|
|
|
[Serializable, NetSerializable]
|
|
internal class ContainerManagerComponentState : ComponentState
|
|
{
|
|
public List<ContainerData> ContainerSet;
|
|
|
|
public ContainerManagerComponentState(List<ContainerData> containers) : base(NetIDs.CONTAINER_MANAGER)
|
|
{
|
|
ContainerSet = containers;
|
|
}
|
|
|
|
[Serializable, NetSerializable]
|
|
public readonly struct ContainerData
|
|
{
|
|
public readonly string ContainerType;
|
|
public readonly string Id;
|
|
public readonly bool ShowContents;
|
|
public readonly bool OccludesLight;
|
|
public readonly EntityUid[] ContainedEntities;
|
|
|
|
public ContainerData(string containerType, string id, bool showContents, bool occludesLight, EntityUid[] containedEntities)
|
|
{
|
|
ContainerType = containerType;
|
|
Id = id;
|
|
ShowContents = showContents;
|
|
OccludesLight = occludesLight;
|
|
ContainedEntities = containedEntities;
|
|
}
|
|
|
|
public void Deconstruct(out string type, out string id, out bool showEnts, out bool occludesLight, out EntityUid[] ents)
|
|
{
|
|
type = ContainerType;
|
|
id = Id;
|
|
showEnts = ShowContents;
|
|
occludesLight = OccludesLight;
|
|
ents = ContainedEntities;
|
|
}
|
|
}
|
|
}
|
|
|
|
[DataDefinition]
|
|
private struct ContainerPrototypeData : IPopulateDefaultValues
|
|
{
|
|
[DataField("entities")]
|
|
public List<EntityUid> Entities;
|
|
|
|
[DataField("type")]
|
|
public string? Type;
|
|
|
|
public ContainerPrototypeData(List<EntityUid> entities, string type)
|
|
{
|
|
Entities = entities;
|
|
Type = type;
|
|
}
|
|
|
|
public void PopulateDefaultValues()
|
|
{
|
|
Entities = new List<EntityUid>();
|
|
}
|
|
}
|
|
|
|
public readonly struct AllContainersEnumerable : IEnumerable<IContainer>
|
|
{
|
|
private readonly ContainerManagerComponent _manager;
|
|
|
|
public AllContainersEnumerable(ContainerManagerComponent manager)
|
|
{
|
|
_manager = manager;
|
|
}
|
|
|
|
public AllContainersEnumerator GetEnumerator()
|
|
{
|
|
return new(_manager);
|
|
}
|
|
|
|
IEnumerator<IContainer> IEnumerable<IContainer>.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
|
|
public struct AllContainersEnumerator : IEnumerator<IContainer>
|
|
{
|
|
private Dictionary<string, IContainer>.ValueCollection.Enumerator _enumerator;
|
|
|
|
public AllContainersEnumerator(ContainerManagerComponent manager)
|
|
{
|
|
_enumerator = manager._containers.Values.GetEnumerator();
|
|
Current = default;
|
|
}
|
|
|
|
public bool MoveNext()
|
|
{
|
|
while (_enumerator.MoveNext())
|
|
{
|
|
if (!_enumerator.Current.Deleted)
|
|
{
|
|
Current = _enumerator.Current;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void IEnumerator.Reset()
|
|
{
|
|
((IEnumerator<IContainer>) _enumerator).Reset();
|
|
}
|
|
|
|
[AllowNull]
|
|
public IContainer Current { get; private set; }
|
|
|
|
object IEnumerator.Current => Current;
|
|
|
|
public void Dispose() { }
|
|
}
|
|
}
|
|
}
|