Revert Arch (#4613)

This commit is contained in:
metalgearsloth
2023-11-27 21:41:01 +11:00
committed by GitHub
parent 7b9aa09b18
commit 24b0165ec9
74 changed files with 1159 additions and 1895 deletions

3
.gitmodules vendored
View File

@@ -13,6 +13,3 @@
[submodule "cefglue"] [submodule "cefglue"]
path = cefglue path = cefglue
url = https://github.com/space-wizards/cefglue.git url = https://github.com/space-wizards/cefglue.git
[submodule "Arch/Arch"]
path = Arch/Arch
url = https://github.com/space-wizards/Arch.git

Submodule Arch/Arch deleted from 12fbc72c54

View File

@@ -1,94 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
<PackageId>Arch</PackageId>
<Title>Arch</Title>
<Version>1.2.7.1-alpha</Version>
<Authors>genaray</Authors>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Description>A high performance c# net.6 and net.7 archetype based ECS ( Entity component system ).</Description>
<PackageReleaseNotes>Updated LowLevel which fixes bugs. </PackageReleaseNotes>
<PackageTags>c#;.net;.net6;.net7;ecs;game;entity;gamedev; game-development; game-engine; entity-component-system;stride;unity;godot;</PackageTags>
<PackageProjectUrl>https://github.com/genaray/Arch</PackageProjectUrl>
<RepositoryUrl>https://github.com/genaray/Arch.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<IsPackable>true</IsPackable>
<LangVersion>11</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Copyright>Apache2.0</Copyright>
<NoWarn>1701;1702;1591</NoWarn>
<Configurations>Debug;Debug-PureECS;Debug-Events;Release;Release-PureECS;Release-Events;</Configurations>
<AssemblyName>Arch</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<DefaultItemExcludes>src/Arch/**/*</DefaultItemExcludes>
<DefineConstants>$(DefineConstants);PURE_ECS;CONTRACTS_FULL</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>$(DefineConstants);PURE_ECS;CONTRACTS_FULL;TRACE;</DefineConstants>
<Optimize>false</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="Arch.Benchmarks" />
<InternalsVisibleTo Include="Arch.Tests" />
</ItemGroup>
<ItemGroup>
<Using Include="System" />
<Using Include="System.Collections" />
<Using Include="System.Collections.Generic" />
<Using Include="System.Diagnostics" />
<Using Include="System.Diagnostics.CodeAnalysis" />
<Using Include="System.IO" />
<Using Include="System.Linq" />
<Using Include="System.Runtime.CompilerServices" />
<Using Include="System.Runtime.InteropServices" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\Arch\src\Arch.SourceGen\Arch.SourceGen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Arch.LowLevel" Version="1.1.0" />
<PackageReference Include="Collections.Pooled" Version="2.0.0-preview.27" />
<PackageReference Include="CommunityToolkit.HighPerformance" Version="7.1.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageReference Include="ZeroAllocJobScheduler" Version="1.0.2" />
</ItemGroup>
<ItemGroup>
<Compile Include="Arch\src\Arch\**\*.cs">
<Link>Arch\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Remove="Arch\src\Arch\obj\**\*.cs" />
<InternalsVisibleTo Include="Arch.Benchmarks" />
<InternalsVisibleTo Include="Arch.Tests" />
</ItemGroup>
<Import Project="../MSBuild/Robust.Properties.targets" />
</Project>

View File

@@ -2203,207 +2203,3 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
- name: Arch
license: |
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 Lars Matthäus/genaray
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,177 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using Arch.Core;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using Robust.Shared.Analyzers;
using static Robust.Benchmarks.EntityManager.ArchetypeComponentAccessBenchmark;
namespace Robust.Benchmarks.Arch;
[MemoryDiagnoser]
[Virtual]
public class ArchComponentAccessBenchmark
{
private const int N = 10000;
private static readonly Consumer Consumer = new();
private Entity _entity;
private World _world = default!;
private QueryDescription _singleQuery;
private QueryDescription _tenQuery;
[GlobalSetup]
public void GlobalSetup()
{
var _ = new JobScheduler.JobScheduler("ArchBenchmark");
_world = World.Create();
for (var i = 0; i < N; i++)
{
var entity = _world.Create();
// Randomly chosen id
if (entity.Id == 1584)
_entity = entity;
_world.Add(
entity,
new Struct1(),
new Struct2(),
new Struct3(),
new Struct4(),
new Struct5(),
new Struct6(),
new Struct7(),
new Struct8(),
new Struct9(),
new Struct10()
);
}
_singleQuery = new QueryDescription().WithAll<Struct1>();
_tenQuery = new QueryDescription().WithAll<Struct1, Struct2, Struct3, Struct4, Struct5, Struct6, Struct7, Struct8, Struct9, Struct10>();
}
[GlobalCleanup]
public void GlobalCleanup()
{
JobScheduler.JobScheduler.Instance.Dispose();
Environment.Exit(0);
}
[Benchmark]
public Struct1 GetSingle()
{
return _world.Get<Struct1>(_entity);
}
[Benchmark]
public (Struct1, Struct2, Struct3, Struct4, Struct5, Struct6, Struct7, Struct8, Struct9, Struct10)
GetTen()
{
return (
_world.Get<Struct1>(_entity),
_world.Get<Struct2>(_entity),
_world.Get<Struct3>(_entity),
_world.Get<Struct4>(_entity),
_world.Get<Struct5>(_entity),
_world.Get<Struct6>(_entity),
_world.Get<Struct7>(_entity),
_world.Get<Struct8>(_entity),
_world.Get<Struct9>(_entity),
_world.Get<Struct10>(_entity)
);
}
[Benchmark]
public bool HasSingle()
{
return _world.Has<Struct1>(_entity);
}
[Benchmark]
public bool HasTen()
{
return _world.Has<Struct1>(_entity) &&
_world.Has<Struct2>(_entity) &&
_world.Has<Struct3>(_entity) &&
_world.Has<Struct4>(_entity) &&
_world.Has<Struct5>(_entity) &&
_world.Has<Struct6>(_entity) &&
_world.Has<Struct7>(_entity) &&
_world.Has<Struct8>(_entity) &&
_world.Has<Struct9>(_entity) &&
_world.Has<Struct10>(_entity);
}
[Benchmark]
public void IterateSingle()
{
_world.Query(_singleQuery, static (ref Struct1 s) => Consumer.Consume(s));
}
[Benchmark]
public void IterateSingleInline()
{
_world.InlineQuery<QueryConsumer>(_singleQuery);
}
[Benchmark]
public void IterateSingleParallel()
{
_world.ParallelQuery(_singleQuery, static (ref Struct1 s) => Consumer.Consume(s));
}
[Benchmark]
public void IterateSingleInlineParallel()
{
_world.InlineParallelQuery<QueryConsumer>(_singleQuery);
}
[Benchmark]
public void IterateTen()
{
_world.Query(_tenQuery,
static (
ref Struct1 s1, ref Struct2 s2, ref Struct3 s3, ref Struct4 s4,
ref Struct5 s5, ref Struct6 s6, ref Struct7 s7, ref Struct8 s8,
ref Struct9 s9, ref Struct10 s10) =>
Consumer.Consume((s1, s2, s3, s4, s5, s6, s7, s8, s9, s10)));
}
[Benchmark]
public void IterateTenInline()
{
_world.InlineQuery<QueryConsumer>(_tenQuery);
}
[Benchmark]
public void IterateTenParallel()
{
_world.ParallelQuery(_tenQuery,
static (
ref Struct1 s1, ref Struct2 s2, ref Struct3 s3, ref Struct4 s4,
ref Struct5 s5, ref Struct6 s6, ref Struct7 s7, ref Struct8 s8,
ref Struct9 s9, ref Struct10 s10) =>
Consumer.Consume((s1, s2, s3, s4, s5, s6, s7, s8, s9, s10)));
}
[Benchmark]
public void IterateTenInlineParallel()
{
_world.InlineParallelQuery<QueryConsumer>(_tenQuery);
}
private struct QueryConsumer : IForEach
{
private static readonly Consumer Consumer = new();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(Entity entity)
{
Consumer.Consume(entity);
}
}
}

View File

@@ -41,7 +41,7 @@ public partial class AddRemoveComponentBenchmark
{ {
for (var i = 2; i <= N+1; i++) for (var i = 2; i <= N+1; i++)
{ {
var uid = new EntityUid(i, -1); var uid = new EntityUid(i);
_entityManager.AddComponent<A>(uid); _entityManager.AddComponent<A>(uid);
_entityManager.RemoveComponent<A>(uid); _entityManager.RemoveComponent<A>(uid);
} }

View File

@@ -57,7 +57,7 @@ public class ComponentIndexBenchmark
private static class CompArrayIndex<T> private static class CompArrayIndex<T>
{ {
// ReSharper disable once StaticMemberInGenericType // ReSharper disable once StaticMemberInGenericType
public static readonly CompIdx Idx = new(Interlocked.Increment(ref _compIndexMaster), typeof(T)); public static readonly CompIdx Idx = new(Interlocked.Increment(ref _compIndexMaster));
} }
private static CompIdx GetCompIdIndex(Type type) private static CompIdx GetCompIdIndex(Type type)

View File

@@ -46,7 +46,7 @@ public partial class GetComponentBenchmark
{ {
for (var i = 2; i <= N+1; i++) for (var i = 2; i <= N+1; i++)
{ {
Comps[i] = _entityManager.GetComponent<A>(new EntityUid(i, -1)); Comps[i] = _entityManager.GetComponent<A>(new EntityUid(i));
} }
// Return something so the JIT doesn't optimize out all the GetComponent calls. // Return something so the JIT doesn't optimize out all the GetComponent calls.

View File

@@ -8,7 +8,6 @@
<NoWarn>RA0003</NoWarn> <NoWarn>RA0003</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Arch\Arch.csproj" />
<ProjectReference Include="..\Robust.Server\Robust.Server.csproj" /> <ProjectReference Include="..\Robust.Server\Robust.Server.csproj" />
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" /> <ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
<ProjectReference Include="..\Robust.UnitTesting\Robust.UnitTesting.csproj" /> <ProjectReference Include="..\Robust.UnitTesting\Robust.UnitTesting.csproj" />

View File

@@ -256,7 +256,7 @@ namespace Robust.Client.Console.Commands
return; return;
} }
var uid = EntityUid.Parse(args[0], "-1"); var uid = EntityUid.Parse(args[0]);
var entmgr = _entityManager; var entmgr = _entityManager;
if (!entmgr.EntityExists(uid)) if (!entmgr.EntityExists(uid))
{ {

View File

@@ -43,7 +43,6 @@ public sealed class ProfileEntitySpawningCommand : IConsoleCommand
GC.Collect(); GC.Collect();
Span<EntityUid> ents = stackalloc EntityUid[amount];
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
stopwatch.Start(); stopwatch.Start();
@@ -51,17 +50,12 @@ public sealed class ProfileEntitySpawningCommand : IConsoleCommand
for (var i = 0; i < amount; i++) for (var i = 0; i < amount; i++)
{ {
ents[i] = _entities.SpawnEntity(prototype, MapCoordinates.Nullspace); _entities.SpawnEntity(prototype, MapCoordinates.Nullspace);
} }
MeasureProfiler.SaveData(); MeasureProfiler.SaveData();
shell.WriteLine($"Client: Profiled spawning {amount} entities in {stopwatch.Elapsed.TotalMilliseconds:N3} ms"); shell.WriteLine($"Client: Profiled spawning {amount} entities in {stopwatch.Elapsed.TotalMilliseconds:N3} ms");
foreach (var ent in ents)
{
_entities.DeleteEntity(ent);
}
} }
} }
#endif #endif

View File

@@ -44,7 +44,7 @@ namespace Robust.Client.GameObjects
EntityUid IClientEntityManagerInternal.CreateEntity(string? prototypeName, out MetaDataComponent metadata) EntityUid IClientEntityManagerInternal.CreateEntity(string? prototypeName, out MetaDataComponent metadata)
{ {
return base.CreateEntity(prototypeName, out metadata, out _); return base.CreateEntity(prototypeName, out metadata);
} }
void IClientEntityManagerInternal.InitializeEntity(EntityUid entity, MetaDataComponent? meta) void IClientEntityManagerInternal.InitializeEntity(EntityUid entity, MetaDataComponent? meta)

View File

@@ -1,9 +1,12 @@
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Map; using Robust.Client.Map;
using Robust.Client.Physics;
using Robust.Client.ResourceManagement; using Robust.Client.ResourceManagement;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Dynamics;
namespace Robust.Client.GameObjects namespace Robust.Client.GameObjects
{ {
@@ -25,5 +28,10 @@ namespace Robust.Client.GameObjects
base.Shutdown(); base.Shutdown();
_overlayManager.RemoveOverlay<TileEdgeOverlay>(); _overlayManager.RemoveOverlay<TileEdgeOverlay>();
} }
protected override void OnMapAdd(EntityUid uid, MapComponent component, ComponentAdd args)
{
EnsureComp<PhysicsMapComponent>(uid);
}
} }
} }

View File

@@ -39,7 +39,7 @@ public sealed class ClientDirtySystem : EntitySystem
private void OnTerminate(ref EntityTerminatingEvent ev) private void OnTerminate(ref EntityTerminatingEvent ev)
{ {
if (!_timing.InPrediction || IsClientSide(ev.Entity, ev.Metadata)) if (!_timing.InPrediction || IsClientSide(ev.Entity))
return; return;
// Client-side entity deletion is not supported and will cause errors. // Client-side entity deletion is not supported and will cause errors.

View File

@@ -5,8 +5,6 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Arch.Core;
using Collections.Pooled;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.ObjectPool;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
@@ -31,9 +29,7 @@ using Robust.Shared.Network.Messages;
using Robust.Shared.Profiling; using Robust.Shared.Profiling;
using Robust.Shared.Replays; using Robust.Shared.Replays;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Toolshed.TypeParsers;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using ComponentType = Arch.Core.Utils.ComponentType;
namespace Robust.Client.GameStates namespace Robust.Client.GameStates
{ {
@@ -56,12 +52,11 @@ namespace Robust.Client.GameStates
private readonly Dictionary<ushort, (IComponent Component, ComponentState? curState, ComponentState? nextState)> _compStateWork = new(); private readonly Dictionary<ushort, (IComponent Component, ComponentState? curState, ComponentState? nextState)> _compStateWork = new();
private readonly Dictionary<EntityUid, HashSet<Type>> _pendingReapplyNetStates = new(); private readonly Dictionary<EntityUid, HashSet<Type>> _pendingReapplyNetStates = new();
private readonly HashSet<NetEntity> _stateEnts = new(); private readonly HashSet<NetEntity> _stateEnts = new();
private readonly List<EntityUid> _toDelete = new();
private readonly List<IComponent> _toRemove = new();
private readonly Dictionary<NetEntity, Dictionary<ushort, ComponentState>> _outputData = new(); private readonly Dictionary<NetEntity, Dictionary<ushort, ComponentState>> _outputData = new();
private readonly List<(EntityUid, TransformComponent)> _queuedBroadphaseUpdates = new(); private readonly List<(EntityUid, TransformComponent)> _queuedBroadphaseUpdates = new();
private readonly List<NetEntity> _created = new();
private readonly List<NetEntity> _detached = new();
private readonly ObjectPool<Dictionary<ushort, ComponentState>> _compDataPool = private readonly ObjectPool<Dictionary<ushort, ComponentState>> _compDataPool =
new DefaultObjectPool<Dictionary<ushort, ComponentState>>(new DictPolicy<ushort, ComponentState>(), 256); new DefaultObjectPool<Dictionary<ushort, ComponentState>>(new DictPolicy<ushort, ComponentState>(), 256);
@@ -545,9 +540,7 @@ namespace Robust.Client.GameStates
var countReset = 0; var countReset = 0;
var system = _entitySystemManager.GetEntitySystem<ClientDirtySystem>(); var system = _entitySystemManager.GetEntitySystem<ClientDirtySystem>();
var metaQuery = _entityManager.GetEntityQuery<MetaDataComponent>(); var metaQuery = _entityManager.GetEntityQuery<MetaDataComponent>();
using var toRemove = new PooledList<IComponent>(); RemQueue<IComponent> toRemove = new();
using var toAdd = new PooledList<ushort>();
using var toAddStates = new PooledList<ComponentState>();
foreach (var entity in system.DirtyEntities) foreach (var entity in system.DirtyEntities)
{ {
@@ -611,17 +604,12 @@ namespace Robust.Client.GameStates
_resettingPredictedEntities = false; _resettingPredictedEntities = false;
} }
if (toRemove.Count > 0) // Remove predicted component additions
foreach (var comp in toRemove)
{ {
// Remove predicted component additions _entities.RemoveComponent(entity, comp);
// TODO: 1 archetype change.
foreach (var comp in toRemove)
{
_entities.RemoveComponent(entity, comp, meta);
}
toRemove.Clear();
} }
toRemove.Clear();
// Re-add predicted removals // Re-add predicted removals
if (system.RemovedComponents.TryGetValue(entity, out var netIds)) if (system.RemovedComponents.TryGetValue(entity, out var netIds))
@@ -634,29 +622,15 @@ namespace Robust.Client.GameStates
if (!last.TryGetValue(netId, out var state)) if (!last.TryGetValue(netId, out var state))
continue; continue;
toAdd.Add(netId); var comp = _entityManager.AddComponent(entity, netId, meta);
toAddStates.Add(state);
}
if (toAdd.Count > 0) if (_sawmill.Level <= LogLevel.Debug)
{ _sawmill.Debug($" A component was removed: {comp.GetType()}");
for (var i = 0; i < toAdd.Count; i++)
{
var netId = toAdd[i];
var state = toAddStates[i];
var comp = _entityManager.AddComponent(entity, netId, meta);
if (_sawmill.Level <= LogLevel.Debug) var stateEv = new ComponentHandleState(state, null);
_sawmill.Debug($" A component was removed: {comp.GetType()}"); _entities.EventBus.RaiseComponentEvent(comp, ref stateEv);
comp.ClearCreationTick(); // don't undo the re-adding.
var stateEv = new ComponentHandleState(state, null); comp.LastModifiedTick = _timing.LastRealTick;
_entities.EventBus.RaiseComponentEvent(comp, ref stateEv);
comp.ClearCreationTick(); // don't undo the re-adding.
comp.LastModifiedTick = _timing.LastRealTick;
}
toAdd.Clear();
toAddStates.Clear();
} }
} }
@@ -739,9 +713,10 @@ namespace Robust.Client.GameStates
_config.TickProcessMessages(); _config.TickProcessMessages();
} }
(IEnumerable<NetEntity> Created, List<NetEntity> Detached) output;
using (_prof.Group("Entity")) using (_prof.Group("Entity"))
{ {
ApplyEntityStates(curState, nextState); output = ApplyEntityStates(curState, nextState);
} }
using (_prof.Group("Player")) using (_prof.Group("Player"))
@@ -751,13 +726,13 @@ namespace Robust.Client.GameStates
using (_prof.Group("Callback")) using (_prof.Group("Callback"))
{ {
GameStateApplied?.Invoke(new GameStateAppliedArgs(curState, _detached)); GameStateApplied?.Invoke(new GameStateAppliedArgs(curState, output.Detached));
} }
return _created; return output.Created;
} }
private void ApplyEntityStates(GameState curState, GameState? nextState) private (IEnumerable<NetEntity> Created, List<NetEntity> Detached) ApplyEntityStates(GameState curState, GameState? nextState)
{ {
var metas = _entities.GetEntityQuery<MetaDataComponent>(); var metas = _entities.GetEntityQuery<MetaDataComponent>();
var xforms = _entities.GetEntityQuery<TransformComponent>(); var xforms = _entities.GetEntityQuery<TransformComponent>();
@@ -766,8 +741,6 @@ namespace Robust.Client.GameStates
var enteringPvs = 0; var enteringPvs = 0;
_toApply.Clear(); _toApply.Clear();
_toCreate.Clear(); _toCreate.Clear();
_detached.Clear();
_created.Clear();
_pendingReapplyNetStates.Clear(); _pendingReapplyNetStates.Clear();
var curSpan = curState.EntityStates.Span; var curSpan = curState.EntityStates.Span;
@@ -792,7 +765,6 @@ namespace Robust.Client.GameStates
var uid = _entities.CreateEntity(metaState.PrototypeId, out var newMeta); var uid = _entities.CreateEntity(metaState.PrototypeId, out var newMeta);
_toCreate.Add(es.NetEntity, es); _toCreate.Add(es.NetEntity, es);
_created.Add(es.NetEntity);
_toApply.Add(uid, (es.NetEntity, newMeta, false, GameTick.Zero, es, null)); _toApply.Add(uid, (es.NetEntity, newMeta, false, GameTick.Zero, es, null));
// Client creates a client-side net entity for the newly created entity. // Client creates a client-side net entity for the newly created entity.
@@ -846,7 +818,7 @@ namespace Robust.Client.GameStates
// Detach entities to null space // Detach entities to null space
var containerSys = _entitySystemManager.GetEntitySystem<ContainerSystem>(); var containerSys = _entitySystemManager.GetEntitySystem<ContainerSystem>();
var lookupSys = _entitySystemManager.GetEntitySystem<EntityLookupSystem>(); var lookupSys = _entitySystemManager.GetEntitySystem<EntityLookupSystem>();
ProcessPvsDeparture(_detached, curState.ToSequence, metas, xforms, xformSys, containerSys, lookupSys); var detached = ProcessPvsDeparture(curState.ToSequence, metas, xforms, xformSys, containerSys, lookupSys);
// Check next state (AFTER having created new entities introduced in curstate) // Check next state (AFTER having created new entities introduced in curstate)
if (nextState != null) if (nextState != null)
@@ -948,6 +920,8 @@ namespace Robust.Client.GameStates
_prof.WriteValue("State Size", ProfData.Int32(curSpan.Length)); _prof.WriteValue("State Size", ProfData.Int32(curSpan.Length));
_prof.WriteValue("Entered PVS", ProfData.Int32(enteringPvs)); _prof.WriteValue("Entered PVS", ProfData.Int32(enteringPvs));
return (_toCreate.Keys, detached);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -978,7 +952,7 @@ namespace Robust.Client.GameStates
var xforms = _entities.GetEntityQuery<TransformComponent>(); var xforms = _entities.GetEntityQuery<TransformComponent>();
var xformSys = _entitySystemManager.GetEntitySystem<SharedTransformSystem>(); var xformSys = _entitySystemManager.GetEntitySystem<SharedTransformSystem>();
using var toDelete = new PooledList<EntityUid>(); _toDelete.Clear();
// Client side entities won't need the transform, but that should always be a tiny minority of entities // Client side entities won't need the transform, but that should always be a tiny minority of entities
var metaQuery = _entityManager.AllEntityQueryEnumerator<MetaDataComponent, TransformComponent>(); var metaQuery = _entityManager.AllEntityQueryEnumerator<MetaDataComponent, TransformComponent>();
@@ -989,7 +963,7 @@ namespace Robust.Client.GameStates
if (metadata.NetEntity.IsClientSide()) if (metadata.NetEntity.IsClientSide())
{ {
if (deleteClientEntities) if (deleteClientEntities)
toDelete.Add(ent); _toDelete.Add(ent);
continue; continue;
} }
@@ -1016,14 +990,14 @@ namespace Robust.Client.GameStates
&& !deleteClientEntities // don't add duplicates && !deleteClientEntities // don't add duplicates
&& _entities.IsClientSide(child.Value)) && _entities.IsClientSide(child.Value))
{ {
toDelete.Add(child.Value); _toDelete.Add(child.Value);
} }
} }
toDelete.Add(ent); _toDelete.Add(ent);
} }
foreach (var ent in toDelete) foreach (var ent in _toDelete)
{ {
_entities.DeleteEntity(ent); _entities.DeleteEntity(ent);
} }
@@ -1083,8 +1057,7 @@ namespace Robust.Client.GameStates
Detach(GameTick.MaxValue, null, entities, metas, xforms, xformSys, containerSys, lookupSys); Detach(GameTick.MaxValue, null, entities, metas, xforms, xformSys, containerSys, lookupSys);
} }
private void ProcessPvsDeparture( private List<NetEntity> ProcessPvsDeparture(
IList<NetEntity> detached,
GameTick toTick, GameTick toTick,
EntityQuery<MetaDataComponent> metas, EntityQuery<MetaDataComponent> metas,
EntityQuery<TransformComponent> xforms, EntityQuery<TransformComponent> xforms,
@@ -1092,17 +1065,18 @@ namespace Robust.Client.GameStates
ContainerSystem containerSys, ContainerSystem containerSys,
EntityLookupSystem lookupSys) EntityLookupSystem lookupSys)
{ {
using var toDetach = new PooledList<(GameTick Tick, List<NetEntity> Entities)>(); var toDetach = _processor.GetEntitiesToDetach(toTick, _pvsDetachBudget);
_processor.GetEntitiesToDetach(toDetach, toTick, _pvsDetachBudget); var detached = new List<NetEntity>();
if (toDetach.Count == 0) if (toDetach.Count == 0)
return; return detached;
// TODO optimize // TODO optimize
// If an entity is leaving PVS, so are all of its children. If we can preserve the hierarchy we can avoid // If an entity is leaving PVS, so are all of its children. If we can preserve the hierarchy we can avoid
// things like container insertion and ejection. // things like container insertion and ejection.
using var _ = _prof.Group("Leave PVS"); using var _ = _prof.Group("Leave PVS");
detached.EnsureCapacity(toDetach.Count);
foreach (var (tick, ents) in toDetach) foreach (var (tick, ents) in toDetach)
{ {
@@ -1110,6 +1084,7 @@ namespace Robust.Client.GameStates
} }
_prof.WriteValue("Count", ProfData.Int32(detached.Count)); _prof.WriteValue("Count", ProfData.Int32(detached.Count));
return detached;
} }
private void Detach(GameTick maxTick, private void Detach(GameTick maxTick,
@@ -1120,7 +1095,7 @@ namespace Robust.Client.GameStates
SharedTransformSystem xformSys, SharedTransformSystem xformSys,
ContainerSystem containerSys, ContainerSystem containerSys,
EntityLookupSystem lookupSys, EntityLookupSystem lookupSys,
IList<NetEntity>? detached = null) List<NetEntity>? detached = null)
{ {
foreach (var netEntity in entities) foreach (var netEntity in entities)
{ {
@@ -1174,7 +1149,7 @@ namespace Robust.Client.GameStates
var metaQuery = _entityManager.GetEntityQuery<MetaDataComponent>(); var metaQuery = _entityManager.GetEntityQuery<MetaDataComponent>();
#if EXCEPTION_TOLERANCE #if EXCEPTION_TOLERANCE
using var brokenEnts = new PooledList<EntityUid>(); var brokenEnts = new List<EntityUid>();
#endif #endif
using (_prof.Group("Initialize Entity")) using (_prof.Group("Initialize Entity"))
{ {
@@ -1238,28 +1213,18 @@ namespace Robust.Client.GameStates
// First remove any deleted components // First remove any deleted components
if (curState?.NetComponents != null) if (curState?.NetComponents != null)
{ {
using var toRemove = new PooledList<IComponent>(); _toRemove.Clear();
using var compTypes = new PooledList<ComponentType>();
foreach (var (id, comp) in meta.NetComponents) foreach (var (id, comp) in meta.NetComponents)
{ {
if (comp.NetSyncEnabled && !curState.NetComponents.Contains(id)) if (comp.NetSyncEnabled && !curState.NetComponents.Contains(id))
{ _toRemove.Add(comp);
toRemove.Add(comp);
compTypes.Add(comp.GetType());
}
} }
if (toRemove.Count > 0) foreach (var comp in _toRemove)
{ {
foreach (var comp in toRemove) _entities.RemoveComponent(uid, comp, meta);
{
_entityManager.RemoveComponentInternal(uid, comp, terminating: false, archetypeChange: false, meta);
}
} }
if (compTypes.Count > 0)
_entityManager.RemoveComponentRange(uid, compTypes);
} }
if (enteringPvs) if (enteringPvs)
@@ -1274,7 +1239,7 @@ namespace Robust.Client.GameStates
if (!meta.NetComponents.TryGetValue(id, out var comp)) if (!meta.NetComponents.TryGetValue(id, out var comp))
{ {
comp = _compFactory.GetComponent(id); comp = _compFactory.GetComponent(id);
_entityManager.AddComponent(uid, comp, metadata: meta); _entityManager.AddComponent(uid, comp, true, metadata: meta);
} }
_compStateWork[id] = (comp, state, null); _compStateWork[id] = (comp, state, null);
@@ -1282,49 +1247,18 @@ namespace Robust.Client.GameStates
} }
else if (curState != null) else if (curState != null)
{ {
using var addedComps = new PooledList<IComponent>();
using var addedCompTypes = new PooledList<ComponentType>();
using var addedRegistrations = new PooledList<ComponentRegistration>();
foreach (var compChange in curState.ComponentChanges.Span) foreach (var compChange in curState.ComponentChanges.Span)
{ {
if (!meta.NetComponents.TryGetValue(compChange.NetID, out var comp)) if (!meta.NetComponents.TryGetValue(compChange.NetID, out var comp))
{ {
var registration = _compFactory.GetRegistration(compChange.NetID); comp = _compFactory.GetComponent(compChange.NetID);
addedRegistrations.Add(registration); _entityManager.AddComponent(uid, comp, true, metadata:meta);
comp = _compFactory.GetComponent(registration);
comp.Owner = uid;
addedComps.Add(comp);
addedCompTypes.Add(comp.GetType());
} }
else if (compChange.LastModifiedTick <= lastApplied && lastApplied != GameTick.Zero) else if (compChange.LastModifiedTick <= lastApplied && lastApplied != GameTick.Zero)
continue; continue;
_compStateWork[compChange.NetID] = (comp, compChange.State, null); _compStateWork[compChange.NetID] = (comp, compChange.State, null);
} }
// To avoid shuffling the archetype we'll set the component range up-front.
if (addedComps.Count > 0)
{
// TODO: This fucking sucks but
// - Frequent archetype changes PER COMPONENT sucks
// - the components will be null in event handlers until it's done.
_entityManager.AddComponentRange(uid, addedCompTypes);
for (var i = 0; i < addedComps.Count; i++)
{
var component = addedComps[i];
var reg = addedRegistrations[i];
_entityManager.AddComponentInternalOnly(uid, component, reg, meta);
}
for (var i = 0; i < addedComps.Count; i++)
{
var component = addedComps[i];
var reg = addedRegistrations[i];
_entityManager.AddComponentEvents(uid, component, reg, false, meta);
}
}
} }
if (nextState != null) if (nextState != null)
@@ -1414,7 +1348,7 @@ namespace Robust.Client.GameStates
return false; return false;
} }
if (!EntityUid.TryParse(args[0], "-1", out uid)) if (!EntityUid.TryParse(args[0], out uid))
{ {
shell.WriteError(Loc.GetString("cmd-parse-failure-uid", ("arg", args[0]))); shell.WriteError(Loc.GetString("cmd-parse-failure-uid", ("arg", args[0])));
meta = null; meta = null;
@@ -1546,22 +1480,23 @@ namespace Robust.Client.GameStates
if (!meta.NetComponents.TryGetValue(id, out var comp)) if (!meta.NetComponents.TryGetValue(id, out var comp))
{ {
comp = _compFactory.GetComponent(id); comp = _compFactory.GetComponent(id);
_entityManager.AddComponent(uid, comp, meta); _entityManager.AddComponent(uid, comp, true, meta);
} }
var handleState = new ComponentHandleState(state, null); var handleState = new ComponentHandleState(state, null);
_entityManager.EventBus.RaiseComponentEvent(comp, ref handleState); _entityManager.EventBus.RaiseComponentEvent(comp, ref handleState);
} }
using var toRemove = new PooledList<IComponent>(); // ensure we don't have any extra components
_toRemove.Clear();
foreach (var (id, comp) in meta.NetComponents) foreach (var (id, comp) in meta.NetComponents)
{ {
if (comp.NetSyncEnabled && !lastState.ContainsKey(id)) if (comp.NetSyncEnabled && !lastState.ContainsKey(id))
toRemove.Add(comp); _toRemove.Add(comp);
} }
foreach (var comp in toRemove) foreach (var comp in _toRemove)
{ {
_entities.RemoveComponent(uid, comp); _entities.RemoveComponent(uid, comp);
} }
@@ -1574,10 +1509,10 @@ namespace Robust.Client.GameStates
public sealed class GameStateAppliedArgs : EventArgs public sealed class GameStateAppliedArgs : EventArgs
{ {
public readonly GameState AppliedState; public GameState AppliedState { get; }
public readonly IReadOnlyList<NetEntity> Detached; public readonly List<NetEntity> Detached;
public GameStateAppliedArgs(GameState appliedState, IReadOnlyList<NetEntity> detached) public GameStateAppliedArgs(GameState appliedState, List<NetEntity> detached)
{ {
AppliedState = appliedState; AppliedState = appliedState;
Detached = detached; Detached = detached;

View File

@@ -304,8 +304,9 @@ Had full state: {LastFullState != null}"
public void ClearDetachQueue() => _pvsDetachMessages.Clear(); public void ClearDetachQueue() => _pvsDetachMessages.Clear();
public void GetEntitiesToDetach(IList<(GameTick Tick, List<NetEntity> Entities)> result, GameTick toTick, int budget) public List<(GameTick Tick, List<NetEntity> Entities)> GetEntitiesToDetach(GameTick toTick, int budget)
{ {
var result = new List<(GameTick Tick, List<NetEntity> Entities)>();
foreach (var (tick, entities) in _pvsDetachMessages) foreach (var (tick, entities) in _pvsDetachMessages)
{ {
if (tick > toTick) if (tick > toTick)
@@ -324,6 +325,7 @@ Had full state: {LastFullState != null}"
entities.RemoveRange(index, budget); entities.RemoveRange(index, budget);
break; break;
} }
return result;
} }
private bool TryGetDeltaState(out GameState? curState, out GameState? nextState) private bool TryGetDeltaState(out GameState? curState, out GameState? nextState)

View File

@@ -44,7 +44,7 @@ namespace Robust.Client.Placement.Modes
var closestEntity = snapToEntities[0]; var closestEntity = snapToEntities[0];
var closestTransform = pManager.EntityManager.GetComponent<TransformComponent>(closestEntity); var closestTransform = pManager.EntityManager.GetComponent<TransformComponent>(closestEntity);
if (!pManager.EntityManager.TryGetComponent(closestEntity, out SpriteComponent? component) || component.BaseRSI == null) if (!pManager.EntityManager.TryGetComponent<SpriteComponent?>(closestEntity, out var component) || component.BaseRSI == null)
{ {
return; return;
} }

View File

@@ -27,9 +27,9 @@
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" /> <PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(EnableClientScripting)' == 'True'"> <ItemGroup Condition="'$(EnableClientScripting)' == 'True'">
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.0.1" PrivateAssets="compile" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.0.1" PrivateAssets="compile" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" PrivateAssets="compile" />
<ProjectReference Include="..\Robust.Shared.Scripting\Robust.Shared.Scripting.csproj" /> <ProjectReference Include="..\Robust.Shared.Scripting\Robust.Shared.Scripting.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -62,7 +62,7 @@ namespace Robust.Client.ViewVariables.Editors
void OnEntered(LineEdit.LineEditEventArgs e) void OnEntered(LineEdit.LineEditEventArgs e)
{ {
var gridVal = EntityUid.Parse(gridId.Text, "-1"); var gridVal = EntityUid.Parse(gridId.Text);
var mapManager = IoCManager.Resolve<IMapManager>(); var mapManager = IoCManager.Resolve<IMapManager>();
var xVal = float.Parse(x.Text, CultureInfo.InvariantCulture); var xVal = float.Parse(x.Text, CultureInfo.InvariantCulture);
var yVal = float.Parse(y.Text, CultureInfo.InvariantCulture); var yVal = float.Parse(y.Text, CultureInfo.InvariantCulture);

View File

@@ -28,7 +28,7 @@ namespace Robust.Client.ViewVariables.Editors
if (!ReadOnly) if (!ReadOnly)
{ {
lineEdit.OnTextEntered += e => lineEdit.OnTextEntered += e =>
ValueChanged(EntityUid.Parse(e.Text, ", -1")); ValueChanged(EntityUid.Parse(e.Text));
} }
var vvButton = new Button() var vvButton = new Button()

View File

@@ -43,7 +43,6 @@ public sealed class ProfileEntitySpawningCommand : IConsoleCommand
GC.Collect(); GC.Collect();
Span<EntityUid> ents = stackalloc EntityUid[amount];
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
stopwatch.Start(); stopwatch.Start();
@@ -51,17 +50,12 @@ public sealed class ProfileEntitySpawningCommand : IConsoleCommand
for (var i = 0; i < amount; i++) for (var i = 0; i < amount; i++)
{ {
ents[i] = _entities.SpawnEntity(prototype, MapCoordinates.Nullspace); _entities.SpawnEntity(prototype, MapCoordinates.Nullspace);
} }
MeasureProfiler.SaveData(); MeasureProfiler.SaveData();
shell.WriteLine($"Server: Profiled spawning {amount} entities in {stopwatch.Elapsed.TotalMilliseconds:N3} ms"); shell.WriteLine($"Server: Profiled spawning {amount} entities in {stopwatch.Elapsed.TotalMilliseconds:N3} ms");
foreach (var ent in ents)
{
_entities.DeleteEntity(ent);
}
} }
} }
#endif #endif

View File

@@ -5,9 +5,6 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Arch.Core;
using Arch.Core.Utils;
using Collections.Pooled;
using Robust.Server.Maps; using Robust.Server.Maps;
using Robust.Shared.ContentPack; using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -157,11 +154,10 @@ public sealed class MapLoaderSystem : EntitySystem
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
result = Deserialize(data); result = Deserialize(data);
_logLoader.Debug($"Loaded map in {sw.Elapsed}");
_logLoader.Info($"Loaded map {resPath} in {sw.Elapsed}");
var xformQuery = _serverEntityManager.GetEntityQuery<TransformComponent>();
var mapEnt = _mapManager.GetMapEntityId(mapId); var mapEnt = _mapManager.GetMapEntityId(mapId);
var xformQuery = _serverEntityManager.GetEntityQuery<TransformComponent>();
var rootEnts = new List<EntityUid>(); var rootEnts = new List<EntityUid>();
// aeoeoeieioe content // aeoeoeieioe content
@@ -178,8 +174,6 @@ public sealed class MapLoaderSystem : EntitySystem
} }
} }
EntityManager.CleanupArch();
rootUids = rootEnts; rootUids = rootEnts;
} }
@@ -434,10 +428,6 @@ public sealed class MapLoaderSystem : EntitySystem
if (data.Version >= 4) if (data.Version >= 4)
{ {
var metaEntities = data.RootMappingNode.Get<SequenceDataNode>("entities"); var metaEntities = data.RootMappingNode.Get<SequenceDataNode>("entities");
using var mapSaveCompType = new PooledSet<Type>()
{
typeof(MapSaveIdComponent)
};
foreach (var metaDef in metaEntities.Cast<MappingDataNode>()) foreach (var metaDef in metaEntities.Cast<MappingDataNode>())
{ {
@@ -457,30 +447,9 @@ public sealed class MapLoaderSystem : EntitySystem
var entities = (SequenceDataNode) metaDef["entities"]; var entities = (SequenceDataNode) metaDef["entities"];
EntityPrototype? proto = null; EntityPrototype? proto = null;
var count = entities.Count;
var entTotal = data.Entities.Count + count;
data.Entities.EnsureCapacity(entTotal);
data.UidEntityMap.EnsureCapacity(entTotal);
data.EntitiesToDeserialize.EnsureCapacity(entTotal);
if (type != null) if (type != null)
{ _prototypeManager.TryIndex(type, out proto);
if (_prototypeManager.TryIndex(type, out proto) && count > 1)
{
ComponentType[] compTypes;
if (data.Options.StoreMapUids)
{
compTypes = EntityManager.GetComponentType(proto, mapSaveCompType);
}
else
{
compTypes = EntityManager.GetComponentType(proto);
}
EntityManager.Reserve(compTypes, count);
}
}
foreach (var entityDef in entities.Cast<MappingDataNode>()) foreach (var entityDef in entities.Cast<MappingDataNode>())
{ {
@@ -495,7 +464,6 @@ public sealed class MapLoaderSystem : EntitySystem
{ {
deletedPrototypeUids.Add(entity); deletedPrototypeUids.Add(entity);
} }
// TODO: Move this elsewhere?
else if (data.Options.StoreMapUids) else if (data.Options.StoreMapUids)
{ {
var comp = _serverEntityManager.AddComponent<MapSaveIdComponent>(entity); var comp = _serverEntityManager.AddComponent<MapSaveIdComponent>(entity);
@@ -604,7 +572,6 @@ public sealed class MapLoaderSystem : EntitySystem
_context.CurrentlyIgnoredComponents = missingComponentList.Cast<ValueDataNode>().Select(x => x.Value).ToHashSet(); _context.CurrentlyIgnoredComponents = missingComponentList.Cast<ValueDataNode>().Select(x => x.Value).ToHashSet();
_serverEntityManager.FinishEntityLoad(uid, meta.EntityPrototype, _context); _serverEntityManager.FinishEntityLoad(uid, meta.EntityPrototype, _context);
if (_context.CurrentlyIgnoredComponents.Count > 0) if (_context.CurrentlyIgnoredComponents.Count > 0)
meta.LastComponentRemoved = _timing.CurTick; meta.LastComponentRemoved = _timing.CurTick;
} }

View File

@@ -24,6 +24,11 @@ namespace Robust.Server.GameObjects
_cfg.OnValueChanged(CVars.GameDeleteEmptyGrids, SetGridDeletion, true); _cfg.OnValueChanged(CVars.GameDeleteEmptyGrids, SetGridDeletion, true);
} }
protected override void OnMapAdd(EntityUid uid, MapComponent component, ComponentAdd args)
{
EnsureComp<PhysicsMapComponent>(uid);
}
private void SetGridDeletion(bool value) private void SetGridDeletion(bool value)
{ {
_deleteEmptyGrids = value; _deleteEmptyGrids = value;

View File

@@ -26,7 +26,7 @@ namespace Robust.Server.GameObjects
/// Manager for entities -- controls things like template loading and instantiation /// Manager for entities -- controls things like template loading and instantiation
/// </summary> /// </summary>
[UsedImplicitly] // DI Container [UsedImplicitly] // DI Container
public sealed partial class ServerEntityManager : EntityManager, IServerEntityManagerInternal public sealed class ServerEntityManager : EntityManager, IServerEntityManagerInternal
{ {
private static readonly Gauge EntitiesCount = Metrics.CreateGauge( private static readonly Gauge EntitiesCount = Metrics.CreateGauge(
"robust_entities_count", "robust_entities_count",
@@ -62,7 +62,7 @@ namespace Robust.Server.GameObjects
EntityUid IServerEntityManagerInternal.AllocEntity(EntityPrototype? prototype) EntityUid IServerEntityManagerInternal.AllocEntity(EntityPrototype? prototype)
{ {
return AllocEntity(prototype, out _, out _); return AllocEntity(prototype, out _);
} }
void IServerEntityManagerInternal.FinishEntityLoad(EntityUid entity, IEntityLoadContext? context) void IServerEntityManagerInternal.FinishEntityLoad(EntityUid entity, IEntityLoadContext? context)
@@ -85,15 +85,15 @@ namespace Robust.Server.GameObjects
StartEntity(entity); StartEntity(entity);
} }
private protected override EntityUid CreateEntity(string? prototypeName, out MetaDataComponent metadata, out TransformComponent xform, IEntityLoadContext? context = null) private protected override EntityUid CreateEntity(string? prototypeName, out MetaDataComponent metadata, IEntityLoadContext? context = null)
{ {
if (prototypeName == null) if (prototypeName == null)
return base.CreateEntity(prototypeName, out metadata, out xform, context); return base.CreateEntity(prototypeName, out metadata, context);
if (!PrototypeManager.TryIndex<EntityPrototype>(prototypeName, out var prototype)) if (!PrototypeManager.TryIndex<EntityPrototype>(prototypeName, out var prototype))
throw new EntityCreationException($"Attempted to spawn an entity with an invalid prototype: {prototypeName}"); throw new EntityCreationException($"Attempted to spawn an entity with an invalid prototype: {prototypeName}");
var entity = base.CreateEntity(prototype, out metadata, out xform, context); var entity = base.CreateEntity(prototype, out metadata, context);
// At this point in time, all data configure on the entity *should* be purely from the prototype. // At this point in time, all data configure on the entity *should* be purely from the prototype.
// As such, we can reset the modified ticks to Zero, // As such, we can reset the modified ticks to Zero,
@@ -159,7 +159,7 @@ namespace Robust.Server.GameObjects
base.TickUpdate(frameTime, noPredictions, histogram); base.TickUpdate(frameTime, noPredictions, histogram);
EntitiesCount.Set(EntityCount); EntitiesCount.Set(Entities.Count);
} }
public uint GetLastMessageSequence(ICommonSession session) public uint GetLastMessageSequence(ICommonSession session)

View File

@@ -251,7 +251,7 @@ namespace Robust.Server.Placement
/// </summary> /// </summary>
public void SendPlacementBegin(EntityUid mob, int range, string objectType, string alignOption) public void SendPlacementBegin(EntityUid mob, int range, string objectType, string alignOption)
{ {
if (!_entityManager.TryGetComponent(mob, out ActorComponent? actor)) if (!_entityManager.TryGetComponent<ActorComponent?>(mob, out var actor))
return; return;
var playerConnection = actor.PlayerSession.Channel; var playerConnection = actor.PlayerSession.Channel;
@@ -272,7 +272,7 @@ namespace Robust.Server.Placement
/// </summary> /// </summary>
public void SendPlacementBeginTile(EntityUid mob, int range, string tileType, string alignOption) public void SendPlacementBeginTile(EntityUid mob, int range, string tileType, string alignOption)
{ {
if (!_entityManager.TryGetComponent(mob, out ActorComponent? actor)) if (!_entityManager.TryGetComponent<ActorComponent?>(mob, out var actor))
return; return;
var playerConnection = actor.PlayerSession.Channel; var playerConnection = actor.PlayerSession.Channel;
@@ -293,7 +293,7 @@ namespace Robust.Server.Placement
/// </summary> /// </summary>
public void SendPlacementCancel(EntityUid mob) public void SendPlacementCancel(EntityUid mob)
{ {
if (!_entityManager.TryGetComponent(mob, out ActorComponent? actor)) if (!_entityManager.TryGetComponent<ActorComponent?>(mob, out var actor))
return; return;
var playerConnection = actor.PlayerSession.Channel; var playerConnection = actor.PlayerSession.Channel;

View File

@@ -22,7 +22,7 @@
<PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
<PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.2" /> <PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.2" />
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" /> <PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.0" PrivateAssets="compile" /> <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="6.0.2" PrivateAssets="compile" />
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" /> <PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" PrivateAssets="compile" /> <PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" PrivateAssets="compile" />
<PackageReference Condition="'$(FullRelease)' != 'True'" Include="JetBrains.Profiler.Api" Version="1.2.0" /> <PackageReference Condition="'$(FullRelease)' != 'True'" Include="JetBrains.Profiler.Api" Version="1.2.0" />

View File

@@ -3,7 +3,6 @@ using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
@@ -295,9 +294,9 @@ namespace Robust.Server.Scripting
loader: TextLoader.From(TextAndVersion.Create(SourceText.From(message.Code), VersionStamp.Create())) loader: TextLoader.From(TextAndVersion.Create(SourceText.From(message.Code), VersionStamp.Create()))
)); ));
var results = await (CompletionService var results = await CompletionService
.GetService(document)? .GetService(document)
.GetCompletionsAsync(document, message.Cursor) ?? Task.FromResult<CompletionList?>(null)); .GetCompletionsAsync(document, message.Cursor);
if (results is not null) if (results is not null)
{ {

View File

@@ -8,9 +8,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="ILReader.Core" Version="1.0.0.4" /> <PackageReference Include="ILReader.Core" Version="1.0.0.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
</ItemGroup> </ItemGroup>

View File

@@ -51,7 +51,7 @@ namespace Robust.Shared.Scripting
public EntityCoordinates gpos(double x, double y, int gridId) public EntityCoordinates gpos(double x, double y, int gridId)
{ {
return gpos(x, y, new EntityUid(gridId, -1)); return gpos(x, y, new EntityUid(gridId));
} }
public EntityCoordinates gpos(double x, double y, EntityUid gridId) public EntityCoordinates gpos(double x, double y, EntityUid gridId)
@@ -61,12 +61,12 @@ namespace Robust.Shared.Scripting
public EntityUid eid(int i) public EntityUid eid(int i)
{ {
return new(i, -1); return new(i);
} }
public MapGridComponent getgrid(int i) public MapGridComponent getgrid(int i)
{ {
return map.GetGrid(new EntityUid(i, -1)); return map.GetGrid(new EntityUid(i));
} }
public MapGridComponent getgrid(EntityUid mapId) public MapGridComponent getgrid(EntityUid mapId)
@@ -193,7 +193,7 @@ namespace Robust.Shared.Scripting
public bool TryComp<T>(EntityUid uid, out T? comp) where T : IComponent public bool TryComp<T>(EntityUid uid, out T? comp) where T : IComponent
=> ent.TryGetComponent(uid, out comp); => ent.TryGetComponent(uid, out comp);
public bool HasComp<T>(EntityUid uid) where T : IComponent public bool HasComp<T>(EntityUid uid)
=> ent.HasComponent<T>(uid); => ent.HasComponent<T>(uid);
public EntityUid Spawn(string? prototype, EntityCoordinates position) public EntityUid Spawn(string? prototype, EntityCoordinates position)

View File

@@ -1,17 +0,0 @@
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Robust.Shared.Console.Commands;
public sealed class ArchTrimCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entManager = default!;
public string Command => "arch_trim";
public string Description => "Runs TrimExcess on arch";
public string Help => Command;
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
_entManager.CleanupArch();
}
}

View File

@@ -1,47 +0,0 @@
using Arch.Core;
using Collections.Pooled;
namespace Robust.Shared.GameObjects;
internal struct ArchetypeIterator
{
private readonly PooledList<Archetype> _archetypes;
internal ArchetypeIterator(PooledList<Archetype> archetypes)
{
_archetypes = archetypes;
}
public ArchetypeEnumerator GetEnumerator()
{
return new ArchetypeEnumerator(_archetypes);
}
}
internal struct ArchetypeEnumerator
{
private readonly PooledList<Archetype> _archetypes;
private int _index;
public ArchetypeEnumerator(PooledList<Archetype> archetypes)
{
_archetypes = archetypes;
_index = _archetypes.Count;
}
public bool MoveNext()
{
while (--_index >= 0)
{
var archetype = Current;
if (archetype.EntityCount > 0)
{
return true;
}
}
return false;
}
public Archetype Current => _archetypes[_index];
}

View File

@@ -1,60 +0,0 @@
using Arch.Core;
namespace Robust.Shared.GameObjects;
internal struct ArchChunkIterator
{
private readonly ArchetypeEnumerator _archetypes;
internal ArchChunkIterator(in ArchetypeEnumerator archetypes)
{
_archetypes = archetypes;
}
public ArchChunkEnumerator GetEnumerator()
{
return new ArchChunkEnumerator(_archetypes);
}
}
internal struct ArchChunkEnumerator
{
private ArchetypeEnumerator _archetypes;
private int _chunkIndex;
public Chunk Current => _archetypes.Current.GetChunk(_chunkIndex);
internal ArchChunkEnumerator(in ArchetypeEnumerator archetypes)
{
_archetypes = archetypes;
if (_archetypes.MoveNext())
{
_chunkIndex = _archetypes.Current.ChunkCount;
}
}
public bool MoveNext()
{
if (--_chunkIndex >= 0 && Current.Size > 0)
{
return true;
}
if (!_archetypes.MoveNext())
{
return false;
}
_chunkIndex = _archetypes.Current.ChunkCount - 1;
return true;
}
}
internal static partial class QueryExtensions
{
internal static ArchChunkIterator ChunkIterator(this in Query query, World world)
{
var archetypeEnumerator = new ArchetypeEnumerator(query.Matches);
return new ArchChunkIterator(in archetypeEnumerator);
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using Arch.Core.Utils;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -14,7 +13,6 @@ public readonly struct CompIdx : IEquatable<CompIdx>
private static readonly Dictionary<Type, CompIdx> SlowStore = new(); private static readonly Dictionary<Type, CompIdx> SlowStore = new();
internal readonly int Value; internal readonly int Value;
internal readonly ComponentType Type;
internal static CompIdx Index<T>() => Store<T>.Index; internal static CompIdx Index<T>() => Store<T>.Index;
@@ -64,13 +62,12 @@ public readonly struct CompIdx : IEquatable<CompIdx>
private static class Store<T> private static class Store<T>
{ {
// ReSharper disable once StaticMemberInGenericType // ReSharper disable once StaticMemberInGenericType
public static readonly CompIdx Index = new(Interlocked.Increment(ref _CompIdxMaster), typeof(T)); public static readonly CompIdx Index = new(Interlocked.Increment(ref _CompIdxMaster));
} }
internal CompIdx(int value, in ComponentType type) internal CompIdx(int value)
{ {
Value = value; Value = value;
Type = type;
} }
public bool Equals(CompIdx other) public bool Equals(CompIdx other)

View File

@@ -55,4 +55,17 @@ namespace Robust.Shared.GameObjects
Meta = meta; Meta = meta;
} }
} }
public readonly struct DeletedComponentEventArgs
{
public readonly ComponentEventArgs BaseArgs;
public readonly bool Terminating;
public DeletedComponentEventArgs(ComponentEventArgs baseArgs, bool terminating)
{
BaseArgs = baseArgs;
Terminating = terminating;
}
}
} }

View File

@@ -27,7 +27,7 @@ namespace Robust.Shared.GameObjects
[ViewVariables] [ViewVariables]
private NetEntity NetParent => _entMan.GetNetEntity(_parent); private NetEntity NetParent => _entMan.GetNetEntity(_parent);
[DataField("parent")] internal EntityUid _parent = EntityUid.Invalid; [DataField("parent")] internal EntityUid _parent;
[DataField("pos")] internal Vector2 _localPosition = Vector2.Zero; // holds offset from grid, or offset from parent [DataField("pos")] internal Vector2 _localPosition = Vector2.Zero; // holds offset from grid, or offset from parent
[DataField("rot")] internal Angle _localRotation; // local rotation [DataField("rot")] internal Angle _localRotation; // local rotation
[DataField("noRot")] internal bool _noLocalRotation; [DataField("noRot")] internal bool _noLocalRotation;
@@ -733,7 +733,7 @@ namespace Robust.Shared.GameObjects
{ {
public bool IsValid() => Uid.IsValid(); public bool IsValid() => Uid.IsValid();
public bool Valid => IsValid(); public bool Valid => IsValid();
public static readonly BroadphaseData Invalid = new(EntityUid.Invalid, EntityUid.Invalid, false, false); public static readonly BroadphaseData Invalid = default;
// TODO include MapId if ever grids are allowed to enter null-space (leave PVS). // TODO include MapId if ever grids are allowed to enter null-space (leave PVS).
} }

View File

@@ -1,48 +0,0 @@
using Arch.Core;
namespace Robust.Shared.GameObjects;
internal struct EntityIterator
{
private readonly Chunk _chunk;
internal EntityIterator(in Chunk chunk)
{
_chunk = chunk;
}
public EntityEnumerator GetEnumerator()
{
return new EntityEnumerator(_chunk);
}
}
internal struct EntityEnumerator
{
private readonly Chunk _chunk;
private int _entityIndex;
public Entity Current { get; private set; }
public EntityEnumerator(in Chunk chunk)
{
_chunk = chunk;
}
public bool MoveNext()
{
if (_entityIndex >= _chunk.Entities.Length)
return false;
Current = _chunk.Entities[_entityIndex];
_entityIndex++;
return true;
}
}
internal static partial class QueryExtensions
{
internal static EntityIterator ChunkIterator(this in Chunk chunk)
{
return new EntityIterator(chunk);
}
}

View File

@@ -1,114 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Arch.Core;
using Arch.Core.Extensions;
using Arch.Core.Utils;
using Collections.Pooled;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Robust.Shared.GameObjects;
public partial class EntityManager
{
private World _world = default!;
private static readonly ComponentType[] DefaultArchetype = new ComponentType[]
{
typeof(MetaDataComponent),
typeof(TransformComponent),
};
protected void InitializeArch()
{
_world = World.Create();
}
protected void ShutdownArch()
{
World.Destroy(_world);
}
protected void DestroyArch(EntityUid uid)
{
var reference = _world.Reference(uid);
if (!_world.IsAlive(reference))
{
throw new InvalidOperationException("Tried to delete an invalid entity reference");
}
_world.Destroy(reference);
}
private void SpawnEntityArch(out EntityUid entity)
{
var archEnt = _world.Create(DefaultArchetype);
var reference = _world.Reference(archEnt);
entity = new EntityUid(reference);
}
public void CleanupArch()
{
var sw = new Stopwatch();
sw.Start();
var arc = _world.Archetypes.Count;
_world.TrimExcess();
arc -= _world.Archetypes.Count;
sw.Stop();
_sawmill.Debug($"Trimming {arc} archetypes took {sw.Elapsed.TotalMilliseconds} milliseconds");
}
internal ComponentType[] GetComponentType(EntityPrototype prototype, ICollection<Type>? added = null, ICollection<Type>? missing = null)
{
var compTypes = new ComponentType[prototype.Components.Count + (added?.Count ?? 0) - (missing?.Count ?? 0)];
var idx = 0;
foreach (var comp in prototype.Components.Values)
{
var componentType = comp.Component.GetType();
if (missing?.Contains(componentType) == true || added?.Contains(componentType) == true)
continue;
compTypes[idx++] = componentType;
}
if (added != null)
{
foreach (var componentType in added)
{
if (missing?.Contains(componentType) == true)
continue;
compTypes[idx++] = componentType;
}
}
return compTypes;
}
/// <summary>
/// Reserves additional slots for the specified ComponentTypes.
/// </summary>
internal void Reserve(ComponentType[] compTypes, int count)
{
_world.Reserve(compTypes, count);
}
/// <summary>
/// WARNING: DO NOT CALL THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
/// Adds the component types to the entity, shuffling its archetype.
/// </summary>
internal void AddComponentRange(EntityUid uid, PooledList<ComponentType> compTypes)
{
DebugTools.Assert(compTypes.Count > 0);
_world.AddRange(uid, compTypes);
}
internal void RemoveComponentRange(EntityUid uid, PooledList<ComponentType> compTypes)
{
DebugTools.Assert(compTypes.Count > 0);
_world.RemoveRange(uid, compTypes.Span);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Arch.Core.Extensions.Dangerous;
using Robust.Shared.Containers; using Robust.Shared.Containers;
namespace Robust.Shared.GameObjects; namespace Robust.Shared.GameObjects;
@@ -41,16 +40,6 @@ public partial class EntityManager
return ents; return ents;
} }
public EntityUid[] SpawnEntities(MapCoordinates coordinates, string? prototype, int count)
{
var ents = new EntityUid[count];
for (var i = 0; i < count; i++)
{
ents[i] = Spawn(prototype, coordinates);
}
return ents;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, List<string?> protoNames) public EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, List<string?> protoNames)
{ {

View File

@@ -2,10 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Arch.Core; using System.Runtime.CompilerServices;
using Arch.Core.Extensions;
using Arch.Core.Utils;
using Collections.Pooled;
using Prometheus; using Prometheus;
using Robust.Shared.Log; using Robust.Shared.Log;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -16,8 +13,6 @@ using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Runtime.CompilerServices;
using ComponentRegistry = Robust.Shared.Prototypes.ComponentRegistry;
namespace Robust.Shared.GameObjects namespace Robust.Shared.GameObjects
{ {
@@ -44,8 +39,6 @@ namespace Robust.Shared.GameObjects
// positions on spawn.... // positions on spawn....
private SharedTransformSystem _xforms = default!; private SharedTransformSystem _xforms = default!;
private QueryDescription _archMetaQuery = new QueryDescription().WithAll<MetaDataComponent>();
public EntityQuery<MetaDataComponent> MetaQuery; public EntityQuery<MetaDataComponent> MetaQuery;
public EntityQuery<TransformComponent> TransformQuery; public EntityQuery<TransformComponent> TransformQuery;
@@ -69,8 +62,15 @@ namespace Robust.Shared.GameObjects
private EntityDiffContext _context = new(); private EntityDiffContext _context = new();
/// <summary>
/// All entities currently stored in the manager.
/// </summary>
protected readonly HashSet<EntityUid> Entities = new();
private EntityEventBus _eventBus = null!; private EntityEventBus _eventBus = null!;
protected int NextEntityUid = (int) EntityUid.FirstUid;
protected int NextNetworkId = (int) NetEntity.First; protected int NextNetworkId = (int) NetEntity.First;
/// <inheritdoc /> /// <inheritdoc />
@@ -116,7 +116,7 @@ namespace Robust.Shared.GameObjects
_eventBus = new EntityEventBus(this); _eventBus = new EntityEventBus(this);
InitializeArch(); InitializeComponents();
_metaReg = _componentFactory.GetRegistration(typeof(MetaDataComponent)); _metaReg = _componentFactory.GetRegistration(typeof(MetaDataComponent));
_xformReg = _componentFactory.GetRegistration(typeof(TransformComponent)); _xformReg = _componentFactory.GetRegistration(typeof(TransformComponent));
_xformName = _xformReg.Name; _xformName = _xformReg.Name;
@@ -144,17 +144,15 @@ namespace Robust.Shared.GameObjects
} }
var protoData = PrototypeManager.GetPrototypeData(prototype); var protoData = PrototypeManager.GetPrototypeData(prototype);
var comps = _world.GetAllComponents(uid); var comps = _entCompIndex[uid];
// Fast check if the component counts match. // Fast check if the component counts match.
// Note that transform and metadata are not included in the prototype data. // Note that transform and metadata are not included in the prototype data.
if (protoData.Count + 2 != comps.Length) if (protoData.Count + 2 != comps.Count)
return false; return false;
foreach (var comp in comps) foreach (var component in comps)
{ {
var component = (IComponent)comp!;
if (component.Deleted) if (component.Deleted)
return false; return false;
@@ -210,7 +208,6 @@ namespace Robust.Shared.GameObjects
FlushEntities(); FlushEntities();
_eventBus.ClearEventTables(); _eventBus.ClearEventTables();
_entitySystemManager.Shutdown(); _entitySystemManager.Shutdown();
ShutdownArch();
ClearComponents(); ClearComponents();
ShuttingDown = false; ShuttingDown = false;
Started = false; Started = false;
@@ -218,12 +215,12 @@ namespace Robust.Shared.GameObjects
public virtual void Cleanup() public virtual void Cleanup()
{ {
_componentFactory.ComponentAdded -= OnComponentAdded;
ShuttingDown = true; ShuttingDown = true;
FlushEntities(); FlushEntities();
_entitySystemManager.Clear(); _entitySystemManager.Clear();
_eventBus.Dispose(); _eventBus.Dispose();
_eventBus = null!; _eventBus = null!;
ShutdownArch();
ClearComponents(); ClearComponents();
ShuttingDown = false; ShuttingDown = false;
@@ -272,27 +269,28 @@ namespace Robust.Shared.GameObjects
public EntityUid CreateEntityUninitialized(string? prototypeName, EntityUid euid, ComponentRegistry? overrides = null) public EntityUid CreateEntityUninitialized(string? prototypeName, EntityUid euid, ComponentRegistry? overrides = null)
{ {
return CreateEntity(prototypeName, out _, out _, overrides); return CreateEntity(prototypeName, out _, overrides);
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual EntityUid CreateEntityUninitialized(string? prototypeName, ComponentRegistry? overrides = null) public virtual EntityUid CreateEntityUninitialized(string? prototypeName, ComponentRegistry? overrides = null)
{ {
return CreateEntity(prototypeName, out _, out _, overrides); return CreateEntity(prototypeName, out _, overrides);
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual EntityUid CreateEntityUninitialized(string? prototypeName, EntityCoordinates coordinates, ComponentRegistry? overrides = null) public virtual EntityUid CreateEntityUninitialized(string? prototypeName, EntityCoordinates coordinates, ComponentRegistry? overrides = null)
{ {
var newEntity = CreateEntity(prototypeName, out _, out var xform, overrides); var newEntity = CreateEntity(prototypeName, out _, overrides);
_xforms.SetCoordinates(newEntity, xform, coordinates, unanchor: false); _xforms.SetCoordinates(newEntity, TransformQuery.GetComponent(newEntity), coordinates, unanchor: false);
return newEntity; return newEntity;
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual EntityUid CreateEntityUninitialized(string? prototypeName, MapCoordinates coordinates, ComponentRegistry? overrides = null) public virtual EntityUid CreateEntityUninitialized(string? prototypeName, MapCoordinates coordinates, ComponentRegistry? overrides = null)
{ {
var newEntity = CreateEntity(prototypeName, out _, out var transform, overrides); var newEntity = CreateEntity(prototypeName, out _, overrides);
var transform = TransformQuery.GetComponent(newEntity);
if (coordinates.MapId == MapId.Nullspace) if (coordinates.MapId == MapId.Nullspace)
{ {
@@ -322,19 +320,10 @@ namespace Robust.Shared.GameObjects
} }
/// <inheritdoc /> /// <inheritdoc />
public int EntityCount => _world.Size; public int EntityCount => Entities.Count;
/// <inheritdoc /> /// <inheritdoc />
public IEnumerable<EntityUid> GetEntities() public IEnumerable<EntityUid> GetEntities() => Entities;
{
var ents = new List<Entity>();
_world.GetEntities(_archMetaQuery, ents);
foreach (var entity in ents)
{
yield return EntityUid.FromArch(_world, entity);
}
}
/// <inheritdoc /> /// <inheritdoc />
public virtual void DirtyEntity(EntityUid uid, MetaDataComponent? metadata = null) public virtual void DirtyEntity(EntityUid uid, MetaDataComponent? metadata = null)
@@ -386,7 +375,7 @@ namespace Robust.Shared.GameObjects
/// <param name="e">Entity to remove</param> /// <param name="e">Entity to remove</param>
public virtual void DeleteEntity(EntityUid? uid) public virtual void DeleteEntity(EntityUid? uid)
{ {
if (uid == null || uid == EntityUid.Invalid) if (uid == null)
return; return;
var e = uid.Value; var e = uid.Value;
@@ -411,9 +400,9 @@ namespace Robust.Shared.GameObjects
} }
// Notify all entities they are being terminated prior to detaching & deleting // Notify all entities they are being terminated prior to detaching & deleting
var xform = TransformQuery.GetComponent(e); RecursiveFlagEntityTermination(e, meta);
RecursiveFlagEntityTermination(e, meta, xform);
var xform = TransformQuery.GetComponent(e);
TransformComponent? parentXform = null; TransformComponent? parentXform = null;
if (xform.ParentUid.IsValid()) if (xform.ParentUid.IsValid())
TransformQuery.Resolve(xform.ParentUid, ref parentXform); TransformQuery.Resolve(xform.ParentUid, ref parentXform);
@@ -424,14 +413,14 @@ namespace Robust.Shared.GameObjects
private void RecursiveFlagEntityTermination( private void RecursiveFlagEntityTermination(
EntityUid uid, EntityUid uid,
MetaDataComponent metadata, MetaDataComponent metadata)
TransformComponent transform)
{ {
var transform = TransformQuery.GetComponent(uid);
metadata.EntityLifeStage = EntityLifeStage.Terminating; metadata.EntityLifeStage = EntityLifeStage.Terminating;
try try
{ {
var ev = new EntityTerminatingEvent(uid, metadata); var ev = new EntityTerminatingEvent(uid);
EventBus.RaiseLocalEvent(uid, ref ev, true); EventBus.RaiseLocalEvent(uid, ref ev, true);
} }
catch (Exception e) catch (Exception e)
@@ -448,7 +437,7 @@ namespace Robust.Shared.GameObjects
continue; continue;
} }
RecursiveFlagEntityTermination(child, childMeta, TransformQuery.GetComponent(child)); RecursiveFlagEntityTermination(child, childMeta);
} }
} }
@@ -496,12 +485,8 @@ namespace Robust.Shared.GameObjects
_sawmill.Error($"Failed to delete all children of entity: {ToPrettyString(uid)}"); _sawmill.Error($"Failed to delete all children of entity: {ToPrettyString(uid)}");
// Shut down all components. // Shut down all components.
var objComps = _world.GetAllComponents(uid); foreach (var component in InSafeOrder(_entCompIndex[uid]))
foreach (var comp in objComps)
{ {
var component = (IComponent)comp!;
if (component.Running) if (component.Running)
{ {
try try
@@ -516,7 +501,7 @@ namespace Robust.Shared.GameObjects
} }
// Dispose all my components, in a safe order so transform is available // Dispose all my components, in a safe order so transform is available
DisposeComponents(uid, metadata); DisposeComponents(uid);
metadata.EntityLifeStage = EntityLifeStage.Deleted; metadata.EntityLifeStage = EntityLifeStage.Deleted;
try try
@@ -529,14 +514,14 @@ namespace Robust.Shared.GameObjects
} }
_eventBus.OnEntityDeleted(uid); _eventBus.OnEntityDeleted(uid);
DestroyArch(uid); Entities.Remove(uid);
// Need to get the ID above before MetadataComponent shutdown but only remove it after everything else is done. // Need to get the ID above before MetadataComponent shutdown but only remove it after everything else is done.
NetEntityLookup.Remove(metadata.NetEntity); NetEntityLookup.Remove(metadata.NetEntity);
} }
public virtual void QueueDeleteEntity(EntityUid? uid) public virtual void QueueDeleteEntity(EntityUid? uid)
{ {
if (uid == null || uid.Value == EntityUid.Invalid) if (uid == null)
return; return;
if (!QueuedDeletionsSet.Add(uid.Value)) if (!QueuedDeletionsSet.Add(uid.Value))
@@ -550,7 +535,7 @@ namespace Robust.Shared.GameObjects
public bool EntityExists(EntityUid uid) public bool EntityExists(EntityUid uid)
{ {
return IsAlive(uid); return MetaQuery.HasComponentInternal(uid);
} }
public bool EntityExists(EntityUid? uid) public bool EntityExists(EntityUid? uid)
@@ -569,26 +554,12 @@ namespace Robust.Shared.GameObjects
public bool Deleted(EntityUid uid) public bool Deleted(EntityUid uid)
{ {
return !IsAlive(uid) || !_world.TryGet(uid, out MetaDataComponent? comp) || comp!.EntityLifeStage > EntityLifeStage.Terminating; return !MetaQuery.TryGetComponentInternal(uid, out var comp) || comp.EntityDeleted;
}
/// <summary>
/// Returns whether the entity is alive inside of the ECS world.
/// </summary>
internal bool IsAlive(EntityUid uid)
{
return ((EntityReference) uid).IsAlive(_world);
}
internal bool TryAlive(EntityUid uid, out EntityReference entity)
{
entity = uid;
return entity.IsAlive(_world);
} }
public bool Deleted([NotNullWhen(false)] EntityUid? uid) public bool Deleted([NotNullWhen(false)] EntityUid? uid)
{ {
return !uid.HasValue || Deleted(uid.Value); return !uid.HasValue || !MetaQuery.TryGetComponentInternal(uid.Value, out var comp) || comp.EntityDeleted;
} }
/// <summary> /// <summary>
@@ -603,9 +574,7 @@ namespace Robust.Shared.GameObjects
DeleteEntity(e); DeleteEntity(e);
} }
CleanupArch(); if (Entities.Count != 0)
if (_world.Size > 0)
_sawmill.Error("Entities were spawned while flushing entities."); _sawmill.Error("Entities were spawned while flushing entities.");
} }
@@ -614,10 +583,9 @@ namespace Robust.Shared.GameObjects
/// </summary> /// </summary>
private protected EntityUid AllocEntity( private protected EntityUid AllocEntity(
EntityPrototype? prototype, EntityPrototype? prototype,
out MetaDataComponent metadata, out MetaDataComponent metadata)
out TransformComponent xform)
{ {
var entity = AllocEntity(out metadata, out xform); var entity = AllocEntity(out metadata);
metadata._entityPrototype = prototype; metadata._entityPrototype = prototype;
Dirty(entity, metadata, metadata); Dirty(entity, metadata, metadata);
return entity; return entity;
@@ -626,9 +594,16 @@ namespace Robust.Shared.GameObjects
/// <summary> /// <summary>
/// Allocates an entity and stores it but does not load components or do initialization. /// Allocates an entity and stores it but does not load components or do initialization.
/// </summary> /// </summary>
private EntityUid AllocEntity(out MetaDataComponent metadata, out TransformComponent xform) private EntityUid AllocEntity(out MetaDataComponent metadata)
{ {
SpawnEntityArch(out var uid); var uid = GenerateEntityUid();
#if DEBUG
if (EntityExists(uid))
{
throw new InvalidOperationException($"UID already taken: {uid}");
}
#endif
// we want this called before adding components // we want this called before adding components
EntityAdded?.Invoke(uid); EntityAdded?.Invoke(uid);
@@ -645,15 +620,16 @@ namespace Robust.Shared.GameObjects
SetNetEntity(uid, netEntity, metadata); SetNetEntity(uid, netEntity, metadata);
Entities.Add(uid);
// add the required MetaDataComponent directly. // add the required MetaDataComponent directly.
AddComponentInternal(uid, metadata, _metaReg, true, metadata); AddComponentInternal(uid, metadata, _metaReg, false, true, metadata);
// allocate the required TransformComponent // allocate the required TransformComponent
xform = Unsafe.As<TransformComponent>(_componentFactory.GetComponent(_xformReg)); var xformComp = Unsafe.As<TransformComponent>(_componentFactory.GetComponent(_xformReg));
#pragma warning disable CS0618 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete
xform.Owner = uid; xformComp.Owner = uid;
#pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0618 // Type or member is obsolete
AddComponentInternal(uid, xform, true, metadata); AddComponentInternal(uid, xformComp, false, true, metadata);
return uid; return uid;
} }
@@ -661,26 +637,26 @@ namespace Robust.Shared.GameObjects
/// <summary> /// <summary>
/// Allocates an entity and loads components but does not do initialization. /// Allocates an entity and loads components but does not do initialization.
/// </summary> /// </summary>
private protected virtual EntityUid CreateEntity(string? prototypeName, out MetaDataComponent metadata, out TransformComponent xform, IEntityLoadContext? context = null) private protected virtual EntityUid CreateEntity(string? prototypeName, out MetaDataComponent metadata, IEntityLoadContext? context = null)
{ {
if (prototypeName == null) if (prototypeName == null)
return AllocEntity(out metadata, out xform); return AllocEntity(out metadata);
if (!PrototypeManager.TryIndex<EntityPrototype>(prototypeName, out var prototype)) if (!PrototypeManager.TryIndex<EntityPrototype>(prototypeName, out var prototype))
throw new EntityCreationException($"Attempted to spawn an entity with an invalid prototype: {prototypeName}"); throw new EntityCreationException($"Attempted to spawn an entity with an invalid prototype: {prototypeName}");
return CreateEntity(prototype, out metadata, out xform, context); return CreateEntity(prototype, out metadata, context);
} }
/// <summary> /// <summary>
/// Allocates an entity and loads components but does not do initialization. /// Allocates an entity and loads components but does not do initialization.
/// </summary> /// </summary>
private protected EntityUid CreateEntity(EntityPrototype prototype, out MetaDataComponent metadata, out TransformComponent xform, IEntityLoadContext? context = null) private protected EntityUid CreateEntity(EntityPrototype prototype, out MetaDataComponent metadata, IEntityLoadContext? context = null)
{ {
var entity = AllocEntity(prototype, out metadata, out xform); var entity = AllocEntity(prototype, out metadata);
try try
{ {
LoadEntity(metadata.EntityPrototype, entity, context); EntityPrototype.LoadEntity(metadata.EntityPrototype, entity, ComponentFactory, this, _serManager, context);
return entity; return entity;
} }
catch (Exception e) catch (Exception e)
@@ -694,105 +670,18 @@ namespace Robust.Shared.GameObjects
private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context) private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context)
{ {
LoadEntity(MetaQuery.GetComponent(entity).EntityPrototype, entity, context); EntityPrototype.LoadEntity(MetaQuery.GetComponent(entity).EntityPrototype, entity, ComponentFactory, this, _serManager, context);
} }
private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context, EntityPrototype? prototype) private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context, EntityPrototype? prototype)
{ {
LoadEntity(prototype, entity, context); EntityPrototype.LoadEntity(prototype, entity, ComponentFactory, this, _serManager, context);
}
internal void LoadEntity(EntityPrototype? prototype, EntityUid entity, IEntityLoadContext? context)
{
var count = prototype?.Components.Count ?? 2;
// Lort forgiv
using var types = new PooledList<ComponentType>(count);
using var comps = new PooledList<IComponent>(count);
using var compRegs = new PooledList<ComponentRegistration>(count);
Archetype arc;
var metadata = MetaQuery.GetComponent(entity);
#if DEBUG
arc = _world.GetArchetype(entity);
#endif
if (prototype != null)
{
foreach (var (name, entry) in prototype.Components)
{
if (context != null && context.ShouldSkipComponent(name))
continue;
var fullData = context != null && context.TryGetComponent(name, out var data) ? data : entry.Component;
var comp = EntityPrototype.EnsureCompExistsAndDeserialize(entity, _componentFactory, this, _serManager, name, fullData, context as ISerializationContext, metadata);
var compType = comp.CompReg.Idx.Type;
// Don't double add an existing component, just set data above.
if (!comp.Add)
{
continue;
}
types.Add(compType);
comps.Add(comp.Comp);
compRegs.Add(comp.CompReg);
}
}
if (context != null)
{
foreach (var name in context.GetExtraComponentTypes())
{
if (prototype != null && prototype.Components.ContainsKey(name))
{
// This component also exists in the prototype.
// This means that the previous step already caught both the prototype data AND map data.
// Meaning that re-running EnsureCompExistsAndDeserialize would wipe prototype data.
continue;
}
if (!context.TryGetComponent(name, out var data))
{
throw new InvalidOperationException(
$"{nameof(IEntityLoadContext)} provided component name {name} but refused to provide data");
}
var comp = EntityPrototype.EnsureCompExistsAndDeserialize(entity, _componentFactory, this, _serManager, name, data, context as ISerializationContext, metadata);
var compType = comp.CompReg.Idx.Type;
// Don't double add an existing component, just set data above.
if (!comp.Add)
{
continue;
}
types.Add(compType);
comps.Add(comp.Comp);
compRegs.Add(comp.CompReg);
}
}
// Shouldn't be changing archetype above or we're having a bad time.
DebugTools.Assert(_world.GetArchetype(entity).Equals(arc));
// Yeah it can happen.
if (types.Count == 0)
return;
_world.AddRange(entity, types);
for (var i = 0; i < comps.Count; i++)
{
AddComponentInternal(entity, comps[i], compRegs[i], true, metadata: metadata);
}
} }
public void InitializeAndStartEntity(EntityUid entity, MapId? mapId = null) public void InitializeAndStartEntity(EntityUid entity, MapId? mapId = null)
{ {
try try
{ {
// TODO: Pass this + transformcomp around
var meta = MetaQuery.GetComponent(entity); var meta = MetaQuery.GetComponent(entity);
InitializeEntity(entity, meta); InitializeEntity(entity, meta);
StartEntity(entity); StartEntity(entity);
@@ -871,6 +760,14 @@ namespace Robust.Shared.GameObjects
DebugTools.Assert("Why are you raising predictive events on the server?"); DebugTools.Assert("Why are you raising predictive events on the server?");
} }
/// <summary>
/// Factory for generating a new EntityUid for an entity currently being created.
/// </summary>
internal EntityUid GenerateEntityUid()
{
return new EntityUid(NextEntityUid++);
}
/// <summary> /// <summary>
/// Generates a unique network id and increments <see cref="NextNetworkId"/> /// Generates a unique network id and increments <see cref="NextNetworkId"/>
/// </summary> /// </summary>

View File

@@ -525,7 +525,7 @@ public partial class EntitySystem
/// Retrieves whether the entity has the specified component or not. /// Retrieves whether the entity has the specified component or not.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool HasComp<T>(EntityUid uid) where T : IComponent protected bool HasComp<T>(EntityUid uid)
{ {
return EntityManager.HasComponent<T>(uid); return EntityManager.HasComponent<T>(uid);
} }
@@ -543,7 +543,7 @@ public partial class EntitySystem
/// Retrieves whether the entity has the specified component or not. /// Retrieves whether the entity has the specified component or not.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool HasComp<T>([NotNullWhen(true)] EntityUid? uid) where T : IComponent protected bool HasComp<T>([NotNullWhen(true)] EntityUid? uid)
{ {
return EntityManager.HasComponent<T>(uid); return EntityManager.HasComponent<T>(uid);
} }
@@ -572,7 +572,7 @@ public partial class EntitySystem
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void AddComp<T>(EntityUid uid, T component, bool overwrite = false) where T : IComponent protected void AddComp<T>(EntityUid uid, T component, bool overwrite = false) where T : IComponent
{ {
EntityManager.AddComponent(uid, component); EntityManager.AddComponent(uid, component, overwrite);
} }
/// <inheritdoc cref="IEntityManager.EnsureComponent&lt;T&gt;(EntityUid)"/> /// <inheritdoc cref="IEntityManager.EnsureComponent&lt;T&gt;(EntityUid)"/>
@@ -614,6 +614,13 @@ public partial class EntitySystem
return EntityManager.RemoveComponentDeferred(uid, type); return EntityManager.RemoveComponentDeferred(uid, type);
} }
/// <inheritdoc cref="IEntityManager.RemoveComponentDeferred(EntityUid, Component)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void RemCompDeferred(EntityUid uid, Component component)
{
EntityManager.RemoveComponentDeferred(uid, component);
}
/// <inheritdoc cref="IEntityManager.RemoveComponentDeferred(EntityUid, IComponent)"/> /// <inheritdoc cref="IEntityManager.RemoveComponentDeferred(EntityUid, IComponent)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void RemCompDeferred(EntityUid uid, IComponent component) protected void RemCompDeferred(EntityUid uid, IComponent component)
@@ -656,6 +663,13 @@ public partial class EntitySystem
return EntityManager.RemoveComponent(uid, type); return EntityManager.RemoveComponent(uid, type);
} }
/// <inheritdoc cref="IEntityManager.RemoveComponent(EntityUid, Component)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void RemComp(EntityUid uid, Component component)
{
EntityManager.RemoveComponent(uid, component);
}
/// <inheritdoc cref="IEntityManager.RemoveComponent(EntityUid, IComponent)"/> /// <inheritdoc cref="IEntityManager.RemoveComponent(EntityUid, IComponent)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void RemComp(EntityUid uid, IComponent component) protected void RemComp(EntityUid uid, IComponent component)

View File

@@ -7,12 +7,10 @@ namespace Robust.Shared.GameObjects
public readonly struct EntityTerminatingEvent public readonly struct EntityTerminatingEvent
{ {
public readonly EntityUid Entity; public readonly EntityUid Entity;
public readonly MetaDataComponent Metadata;
public EntityTerminatingEvent(EntityUid entity, MetaDataComponent metadata) public EntityTerminatingEvent(EntityUid entity)
{ {
Entity = entity; Entity = entity;
Metadata = metadata;
} }
} }
} }

View File

@@ -1,7 +1,4 @@
using System; using System;
using System.Runtime.CompilerServices;
using Arch.Core;
using Arch.Core.Extensions.Dangerous;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -12,7 +9,7 @@ using Robust.Shared.ViewVariables;
namespace Robust.Shared.GameObjects namespace Robust.Shared.GameObjects
{ {
/// <summary> /// <summary>
/// This type contains a local identification number of an entity. /// This type contains a network identification number of an entity.
/// This can be used by the EntityManager to access an entity /// This can be used by the EntityManager to access an entity
/// </summary> /// </summary>
[CopyByRef] [CopyByRef]
@@ -20,40 +17,22 @@ namespace Robust.Shared.GameObjects
{ {
public readonly int Id; public readonly int Id;
public readonly int Version;
/// <summary> /// <summary>
/// An Invalid entity UID you can compare against. /// An Invalid entity UID you can compare against.
/// </summary> /// </summary>
public static readonly EntityUid Invalid = new(-1 + ArchUidOffset, -1 + ArchVersionOffset); public static readonly EntityUid Invalid = new(0);
/// <summary> /// <summary>
/// The first entity UID the entityManager should use when the manager is initialized. /// The first entity UID the entityManager should use when the manager is initialized.
/// </summary> /// </summary>
public static readonly EntityUid FirstUid = new(0 + ArchUidOffset, 1 + ArchVersionOffset); public static readonly EntityUid FirstUid = new(1);
internal const int ArchUidOffset = 1;
internal const int ArchVersionOffset = 1;
public EntityUid()
{
Id = Invalid.Id;
Version = Invalid.Version;
}
internal EntityUid(EntityReference reference)
{
Id = reference.Entity.Id + ArchUidOffset;
Version = reference.Version + ArchVersionOffset;
}
/// <summary> /// <summary>
/// Creates an instance of this structure, with the given network ID. /// Creates an instance of this structure, with the given network ID.
/// </summary> /// </summary>
public EntityUid(int id, int version) public EntityUid(int id)
{ {
Id = id; Id = id;
Version = version;
} }
public bool Valid => IsValid(); public bool Valid => IsValid();
@@ -61,16 +40,16 @@ namespace Robust.Shared.GameObjects
/// <summary> /// <summary>
/// Creates an entity UID by parsing a string number. /// Creates an entity UID by parsing a string number.
/// </summary> /// </summary>
public static EntityUid Parse(ReadOnlySpan<char> uid, ReadOnlySpan<char> version) public static EntityUid Parse(ReadOnlySpan<char> uid)
{ {
return new EntityUid(int.Parse(uid), int.Parse(version)); return new EntityUid(int.Parse(uid));
} }
public static bool TryParse(ReadOnlySpan<char> uid, ReadOnlySpan<char> version, out EntityUid entityUid) public static bool TryParse(ReadOnlySpan<char> uid, out EntityUid entityUid)
{ {
try try
{ {
entityUid = Parse(uid, version); entityUid = Parse(uid);
return true; return true;
} }
catch (FormatException) catch (FormatException)
@@ -80,15 +59,6 @@ namespace Robust.Shared.GameObjects
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EntityUid FromArch(in World world, in Entity entity)
{
return new EntityUid(entity.Id + ArchUidOffset, world.Reference(entity).Version + ArchVersionOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetArchId() => Id - ArchUidOffset;
/// <summary> /// <summary>
/// Checks if the ID value is valid. Does not check if it identifies /// Checks if the ID value is valid. Does not check if it identifies
/// a valid Entity. /// a valid Entity.
@@ -96,13 +66,13 @@ namespace Robust.Shared.GameObjects
[Pure] [Pure]
public bool IsValid() public bool IsValid()
{ {
return Id > Invalid.Id; return Id > 0;
} }
/// <inheritdoc /> /// <inheritdoc />
public bool Equals(EntityUid other) public bool Equals(EntityUid other)
{ {
return Id == other.Id && Version == other.Version; return Id == other.Id;
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -117,7 +87,9 @@ namespace Robust.Shared.GameObjects
{ {
unchecked unchecked
{ {
return Id.GetHashCode() * 397 ^ Version.GetHashCode(); // * 397 for whenever we get versioning back
// and avoid hashcode bugs in the interim.
return Id.GetHashCode() * 397;
} }
} }
@@ -126,7 +98,7 @@ namespace Robust.Shared.GameObjects
/// </summary> /// </summary>
public static bool operator ==(EntityUid a, EntityUid b) public static bool operator ==(EntityUid a, EntityUid b)
{ {
return a.Id == b.Id && a.Version == b.Version; return a.Id == b.Id;
} }
/// <summary> /// <summary>
@@ -146,21 +118,6 @@ namespace Robust.Shared.GameObjects
return self.Id; return self.Id;
} }
public static implicit operator Entity(EntityUid self)
{
return DangerousEntityExtensions.CreateEntityStruct(self.Id - ArchUidOffset, 0);
}
public static implicit operator EntityReference(EntityUid other)
{
return DangerousEntityExtensions.CreateEntityReferenceStruct(other.Id - ArchUidOffset, other.Version - ArchVersionOffset, 0);
}
public static implicit operator EntityUid(EntityReference other)
{
return new EntityUid(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() public override string ToString()
{ {

View File

@@ -71,7 +71,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity being modified.</param> /// <param name="uid">Entity being modified.</param>
/// <param name="component">Component to add.</param> /// <param name="component">Component to add.</param>
/// <param name="overwrite">Should it overwrite existing components?</param> /// <param name="overwrite">Should it overwrite existing components?</param>
void AddComponent<T>(EntityUid uid, T component, MetaDataComponent? metadata = null) where T : IComponent; void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : IComponent;
/// <summary> /// <summary>
/// Removes the component with the specified reference type, /// Removes the component with the specified reference type,
@@ -136,6 +136,14 @@ namespace Robust.Shared.GameObjects
/// <param name="component">Component to remove.</param> /// <param name="component">Component to remove.</param>
void RemoveComponentDeferred(EntityUid uid, IComponent component); void RemoveComponentDeferred(EntityUid uid, IComponent component);
/// <summary>
/// Immediately shuts down a component, but defers the removal and deletion until the end of the tick.
/// Throws if the given component does not belong to the entity.
/// </summary>
/// <param name="uid">Entity UID to modify.</param>
/// <param name="component">Component to remove.</param>
void RemoveComponentDeferred(EntityUid uid, Component component);
/// <summary> /// <summary>
/// Removes all components from an entity, except the required components. /// Removes all components from an entity, except the required components.
/// </summary> /// </summary>
@@ -156,7 +164,7 @@ namespace Robust.Shared.GameObjects
/// <typeparam name="T">Component reference type to check for.</typeparam> /// <typeparam name="T">Component reference type to check for.</typeparam>
/// <param name="uid">Entity UID to check.</param> /// <param name="uid">Entity UID to check.</param>
/// <returns>True if the entity has the component type, otherwise false.</returns> /// <returns>True if the entity has the component type, otherwise false.</returns>
bool HasComponent<T>(EntityUid uid) where T : IComponent; bool HasComponent<T>(EntityUid uid);
/// <summary> /// <summary>
/// Checks if the entity has a component type. /// Checks if the entity has a component type.
@@ -164,7 +172,7 @@ namespace Robust.Shared.GameObjects
/// <typeparam name="T">Component reference type to check for.</typeparam> /// <typeparam name="T">Component reference type to check for.</typeparam>
/// <param name="uid">Entity UID to check.</param> /// <param name="uid">Entity UID to check.</param>
/// <returns>True if the entity has the component type, otherwise false.</returns> /// <returns>True if the entity has the component type, otherwise false.</returns>
bool HasComponent<T>(EntityUid? uid) where T : IComponent; bool HasComponent<T>(EntityUid? uid);
/// <summary> /// <summary>
/// Checks if the entity has a component type. /// Checks if the entity has a component type.
@@ -273,7 +281,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity UID to check.</param> /// <param name="uid">Entity UID to check.</param>
/// <param name="component">Component of the specified type (if exists).</param> /// <param name="component">Component of the specified type (if exists).</param>
/// <returns>If the component existed in the entity.</returns> /// <returns>If the component existed in the entity.</returns>
bool TryGetComponent<T>(EntityUid uid, [NotNullWhen(true)] out T? component) where T : IComponent?; bool TryGetComponent<T>(EntityUid uid, [NotNullWhen(true)] out T? component);
/// <summary> /// <summary>
/// Returns the component of a specific type. /// Returns the component of a specific type.
@@ -282,7 +290,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity UID to check.</param> /// <param name="uid">Entity UID to check.</param>
/// <param name="component">Component of the specified type (if exists).</param> /// <param name="component">Component of the specified type (if exists).</param>
/// <returns>If the component existed in the entity.</returns> /// <returns>If the component existed in the entity.</returns>
bool TryGetComponent<T>([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? component) where T : IComponent?; bool TryGetComponent<T>([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? component);
/// <summary> /// <summary>
/// Returns the component of a specific type. /// Returns the component of a specific type.
@@ -497,7 +505,5 @@ namespace Robust.Shared.GameObjects
/// Culls all components from the collection that are marked as deleted. This needs to be called often. /// Culls all components from the collection that are marked as deleted. This needs to be called often.
/// </summary> /// </summary>
void CullRemovedComponents(); void CullRemovedComponents();
void CleanupArch();
} }
} }

View File

@@ -19,7 +19,6 @@ public partial interface IEntityManager
EntityUid SpawnEntity(string? protoName, MapCoordinates coordinates, ComponentRegistry? overrides = null); EntityUid SpawnEntity(string? protoName, MapCoordinates coordinates, ComponentRegistry? overrides = null);
EntityUid[] SpawnEntities(MapCoordinates coordinates, params string?[] protoNames); EntityUid[] SpawnEntities(MapCoordinates coordinates, params string?[] protoNames);
EntityUid[] SpawnEntities(MapCoordinates coordinates, string? prototype, int count);
EntityUid[] SpawnEntities(MapCoordinates coordinates, List<string?> protoNames); EntityUid[] SpawnEntities(MapCoordinates coordinates, List<string?> protoNames);
EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, List<string?> protoNames); EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, List<string?> protoNames);
EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, params string?[] protoNames); EntityUid[] SpawnEntitiesAttachedTo(EntityCoordinates coordinates, params string?[] protoNames);
@@ -53,7 +52,7 @@ public partial interface IEntityManager
EntityUid containerUid, EntityUid containerUid,
string containerId, string containerId,
[NotNullWhen(true)] out EntityUid? uid, [NotNullWhen(true)] out EntityUid? uid,
ContainerManagerComponent? containerComp = null, ContainerManagerComponent? containerComp = null,
ComponentRegistry? overrides = null); ComponentRegistry? overrides = null);
/// <summary> /// <summary>
@@ -65,7 +64,7 @@ public partial interface IEntityManager
EntityUid containerUid, EntityUid containerUid,
string containerId, string containerId,
TransformComponent? xform = null, TransformComponent? xform = null,
ContainerManagerComponent? containerComp = null, ContainerManagerComponent? containerComp = null,
ComponentRegistry? overrides = null); ComponentRegistry? overrides = null);
/// <summary> /// <summary>
@@ -85,8 +84,8 @@ public partial interface IEntityManager
/// instead attempt to spawn the entity next to the target's parent. /// instead attempt to spawn the entity next to the target's parent.
/// </summary> /// </summary>
EntityUid SpawnNextToOrDrop( EntityUid SpawnNextToOrDrop(
string? protoName, string? protoName,
EntityUid target, EntityUid target,
TransformComponent? xform = null, TransformComponent? xform = null,
ComponentRegistry? overrides = null); ComponentRegistry? overrides = null);
} }

View File

@@ -113,6 +113,7 @@ public sealed partial class EntityLookupSystem : EntitySystem
SubscribeLocalEvent<BroadphaseComponent, EntityTerminatingEvent>(OnBroadphaseTerminating); SubscribeLocalEvent<BroadphaseComponent, EntityTerminatingEvent>(OnBroadphaseTerminating);
SubscribeLocalEvent<BroadphaseComponent, ComponentAdd>(OnBroadphaseAdd); SubscribeLocalEvent<BroadphaseComponent, ComponentAdd>(OnBroadphaseAdd);
SubscribeLocalEvent<GridAddEvent>(OnGridAdd);
SubscribeLocalEvent<MapChangedEvent>(OnMapChange); SubscribeLocalEvent<MapChangedEvent>(OnMapChange);
SubscribeLocalEvent<MoveEvent>(OnMove); SubscribeLocalEvent<MoveEvent>(OnMove);
@@ -191,6 +192,12 @@ public sealed partial class EntityLookupSystem : EntitySystem
} }
} }
private void OnGridAdd(GridAddEvent ev)
{
// Must be done before initialization as that's when broadphase data starts getting set.
EnsureComp<BroadphaseComponent>(ev.EntityUid);
}
private void OnBroadphaseAdd(EntityUid uid, BroadphaseComponent component, ComponentAdd args) private void OnBroadphaseAdd(EntityUid uid, BroadphaseComponent component, ComponentAdd args)
{ {
component.StaticSundriesTree = new DynamicTree<EntityUid>( component.StaticSundriesTree = new DynamicTree<EntityUid>(
@@ -432,7 +439,7 @@ public sealed partial class EntityLookupSystem : EntitySystem
{ {
DebugTools.Assert(!_container.IsEntityOrParentInContainer(uid)); DebugTools.Assert(!_container.IsEntityOrParentInContainer(uid));
DebugTools.Assert(xform.Broadphase == null || xform.Broadphase == new BroadphaseData(broadUid, default, false, staticBody)); DebugTools.Assert(xform.Broadphase == null || xform.Broadphase == new BroadphaseData(broadUid, default, false, staticBody));
xform.Broadphase ??= new BroadphaseData(broadUid, EntityUid.Invalid, false, staticBody); xform.Broadphase ??= new(broadUid, default, false, staticBody);
(staticBody ? broadphase.StaticSundriesTree : broadphase.SundriesTree).AddOrUpdate(uid, aabb); (staticBody ? broadphase.StaticSundriesTree : broadphase.SundriesTree).AddOrUpdate(uid, aabb);
} }

View File

@@ -429,7 +429,8 @@ public abstract partial class SharedMapSystem
private void OnGridInit(EntityUid uid, MapGridComponent component, ComponentInit args) private void OnGridInit(EntityUid uid, MapGridComponent component, ComponentInit args)
{ {
var xform = _xformQuery.GetComponent(uid); var xformQuery = GetEntityQuery<TransformComponent>();
var xform = xformQuery.GetComponent(uid);
// Force networkedmapmanager to send it due to non-ECS legacy code. // Force networkedmapmanager to send it due to non-ECS legacy code.
var curTick = _timing.CurTick; var curTick = _timing.CurTick;
@@ -442,7 +443,7 @@ public abstract partial class SharedMapSystem
component.LastTileModifiedTick = curTick; component.LastTileModifiedTick = curTick;
if (xform.MapUid != null && xform.MapUid != uid) if (xform.MapUid != null && xform.MapUid != uid)
_transform.SetParent(uid, xform, xform.MapUid.Value); _transform.SetParent(uid, xform, xform.MapUid.Value, xformQuery);
if (!HasComp<MapComponent>(uid)) if (!HasComp<MapComponent>(uid))
{ {

View File

@@ -10,6 +10,7 @@ public abstract partial class SharedMapSystem
{ {
private void InitializeMap() private void InitializeMap()
{ {
SubscribeLocalEvent<MapComponent, ComponentAdd>(OnMapAdd);
SubscribeLocalEvent<MapComponent, ComponentInit>(OnMapInit); SubscribeLocalEvent<MapComponent, ComponentInit>(OnMapInit);
SubscribeLocalEvent<MapComponent, ComponentShutdown>(OnMapRemoved); SubscribeLocalEvent<MapComponent, ComponentShutdown>(OnMapRemoved);
SubscribeLocalEvent<MapComponent, ComponentHandleState>(OnMapHandleState); SubscribeLocalEvent<MapComponent, ComponentHandleState>(OnMapHandleState);
@@ -42,6 +43,8 @@ public abstract partial class SharedMapSystem
args.State = new MapComponentState(component.MapId, component.LightingEnabled, component.MapPaused); args.State = new MapComponentState(component.MapId, component.LightingEnabled, component.MapPaused);
} }
protected abstract void OnMapAdd(EntityUid uid, MapComponent component, ComponentAdd args);
private void OnMapInit(EntityUid uid, MapComponent component, ComponentInit args) private void OnMapInit(EntityUid uid, MapComponent component, ComponentInit args)
{ {
EnsureComp<GridTreeComponent>(uid); EnsureComp<GridTreeComponent>(uid);

View File

@@ -25,7 +25,7 @@ namespace Robust.Shared.Localization
private bool TryGetEntityLocAttrib(EntityUid entity, string attribute, [NotNullWhen(true)] out string? value) private bool TryGetEntityLocAttrib(EntityUid entity, string attribute, [NotNullWhen(true)] out string? value)
{ {
if (_entMan.TryGetComponent(entity, out GrammarComponent? grammar) && if (_entMan.TryGetComponent<GrammarComponent?>(entity, out var grammar) &&
grammar.Attributes.TryGetValue(attribute, out value)) grammar.Attributes.TryGetValue(attribute, out value))
{ {
return true; return true;

View File

@@ -174,7 +174,7 @@ namespace Robust.Shared.Localization
{ {
EntityUid entity = (EntityUid)entity0.Value; EntityUid entity = (EntityUid)entity0.Value;
if (_entMan.TryGetComponent(entity, out GrammarComponent? grammar) && grammar.Gender.HasValue) if (_entMan.TryGetComponent<GrammarComponent?>(entity, out var grammar) && grammar.Gender.HasValue)
{ {
return new LocValueString(grammar.Gender.Value.ToString().ToLowerInvariant()); return new LocValueString(grammar.Gender.Value.ToString().ToLowerInvariant());
} }
@@ -307,7 +307,7 @@ namespace Robust.Shared.Localization
{ {
EntityUid entity = (EntityUid)entity0.Value; EntityUid entity = (EntityUid)entity0.Value;
if (_entMan.TryGetComponent(entity, out GrammarComponent? grammar) && grammar.ProperNoun.HasValue) if (_entMan.TryGetComponent<GrammarComponent?>(entity, out var grammar) && grammar.ProperNoun.HasValue)
{ {
return new LocValueString(grammar.ProperNoun.Value.ToString().ToLowerInvariant()); return new LocValueString(grammar.ProperNoun.Value.ToString().ToLowerInvariant());
} }

View File

@@ -37,12 +37,6 @@ namespace Robust.Shared.Map
/// </summary> /// </summary>
public float Y => Position.Y; public float Y => Position.Y;
public EntityCoordinates()
{
EntityId = EntityUid.Invalid;
Position = Vector2.Zero;
}
/// <summary> /// <summary>
/// Constructs a new instance of <see cref="EntityCoordinates"/>. /// Constructs a new instance of <see cref="EntityCoordinates"/>.
/// </summary> /// </summary>

View File

@@ -4,8 +4,6 @@ using System.Diagnostics.CodeAnalysis;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Utility; using Robust.Shared.Utility;
// All the obsolete warnings about GridId are probably useless here. // All the obsolete warnings about GridId are probably useless here.
@@ -161,9 +159,6 @@ internal partial class MapManager
var grid = EntityManager.AddComponent<MapGridComponent>(gridEnt); var grid = EntityManager.AddComponent<MapGridComponent>(gridEnt);
grid.ChunkSize = chunkSize; grid.ChunkSize = chunkSize;
EntityManager.AddComponent<PhysicsComponent>(gridEnt);
EntityManager.AddComponent<FixturesComponent>(gridEnt);
EntityManager.AddComponent<BroadphaseComponent>(gridEnt);
_sawmill.Debug($"Binding new grid {gridEnt}"); _sawmill.Debug($"Binding new grid {gridEnt}");

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Robust.Shared.Map; namespace Robust.Shared.Map;
@@ -234,7 +233,6 @@ internal partial class MapManager
var mapComp = EntityManager.AddComponent<MapComponent>(newEnt); var mapComp = EntityManager.AddComponent<MapComponent>(newEnt);
mapComp.MapId = actualId; mapComp.MapId = actualId;
EntityManager.AddComponent<PhysicsMapComponent>(newEnt);
var meta = EntityManager.GetComponent<MetaDataComponent>(newEnt); var meta = EntityManager.GetComponent<MetaDataComponent>(newEnt);
EntityManager.System<MetaDataSystem>().SetEntityName(newEnt, $"map {actualId}", meta); EntityManager.System<MetaDataSystem>().SetEntityName(newEnt, $"map {actualId}", meta);
EntityManager.Dirty(newEnt, mapComp, meta); EntityManager.Dirty(newEnt, mapComp, meta);

View File

@@ -165,6 +165,6 @@ internal sealed class MapSerializationContext : ISerializationContext, IEntityLo
bool skipHook, bool skipHook,
ISerializationContext? context = null) ISerializationContext? context = null)
{ {
return new EntityUid(source.Id, source.Version); return new((int)source);
} }
} }

View File

@@ -1,33 +1,32 @@
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Physics.BroadPhase; using Robust.Shared.Physics.BroadPhase;
namespace Robust.Shared.Physics; namespace Robust.Shared.Physics
/// <summary>
/// Stores the broadphase structure for the relevant grid / map.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class BroadphaseComponent : Component
{ {
/// <summary> /// <summary>
/// Stores all non-static bodies. /// Stores the broadphase structure for the relevant grid / map.
/// </summary> /// </summary>
public IBroadPhase DynamicTree = new DynamicTreeBroadPhase(); [RegisterComponent]
public sealed partial class BroadphaseComponent : Component
{
/// <summary>
/// Stores all non-static bodies.
/// </summary>
public IBroadPhase DynamicTree = new DynamicTreeBroadPhase();
/// <summary> /// <summary>
/// Stores all static bodies. /// Stores all static bodies.
/// </summary> /// </summary>
public IBroadPhase StaticTree = new DynamicTreeBroadPhase(); public IBroadPhase StaticTree = new DynamicTreeBroadPhase();
/// <summary> /// <summary>
/// Stores all other non-static entities not in another tree. /// Stores all other non-static entities not in another tree.
/// </summary> /// </summary>
public DynamicTree<EntityUid> SundriesTree = default!; public DynamicTree<EntityUid> SundriesTree = default!;
/// <summary> /// <summary>
/// Stores all other static entities not in another tree. /// Stores all other static entities not in another tree.
/// </summary> /// </summary>
public DynamicTree<EntityUid> StaticSundriesTree = default!; public DynamicTree<EntityUid> StaticSundriesTree = default!;
}
} }

View File

@@ -322,7 +322,7 @@ public partial class SharedPhysicsSystem
body.AngularVelocity = value; body.AngularVelocity = value;
if (dirty) if (dirty)
Dirty(uid, body); Dirty(body);
} }
/// <summary> /// <summary>
@@ -347,7 +347,7 @@ public partial class SharedPhysicsSystem
body.LinearVelocity = velocity; body.LinearVelocity = velocity;
if (dirty) if (dirty)
Dirty(uid, body); Dirty(body);
} }
public void SetAngularDamping(PhysicsComponent body, float value, bool dirty = true) public void SetAngularDamping(PhysicsComponent body, float value, bool dirty = true)

View File

@@ -62,7 +62,6 @@ namespace Robust.Shared.Physics.Systems
public bool MetricsEnabled { get; protected set; } public bool MetricsEnabled { get; protected set; }
private EntityQuery<CollideOnAnchorComponent> _collideAnchorQuery;
private EntityQuery<FixturesComponent> _fixturesQuery; private EntityQuery<FixturesComponent> _fixturesQuery;
protected EntityQuery<PhysicsComponent> PhysicsQuery; protected EntityQuery<PhysicsComponent> PhysicsQuery;
private EntityQuery<TransformComponent> _xformQuery; private EntityQuery<TransformComponent> _xformQuery;
@@ -71,12 +70,11 @@ namespace Robust.Shared.Physics.Systems
{ {
base.Initialize(); base.Initialize();
_collideAnchorQuery = GetEntityQuery<CollideOnAnchorComponent>();
_fixturesQuery = GetEntityQuery<FixturesComponent>(); _fixturesQuery = GetEntityQuery<FixturesComponent>();
PhysicsQuery = GetEntityQuery<PhysicsComponent>(); PhysicsQuery = GetEntityQuery<PhysicsComponent>();
_xformQuery = GetEntityQuery<TransformComponent>(); _xformQuery = GetEntityQuery<TransformComponent>();
SubscribeLocalEvent<GridInitializeEvent>(OnGridAdd); SubscribeLocalEvent<GridAddEvent>(OnGridAdd);
SubscribeLocalEvent<PhysicsWakeEvent>(OnWake); SubscribeLocalEvent<PhysicsWakeEvent>(OnWake);
SubscribeLocalEvent<PhysicsSleepEvent>(OnSleep); SubscribeLocalEvent<PhysicsSleepEvent>(OnSleep);
SubscribeLocalEvent<CollisionChangeEvent>(OnCollisionChange); SubscribeLocalEvent<CollisionChangeEvent>(OnCollisionChange);
@@ -180,12 +178,14 @@ namespace Robust.Shared.Physics.Systems
/// </summary> /// </summary>
private void HandleMapChange(EntityUid uid, TransformComponent xform, PhysicsComponent? body, MapId oldMapId, MapId newMapId) private void HandleMapChange(EntityUid uid, TransformComponent xform, PhysicsComponent? body, MapId oldMapId, MapId newMapId)
{ {
var bodyQuery = GetEntityQuery<PhysicsComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
var jointQuery = GetEntityQuery<JointComponent>(); var jointQuery = GetEntityQuery<JointComponent>();
TryComp(_mapManager.GetMapEntityId(oldMapId), out PhysicsMapComponent? oldMap); TryComp(_mapManager.GetMapEntityId(oldMapId), out PhysicsMapComponent? oldMap);
TryComp(_mapManager.GetMapEntityId(newMapId), out PhysicsMapComponent? newMap); TryComp(_mapManager.GetMapEntityId(newMapId), out PhysicsMapComponent? newMap);
RecursiveMapUpdate(uid, xform, body, newMap, oldMap, jointQuery); RecursiveMapUpdate(uid, xform, body, newMap, oldMap, bodyQuery, xformQuery, jointQuery);
} }
/// <summary> /// <summary>
@@ -197,6 +197,8 @@ namespace Robust.Shared.Physics.Systems
PhysicsComponent? body, PhysicsComponent? body,
PhysicsMapComponent? newMap, PhysicsMapComponent? newMap,
PhysicsMapComponent? oldMap, PhysicsMapComponent? oldMap,
EntityQuery<PhysicsComponent> bodyQuery,
EntityQuery<TransformComponent> xformQuery,
EntityQuery<JointComponent> jointQuery) EntityQuery<JointComponent> jointQuery)
{ {
DebugTools.Assert(!Deleted(uid)); DebugTools.Assert(!Deleted(uid));
@@ -220,15 +222,15 @@ namespace Robust.Shared.Physics.Systems
var childEnumerator = xform.ChildEnumerator; var childEnumerator = xform.ChildEnumerator;
while (childEnumerator.MoveNext(out var child)) while (childEnumerator.MoveNext(out var child))
{ {
if (_xformQuery.TryGetComponent(child, out var childXform)) if (xformQuery.TryGetComponent(child, out var childXform))
{ {
PhysicsQuery.TryGetComponent(child, out var childBody); bodyQuery.TryGetComponent(child, out var childBody);
RecursiveMapUpdate(child.Value, childXform, childBody, newMap, oldMap, jointQuery); RecursiveMapUpdate(child.Value, childXform, childBody, newMap, oldMap, bodyQuery, xformQuery, jointQuery);
} }
} }
} }
private void OnGridAdd(GridInitializeEvent ev) private void OnGridAdd(GridAddEvent ev)
{ {
var guid = ev.EntityUid; var guid = ev.EntityUid;
@@ -254,7 +256,7 @@ namespace Robust.Shared.Physics.Systems
private void OnWake(ref PhysicsWakeEvent @event) private void OnWake(ref PhysicsWakeEvent @event)
{ {
var mapId = _xformQuery.GetComponent(@event.Entity).MapID; var mapId = EntityManager.GetComponent<TransformComponent>(@event.Entity).MapID;
if (mapId == MapId.Nullspace) if (mapId == MapId.Nullspace)
return; return;
@@ -265,7 +267,7 @@ namespace Robust.Shared.Physics.Systems
private void OnSleep(ref PhysicsSleepEvent @event) private void OnSleep(ref PhysicsSleepEvent @event)
{ {
var mapId = _xformQuery.GetComponent(@event.Entity).MapID; var mapId = EntityManager.GetComponent<TransformComponent>(@event.Entity).MapID;
if (mapId == MapId.Nullspace) if (mapId == MapId.Nullspace)
return; return;
@@ -280,7 +282,7 @@ namespace Robust.Shared.Physics.Systems
if (MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating) return; if (MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating) return;
// If this entity is only meant to collide when anchored, return early. // If this entity is only meant to collide when anchored, return early.
if (_collideAnchorQuery.TryGetComponent(uid, out var collideComp) && collideComp.Enable) if (TryComp(uid, out CollideOnAnchorComponent? collideComp) && collideComp.Enable)
return; return;
WakeBody(uid, body: physics); WakeBody(uid, body: physics);

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Arch.Core.Utils;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
@@ -14,7 +12,6 @@ using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
using Component = Robust.Shared.GameObjects.Component;
namespace Robust.Shared.Prototypes namespace Robust.Shared.Prototypes
{ {
@@ -196,37 +193,76 @@ namespace Robust.Shared.Prototypes
return true; return true;
} }
internal static (ComponentRegistration CompReg, IComponent Comp, bool Add) EnsureCompExistsAndDeserialize(EntityUid entity, internal static void LoadEntity(
EntityPrototype? prototype,
EntityUid entity,
IComponentFactory factory,
IEntityManager entityManager,
ISerializationManager serManager,
IEntityLoadContext? context) //yeah officer this method right here
{
if (prototype != null)
{
foreach (var (name, entry) in prototype.Components)
{
if (context != null && context.ShouldSkipComponent(name))
continue;
var fullData = context != null && context.TryGetComponent(name, out var data) ? data : entry.Component;
EnsureCompExistsAndDeserialize(entity, factory, entityManager, serManager, name, fullData, context as ISerializationContext);
}
}
if (context != null)
{
foreach (var name in context.GetExtraComponentTypes())
{
if (prototype != null && prototype.Components.ContainsKey(name))
{
// This component also exists in the prototype.
// This means that the previous step already caught both the prototype data AND map data.
// Meaning that re-running EnsureCompExistsAndDeserialize would wipe prototype data.
continue;
}
if (!context.TryGetComponent(name, out var data))
{
throw new InvalidOperationException(
$"{nameof(IEntityLoadContext)} provided component name {name} but refused to provide data");
}
EnsureCompExistsAndDeserialize(entity, factory, entityManager, serManager, name, data, context as ISerializationContext);
}
}
}
public static void EnsureCompExistsAndDeserialize(EntityUid entity,
IComponentFactory factory, IComponentFactory factory,
IEntityManager entityManager, IEntityManager entityManager,
ISerializationManager serManager, ISerializationManager serManager,
string compName, string compName,
IComponent data, IComponent data,
ISerializationContext? context, ISerializationContext? context)
MetaDataComponent metadata)
{ {
// TODO optimize
var compReg = factory.GetRegistration(compName); var compReg = factory.GetRegistration(compName);
var add = false;
if (!entityManager.TryGetComponent(entity, compReg.Idx, out var component)) if (!entityManager.TryGetComponent(entity, compReg.Idx, out var component))
{ {
var newComponent = factory.GetComponent(compName); var newComponent = factory.GetComponent(compName);
newComponent.Owner = entity; entityManager.AddComponent(entity, newComponent);
component = newComponent; component = newComponent;
add = true;
} }
if (context is not MapSerializationContext map) if (context is not MapSerializationContext map)
{ {
serManager.CopyTo(data, ref component, context, notNullableOverride: true); serManager.CopyTo(data, ref component, context, notNullableOverride: true);
return (compReg, component, add); return;
} }
map.CurrentComponent = compName; map.CurrentComponent = compName;
serManager.CopyTo(data, ref component, context, notNullableOverride: true); serManager.CopyTo(data, ref component, context, notNullableOverride: true);
map.CurrentComponent = null; map.CurrentComponent = null;
return (compReg, component, add);
} }
public override string ToString() public override string ToString()

View File

@@ -6,9 +6,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Collections.Pooled" Version="2.0.0-preview.27" PrivateAssets="compile" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="6.0.2" />
<PackageReference Include="Microsoft.ILVerification" Version="6.0.0" PrivateAssets="compile" /> <PackageReference Include="Microsoft.ILVerification" Version="6.0.0" PrivateAssets="compile" />
<PackageReference Include="Nett" Version="0.15.0" PrivateAssets="compile" /> <PackageReference Include="Nett" Version="0.15.0" PrivateAssets="compile" />
<PackageReference Include="Pidgin" Version="2.5.0" /> <PackageReference Include="Pidgin" Version="2.5.0" />
@@ -28,7 +27,6 @@
<ProjectReference Include="..\NetSerializer\NetSerializer\NetSerializer.csproj" /> <ProjectReference Include="..\NetSerializer\NetSerializer\NetSerializer.csproj" />
<ProjectReference Include="..\Robust.Physics\Robust.Physics.csproj" /> <ProjectReference Include="..\Robust.Physics\Robust.Physics.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" /> <ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
<ProjectReference Include="..\Arch\Arch.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Utility\TypeAbbreviations.yaml"> <EmbeddedResource Include="Utility\TypeAbbreviations.yaml">

View File

@@ -12,6 +12,7 @@ using Robust.Shared.Serialization.Markdown.Sequence;
using Robust.Shared.Serialization.Markdown.Validation; using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.Markdown.Value; using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Serialization.TypeSerializers.Interfaces; using Robust.Shared.Serialization.TypeSerializers.Interfaces;
using Robust.Shared.Utility;
using static Robust.Shared.Prototypes.EntityPrototype; using static Robust.Shared.Prototypes.EntityPrototype;
namespace Robust.Shared.Serialization.TypeSerializers.Implementations namespace Robust.Shared.Serialization.TypeSerializers.Implementations
@@ -63,8 +64,8 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
var copy = componentMapping.Copy()!; var copy = componentMapping.Copy()!;
copy.Remove("type"); copy.Remove("type");
var reg = factory.GetRegistration(compType); var type = factory.GetRegistration(compType).Type;
var read = (IComponent)serializationManager.Read(reg.Type, copy, hookCtx, context)!; var read = (IComponent)serializationManager.Read(type, copy, hookCtx, context)!;
components[compType] = new ComponentRegistryEntry(read, copy); components[compType] = new ComponentRegistryEntry(read, copy);
} }

View File

@@ -17,10 +17,9 @@ internal sealed class EntityTypeParser : TypeParser<EntityUid>
{ {
var start = parser.Index; var start = parser.Index;
var word = parser.GetWord(ParserContext.IsToken); var word = parser.GetWord(ParserContext.IsToken);
var wordTwo = parser.GetWord(ParserContext.IsToken);
error = null; error = null;
if (!EntityUid.TryParse(word, wordTwo, out var ent)) if (!EntityUid.TryParse(word, out var ent))
{ {
result = null; result = null;

View File

@@ -86,13 +86,13 @@ internal abstract partial class ViewVariablesManager
var segments = path.Split('/'); var segments = path.Split('/');
if (segments.Length < 2) if (segments.Length == 0)
return EmptyResolve; return EmptyResolve;
if (!int.TryParse(segments[0], out var num) || num <= 0 || !int.TryParse(segments[1], out var numTwo) || numTwo < 0) if (!int.TryParse(segments[0], out var num) || num <= 0)
return EmptyResolve; return EmptyResolve;
var uid = new EntityUid(num, numTwo); var uid = new EntityUid(num);
return (new ViewVariablesInstancePath(uid), segments[1..]); return (new ViewVariablesInstancePath(uid), segments[1..]);
} }

View File

@@ -915,13 +915,11 @@ namespace Robust.UnitTesting
// use server side uids on the client and vice versa. This can sometimes accidentally work if the // use server side uids on the client and vice versa. This can sometimes accidentally work if the
// entities get created in the same order. For that reason we arbitrarily increment the queued Uid by // entities get created in the same order. For that reason we arbitrarily increment the queued Uid by
// some arbitrary quantity. // some arbitrary quantity.
var e = (EntityManager) EntMan;
/* TODO: End my suffering and fix this because entmanager hasn't started up yet.
for (var i = 0; i < 10; i++) for (var i = 0; i < 10; i++)
{ {
EntMan.SpawnEntity(null, MapCoordinates.Nullspace); e.GenerateEntityUid();
} }
*/
return client; return client;
} }

View File

@@ -1,59 +0,0 @@
using Arch.Core.Extensions.Dangerous;
using NUnit.Framework;
using Robust.Shared.Console.Commands;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Robust.UnitTesting.Server.GameObjects;
/// <summary>
/// Tests engine integrations with Arch.
/// </summary>
[TestFixture]
public sealed class ArchTests
{
/// <summary>
/// Asserts that EntityUids match the expected Arch EntityReference.
/// </summary>
[Test]
public void EntityTest()
{
var sim = RobustServerSimulation.NewSimulation().InitializeInstance();
var entManager = sim.Resolve<IEntityManager>();
var entity = entManager.Spawn(null, MapCoordinates.Nullspace);
var entReference = DangerousEntityExtensions.CreateEntityReferenceStruct(0, 1, 0);
Assert.That(entity.Id, Is.EqualTo(entReference.Entity.Id + EntityUid.ArchUidOffset));
Assert.That(entity.Version, Is.EqualTo(entReference.Version + EntityUid.ArchVersionOffset));
entManager.DeleteEntity(entity);
}
/// <summary>
/// Asserts that deleted entities stay deleted despite entity recycling.
/// If we don't account for EntityReference / versions correctly old entities may return as being nopt deleted.
/// </summary>
[Test]
public void EntityVersionTest()
{
var sim = RobustServerSimulation.NewSimulation().InitializeInstance();
var entManager = sim.Resolve<IEntityManager>();
var entity = entManager.Spawn(null, MapCoordinates.Nullspace);
entManager.DeleteEntity(entity);
Assert.That(entManager.Deleted(entity));
Assert.That(!entManager.EntityExists(entity));
// Spawn a new entity and check it is a recycled ID.
var entity2 = entManager.Spawn(null, MapCoordinates.Nullspace);
Assert.That(entity.Id, Is.EqualTo(entity2.Id));
Assert.That(entity.Version, Is.Not.EqualTo(entity2.Version));
// Assert the old entity still returns deleted but new one isn't.
Assert.That(entManager.Deleted(entity));
Assert.That(!entManager.Deleted(entity2));
Assert.That(!entManager.EntityExists(entity));
Assert.That(entManager.EntityExists(entity2));
entManager.DeleteEntity(entity2);
}
}

View File

@@ -38,7 +38,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entManager = sim.Resolve<IEntityManager>(); var entManager = sim.Resolve<IEntityManager>();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy"); var container = containerSys.MakeContainer<Container>(entity, "dummy");
@@ -75,8 +75,8 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entManager = sim.Resolve<IEntityManager>(); var entManager = sim.Resolve<IEntityManager>();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var owner = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var owner = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var inserted = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var inserted = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var transform = entManager.GetComponent<TransformComponent>(inserted); var transform = entManager.GetComponent<TransformComponent>(inserted);
var container = containerSys.MakeContainer<Container>(owner, "dummy"); var container = containerSys.MakeContainer<Container>(owner, "dummy");
@@ -105,10 +105,10 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entManager = sim.Resolve<IEntityManager>(); var entManager = sim.Resolve<IEntityManager>();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var owner = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var owner = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var inserted = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var inserted = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var transform = entManager.GetComponent<TransformComponent>(inserted); var transform = entManager.GetComponent<TransformComponent>(inserted);
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(owner, "dummy"); var container = containerSys.MakeContainer<Container>(owner, "dummy");
Assert.That(container.Insert(inserted), Is.True); Assert.That(container.Insert(inserted), Is.True);
@@ -133,7 +133,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var coordinates = new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0)); var coordinates = new EntityCoordinates(new EntityUid(1), new Vector2(0, 0));
var entityOne = sim.SpawnEntity(null, coordinates); var entityOne = sim.SpawnEntity(null, coordinates);
var entityTwo = sim.SpawnEntity(null, coordinates); var entityTwo = sim.SpawnEntity(null, coordinates);
var entityThree = sim.SpawnEntity(null, coordinates); var entityThree = sim.SpawnEntity(null, coordinates);
@@ -166,7 +166,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var sim = SimulationFactory(); var sim = SimulationFactory();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy"); var container = containerSys.MakeContainer<Container>(entity, "dummy");
Assert.That(container.Insert(entity), Is.False); Assert.That(container.Insert(entity), Is.False);
@@ -179,8 +179,8 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var sim = SimulationFactory(); var sim = SimulationFactory();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var mapEnt = EntityUid.FirstUid; var mapEnt = new EntityUid(1);
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy"); var container = containerSys.MakeContainer<Container>(entity, "dummy");
Assert.That(container.Insert(mapEnt), Is.False); Assert.That(container.Insert(mapEnt), Is.False);
@@ -194,7 +194,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var grid = sim.Resolve<IMapManager>().CreateGridEntity(new MapId(1)).Owner; var grid = sim.Resolve<IMapManager>().CreateGridEntity(new MapId(1)).Owner;
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy"); var container = containerSys.MakeContainer<Container>(entity, "dummy");
Assert.That(container.Insert(grid), Is.False); Assert.That(container.Insert(grid), Is.False);
@@ -208,9 +208,9 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entManager = sim.Resolve<IEntityManager>(); var entManager = sim.Resolve<IEntityManager>();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var containerEntity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var containerEntity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(containerEntity, "dummy"); var container = containerSys.MakeContainer<Container>(containerEntity, "dummy");
var insertEntity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var insertEntity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var result = container.Insert(insertEntity); var result = container.Insert(insertEntity);
@@ -231,9 +231,9 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var sim = SimulationFactory(); var sim = SimulationFactory();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var containerEntity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var containerEntity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(containerEntity, "dummy"); var container = containerSys.MakeContainer<Container>(containerEntity, "dummy");
var insertEntity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var insertEntity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var result = container.Remove(insertEntity); var result = container.Remove(insertEntity);
@@ -246,11 +246,11 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var sim = SimulationFactory(); var sim = SimulationFactory();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>(); var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var entity1 = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity1 = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container1 = containerSys.MakeContainer<Container>(entity1, "dummy"); var container1 = containerSys.MakeContainer<Container>(entity1, "dummy");
var entity2 = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity2 = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container2 = containerSys.MakeContainer<Container>(entity2, "dummy"); var container2 = containerSys.MakeContainer<Container>(entity2, "dummy");
var transferEntity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var transferEntity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
container1.Insert(transferEntity); container1.Insert(transferEntity);
var result = container2.Insert(transferEntity); var result = container2.Insert(transferEntity);
@@ -267,9 +267,9 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var entManager = sim.Resolve<IEntityManager>(); var entManager = sim.Resolve<IEntityManager>();
var containerSys = entManager.System<ContainerSystem>(); var containerSys = entManager.System<ContainerSystem>();
var entity = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy"); var container = containerSys.MakeContainer<Container>(entity, "dummy");
var childEnt = sim.SpawnEntity(null, new EntityCoordinates(EntityUid.FirstUid, new Vector2(0, 0))); var childEnt = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
container.OccludesLight = true; container.OccludesLight = true;
container.ShowContents = true; container.ShowContents = true;

View File

@@ -40,7 +40,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
private MapId MapB; private MapId MapB;
private Entity<MapGridComponent> GridB; private Entity<MapGridComponent> GridB;
private static readonly EntityCoordinates InitialPos = new(EntityUid.FirstUid, new Vector2(0, 0)); private static readonly EntityCoordinates InitialPos = new(new EntityUid(1), new Vector2(0, 0));
[OneTimeSetUp] [OneTimeSetUp]
public void Setup() public void Setup()

View File

@@ -16,7 +16,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var compFactory = new ComponentFactory(new DynamicTypeFactory(), new ReflectionManagerTest(), new LogManager()); var compFactory = new ComponentFactory(new DynamicTypeFactory(), new ReflectionManagerTest(), new LogManager());
// Arrange // Arrange
var entUid = new EntityUid(7, -1); var entUid = new EntityUid(7);
var compInstance = new MetaDataComponent(); var compInstance = new MetaDataComponent();
var entManMock = new Mock<IEntityManager>(); var entManMock = new Mock<IEntityManager>();
@@ -67,7 +67,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
public void UnsubscribeCompEvent() public void UnsubscribeCompEvent()
{ {
// Arrange // Arrange
var entUid = new EntityUid(7, -1); var entUid = new EntityUid(7);
var compInstance = new MetaDataComponent(); var compInstance = new MetaDataComponent();
var entManMock = new Mock<IEntityManager>(); var entManMock = new Mock<IEntityManager>();
@@ -121,7 +121,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
public void SubscribeCompLifeEvent() public void SubscribeCompLifeEvent()
{ {
// Arrange // Arrange
var entUid = new EntityUid(7, -1); var entUid = new EntityUid(7);
var compInstance = new MetaDataComponent(); var compInstance = new MetaDataComponent();
var entManMock = new Mock<IEntityManager>(); var entManMock = new Mock<IEntityManager>();
@@ -176,7 +176,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
public void CompEventOrdered() public void CompEventOrdered()
{ {
// Arrange // Arrange
var entUid = new EntityUid(7, -1); var entUid = new EntityUid(7);
var entManMock = new Mock<IEntityManager>(); var entManMock = new Mock<IEntityManager>();
var compFacMock = new Mock<IComponentFactory>(); var compFacMock = new Mock<IComponentFactory>();

View File

@@ -13,7 +13,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
[TestFixture, Parallelizable ,TestOf(typeof(EntityManager))] [TestFixture, Parallelizable ,TestOf(typeof(EntityManager))]
public sealed partial class EntityManager_Components_Tests public sealed partial class EntityManager_Components_Tests
{ {
private static readonly EntityCoordinates DefaultCoords = new(EntityUid.FirstUid, Vector2.Zero); private static readonly EntityCoordinates DefaultCoords = new(new EntityUid(1), Vector2.Zero);
[Test] [Test]
public void AddComponentTest() public void AddComponentTest()
@@ -48,7 +48,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
}; };
// Act // Act
entMan.AddComponent(entity, component); entMan.AddComponent(entity, component, true);
// Assert // Assert
var result = entMan.GetComponent<DummyComponent>(entity); var result = entMan.GetComponent<DummyComponent>(entity);
@@ -82,7 +82,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sim = SimulationFactory(); var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
entMan.AddComponent<DummyComponent>(entity); IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.HasComponent<DummyComponent>(entity); var result = entMan.HasComponent<DummyComponent>(entity);
@@ -91,22 +91,6 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.That(result, Is.True); Assert.That(result, Is.True);
} }
[Test]
public void HasComponentNoGenericTest()
{
// Arrange
var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords);
entMan.AddComponent<DummyComponent>(entity);
// Act
var result = entMan.HasComponent(entity, typeof(DummyComponent));
// Assert
Assert.That(result, Is.True);
}
[Test] [Test]
public void HasNetComponentTest() public void HasNetComponentTest()
{ {
@@ -118,7 +102,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
entMan.AddComponent<DummyComponent>(entity); IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.HasComponent(entity, netId.Value); var result = entMan.HasComponent(entity, netId.Value);
@@ -138,7 +122,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.GetComponent(entity, netId.Value); var result = entMan.GetComponent(entity, netId.Value);
@@ -154,7 +138,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sim = SimulationFactory(); var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.TryGetComponent<DummyComponent>(entity, out var comp); var result = entMan.TryGetComponent<DummyComponent>(entity, out var comp);
@@ -175,7 +159,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.TryGetComponent(entity, netId.Value, out var comp); var result = entMan.TryGetComponent(entity, netId.Value, out var comp);
@@ -192,7 +176,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sim = SimulationFactory(); var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
entMan.RemoveComponent<DummyComponent>(entity); entMan.RemoveComponent<DummyComponent>(entity);
@@ -230,7 +214,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
entMan.RemoveComponent(entity, netId.Value); entMan.RemoveComponent(entity, netId.Value);
@@ -247,7 +231,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sim = SimulationFactory(); var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.GetComponents<DummyComponent>(entity); var result = entMan.GetComponents<DummyComponent>(entity);
@@ -265,7 +249,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sim = SimulationFactory(); var sim = SimulationFactory();
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.EntityQuery<DummyComponent>(true); var result = entMan.EntityQuery<DummyComponent>(true);
@@ -284,7 +268,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var fac = sim.Resolve<IComponentFactory>(); var fac = sim.Resolve<IComponentFactory>();
var entity = entMan.SpawnEntity(null, DefaultCoords); var entity = entMan.SpawnEntity(null, DefaultCoords);
var component = entMan.AddComponent<DummyComponent>(entity); var component = IoCManager.Resolve<IEntityManager>().AddComponent<DummyComponent>(entity);
// Act // Act
var result = entMan.GetComponents(entity); var result = entMan.GetComponents(entity);

View File

@@ -43,8 +43,8 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
void MoveEventHandler(ref MoveEvent ev) void MoveEventHandler(ref MoveEvent ev)
{ {
calledCount++; calledCount++;
Assert.That(ev.OldPosition, Is.EqualTo(new EntityCoordinates(EntityUid.FirstUid, Vector2.Zero))); Assert.That(ev.OldPosition, Is.EqualTo(new EntityCoordinates(new EntityUid(1), Vector2.Zero)));
Assert.That(ev.NewPosition, Is.EqualTo(new EntityCoordinates(EntityUid.FirstUid, Vector2.One))); Assert.That(ev.NewPosition, Is.EqualTo(new EntityCoordinates(new EntityUid(1), Vector2.One)));
} }
} }

View File

@@ -248,7 +248,7 @@ public sealed partial class ComponentStateTests : RobustIntegrationTest
var clientEntA = client.EntMan.GetEntity(serverNetA); var clientEntA = client.EntMan.GetEntity(serverNetA);
var clientEntB = client.EntMan.GetEntity(serverNetB); var clientEntB = client.EntMan.GetEntity(serverNetB);
Assert.That(client.EntMan.EntityExists(clientEntB), Is.True); Assert.That(client.EntMan.EntityExists(clientEntB), Is.True);
Assert.That(client.EntMan.EntityExists(clientEntA), Is.False); Assert.That(client.EntMan.EntityExists(client.EntMan.GetEntity(serverNetA)), Is.False);
Assert.That(client.EntMan.TryGetComponent(clientEntB, out UnknownEntityTestComponent? cmp)); Assert.That(client.EntMan.TryGetComponent(clientEntB, out UnknownEntityTestComponent? cmp));
Assert.That(cmp?.Other, Is.EqualTo(clientEntA)); Assert.That(cmp?.Other, Is.EqualTo(clientEntA));

View File

@@ -160,9 +160,8 @@ public sealed class GridSplit_Tests
grid.SetTile(new Vector2i(2, 0), Tile.Empty); grid.SetTile(new Vector2i(2, 0), Tile.Empty);
Assert.That(mapManager.GetAllGrids(mapId).Count(), Is.EqualTo(2)); Assert.That(mapManager.GetAllGrids(mapId).Count(), Is.EqualTo(2));
var newGrid = mapManager.GetAllMapGrids(mapId).First(); var newGrid = mapManager.GetAllGrids(mapId).Last();
Assert.That(newGrid, Is.Not.EqualTo(grid)); var newGridXform = entManager.GetComponent<TransformComponent>(newGrid);
var newGridXform = entManager.GetComponent<TransformComponent>(newGrid.Owner);
Assert.Multiple(() => Assert.Multiple(() =>
{ {

View File

@@ -55,7 +55,7 @@ namespace Robust.UnitTesting.Shared.Map
} }
/// <summary> /// <summary>
/// When entities are flushed check nullsapce is also culled. /// When the map manager is restarted, Nullspace is recreated.
/// </summary> /// </summary>
[Test] [Test]
public void Restart_NullspaceMap_IsEmptied() public void Restart_NullspaceMap_IsEmptied()
@@ -64,8 +64,9 @@ namespace Robust.UnitTesting.Shared.Map
var entMan = sim.Resolve<IEntityManager>(); var entMan = sim.Resolve<IEntityManager>();
var oldEntity = entMan.CreateEntityUninitialized(null, MapCoordinates.Nullspace); var oldEntity = entMan.CreateEntityUninitialized(null, MapCoordinates.Nullspace);
entMan.InitializeComponents(oldEntity); entMan.InitializeComponents(oldEntity);
entMan.FlushEntities(); entMan.Shutdown();
Assert.That(entMan.Deleted(oldEntity), Is.True); Assert.That(entMan.Deleted(oldEntity), Is.True);
} }
/// <summary> /// <summary>

View File

@@ -112,7 +112,6 @@ public abstract partial class EntitySpawnHelpersTest : RobustIntegrationTest
public override IReadOnlyList<EntityUid> ContainedEntities => _ents; public override IReadOnlyList<EntityUid> ContainedEntities => _ents;
protected override void InternalInsert(EntityUid toInsert, IEntityManager entMan) => _ents.Add(toInsert); protected override void InternalInsert(EntityUid toInsert, IEntityManager entMan) => _ents.Add(toInsert);
protected override void InternalRemove(EntityUid toRemove, IEntityManager entMan) => _ents.Remove(toRemove); protected override void InternalRemove(EntityUid toRemove, IEntityManager entMan) => _ents.Remove(toRemove);
public override bool Contains(EntityUid contained) => _ents.Contains(contained); public override bool Contains(EntityUid contained) => _ents.Contains(contained);
protected override void InternalShutdown(IEntityManager entMan, bool isClient) { } protected override void InternalShutdown(IEntityManager entMan, bool isClient) { }
protected internal override bool CanInsert(EntityUid toinsert, bool assumeEmpty, IEntityManager entMan) protected internal override bool CanInsert(EntityUid toinsert, bool assumeEmpty, IEntityManager entMan)

View File

@@ -42,7 +42,7 @@ public sealed partial class ToolshedParserTest : ToolshedTest
{ {
await Server.WaitAssertion(() => await Server.WaitAssertion(() =>
{ {
ParseCommand("ent 1 2"); ParseCommand("ent 1");
// Clientside entities are a myth. // Clientside entities are a myth.
ExpectError<InvalidEntity>(); ExpectError<InvalidEntity>();