Skip to content

Commit

Permalink
Fix NullReferenceException on subsequent runs
Browse files Browse the repository at this point in the history
Use lazy initialization
  • Loading branch information
arthurkehrwald committed Nov 1, 2024
1 parent 3e5782d commit d9a2c5d
Showing 1 changed file with 23 additions and 5 deletions.
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

0 comments on commit d9a2c5d

Please sign in to comment.