Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NullReferenceException on subsequent runs #485

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,24 @@ public class PhysicsEngine : MonoBehaviour
[NonSerialized] private NativeColliders _kinematicCollidersAtIdentity;
[NonSerialized] private NativeParallelHashMap<int, NativeColliderIds> _kinematicColliderLookups;
[NonSerialized] private NativeArray<PhysicsEnv> _physicsEnv = new(1, Allocator.Persistent);
[NonSerialized] private NativeQueue<EventData> _eventQueue = new(Allocator.Persistent);

// This initialization logic is very verbose. We cannot use a field initializer as we do
// for the other native structs, because that causes a NullReferenceException to be thrown
// on subsequent runs even if the NativeQueue is disposed. We cannot initialize in Awake,
// because other scripts may access the queue before that runs.
private bool isEventQueueIinitalized = false;
[NonSerialized] private NativeQueue<EventData> _eventQueue;
private NativeQueue<EventData> _EventQueue
{
get
{
if (!isEventQueueIinitalized) {
_eventQueue = new(Allocator.Persistent);
isEventQueueIinitalized = true;
}
return _eventQueue;
}
}

[NonSerialized] private NativeParallelHashMap<int, BallState> _ballStates = new(0, Allocator.Persistent);
[NonSerialized] private NativeParallelHashMap<int, BumperState> _bumperStates = new(0, Allocator.Persistent);
Expand Down Expand Up @@ -99,7 +116,7 @@ public void ScheduleAction(uint timeoutMs, Action action)

internal ref NativeParallelHashMap<int, BallState> Balls => ref _ballStates;
internal ref InsideOfs InsideOfs => ref _insideOfs;
internal NativeQueue<EventData>.ParallelWriter EventQueue => _eventQueue.AsParallelWriter();
internal NativeQueue<EventData>.ParallelWriter EventQueue => _EventQueue.AsParallelWriter();

internal void Schedule(InputAction action) => _inputActions.Enqueue(action);
internal ref BallState BallState(int ballId) => ref _ballStates.GetValueByRef(ballId);
Expand Down Expand Up @@ -170,6 +187,7 @@ internal void DisableCollider(int itemId)

private void Awake()
{
_eventQueue = new(Allocator.Persistent);
_player = GetComponentInParent<Player>();
_insideOfs = new InsideOfs(Allocator.Persistent);
_physicsEnv[0] = new PhysicsEnv(NowUsec, GetComponentInChildren<PlayfieldComponent>(), GravityStrength);
Expand Down Expand Up @@ -245,7 +263,7 @@ private void Update()
}

// prepare job
var events = _eventQueue.AsParallelWriter();
var events = _EventQueue.AsParallelWriter();
var updatePhysics = new PhysicsUpdateJob {
InitialTimeUsec = NowUsec,
DeltaTimeMs = Time.deltaTime * 1000,
Expand Down Expand Up @@ -291,7 +309,7 @@ private void Update()
updatePhysics.Run();

// dequeue events
while (_eventQueue.TryDequeue(out var eventData)) {
while (_EventQueue.TryDequeue(out var eventData)) {
_player.OnEvent(in eventData);
}

Expand Down Expand Up @@ -416,7 +434,7 @@ private void Update()
private void OnDestroy()
{
_physicsEnv.Dispose();
_eventQueue.Dispose();
_EventQueue.Dispose();
_ballStates.Dispose();
_colliders.Dispose();
_insideOfs.Dispose();
Expand Down