72 lines
2.7 KiB
C#
72 lines
2.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace VF.Model {
|
|
public abstract class VRCFuryComponent : MonoBehaviour, ISerializationCallbackReceiver {
|
|
private static readonly int VRCFURY_SER_VERSION = 7;
|
|
private static readonly HashSet<string> attemptedReload = new HashSet<string>();
|
|
|
|
public int vrcfSerVersion;
|
|
[NonSerialized]
|
|
public bool failedToLoad = false;
|
|
|
|
public bool IsBroken() {
|
|
return vrcfSerVersion > VRCFURY_SER_VERSION || ContainsNullsInList(this);
|
|
}
|
|
|
|
public virtual void OnAfterDeserialize() {
|
|
if (IsBroken()) {
|
|
failedToLoad = true;
|
|
#if UNITY_EDITOR
|
|
EditorApplication.delayCall += () => {
|
|
var path = AssetDatabase.GetAssetPath(this);
|
|
if (!string.IsNullOrWhiteSpace(path) && !attemptedReload.Contains(path)) {
|
|
//Debug.LogError("VRCFury is triggering manual reload of asset " + path + " (previous import corrupted)");
|
|
Debug.LogWarning(
|
|
$"VRCFury detected VRCFury component in asset at path ${path} is corrupted. " +
|
|
"Hopefully it will be fixed during the prefab import auto-fix.");
|
|
attemptedReload.Add(path);
|
|
//AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);
|
|
}
|
|
};
|
|
#endif
|
|
} else {
|
|
vrcfSerVersion = VRCFURY_SER_VERSION;
|
|
failedToLoad = false;
|
|
}
|
|
}
|
|
|
|
public virtual void OnBeforeSerialize() {
|
|
}
|
|
|
|
private static bool ContainsNullsInList(object obj) {
|
|
if (obj == null) return false;
|
|
var objType = obj.GetType();
|
|
if (!objType.FullName.StartsWith("VF")) return false;
|
|
var fields = objType.GetFields();
|
|
foreach (var field in fields) {
|
|
var value = field.GetValue(obj);
|
|
if (value is IList) {
|
|
var list = value as IList;
|
|
var isRef = field.GetCustomAttribute<SerializeReference>() != null;
|
|
foreach (var t in list) {
|
|
if (t == null && isRef) return true;
|
|
if (ContainsNullsInList(t)) return true;
|
|
}
|
|
} else {
|
|
var type = field.FieldType;
|
|
if (type.IsClass) {
|
|
if (ContainsNullsInList(value)) return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|