Skip to content
Draft
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ public static bool TryGetIdentity(this PredictedComponentID? id, PredictionManag
return id?.TryGetIdentity(manager, out identity) ?? false;
}
}
}
}
110 changes: 82 additions & 28 deletions Assets/PurrDiction/Runtime/Core/PredictionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -388,15 +388,22 @@ public void UnregisterPooledInstance(GameObject go)
}

readonly Dictionary<PredictedComponentID, PredictedIdentity> _instanceMap = new ();
readonly Dictionary<PredictedComponentID, PredictedIdentity> _deletingInstanceMap = new ();

public bool TryGetIdentity(PredictedComponentID id, out PredictedIdentity instance)
{
return _instanceMap.TryGetValue(id, out instance);
if (_instanceMap.TryGetValue(id, out instance))
return true;

return _deletingInstanceMap.TryGetValue(id, out instance);
}

public PredictedIdentity GetIdentity(PredictedComponentID id)
{
return _instanceMap.GetValueOrDefault(id);
if (_instanceMap.TryGetValue(id, out var identity))
return identity;

return _deletingInstanceMap.GetValueOrDefault(id);
}

private void RegisterInstance(PredictedIdentity system, PredictedObjectID objectId, uint componentId, PlayerID? owner)
Expand Down Expand Up @@ -679,8 +686,7 @@ private void OnPreTick()
}
}

for (var i = 0; i < _systemsCount; i++)
_systems[i].PostSimulate();
PostSimulateAll();

if (cachedIsServer)
FinalizeTickOnServer(cachedIsClient);
Expand Down Expand Up @@ -1176,8 +1182,7 @@ private void SimulateFrameInPlace(ulong verifiedTick)
lateSimulateMarker.Dispose();
}

for (var i = 0; i < _systemsCount; i++)
_systems[i].PostSimulate();
PostSimulateAll();
for (var j = 0; j < _systemsCount; j++)
_systems[j].GetLatestUnityState();

Expand Down Expand Up @@ -1258,8 +1263,7 @@ private void SimulateFrame(ulong verifiedTick, bool saveState)
}
}

for (var i = 0; i < _systemsCount; i++)
_systems[i].PostSimulate();
PostSimulateAll();

for (var j = 0; j < _systemsCount; j++)
_systems[j].GetLatestUnityState();
Expand Down Expand Up @@ -1502,34 +1506,84 @@ internal GameObject InternalCreate(GameObject prefab, Vector3 position, Quaterni

internal void InternalDelete(PackedInt prefabId, GameObject instance)
{
int pid = prefabId;

if (!_predictedPrefabs || pid < 0 || pid >= _predictedPrefabs.prefabs.Count)
var deletingIds = BeginDeletingInstance(instance);
try
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
return;
}
int pid = prefabId;

var prefabsInfo = _predictedPrefabs.prefabs[pid];
if (!_predictedPrefabs || pid < 0 || pid >= _predictedPrefabs.prefabs.Count)
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
return;
}

if (!prefabsInfo.pooled)
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
return;
}
var prefabsInfo = _predictedPrefabs.prefabs[pid];

if (!prefabsInfo.pooled)
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
return;
}

if (_pools != null && _pools.TryGetPool(prefabsInfo.prefab, out var pool))
if (_pools != null && _pools.TryGetPool(prefabsInfo.prefab, out var pool))
{
UnregisterPooledInstance(instance);
pool.Delete(instance);
}
else
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
}
}
finally
{
UnregisterPooledInstance(instance);
pool.Delete(instance);
if (!isSimulating)
EndDeletingInstance(deletingIds);
}
else
}

private List<PredictedComponentID> BeginDeletingInstance(GameObject instance)
{
var deletingIds = new List<PredictedComponentID>();

if (!instance)
return deletingIds;

var identities = ListPool<PredictedIdentity>.Instantiate();
instance.GetComponentsInChildren(true, identities);

for (int i = 0; i < identities.Count; i++)
{
UnregisterInstance(instance, false, true);
UnityProxy.DestroyImmediateDirectly(instance);
var identity = identities[i];
var id = identity.id;
_deletingInstanceMap[id] = identity;
deletingIds.Add(id);
}

ListPool<PredictedIdentity>.Destroy(identities);
return deletingIds;
}

private void EndDeletingInstance(List<PredictedComponentID> deletingIds)
{
for (int i = 0; i < deletingIds.Count; i++)
_deletingInstanceMap.Remove(deletingIds[i]);
}

private void ClearDeletingInstanceMap()
{
_deletingInstanceMap.Clear();
}

private void PostSimulateAll()
{
for (var i = 0; i < _systemsCount; i++)
_systems[i].PostSimulate();

ClearDeletingInstanceMap();
}

public void SetOwnership(PredictedObjectID? root, PlayerID? player)
Expand Down
Loading