Skip to content

Commit

Permalink
SafeSerialize
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicAglialoro committed Sep 24, 2022
1 parent 8f4f60d commit dba4641
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 120 deletions.
34 changes: 12 additions & 22 deletions SRXDCustomVisuals.Core/Element/VisualElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,30 @@ public class VisualElement : MonoBehaviour, ISerializationCallbackReceiver {
[SerializeField] private VisualElementEvent[] events;
[SerializeField] private VisualElementProperty[] properties;

[SerializeField, HideInInspector] private List<VisualsController> events_visualsControllers;
[SerializeField, HideInInspector] private string events_jData;
[SerializeField, HideInInspector] private List<VisualsController> events_visualsControllers = new();
[SerializeField, HideInInspector] private string events_jData = string.Empty;

[SerializeField, HideInInspector] private List<VisualsController> properties_visualsControllers;
[SerializeField, HideInInspector] private string properties_jData;
[SerializeField, HideInInspector] private List<VisualsController> properties_visualsControllers = new();
[SerializeField, HideInInspector] private string properties_jData = string.Empty;

internal VisualElementEvent[] Events => events;

internal VisualElementProperty[] Properties => properties;

public void OnBeforeSerialize() {
events ??= Array.Empty<VisualElementEvent>();
events_visualsControllers = new List<VisualsController>();
events_jData = JsonConvert.SerializeObject(events, new JsonSerializerSettings {
Converters = { new UnityObjectConverter<VisualsController>(events_visualsControllers) },
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

properties ??= Array.Empty<VisualElementProperty>();
properties_visualsControllers = new List<VisualsController>();
properties_jData = JsonConvert.SerializeObject(properties, new JsonSerializerSettings {
Converters = { new UnityObjectConverter<VisualsController>(properties_visualsControllers) },
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

events_visualsControllers.Clear();
properties_visualsControllers.Clear();

events_jData = SafeSerialize.Serialize(events, new UnityObjectConverter<VisualsController>(events_visualsControllers));
properties_jData = SafeSerialize.Serialize(properties, new UnityObjectConverter<VisualsController>(properties_visualsControllers));
}

public void OnAfterDeserialize() {
events_visualsControllers ??= new List<VisualsController>();
events_jData ??= string.Empty;
events ??= JsonConvert.DeserializeObject<VisualElementEvent[]>(events_jData, new UnityObjectConverter<VisualsController>(events_visualsControllers));

properties_visualsControllers ??= new List<VisualsController>();
properties_jData ??= string.Empty;
properties ??= JsonConvert.DeserializeObject<VisualElementProperty[]>(properties_jData, new UnityObjectConverter<VisualsController>(properties_visualsControllers));
events ??= SafeSerialize.Deserialize<VisualElementEvent[]>(events_jData, new UnityObjectConverter<VisualsController>(events_visualsControllers));
properties ??= SafeSerialize.Deserialize<VisualElementProperty[]>(properties_jData, new UnityObjectConverter<VisualsController>(properties_visualsControllers));
}

internal void InitControllers(IVisualsParams parameters, IVisualsResources resources) {
Expand Down
4 changes: 2 additions & 2 deletions SRXDCustomVisuals.Core/Element/VisualsEventMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace SRXDCustomVisuals.Core;

[Serializable]
public class VisualsEventMapping {
public string name;

public VisualsController target;

public string name;

public VisualsParamMapping[] parameters;
}
4 changes: 2 additions & 2 deletions SRXDCustomVisuals.Core/Element/VisualsPropertyMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ namespace SRXDCustomVisuals.Core;

[Serializable]
public class VisualsPropertyMapping {
public string name;

public VisualsController target;

public string name;

public VisualsParamType type;

public Vector4 scale = Vector4.one;
Expand Down
2 changes: 1 addition & 1 deletion SRXDCustomVisuals.Core/SRXDCustomVisuals.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@
<Compile Include="Scene\VisualsScene.cs" />
<Compile Include="Scene\VisualsSceneLoader.cs" />
<Compile Include="Scene\VisualsSceneManager.cs" />
<Compile Include="Util\SafeSerialize.cs" />
<Compile Include="Util\UnityObjectConverter.cs" />
<Compile Include="Util\Util.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Value\VisualsValue.cs" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions SRXDCustomVisuals.Core/Scene/CompositeVisualsEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public MappingInvoker(VisualsEventMapping mapping) {

switch (parameterMapping.type) {
case VisualsParamType.Bool:
cachedParameters.SetBool(name, parameterMapping.scale.x > 0f);
cachedParameters.SetBool(name, parameterMapping.scale.x >= 0f);

continue;
case VisualsParamType.Int:
Expand Down Expand Up @@ -85,7 +85,7 @@ public void Invoke(IVisualsParams parameters) {

switch (parameterMapping.type) {
case VisualsParamType.Bool:
cachedParameters.SetBool(name, parameters.GetBool(parameter) == scale.x > 0f);
cachedParameters.SetBool(name, parameters.GetBool(parameter) == scale.x >= 0f);

continue;
case VisualsParamType.Int:
Expand Down
2 changes: 1 addition & 1 deletion SRXDCustomVisuals.Core/Scene/CompositeVisualsProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void Invoke(VisualsValue value) {

switch (mapping.type) {
case VisualsParamType.Bool:
visualsProperty.SetBool(value.Bool == scale.x > 0f || bias.x > 0f);
visualsProperty.SetBool(value.Bool == scale.x >= 0f);

break;
case VisualsParamType.Int:
Expand Down
78 changes: 78 additions & 0 deletions SRXDCustomVisuals.Core/Util/SafeSerialize.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using UnityEngine;

namespace SRXDCustomVisuals.Core;

public static class SafeSerialize {
public static T Deserialize<T>(string jData, params JsonConverter[] converters)
=> JsonConvert.DeserializeObject<T>(jData ?? string.Empty, new JsonSerializerSettings {
Converters = converters,
ContractResolver = UnitySerializationContractResolver.Instance,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

public static string Serialize(object obj, params JsonConverter[] converters)
=> JsonConvert.SerializeObject(obj, new JsonSerializerSettings {
Converters = converters,
ContractResolver = UnitySerializationContractResolver.Instance,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

private class UnitySerializationContractResolver : DefaultContractResolver {
public static UnitySerializationContractResolver Instance { get; } = new();

protected override List<MemberInfo> GetSerializableMembers(Type objectType) {
var memberInfo = new List<MemberInfo>();

foreach (var fieldInfo in objectType.GetFields()) {
if (IsSerializable(fieldInfo))
memberInfo.Add(fieldInfo);
}

return memberInfo;
}

private static bool IsSerializable(FieldInfo fieldInfo) {
if (fieldInfo.IsStatic || fieldInfo.IsLiteral || fieldInfo.IsInitOnly || fieldInfo.IsNotSerialized)
return false;

bool hasSerializeField = false;

foreach (var attribute in fieldInfo.GetCustomAttributes()) {
switch (attribute) {
case SerializeField:
hasSerializeField = true;
continue;
case NonSerializedAttribute:
return false;
}
}

return (hasSerializeField || fieldInfo.IsPublic) && IsSerializableType(fieldInfo.FieldType);
}

private static bool IsSerializableType(Type type) {
while (true) {
if (type == null)
return false;

if (type == typeof(Array)) {
type = type.GetElementType();
continue;
}

if (!type.IsGenericType)
return true;

if (type.GetGenericTypeDefinition() != typeof(List<>))
return false;

type = type.GenericTypeArguments[0];
}
}
}
}
6 changes: 3 additions & 3 deletions SRXDCustomVisuals.Core/Util/UnityObjectConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
using Newtonsoft.Json;
using Object = UnityEngine.Object;

namespace SRXDCustomVisuals.Core;
namespace SRXDCustomVisuals.Core;

public class UnityObjectConverter<T> : JsonConverter<T> where T : Object {
private List<T> objects;

public UnityObjectConverter(List<T> objects) => this.objects = objects;

public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer) {
writer.WriteValue(objects.Count);
writer.WriteValue((long) objects.Count);
objects.Add(value);
}

public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer) {
if (reader.Value is not long asLong)
if (reader.Value is not long asLong || asLong < 0 || asLong >= objects.Count)
return null;

return objects[(int) asLong];
Expand Down
78 changes: 0 additions & 78 deletions SRXDCustomVisuals.Core/Util/Util.cs

This file was deleted.

37 changes: 28 additions & 9 deletions SRXDCustomVisuals.Plugin/Patches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,29 +116,48 @@ private static bool TryGetSceneLoader(string name, out VisualsSceneLoader sceneL
foreach (string bundleName in backgroundDefinition.AssetBundles) {
if (AssetBundleUtility.TryGetAssetBundle(ASSET_BUNDLES_PATH, bundleName, out var bundle))
assetBundles.Add(bundleName, bundle);
else
else {
Plugin.Logger.LogWarning($"Could not load asset bundle {bundleName}");
success = false;
}
}

foreach (string assembly in backgroundDefinition.Assemblies) {
if (!Util.TryLoadAssembly(assembly))
success = false;
if (Util.TryLoadAssembly(assembly))
continue;

Plugin.Logger.LogWarning($"Could not load assembly {assembly}");
success = false;
}

if (!success)
return false;

foreach (var moduleReference in backgroundDefinition.Modules) {
if (assetBundles.TryGetValue(moduleReference.Bundle, out var bundle)) {
var module = bundle.LoadAsset<VisualsModule>(moduleReference.Asset);
if (!assetBundles.TryGetValue(moduleReference.Bundle, out var bundle)) {
Plugin.Logger.LogWarning($"Could not find asset bundle {moduleReference.Bundle}");
success = false;

continue;
}

if (module != null)
modules.Add(module);
if (!bundle.Contains(moduleReference.Asset)) {
Plugin.Logger.LogWarning($"Could not find module {moduleReference.Asset} in bundle {moduleReference.Bundle}");
success = false;

continue;
}
else {
Plugin.Logger.LogWarning($"Could not find asset bundle {moduleReference.Bundle}");

var module = bundle.LoadAsset<VisualsModule>(moduleReference.Asset);

if (module == null) {
Plugin.Logger.LogWarning($"Asset {moduleReference.Asset} in bundle {moduleReference.Bundle} is not a module");
success = false;

continue;
}

modules.Add(module);
}

if (!success)
Expand Down

0 comments on commit dba4641

Please sign in to comment.