This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
/
MockWorld.cs
141 lines (112 loc) · 4.16 KB
/
MockWorld.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Collections.Generic;
using Improbable.Gdk.Core;
using Improbable.Gdk.Subscriptions;
using Unity.Entities;
using UnityEngine;
namespace Improbable.Gdk.TestUtils
{
public class MockWorld : IDisposable
{
public struct Options
{
public string WorkerType;
public Action<World> AdditionalSystems;
public ILogDispatcher Logger;
public bool EnableSerialization;
}
public WorkerInWorld Worker { get; private set; }
public MockConnectionHandler Connection { get; private set; }
public EntityGameObjectLinker Linker { get; private set; }
private readonly HashSet<GameObject> gameObjects = new HashSet<GameObject>();
public static MockWorld Create(Options options)
{
var mockWorld = new MockWorld();
var connectionBuilder = new MockConnectionHandlerBuilder(options.EnableSerialization);
mockWorld.Connection = connectionBuilder.ConnectionHandler;
mockWorld.Worker = WorkerInWorld
.CreateWorkerInWorldAsync(connectionBuilder,
options.WorkerType ?? "TestWorkerType",
options.Logger ?? new LoggingDispatcher(),
Vector3.zero)
.Result;
options.AdditionalSystems?.Invoke(mockWorld.Worker.World);
mockWorld.Linker = new EntityGameObjectLinker(mockWorld.Worker.World);
mockWorld.GetSystem<CommandSystem>().OutgoingHandler = mockWorld.Connection.OutgoingCommandHandler;
PlayerLoopUtils.ResolveSystemGroups(mockWorld.Worker.World);
return mockWorld;
}
public T GetSystem<T>() where T : ComponentSystemBase
{
return Worker.World.GetExistingSystem<T>();
}
public MockWorldWithContext<T> Step<T>(Func<MockWorld, T> frame)
{
var context = frame(this);
Update();
return new MockWorldWithContext<T>(this, context);
}
public MockWorld Step(Action<MockWorld> frame)
{
frame(this);
Update();
return this;
}
private void Update()
{
Worker.World.Update();
}
public (GameObject, T) CreateGameObject<T>(long entityId) where T : MonoBehaviour
{
var gameObject = new GameObject("TestGameObject");
gameObjects.Add(gameObject);
var component = gameObject.AddComponent<T>();
component.enabled = false;
Linker.LinkGameObjectToSpatialOSEntity(new EntityId(entityId), gameObject);
return (gameObject, component);
}
public void Dispose()
{
foreach (var go in gameObjects)
{
UnityEngine.Object.DestroyImmediate(go);
}
Worker?.Dispose();
Connection?.Dispose();
}
public readonly struct MockWorldWithContext<T>
{
private readonly T context;
private readonly MockWorld world;
public MockWorldWithContext(MockWorld world, T context)
{
this.world = world;
this.context = context;
}
public MockWorldWithContext<U> Step<U>(Func<MockWorld, T, U> frame)
{
var newContext = frame(world, context);
world.Update();
return new MockWorldWithContext<U>(world, newContext);
}
public MockWorldWithContext<U> Step<U>(Func<MockWorld, U> frame)
{
var newContext = frame(world);
world.Update();
return new MockWorldWithContext<U>(world, newContext);
}
public MockWorldWithContext<T> Step(Action<MockWorld> frame)
{
frame(world);
world.Update();
return this;
}
public MockWorldWithContext<T> Step(Action<MockWorld, T> frame)
{
frame(world, context);
world.Update();
return this;
}
}
}
}