mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-04 03:39:55 +00:00
add support for delayed readiness in WorldObject and WorldObjectManager
(also slightly optimize qsbworldsync)
This commit is contained in:
parent
629deaa927
commit
c760fe2c41
@ -9,7 +9,7 @@ namespace QSB.Anglerfish.TransformSync
|
||||
{
|
||||
public class AnglerTransformSync : UnsectoredRigidbodySync
|
||||
{
|
||||
public override bool IsReady => QSBCore.WorldObjectsReady;
|
||||
public override bool IsReady => WorldObjectManager.AllAdded;
|
||||
public override bool UseInterpolation => false;
|
||||
|
||||
private QSBAngler _qsbAngler;
|
||||
|
@ -22,13 +22,21 @@ namespace QSB.Anglerfish.WorldObjects
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab));
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
TransformSync.NetIdentity.RegisterAuthQueue());
|
||||
}
|
||||
|
||||
// for when you host/connect mid-game
|
||||
StartDelayedReady();
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
TransformSync.NetIdentity.FireAuthQueue(!AttachedObject._anglerBody.IsSuspended()));
|
||||
{
|
||||
FinishDelayedReady();
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
TransformSync.NetIdentity.RegisterAuthQueue();
|
||||
}
|
||||
|
||||
// for when you host/connect mid-game
|
||||
TransformSync.NetIdentity.FireAuthQueue(!AttachedObject._anglerBody.IsSuspended());
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
|
@ -11,7 +11,7 @@ namespace QSB.JellyfishSync.TransformSync
|
||||
{
|
||||
public class JellyfishTransformSync : UnsectoredRigidbodySync
|
||||
{
|
||||
public override bool IsReady => QSBCore.WorldObjectsReady;
|
||||
public override bool IsReady => WorldObjectManager.AllAdded;
|
||||
public override bool UseInterpolation => false;
|
||||
|
||||
private QSBJellyfish _qsbJellyfish;
|
||||
|
@ -20,13 +20,21 @@ namespace QSB.JellyfishSync.WorldObjects
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.JellyfishPrefab));
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
TransformSync.NetIdentity.RegisterAuthQueue());
|
||||
}
|
||||
|
||||
// for when you host/connect mid-game
|
||||
StartDelayedReady();
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
TransformSync.NetIdentity.FireAuthQueue(!AttachedObject._jellyfishBody.IsSuspended()));
|
||||
{
|
||||
FinishDelayedReady();
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
TransformSync.NetIdentity.RegisterAuthQueue();
|
||||
}
|
||||
|
||||
// for when you host/connect mid-game
|
||||
TransformSync.NetIdentity.FireAuthQueue(!AttachedObject._jellyfishBody.IsSuspended());
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
|
@ -23,7 +23,7 @@ namespace QSB.MeteorSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, FragmentDamageMessage message)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace QSB.MeteorSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, FragmentResyncMessage msg)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace QSB.MeteorSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, MeteorLaunchMessage message)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace QSB.MeteorSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, WorldObjectMessage message)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace QSB.MeteorSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, WorldObjectMessage message)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -6,21 +6,19 @@ namespace QSB.MeteorSync
|
||||
{
|
||||
public class MeteorManager : WorldObjectManager
|
||||
{
|
||||
public static bool Ready => AllReady && _ready;
|
||||
private static bool _ready;
|
||||
public static WhiteHoleVolume WhiteHoleVolume;
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
_ready = false;
|
||||
// wait for all late initializers (which includes meteor launchers) to finish
|
||||
StartDelayedReady();
|
||||
QSBCore.UnityEvents.RunWhen(() => LateInitializerManager.s_lateInitializers.Count == 0, () =>
|
||||
{
|
||||
FinishDelayedReady();
|
||||
WhiteHoleVolume = QSBWorldSync.GetUnityObjects<WhiteHoleVolume>().First();
|
||||
QSBWorldSync.Init<QSBMeteorLauncher, MeteorLauncher>();
|
||||
QSBWorldSync.Init<QSBMeteor, MeteorController>();
|
||||
QSBWorldSync.Init<QSBFragment, FragmentIntegrity>();
|
||||
_ready = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ namespace QSB.MeteorSync.Patches
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace QSB.MeteorSync.Patches
|
||||
[HarmonyPatch(typeof(MeteorLauncher), nameof(MeteorLauncher.FixedUpdate))]
|
||||
public static bool FixedUpdate(MeteorLauncher __instance)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -202,7 +202,7 @@ namespace QSB.MeteorSync.Patches
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!MeteorManager.Ready)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
@ -32,16 +32,19 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
}
|
||||
|
||||
base.Init(attachedObject, id);
|
||||
}
|
||||
|
||||
public override void PostInit()
|
||||
{
|
||||
QuantumStates = AttachedObject._states.ToList().Select(x => QSBWorldSync.GetWorldFromUnity<QSBQuantumState>(x)).ToList();
|
||||
|
||||
if (QuantumStates.Any(x => x == null))
|
||||
StartDelayedReady();
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllAdded, () =>
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {AttachedObject.name} has one or more null QSBQuantumStates assigned!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
FinishDelayedReady();
|
||||
|
||||
QuantumStates = AttachedObject._states.Select(QSBWorldSync.GetWorldFromUnity<QSBQuantumState>).ToList();
|
||||
|
||||
if (QuantumStates.Any(x => x == null))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {AttachedObject.name} has one or more null QSBQuantumStates assigned!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ChangeState(int newStateIndex)
|
||||
|
@ -76,7 +76,7 @@ namespace QSB.Syncs
|
||||
&& Player.IsReady
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U
|
||||
&& WorldObjectManager.AllReady;
|
||||
&& WorldObjectManager.AllAdded;
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
public abstract bool IgnoreDisabledAttachedObject { get; }
|
||||
|
@ -7,7 +7,6 @@ namespace QSB.WorldSync
|
||||
int ObjectId { get; }
|
||||
string Name { get; }
|
||||
|
||||
void PostInit();
|
||||
void OnRemoval();
|
||||
MonoBehaviour ReturnObject();
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OWML.Common;
|
||||
using QSB.OrbSync.TransformSync;
|
||||
using QSB.OrbSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.WorldSync
|
||||
{
|
||||
public static class QSBWorldSync
|
||||
{
|
||||
public static List<NomaiInterfaceOrb> OldOrbList { get; set; } = new List<NomaiInterfaceOrb>();
|
||||
public static List<CharacterDialogueTree> OldDialogueTrees { get; set; } = new List<CharacterDialogueTree>();
|
||||
public static Dictionary<string, bool> DialogueConditions { get; } = new Dictionary<string, bool>();
|
||||
public static List<FactReveal> ShipLogFacts { get; } = new List<FactReveal>();
|
||||
public static List<NomaiInterfaceOrb> OldOrbList { get; set; } = new();
|
||||
public static List<CharacterDialogueTree> OldDialogueTrees { get; set; } = new();
|
||||
public static Dictionary<string, bool> DialogueConditions { get; } = new();
|
||||
public static List<FactReveal> ShipLogFacts { get; } = new();
|
||||
|
||||
private static readonly List<IWorldObject> WorldObjects = new();
|
||||
private static readonly Dictionary<MonoBehaviour, IWorldObject> WorldObjectsToUnityObjects = new();
|
||||
@ -24,18 +24,19 @@ namespace QSB.WorldSync
|
||||
|
||||
public static TWorldObject GetWorldFromId<TWorldObject>(int id)
|
||||
{
|
||||
if (id < 0 || id >= GetWorldObjects<TWorldObject>().Count())
|
||||
var worldObjects = GetWorldObjects<TWorldObject>().ToList();
|
||||
if (id < 0 || id >= worldObjects.Count)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to find {typeof(TWorldObject).Name} id {id}. Count is {GetWorldObjects<TWorldObject>().Count()}.", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - Tried to find {typeof(TWorldObject).Name} id {id}. Count is {worldObjects.Count}.", MessageType.Warning);
|
||||
return default;
|
||||
}
|
||||
|
||||
return GetWorldObjects<TWorldObject>().ToList()[id];
|
||||
return worldObjects[id];
|
||||
}
|
||||
|
||||
public static IWorldObject GetWorldFromUnity(MonoBehaviour unityObject)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
if (!WorldObjectManager.AllAdded)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
@ -52,14 +53,12 @@ namespace QSB.WorldSync
|
||||
return default;
|
||||
}
|
||||
|
||||
if (!WorldObjectsToUnityObjects.ContainsKey(unityObject))
|
||||
if (!WorldObjectsToUnityObjects.TryGetValue(unityObject, out var returnObject))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"! TUnityObject:{unityObject.GetType().Name}", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
var returnObject = WorldObjectsToUnityObjects[unityObject];
|
||||
|
||||
if (returnObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - World object for unity object {unityObject.name} is null! TUnityObject:{unityObject.GetType().Name}", MessageType.Error);
|
||||
@ -72,7 +71,7 @@ namespace QSB.WorldSync
|
||||
public static TWorldObject GetWorldFromUnity<TWorldObject>(MonoBehaviour unityObject)
|
||||
where TWorldObject : IWorldObject
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
if (!WorldObjectManager.AllAdded)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
@ -89,21 +88,19 @@ namespace QSB.WorldSync
|
||||
return default;
|
||||
}
|
||||
|
||||
if (!WorldObjectsToUnityObjects.ContainsKey(unityObject))
|
||||
if (!WorldObjectsToUnityObjects.TryGetValue(unityObject, out var returnObject))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
var returnObject = (TWorldObject)WorldObjectsToUnityObjects[unityObject];
|
||||
|
||||
if (returnObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - World object for unity object {unityObject.name} is null! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
return returnObject;
|
||||
return (TWorldObject)returnObject;
|
||||
}
|
||||
|
||||
public static int GetIdFromUnity<TWorldObject>(MonoBehaviour unityObject)
|
||||
@ -115,7 +112,7 @@ namespace QSB.WorldSync
|
||||
var index = GetWorldObjects<TTypeSubset>().ToList().IndexOf(typeSubset);
|
||||
if (index == -1)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {(typeSubset as IWorldObject).Name} doesn't exist in list of {typeof(TTypeSubset).Name} !", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - {((IWorldObject)typeSubset).Name} doesn't exist in list of {typeof(TTypeSubset).Name} !", MessageType.Warning);
|
||||
}
|
||||
|
||||
return index;
|
||||
@ -123,21 +120,16 @@ namespace QSB.WorldSync
|
||||
|
||||
public static void RemoveWorldObjects<TWorldObject>()
|
||||
{
|
||||
if (WorldObjects == null || WorldObjects.Count == 0)
|
||||
if (WorldObjects.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to remove WorldObjects of type {typeof(TWorldObject).Name}, but there are no WorldObjects!");
|
||||
DebugLog.ToConsole($"Warning - Trying to remove WorldObjects of type {typeof(TWorldObject).Name}, but there are no WorldObjects!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var itemsToRemove = WorldObjects.Where(x => x is TWorldObject);
|
||||
|
||||
foreach (var item in itemsToRemove)
|
||||
{
|
||||
if (item is null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to remove a null WorldObject of type {typeof(TWorldObject).Name}.", MessageType.Error);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
WorldObjectsToUnityObjects.Remove(item.ReturnObject());
|
||||
|
@ -12,8 +12,13 @@ namespace QSB.WorldSync
|
||||
public string LogName => $"{QSBPlayerManager.LocalPlayerId}.{ObjectId}:{GetType().Name}";
|
||||
|
||||
public abstract void Init(T attachedObject, int id);
|
||||
public virtual void PostInit() { }
|
||||
public virtual void OnRemoval() { }
|
||||
public MonoBehaviour ReturnObject() => AttachedObject;
|
||||
|
||||
/// indicates that this won't become ready immediately
|
||||
protected void StartDelayedReady() => WorldObjectManager._numObjectsReadying++;
|
||||
|
||||
/// indicates that this is now ready
|
||||
protected void FinishDelayedReady() => WorldObjectManager._numObjectsReadying--;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.WorldSync
|
||||
@ -10,7 +12,7 @@ namespace QSB.WorldSync
|
||||
{
|
||||
private static readonly List<WorldObjectManager> _managers = new();
|
||||
|
||||
// BUG : this gets set to true even if the objects aren't technically ready (i.e. they wait for something else)
|
||||
public static bool AllAdded { get; private set; }
|
||||
public static bool AllReady { get; private set; }
|
||||
|
||||
public virtual void Awake()
|
||||
@ -25,9 +27,17 @@ namespace QSB.WorldSync
|
||||
_managers.Remove(this);
|
||||
}
|
||||
|
||||
public static void SetNotReady() => AllReady = false;
|
||||
public static void SetNotReady()
|
||||
{
|
||||
AllAdded = false;
|
||||
AllReady = false;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse) => AllReady = false;
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
AllAdded = false;
|
||||
AllReady = false;
|
||||
}
|
||||
|
||||
public static void Rebuild(OWScene scene)
|
||||
{
|
||||
@ -56,6 +66,10 @@ namespace QSB.WorldSync
|
||||
|
||||
private static void DoRebuild(OWScene scene)
|
||||
{
|
||||
_numManagersReadying = 0;
|
||||
_numObjectsReadying = 0;
|
||||
AllAdded = false;
|
||||
AllReady = false;
|
||||
foreach (var manager in _managers)
|
||||
{
|
||||
try
|
||||
@ -68,19 +82,27 @@ namespace QSB.WorldSync
|
||||
}
|
||||
}
|
||||
|
||||
QSBCore.UnityEvents.FireInNUpdates(DoPostInit, 1);
|
||||
}
|
||||
|
||||
private static void DoPostInit()
|
||||
{
|
||||
AllReady = true;
|
||||
var allWorldObjects = QSBWorldSync.GetWorldObjects<IWorldObject>();
|
||||
foreach (var worldObject in allWorldObjects)
|
||||
QSBCore.UnityEvents.RunWhen(() => _numManagersReadying == 0, () =>
|
||||
{
|
||||
worldObject.PostInit();
|
||||
}
|
||||
AllAdded = true;
|
||||
DebugLog.DebugWrite("World Objects added.", MessageType.Success);
|
||||
QSBCore.UnityEvents.RunWhen(() => _numObjectsReadying == 0, () =>
|
||||
{
|
||||
AllReady = true;
|
||||
DebugLog.DebugWrite("World Objects ready.", MessageType.Success);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void RebuildWorldObjects(OWScene scene);
|
||||
|
||||
private static uint _numManagersReadying;
|
||||
internal static uint _numObjectsReadying;
|
||||
|
||||
/// indicates that this won't become ready immediately
|
||||
protected void StartDelayedReady() => _numManagersReadying++;
|
||||
|
||||
/// indicates that this is now ready
|
||||
protected void FinishDelayedReady() => _numManagersReadying--;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user