fix lag - but trade for long load time

This commit is contained in:
Mister_Nebula 2021-02-18 15:36:11 +00:00
parent aee4a88391
commit 7294327fcd
9 changed files with 191 additions and 164 deletions

View File

@ -210,7 +210,6 @@
<Compile Include="Utility\DebugBoxManager.cs" />
<Compile Include="Utility\DebugZOverride.cs" />
<Compile Include="Utility\Extensions.cs" />
<Compile Include="Utility\OnEnableDisableTracker.cs" />
<Compile Include="Utility\Popcron.Gizmos\Constants.cs" />
<Compile Include="Utility\Popcron.Gizmos\Drawers\CubeDrawer.cs" />
<Compile Include="Utility\Popcron.Gizmos\Drawer.cs" />

View File

@ -6,14 +6,17 @@ using QSB.ElevatorSync;
using QSB.GeyserSync;
using QSB.OrbSync;
using QSB.Patches;
using QSB.Player;
using QSB.QuantumSync;
using QSB.SectorSync;
using QSB.TimeSync;
using QSB.TranslationSync;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET;
using QuantumUNET.Components;
using System.Linq;
using System.Reflection;
using UnityEngine;
/*
@ -98,6 +101,77 @@ namespace QSB
public void Update() =>
QNetworkIdentity.UNetStaticUpdate();
public void OnGUI()
{
GUI.Label(new Rect(220, 10, 200f, 20f), $"Rough FPS : {1f / Time.smoothDeltaTime}");
GUI.Label(new Rect(220, 40, 200f, 20f), $"HasWokenUp : {QSBCore.HasWokenUp}");
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode)
{
return;
}
if (QSBSceneManager.CurrentScene != OWScene.SolarSystem)
{
return;
}
var offset = 70f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Visible : {Locator.GetQuantumMoon().IsVisible()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Locked : {Locator.GetQuantumMoon().IsLocked()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Illuminated : {Locator.GetQuantumMoon().IsIlluminated()}");
offset += 30f;
//GUI.Label(new Rect(220, offset, 200f, 20f), $"Shrine player in dark? : {QuantumManager.Instance.Shrine.IsPlayerInDarkness()}");
//offset += 30f;
var tracker = Locator.GetQuantumMoon().GetValue<ShapeVisibilityTracker>("_visibilityTracker");
foreach (var camera in QSBPlayerManager.GetPlayerCameras())
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- {camera.name} : {tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(tracker, new object[] { camera.GetFrustumPlanes() })}");
offset += 30f;
}
// Used for diagnosing specific socketed objects. Just set <index> to be the correct index.
/*
var index = 110;
var socketedObject = QSBWorldSync.GetWorldObject<QSBSocketedQuantumObject>(index);
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Controller : {socketedObject.ControllingPlayer}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Visible : {socketedObject.AttachedObject.IsVisible()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Locked : {socketedObject.AttachedObject.IsLocked()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Illuminated : {socketedObject.AttachedObject.IsIlluminated()}");
offset += 30f;
var socketedTrackers = socketedObject.AttachedObject.GetComponentsInChildren<ShapeVisibilityTracker>();
if (socketedTrackers == null || socketedTrackers.Length == 0)
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- List is null or empty.");
return;
}
if (socketedTrackers.Any(x => x is null))
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- Uses a null.");
return;
}
foreach (var camera in QSBPlayerManager.GetPlayerCameras())
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- {camera.name} : {socketedTrackers.Any(x => (bool)x.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(x, new object[] { camera.GetFrustumPlanes() }))}");
offset += 30f;
}
*/
offset = 10f;
GUI.Label(new Rect(440, offset, 200f, 20f), $"Owned Objects :");
offset += 30f;
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().Where(x => x.ControllingPlayer == QSBPlayerManager.LocalPlayerId))
{
GUI.Label(new Rect(440, offset, 200f, 20f), $"- {(obj as IWorldObject).Name}");
offset += 30f;
}
}
public override void Configure(IModConfig config)
{
DefaultServerIP = config.GetSettingsValue<string>("defaultServerIP");

View File

@ -178,9 +178,9 @@ namespace QSB
if (QSBSceneManager.IsInUniverse)
{
QSBSectorManager.Instance.RebuildSectors();
OrbManager.Instance.QueueBuildSlots();
QuantumManager.Instance.RebuildQuantumObjects(QSBSceneManager.CurrentScene);
QSBSectorManager.Instance?.RebuildSectors();
OrbManager.Instance?.QueueBuildSlots();
QuantumManager.Instance?.RebuildQuantumObjects(QSBSceneManager.CurrentScene);
}
var specificType = QNetworkServer.active ? QSBPatchTypes.OnServerClientConnect : QSBPatchTypes.OnNonServerClientConnect;

View File

@ -28,6 +28,8 @@ namespace QSB.QuantumSync.Patches
QSBCore.Helper.HarmonyHelper.AddPrefix<QuantumShrine>("OnEntry", typeof(QuantumPatches), nameof(Shrine_OnEntry));
QSBCore.Helper.HarmonyHelper.AddPrefix<QuantumShrine>("OnExit", typeof(QuantumPatches), nameof(Shrine_OnExit));
QSBCore.Helper.HarmonyHelper.AddPrefix<QuantumMoon>("CheckPlayerFogProximity", typeof(QuantumPatches), nameof(Moon_CheckPlayerFogProximity));
QSBCore.Helper.HarmonyHelper.AddPostfix<Shape>("OnEnable", typeof(QuantumPatches), nameof(Shape_OnEnable));
QSBCore.Helper.HarmonyHelper.AddPostfix<Shape>("OnDisable", typeof(QuantumPatches), nameof(Shape_OnDisable));
}
public override void DoUnpatches()
@ -42,6 +44,60 @@ namespace QSB.QuantumSync.Patches
QSBCore.Helper.HarmonyHelper.Unpatch<QuantumShrine>("OnEntry");
QSBCore.Helper.HarmonyHelper.Unpatch<QuantumShrine>("OnExit");
QSBCore.Helper.HarmonyHelper.Unpatch<QuantumMoon>("CheckPlayerFogProximity");
QSBCore.Helper.HarmonyHelper.Unpatch<Shape>("OnEnable");
QSBCore.Helper.HarmonyHelper.Unpatch<Shape>("OnDisable");
}
private static IQSBQuantumObject GetWorldObjectFromShape(Shape shape)
{
var obj = QuantumManager.Instance._shapesToTrackers.FirstOrDefault(x => x.Key.Contains(shape));
if (obj.Equals(default(KeyValuePair<Shape[], VisibilityTracker>)))
{
return null;
}
var quantumObject = QuantumManager.Instance._objectToTrackers.FirstOrDefault(x => x.Value.Contains(obj.Value));
if (quantumObject.Equals(default(KeyValuePair<VisibilityObject, List<VisibilityTracker>>)))
{
return null;
}
IQSBQuantumObject worldObject = null;
if (quantumObject.Key.GetType() == typeof(SocketedQuantumObject))
{
worldObject = QSBWorldSync.GetWorldObject<QSBSocketedQuantumObject, SocketedQuantumObject>(quantumObject.Key.GetComponent<SocketedQuantumObject>());
}
if (quantumObject.Key.GetType() == typeof(MultiStateQuantumObject))
{
worldObject = QSBWorldSync.GetWorldObject<QSBMultiStateQuantumObject, MultiStateQuantumObject>(quantumObject.Key.GetComponent<MultiStateQuantumObject>());
}
if (quantumObject.Key.GetType() == typeof(QuantumShuffleObject))
{
worldObject = QSBWorldSync.GetWorldObject<QSBQuantumShuffleObject, QuantumShuffleObject>(quantumObject.Key.GetComponent<QuantumShuffleObject>());
}
if (quantumObject.Key.GetType() == typeof(QuantumSocket))
{
return null;
}
return worldObject;
}
public static void Shape_OnEnable(Shape __instance)
{
var worldObject = GetWorldObjectFromShape(__instance);
if (worldObject == null)
{
return;
}
worldObject.Enable();
}
public static void Shape_OnDisable(Shape __instance)
{
var worldObject = GetWorldObjectFromShape(__instance);
if (worldObject == null)
{
return;
}
worldObject.Disable();
}
public static bool Socketed_ChangeQuantumState(SocketedQuantumObject __instance)

View File

@ -16,10 +16,8 @@ namespace QSB.QuantumSync
{
public static QuantumManager Instance { get; private set; }
private List<SocketedQuantumObject> _socketedQuantumObjects;
private List<MultiStateQuantumObject> _multiStateQuantumObjects;
private List<QuantumSocket> _quantumSockets;
private List<QuantumShuffleObject> _quantumShuffleObjects;
public Dictionary<Shape[], VisibilityTracker> _shapesToTrackers = new Dictionary<Shape[], VisibilityTracker>();
public Dictionary<VisibilityObject, List<VisibilityTracker>> _objectToTrackers = new Dictionary<VisibilityObject, List<VisibilityTracker>>();
public QuantumShrine Shrine;
public bool IsReady;
@ -34,14 +32,54 @@ namespace QSB.QuantumSync
public void RebuildQuantumObjects(OWScene scene)
{
DebugLog.DebugWrite("Rebuilding quantum objects...", MessageType.Warning);
_socketedQuantumObjects = QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
_multiStateQuantumObjects = QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
_quantumSockets = QSBWorldSync.Init<QSBQuantumSocket, QuantumSocket>();
_quantumShuffleObjects = QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
QSBWorldSync.Init<QSBQuantumSocket, QuantumSocket>();
QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
if (scene == OWScene.SolarSystem)
{
Shrine = Resources.FindObjectsOfTypeAll<QuantumShrine>().First();
}
var visibilityObjects = Resources.FindObjectsOfTypeAll<VisibilityObject>().Where(
x => x != null
&& x.GetValue<VisibilityTracker[]>("_visibilityTrackers") != null
&& x.GetValue<VisibilityTracker[]>("_visibilityTrackers")?.Length != 0);
var trackers = Resources.FindObjectsOfTypeAll<VisibilityTracker>();
foreach (var tracker in trackers)
{
if (tracker.GetType() != typeof(ShapeVisibilityTracker))
{
continue;
}
var shapes = tracker.GetValue<Shape[]>("_shapes");
if (shapes == null)
{
continue;
}
_shapesToTrackers.Add(shapes, tracker);
var visibilityObject = visibilityObjects.FirstOrDefault(x => x.GetValue<VisibilityTracker[]>("_visibilityTrackers").Contains(tracker));
if (visibilityObject == null)
{
continue;
}
if (_objectToTrackers.ContainsKey(visibilityObject))
{
_objectToTrackers[visibilityObject].Add(tracker);
}
else
{
_objectToTrackers.Add(
visibilityObject,
new List<VisibilityTracker>()
{
tracker
});
}
}
IsReady = true;
}
@ -73,76 +111,6 @@ namespace QSB.QuantumSync
}
}
public void OnGUI()
{
GUI.Label(new Rect(220, 10, 200f, 20f), $"HasWokenUp : {QSBCore.HasWokenUp}");
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode)
{
return;
}
if (QSBSceneManager.CurrentScene != OWScene.SolarSystem)
{
return;
}
var offset = 40f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Visible : {Locator.GetQuantumMoon().IsVisible()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Locked : {Locator.GetQuantumMoon().IsLocked()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Illuminated : {Locator.GetQuantumMoon().IsIlluminated()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"Shrine player in dark? : {Shrine.IsPlayerInDarkness()}");
offset += 30f;
var tracker = Locator.GetQuantumMoon().GetValue<ShapeVisibilityTracker>("_visibilityTracker");
foreach (var camera in QSBPlayerManager.GetPlayerCameras())
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- {camera.name} : {tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(tracker, new object[] { camera.GetFrustumPlanes() })}");
offset += 30f;
}
// Used for diagnosing specific socketed objects. Just set <index> to be the correct index.
/*
var index = 110;
var socketedObject = QSBWorldSync.GetWorldObject<QSBSocketedQuantumObject>(index);
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Controller : {socketedObject.ControllingPlayer}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Visible : {socketedObject.AttachedObject.IsVisible()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Locked : {socketedObject.AttachedObject.IsLocked()}");
offset += 30f;
GUI.Label(new Rect(220, offset, 200f, 20f), $"{index} Illuminated : {socketedObject.AttachedObject.IsIlluminated()}");
offset += 30f;
var socketedTrackers = socketedObject.AttachedObject.GetComponentsInChildren<ShapeVisibilityTracker>();
if (socketedTrackers == null || socketedTrackers.Length == 0)
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- List is null or empty.");
return;
}
if (socketedTrackers.Any(x => x is null))
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- Uses a null.");
return;
}
foreach (var camera in QSBPlayerManager.GetPlayerCameras())
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"- {camera.name} : {socketedTrackers.Any(x => (bool)x.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(x, new object[] { camera.GetFrustumPlanes() }))}");
offset += 30f;
}
*/
offset = 10f;
GUI.Label(new Rect(440, offset, 200f, 20f), $"Owned Objects :");
offset += 30f;
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().Where(x => x.ControllingPlayer == QSBPlayerManager.LocalPlayerId))
{
GUI.Label(new Rect(440, offset, 200f, 20f), $"- {(obj as IWorldObject).Name}");
offset += 30f;
}
}
public static bool IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
return tracker.gameObject.activeInHierarchy

View File

@ -4,5 +4,8 @@
{
uint ControllingPlayer { get; set; }
bool IsEnabled { get; set; }
void Enable();
void Disable();
}
}

View File

@ -1,9 +1,6 @@
using OWML.Utils;
using QSB.Events;
using QSB.Events;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
namespace QSB.QuantumSync.WorldObjects
@ -14,26 +11,9 @@ namespace QSB.QuantumSync.WorldObjects
public uint ControllingPlayer { get; set; }
public bool IsEnabled { get; set; }
private OnEnableDisableTracker _tracker;
public override void Init(T attachedObject, int id) => ControllingPlayer = 0u;
public override void OnRemoval()
{
_tracker.OnEnableEvent -= OnEnable;
_tracker.OnDisableEvent -= OnDisable;
Object.Destroy(_tracker);
}
public override void Init(T attachedObject, int id)
{
_tracker = QSBCore.GameObjectInstance.AddComponent<OnEnableDisableTracker>();
_tracker.AttachedComponent = AttachedObject;
_tracker.OnEnableEvent += OnEnable;
_tracker.OnDisableEvent += OnDisable;
ControllingPlayer = 0u;
}
private void OnEnable()
public void Enable()
{
IsEnabled = true;
if (!QSBCore.HasWokenUp && !QSBCore.IsServer)
@ -50,7 +30,7 @@ namespace QSB.QuantumSync.WorldObjects
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, id, QSBPlayerManager.LocalPlayerId);
}
private void OnDisable()
public void Disable()
{
IsEnabled = false;
if (!QSBCore.HasWokenUp && !QSBCore.IsServer)

View File

@ -1,58 +0,0 @@
using OWML.Utils;
using System;
using System.Linq;
using UnityEngine;
namespace QSB.Utility
{
public class OnEnableDisableTracker : MonoBehaviour
{
public event Action OnEnableEvent;
public event Action OnDisableEvent;
public MonoBehaviour AttachedComponent;
private ComponentState _wasEnabled = ComponentState.NotChecked;
public OnEnableDisableTracker()
=> QSBSceneManager.OnSceneLoaded += (OWScene scene, bool inUniverse) => Destroy(this);
private void OnDestroy()
=> QSBSceneManager.OnSceneLoaded -= (OWScene scene, bool inUniverse) => Destroy(this);
private bool GetAnyVisibilityTrackersActive()
{
var visibilityTrackers = AttachedComponent.GetValue<VisibilityTracker[]>("_visibilityTrackers");
return visibilityTrackers.All(x => x.GetValue<Shape[]>("_shapes").All(y => y.enabled));
}
private void Update()
{
if (AttachedComponent == null)
{
DebugLog.ToConsole($"Attached component is null!", OWML.Common.MessageType.Error);
return;
}
var state = AttachedComponent.isActiveAndEnabled && GetAnyVisibilityTrackersActive() ? ComponentState.Enabled : ComponentState.Disabled;
if (_wasEnabled != state)
{
_wasEnabled = state;
if (state == ComponentState.Enabled)
{
OnEnableEvent?.SafeInvoke();
}
else
{
OnDisableEvent?.SafeInvoke();
}
}
}
}
internal enum ComponentState
{
NotChecked = 0,
Enabled = 1,
Disabled = 2
}
}

View File

@ -32,6 +32,11 @@ namespace QSB.WorldSync
where TUnityObject : MonoBehaviour
{
var allWorldObjects = GetWorldObjects<TWorldObject>();
if (allWorldObjects.Count() == 0)
{
DebugLog.ToConsole($"Error - No worldobjects exist of type {typeof(TWorldObject).Name}!", MessageType.Error);
return null;
}
var correctWorldObject = allWorldObjects.First(x => x.AttachedObject == unityObject);
return correctWorldObject;
}