diff --git a/.csc.rsp.nullsafe b/.csc.rsp.nullsafe new file mode 100644 index 000000000..9a26da866 --- /dev/null +++ b/.csc.rsp.nullsafe @@ -0,0 +1,5 @@ +#"Shared csc.rsp file with null safe. origin is at .csc.rsp.nullsafe and symlinked to each assemblies of AAO" +-langversion:10 +#"PUBLISH DELETE MARKER // lines below are only for development to reduce unexpected compile errors" +-warnaserror:nullable +-nullable:enable diff --git a/.csc.rsp.nullunsafe b/.csc.rsp.nullunsafe new file mode 100644 index 000000000..e55888f86 --- /dev/null +++ b/.csc.rsp.nullunsafe @@ -0,0 +1,4 @@ +#"Shared csc.rsp file with null unsafe. origin is at .csc.rsp.nullunsafe and symlinked to each assemblies of AAO" +-langversion:10 +#"PUBLISH DELETE MARKER // lines below are only for development to reduce unexpected compile errors" +-warnaserror:nullable diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8d413c00d..da21fbbc1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -169,6 +169,11 @@ jobs: sed -i'.bak' -e "s|${STABLE_URL}|${STABLE_URL}#${VERSION}|" package.json fi rm package.json.bak + + - name: update csc.rsp + run: | + sed -n '/PUBLISH DELETE MARKER/q;p' -i .csc.rsp.nullunsafe + sed -n '/PUBLISH DELETE MARKER/q;p' -i .csc.rsp.nullsafe # region vpm release - name: Build VPM release diff --git a/API-Editor/ComponentInformation.cs b/API-Editor/ComponentInformation.cs index f57805108..65230dd04 100644 --- a/API-Editor/ComponentInformation.cs +++ b/API-Editor/ComponentInformation.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using JetBrains.Annotations; @@ -30,7 +32,7 @@ public sealed class ComponentInformationAttribute : APIInternal.ComponentInforma [PublicAPI] public ComponentInformationAttribute(Type targetType) { - TargetType = targetType; + TargetType = targetType ?? throw new ArgumentNullException(nameof(targetType)); } internal override Type GetTargetType() => TargetType; @@ -167,7 +169,7 @@ internal ComponentDependencyCollector() /// The dependency /// The object to configure the dependency [PublicAPI] - public abstract ComponentDependencyInfo AddDependency(Component dependant, Component dependency); + public abstract ComponentDependencyInfo AddDependency(Component? dependant, Component? dependency); /// /// Adds as dependencies of current component. @@ -178,7 +180,7 @@ internal ComponentDependencyCollector() /// The dependency /// The object to configure the dependency [PublicAPI] - public abstract ComponentDependencyInfo AddDependency(Component dependency); + public abstract ComponentDependencyInfo AddDependency(Component? dependency); /// /// Adds relative path from to as dependencies of current component. @@ -223,7 +225,7 @@ internal ComponentDependencyCollector() /// The GameObject the relative path starts from /// If the is not child of . [PublicAPI] - public abstract PathDependencyInfo AddPathDependency([NotNull] Transform dependency, [NotNull] Transform root); + public abstract PathDependencyInfo AddPathDependency(Transform dependency, Transform root); // TODO: rename to better name and make public // NOTE for external users: this is API Proposal to compute value of animatable bool property @@ -309,13 +311,11 @@ internal ComponentMutationsCollector() /// The component current component will modifies /// The list of properties current component will modifies [PublicAPI] - public abstract void ModifyProperties([NotNull] Component component, - [NotNull] [ItemNotNull] IEnumerable properties); + public abstract void ModifyProperties(Component component, IEnumerable properties); /// [PublicAPI] - public void ModifyProperties([NotNull] Component component, - [NotNull] [ItemNotNull] params string[] properties) => + public void ModifyProperties(Component component, params string[] properties) => ModifyProperties(component, (IEnumerable)properties); } @@ -370,7 +370,7 @@ internal MappedComponentInfo() /// to animation property, for example, blendShape related SkinnedMeshRenderer. /// [PublicAPI] - public abstract T MappedComponent { get; } + public abstract T? MappedComponent { get; } /// /// Maps animation property name to component and MappedPropertyInfo. diff --git a/API-Editor/Internal/InternalParts.cs b/API-Editor/Internal/InternalParts.cs index 9b063a963..54686a3e5 100644 --- a/API-Editor/Internal/InternalParts.cs +++ b/API-Editor/Internal/InternalParts.cs @@ -1,6 +1,7 @@ +#nullable enable + using System; using Anatawa12.AvatarOptimizer.API; -using JetBrains.Annotations; using UnityEngine; namespace Anatawa12.AvatarOptimizer.APIInternal @@ -8,7 +9,7 @@ namespace Anatawa12.AvatarOptimizer.APIInternal public abstract class ComponentInformationAttributeBase : Attribute { internal ComponentInformationAttributeBase() { } - [CanBeNull] internal abstract Type GetTargetType(); + internal abstract Type? GetTargetType(); } /// @@ -33,4 +34,4 @@ internal ComponentInformation() internal class AllowInheritAttribute : Attribute { } -} \ No newline at end of file +} diff --git a/Editor/.MergePhysBoneEditorModificationUtils.ts b/Editor/.MergePhysBoneEditorModificationUtils.ts index dbae92fa7..8174d252f 100644 --- a/Editor/.MergePhysBoneEditorModificationUtils.ts +++ b/Editor/.MergePhysBoneEditorModificationUtils.ts @@ -43,7 +43,8 @@ const config: Config = { } satisfies Config; console.log("// ") -console.log("// generated by .MergePhysBoneEditorModificationUtils.ts") +console.log("#nullable enable") +console.log("") console.log("#if AAO_VRCSDK3_AVATARS") console.log("") console.log("using System.Collections.Generic;") @@ -59,14 +60,14 @@ for (let [type, info] of Object.entries(config)) { console.log(` {`) for (let [value] of info.values) { console.log(` public readonly SerializedProperty Override${value};`) - console.log(` public SerializedProperty Source${value} { get; private set; }`) + console.log(` public SerializedProperty? Source${value} { get; private set; }`) console.log(` public readonly string PhysBone${value}Name;`) } console.log(``) console.log(` public ${type}(`) - console.log(` [NotNull] SerializedProperty rootProperty`) + console.log(` SerializedProperty rootProperty`) for (let [value] of info.values) { - console.log(` , [NotNull] string physBone${value}Name`) + console.log(` , string physBone${value}Name`) } console.log(` ) : base(rootProperty)`) console.log(` {`) @@ -83,7 +84,7 @@ for (let [type, info] of Object.entries(config)) { } console.log(` }`) for (let [value] of info.values) { - console.log(` public SerializedProperty Get${value}Property(bool @override) => @override ? Override${value} : Source${value};`) + console.log(` public SerializedProperty Get${value}Property(bool @override) => @override ? Override${value} : Source${value}!;`) } console.log(` }`) } diff --git a/Editor/APIInternal/ComponentInfoRegistry.cs b/Editor/APIInternal/ComponentInfoRegistry.cs index 951d31f0a..0c8ffd86b 100644 --- a/Editor/APIInternal/ComponentInfoRegistry.cs +++ b/Editor/APIInternal/ComponentInfoRegistry.cs @@ -8,8 +8,7 @@ namespace Anatawa12.AvatarOptimizer.APIInternal { internal static class ComponentInfoRegistry { - private static readonly Dictionary InformationByType = - new Dictionary(); + private static readonly Dictionary InformationByType = new(); [InitializeOnLoadMethod] static void FindAllInfoImplements() @@ -107,7 +106,7 @@ internal static bool TryGetInformation(Type type, out ComponentInformation infor return false; } - private static HashSet _meaninglessTypes; + private static HashSet? _meaninglessTypes; public static void InvalidateCache() => _meaninglessTypes = null; @@ -128,7 +127,7 @@ private static bool IsMeaninglessType(Type type) class MeaninglessComponentInformation : ComponentInformation { - public static MeaninglessComponentInformation Instance { get; } = new MeaninglessComponentInformation(); + public static MeaninglessComponentInformation Instance { get; } = new(); private MeaninglessComponentInformation() { diff --git a/Editor/APIInternal/ComponentInformationWithGUIDAttribute.cs b/Editor/APIInternal/ComponentInformationWithGUIDAttribute.cs index b9bfcc8fe..ca3a084c7 100644 --- a/Editor/APIInternal/ComponentInformationWithGUIDAttribute.cs +++ b/Editor/APIInternal/ComponentInformationWithGUIDAttribute.cs @@ -19,12 +19,12 @@ public ComponentInformationWithGUIDAttribute(string guid, int fileID) FileID = fileID; } - internal override Type GetTargetType() + internal override Type? GetTargetType() { if (!GlobalObjectId.TryParse($"GlobalObjectId_V1-{1}-{Guid}-{(uint)FileID}-{0}", out var id)) return null; var script = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(id) as MonoScript; - if (!script) return null; + if (script == null) return null; return script.GetClass(); } } -} \ No newline at end of file +} diff --git a/Editor/APIInternal/ComponentInfos.DynamicBone.cs b/Editor/APIInternal/ComponentInfos.DynamicBone.cs index 7e28e80ea..450228e42 100644 --- a/Editor/APIInternal/ComponentInfos.DynamicBone.cs +++ b/Editor/APIInternal/ComponentInfos.DynamicBone.cs @@ -58,4 +58,4 @@ protected override void CollectDependency(Component component, ComponentDependen { } } -} \ No newline at end of file +} diff --git a/Editor/APIInternal/ComponentInfos.VRCSDK.cs b/Editor/APIInternal/ComponentInfos.VRCSDK.cs index 704591bf8..4ade32523 100644 --- a/Editor/APIInternal/ComponentInfos.VRCSDK.cs +++ b/Editor/APIInternal/ComponentInfos.VRCSDK.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.API; -using JetBrains.Annotations; using nadena.dev.ndmf.runtime; using UnityEngine; using VRC.SDK3; @@ -14,10 +13,8 @@ using VRC.SDK3.Dynamics.PhysBone.Components; using VRC.SDKBase; -#if AAO_VRCSDK3_AVATARS_CONSTRAINTS using VRC.Dynamics.ManagedTypes; using VRC.SDK3.Dynamics.Constraint.Components; -#endif namespace Anatawa12.AvatarOptimizer.APIInternal.VRCSDK { @@ -162,7 +159,6 @@ protected override void ApplySpecialMapping(T component, MappingSource mappingSo } } - [NotNull] private static string ParseBlendShapeProperty(string prop) => prop.StartsWith("blendShape.", StringComparison.Ordinal) ? prop.Substring("blendShape.".Length) @@ -472,7 +468,6 @@ protected override void CollectDependency(VRCImpostorSettings component, Compone } } -#if AAO_VRCSDK3_AVATARS_IMPOSTER_SETTINGS // this component has no documentation so this implementation is based on assumption [ComponentInformation(typeof(VRCImpostorEnvironment))] internal class VRCImpostorEnvironmentInformation : ComponentInformation @@ -483,9 +478,7 @@ protected override void CollectDependency(VRCImpostorEnvironment component, Comp collector.MarkEntrypoint(); } } -#endif -#if AAO_VRCSDK3_AVATARS_HEAD_CHOP [ComponentInformation(typeof(VRCHeadChop))] internal class VRCHeadChopInformation : ComponentInformation { @@ -501,9 +494,7 @@ protected override void CollectDependency(VRCHeadChop component, ComponentDepend collector.MarkBehaviour(); } } -#endif -#if AAO_VRCSDK3_AVATARS_CONSTRAINTS [ComponentInformation(typeof(VRCConstraintBase))] [ComponentInformation(typeof(VRCParentConstraintBase))] [ComponentInformation(typeof(VRCParentConstraint))] @@ -548,7 +539,5 @@ protected override void CollectDependency(VRCWorldUpConstraintBase component, Co collector.AddDependency(component.WorldUpTransform); } } - -#endif } #endif diff --git a/Editor/APIInternal/ComponentInfos.VRM0.cs b/Editor/APIInternal/ComponentInfos.VRM0.cs index ffa182461..6aa955d08 100644 --- a/Editor/APIInternal/ComponentInfos.VRM0.cs +++ b/Editor/APIInternal/ComponentInfos.VRM0.cs @@ -151,4 +151,4 @@ protected override void ApplySpecialMapping(VRMFirstPerson component, MappingSou } } -#endif \ No newline at end of file +#endif diff --git a/Editor/APIInternal/ComponentInfos.VRM1.cs b/Editor/APIInternal/ComponentInfos.VRM1.cs index 5d1533df5..c0dfb22a6 100644 --- a/Editor/APIInternal/ComponentInfos.VRM1.cs +++ b/Editor/APIInternal/ComponentInfos.VRM1.cs @@ -76,14 +76,14 @@ protected override void CollectMutations(Vrm10Instance component, ComponentMutat } } - Transform GetBoneTransformForVrm10(Vrm10Instance component, HumanBodyBones bones) + Transform? GetBoneTransformForVrm10(Vrm10Instance component, HumanBodyBones bones) { - if (component.GetComponent() is Humanoid avatarHumanoid) + if (component.GetComponent() is { } avatarHumanoid) { return avatarHumanoid.GetBoneTransform(bones); } - if (component.GetComponent() is Animator avatarAnimator) + if (component.GetComponent() is { } avatarAnimator) { return avatarAnimator.GetBoneTransform(bones); } @@ -180,4 +180,4 @@ protected override void CollectDependency(Humanoid component, ComponentDependenc } -#endif \ No newline at end of file +#endif diff --git a/Editor/APIInternal/ComponentInfos.cs b/Editor/APIInternal/ComponentInfos.cs index fb4283ab8..f0e0b9dc1 100644 --- a/Editor/APIInternal/ComponentInfos.cs +++ b/Editor/APIInternal/ComponentInfos.cs @@ -178,11 +178,7 @@ protected override void CollectDependency(ParticleSystem component, ComponentDep switch (component.collision.type) // not animated { case ParticleSystemCollisionType.Planes: -#if UNITY_2020_2_OR_NEWER for (var i = 0; i < component.collision.planeCount; i++) -#else - for (var i = 0; i < component.collision.maxPlaneCount; i++) -#endif collector.AddDependency(component.collision.GetPlane(i)); break; case ParticleSystemCollisionType.World: @@ -193,11 +189,7 @@ protected override void CollectDependency(ParticleSystem component, ComponentDep if (collector.GetAnimatedFlag(component, "TriggerModule.enabled", component.trigger.enabled) != false) { -#if UNITY_2020_2_OR_NEWER for (var i = 0; i < component.trigger.colliderCount; i++) -#else - for (var i = 0; i < component.trigger.maxColliderCount; i++) -#endif { var collider = component.trigger.GetCollider(i); if (!collider) continue; diff --git a/Editor/AnimatorParserV2/AnimationParser.cs b/Editor/AnimatorParserV2/AnimationParser.cs index c895381bd..cbaf2ec8e 100644 --- a/Editor/AnimatorParserV2/AnimationParser.cs +++ b/Editor/AnimatorParserV2/AnimationParser.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; @@ -12,15 +11,15 @@ namespace Anatawa12.AvatarOptimizer.AnimatorParsersV2 { class AnimationParser { - internal ImmutableNodeContainer ParseMotion([NotNull] GameObject root, [CanBeNull] Motion motion, - [NotNull] IReadOnlyDictionary mapping) + internal ImmutableNodeContainer ParseMotion(GameObject root, Motion? motion, + IReadOnlyDictionary mapping) { using (ErrorReport.WithContextObject(motion)) return ParseMotionInner(root, motion, mapping); } - private ImmutableNodeContainer ParseMotionInner([NotNull] GameObject root, [CanBeNull] Motion motion, - [NotNull] IReadOnlyDictionary mapping) + private ImmutableNodeContainer ParseMotionInner(GameObject root, Motion? motion, + IReadOnlyDictionary mapping) { switch (motion) { @@ -74,7 +73,7 @@ public BlendTreeMergeProperty(BlendTreeType blendType) _blendType = blendType; } - public ImmutableNodeContainer CreateContainer() => new ImmutableNodeContainer(); + public ImmutableNodeContainer CreateContainer() => new(); public ImmutableNodeContainer GetContainer(ImmutableNodeContainer source) => source; public BlendTreeElement GetIntermediate(ImmutableNodeContainer source, @@ -90,10 +89,9 @@ public ImmutablePropModNode MergeNode(List> nod new BlendTreeNode(nodes, _blendType, partial: nodes.Count != sourceCount); } - [NotNull] private readonly Dictionary<(GameObject, AnimationClip), ImmutableNodeContainer> _parsedAnimationCache = - new Dictionary<(GameObject, AnimationClip), ImmutableNodeContainer>(); + private readonly Dictionary<(GameObject, AnimationClip), ImmutableNodeContainer> _parsedAnimationCache = new(); - internal ImmutableNodeContainer GetParsedAnimation([NotNull] GameObject root, [CanBeNull] AnimationClip clip) + internal ImmutableNodeContainer GetParsedAnimation(GameObject root, AnimationClip? clip) { if (clip == null) return new ImmutableNodeContainer(); if (!_parsedAnimationCache.TryGetValue((root, clip), out var parsed)) @@ -101,7 +99,7 @@ internal ImmutableNodeContainer GetParsedAnimation([NotNull] GameObject root, [C return parsed; } - public static ImmutableNodeContainer ParseAnimation([NotNull] GameObject root, [NotNull] AnimationClip clip) + public static ImmutableNodeContainer ParseAnimation(GameObject root, AnimationClip clip) { var nodes = new ImmutableNodeContainer(); diff --git a/Editor/AnimatorParserV2/AnimatorControllerPropModNode.cs b/Editor/AnimatorParserV2/AnimatorControllerPropModNode.cs index 8fdcc38ae..ec1a79e24 100644 --- a/Editor/AnimatorParserV2/AnimatorControllerPropModNode.cs +++ b/Editor/AnimatorParserV2/AnimatorControllerPropModNode.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor.Animations; using UnityEngine; @@ -10,7 +9,7 @@ namespace Anatawa12.AvatarOptimizer.AnimatorParsersV2 { class HumanoidAnimatorPropModNode : ComponentPropModNode { - public HumanoidAnimatorPropModNode([NotNull] Animator component) : base(component) + public HumanoidAnimatorPropModNode(Animator component) : base(component) { } @@ -19,6 +18,7 @@ public HumanoidAnimatorPropModNode([NotNull] Animator component) : base(componen } internal readonly struct PlayableLayerNodeInfo : ILayer + where T : notnull { public AnimatorWeightState Weight { get; } public AnimatorLayerBlendingMode BlendingMode { get; } @@ -28,7 +28,7 @@ public HumanoidAnimatorPropModNode([NotNull] Animator component) : base(componen IPropModNode ILayer.Node => Node; public PlayableLayerNodeInfo(AnimatorWeightState weight, AnimatorLayerBlendingMode blendingMode, - [NotNull] AnimatorControllerPropModNode node, int layerIndex) + AnimatorControllerPropModNode node, int layerIndex) { Weight = weight; BlendingMode = blendingMode; @@ -36,7 +36,7 @@ public PlayableLayerNodeInfo(AnimatorWeightState weight, AnimatorLayerBlendingMo Node = node; } - public PlayableLayerNodeInfo([NotNull] AnimatorControllerPropModNode node, int layerIndex) + public PlayableLayerNodeInfo(AnimatorControllerPropModNode node, int layerIndex) { Weight = AnimatorWeightState.AlwaysOne; BlendingMode = AnimatorLayerBlendingMode.Override; @@ -46,13 +46,12 @@ public PlayableLayerNodeInfo([NotNull] AnimatorControllerPropModNode node, in } class AnimatorPropModNode : ComponentPropModNode + where T : notnull { private readonly IEnumerable> _layersReversed; - public AnimatorPropModNode( - [NotNull] Animator component, - [NotNull] IEnumerable> layersReversed - ) : base(component) + public AnimatorPropModNode(Animator component,IEnumerable> layersReversed) + : base(component) { _layersReversed = layersReversed; @@ -77,6 +76,7 @@ [NotNull] IEnumerable> layersReversed } internal readonly struct AnimatorLayerNodeInfo : ILayer + where T : notnull { public AnimatorWeightState Weight { get; } public AnimatorLayerBlendingMode BlendingMode { get; } @@ -86,7 +86,7 @@ [NotNull] IEnumerable> layersReversed IPropModNode ILayer.Node => Node; public AnimatorLayerNodeInfo(AnimatorWeightState weight, AnimatorLayerBlendingMode blendingMode, - [NotNull] AnimatorLayerPropModNode node, int layerIndex) + AnimatorLayerPropModNode node, int layerIndex) { Weight = weight; BlendingMode = blendingMode; @@ -96,11 +96,11 @@ public AnimatorLayerNodeInfo(AnimatorWeightState weight, AnimatorLayerBlendingMo } class AnimatorControllerPropModNode : PropModNode + where T : notnull { private readonly IEnumerable> _layersReversed; - [CanBeNull] - public static AnimatorControllerPropModNode Create([NotNull] List> value) + public static AnimatorControllerPropModNode? Create(List> value) { if (value.Count == 0) return null; if (value.All(x => x.BlendingMode == AnimatorLayerBlendingMode.Additive && x.Node.Value.IsConstant)) @@ -134,6 +134,7 @@ internal enum AnimatorWeightState } internal class AnimatorLayerPropModNode : ImmutablePropModNode + where T : notnull { private readonly IEnumerable> _children; private readonly bool _partial; @@ -155,6 +156,7 @@ public AnimatorLayerPropModNode(IEnumerable> childre } internal class AnimatorStatePropModNode : ImmutablePropModNode + where T : notnull { private readonly ImmutablePropModNode _node; private readonly AnimatorState _state; @@ -171,4 +173,4 @@ public AnimatorStatePropModNode(ImmutablePropModNode node, AnimatorState stat public override ValueInfo Value => _node.Value; public override IEnumerable ContextReferences => _node.ContextReferences; } -} \ No newline at end of file +} diff --git a/Editor/AnimatorParserV2/AnimatorParser.cs b/Editor/AnimatorParserV2/AnimatorParser.cs index c733ea8ca..376f963a9 100644 --- a/Editor/AnimatorParserV2/AnimatorParser.cs +++ b/Editor/AnimatorParserV2/AnimatorParser.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Anatawa12.AvatarOptimizer.API; using Anatawa12.AvatarOptimizer.APIInternal; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor.Animations; using UnityEngine; @@ -25,7 +25,7 @@ public AnimatorParser(bool mmdWorldCompatibility) _mmdWorldCompatibility = mmdWorldCompatibility; } - public RootPropModNodeContainer GatherAnimationModifications([NotNull] BuildContext context) + public RootPropModNodeContainer GatherAnimationModifications(BuildContext context) { var rootNode = new RootPropModNodeContainer(); @@ -129,15 +129,15 @@ private class Collector : ComponentMutationsCollector private readonly RootPropModNodeContainer _modifications; public Collector(RootPropModNodeContainer modifications) => _modifications = modifications; - public Component Modifier { get; set; } + public Component? Modifier { get; set; } public override void ModifyProperties(Component component, IEnumerable properties) { foreach (var prop in properties) { - _modifications.Add(component, prop, new VariableComponentPropModNode(Modifier), true); - _modifications.Add(component, prop, new VariableComponentPropModNode(Modifier), true); + _modifications.Add(component, prop, new VariableComponentPropModNode(Modifier!), true); + _modifications.Add(component, prop, new VariableComponentPropModNode(Modifier!), true); } } } @@ -163,8 +163,8 @@ private static void OtherMutateComponents(RootPropModNodeContainer mod, BuildCon #region Avatar Root Animator - private void CollectAvatarRootAnimatorModifications([NotNull] BuildContext session, - [NotNull] RootPropModNodeContainer modifications) + private void CollectAvatarRootAnimatorModifications(BuildContext session, + RootPropModNodeContainer modifications) { var animator = session.AvatarRootObject.GetComponent(); if (animator) @@ -190,8 +190,8 @@ private void CollectAvatarRootAnimatorModifications([NotNull] BuildContext sessi } #if AAO_VRCSDK3_AVATARS - private void CollectAvatarDescriptorModifications([NotNull] RootPropModNodeContainer modifications, - [NotNull] VRCAvatarDescriptor descriptor) + private void CollectAvatarDescriptorModifications(RootPropModNodeContainer modifications, + VRCAvatarDescriptor descriptor) { // process playable layers // see https://misskey.niri.la/notes/9ioemawdit @@ -209,7 +209,7 @@ private void CollectAvatarDescriptorModifications([NotNull] RootPropModNodeConta // load controllers var controllers = new AnimatorLayerMap(); foreach (var layer in descriptor.specialAnimationLayers.Concat(descriptor.baseAnimationLayers)) - controllers[layer.type] = GetPlayableLayerController(layer, useDefaultLayers); + controllers[layer.type] = GetPlayableLayerController(layer, useDefaultLayers)!; // parse weight changes var animatorLayerWeightChanged = new AnimatorLayerMap(); @@ -240,7 +240,7 @@ private void CollectAvatarDescriptorModifications([NotNull] RootPropModNodeConta } var playableLayers = - new List<(AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer)>(); + new List<(AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?)>(); void MergeLayer( VRCAvatarDescriptor.AnimLayerType type, @@ -274,13 +274,14 @@ void MergeLayer( MergeLayer(VRCAvatarDescriptor.AnimLayerType.Action, false, 0); MergeLayer(VRCAvatarDescriptor.AnimLayerType.FX, false, 1); - modifications.Add(NodesMerger.ComponentFromPlayableLayers(animator, playableLayers), true); + if (animator != null) + modifications.Add(NodesMerger.ComponentFromPlayableLayers(animator, playableLayers), true); // TPose and IKPose should only affect to Humanoid so skip here~ var bodySkinnedMesh = descriptor.transform.Find("Body")?.GetComponent(); - if (_mmdWorldCompatibility && bodySkinnedMesh) + if (_mmdWorldCompatibility && bodySkinnedMesh != null) { foreach (var shape in MmdBlendShapeNames) modifications.Add(bodySkinnedMesh, $"blendShape.{shape}", @@ -288,8 +289,7 @@ void MergeLayer( } } - [CanBeNull] - private static RuntimeAnimatorController GetPlayableLayerController(VRCAvatarDescriptor.CustomAnimLayer layer, + private static RuntimeAnimatorController? GetPlayableLayerController(VRCAvatarDescriptor.CustomAnimLayer layer, bool useDefault = false) { if (!useDefault && !layer.isDefault && layer.animatorController) @@ -307,9 +307,8 @@ private static RuntimeAnimatorController GetPlayableLayerController(VRCAvatarDes #endif #if AAO_VRM0 - [NotNull] - private static ComponentNodeContainer CollectBlendShapeProxyModifications([NotNull] BuildContext context, - [NotNull] VRM.VRMBlendShapeProxy vrmBlendShapeProxy) + private static ComponentNodeContainer CollectBlendShapeProxyModifications(BuildContext context, + VRM.VRMBlendShapeProxy vrmBlendShapeProxy) { var nodes = new ComponentNodeContainer(); @@ -333,9 +332,8 @@ private static ComponentNodeContainer CollectBlendShapeProxyModifications([NotNu #endif #if AAO_VRM1 - [NotNull] - private static ComponentNodeContainer CollectVrm10InstanceModifications([NotNull] BuildContext context, - [NotNull] UniVRM10.Vrm10Instance vrm10Instance) + private static ComponentNodeContainer CollectVrm10InstanceModifications( BuildContext context, + UniVRM10.Vrm10Instance vrm10Instance) { var nodes = new ComponentNodeContainer(); @@ -363,9 +361,8 @@ private static ComponentNodeContainer CollectVrm10InstanceModifications([NotNull #region Animator /// Mark rotations of humanoid bones as changeable variables - [CanBeNull] - private ComponentNodeContainer AddHumanoidModifications([CanBeNull] ComponentNodeContainer container, - [NotNull] Animator animator) + [return:NotNullIfNotNull("container")] + private ComponentNodeContainer? AddHumanoidModifications(ComponentNodeContainer? container, Animator animator) { // if it's not humanoid, this pass doesn't matter if (!animator.isHuman) return container; @@ -385,11 +382,10 @@ private ComponentNodeContainer AddHumanoidModifications([CanBeNull] ComponentNod return container; } - [CanBeNull] public AnimatorControllerNodeContainer ParseAnimatorController( - [NotNull] GameObject root, - [NotNull] RuntimeAnimatorController controller, - [CanBeNull] AnimatorWeightChangesList externallyWeightChanged = null) + GameObject root, + RuntimeAnimatorController controller, + AnimatorWeightChangesList? externallyWeightChanged = null) { using (ErrorReport.WithContextObject(controller)) { @@ -398,12 +394,11 @@ public AnimatorControllerNodeContainer ParseAnimatorController( } } - [CanBeNull] internal AnimatorControllerNodeContainer AdvancedParseAnimatorController( - [NotNull] GameObject root, - [NotNull] AnimatorController controller, - [NotNull] IReadOnlyDictionary mapping, - [CanBeNull] AnimatorWeightChangesList externallyWeightChanged) + GameObject root, + AnimatorController controller, + IReadOnlyDictionary mapping, + AnimatorWeightChangesList? externallyWeightChanged) { var layers = controller.layers; return NodesMerger.AnimatorControllerFromAnimatorLayers(controller.layers.Select((layer, i) => @@ -417,7 +412,7 @@ internal AnimatorControllerNodeContainer AdvancedParseAnimatorController( { var external = externallyWeightChanged?.Get(i) ?? AnimatorWeightChange.NotChanged; - if (!(GetWeightState(layers[i].defaultWeight, external) is AnimatorWeightState parsed)) + if (GetWeightState(layers[i].defaultWeight, external) is not { } parsed) return (default, default, null); // skip weight zero layer weightState = parsed; @@ -425,15 +420,14 @@ internal AnimatorControllerNodeContainer AdvancedParseAnimatorController( var parsedLayer = ParseAnimatorControllerLayer(root, controller, mapping, i); - return (weightState, layer.blendingMode, parsedLayer); + return (weightState, layer.blendingMode, (AnimatorLayerNodeContainer?)parsedLayer); })); } - [NotNull] public AnimatorLayerNodeContainer ParseAnimatorControllerLayer( - [NotNull] GameObject root, - [NotNull] AnimatorController controller, - [NotNull] IReadOnlyDictionary mapping, + GameObject root, + AnimatorController controller, + IReadOnlyDictionary mapping, int layerIndex) { var layer = controller.layers[layerIndex]; @@ -655,7 +649,7 @@ public AnimatorLayerPropModNode "瞳大", "頬染め", "青ざめ", - }.Where(x => x != null).Distinct().ToArray(); + }.Where(x => x != null).Distinct().ToArray()!; // removed null with Where // @formatter:on #endregion diff --git a/Editor/AnimatorParserV2/AnimatorParserDebugWindow.cs b/Editor/AnimatorParserV2/AnimatorParserDebugWindow.cs index 0de98910d..50677aac2 100644 --- a/Editor/AnimatorParserV2/AnimatorParserDebugWindow.cs +++ b/Editor/AnimatorParserV2/AnimatorParserDebugWindow.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Text; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEngine; @@ -15,15 +14,15 @@ internal class AnimatorParserDebugWindow : EditorWindow private static void Open() => GetWindow("AnimatorParser Debug Window V2"); public ParserSource parserSource; - public RuntimeAnimatorController animatorController; - public GameObject avatar; - public GameObject rootGameObject; - public Motion motion; + public RuntimeAnimatorController? animatorController; + public GameObject? avatar; + public GameObject? rootGameObject; + public Motion? motion; public Vector2 scrollView; - public GameObject parsedRootObject; - public INodeContainer Container; + public GameObject? parsedRootObject; + public INodeContainer? Container; private void OnGUI() { @@ -67,10 +66,10 @@ private void OnGUI() private string CreateText(bool detailed = false) { - var root = parsedRootObject.transform; + var root = parsedRootObject!.transform; var resultText = new StringBuilder(); - foreach (var group in Container.FloatNodes.GroupBy(x => x.Key.target)) + foreach (var group in Container!.FloatNodes.GroupBy(x => x.Key.target)) { var gameObject = group.Key.transform; resultText.Append(Utils.RelativePath(root, gameObject)).Append(": ") @@ -201,7 +200,7 @@ void OnParserSourceGUI() using (new EditorGUI.DisabledScope(!animatorController || !rootGameObject)) { - if (GUILayout.Button("Parse") && animatorController && rootGameObject) + if (GUILayout.Button("Parse") && animatorController != null && rootGameObject != null) { parsedRootObject = rootGameObject; Container = new AnimatorParser(true) @@ -216,7 +215,7 @@ void OnParserSourceGUI() using (new EditorGUI.DisabledScope(!motion)) { - if (GUILayout.Button("Parse") && motion && rootGameObject) + if (GUILayout.Button("Parse") && motion && rootGameObject != null) { parsedRootObject = rootGameObject; Container = new AnimationParser() @@ -230,7 +229,7 @@ void OnParserSourceGUI() } } - private static void ObjectField(ref T value, [CanBeNull] string label, bool allowScene) where T : Object + private static void ObjectField(ref T? value, string? label, bool allowScene) where T : Object { value = EditorGUILayout.ObjectField(label, value, typeof(T), allowScene) as T; } diff --git a/Editor/AnimatorParserV2/NodeContainer.cs b/Editor/AnimatorParserV2/NodeContainer.cs index 75b8311e4..9c284f360 100644 --- a/Editor/AnimatorParserV2/NodeContainer.cs +++ b/Editor/AnimatorParserV2/NodeContainer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEngine; using Object = UnityEngine.Object; @@ -39,7 +38,7 @@ internal class RootPropModNodeContainer : INodeContainer, public IReadOnlyDictionary<(ComponentOrGameObject target, string prop), RootPropModNode> ObjectNodes => _objectNodes; - public void Add([CanBeNull] ComponentNodeContainer container, bool alwaysApplied) + public void Add(ComponentNodeContainer? container, bool alwaysApplied) { if (container == null) return; @@ -99,24 +98,24 @@ internal class NodeContainerBase : INodeContainer> INodeContainer. ObjectNodes => Utils.CastDic>().CastedDic(_objectNodes); - public void Add(ComponentOrGameObject target, string prop, [NotNull] TFloatNode node) + public void Add(ComponentOrGameObject target, string prop, TFloatNode node) { if (node == null) throw new ArgumentNullException(nameof(node)); _floatNodes.Add((target, prop), node); } - public void Add(ComponentOrGameObject target, string prop, [NotNull] TObjectNode node) + public void Add(ComponentOrGameObject target, string prop, TObjectNode node) { if (node == null) throw new ArgumentNullException(nameof(node)); _objectNodes.Add((target, prop), node); } - public void Set(ComponentOrGameObject target, string prop, [NotNull] TFloatNode node) + public void Set(ComponentOrGameObject target, string prop, TFloatNode node) { _floatNodes[(target, prop)] = node ?? throw new ArgumentNullException(nameof(node)); } - public void Set(ComponentOrGameObject target, string prop, [NotNull] TObjectNode node) + public void Set(ComponentOrGameObject target, string prop, TObjectNode node) { if (node == null) throw new ArgumentNullException(nameof(node)); _objectNodes[(target, prop)] = node; diff --git a/Editor/AnimatorParserV2/PropModNode.cs b/Editor/AnimatorParserV2/PropModNode.cs index 0676e197a..6ebdaa85d 100644 --- a/Editor/AnimatorParserV2/PropModNode.cs +++ b/Editor/AnimatorParserV2/PropModNode.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; @@ -11,7 +11,7 @@ namespace Anatawa12.AvatarOptimizer.AnimatorParsersV2 { - interface IPropModNode + interface IPropModNode { bool AppliedAlways { get; } } @@ -27,11 +27,13 @@ interface IPropModNode /// Most nodes are immutable but some nodes are mutable. /// internal abstract class PropModNode : IErrorContext, IPropModNode + where T : notnull { /// /// Returns true if this node is always applied. For inactive nodes, this returns false. /// public abstract bool AppliedAlways { get; } + public abstract ValueInfo Value { get; } public abstract IEnumerable ContextReferences { get; } } @@ -41,27 +43,27 @@ internal abstract class PropModNode : IErrorContext, IPropModNode /// // by design, this struct doesn't handle blending between two states. internal readonly struct ValueInfo + where T : notnull { public bool IsConstant => _possibleValues != null && _possibleValues.Length == 1; - [CanBeNull] private readonly T[] _possibleValues; + private readonly T[]? _possibleValues; public T ConstantValue { get { if (!IsConstant) throw new InvalidOperationException("Not Constant"); - Debug.Assert(_possibleValues != null, nameof(_possibleValues) + " != null"); - return _possibleValues[0]; + return _possibleValues![0]; // non constant => there is value } } - [CanBeNull] public T[] PossibleValues => _possibleValues; + public T[]? PossibleValues => _possibleValues; public static ValueInfo Variable => default; public ValueInfo(T value) => _possibleValues = new[] { value }; - public ValueInfo([NotNull] T[] possibleValues) + public ValueInfo(T[] possibleValues) { if (possibleValues == null) throw new ArgumentNullException(nameof(possibleValues)); if (possibleValues.Length == 0) @@ -71,7 +73,7 @@ public ValueInfo([NotNull] T[] possibleValues) _possibleValues = possibleValues; } - public bool TryGetConstantValue(out T o) + public bool TryGetConstantValue([NotNullWhen(true)] out T? o) { if (IsConstant) { @@ -92,9 +94,7 @@ public bool Equals(ValueInfo other) public override bool Equals(object obj) => obj is ValueInfo other && Equals(other); - public override int GetHashCode() => _possibleValues == null - ? 0 - : _possibleValues.Aggregate(0, (current, value) => current ^ value.GetHashCode()); + public override int GetHashCode() => _possibleValues == null ? 0 : _possibleValues.GetSetHashCode(); public override string ToString() => _possibleValues == null @@ -104,7 +104,7 @@ public override string ToString() => internal static class NodeImplUtils { - public static bool SetEquals(T[] a, T[] b) + public static bool SetEquals(T[]? a, T[]? b) { if (a == null && b == null) return true; if (a == null || b == null) return false; @@ -112,7 +112,7 @@ public static bool SetEquals(T[] a, T[] b) return new HashSet(a).SetEquals(b); } - public static ValueInfo ConstantInfoForSideBySide(IEnumerable> nodes) + public static ValueInfo ConstantInfoForSideBySide(IEnumerable> nodes) where T : notnull { using (var enumerator = nodes.GetEnumerator()) { @@ -136,6 +136,7 @@ public static ValueInfo ConstantInfoForSideBySide(IEnumerable(IEnumerable layersReversed) + where T : notnull where TLayer : ILayer { return layersReversed.Any(x => @@ -144,6 +145,7 @@ public static bool AlwaysAppliedForOverriding(IEnumerable lay } public static ValueInfo ConstantInfoForOverriding(IEnumerable layersReversed) + where T : notnull where TLayer : ILayer { var allPossibleValues = new HashSet(); @@ -183,7 +185,7 @@ public static bool IsAlwaysOverride(this TLayer layer) } public static IEnumerable WhileApplied(this IEnumerable layer) - where TLayer : ILayer + where TLayer : ILayer { foreach (var layerInfo in layer) { @@ -201,6 +203,7 @@ interface ILayer } internal interface ILayer : ILayer + where T : notnull { new AnimatorWeightState Weight { get; } new AnimatorLayerBlendingMode BlendingMode { get; } @@ -208,6 +211,7 @@ internal interface ILayer : ILayer } internal sealed class RootPropModNode : PropModNode, IErrorContext + where T : notnull { internal readonly struct ComponentInfo { @@ -230,7 +234,10 @@ public ComponentInfo(ComponentPropModNodeBase node, bool alwaysApplied) public IEnumerable Children => _children; public override bool AppliedAlways => _children.All(x => x.AppliedAlways); - public override IEnumerable ContextReferences => _children.SelectMany(x => x.ContextReferences); + + public override IEnumerable ContextReferences => + _children.SelectMany(x => x.ContextReferences); + public override ValueInfo Value => NodeImplUtils.ConstantInfoForSideBySide(_children.Select(x => x.Node)); public bool IsEmpty => _children.Count == 0; @@ -243,8 +250,8 @@ public void Add(ComponentPropModNodeBase node, bool alwaysApplied) _children.Add(new ComponentInfo(node, alwaysApplied)); DestroyTracker.Track(node.Component, OnDestroy); } - - public void Add([NotNull] RootPropModNode toAdd) + + public void Add(RootPropModNode toAdd) { if (toAdd == null) throw new ArgumentNullException(nameof(toAdd)); foreach (var child in toAdd._children) @@ -263,20 +270,20 @@ public void Invalidate() _children.Clear(); } - [CanBeNull] public RootPropModNode Normalize() => IsEmpty ? null : this; + public RootPropModNode? Normalize() => IsEmpty ? null : this; } internal abstract class ImmutablePropModNode : PropModNode + where T : notnull { } internal class FloatAnimationCurveNode : ImmutablePropModNode { - [NotNull] public AnimationCurve Curve { get; } - [NotNull] public AnimationClip Clip { get; } + public AnimationCurve Curve { get; } + public AnimationClip Clip { get; } - [CanBeNull] - public static FloatAnimationCurveNode Create([NotNull] AnimationClip clip, EditorCurveBinding binding) + public static FloatAnimationCurveNode? Create(AnimationClip clip, EditorCurveBinding binding) { var curve = AnimationUtility.GetEditorCurve(clip, binding); if (curve == null) return null; @@ -284,7 +291,7 @@ public static FloatAnimationCurveNode Create([NotNull] AnimationClip clip, Edito return new FloatAnimationCurveNode(clip, curve); } - private FloatAnimationCurveNode([NotNull] AnimationClip clip, [NotNull] AnimationCurve curve) + private FloatAnimationCurveNode(AnimationClip clip, AnimationCurve curve) { if (!clip) throw new ArgumentNullException(nameof(clip)); if (curve == null) throw new ArgumentNullException(nameof(curve)); @@ -298,7 +305,7 @@ private FloatAnimationCurveNode([NotNull] AnimationClip clip, [NotNull] Animatio public override bool AppliedAlways => true; public override ValueInfo Value => _constantInfo.Value; - public override IEnumerable ContextReferences => new []{ ObjectRegistry.GetReference(Clip) }; + public override IEnumerable ContextReferences => new[] { ObjectRegistry.GetReference(Clip) }; private static ValueInfo ParseProperty(AnimationCurve curve) { @@ -328,8 +335,7 @@ internal class ObjectAnimationCurveNode : ImmutablePropModNode public ObjectReferenceKeyframe[] Frames { get; set; } public AnimationClip Clip { get; } - [CanBeNull] - public static ObjectAnimationCurveNode Create([NotNull] AnimationClip clip, EditorCurveBinding binding) + public static ObjectAnimationCurveNode? Create(AnimationClip clip, EditorCurveBinding binding) { var curve = AnimationUtility.GetObjectReferenceCurve(clip, binding); if (curve == null) return null; @@ -350,18 +356,19 @@ private ObjectAnimationCurveNode(AnimationClip clip, ObjectReferenceKeyframe[] f public override bool AppliedAlways => true; public override ValueInfo Value => _constantInfo.Value; - public override IEnumerable ContextReferences => new []{ ObjectRegistry.GetReference(Clip) }; + public override IEnumerable ContextReferences => new[] { ObjectRegistry.GetReference(Clip) }; private static ValueInfo ParseProperty(ObjectReferenceKeyframe[] frames) => new ValueInfo(frames.Select(x => x.value).Distinct().ToArray()); } internal struct BlendTreeElement + where T : notnull { public int Index; public ImmutablePropModNode Node; - public BlendTreeElement(int index, [NotNull] ImmutablePropModNode node) + public BlendTreeElement(int index, ImmutablePropModNode node) { Index = index; Node = node ?? throw new ArgumentNullException(nameof(node)); @@ -369,12 +376,14 @@ public BlendTreeElement(int index, [NotNull] ImmutablePropModNode node) } internal class BlendTreeNode : ImmutablePropModNode + where T : notnull { private readonly List> _children; private readonly BlendTreeType _blendTreeType; private readonly bool _partial; - public BlendTreeNode([NotNull] List> children, BlendTreeType blendTreeType, bool partial) + public BlendTreeNode(List> children, + BlendTreeType blendTreeType, bool partial) { // expected to pass list or array // ReSharper disable once PossibleMultipleEnumeration @@ -389,6 +398,7 @@ public BlendTreeNode([NotNull] List> children, BlendTreeType private bool WeightSumIsOne => _blendTreeType != BlendTreeType.Direct; public IReadOnlyList> Children => _children; public override bool AppliedAlways => WeightSumIsOne && !_partial && _children.All(x => x.Node.AppliedAlways); + public override ValueInfo Value => !WeightSumIsOne ? ValueInfo.Variable : NodeImplUtils.ConstantInfoForSideBySide(_children.Select(x => x.Node)); @@ -398,8 +408,9 @@ public BlendTreeNode([NotNull] List> children, BlendTreeType } abstract class ComponentPropModNodeBase : PropModNode + where T : notnull { - protected ComponentPropModNodeBase([NotNull] Component component) + protected ComponentPropModNodeBase(Component component) { if (!component) throw new ArgumentNullException(nameof(component)); Component = component; @@ -407,13 +418,15 @@ protected ComponentPropModNodeBase([NotNull] Component component) public Component Component { get; } - public override IEnumerable ContextReferences => new [] { ObjectRegistry.GetReference(Component) }; + public override IEnumerable ContextReferences => + new[] { ObjectRegistry.GetReference(Component) }; } abstract class ComponentPropModNode : ComponentPropModNodeBase + where T : notnull where TComponent : Component { - protected ComponentPropModNode([NotNull] TComponent component) : base(component) + protected ComponentPropModNode(TComponent component) : base(component) { if (!component) throw new ArgumentNullException(nameof(component)); Component = component; @@ -421,12 +434,14 @@ protected ComponentPropModNode([NotNull] TComponent component) : base(component) public new TComponent Component { get; } - public override IEnumerable ContextReferences => new [] { ObjectRegistry.GetReference(Component) }; + public override IEnumerable ContextReferences => + new[] { ObjectRegistry.GetReference(Component) }; } class VariableComponentPropModNode : ComponentPropModNode + where T : notnull { - public VariableComponentPropModNode([NotNull] Component component) : base(component) + public VariableComponentPropModNode(Component component) : base(component) { } @@ -435,10 +450,11 @@ public VariableComponentPropModNode([NotNull] Component component) : base(compon } class AnimationComponentPropModNode : ComponentPropModNode + where T : notnull { public ImmutablePropModNode Animation { get; } - public AnimationComponentPropModNode([NotNull] Animation component, ImmutablePropModNode animation) : base(component) + public AnimationComponentPropModNode(Animation component, ImmutablePropModNode animation) : base(component) { Animation = animation; _constantInfo = new Lazy>(() => animation.Value, isThreadSafe: false); diff --git a/Editor/AnimatorParserV2/Utilities.cs b/Editor/AnimatorParserV2/Utilities.cs index 349a46b51..19c3f1f55 100644 --- a/Editor/AnimatorParserV2/Utilities.cs +++ b/Editor/AnimatorParserV2/Utilities.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; +using System.Diagnostics.CodeAnalysis; using UnityEditor.Animations; using UnityEngine; using Object = UnityEngine.Object; @@ -23,7 +23,13 @@ public static TResultContainer Merge< TSourceObjectNode, TMerger - >([NotNull] [ItemNotNull] IEnumerable sources, TMerger merger) + >(IEnumerable sources, TMerger merger) + where TSource : notnull + where TIntermediateFloat : notnull + where TIntermediateObject : notnull + where TSourceFloatNode : notnull + where TSourceObjectNode : notnull + where TResultContainer : NodeContainerBase where TResultFloatNode : PropModNode where TResultObjectNode : PropModNode @@ -93,25 +99,29 @@ interface IMergeProperty1 < where TResultFloatNode : PropModNode where TResultObjectNode : PropModNode where TSourceContainer : INodeContainer + + where TSource : notnull + where TIntermediateFloat : notnull + where TIntermediateObject : notnull + where TSourceFloatNode : notnull + where TSourceObjectNode : notnull { - [NotNull] TResultContainer CreateContainer(); + TResultContainer CreateContainer(); - [CanBeNull] TSourceContainer GetContainer([NotNull] TSource source); + TSourceContainer? GetContainer(TSource source); - [NotNull] TIntermediateFloat GetIntermediate([NotNull] TSource source, [NotNull] TSourceFloatNode node, int index); - [NotNull] TIntermediateObject GetIntermediate([NotNull] TSource source, [NotNull] TSourceObjectNode node, int index); + TIntermediateFloat GetIntermediate(TSource source, TSourceFloatNode node, int index); + TIntermediateObject GetIntermediate(TSource source, TSourceObjectNode node, int index); - [CanBeNull] TResultFloatNode MergeNode([NotNull] [ItemNotNull] List nodes, int sourceCount); - [CanBeNull] TResultObjectNode MergeNode([NotNull] [ItemNotNull] List nodes, int sourceCount); + TResultFloatNode? MergeNode(List nodes, int sourceCount); + TResultObjectNode? MergeNode(List nodes, int sourceCount); } static partial class NodesMerger { - [CanBeNull] - [ContractAnnotation("controller: null => null")] - [ContractAnnotation("controller: notnull => notnull")] - public static ComponentNodeContainer AnimatorComponentFromController([NotNull] Animator animator, - [CanBeNull] AnimatorControllerNodeContainer controller) + [return:NotNullIfNotNull("controller")] + public static ComponentNodeContainer? AnimatorComponentFromController(Animator animator, + AnimatorControllerNodeContainer? controller) { if (controller == null) return null; @@ -132,9 +142,8 @@ public static ComponentNodeContainer AnimatorComponentFromController([NotNull] A return animatorNodeContainer; } - [NotNull] - public static ComponentNodeContainer AnimationComponentFromAnimationClip([NotNull] Animation animation, - [NotNull] ImmutableNodeContainer animationClip) + public static ComponentNodeContainer AnimationComponentFromAnimationClip(Animation animation, + ImmutableNodeContainer animationClip) { if (animationClip == null) throw new ArgumentNullException(nameof(animationClip)); var animatorNodeContainer = new ComponentNodeContainer(); @@ -153,12 +162,12 @@ public static ComponentNodeContainer AnimationComponentFromAnimationClip([NotNul } public static ComponentNodeContainer ComponentFromPlayableLayers(Animator animator, - IEnumerable<(AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer)> + IEnumerable<(AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?)> playableLayers) => Merge< ComponentNodeContainer, ComponentPropModNodeBase, ComponentPropModNodeBase, PlayableLayerNodeInfo, PlayableLayerNodeInfo, - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer), + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?), AnimatorControllerNodeContainer, AnimatorControllerPropModNode, AnimatorControllerPropModNode, PlayableLayerMerger @@ -167,7 +176,7 @@ public static ComponentNodeContainer ComponentFromPlayableLayers(Animator animat readonly struct PlayableLayerMerger : IMergeProperty1< ComponentNodeContainer, ComponentPropModNodeBase, ComponentPropModNodeBase, PlayableLayerNodeInfo, PlayableLayerNodeInfo, - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer), + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?), AnimatorControllerNodeContainer, AnimatorControllerPropModNode, AnimatorControllerPropModNode > { @@ -177,17 +186,17 @@ public static ComponentNodeContainer ComponentFromPlayableLayers(Animator animat public ComponentNodeContainer CreateContainer() => new ComponentNodeContainer(); - public AnimatorControllerNodeContainer GetContainer( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer) source) => + public AnimatorControllerNodeContainer? GetContainer( + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?) source) => source.Item3; public PlayableLayerNodeInfo GetIntermediate( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer) source, + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?) source, AnimatorControllerPropModNode node, int index) => new PlayableLayerNodeInfo(source.Item1, source.Item2, node, index); public PlayableLayerNodeInfo GetIntermediate( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer) source, + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorControllerNodeContainer?) source, AnimatorControllerPropModNode node, int index) => new PlayableLayerNodeInfo(source.Item1, source.Item2, node, index); @@ -199,11 +208,11 @@ public ComponentPropModNodeBase MergeNode(List layers) => + IEnumerable<(AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?)> layers) => Merge< AnimatorControllerNodeContainer, AnimatorControllerPropModNode, AnimatorControllerPropModNode, AnimatorLayerNodeInfo, AnimatorLayerNodeInfo, - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer), + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?), AnimatorLayerNodeContainer, AnimatorLayerPropModNode, AnimatorLayerPropModNode, AnimatorLayerMerger >(layers, default); @@ -212,31 +221,31 @@ private struct AnimatorLayerMerger : IMergeProperty1< AnimatorControllerNodeContainer, AnimatorControllerPropModNode, AnimatorControllerPropModNode , AnimatorLayerNodeInfo, AnimatorLayerNodeInfo, - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer), + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?), AnimatorLayerNodeContainer, AnimatorLayerPropModNode, AnimatorLayerPropModNode > { public AnimatorControllerNodeContainer CreateContainer() => new AnimatorControllerNodeContainer(); - public AnimatorLayerNodeContainer GetContainer( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer) source) => + public AnimatorLayerNodeContainer? GetContainer( + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?) source) => source.Item3; public AnimatorLayerNodeInfo GetIntermediate( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer) source, + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?) source, AnimatorLayerPropModNode node, int index) => new AnimatorLayerNodeInfo(source.Item1, source.Item2, node, index); public AnimatorLayerNodeInfo GetIntermediate( - (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer) source, + (AnimatorWeightState, AnimatorLayerBlendingMode, AnimatorLayerNodeContainer?) source, AnimatorLayerPropModNode node, int index) => new AnimatorLayerNodeInfo(source.Item1, source.Item2, node, index); - public AnimatorControllerPropModNode MergeNode(List> nodes, + public AnimatorControllerPropModNode? MergeNode(List> nodes, int sourceCount) => AnimatorControllerPropModNode.Create(nodes); - public AnimatorControllerPropModNode MergeNode(List> nodes, + public AnimatorControllerPropModNode? MergeNode(List> nodes, int sourceCount) => AnimatorControllerPropModNode.Create(nodes); } diff --git a/Editor/AssetDescription.cs b/Editor/AssetDescription.cs index c740bfd47..645d1e4de 100644 --- a/Editor/AssetDescription.cs +++ b/Editor/AssetDescription.cs @@ -14,7 +14,10 @@ internal class AssetDescription : ScriptableObject { [SerializeField] [TextArea] + // only for serialization so ignore warning +#pragma warning disable CS0414 private string comment = ""; +#pragma warning restore CS0414 [SerializeField] private ClassReference[] meaninglessComponents = Array.Empty(); @@ -36,7 +39,7 @@ public static IEnumerable GetMeaninglessComponents() .SelectMany(description => description.meaninglessComponents) .Select(component => GetMonoScriptFromGuid(component.guid, component.fileID) as MonoScript) .Where(monoScript => monoScript != null) - .Select(monoScript => monoScript.GetClass()); + .Select(monoScript => monoScript!.GetClass()); } private static Object GetMonoScriptFromGuid(string guid, ulong fileid) @@ -49,8 +52,8 @@ private static Object GetMonoScriptFromGuid(string guid, ulong fileid) [CustomEditor(typeof(AssetDescription))] internal class AssetDescriptionEditor : Editor { - private SerializedProperty _comment; - private SerializedProperty _meaninglessComponents; + private SerializedProperty _comment = null!; // Initialized by OnEnable + private SerializedProperty _meaninglessComponents = null!; // Initialized by OnEnable private void OnEnable() { diff --git a/Editor/CheckForUpdate.cs b/Editor/CheckForUpdate.cs index e321b79b5..d44efb5db 100644 --- a/Editor/CheckForUpdate.cs +++ b/Editor/CheckForUpdate.cs @@ -4,7 +4,6 @@ using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -24,7 +23,7 @@ public static bool OutOfDate private set => SessionState.SetBool("com.anatawa12.avatar-optimizer.out-of-date", value); } - public static string LatestVersionName + public static string? LatestVersionName { get => SessionState.GetString("com.anatawa12.avatar-optimizer.latest", ""); private set => SessionState.SetString("com.anatawa12.avatar-optimizer.latest", value); @@ -61,8 +60,7 @@ static async void DoCheckForUpdate() } } - [CanBeNull] - static string GetCurrentVersion() + static string? GetCurrentVersion() { try { @@ -80,8 +78,7 @@ static string GetCurrentVersion() } } - [ItemCanBeNull] - static async Task GetLatestVersion(bool beta, string version) + static async Task GetLatestVersion(bool beta, string version) { var latestVersionUrl = beta @@ -112,7 +109,7 @@ static async Task GetLatestVersion(bool beta, string version) // out of date or invalid cached version - string fetchedLatestVersion = null; + string? fetchedLatestVersion = null; try { using (var client = new HttpClient()) @@ -158,7 +155,7 @@ static async Task GetLatestVersion(bool beta, string version) [Serializable] class PackageJson { - public string version; + public string? version; } } -} \ No newline at end of file +} diff --git a/Editor/ContextExtensions.cs b/Editor/ContextExtensions.cs index 1fff440fc..9d81d5a9e 100644 --- a/Editor/ContextExtensions.cs +++ b/Editor/ContextExtensions.cs @@ -1,8 +1,5 @@ using System; using Anatawa12.AvatarOptimizer.AnimatorParsersV2; -using Anatawa12.AvatarOptimizer.Processors; -using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; @@ -10,53 +7,53 @@ namespace Anatawa12.AvatarOptimizer { internal static class ContextExtensions { - public static T[] GetComponents([NotNull] this BuildContext context) where T : Component + public static T[] GetComponents(this BuildContext context) where T : Component { if (context == null) throw new ArgumentNullException(nameof(context)); return context.AvatarRootObject.GetComponentsInChildren(true); } - public static ObjectMappingBuilder GetMappingBuilder([NotNull] this BuildContext context) + public static ObjectMappingBuilder GetMappingBuilder(this BuildContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); - return context.Extension().MappingBuilder; + return context.Extension().MappingBuilder!; // activated so not null } - public static void RecordMergeComponent([NotNull] this BuildContext context, T from, T mergeTo) + public static void RecordMergeComponent(this BuildContext context, T from, T mergeTo) where T : Component => GetMappingBuilder(context).RecordMergeComponent(from, mergeTo); - public static void RecordMoveProperties([NotNull] this BuildContext context, Component from, + public static void RecordMoveProperties(this BuildContext context, Component from, params (string old, string @new)[] props) => GetMappingBuilder(context).RecordMoveProperties(from, props); - public static void RecordMoveProperty([NotNull] this BuildContext context, Component from, string oldProp, + public static void RecordMoveProperty(this BuildContext context, Component from, string oldProp, string newProp) => GetMappingBuilder(context).RecordMoveProperty(from, oldProp, newProp); - public static void RecordRemoveProperty([NotNull] this BuildContext context, Component from, string oldProp) => + public static void RecordRemoveProperty(this BuildContext context, Component from, string oldProp) => GetMappingBuilder(context).RecordRemoveProperty(from, oldProp); - public static AnimationComponentInfo GetAnimationComponent([NotNull] this BuildContext context, + public static AnimationComponentInfo GetAnimationComponent(this BuildContext context, ComponentOrGameObject component) => GetMappingBuilder(context).GetAnimationComponent(component); - public static bool? GetConstantValue([NotNull] this BuildContext context, ComponentOrGameObject obj, + public static bool? GetConstantValue(this BuildContext context, ComponentOrGameObject obj, string property, bool currentValue) => !context.GetAnimationComponent(obj).TryGetFloat(property, out var node) ? currentValue : node.AsConstantValue(currentValue); - public static bool? AsConstantValue([CanBeNull] this PropModNode node, bool currentValue) + public static bool? AsConstantValue(this PropModNode? node, bool currentValue) { if (node == null) return currentValue; - if (node.Value.PossibleValues is float[] values) + if (node.Value.PossibleValues is { } values) { bool? constValue = null; foreach (var value in values) { var current = value != 0; - if (!(constValue is bool b)) constValue = current; + if (constValue is not { } b) constValue = current; else if (b != current) return null; } if (node.AppliedAlways || constValue == currentValue) @@ -66,4 +63,4 @@ public static AnimationComponentInfo GetAnimationComponent([NotNul return null; } } -} \ No newline at end of file +} diff --git a/Editor/EditModePreview/BlendShapePreviewContext.cs b/Editor/EditModePreview/BlendShapePreviewContext.cs index e3060be37..694c6c2f7 100644 --- a/Editor/EditModePreview/BlendShapePreviewContext.cs +++ b/Editor/EditModePreview/BlendShapePreviewContext.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Linq; @@ -202,4 +204,4 @@ bool ZeroForWeightZero() } } } -} \ No newline at end of file +} diff --git a/Editor/EditModePreview/MeshPreviewController.cs b/Editor/EditModePreview/MeshPreviewController.cs index 57ccdf36b..3dc5f653a 100644 --- a/Editor/EditModePreview/MeshPreviewController.cs +++ b/Editor/EditModePreview/MeshPreviewController.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Linq; using System.Reflection; @@ -5,9 +7,6 @@ using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; -#if !UNITY_2020_1_OR_NEWER -using AnimationModeDriver = UnityEngine.Object; -#endif namespace Anatawa12.AvatarOptimizer.EditModePreview { @@ -242,39 +241,6 @@ public void StopPreview() _previewController = null; } -#if !UNITY_2020_1_OR_NEWER - private static AnimationModeDriver CreateDriver() => - ScriptableObject.CreateInstance( - typeof(UnityEditor.AnimationMode).Assembly.GetType("UnityEditor.AnimationModeDriver")); -#else private static AnimationModeDriver CreateDriver() => ScriptableObject.CreateInstance(); -#endif - -#if !UNITY_2020_1_OR_NEWER - public static class AnimationMode - { - public static void BeginSampling() => UnityEditor.AnimationMode.BeginSampling(); - public static void EndSampling() => UnityEditor.AnimationMode.EndSampling(); - public static bool InAnimationMode() => UnityEditor.AnimationMode.InAnimationMode(); - public static bool InAnimationMode(AnimationModeDriver o) => StartAnimationMode("InAnimationMode", o); - public static void StartAnimationMode(AnimationModeDriver o) => StartAnimationMode("StartAnimationMode", o); - public static void StopAnimationMode(AnimationModeDriver o) => StartAnimationMode("StopAnimationMode", o); - - public static void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, - bool keepPrefabOverride) => - UnityEditor.AnimationMode.AddPropertyModification(binding, modification, keepPrefabOverride); - - private static R StartAnimationMode(string name, AnimationModeDriver o) - { - var method = typeof(UnityEditor.AnimationMode).GetMethod(name, - BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, - null, - new[] { typeof(AnimationModeDriver) }, - null); - System.Diagnostics.Debug.Assert(method != null, nameof(method) + " != null"); - return (R)method.Invoke(null, new object[] { o }); - } - } -#endif } } diff --git a/Editor/EditModePreview/RemoveMeshByBlendShapePreviewContext.cs b/Editor/EditModePreview/RemoveMeshByBlendShapePreviewContext.cs index d429ce0af..ceb62c479 100644 --- a/Editor/EditModePreview/RemoveMeshByBlendShapePreviewContext.cs +++ b/Editor/EditModePreview/RemoveMeshByBlendShapePreviewContext.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using Unity.Collections; @@ -51,4 +53,4 @@ public void Dispose() _blendShapeMovements.Dispose(); } } -} \ No newline at end of file +} diff --git a/Editor/EditModePreview/RemoveMeshPreviewController.cs b/Editor/EditModePreview/RemoveMeshPreviewController.cs index 354fffdc1..a94858249 100644 --- a/Editor/EditModePreview/RemoveMeshPreviewController.cs +++ b/Editor/EditModePreview/RemoveMeshPreviewController.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using JetBrains.Annotations; diff --git a/Editor/EditModePreview/RemoveMeshWithBoxPreviewContext.cs b/Editor/EditModePreview/RemoveMeshWithBoxPreviewContext.cs index b68bd2749..120afe852 100644 --- a/Editor/EditModePreview/RemoveMeshWithBoxPreviewContext.cs +++ b/Editor/EditModePreview/RemoveMeshWithBoxPreviewContext.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using JetBrains.Annotations; using Unity.Burst; @@ -155,4 +157,4 @@ public void Dispose() _boneIndexStart.Dispose(); } } -} \ No newline at end of file +} diff --git a/Editor/EditSkinnedMeshComponentUtil.cs b/Editor/EditSkinnedMeshComponentUtil.cs index ed2682a9b..100c35770 100644 --- a/Editor/EditSkinnedMeshComponentUtil.cs +++ b/Editor/EditSkinnedMeshComponentUtil.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -33,18 +32,17 @@ private static SkinnedMeshEditorSorter CreateSharedSorterWithScene() public static (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => EditorShared.GetBlendShapes(renderer, before); - public static Material[] GetMaterials(SkinnedMeshRenderer renderer) => EditorShared.GetMaterials(renderer); + public static Material?[] GetMaterials(SkinnedMeshRenderer renderer) => EditorShared.GetMaterials(renderer); // Rider's problem, to call GetMaterials(renderer, fast: false) // ReSharper disable once MethodOverloadWithOptionalParameter - public static Material[] GetMaterials(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before = null, + public static Material?[] GetMaterials(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent? before = null, bool fast = true) => EditorShared.GetMaterials(renderer, before, fast); - [CanBeNull] private static SkinnedMeshEditorSorter _editorShared; + private static SkinnedMeshEditorSorter? _editorShared; - [NotNull] private static SkinnedMeshEditorSorter EditorShared => - _editorShared ?? (_editorShared = CreateSharedSorterWithScene()); + _editorShared ??= CreateSharedSorterWithScene(); } internal class SkinnedMeshEditorSorter @@ -66,19 +64,18 @@ public bool IsModifiedByEditComponent(SkinnedMeshRenderer renderer) => public (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer) => GetBlendShapes(renderer, null); - public (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => + public (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent? before) => GetProcessors(renderer)?.GetBlendShapes(before) ?? SourceMeshInfoComputer.BlendShapes(renderer); - public Material[] GetMaterials(SkinnedMeshRenderer renderer) => GetMaterials(renderer, null); + public Material?[] GetMaterials(SkinnedMeshRenderer renderer) => GetMaterials(renderer, null); // Rider's problem, to call GetMaterials(renderer, fast: false) // ReSharper disable once MethodOverloadWithOptionalParameter - public Material[] GetMaterials(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before = null, + public Material?[] GetMaterials(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent? before = null, bool fast = true) => GetProcessors(renderer)?.GetMaterials(before, fast) ?? SourceMeshInfoComputer.Materials(renderer); - [CanBeNull] - private SkinnedMeshProcessors GetProcessors(SkinnedMeshRenderer target) + private SkinnedMeshProcessors? GetProcessors(SkinnedMeshRenderer target) { ProcessorsByRenderer.TryGetValue(target, out var processors); return processors; @@ -87,7 +84,7 @@ private SkinnedMeshProcessors GetProcessors(SkinnedMeshRenderer target) public IEnumerable GetSortedProcessors( IEnumerable targets) { - var processors = new LinkedList(targets.Select(GetProcessors).Where(x => x != null)); + var processors = new LinkedList(targets.Select(GetProcessors).Where(x => x != null)!); var proceed = new HashSet(); foreach (var renderer in processors @@ -114,8 +111,8 @@ internal class SkinnedMeshProcessors { internal readonly SkinnedMeshRenderer Target; private readonly HashSet _processors = new HashSet(); - private List _sorted = new List(); - private IMeshInfoComputer[] _computers; + private List? _sorted = new List(); + private IMeshInfoComputer[]? _computers; public SkinnedMeshProcessors(SkinnedMeshRenderer target) { @@ -157,13 +154,13 @@ private IMeshInfoComputer[] GetComputers() return _computers; } - private IMeshInfoComputer GetComputer(EditSkinnedMeshComponent before = null) => !before + private IMeshInfoComputer GetComputer(EditSkinnedMeshComponent? before = null) => !before ? GetComputers().Last() - : GetComputers()[_sorted.FindIndex(x => x.Component == before)]; + : GetComputers()[_sorted!.FindIndex(x => x.Component == before)]; - public (string, float)[] GetBlendShapes(EditSkinnedMeshComponent before = null) => GetComputer(before).BlendShapes(); + public (string, float)[] GetBlendShapes(EditSkinnedMeshComponent? before = null) => GetComputer(before).BlendShapes(); - public Material[] GetMaterials(EditSkinnedMeshComponent before = null, bool fast = true) => + public Material?[] GetMaterials(EditSkinnedMeshComponent? before = null, bool fast = true) => GetComputer(before).Materials(fast); private class RecursiveDetector : IMeshInfoComputer @@ -176,7 +173,7 @@ public RecursiveDetector(IMeshInfoComputer origin) } [ThreadStatic] - private static HashSet _currentThreadDetectors; + private static HashSet? _currentThreadDetectors; private T CheckRecursive(Func compute) { @@ -195,7 +192,7 @@ private T CheckRecursive(Func compute) } public (string, float)[] BlendShapes() => CheckRecursive(() => _origin.BlendShapes()); - public Material[] Materials(bool fast = true) => CheckRecursive(() => _origin.Materials(fast)); + public Material?[] Materials(bool fast = true) => CheckRecursive(() => _origin.Materials(fast)); } } diff --git a/Editor/Inspector/AvatarGlobalComponentEditorBase.cs b/Editor/Inspector/AvatarGlobalComponentEditorBase.cs index 459c934ce..6cac14492 100644 --- a/Editor/Inspector/AvatarGlobalComponentEditorBase.cs +++ b/Editor/Inspector/AvatarGlobalComponentEditorBase.cs @@ -1,13 +1,8 @@ using UnityEditor; using UnityEngine; -#if AAO_VRCSDK3_AVATARS -using VRC.SDK3.Avatars.Components; -#endif - namespace Anatawa12.AvatarOptimizer { - [InitializeOnLoad] abstract class AvatarGlobalComponentEditorBase : AvatarTagComponentEditorBase { protected override void OnInspectorGUIInner() diff --git a/Editor/Inspector/AvatarTagComponentEditorBase.cs b/Editor/Inspector/AvatarTagComponentEditorBase.cs index 9afa73a34..42ce52f82 100644 --- a/Editor/Inspector/AvatarTagComponentEditorBase.cs +++ b/Editor/Inspector/AvatarTagComponentEditorBase.cs @@ -1,4 +1,3 @@ -using JetBrains.Annotations; using UnityEditor; namespace Anatawa12.AvatarOptimizer @@ -16,9 +15,8 @@ public sealed override void OnInspectorGUI() OnInspectorGUIInner(); } - private string _descriptionKey; - [CanBeNull] - protected virtual string Description + private string? _descriptionKey; + protected virtual string? Description { get { diff --git a/Editor/Inspector/ClearEndpointPositionEditor.cs b/Editor/Inspector/ClearEndpointPositionEditor.cs index 139d1a7c6..e69232dd3 100644 --- a/Editor/Inspector/ClearEndpointPositionEditor.cs +++ b/Editor/Inspector/ClearEndpointPositionEditor.cs @@ -34,4 +34,4 @@ protected override void OnInspectorGUIInner() } } -#endif \ No newline at end of file +#endif diff --git a/Editor/Inspector/FreezeBlendShapeEditor.cs b/Editor/Inspector/FreezeBlendShapeEditor.cs index 01465a8b4..a03a53241 100644 --- a/Editor/Inspector/FreezeBlendShapeEditor.cs +++ b/Editor/Inspector/FreezeBlendShapeEditor.cs @@ -6,7 +6,7 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(FreezeBlendShape))] class FreezeBlendShapeEditor : AvatarTagComponentEditorBase { - private PrefabSafeSet.EditorUtil _shapeKeysSet; + private PrefabSafeSet.EditorUtil _shapeKeysSet = null!; // initialized in OnEnable private void OnEnable() { diff --git a/Editor/Inspector/MakeChildrenEditor.cs b/Editor/Inspector/MakeChildrenEditor.cs index 51683d304..fc7f42d43 100644 --- a/Editor/Inspector/MakeChildrenEditor.cs +++ b/Editor/Inspector/MakeChildrenEditor.cs @@ -6,8 +6,8 @@ namespace Anatawa12.AvatarOptimizer [CanEditMultipleObjects] internal class MakeChildrenEditor : AvatarTagComponentEditorBase { - private SerializedProperty _executeEarly; - private SerializedProperty _children; + private SerializedProperty _executeEarly = null!; // initialized in OnEnable + private SerializedProperty _children = null!; // initialized in OnEnable private void OnEnable() { diff --git a/Editor/Inspector/MergePhysBoneEditor.cs b/Editor/Inspector/MergePhysBoneEditor.cs index 02d503231..cf63bd513 100644 --- a/Editor/Inspector/MergePhysBoneEditor.cs +++ b/Editor/Inspector/MergePhysBoneEditor.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; using VRC.Dynamics; @@ -13,9 +12,9 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(MergePhysBone))] internal class MergePhysBoneEditor : AvatarTagComponentEditorBase { - private MergePhysBoneEditorRenderer _renderer; - private SerializedProperty _makeParent; - private SerializedProperty _componentsSetProp; + private MergePhysBoneEditorRenderer _renderer = null!; // initialized in OnEnable + private SerializedProperty _makeParent = null!; // initialized in OnEnable + private SerializedProperty _componentsSetProp = null!; // initialized in OnEnable private void OnEnable() { @@ -170,7 +169,7 @@ protected override void PbVersionProp(string label, { // Copy mode EditorGUI.BeginDisabledGroup(true); - var differ = renderer(prop.SourceValue); + var differ = renderer(prop.SourceValue!); EditorGUI.EndDisabledGroup(); EditorGUI.BeginProperty(overrideRect, null, prop.IsOverrideProperty); @@ -359,10 +358,10 @@ void DrawCurve(string curveLabel, SerializedProperty curveProp) private static readonly string[] CopyOverride = { "C:Copy", "O:Override" }; - private void PbPropImpl([NotNull] string label, - [NotNull] OverridePropBase prop, + private void PbPropImpl(string label, + OverridePropBase prop, bool forceOverride, - [NotNull] Func renderer) + Func renderer) { var labelContent = new GUIContent(label); @@ -420,7 +419,7 @@ protected override void CollidersProp(string label, CollidersConfigProp prop) { case MergePhysBone.CollidersConfig.CollidersOverride.Copy: { - var colliders = prop.PhysBoneValue; + var colliders = prop.PhysBoneValue!; var height = EditorGUI.GetPropertyHeight(colliders, null, true); @@ -496,7 +495,7 @@ private void EndpointPositionProp(string label, EndpointPositionConfigProp prop) break; case MergePhysBone.EndPointPositionConfig.Override.Copy: { - var valueProperty = prop.PhysBoneValue; + var valueProperty = prop.PhysBoneValue!; var height = EditorGUI.GetPropertyHeight(valueProperty, null, true); @@ -607,7 +606,7 @@ protected override void TransformSection() if (EndpointPosition.OverrideProperty.enumValueIndex == (int)MergePhysBone.EndPointPositionConfig.Override.Copy) { - if (EndpointPosition.PhysBoneValue.hasMultipleDifferentValues) + if (EndpointPosition.PhysBoneValue!.hasMultipleDifferentValues) _differProps.Add("Endpoint Position"); } @@ -649,10 +648,10 @@ protected override void Pb3DCurveProp(string label, { if (forceOverride || prop.IsOverride) return; - if (prop.SourceValue.hasMultipleDifferentValues - || prop.SourceCurveX.hasMultipleDifferentValues - || prop.SourceCurveY.hasMultipleDifferentValues - || prop.SourceCurveZ.hasMultipleDifferentValues) + if (prop.SourceValue!.hasMultipleDifferentValues + || prop.SourceCurveX!.hasMultipleDifferentValues + || prop.SourceCurveY!.hasMultipleDifferentValues + || prop.SourceCurveZ!.hasMultipleDifferentValues) _differProps.Add(label); _usingCopyCurve |= prop.GetCurveXProperty(false).animationCurveValue.length > 0; @@ -664,10 +663,10 @@ protected override void PbPermissionProp(string label, PermissionConfigProp prop { if (forceOverride || prop.IsOverride) return; - if (prop.SourceValue.enumValueIndex == 2) + if (prop.SourceValue!.enumValueIndex == 2) { if (prop.SourceValue.hasMultipleDifferentValues - || prop.SourceFilter.hasMultipleDifferentValues) + || prop.SourceFilter!.hasMultipleDifferentValues) _differProps.Add(label); } else @@ -682,7 +681,7 @@ protected override void CollidersProp(string label, CollidersConfigProp prop) // 0: copy if (prop.OverrideProperty.enumValueIndex == 0) { - if (prop.PhysBoneValue.hasMultipleDifferentValues) + if (prop.PhysBoneValue!.hasMultipleDifferentValues) _differProps.Add(label); } } diff --git a/Editor/Inspector/MergeSkinnedMeshEditor.cs b/Editor/Inspector/MergeSkinnedMeshEditor.cs index d317a3cfe..f9077b72f 100644 --- a/Editor/Inspector/MergeSkinnedMeshEditor.cs +++ b/Editor/Inspector/MergeSkinnedMeshEditor.cs @@ -23,11 +23,11 @@ private static class Style }; } - SerializedProperty _renderersSetProp; - SerializedProperty _staticRenderersSetProp; - SerializedProperty _removeEmptyRendererObjectProp; - SerializedProperty _skipEnablementMismatchedRenderers; - PrefabSafeSet.EditorUtil _doNotMergeMaterials; + SerializedProperty _renderersSetProp = null!; // initialized in OnEnable + SerializedProperty _staticRenderersSetProp = null!; // initialized in OnEnable + SerializedProperty _removeEmptyRendererObjectProp = null!; // initialized in OnEnable + SerializedProperty _skipEnablementMismatchedRenderers = null!; // initialized in OnEnable + PrefabSafeSet.EditorUtil _doNotMergeMaterials = null!; // initialized in OnEnable private void OnEnable() { @@ -40,7 +40,7 @@ private void OnEnable() _doNotMergeMaterials = PrefabSafeSet.EditorUtil.Create( serializedObject.FindProperty("doNotMergeMaterials"), nestCount, - x => x.objectReferenceValue as Material, + x => (Material)x.objectReferenceValue, (x, v) => x.objectReferenceValue = v); } @@ -68,7 +68,7 @@ protected override void OnInspectorGUIInner() public void MergeMaterials(MergeSkinnedMesh merge) { - var materials = new HashSet(); + var materials = new HashSet(); var renderersSetAsList = merge.renderersSet.GetAsList(); var staticRenderersSetAsList = merge.staticRenderersSet.GetAsList(); var ofRenderers = renderersSetAsList.Select(EditSkinnedMeshComponentUtil.GetMaterials); @@ -77,6 +77,7 @@ public void MergeMaterials(MergeSkinnedMesh merge) .SelectMany((x, renderer) => x.Select((mat, material) => (mat, renderer, material))) .GroupBy(x => x.mat)) { + if (group.Key == null) continue; materials.Add(group.Key); if (group.Count() == 1) { diff --git a/Editor/Inspector/MergeToonLitMaterialEditor.cs b/Editor/Inspector/MergeToonLitMaterialEditor.cs index a9adfdbe7..f0442568d 100644 --- a/Editor/Inspector/MergeToonLitMaterialEditor.cs +++ b/Editor/Inspector/MergeToonLitMaterialEditor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; using UnityEditor; @@ -11,20 +12,19 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(MergeToonLitMaterial))] internal class MergeToonLitMaterialEditor : AvatarTagComponentEditorBase { - private Material[] _upstreamMaterials; - private (Material mat, int index)[] _materials; + private Material?[] _upstreamMaterials = null!; // initialized in OnEnable + private (Material mat, int index)[] _materials = null!; // initialized in OnEnable - private (Material mat, int index)[] _candidateMaterials; - private string[] _candidateNames; + private (Material mat, int index)[] _candidateMaterials = null!; // initialized in OnEnable + private string[] _candidateNames = null!; // initialized in OnEnable - private Texture[] _generatedPreviews; + private Texture[]? _generatedPreviews; private readonly Func _createNewSource; private readonly Func _createNewMergeInfo; public MergeToonLitMaterialEditor() { - // ReSharper disable once PossibleNullReferenceException _createNewSource = () => new MergeToonLitMaterial.MergeSource { materialIndex = _candidateMaterials[0].index }; _createNewMergeInfo = () => new MergeToonLitMaterial.MergeInfo @@ -32,15 +32,15 @@ public MergeToonLitMaterialEditor() } private static void DrawList( - ref T[] array, + [AllowNull] ref T[] array, string addButton, Action drawer, - Func newElement, + Func? newElement, bool noEmpty = false, - Action postButtons = null, - Action onMoved = null, - Action onRemoved = null, - Action onAdded = null + Action? postButtons = null, + Action? onMoved = null, + Action? onRemoved = null, + Action? onAdded = null ) { if (array == null) array = Array.Empty(); @@ -85,10 +85,10 @@ private static void DrawList( using (new EditorGUI.DisabledScope(newElement == null)) if (GUILayout.Button(addButton)) { - Debug.Assert(newElement != null, nameof(newElement) + " != null"); + if (newElement == null) throw new InvalidOperationException(); T element; ArrayUtility.Add(ref array, element = newElement()); - onAdded(element); + onAdded?.Invoke(element); } } @@ -101,7 +101,7 @@ protected override void OnInspectorGUIInner() DrawList(ref component.merges, AAOL10N.Tr("MergeToonLitMaterial:button:Add Merged Material"), (componentMerge, i) => { - DrawList(ref componentMerge.source, AAOL10N.Tr("MergeToonLitMaterial:button:Add Source"), (mergeSource, _2) => + DrawList(ref componentMerge.source, AAOL10N.Tr("MergeToonLitMaterial:button:Add Source"), (mergeSource, _) => { var found = _materials.FirstOrDefault(x => x.index == mergeSource.materialIndex); _candidateNames[0] = found.mat != null ? found.mat.name : "(invalid)"; @@ -166,8 +166,8 @@ private void OnEnable() .GetMaterials(component.GetComponent(), component); _materials = _upstreamMaterials .Select((mat, index) => (mat, index)) - .Where(x => x.mat.shader == Assets.ToonLitShader) - .ToArray(); + .Where(x => x.mat?.shader == Assets.ToonLitShader) + .ToArray()!; OnChanged(dirty: false); } } diff --git a/Editor/Inspector/RemoveMeshByBlendShapeEditor.cs b/Editor/Inspector/RemoveMeshByBlendShapeEditor.cs index 25c1e74e8..efd0e48a5 100644 --- a/Editor/Inspector/RemoveMeshByBlendShapeEditor.cs +++ b/Editor/Inspector/RemoveMeshByBlendShapeEditor.cs @@ -7,9 +7,9 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(RemoveMeshByBlendShape))] internal class RemoveMeshByBlendShapeEditor : AvatarTagComponentEditorBase { - private PrefabSafeSet.EditorUtil _shapeKeysSet; - private SerializedProperty _toleranceProp; - private SkinnedMeshRenderer _renderer; + private PrefabSafeSet.EditorUtil _shapeKeysSet = null!; // initialized in OnEnable + private SerializedProperty _toleranceProp = null!; // initialized in OnEnable + private SkinnedMeshRenderer? _renderer; public bool automaticallySetWeightWhenToggle; private void OnEnable() @@ -31,7 +31,7 @@ protected override void OnInspectorGUIInner() EditModePreview.MeshPreviewController.ShowPreviewControl(component); - if (!_renderer) + if (_renderer == null) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ToggleLeft( @@ -86,7 +86,7 @@ protected override void OnInspectorGUIInner() if (existence != element.Contains) { element.SetExistence(existence); - if (automaticallySetWeightWhenToggle) + if (automaticallySetWeightWhenToggle && _renderer != null) { var shapeIndex = _renderer.sharedMesh.GetBlendShapeIndex(shapeKeyName); if (shapeIndex != -1) diff --git a/Editor/Inspector/RemoveMeshByMaskEditor.cs b/Editor/Inspector/RemoveMeshByMaskEditor.cs index b05fb9018..e2a4c8b7c 100644 --- a/Editor/Inspector/RemoveMeshByMaskEditor.cs +++ b/Editor/Inspector/RemoveMeshByMaskEditor.cs @@ -1,5 +1,3 @@ -using System.Linq; -using JetBrains.Annotations; using Unity.Collections; using UnityEditor; using UnityEngine; @@ -9,8 +7,8 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(RemoveMeshByMask))] internal class RemoveMeshByMaskEditor : AvatarTagComponentEditorBase { - private SerializedProperty _materials; - private SkinnedMeshRenderer _renderer; + private SerializedProperty _materials = null!; // Initialized in OnEnable + private SkinnedMeshRenderer _renderer = null!; // Initialized in OnEnable public bool automaticallySetWeightWhenToggle; private void OnEnable() @@ -107,7 +105,7 @@ protected override void OnInspectorGUIInner() serializedObject.ApplyModifiedProperties(); } - [CanBeNull] TextureImporter GetTextureImporter(Texture2D texture) + TextureImporter? GetTextureImporter(Texture2D texture) { var path = AssetDatabase.GetAssetPath(texture); if (string.IsNullOrEmpty(path)) diff --git a/Editor/Inspector/RemoveMeshInBoxEditor.cs b/Editor/Inspector/RemoveMeshInBoxEditor.cs index 5d432b6b0..d0ee15725 100644 --- a/Editor/Inspector/RemoveMeshInBoxEditor.cs +++ b/Editor/Inspector/RemoveMeshInBoxEditor.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; @@ -10,8 +9,8 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(RemoveMeshInBox))] internal class RemoveMeshInBoxEditor : AvatarTagComponentEditorBase { - private SerializedProperty _boxes; - private string _editingBoxPropPath; + private SerializedProperty _boxes = null!; // Initialized in OnEnable + private string? _editingBoxPropPath; private readonly Dictionary _eulerAngles = new Dictionary(); @@ -36,11 +35,11 @@ protected override void OnInspectorGUIInner() [CustomPropertyDrawer(typeof(RemoveMeshInBox.BoundingBox))] class BoundingBoxEditor : PropertyDrawer { - [CanBeNull] private static RemoveMeshInBoxEditor _upstreamEditor; + private static RemoveMeshInBoxEditor? _upstreamEditor; public readonly struct EditorScope : IDisposable { - private readonly RemoveMeshInBoxEditor _oldEditor; + private readonly RemoveMeshInBoxEditor? _oldEditor; public EditorScope(RemoveMeshInBoxEditor editor) { @@ -84,7 +83,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten using (new GUILayout.HorizontalScope()) { - if (_upstreamEditor) + if (_upstreamEditor != null) { var editingCurrent = _upstreamEditor._editingBoxPropPath == property.propertyPath; if (GUI.Button(position, editingCurrent ? "Finish Editing Box" : "Edit This Box")) @@ -107,7 +106,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten EditorGUI.PropertyField(position, sizeProp); position.y += EditorGUIUtility.standardVerticalSpacing + vector3Height; - if (!_upstreamEditor || + if (_upstreamEditor == null || !_upstreamEditor._eulerAngles.TryGetValue(property.propertyPath, out var eulerCache) || eulerCache.value != rotationProp.quaternionValue) { @@ -127,7 +126,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten eulerCache = (quot, euler); } - if (_upstreamEditor) + if (_upstreamEditor != null) _upstreamEditor._eulerAngles[property.propertyPath] = eulerCache; EditorGUI.EndProperty(); diff --git a/Editor/Inspector/TraceAndOptimizeEditor.cs b/Editor/Inspector/TraceAndOptimizeEditor.cs index 441d33873..e3adbafa8 100644 --- a/Editor/Inspector/TraceAndOptimizeEditor.cs +++ b/Editor/Inspector/TraceAndOptimizeEditor.cs @@ -6,18 +6,16 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(TraceAndOptimize))] internal class TraceAndOptimizeEditor : AvatarGlobalComponentEditorBase { - private SerializedProperty _freezeBlendShape; - private SerializedProperty _removeUnusedObjects; - private SerializedProperty _preserveEndBone; - private SerializedProperty _removeZeroSizedPolygons; - private SerializedProperty _optimizePhysBone; - private SerializedProperty _optimizeAnimator; - private SerializedProperty _mergeSkinnedMesh; - private SerializedProperty _allowShuffleMaterialSlots; - private SerializedProperty _animatorOptimizerEnabled; - private SerializedProperty _animatorOptimizerEnd; - private SerializedProperty _mmdWorldCompatibility; - private SerializedProperty _advancedSettings; + private SerializedProperty _freezeBlendShape = null!; // Initialized in OnEnable + private SerializedProperty _removeUnusedObjects = null!; // Initialized in OnEnable + private SerializedProperty _preserveEndBone = null!; // Initialized in OnEnable + private SerializedProperty _removeZeroSizedPolygons = null!; // Initialized in OnEnable + private SerializedProperty _optimizePhysBone = null!; // Initialized in OnEnable + private SerializedProperty _optimizeAnimator = null!; // Initialized in OnEnable + private SerializedProperty _mergeSkinnedMesh = null!; // Initialized in OnEnable + private SerializedProperty _allowShuffleMaterialSlots = null!; // Initialized in OnEnable + private SerializedProperty _mmdWorldCompatibility = null!; // Initialized in OnEnable + private SerializedProperty _advancedSettings = null!; // Initialized in OnEnable private GUIContent _advancedSettingsLabel = new GUIContent(); private GUIContent _debugOptionsLabel = new GUIContent(); @@ -61,10 +59,6 @@ protected override void OnInspectorGUIInner() EditorGUI.indentLevel--; } -#if !UNITY_2021_3_OR_NEWER - if (_optimizeAnimator.boolValue) - EditorGUILayout.HelpBox(AAOL10N.Tr("TraceAndOptimize:OptimizeAnimator:Unity2019"), MessageType.Info); -#endif _advancedSettingsLabel.text = AAOL10N.Tr("TraceAndOptimize:prop:advancedOptimization"); AdvancedOpened = EditorGUILayout.Foldout(AdvancedOpened, _advancedSettingsLabel); if (AdvancedOpened) diff --git a/Editor/Inspector/UnusedBonesByReferencesToolEditor.cs b/Editor/Inspector/UnusedBonesByReferencesToolEditor.cs index 4020df5b2..8dfcf6552 100644 --- a/Editor/Inspector/UnusedBonesByReferencesToolEditor.cs +++ b/Editor/Inspector/UnusedBonesByReferencesToolEditor.cs @@ -9,8 +9,8 @@ namespace Anatawa12.AvatarOptimizer [CustomEditor(typeof(UnusedBonesByReferencesTool))] class UnusedBonesByReferencesToolEditor : AvatarGlobalComponentEditorBase { - private SerializedProperty _preserveEndBone; - private SerializedProperty _detectExtraChild; + private SerializedProperty _preserveEndBone = null!; // Initialized in OnEnable + private SerializedProperty _detectExtraChild = null!; // Initialized in OnEnable private void OnEnable() { @@ -61,4 +61,4 @@ protected override void OnInspectorGUIInner() } } } -} \ No newline at end of file +} diff --git a/Editor/MaskTextureEditor/Inspector.cs b/Editor/MaskTextureEditor/Inspector.cs index c362718d2..5f52783b2 100644 --- a/Editor/MaskTextureEditor/Inspector.cs +++ b/Editor/MaskTextureEditor/Inspector.cs @@ -77,7 +77,7 @@ public static void DrawFields( EditorGUILayout.PropertyField(mode); } - private static Texture2D CreateTexture(Vector2Int size, Color color) + private static Texture2D? CreateTexture(Vector2Int size, Color color) { var path = EditorUtility.SaveFilePanelInProject( AAOL10N.Tr("MaskTextureEditor:create"), @@ -100,7 +100,7 @@ private static Texture2D CreateTexture(Vector2Int size, Color color) AssetDatabase.ImportAsset(path); - var importer = AssetImporter.GetAtPath(path) as TextureImporter; + var importer = (TextureImporter)AssetImporter.GetAtPath(path); importer.isReadable = true; importer.SaveAndReimport(); diff --git a/Editor/MaskTextureEditor/TexturePainter.cs b/Editor/MaskTextureEditor/TexturePainter.cs index 2fc5dc536..c98fe0872 100644 --- a/Editor/MaskTextureEditor/TexturePainter.cs +++ b/Editor/MaskTextureEditor/TexturePainter.cs @@ -17,19 +17,19 @@ internal class TexturePainter : ScriptableObject private Color _brushColor = Color.black; [SerializeField] - private RenderTexture _target = null; + private RenderTexture _target = null!; // Initialized by Init and Load [SerializeField] - private RenderTexture _buffer = null; + private RenderTexture _buffer = null!; // Initialized by Init and Load [SerializeField] - private Material _fillMaterial = null; + private Material _fillMaterial = null!; // Initialized by Init and Load [SerializeField] - private Material _paintMaterial = null; + private Material _paintMaterial = null!; // Initialized by Init and Load [SerializeField] - private Material _inverseMaterial = null; + private Material _inverseMaterial = null!; // Initialized by Init and Load public float BrushSize { get => _brushSize; set => _brushSize = value; } public Color BrushColor { get => _brushColor; set => _brushColor = value; } @@ -114,11 +114,7 @@ public void Save(Texture2D texture) { RenderTexture.active = _target; -#if UNITY_2021_2_OR_NEWER texture.Reinitialize(_target.width, _target.height); -#else - texture.Resize(_target.width, _target.height); -#endif texture.ReadPixels(new Rect(Vector2.zero, TextureSize), 0, 0); texture.Apply(); @@ -159,27 +155,27 @@ private void OnDestroy() if (_target != null) { DestroyImmediate(_target); - _target = null; + _target = null!; // resetting } if (_buffer != null) { DestroyImmediate(_buffer); - _buffer = null; + _buffer = null!; // resetting } if (_fillMaterial != null) { DestroyImmediate(_fillMaterial); - _fillMaterial = null; + _fillMaterial = null!; // resetting } if (_paintMaterial != null) { DestroyImmediate(_paintMaterial); - _paintMaterial = null; + _paintMaterial = null!; // resetting } if (_inverseMaterial != null) { DestroyImmediate(_inverseMaterial); - _inverseMaterial = null; + _inverseMaterial = null!; // resetting } } } diff --git a/Editor/MaskTextureEditor/TextureUndoStack.cs b/Editor/MaskTextureEditor/TextureUndoStack.cs index a0fee039a..cbd91066b 100644 --- a/Editor/MaskTextureEditor/TextureUndoStack.cs +++ b/Editor/MaskTextureEditor/TextureUndoStack.cs @@ -20,13 +20,13 @@ private void Awake() } [SerializeField] - private RenderTexture _target = null; + private RenderTexture _target = null!; // initialized by Init [SerializeField] - private List _stack = null; + private List _stack = null!; // initialized by Init [SerializeField] - private Counter _counter = null; + private Counter _counter = null!; // initialized by Init public bool CanUndo => _counter.Count > 1; public bool CanRedo => _counter.Count < _stack.Count; @@ -131,12 +131,12 @@ private void OnDestroy() DestroyImmediate(texture); } } - _stack = null; + _stack = null!; // resetting } if (_counter != null) { DestroyImmediate(_counter); - _counter = null; + _counter = null!; // resetting } } } diff --git a/Editor/MaskTextureEditor/UvMapDrawer.cs b/Editor/MaskTextureEditor/UvMapDrawer.cs index f40c42afc..b3f550ba6 100644 --- a/Editor/MaskTextureEditor/UvMapDrawer.cs +++ b/Editor/MaskTextureEditor/UvMapDrawer.cs @@ -8,17 +8,17 @@ namespace Anatawa12.AvatarOptimizer.MaskTextureEditor internal class UvMapDrawer : ScriptableObject { [SerializeField] - private SkinnedMeshRenderer _renderer = null; + private SkinnedMeshRenderer _renderer = null!; // Initialized by Init [SerializeField] private int _subMesh = 0; - private Mesh _mesh = null; + private Mesh? _mesh = null; private int _meshDirtyCount = 0; - private Vector2[] _points = null; - private Vector3[] _buffer = null; - private int[] _lineIndices = null; - private int[] _removedLineIndices = null; + private Vector2[]? _points = null; + private Vector3[]? _buffer = null; + private int[]? _lineIndices = null; + private int[]? _removedLineIndices = null; private void Awake() { @@ -45,6 +45,8 @@ public void Draw(Rect rect) _meshDirtyCount = EditorUtility.GetDirtyCount(_mesh); CollectPointsAndLineIndices(); + _ = _buffer![0]; // initialized by CollectPointsAndLineIndices + _ = _points![0]; // initialized by CollectPointsAndLineIndices } // Draw the main texture if present @@ -90,8 +92,8 @@ private void CollectPointsAndLineIndices() } else { - var lines = CollectLines(_mesh, _subMesh); - _points = _mesh.uv; + var lines = CollectLines(_mesh!, _subMesh); + _points = _mesh!.uv; _buffer = new Vector3[_points.Length]; _lineIndices = FlattenLineIndices(lines); _removedLineIndices = new int[0]; diff --git a/Editor/MaskTextureEditor/Window.cs b/Editor/MaskTextureEditor/Window.cs index a23260f85..fce301fef 100644 --- a/Editor/MaskTextureEditor/Window.cs +++ b/Editor/MaskTextureEditor/Window.cs @@ -37,13 +37,13 @@ private static class Events private const float BrushSizeFactor = 0.1f; [SerializeField] - private SkinnedMeshRenderer _renderer = null; + private SkinnedMeshRenderer _renderer = null!; // Initialized by Open [SerializeField] private int _subMesh = 0; [SerializeField] - private Texture2D _texture = null; + private Texture2D? _texture = null; [SerializeField] private Vector2 _viewPosition = Vector2.zero; @@ -58,23 +58,18 @@ private static class Events private bool _requestResetView = true; [SerializeField] - private UvMapDrawer _uvMapDrawer = null; + private UvMapDrawer _uvMapDrawer = null!; // Initialized by Open [SerializeField] - private TexturePainter _texturePainter = null; + private TexturePainter _texturePainter = null!; // Initialized by Open [SerializeField] - private TextureUndoStack _textureUndoStack = null; + private TextureUndoStack _textureUndoStack = null!; // Initialized by Open [SerializeField] private int _previewTextureInstanceIdWhenSaved = 0; -#if !UNITY_2020_2_OR_NEWER - private bool hasUnsavedChanges = false; - private string saveChangesMessage = string.Empty; -#endif - - public static Window Instance + public static Window? Instance { get { @@ -148,7 +143,6 @@ public void SafeClose() } case 2: { - DiscardChanges(); Close(); break; } @@ -429,14 +423,9 @@ private void HandleEvents(Rect rect) _viewPosition = Vector2.Max(_viewPosition, Vector2.zero); } -#if UNITY_2020_2_OR_NEWER public override void SaveChanges() { base.SaveChanges(); -#else - private void SaveChanges() - { -#endif var path = AssetDatabase.GetAssetPath(_texture); var texture = new Texture2D(0, 0); @@ -448,7 +437,7 @@ private void SaveChanges() AssetDatabase.ImportAsset(path); - var importer = AssetImporter.GetAtPath(path) as TextureImporter; + var importer = (TextureImporter)AssetImporter.GetAtPath(path); importer.isReadable = true; importer.SaveAndReimport(); @@ -469,32 +458,22 @@ private void SaveChanges() } } -#if UNITY_2020_2_OR_NEWER - public override void DiscardChanges() - { - base.DiscardChanges(); -#else - private void DiscardChanges() - { -#endif - } - private void OnDestroy() { if (_uvMapDrawer != null) { DestroyImmediate(_uvMapDrawer); - _uvMapDrawer = null; + _uvMapDrawer = null!; // reset } if (_texturePainter != null) { DestroyImmediate(_texturePainter); - _texturePainter = null; + _texturePainter = null!; // reset } if (_textureUndoStack != null) { DestroyImmediate(_textureUndoStack); - _textureUndoStack = null; + _textureUndoStack = null!; // reset } } } diff --git a/Editor/MergePhysBoneEditorModificationUtils.cs b/Editor/MergePhysBoneEditorModificationUtils.cs index 2a712f636..c2feee93c 100644 --- a/Editor/MergePhysBoneEditorModificationUtils.cs +++ b/Editor/MergePhysBoneEditorModificationUtils.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using VRC.Dynamics; using Object = UnityEngine.Object; @@ -14,56 +13,56 @@ internal abstract partial class MergePhysBoneEditorModificationUtils { // ReSharper disable MemberCanBePrivate.Global private readonly SerializedObject _serializedObject; - private SerializedObject _sourcePhysBone; + private SerializedObject? _sourcePhysBone; protected readonly SerializedProperty MakeParent; private readonly List _props = new List(); - [NotNull] protected readonly ValueConfigProp Version; + protected readonly ValueConfigProp Version; #region == Transform == // rootTransform // ignoreTransforms - [NotNull] protected readonly EndpointPositionConfigProp EndpointPosition; + protected readonly EndpointPositionConfigProp EndpointPosition; // multiChildType #endregion #region == Forces == - [NotNull] protected readonly ValueConfigProp IntegrationType; - [NotNull] protected readonly CurveConfigProp Pull; + protected readonly ValueConfigProp IntegrationType; + protected readonly CurveConfigProp Pull; // spring a.k.a. Momentum - [NotNull] protected readonly CurveConfigProp Spring; - [NotNull] protected readonly CurveConfigProp Stiffness; - [NotNull] protected readonly CurveConfigProp Gravity; - [NotNull] protected readonly CurveConfigProp GravityFalloff; - [NotNull] protected readonly ValueConfigProp ImmobileType; - [NotNull] protected readonly CurveConfigProp Immobile; + protected readonly CurveConfigProp Spring; + protected readonly CurveConfigProp Stiffness; + protected readonly CurveConfigProp Gravity; + protected readonly CurveConfigProp GravityFalloff; + protected readonly ValueConfigProp ImmobileType; + protected readonly CurveConfigProp Immobile; #endregion #region == Limits == - [NotNull] protected readonly ValueConfigProp LimitType; - [NotNull] protected readonly CurveConfigProp MaxAngleX; - [NotNull] protected readonly CurveConfigProp MaxAngleZ; - [NotNull] protected readonly CurveVector3ConfigProp LimitRotation; + protected readonly ValueConfigProp LimitType; + protected readonly CurveConfigProp MaxAngleX; + protected readonly CurveConfigProp MaxAngleZ; + protected readonly CurveVector3ConfigProp LimitRotation; #endregion #region == Collision == - [NotNull] protected readonly CurveConfigProp Radius; - [NotNull] protected readonly PermissionConfigProp AllowCollision; - [NotNull] protected readonly CollidersConfigProp Colliders; + protected readonly CurveConfigProp Radius; + protected readonly PermissionConfigProp AllowCollision; + protected readonly CollidersConfigProp Colliders; #endregion #region == Stretch & Squish == - [NotNull] protected readonly CurveConfigProp StretchMotion; - [NotNull] protected readonly CurveConfigProp MaxStretch; - [NotNull] protected readonly CurveConfigProp MaxSquish; + protected readonly CurveConfigProp StretchMotion; + protected readonly CurveConfigProp MaxStretch; + protected readonly CurveConfigProp MaxSquish; #endregion #region == Grab & Pose == - [NotNull] protected readonly PermissionConfigProp AllowGrabbing; - [NotNull] protected readonly PermissionConfigProp AllowPosing; - [NotNull] protected readonly ValueConfigProp GrabMovement; - [NotNull] protected readonly ValueConfigProp SnapToHand; + protected readonly PermissionConfigProp AllowGrabbing; + protected readonly PermissionConfigProp AllowPosing; + protected readonly ValueConfigProp GrabMovement; + protected readonly ValueConfigProp SnapToHand; #endregion #region == Options == - [NotNull] protected readonly NoOverrideValueConfigProp Parameter; - [NotNull] protected readonly NoOverrideValueConfigProp IsAnimated; - [NotNull] protected readonly ValueConfigProp ResetWhenDisabled; + protected readonly NoOverrideValueConfigProp Parameter; + protected readonly NoOverrideValueConfigProp IsAnimated; + protected readonly ValueConfigProp ResetWhenDisabled; #endregion protected readonly PrefabSafeSet.EditorUtil ComponentsSetEditorUtil; @@ -268,9 +267,9 @@ public void DoProcess() } } - protected SerializedProperty GetSourceProperty(string name) => _sourcePhysBone.FindProperty(name); + protected SerializedProperty GetSourceProperty(string name) => _sourcePhysBone!.FindProperty(name); - protected IEnumerable SourcePhysBones => _sourcePhysBone.targetObjects.Cast(); + protected IEnumerable SourcePhysBones => _sourcePhysBone!.targetObjects.Cast(); protected abstract void BeginPbConfig(); @@ -293,29 +292,28 @@ private bool NextSection(string name, string docTag) protected abstract void UnsupportedPbVersion(); - protected abstract void PbVersionProp([NotNull] string label, [NotNull] ValueConfigProp prop, bool forceOverride = false); + protected abstract void PbVersionProp(string label, ValueConfigProp prop, bool forceOverride = false); - protected abstract void PbProp([NotNull] string label, [NotNull] ValueConfigProp prop, bool forceOverride = false); + protected abstract void PbProp(string label, ValueConfigProp prop, bool forceOverride = false); - protected abstract void PbCurveProp([NotNull] string label, [NotNull] CurveConfigProp prop, bool forceOverride = false); + protected abstract void PbCurveProp(string label, CurveConfigProp prop, bool forceOverride = false); - protected abstract void PbPermissionProp([NotNull] string label, [NotNull] PermissionConfigProp prop, bool forceOverride = false); + protected abstract void PbPermissionProp(string label, PermissionConfigProp prop, bool forceOverride = false); - protected abstract void Pb3DCurveProp([NotNull] string label, - [NotNull] string pbXCurveLabel, - [NotNull] string pbYCurveLabel, - [NotNull] string pbZCurveLabel, - [NotNull] CurveVector3ConfigProp prop, + protected abstract void Pb3DCurveProp(string label, + string pbXCurveLabel, + string pbYCurveLabel, + string pbZCurveLabel, + CurveVector3ConfigProp prop, bool forceOverride = false); - protected abstract void CollidersProp([NotNull] string label, - [NotNull] CollidersConfigProp prop); + protected abstract void CollidersProp(string label, CollidersConfigProp prop); protected abstract class PropBase { public readonly SerializedProperty RootProperty; - public PropBase([NotNull] SerializedProperty rootProperty) + public PropBase(SerializedProperty rootProperty) { RootProperty = rootProperty ?? throw new ArgumentNullException(nameof(rootProperty)); } @@ -329,7 +327,7 @@ protected abstract class OverridePropBase: PropBase public bool IsOverride => IsOverrideProperty.boolValue; - public OverridePropBase([NotNull] SerializedProperty rootProperty) : base(rootProperty) + public OverridePropBase(SerializedProperty rootProperty) : base(rootProperty) { IsOverrideProperty = rootProperty.FindPropertyRelative("override"); } @@ -340,12 +338,12 @@ protected class CollidersConfigProp : PropBase { public readonly SerializedProperty OverrideProperty; public readonly SerializedProperty ValueProperty; - public SerializedProperty PhysBoneValue { get; private set; } + public SerializedProperty? PhysBoneValue { get; private set; } public readonly string PhysBoneValueName; public CollidersConfigProp( - [NotNull] SerializedProperty rootProperty, - [NotNull] string physBoneValueName) : base(rootProperty) + SerializedProperty rootProperty, + string physBoneValueName) : base(rootProperty) { OverrideProperty = rootProperty.FindPropertyRelative("override"); ValueProperty = rootProperty.FindPropertyRelative("value"); @@ -363,12 +361,12 @@ protected class EndpointPositionConfigProp : PropBase { public readonly SerializedProperty OverrideProperty; public readonly SerializedProperty ValueProperty; - public SerializedProperty PhysBoneValue { get; private set; } + public SerializedProperty? PhysBoneValue { get; private set; } public readonly string PhysBoneValueName; public EndpointPositionConfigProp( - [NotNull] SerializedProperty rootProperty, - [NotNull] string physBoneValueName) : base(rootProperty) + SerializedProperty rootProperty, + string physBoneValueName) : base(rootProperty) { OverrideProperty = rootProperty.FindPropertyRelative("override"); ValueProperty = rootProperty.FindPropertyRelative("value"); diff --git a/Editor/MergePhysBoneEditorModificationUtils.generated.cs b/Editor/MergePhysBoneEditorModificationUtils.generated.cs index d70ef3421..082318e2c 100644 --- a/Editor/MergePhysBoneEditorModificationUtils.generated.cs +++ b/Editor/MergePhysBoneEditorModificationUtils.generated.cs @@ -1,5 +1,6 @@ // -// generated by .MergePhysBoneEditorModificationUtils.ts +#nullable enable + #if AAO_VRCSDK3_AVATARS using System.Collections.Generic; @@ -13,16 +14,16 @@ partial class MergePhysBoneEditorModificationUtils protected partial class CurveConfigProp : OverridePropBase { public readonly SerializedProperty OverrideValue; - public SerializedProperty SourceValue { get; private set; } + public SerializedProperty? SourceValue { get; private set; } public readonly string PhysBoneValueName; public readonly SerializedProperty OverrideCurve; - public SerializedProperty SourceCurve { get; private set; } + public SerializedProperty? SourceCurve { get; private set; } public readonly string PhysBoneCurveName; public CurveConfigProp( - [NotNull] SerializedProperty rootProperty - , [NotNull] string physBoneValueName - , [NotNull] string physBoneCurveName + SerializedProperty rootProperty + , string physBoneValueName + , string physBoneCurveName ) : base(rootProperty) { OverrideValue = rootProperty.FindPropertyRelative("value"); @@ -36,30 +37,30 @@ internal override void UpdateSource(SerializedObject sourcePb) SourceValue = sourcePb.FindProperty(PhysBoneValueName); SourceCurve = sourcePb.FindProperty(PhysBoneCurveName); } - public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue; - public SerializedProperty GetCurveProperty(bool @override) => @override ? OverrideCurve : SourceCurve; + public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue!; + public SerializedProperty GetCurveProperty(bool @override) => @override ? OverrideCurve : SourceCurve!; } protected partial class CurveVector3ConfigProp : OverridePropBase { public readonly SerializedProperty OverrideValue; - public SerializedProperty SourceValue { get; private set; } + public SerializedProperty? SourceValue { get; private set; } public readonly string PhysBoneValueName; public readonly SerializedProperty OverrideCurveX; - public SerializedProperty SourceCurveX { get; private set; } + public SerializedProperty? SourceCurveX { get; private set; } public readonly string PhysBoneCurveXName; public readonly SerializedProperty OverrideCurveY; - public SerializedProperty SourceCurveY { get; private set; } + public SerializedProperty? SourceCurveY { get; private set; } public readonly string PhysBoneCurveYName; public readonly SerializedProperty OverrideCurveZ; - public SerializedProperty SourceCurveZ { get; private set; } + public SerializedProperty? SourceCurveZ { get; private set; } public readonly string PhysBoneCurveZName; public CurveVector3ConfigProp( - [NotNull] SerializedProperty rootProperty - , [NotNull] string physBoneValueName - , [NotNull] string physBoneCurveXName - , [NotNull] string physBoneCurveYName - , [NotNull] string physBoneCurveZName + SerializedProperty rootProperty + , string physBoneValueName + , string physBoneCurveXName + , string physBoneCurveYName + , string physBoneCurveZName ) : base(rootProperty) { OverrideValue = rootProperty.FindPropertyRelative("value"); @@ -79,24 +80,24 @@ internal override void UpdateSource(SerializedObject sourcePb) SourceCurveY = sourcePb.FindProperty(PhysBoneCurveYName); SourceCurveZ = sourcePb.FindProperty(PhysBoneCurveZName); } - public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue; - public SerializedProperty GetCurveXProperty(bool @override) => @override ? OverrideCurveX : SourceCurveX; - public SerializedProperty GetCurveYProperty(bool @override) => @override ? OverrideCurveY : SourceCurveY; - public SerializedProperty GetCurveZProperty(bool @override) => @override ? OverrideCurveZ : SourceCurveZ; + public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue!; + public SerializedProperty GetCurveXProperty(bool @override) => @override ? OverrideCurveX : SourceCurveX!; + public SerializedProperty GetCurveYProperty(bool @override) => @override ? OverrideCurveY : SourceCurveY!; + public SerializedProperty GetCurveZProperty(bool @override) => @override ? OverrideCurveZ : SourceCurveZ!; } protected partial class PermissionConfigProp : OverridePropBase { public readonly SerializedProperty OverrideValue; - public SerializedProperty SourceValue { get; private set; } + public SerializedProperty? SourceValue { get; private set; } public readonly string PhysBoneValueName; public readonly SerializedProperty OverrideFilter; - public SerializedProperty SourceFilter { get; private set; } + public SerializedProperty? SourceFilter { get; private set; } public readonly string PhysBoneFilterName; public PermissionConfigProp( - [NotNull] SerializedProperty rootProperty - , [NotNull] string physBoneValueName - , [NotNull] string physBoneFilterName + SerializedProperty rootProperty + , string physBoneValueName + , string physBoneFilterName ) : base(rootProperty) { OverrideValue = rootProperty.FindPropertyRelative("value"); @@ -110,18 +111,18 @@ internal override void UpdateSource(SerializedObject sourcePb) SourceValue = sourcePb.FindProperty(PhysBoneValueName); SourceFilter = sourcePb.FindProperty(PhysBoneFilterName); } - public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue; - public SerializedProperty GetFilterProperty(bool @override) => @override ? OverrideFilter : SourceFilter; + public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue!; + public SerializedProperty GetFilterProperty(bool @override) => @override ? OverrideFilter : SourceFilter!; } protected partial class ValueConfigProp : OverridePropBase { public readonly SerializedProperty OverrideValue; - public SerializedProperty SourceValue { get; private set; } + public SerializedProperty? SourceValue { get; private set; } public readonly string PhysBoneValueName; public ValueConfigProp( - [NotNull] SerializedProperty rootProperty - , [NotNull] string physBoneValueName + SerializedProperty rootProperty + , string physBoneValueName ) : base(rootProperty) { OverrideValue = rootProperty.FindPropertyRelative("value"); @@ -132,17 +133,17 @@ internal override void UpdateSource(SerializedObject sourcePb) { SourceValue = sourcePb.FindProperty(PhysBoneValueName); } - public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue; + public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue!; } protected partial class NoOverrideValueConfigProp : PropBase { public readonly SerializedProperty OverrideValue; - public SerializedProperty SourceValue { get; private set; } + public SerializedProperty? SourceValue { get; private set; } public readonly string PhysBoneValueName; public NoOverrideValueConfigProp( - [NotNull] SerializedProperty rootProperty - , [NotNull] string physBoneValueName + SerializedProperty rootProperty + , string physBoneValueName ) : base(rootProperty) { OverrideValue = rootProperty.FindPropertyRelative("value"); @@ -153,7 +154,7 @@ internal override void UpdateSource(SerializedObject sourcePb) { SourceValue = sourcePb.FindProperty(PhysBoneValueName); } - public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue; + public SerializedProperty GetValueProperty(bool @override) => @override ? OverrideValue : SourceValue!; } } } diff --git a/Editor/MergeSkinnedMeshWindow.cs b/Editor/MergeSkinnedMeshWindow.cs index 1ba3b2c2e..84f605407 100644 --- a/Editor/MergeSkinnedMeshWindow.cs +++ b/Editor/MergeSkinnedMeshWindow.cs @@ -5,7 +5,7 @@ namespace Anatawa12.AvatarOptimizer { internal class MergeSkinnedMeshWindow : EditorWindow { - private Mesh _mesh; + private Mesh? _mesh; private void OnGUI() { @@ -51,7 +51,7 @@ private void OnGUI() } } - private void SelectableLabelField(string label, T value) + private void SelectableLabelField(string label, T value) where T : notnull { var fullRect = EditorGUILayout.GetControlRect(true); var elementRect = EditorGUI.PrefixLabel(fullRect, new GUIContent(label)); diff --git a/Editor/ObjectMapping/AnimationObjectMapper.cs b/Editor/ObjectMapping/AnimationObjectMapper.cs index ed5184d6a..73d88fdd2 100644 --- a/Editor/ObjectMapping/AnimationObjectMapper.cs +++ b/Editor/ObjectMapping/AnimationObjectMapper.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -12,8 +11,7 @@ internal class AnimationObjectMapper readonly BeforeGameObjectTree _beforeGameObjectTree; readonly ObjectMapping _objectMapping; - private readonly Dictionary _pathsCache = - new Dictionary(); + private readonly Dictionary _pathsCache = new(); public AnimationObjectMapper(GameObject rootGameObject, BeforeGameObjectTree beforeGameObjectTree, ObjectMapping objectMapping) @@ -24,8 +22,7 @@ public AnimationObjectMapper(GameObject rootGameObject, BeforeGameObjectTree bef } // null means nothing to map - [CanBeNull] - private MappedGameObjectInfo GetGameObjectInfo(string path) + private MappedGameObjectInfo? GetGameObjectInfo(string path) { if (_pathsCache.TryGetValue(path, out var info)) return info; @@ -38,7 +35,7 @@ private MappedGameObjectInfo GetGameObjectInfo(string path) else { var foundGameObject = EditorUtility.InstanceIDToObject(tree.InstanceId) as GameObject; - var newPath = foundGameObject + var newPath = foundGameObject != null ? Utils.RelativePath(_rootGameObject.transform, foundGameObject.transform) : null; @@ -56,17 +53,16 @@ class MappedGameObjectInfo readonly BeforeGameObjectTree _tree; // null means removed gameObject - [CanBeNull] public readonly string NewPath; + public readonly string? NewPath; - public MappedGameObjectInfo(ObjectMapping objectMapping, string newPath, - BeforeGameObjectTree tree) + public MappedGameObjectInfo(ObjectMapping objectMapping, string? newPath, BeforeGameObjectTree tree) { _objectMapping = objectMapping; NewPath = newPath; _tree = tree; } - public (int instanceId, ComponentInfo) GetComponentByType(Type type) + public (int instanceId, ComponentInfo?) GetComponentByType(Type type) { if (!_tree.ComponentInstanceIdByType.TryGetValue(type, out var instanceId)) return (instanceId, null); // Nothing to map @@ -74,8 +70,7 @@ public MappedGameObjectInfo(ObjectMapping objectMapping, string newPath, } } - [CanBeNull] - public string MapPath(string srcPath, Type type) + public string? MapPath(string srcPath, Type type) { var gameObjectInfo = GetGameObjectInfo(srcPath); if (gameObjectInfo == null) @@ -105,8 +100,7 @@ public string MapPath(string srcPath, Type type) } } - [CanBeNull] - public (string path, Type type, string propertyName)[] MapBinding(string path, Type type, string propertyName) + public (string path, Type type, string propertyName)[]? MapBinding(string path, Type type, string propertyName) { var gameObjectInfo = GetGameObjectInfo(path); if (gameObjectInfo == null) @@ -159,13 +153,18 @@ public string MapPath(string srcPath, Type type) } else { - var component = new ComponentOrGameObject(EditorUtility.InstanceIDToObject(componentInfo.MergedInto)); - if (!component) return Array.Empty<(string path, Type type, string propertyName)>(); // this means removed. + var component = + new ComponentOrGameObject(EditorUtility.InstanceIDToObject(componentInfo.MergedInto)); + if (!component) + return Array.Empty<(string path, Type type, string propertyName)>(); // this means removed. var newPath = Utils.RelativePath(_rootGameObject.transform, component.transform); - if (newPath == null) return Array.Empty<(string path, Type type, string propertyName)>(); // this means moved to out of the animator scope + if (newPath == null) + return Array + .Empty<(string path, Type type, string propertyName + )>(); // this means moved to out of the animator scope if (path == newPath) return null; - return new []{ (newPath, type, propertyName) }; + return new[] { (newPath, type, propertyName) }; } } else @@ -173,7 +172,8 @@ public string MapPath(string srcPath, Type type) // The component is not merged & no prop mapping so process GameObject mapping var component = EditorUtility.InstanceIDToObject(instanceId); - if (!component) return Array.Empty<(string path, Type type, string propertyName)>(); // this means removed + if (!component) + return Array.Empty<(string path, Type type, string propertyName)>(); // this means removed if (gameObjectInfo.NewPath == null) return Array.Empty<(string path, Type type, string propertyName)>(); if (path == gameObjectInfo.NewPath) return null; diff --git a/Editor/ObjectMapping/ObjectMapping.cs b/Editor/ObjectMapping/ObjectMapping.cs index 259da4d45..9327087ea 100644 --- a/Editor/ObjectMapping/ObjectMapping.cs +++ b/Editor/ObjectMapping/ObjectMapping.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; @@ -21,7 +20,7 @@ public ObjectMapping( _componentMapping = componentMapping; } - public bool MapComponentInstance(int instanceId, out Component component) + public bool MapComponentInstance(int instanceId, out Component? component) { if (instanceId == 0) { @@ -47,18 +46,17 @@ public bool MapComponentInstance(int instanceId, out Component component) return false; } - internal BeforeGameObjectTree GetBeforeGameObjectTree(GameObject rootGameObject) => + internal BeforeGameObjectTree? GetBeforeGameObjectTree(GameObject rootGameObject) => _beforeTree.TryGetValue(rootGameObject.GetInstanceID(), out var tree) ? tree : null; // null means nothing to map - [CanBeNull] - public ComponentInfo GetComponentMapping(int instanceId) => + public ComponentInfo? GetComponentMapping(int instanceId) => _componentMapping.TryGetValue(instanceId, out var info) ? info : null; - [CanBeNull] public AnimationObjectMapper CreateAnimationMapper(GameObject rootGameObject) { - if (!_beforeTree.TryGetValue(rootGameObject.GetInstanceID(), out var beforeTree)) return null; + if (!_beforeTree.TryGetValue(rootGameObject.GetInstanceID(), out var beforeTree)) + throw new InvalidOperationException($"rootGameObject {rootGameObject} is not in the mapping"); return new AnimationObjectMapper(rootGameObject, beforeTree, this); } } @@ -66,10 +64,10 @@ class BeforeGameObjectTree { public readonly int InstanceId; public readonly int ParentInstanceId; - [NotNull] public readonly string Name; - [NotNull] public readonly IReadOnlyDictionary ComponentInstanceIdByType; - [NotNull] public readonly int[] ComponentInstanceIds; - [NotNull] public readonly BeforeGameObjectTree[] Children; + public readonly string Name; + public readonly IReadOnlyDictionary ComponentInstanceIdByType; + public readonly int[] ComponentInstanceIds; + public readonly BeforeGameObjectTree[] Children; public bool HasSlashInNameInDirectChildren { get; private set; } public bool HasSlashInNameInChildren { get; private set; } @@ -114,8 +112,7 @@ public void InitializeRecursive() HasSlashInNameInChildren = Children.Any(x => x.HasSlashInNameInChildren || x.Name.Contains('/')); } - [CanBeNull] - public BeforeGameObjectTree ResolvePath(string relative) => + public BeforeGameObjectTree? ResolvePath(string relative) => relative == "" ? this : ResolvePathAll(relative).FirstOrDefault(); private IEnumerable ResolvePathAll(string relative) @@ -167,8 +164,8 @@ public ComponentInfo(int instanceId, int mergedInto, Type type, { public static readonly PropertyDescriptor Removed = default; public readonly int InstanceId; - [NotNull] public readonly Type Type; - [NotNull] public readonly string Name; + public readonly Type Type; + public readonly string Name; public PropertyDescriptor(int instanceId, Type type, string name) { @@ -177,20 +174,10 @@ public PropertyDescriptor(int instanceId, Type type, string name) Name = name; } - public override int GetHashCode() - { - unchecked - { - var hashCode = InstanceId; - hashCode = (hashCode * 397) ^ Type.GetHashCode(); - hashCode = (hashCode * 397) ^ Name.GetHashCode(); - return hashCode; - } - } - + public override int GetHashCode() => HashCode.Combine(InstanceId, Type, Name); public bool Equals(PropertyDescriptor other) => InstanceId == other.InstanceId && Type == other.Type && Name == other.Name; - public override bool Equals(object obj) => obj is PropertyDescriptor other && Equals(other); + public override bool Equals(object? obj) => obj is PropertyDescriptor other && Equals(other); public static bool operator ==(PropertyDescriptor left, PropertyDescriptor right) => left.Equals(right); public static bool operator !=(PropertyDescriptor left, PropertyDescriptor right) => !left.Equals(right); } @@ -244,7 +231,7 @@ static class Props { private const string Enabled = "m_Enabled"; // enabled for behaviour-like components - public static string EnabledFor(Object obj) => obj == null ? Enabled : EnabledFor(obj.GetType()); + public static string EnabledFor(Object? obj) => obj == null ? Enabled : EnabledFor(obj.GetType()); public static string EnabledFor(Type type) => type == typeof(Animator) ? VProp.AnimatorEnabledAsBehavior : Enabled; diff --git a/Editor/ObjectMapping/ObjectMappingBuilder.cs b/Editor/ObjectMapping/ObjectMappingBuilder.cs index 5d30c7eca..58262ad2b 100644 --- a/Editor/ObjectMapping/ObjectMappingBuilder.cs +++ b/Editor/ObjectMapping/ObjectMappingBuilder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -21,10 +20,10 @@ internal class ObjectMappingBuilder private readonly IReadOnlyDictionary _beforeGameObjectInfos; // key: instanceId - private readonly Dictionary _originalComponentInfos = new Dictionary(); - private readonly Dictionary _componentInfos = new Dictionary(); + private readonly Dictionary _originalComponentInfos = new(); + private readonly Dictionary _componentInfos = new(); - public ObjectMappingBuilder([NotNull] GameObject rootObject) + public ObjectMappingBuilder(GameObject rootObject) { if (!rootObject) throw new ArgumentNullException(nameof(rootObject)); var transforms = rootObject.GetComponentsInChildren(true); @@ -103,16 +102,16 @@ public ObjectMapping BuildObjectMapping() class AnimationPropertyInfo { - [CanBeNull] public readonly BuildingComponentInfo Component; - [CanBeNull] public readonly string Name; - [CanBeNull] public AnimationPropertyInfo MergedTo { get; private set; } + public readonly BuildingComponentInfo? Component; + public readonly string? Name; + public AnimationPropertyInfo? MergedTo { get; private set; } private MappedPropertyInfo? _mappedPropertyInfo; public TPropInfo PropertyInfo; - [CanBeNull] public List CopiedTo { get; private set; } + public List? CopiedTo { get; private set; } - public AnimationPropertyInfo([NotNull] BuildingComponentInfo component, [NotNull] string name) + public AnimationPropertyInfo(BuildingComponentInfo component, string name) { Component = component ?? throw new ArgumentNullException(nameof(component)); Name = name ?? throw new ArgumentNullException(nameof(name)); @@ -122,7 +121,9 @@ private AnimationPropertyInfo() { } - public static readonly AnimationPropertyInfo RemovedMarker = new AnimationPropertyInfo(); + // TODO: split type for removed marker? + // If we do that, we can remove nullabile from Component and Name + public static readonly AnimationPropertyInfo RemovedMarker = new(); public void MergeTo(AnimationPropertyInfo property) { @@ -140,7 +141,7 @@ public void CopyTo(AnimationPropertyInfo property) public MappedPropertyInfo GetMappedInfo() { - if (_mappedPropertyInfo is MappedPropertyInfo property) return property; + if (_mappedPropertyInfo is { } property) return property; property = ComputeMappedInfo(); _mappedPropertyInfo = property; return property; @@ -149,8 +150,8 @@ public MappedPropertyInfo GetMappedInfo() private MappedPropertyInfo ComputeMappedInfo() { if (this == RemovedMarker) return MappedPropertyInfo.Removed; - - System.Diagnostics.Debug.Assert(Component != null, nameof(Component) + " != null"); + + if (Component == null) throw new InvalidOperationException("Component is null"); if (MergedTo != null) { @@ -170,9 +171,9 @@ private MappedPropertyInfo ComputeMappedInfo() { // this is edge if (CopiedTo == null || CopiedTo.Count == 0) - return new MappedPropertyInfo(Component.InstanceId, Component.Type, Name); + return new MappedPropertyInfo(Component.InstanceId, Component.Type, Name!); - var descriptor = new PropertyDescriptor(Component.InstanceId, Component.Type, Name); + var descriptor = new PropertyDescriptor(Component.InstanceId, Component.Type, Name!); var copied = new List { descriptor }; foreach (var copiedTo in CopiedTo) @@ -189,13 +190,11 @@ class BuildingComponentInfo : AnimationComponentInfo internal readonly Type Type; // id in this -> id in merged - private BuildingComponentInfo _mergedInto; + private BuildingComponentInfo? _mergedInto; - private readonly Dictionary _beforePropertyIds = - new Dictionary(); + private readonly Dictionary _beforePropertyIds = new(); - private readonly Dictionary _afterPropertyIds = - new Dictionary(); + private readonly Dictionary _afterPropertyIds = new(); public BuildingComponentInfo(ComponentOrGameObject component) { @@ -205,7 +204,6 @@ public BuildingComponentInfo(ComponentOrGameObject component) internal bool IsMerged => _mergedInto != null; - [NotNull] private AnimationPropertyInfo GetProperty(string name, bool remove = false) { if (_afterPropertyIds.TryGetValue(name, out var prop)) @@ -223,13 +221,13 @@ private AnimationPropertyInfo GetProperty(string name, bool remove = false) } } - public void MergedTo([NotNull] BuildingComponentInfo mergeTo) + public void MergedTo(BuildingComponentInfo mergeTo) { if (Type == typeof(Transform)) throw new Exception("Merging Transform is not supported!"); if (_mergedInto != null) throw new InvalidOperationException("Already merged"); _mergedInto = mergeTo ?? throw new ArgumentNullException(nameof(mergeTo)); foreach (var property in _afterPropertyIds.Values) - property.MergeTo(mergeTo.GetProperty(property.Name)); + property.MergeTo(mergeTo.GetProperty(property.Name!)); _afterPropertyIds.Clear(); } diff --git a/Editor/ObjectMapping/ObjectMappingContext.cs b/Editor/ObjectMapping/ObjectMappingContext.cs index edd0f67e3..1f0fefffe 100644 --- a/Editor/ObjectMapping/ObjectMappingContext.cs +++ b/Editor/ObjectMapping/ObjectMappingContext.cs @@ -1,8 +1,6 @@ -using System; using System.Linq; using Anatawa12.AvatarOptimizer.API; using Anatawa12.AvatarOptimizer.APIInternal; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; @@ -13,7 +11,7 @@ namespace Anatawa12.AvatarOptimizer { internal class ObjectMappingContext : IExtensionContext { - public ObjectMappingBuilder MappingBuilder { get; private set; } + public ObjectMappingBuilder? MappingBuilder { get; private set; } public void OnActivate(BuildContext context) { @@ -59,7 +57,7 @@ public void OnDeactivate(BuildContext context) } var serialized = new SerializedObject(component); - AnimatorControllerMapper mapper = null; + AnimatorControllerMapper? mapper = null; foreach (var p in serialized.ObjectReferenceProperties()) { @@ -135,11 +133,11 @@ public override bool TryMapProperty(string property, out API.MappedPropertyInfo private class ComponentInfo : MappedComponentInfo where T : Object { - [NotNull] private readonly ComponentInfo _info; + private readonly ComponentInfo _info; - public ComponentInfo([NotNull] ComponentInfo info) => _info = info; + public ComponentInfo(ComponentInfo info) => _info = info; - public override T MappedComponent => EditorUtility.InstanceIDToObject(_info.MergedInto) as T; + public override T MappedComponent => (T)EditorUtility.InstanceIDToObject(_info.MergedInto); public override bool TryMapProperty(string property, out API.MappedPropertyInfo found) { found = default; @@ -149,7 +147,7 @@ public override bool TryMapProperty(string property, out API.MappedPropertyInfo found = new API.MappedPropertyInfo(MappedComponent, property); return true; } - if (mappedProp.MappedProperty.Name == null) return false; + if (mappedProp.MappedProperty == default) return false; found = new API.MappedPropertyInfo( EditorUtility.InstanceIDToObject(mappedProp.MappedProperty.InstanceId), @@ -169,7 +167,7 @@ public AnimatorControllerMapper(AnimationObjectMapper mapping) _mapping = mapping; } - protected override Object CustomClone(Object o) + protected override Object? CustomClone(Object o) { if (o is AnimationClip clip) { @@ -250,7 +248,7 @@ protected override Object CustomClone(Object o) return newClip; } -#if AAO_VRCSDK3_AVATARS_ANIMATOR_PLAY_AUDIO +#if AAO_VRCSDK3_AVATARS else if (o is VRC.SDKBase.VRC_AnimatorPlayAudio playAudio) { using (new MappedScope(this)) diff --git a/Editor/ObjectMapping/PropertyInfo.cs b/Editor/ObjectMapping/PropertyInfo.cs index b4f07030d..3eee88da1 100644 --- a/Editor/ObjectMapping/PropertyInfo.cs +++ b/Editor/ObjectMapping/PropertyInfo.cs @@ -1,19 +1,19 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Anatawa12.AvatarOptimizer.AnimatorParsersV2; -using JetBrains.Annotations; using Object = UnityEngine.Object; namespace Anatawa12.AvatarOptimizer { internal struct PropertyInfo : IPropertyInfo { - [CanBeNull] private RootPropModNode _floatNode; - [CanBeNull] private RootPropModNode _objectNode; + private RootPropModNode? _floatNode; + private RootPropModNode? _objectNode; - [CanBeNull] public RootPropModNode FloatNode => _floatNode?.Normalize(); - [CanBeNull] public RootPropModNode ObjectNode => _objectNode?.Normalize(); + public RootPropModNode? FloatNode => _floatNode?.Normalize(); + public RootPropModNode? ObjectNode => _objectNode?.Normalize(); public void MergeTo(ref PropertyInfo property) { @@ -21,8 +21,8 @@ public void MergeTo(ref PropertyInfo property) MergeNode(ref property._objectNode, ref _objectNode); } - private static void MergeNode([CanBeNull] ref RootPropModNode mergeTo, - [CanBeNull] ref RootPropModNode merge) + private static void MergeNode(ref RootPropModNode? mergeTo, ref RootPropModNode? merge) + where T : notnull { if (merge == null || merge.IsEmpty) return; if (mergeTo == null || merge.IsEmpty) @@ -42,8 +42,8 @@ public void CopyTo(ref PropertyInfo property) CopyNode(ref property._objectNode, _objectNode); } - private static void CopyNode([CanBeNull] ref RootPropModNode mergeTo, - [CanBeNull] RootPropModNode merge) + private static void CopyNode(ref RootPropModNode? mergeTo, RootPropModNode? merge) + where T : notnull { if (merge == null || merge.IsEmpty) return; if (mergeTo == null || merge.IsEmpty) @@ -82,7 +82,7 @@ public void AddModification(ComponentPropModNodeBase node, bool alwaysAp internal static class AnimationComponentInfoExtensions { - public static void ImportModifications([NotNull] this ObjectMappingBuilder builder, + public static void ImportModifications(this ObjectMappingBuilder builder, RootPropModNodeContainer modifications) { foreach (var ((target, prop), value) in modifications.FloatNodes) @@ -92,44 +92,43 @@ public static void ImportModifications([NotNull] this ObjectMappingBuilder info, string property) + public static bool ContainsFloat(this AnimationComponentInfo info, string property) { if (info == null) throw new ArgumentNullException(nameof(info)); return info.TryGetPropertyInfo(property).FloatNode != null; } - [Pure] - [ContractAnnotation("=> true, animation: notnull; => false, animation: null")] - public static bool TryGetFloat([NotNull] this AnimationComponentInfo info, string property, - [CanBeNull] out RootPropModNode animation) + [JetBrains.Annotations.Pure] + public static bool TryGetFloat(this AnimationComponentInfo info, string property, + [NotNullWhen(true)] out RootPropModNode? animation) { if (info == null) throw new ArgumentNullException(nameof(info)); animation = info.TryGetPropertyInfo(property).FloatNode; return animation != null; } - public static void AddModification([NotNull] this AnimationComponentInfo info, string property, + public static void AddModification(this AnimationComponentInfo info, string property, ComponentPropModNodeBase node, bool alwaysApplied) { if (info == null) throw new ArgumentNullException(nameof(info)); info.GetPropertyInfo(property).AddModification(node, alwaysApplied); } - public static bool ContainsObject([NotNull] this AnimationComponentInfo info, string property) + public static bool ContainsObject(this AnimationComponentInfo info, string property) { if (info == null) throw new ArgumentNullException(nameof(info)); return info.TryGetPropertyInfo(property).ObjectNode != null; } - public static bool TryGetObject([NotNull] this AnimationComponentInfo info, string property, - out RootPropModNode animation) + public static bool TryGetObject(this AnimationComponentInfo info, string property, + [NotNullWhen(true)] out RootPropModNode? animation) { if (info == null) throw new ArgumentNullException(nameof(info)); animation = info.TryGetPropertyInfo(property).ObjectNode; return animation != null; } - public static void AddModification([NotNull] this AnimationComponentInfo info, string property, + public static void AddModification(this AnimationComponentInfo info, string property, ComponentPropModNodeBase node, bool alwaysApplied) { if (info == null) throw new ArgumentNullException(nameof(info)); @@ -137,17 +136,17 @@ public static void AddModification([NotNull] this AnimationComponentInfo)> GetAllFloatProperties( - [NotNull] this AnimationComponentInfo info) + this AnimationComponentInfo info) { return info.GetAllPropertyInfo.Where(x => x.info.FloatNode != null) - .Select(x => (x.name, x.info.FloatNode)); + .Select(x => (x.name, x.info.FloatNode!)); } public static IEnumerable<(string, RootPropModNode)> GetAllObjectProperties( - [NotNull] this AnimationComponentInfo info) + this AnimationComponentInfo info) { return info.GetAllPropertyInfo.Where(x => x.info.ObjectNode != null) - .Select(x => (x.name, x.info.ObjectNode)); + .Select(x => (x.name, x.info.ObjectNode!)); } } -} \ No newline at end of file +} diff --git a/Editor/OptimizerPlugin.cs b/Editor/OptimizerPlugin.cs index 3e300f31c..4509dbaa6 100644 --- a/Editor/OptimizerPlugin.cs +++ b/Editor/OptimizerPlugin.cs @@ -23,7 +23,7 @@ protected override void Configure() var components = ctx.AvatarRootObject.GetComponentInChildren(true); if (components && CheckForUpdate.OutOfDate) BuildLog.LogInfo("CheckForUpdate:out-of-date", - CheckForUpdate.LatestVersionName, CheckForUpdate.CurrentVersionName); + CheckForUpdate.LatestVersionName!, CheckForUpdate.CurrentVersionName); }) .Then.Run(Processors.UnusedBonesByReferencesToolEarlyProcessor.Instance) .Then.Run("Early: MakeChildren", @@ -77,7 +77,6 @@ protected override void Configure() ; }); -#if UNITY_2021_3_OR_NEWER // animator optimizer is written in newer C# so requires 2021.3 or newer mainSequence.Run(Processors.AnimatorOptimizer.InitializeAnimatorOptimizer.Instance) #if AAO_VRCSDK3_AVATARS @@ -87,7 +86,6 @@ protected override void Configure() .Then.Run(Processors.AnimatorOptimizer.MergeBlendTreeLayer.Instance) .Then.Run(Processors.AnimatorOptimizer.RemoveMeaninglessLayer.Instance) ; -#endif } protected override void OnUnhandledException(Exception e) diff --git a/Editor/Processors/ClearEndpointPositionProcessor.cs b/Editor/Processors/ClearEndpointPositionProcessor.cs index 12332d805..a12093f33 100644 --- a/Editor/Processors/ClearEndpointPositionProcessor.cs +++ b/Editor/Processors/ClearEndpointPositionProcessor.cs @@ -54,4 +54,4 @@ internal static bool WalkChildrenAndSetEndpoint(Transform target, VRCPhysBoneBas } } -#endif \ No newline at end of file +#endif diff --git a/Editor/Processors/InitializeAnimatorOptimizer.cs b/Editor/Processors/InitializeAnimatorOptimizer.cs index 8444e4065..98860f183 100644 --- a/Editor/Processors/InitializeAnimatorOptimizer.cs +++ b/Editor/Processors/InitializeAnimatorOptimizer.cs @@ -1,14 +1,10 @@ -#if UNITY_2021_3_OR_NEWER - using System; using System.Collections.Generic; using Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; using UnityEngine; -using UnityEngine.Profiling; using Object = UnityEngine.Object; #if AAO_VRCSDK3_AVATARS @@ -126,25 +122,24 @@ protected override void Execute(BuildContext context, TraceAndOptimizeState stat class AnimatorControllerCloner : DeepCloneHelper { - [NotNull] private readonly BuildContext _context; - [CanBeNull] private readonly IReadOnlyDictionary _mapping; + private readonly BuildContext _context; + private readonly IReadOnlyDictionary? _mapping; - private AnimatorControllerCloner([NotNull] BuildContext context, - [CanBeNull] IReadOnlyDictionary mapping) + private AnimatorControllerCloner(BuildContext context, + IReadOnlyDictionary? mapping) { _context = context ?? throw new ArgumentNullException(nameof(context)); _mapping = mapping; } - public static AnimatorController Clone([NotNull] BuildContext context, - [NotNull] RuntimeAnimatorController runtimeController) + public static AnimatorController Clone(BuildContext context, RuntimeAnimatorController runtimeController) { var (controller, mapping) = ACUtils.GetControllerAndOverrides(runtimeController); return new AnimatorControllerCloner(context, mapping).MapObject(controller); } - protected override Object CustomClone(Object o) + protected override Object? CustomClone(Object o) { if (o is AnimationClip clip) { @@ -178,5 +173,3 @@ protected override ComponentSupport GetComponentSupport(Object o) } } } - -#endif diff --git a/Editor/Processors/MergeBoneProcessor.cs b/Editor/Processors/MergeBoneProcessor.cs index 20f3027fa..1cb197316 100644 --- a/Editor/Processors/MergeBoneProcessor.cs +++ b/Editor/Processors/MergeBoneProcessor.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; using Object = UnityEngine.Object; @@ -79,7 +78,7 @@ protected override void Execute(BuildContext context) using (ErrorReport.WithContextObject(renderer)) { var meshInfo2 = context.GetMeshInfoFor(renderer); - if (meshInfo2.Bones.Any(x => x.Transform && mergeMapping.ContainsKey(x.Transform))) + if (meshInfo2.Bones.Any(x => x.Transform != null && mergeMapping.ContainsKey(x.Transform))) DoBoneMap2(meshInfo2, mergeMapping); } } @@ -150,7 +149,7 @@ private void DoBoneMap2(MeshInfo2 meshInfo2, Dictionary me // first, simply update bone weights by updating BindPose foreach (var bone in meshInfo2.Bones) { - if (!bone.Transform) continue; + if (bone.Transform == null) continue; if (mergeMapping.TryGetValue(bone.Transform, out var mapped)) { bone.Bindpose = mapped.worldToLocalMatrix * bone.Transform.localToWorldMatrix * bone.Bindpose; @@ -221,7 +220,7 @@ private void DoBoneMap2(MeshInfo2 meshInfo2, Dictionary me var boneMapping = new Dictionary(); foreach (var grouping in meshInfo2.Bones.GroupBy(x => new BoneUniqKey(x))) { - if (!grouping.Key.Transform) continue; + if (grouping.Key.Transform == null) continue; primaryBones.TryGetValue(grouping.Key.Transform, out var primaryBone); var group = grouping.ToArray(); if (group.All(x => x != primaryBone)) @@ -267,7 +266,7 @@ private bool ValidBindPose(Matrix4x4 matrix) private readonly struct BoneUniqKey : IEquatable { private readonly Matrix4x4 _bindPoseInfo; - public readonly Transform Transform; + public readonly Transform? Transform; public BoneUniqKey(Bone bone) { @@ -293,12 +292,10 @@ public BoneUniqKey(Bone bone) public bool Equals(BoneUniqKey other) => Equals(Transform, other.Transform) && _bindPoseInfo == other._bindPoseInfo; - public override bool Equals(object obj) => obj is BoneUniqKey other && Equals(other); - - public override int GetHashCode() => - unchecked(_bindPoseInfo.GetHashCode() * 397) ^ (Transform != null ? Transform.GetHashCode() : 0); + public override bool Equals(object? obj) => obj is BoneUniqKey other && Equals(other); + public override int GetHashCode() => HashCode.Combine(_bindPoseInfo, Transform); } - + public struct MergeBoneTransParentInfo { @@ -307,7 +304,7 @@ public struct MergeBoneTransParentInfo public bool ActiveSelf; public string NamePrefix; - public (Vector3 position, Quaternion rotation, Vector3 scale) ComputeInfoFor([NotNull] Transform child) + public (Vector3 position, Quaternion rotation, Vector3 scale) ComputeInfoFor(Transform child) { if (child == null) throw new ArgumentNullException(nameof(child)); @@ -324,7 +321,7 @@ public struct MergeBoneTransParentInfo return (matrix.offset, rotation, scale); } - public static MergeBoneTransParentInfo Compute([NotNull] Transform parent, [CanBeNull] Transform root) + public static MergeBoneTransParentInfo Compute(Transform parent, Transform? root) { var parentRotation = Quaternion.identity; var parentMatrix = Matrix4x4.identity; diff --git a/Editor/Processors/MergePhysBoneProcessor.cs b/Editor/Processors/MergePhysBoneProcessor.cs index d36fd6392..e5029a990 100644 --- a/Editor/Processors/MergePhysBoneProcessor.cs +++ b/Editor/Processors/MergePhysBoneProcessor.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.AnimatorParsersV2; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEngine; @@ -33,7 +32,7 @@ protected override void Execute(BuildContext context) private static bool SetEq(IEnumerable a, IEnumerable b) => new HashSet(a).SetEquals(b); - internal static void DoMerge(MergePhysBone merge, [CanBeNull] BuildContext context) + internal static void DoMerge(MergePhysBone merge, BuildContext? context) { var sourceComponents = merge.componentsSet.GetAsList(); if (sourceComponents.Count == 0) return; diff --git a/Editor/Processors/OriginalState.cs b/Editor/Processors/OriginalState.cs index 6df7258f5..991fd0002 100644 --- a/Editor/Processors/OriginalState.cs +++ b/Editor/Processors/OriginalState.cs @@ -14,7 +14,7 @@ internal class OriginalState // avatar root => transform matrix (root.worldToLocalMatrix * transform.localToWorldMatrix) // we can local to world by root.localToWorldMatrix * thisMatrix private Dictionary _originalTransforms = new Dictionary(); - public Transform AvatarRoot { get; set; } + public Transform AvatarRoot { get; set; } = null!; // set by FetchOriginalStatePass public void Register(Transform transform) { @@ -44,4 +44,4 @@ protected override void Execute(BuildContext context) } } } -} \ No newline at end of file +} diff --git a/Editor/Processors/ParseAnimator.cs b/Editor/Processors/ParseAnimator.cs index 13277fe09..835057fe3 100644 --- a/Editor/Processors/ParseAnimator.cs +++ b/Editor/Processors/ParseAnimator.cs @@ -17,8 +17,8 @@ protected override void Execute(BuildContext context) var modifications = new AnimatorParser(traceAndOptimize.MmdWorldCompatibility) .GatherAnimationModifications(context); context.Extension() - .MappingBuilder + .MappingBuilder! .ImportModifications(modifications); } } -} \ No newline at end of file +} diff --git a/Editor/Processors/RemoveInvalidProperties.cs b/Editor/Processors/RemoveInvalidProperties.cs index 387556368..02781f1a3 100644 --- a/Editor/Processors/RemoveInvalidProperties.cs +++ b/Editor/Processors/RemoveInvalidProperties.cs @@ -43,7 +43,7 @@ static class AnimatablePropertyRegistry private static readonly Dictionary> _properties = new Dictionary>(); - public static Func Get(BuildContext context, Object component) + public static Func? Get(BuildContext context, Object component) { if (!_properties.TryGetValue(component.GetType(), out var func)) return null; @@ -78,7 +78,7 @@ static AnimatablePropertyRegistry() }); } - private static bool TrySubProp(string prop, string subProp, out string sub) + private static bool TrySubProp(string prop, string subProp, out string? sub) { sub = null; if (!prop.StartsWith(subProp + '.')) return false; diff --git a/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs b/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs index c5ea84ba4..94792e45f 100644 --- a/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; @@ -29,7 +28,7 @@ protected EditSkinnedMeshProcessor(TComponent component) protected bool Equals(EditSkinnedMeshProcessor other) => Component == other.Component; - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj != null && (ReferenceEquals(this, obj) || obj.GetType() == this.GetType() && Equals((EditSkinnedMeshProcessor)obj)); @@ -45,7 +44,7 @@ internal interface IEditSkinnedMeshProcessor EditSkinnedMeshComponent Component { get; } void Process(BuildContext context, MeshInfo2 target); - [NotNull] IMeshInfoComputer GetComputer([NotNull] IMeshInfoComputer upstream); + IMeshInfoComputer GetComputer(IMeshInfoComputer upstream); } enum EditSkinnedMeshProcessorOrder : int @@ -60,21 +59,21 @@ enum EditSkinnedMeshProcessorOrder : int internal interface IMeshInfoComputer { (string name, float weight)[] BlendShapes(); - Material[] Materials(bool fast = true); + Material?[] Materials(bool fast = true); } internal class AbstractMeshInfoComputer : IMeshInfoComputer { - private readonly IMeshInfoComputer _upstream; + private readonly IMeshInfoComputer? _upstream; - public AbstractMeshInfoComputer(IMeshInfoComputer upstream) + public AbstractMeshInfoComputer(IMeshInfoComputer? upstream) { _upstream = upstream; } public virtual (string name, float weight)[] BlendShapes() => _upstream?.BlendShapes() ?? Array.Empty<(string, float)>(); - public virtual Material[] Materials(bool fast = true) => _upstream?.Materials(fast) ?? Array.Empty(); + public virtual Material?[] Materials(bool fast = true) => _upstream?.Materials(fast) ?? Array.Empty(); } diff --git a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs index 8520f6ae0..340c4d0ec 100644 --- a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs @@ -34,12 +34,6 @@ public override void Process(BuildContext context, MeshInfo2 target) var (subMeshIndexMap, materials) = GenerateSubMeshMapping(meshInfos, Component.doNotMergeMaterials.GetAsSet()); -#if !UNITY_2021_2_OR_NEWER - Profiler.BeginSample("ShiftIndex For Unity Bug"); - ShiftIndexForUnityBugWorkaround(context, meshInfos, materials, subMeshIndexMap); - Profiler.EndSample(); -#endif - DoMerge(context, target, meshInfos, subMeshIndexMap, materials); MergeBounds(target, meshInfos); @@ -76,7 +70,7 @@ bool RendererEnabled(Renderer x) Profiler.BeginSample("Merge PreserveBlendShapes"); { var state = context.GetState(); - HashSet thisPreserve = null; + HashSet? thisPreserve = null; foreach (var skinnedRenderer in skinnedMeshRenderers) { if (!state.PreserveBlendShapes.TryGetValue(skinnedRenderer, out var preserve)) continue; @@ -191,7 +185,7 @@ from meshInfo2 in meshInfos } - public static (int[][] subMeshIndexMap, List<(MeshTopology topology, Material material)> materials) + public static (int[][] subMeshIndexMap, List<(MeshTopology topology, Material? material)> materials) GenerateSubMeshMapping( MeshInfo2[] meshInfos, HashSet doNotMerges) @@ -211,7 +205,7 @@ public static void DoMerge( MeshInfo2 target, MeshInfo2[] meshInfos, int[][] subMeshIndexMap, - List<(MeshTopology topology, Material material)> materials + List<(MeshTopology topology, Material? material)> materials ) { target.ClearMeshData(); target.SubMeshes.Capacity = Math.Max(target.SubMeshes.Capacity, materials.Count); @@ -292,15 +286,14 @@ MeshInfo2[] meshInfos Profiler.BeginSample("Update Bounds"); var sourceRootBone = target.RootBone; - var updateBounds = sourceRootBone && target.Bounds == default; - if (updateBounds) + if (sourceRootBone != null && target.Bounds == default) { var newBoundMin = Vector3.positiveInfinity; var newBoundMax = Vector3.negativeInfinity; foreach (var meshInfo in meshInfos) { - if (meshInfo.RootBone) + if (meshInfo.RootBone != null) { foreach (var inSource in meshInfo.Bounds.Corners()) { @@ -339,7 +332,7 @@ bool removeEmptyRendererObject Profiler.BeginSample("Postprocess Source Renderers"); if (removeEmptyRendererObject) { - var boneTransforms = new HashSet(target.Bones.Select(x => x.Transform)); + var boneTransforms = new HashSet(target.Bones.Select(x => x.Transform)); foreach (var rendererGameObject in from meshInfo in meshInfos @@ -391,8 +384,8 @@ private static void MaterialParameterAnimationWarnings(MeshInfo2[] sourceRendere if (component.TryGetObject($"m_Materials.Array.data[{i}]", out var objectNode)) materials.AddRange(objectNode.Value.PossibleValues?.OfType().Where(x => x) ?? Enumerable.Empty()); - if (meshInfo2.SubMeshes[i].SharedMaterial) - materials.Add(meshInfo2.SubMeshes[i].SharedMaterial); + if (meshInfo2.SubMeshes[i].SharedMaterial is {} newMaterial) + materials.Add(newMaterial); } materialByMeshInfo2.Add((meshInfo2, materials)); } @@ -467,11 +460,11 @@ private static HashSet GetAnimationLocations(BuildContext con return locations; } - private static (int[][] mapping, List<(MeshTopology topology, Material material)> materials) - CreateMergedMaterialsAndSubMeshIndexMapping((MeshTopology topology, Material material)[][] sourceMaterials, + private static (int[][] mapping, List<(MeshTopology topology, Material? material)> materials) + CreateMergedMaterialsAndSubMeshIndexMapping((MeshTopology topology, Material? material)[][] sourceMaterials, HashSet doNotMerges) { - var resultMaterials = new List<(MeshTopology, Material)>(); + var resultMaterials = new List<(MeshTopology, Material?)>(); var resultIndices = new int[sourceMaterials.Length][]; for (var i = 0; i < sourceMaterials.Length; i++) @@ -483,7 +476,7 @@ private static (int[][] mapping, List<(MeshTopology topology, Material material) { var material = materials[j]; var foundIndex = resultMaterials.IndexOf(material); - if (doNotMerges.Contains(material.material) || foundIndex == -1) + if (material.material != null && doNotMerges.Contains(material.material) || foundIndex == -1) { indices[j] = resultMaterials.Count; resultMaterials.Add(material); @@ -498,61 +491,6 @@ private static (int[][] mapping, List<(MeshTopology topology, Material material) return (resultIndices, resultMaterials); } -#if !UNITY_2021_2_OR_NEWER - // material slot #4 should not be animated to avoid Unity bug - // https://issuetracker.unity3d.com/issues/material-is-applied-to-two-slots-when-applying-material-to-a-single-slot-while-recording-animation - private static void ShiftIndexForUnityBugWorkaround( - BuildContext context, - MeshInfo2[] meshInfos, - List<(MeshTopology, Material)> materials, - int[][] subMeshIndexMap - ) - { - const int subMeshIndexToShiftIfAnimated = 4; - if (IsAnimatingTheSubMeshIndex(context, meshInfos, subMeshIndexMap, subMeshIndexToShiftIfAnimated)) - MakeHoleSubMesh(subMeshIndexMap, materials, subMeshIndexToShiftIfAnimated); - } - - private static bool IsAnimatingTheSubMeshIndex(BuildContext context, MeshInfo2[] meshInfos, - int[][] subMeshIndexMap, int targetSubMeshIndex) - { - for (var i = 0; i < subMeshIndexMap.Length; i++) - { - var indices = subMeshIndexMap[i]; - - for (var sourceSubMesh = 0; sourceSubMesh < indices.Length; sourceSubMesh++) - { - var destSubMesh = indices[sourceSubMesh]; - if (destSubMesh == targetSubMeshIndex) - { - var animationComponent = context.GetAnimationComponent(meshInfos[i].SourceRenderer); - if (animationComponent.ContainsObject($"m_Materials.Array.data[{sourceSubMesh}]")) - { - return true; - } - } - } - } - - return false; - } - - private static void MakeHoleSubMesh(int[][] subMeshIndexMap, List<(MeshTopology, Material)> materials, - int targetSubMeshIndex) - { - materials.Insert(targetSubMeshIndex, (MeshTopology.Triangles, null)); - - foreach (var indices in subMeshIndexMap) - { - for (var sourceSubMesh = 0; sourceSubMesh < indices.Length; sourceSubMesh++) - { - if (indices[sourceSubMesh] >= targetSubMeshIndex) - indices[sourceSubMesh]++; - } - } - } -#endif - public override IMeshInfoComputer GetComputer(IMeshInfoComputer upstream) => new MeshInfoComputer(this); class MeshInfoComputer : IMeshInfoComputer @@ -567,7 +505,7 @@ class MeshInfoComputer : IMeshInfoComputer .Distinct(BlendShapeNameComparator.Instance) .ToArray(); - public Material[] Materials(bool fast = true) + public Material?[] Materials(bool fast = true) { var sourceMaterials = _processor.SkinnedMeshRenderers.Select(EditSkinnedMeshComponentUtil.GetMaterials) .Concat(_processor.StaticMeshRenderers.Select(x => x.sharedMaterials)) @@ -583,7 +521,7 @@ public Material[] Materials(bool fast = true) private class BlendShapeNameComparator : IEqualityComparer<(string name, float weight)> { - public static readonly BlendShapeNameComparator Instance = new BlendShapeNameComparator(); + public static readonly BlendShapeNameComparator Instance = new(); public bool Equals((string name, float weight) x, (string name, float weight) y) { @@ -592,7 +530,7 @@ public bool Equals((string name, float weight) x, (string name, float weight) y) public int GetHashCode((string name, float weight) obj) { - return obj.name?.GetHashCode() ?? 0; + return obj.name.GetHashCode(); } } } diff --git a/Editor/Processors/SkinnedMeshes/MergeToonLitMaterialProcessor.cs b/Editor/Processors/SkinnedMeshes/MergeToonLitMaterialProcessor.cs index 2266ae176..6902c0260 100644 --- a/Editor/Processors/SkinnedMeshes/MergeToonLitMaterialProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/MergeToonLitMaterialProcessor.cs @@ -16,10 +16,10 @@ internal class MergeToonLitMaterialProcessor : EditSkinnedMeshProcessor - _helperMaterial ? _helperMaterial : _helperMaterial = new Material(Assets.MergeTextureHelper); + _helperMaterial != null ? _helperMaterial : _helperMaterial = new Material(Assets.MergeTextureHelper); public MergeToonLitMaterialProcessor(MergeToonLitMaterial component) : base(component) { @@ -114,7 +114,7 @@ public BitArray ComputeMergingIndices(int subMeshCount) return mergingIndices; } - private Material[] CreateMaterials(BitArray mergingIndices, Material[] upstream, bool fast) + private Material?[] CreateMaterials(BitArray mergingIndices, Material?[] upstream, bool fast) { var copied = upstream.Where((_, i) => !mergingIndices[i]); if (fast) @@ -135,7 +135,7 @@ private static Material CreateMaterial(Texture texture) return mat; } - public static Texture[] GenerateTextures(MergeToonLitMaterial config, Material[] materials, bool compress) + public static Texture[] GenerateTextures(MergeToonLitMaterial config, Material?[] materials, bool compress) { return config.merges.Select(x => GenerateTexture(x, materials, compress)).ToArray(); } @@ -254,7 +254,7 @@ private static RenderTextureFormat GetRenderTarget(MergeToonLitMaterial.MergedTe private static Texture GenerateTexture( MergeToonLitMaterial.MergeInfo mergeInfo, - Material[] materials, + Material?[] materials, bool compress ) { @@ -275,7 +275,7 @@ bool compress foreach (var source in mergeInfo.source) { - var sourceMat = materials[source.materialIndex]; + var sourceMat = materials[source.materialIndex]!; // selected material should not be null var sourceTex = sourceMat.GetTexture(MainTexProp); var sourceTexSt = sourceMat.GetVector(MainTexStProp); HelperMaterial.SetTexture(MainTexProp, sourceTex); @@ -327,7 +327,7 @@ class MeshInfoComputer : AbstractMeshInfoComputer public MeshInfoComputer(MergeToonLitMaterialProcessor processor, IMeshInfoComputer upstream) : base(upstream) => _processor = processor; - public override Material[] Materials(bool fast = true) + public override Material?[] Materials(bool fast = true) { var upstream = base.Materials(fast); return _processor.CreateMaterials(_processor.ComputeMergingIndices(upstream.Length), upstream, fast); diff --git a/Editor/Processors/SkinnedMeshes/RemoveMeshByMaskProcessor.cs b/Editor/Processors/SkinnedMeshes/RemoveMeshByMaskProcessor.cs index bba44efa3..fdd080dd2 100644 --- a/Editor/Processors/SkinnedMeshes/RemoveMeshByMaskProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/RemoveMeshByMaskProcessor.cs @@ -47,7 +47,7 @@ public override void Process(BuildContext context, MeshInfo2 target) { var originalMeshImporter = GetImporter(ObjectRegistry.GetReference(mask).Object as Texture2D); - TextureImporter GetImporter(Texture2D importingMesh) + TextureImporter? GetImporter(Texture2D? importingMesh) { if (!importingMesh) return null; var path = AssetDatabase.GetAssetPath(importingMesh); diff --git a/Editor/Processors/TraceAndOptimize/AutoMergeSkinnedMesh.cs b/Editor/Processors/TraceAndOptimize/AutoMergeSkinnedMesh.cs index d31074f11..ec55c85f9 100644 --- a/Editor/Processors/TraceAndOptimize/AutoMergeSkinnedMesh.cs +++ b/Editor/Processors/TraceAndOptimize/AutoMergeSkinnedMesh.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; using UnityEngine.Profiling; @@ -128,7 +127,7 @@ protected override void Execute(BuildContext context, TraceAndOptimizeState stat Profiler.BeginSample("Merge Meshes"); - Func)> createSubMeshes; + Func)> createSubMeshes; if (state.SkipMergeMaterials) createSubMeshes = CreateSubMeshesNoMerge; @@ -172,7 +171,7 @@ private void MergeStaticSkinnedMesh( Func gameObjectFactory, CategorizationKey key, List meshInfos, - Func)> createSubMeshes + Func)> createSubMeshes ) { // if there's no activeness animation, we merge them at root @@ -196,7 +195,7 @@ private void MergeAnimatingSkinnedMesh( Func gameObjectFactory, CategorizationKey key, List meshInfos, - Func)> createSubMeshes, + Func)> createSubMeshes, ObjectMappingBuilder mappingBuilder) { // if there is activeness animation, we have to decide the parent of merged mesh @@ -248,8 +247,7 @@ private void MergeAnimatingSkinnedMesh( removeEmptyRendererObject: false); } - [NotNull] - private static Transform ComputeCommonParent(IReadOnlyList meshInfos, [NotNull] Transform avatarRoot) + private static Transform ComputeCommonParent(IReadOnlyList meshInfos, Transform avatarRoot) { // if there is activeness animation, we have to decide the parent of merged mesh var commonParents = new HashSet( @@ -258,7 +256,7 @@ private static Transform ComputeCommonParent(IReadOnlyList meshInfos, commonParents.IntersectWith( meshInfo.SourceRenderer.transform.ParentEnumerable(root: avatarRoot)); - Transform commonParent = null; + Transform? commonParent = null; // we merge at the child-most common parent foreach (var someCommonParent in commonParents) { @@ -328,7 +326,6 @@ private static Transform CreateIntermediateGameObjects( return commonParent; } - [CanBeNull] private static (Activeness, EqualsHashSet<(bool initial, EqualsHashSet animations)>)? GetActivenessInformation(BuildContext context, Renderer component) { @@ -376,8 +373,7 @@ private static (Activeness, EqualsHashSet<(bool initial, EqualsHashSet + private static EqualsHashSet<(string property, AnimationLocation location)>? GetAnimationLocationsForRendererAnimation( BuildContext context, Component component) { @@ -425,10 +421,10 @@ CategorizationKey key return newSkinnedMeshRenderer; } - public static (int[][], List<(MeshTopology, Material)>) CreateSubMeshesNoMerge(MeshInfo2[] meshInfos) + public static (int[][], List<(MeshTopology, Material?)>) CreateSubMeshesNoMerge(MeshInfo2[] meshInfos) { var subMeshIndexMap = new int[meshInfos.Length][]; - var materials = new List<(MeshTopology topology, Material material)>(); + var materials = new List<(MeshTopology topology, Material? material)>(); for (var i = 0; i < meshInfos.Length; i++) { var meshInfo = meshInfos[i]; @@ -444,22 +440,22 @@ public static (int[][], List<(MeshTopology, Material)>) CreateSubMeshesNoMerge(M return (subMeshIndexMap, materials); } - public static (int[][], List<(MeshTopology, Material)>) CreateSubMeshesMergeShuffling(MeshInfo2[] meshInfos) => + public static (int[][], List<(MeshTopology, Material?)>) CreateSubMeshesMergeShuffling(MeshInfo2[] meshInfos) => MergeSkinnedMeshProcessor.GenerateSubMeshMapping(meshInfos, new HashSet()); - public static (int[][], List<(MeshTopology, Material)>) CreateSubMeshesMergePreserveOrder(MeshInfo2[] meshInfos) + public static (int[][], List<(MeshTopology, Material?)>) CreateSubMeshesMergePreserveOrder(MeshInfo2[] meshInfos) { // merge consecutive submeshes with same material to one for simpler logic // note: both start and end are inclusive var reducedMeshInfos = - new LinkedList<((MeshTopology topology, Material material) info, (int start, int end) actualIndices)> + new LinkedList<((MeshTopology topology, Material? material) info, (int start, int end) actualIndices)> [meshInfos.Length]; for (var meshI = 0; meshI < meshInfos.Length; meshI++) { var meshInfo = meshInfos[meshI]; var reducedMeshInfo = - new LinkedList<((MeshTopology topology, Material material) info, (int start, int end) actualIndices + new LinkedList<((MeshTopology topology, Material? material) info, (int start, int end) actualIndices )>(); if (meshInfo.SubMeshes.Count > 0) @@ -490,7 +486,7 @@ public static (int[][], List<(MeshTopology, Material)>) CreateSubMeshesMergePres for (var i = 0; i < meshInfos.Length; i++) subMeshIndexMap[i] = new int[meshInfos[i].SubMeshes.Count]; - var materials = new List<(MeshTopology topology, Material material)>(); + var materials = new List<(MeshTopology topology, Material? material)>(); while (reducedMeshInfos.Any(x => x.First != null)) @@ -547,7 +543,7 @@ int GetNextAddingMeshIndex() return mostUsedMaterial; } - bool UsedByRest((MeshTopology topology, Material material) subMesh) + bool UsedByRest((MeshTopology topology, Material? material) subMesh) { foreach (var meshInfo in reducedMeshInfos) { @@ -717,35 +713,31 @@ public bool Equals(CategorizationKey other) SkinnedMotionVectors == other.SkinnedMotionVectors; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is CategorizationKey other && Equals(other); } public override int GetHashCode() { - unchecked - { - var hashCode = HasNormals.GetHashCode(); - hashCode = (hashCode * 397) ^ ActivenessAnimationLocations.GetHashCode(); - hashCode = (hashCode * 397) ^ RendererAnimationLocations.GetHashCode(); - hashCode = (hashCode * 397) ^ Activeness.GetHashCode(); - hashCode = (hashCode * 397) ^ Bounds.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)ShadowCastingMode; - hashCode = (hashCode * 397) ^ ReceiveShadows.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)LightProbeUsage; - hashCode = (hashCode * 397) ^ (int)ReflectionProbeUsage; - hashCode = (hashCode * 397) ^ AllowOcclusionWhenDynamic.GetHashCode(); - hashCode = (hashCode * 397) ^ (LightProbeProxyVolumeOverride != null - ? LightProbeProxyVolumeOverride.GetHashCode() - : 0); - hashCode = (hashCode * 397) ^ (ProbeAnchor != null ? ProbeAnchor.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (int)Quality; - hashCode = (hashCode * 397) ^ UpdateWhenOffscreen.GetHashCode(); - hashCode = (hashCode * 397) ^ (RootBone != null ? RootBone.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ SkinnedMotionVectors.GetHashCode(); - return hashCode; - } + var hashCode = new HashCode(); + hashCode.Add(HasNormals); + hashCode.Add(ActivenessAnimationLocations); + hashCode.Add(RendererAnimationLocations); + hashCode.Add(Activeness); + hashCode.Add(Bounds); + hashCode.Add(ShadowCastingMode); + hashCode.Add(ReceiveShadows); + hashCode.Add(LightProbeUsage); + hashCode.Add(ReflectionProbeUsage); + hashCode.Add(AllowOcclusionWhenDynamic); + hashCode.Add(LightProbeProxyVolumeOverride); + hashCode.Add(ProbeAnchor); + hashCode.Add(Quality); + hashCode.Add(UpdateWhenOffscreen); + hashCode.Add(RootBone); + hashCode.Add(SkinnedMotionVectors); + return hashCode.ToHashCode(); } } } diff --git a/Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs b/Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs index c7291b2b7..a3bdaa283 100644 --- a/Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs +++ b/Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs @@ -3,7 +3,6 @@ using System.Linq; using Anatawa12.AvatarOptimizer.APIInternal; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEngine; @@ -135,8 +134,8 @@ internal class Collector : API.ComponentDependencyCollector private readonly ComponentDependencyCollector _collector; private readonly GCComponentInfoHolder _componentInfos; private readonly HashSet _parameters; - private GCComponentInfo _info; - [CanBeNull] private IDependencyInfo _dependencyInfo; + private GCComponentInfo? _info; + private IDependencyInfo? _dependencyInfo; public Collector(ComponentDependencyCollector collector, GCComponentInfoHolder componentInfos, HashSet parameters) @@ -157,13 +156,13 @@ public void Init(GCComponentInfo info) public MeshInfo2 GetMeshInfoFor(SkinnedMeshRenderer renderer) => _collector._session.GetMeshInfoFor(renderer); - public override void MarkEntrypoint() => _info.MarkEntrypoint(); - public override void MarkHeavyBehaviour() => _info.MarkHeavyBehaviour(); - public override void MarkBehaviour() => _info.MarkBehaviour(); + public override void MarkEntrypoint() => _info!.MarkEntrypoint(); + public override void MarkHeavyBehaviour() => _info!.MarkHeavyBehaviour(); + public override void MarkBehaviour() => _info!.MarkBehaviour(); private API.ComponentDependencyInfo AddDependencyInternal( - [CanBeNull] GCComponentInfo info, - [CanBeNull] Component dependency, + GCComponentInfo? info, + Component? dependency, GCComponentInfo.DependencyType type = GCComponentInfo.DependencyType.Normal) { _dependencyInfo?.Finish(); @@ -178,10 +177,10 @@ private API.ComponentDependencyInfo AddDependencyInternal( return dependencyInfo; } - public override API.ComponentDependencyInfo AddDependency(Component dependant, Component dependency) => + public override API.ComponentDependencyInfo AddDependency(Component? dependant, Component? dependency) => AddDependencyInternal(_collector._componentInfos.TryGetInfo(dependant), dependency); - public override API.ComponentDependencyInfo AddDependency(Component dependency) => + public override API.ComponentDependencyInfo AddDependency(Component? dependency) => AddDependencyInternal(_info, dependency); internal override bool? GetAnimatedFlag(Component component, string animationProperty, bool currentValue) => @@ -203,13 +202,13 @@ public override API.PathDependencyInfo AddPathDependency(Transform dependency, T if (transforms.Count == 0) throw new ArgumentException("dependency is not child of root"); - if (transforms[transforms.Count - 1].parent != root) + if (transforms[^1].parent != root) throw new ArgumentException("dependency is not child of root"); if (!dependency.transform.IsChildOf(_collector._session.AvatarRootTransform)) return DummyPathDependencyInfo.Instance; - var dependencyInfo = new PathDependencyInfo(_info, transforms.ToArray()); + var dependencyInfo = new PathDependencyInfo(_info!, transforms.ToArray()); _dependencyInfo = dependencyInfo; return dependencyInfo; } @@ -218,7 +217,7 @@ public void AddParentDependency(Transform component) => AddDependencyInternal(_info, component.parent, GCComponentInfo.DependencyType.Parent) .EvenIfDependantDisabled(); - public void AddBoneDependency(Transform bone) => + public void AddBoneDependency(Transform? bone) => AddDependencyInternal(_info, bone, GCComponentInfo.DependencyType.Bone) .EvenIfDependantDisabled(); @@ -236,7 +235,7 @@ internal interface IDependencyInfo private class DummyComponentDependencyInfo : API.ComponentDependencyInfo { - public static DummyComponentDependencyInfo Instance { get; } = new DummyComponentDependencyInfo(); + public static DummyComponentDependencyInfo Instance { get; } = new(); public override API.ComponentDependencyInfo EvenIfDependantDisabled() => this; public override API.ComponentDependencyInfo OnlyIfTargetCanBeEnable() => this; @@ -246,8 +245,8 @@ private class ComponentDependencyInfo : API.ComponentDependencyInfo, IDependency { private readonly GCComponentInfoHolder _componentInfos; - [CanBeNull] private Component _dependency; - [NotNull] private readonly GCComponentInfo _dependantInformation; + private Component? _dependency; + private readonly GCComponentInfo _dependantInformation; private readonly GCComponentInfo.DependencyType _type; private bool _evenIfTargetIsDisabled = true; @@ -256,8 +255,8 @@ private class ComponentDependencyInfo : API.ComponentDependencyInfo, IDependency // ReSharper disable once NotNullOrRequiredMemberIsNotInitialized public ComponentDependencyInfo( GCComponentInfoHolder componentInfos, - [NotNull] GCComponentInfo dependantInformation, - [NotNull] Component component, + GCComponentInfo dependantInformation, + Component component, GCComponentInfo.DependencyType type = GCComponentInfo.DependencyType.Normal) { _componentInfos = componentInfos; @@ -275,7 +274,7 @@ public void Finish() private void SetToDictionary() { - Debug.Assert(_dependency != null, nameof(_dependency) + " != null"); + if (_dependency == null) throw new InvalidOperationException("Called after another call"); if (!_evenIfThisIsDisabled) { @@ -317,15 +316,15 @@ private class DummyPathDependencyInfo : API.PathDependencyInfo private class PathDependencyInfo : API.PathDependencyInfo, IDependencyInfo { - [CanBeNull] [ItemNotNull] private Transform[] _dependencies; - [NotNull] private readonly GCComponentInfo _dependantInformation; + private Transform[]? _dependencies; + private readonly GCComponentInfo _dependantInformation; private bool _evenIfThisIsDisabled; // ReSharper disable once NotNullOrRequiredMemberIsNotInitialized public PathDependencyInfo( - [NotNull] GCComponentInfo dependantInformation, - [NotNull] [ItemCanBeNull] Transform[] component) + GCComponentInfo dependantInformation, + Transform[] component) { _dependencies = component; _dependantInformation = dependantInformation; @@ -341,7 +340,7 @@ public void Finish() private void SetToDictionary() { - Debug.Assert(_dependencies != null, nameof(_dependencies) + " != null"); + if (_dependencies == null) throw new InvalidOperationException("Called after another call"); if (!_evenIfThisIsDisabled) { diff --git a/Editor/Processors/TraceAndOptimize/ConfigureRemoveZeroSizedPolygon.cs b/Editor/Processors/TraceAndOptimize/ConfigureRemoveZeroSizedPolygon.cs index 2a3cf1752..59885b8da 100644 --- a/Editor/Processors/TraceAndOptimize/ConfigureRemoveZeroSizedPolygon.cs +++ b/Editor/Processors/TraceAndOptimize/ConfigureRemoveZeroSizedPolygon.cs @@ -16,4 +16,4 @@ protected override void Execute(BuildContext context, TraceAndOptimizeState stat renderer.gameObject.GetOrAddComponent(); } } -} \ No newline at end of file +} diff --git a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs index 151a39521..0c8cfd30a 100644 --- a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs +++ b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs @@ -145,7 +145,7 @@ private void ActivenessAnimation(GCComponentInfoHolder componentInfos) resultSet.Remove(componentInfo.Component.transform); resultSet.ExceptWith(componentInfo.Component.transform.ParentEnumerable()); - Component commonActiveness; + Component? commonActiveness; // TODO: we may use all activeness with nested identity transform // if activeness animation is not changed if (resultSet.Count == 0) @@ -188,13 +188,13 @@ private void ActivenessAnimation(GCComponentInfoHolder componentInfos) if (commonActiveness is Transform) { - _context.Extension().MappingBuilder + _context.Extension().MappingBuilder! .RecordCopyProperty(commonActiveness.gameObject, Props.IsActive, componentInfo.Component, Props.EnabledFor(componentInfo.Component)); } else { - _context.Extension().MappingBuilder + _context.Extension().MappingBuilder! .RecordCopyProperty(commonActiveness, Props.EnabledFor(commonActiveness), componentInfo.Component, Props.EnabledFor(componentInfo.Component)); } @@ -323,8 +323,7 @@ private void MergeBone(GCComponentInfoHolder componentInfos) ConfigureRecursive(_context.AvatarRootTransform, _context); // returns (original mergedChildren, list of merged children if merged, and null if not merged) - //[CanBeNull] - (bool, List) ConfigureRecursive(Transform transform, BuildContext context) + (bool, List?) ConfigureRecursive(Transform transform, BuildContext context) { var mergedChildren = true; var afterChildren = new List(); @@ -349,8 +348,8 @@ private void MergeBone(GCComponentInfoHolder componentInfos) | GCComponentInfo.DependencyType.ComponentToTransform; // functions for make it easier to know meaning of result - (bool, List) YesMerge() => (mergedChildren, afterChildren); - (bool, List) NotMerged() => (mergedChildren, null); + (bool, List?) YesMerge() => (mergedChildren, afterChildren); + (bool, List?) NotMerged() => (mergedChildren, null); // Already Merged if (transform.GetComponent()) return YesMerge(); diff --git a/Editor/Processors/TraceAndOptimize/GCComponentInfo.cs b/Editor/Processors/TraceAndOptimize/GCComponentInfo.cs index 342e4f2bb..8fa7dc767 100644 --- a/Editor/Processors/TraceAndOptimize/GCComponentInfo.cs +++ b/Editor/Processors/TraceAndOptimize/GCComponentInfo.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; @@ -43,11 +42,9 @@ private void InitializeDependencies(Transform transform, bool? parentActiveness) public IEnumerable AllInformation => _dependencies.Values; - [CanBeNull] - public GCComponentInfo TryGetInfo(Component dependent) => - _dependencies.TryGetValue(dependent, out var dependencies) ? dependencies : null; + public GCComponentInfo? TryGetInfo(Component? dependent) => + dependent != null && _dependencies.TryGetValue(dependent, out var dependencies) ? dependencies : null; - [NotNull] public GCComponentInfo GetInfo(Component dependent) => _dependencies[dependent]; } @@ -71,19 +68,19 @@ internal class GCComponentInfo /// /// Dependencies of this component /// - [NotNull] internal readonly Dictionary Dependencies = + internal readonly Dictionary Dependencies = new Dictionary(); /// /// Dependants entrypoint components /// - [NotNull] internal readonly Dictionary DependantEntrypoint = + internal readonly Dictionary DependantEntrypoint = new Dictionary(); /// /// Dependants entrypoint components /// - [NotNull] internal readonly Dictionary DependantBehaviours = + internal readonly Dictionary DependantBehaviours = new Dictionary(); internal IEnumerable DependantComponents => @@ -164,17 +161,11 @@ internal readonly partial struct GCComponentInfoHolder case OcclusionArea _: case OcclusionPortal _: case ParticleSystem _: -#if !UNITY_2021_3_OR_NEWER - case ParticleSystemForceField _: -#endif case Rigidbody _: case Rigidbody2D _: case TextMesh _: case Tree _: case WindZone _: -#if !UNITY_2020_2_OR_NEWER - case UnityEngine.XR.WSA.WorldAnchor _: -#endif activeness = true; break; case Component _: diff --git a/Editor/Processors/TraceAndOptimize/GCDebug.cs b/Editor/Processors/TraceAndOptimize/GCDebug.cs index a1b595c14..daddbb654 100644 --- a/Editor/Processors/TraceAndOptimize/GCDebug.cs +++ b/Editor/Processors/TraceAndOptimize/GCDebug.cs @@ -52,6 +52,7 @@ string CreateData() var collect = new StringBuilder(); foreach (var gcData in root.GetComponentsInChildren(true)) { + if (gcData.component is null) continue; // use is instead of null to get type information of missing component collect.Append(RuntimeUtil.RelativePath(root, gcData.gameObject)) .Append("(").Append(gcData.component.GetType().Name).Append("):\n"); collect.Append(" IsEntryPoint: ").Append(gcData.isEntryPoint).Append('\n'); @@ -81,11 +82,11 @@ orderby processing class GCDebugInfo : MonoBehaviour { - public Component component; + public Component? component; public Activeness activeness; public bool isEntryPoint; - public ComponentTypePair[] dependencies; - public ComponentTypePair[] entryPoints; + public ComponentTypePair[] dependencies = Array.Empty(); + public ComponentTypePair[] entryPoints = Array.Empty(); public static Activeness ActivenessFromBool(bool? activeness) { @@ -136,4 +137,4 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten } } } -} \ No newline at end of file +} diff --git a/Editor/Processors/TraceAndOptimize/RequireComponentCache.cs b/Editor/Processors/TraceAndOptimize/RequireComponentCache.cs index f27a37162..ccdb3b358 100644 --- a/Editor/Processors/TraceAndOptimize/RequireComponentCache.cs +++ b/Editor/Processors/TraceAndOptimize/RequireComponentCache.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Reflection; -using JetBrains.Annotations; using UnityEngine; namespace Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes @@ -11,9 +10,7 @@ internal static class RequireComponentCache private static Dictionary> _requireComponentCache = new Dictionary>(); private static Dictionary> _dependantComponentCache = new Dictionary>(); - [NotNull] - [ItemNotNull] - public static HashSet GetRequiredComponents([NotNull] Type type) + public static HashSet GetRequiredComponents(Type type) { if (type == null) throw new ArgumentNullException(nameof(type)); if (_requireComponentCache.TryGetValue(type, out var result)) return result; @@ -39,9 +36,7 @@ public static HashSet GetRequiredComponents([NotNull] Type type) return result; } - [NotNull] - [ItemNotNull] - public static HashSet GetDependantComponents([NotNull] Type type) + public static HashSet GetDependantComponents(Type type) { if (type == null) throw new ArgumentNullException(nameof(type)); if (!_dependantComponentCache.TryGetValue(type, out var result)) diff --git a/Editor/Processors/UnusedBonesByReferencesToolEarlyProcessor.cs b/Editor/Processors/UnusedBonesByReferencesToolEarlyProcessor.cs index 912fdfc5a..15ee0e37d 100644 --- a/Editor/Processors/UnusedBonesByReferencesToolEarlyProcessor.cs +++ b/Editor/Processors/UnusedBonesByReferencesToolEarlyProcessor.cs @@ -74,8 +74,7 @@ public static List Make(Transform root, bool detectExtraChild = f else { boneHierarchy.Add(bone, - new BoneReference - { Bone = bone, References = new HashSet { renderer.transform } }); + new BoneReference(bone) { References = new HashSet { renderer.transform } }); } } } @@ -114,6 +113,11 @@ public static List Make(Transform root, bool detectExtraChild = f public HashSet References = new HashSet(); public bool HasExtraChild = false; + public BoneReference(Transform bone) + { + Bone = bone; + } + public bool ReferencesAllEditorOnly { get => References.All(t => t.CompareTag(EditorOnlyTag)); @@ -137,12 +141,12 @@ public string BoneParentPath public class UnusedBonesByReferences { - public IList BoneReferences { get; set; } + public IList BoneReferences { get; set; } = null!; // Initialized later public bool PreserveEndBone { get; set; } - public HashSet UnusedBones { get; private set; } - public HashSet DisabledBones { get; private set; } - public HashSet ForceEnabledBones { get; private set; } + public HashSet UnusedBones { get; private set; } = null!; // Initialized later + public HashSet DisabledBones { get; private set; } = null!; // Initialized later + public HashSet ForceEnabledBones { get; private set; } = null!; // Initialized later public static UnusedBonesByReferences Make(IList boneReferences, bool preserveEndBone = false) diff --git a/Editor/Utils/AnimationLocation.cs b/Editor/Utils/AnimationLocation.cs index 48c0397ee..b3d2fcb78 100644 --- a/Editor/Utils/AnimationLocation.cs +++ b/Editor/Utils/AnimationLocation.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.AnimatorParsersV2; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; @@ -13,17 +12,17 @@ namespace Anatawa12.AvatarOptimizer // The class describes the location of the animation curve internal sealed class AnimationLocation : IErrorContext { - [NotNull] public Animator Component { get; } + public Animator Component { get; } public int PlayableLayerIndex { get; } public int AnimationLayerIndex { get; } - [NotNull] public AnimatorState AnimatorState { get; } - [NotNull] public int[] BlendTreeLocation { get; } - [NotNull] public AnimationCurve Curve { get; } - [NotNull] public AnimationClip Clip { get; set; } + public AnimatorState AnimatorState { get; } + public int[] BlendTreeLocation { get; } + public AnimationCurve Curve { get; } + public AnimationClip Clip { get; set; } - public AnimationLocation([NotNull] Animator component, int playableLayerIndex, int animationLayerIndex, - [NotNull] AnimatorState state, int[] blendTreeLocation, [NotNull] AnimationCurve curve, - [NotNull] AnimationClip clip) + public AnimationLocation(Animator component, int playableLayerIndex, int animationLayerIndex, + AnimatorState state, int[]? blendTreeLocation, AnimationCurve curve, + AnimationClip clip) { if (!component) throw new ArgumentNullException(nameof(component)); if (!state) throw new ArgumentNullException(nameof(state)); @@ -101,23 +100,20 @@ private bool Equals(AnimationLocation other) => AnimationLayerIndex == other.AnimationLayerIndex && Equals(AnimatorState, other.AnimatorState) && BlendTreeLocation.SequenceEqual(other.BlendTreeLocation) && Equals(Curve, other.Curve); - public override bool Equals(object obj) => + public override bool Equals(object? obj) => ReferenceEquals(this, obj) || obj is AnimationLocation other && Equals(other); public override int GetHashCode() { - unchecked - { - var hashCode = Component.GetHashCode(); - hashCode = (hashCode * 397) ^ PlayableLayerIndex; - hashCode = (hashCode * 397) ^ AnimationLayerIndex; - hashCode = (hashCode * 397) ^ AnimatorState.GetHashCode(); - hashCode = (hashCode * 397) ^ BlendTreeLocation.Length; - foreach (var location in BlendTreeLocation) - hashCode = (hashCode * 397) ^ location; - hashCode = (hashCode * 397) ^ Curve.GetHashCode2(); - return hashCode; - } + var hashCode = new HashCode(); + hashCode.Add(Component); + hashCode.Add(PlayableLayerIndex); + hashCode.Add(AnimationLayerIndex); + hashCode.Add(AnimatorState); + foreach (var location in BlendTreeLocation) + hashCode.Add(location); + hashCode.Add(Curve); + return hashCode.ToHashCode(); } public IEnumerable ContextReferences => new[] diff --git a/Editor/Utils/AnimatorLayerMap.cs b/Editor/Utils/AnimatorLayerMap.cs index f14d8024d..51fe0b65a 100644 --- a/Editor/Utils/AnimatorLayerMap.cs +++ b/Editor/Utils/AnimatorLayerMap.cs @@ -41,4 +41,4 @@ public ref T this[VRCAvatarDescriptor.AnimLayerType type] } } -#endif \ No newline at end of file +#endif diff --git a/Editor/Utils/Assets.cs b/Editor/Utils/Assets.cs index d164c866d..1bfc9197d 100644 --- a/Editor/Utils/Assets.cs +++ b/Editor/Utils/Assets.cs @@ -13,4 +13,4 @@ internal class Assets private static CachedGuidLoader _previewHereTex = "617775211fe634657ae06fc9f81b6ceb"; public static Texture2D PreviewHereTex => _previewHereTex.Value; } -} \ No newline at end of file +} diff --git a/Editor/Utils/ComponentOrGameObject.cs b/Editor/Utils/ComponentOrGameObject.cs index 850e33610..0b4c49d5d 100644 --- a/Editor/Utils/ComponentOrGameObject.cs +++ b/Editor/Utils/ComponentOrGameObject.cs @@ -1,3 +1,7 @@ +#nullable disable + +// TODO: consider nullable reference type +// This class may and may not be null so it's hard to determine if it's nullable or not using System; using UnityEngine; using Object = UnityEngine.Object; @@ -45,7 +49,7 @@ public bool TryAs(out T gameObject) where T : Object public bool Equals(ComponentOrGameObject other) => Equals(_object, other._object); public override bool Equals(object obj) => obj is ComponentOrGameObject other && Equals(other); - public override int GetHashCode() => _object != null ? _object.GetHashCode() : 0; + public override int GetHashCode() => HashCode.Combine(_object); public override string ToString() => _object != null ? _object.ToString() : string.Empty; } -} \ No newline at end of file +} diff --git a/Editor/Utils/Utils.VRCSDKWeightChanges.cs b/Editor/Utils/Utils.VRCSDKWeightChanges.cs index 7cecfc9e2..a51be096b 100644 --- a/Editor/Utils/Utils.VRCSDKWeightChanges.cs +++ b/Editor/Utils/Utils.VRCSDKWeightChanges.cs @@ -1,18 +1,16 @@ #if AAO_VRCSDK3_AVATARS -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; -using VRC.SDK3.Avatars.Components; using VRC.SDKBase; namespace Anatawa12.AvatarOptimizer { partial class VRCSDKUtils { - public static void CollectWeightChangesInController([CanBeNull] RuntimeAnimatorController runtimeController, - [NotNull] AnimatorLayerMap playableWeightChanged, - [NotNull] AnimatorLayerMap animatorLayerWeightChanged) + public static void CollectWeightChangesInController(RuntimeAnimatorController? runtimeController, + AnimatorLayerMap playableWeightChanged, + AnimatorLayerMap animatorLayerWeightChanged) { if (runtimeController == null) return; using (ErrorReport.WithContextObject(runtimeController)) @@ -32,10 +30,10 @@ public static void CollectWeightChangesInController([CanBeNull] RuntimeAnimatorC } } - private static void AddPlayableLayerChanges([NotNull] VRC_PlayableLayerControl control, - [NotNull] AnimatorLayerMap playableWeightChanged) + private static void AddPlayableLayerChanges(VRC_PlayableLayerControl control, + AnimatorLayerMap playableWeightChanged) { - if (!(control.layer.ToAnimLayerType() is VRCAvatarDescriptor.AnimLayerType layer)) + if (control.layer.ToAnimLayerType() is not { } layer) { BuildLog.LogWarning( "AnimatorParser:PlayableLayerControl:UnknownBlendablePlayableLayer", @@ -49,10 +47,10 @@ private static void AddPlayableLayerChanges([NotNull] VRC_PlayableLayerControl c playableWeightChanged[layer] = playableWeightChanged[layer].Merge(current); } - private static void AddAnimatorLayerChanges([NotNull] VRC_AnimatorLayerControl control, - [NotNull] AnimatorLayerMap animatorLayerWeightChanged) + private static void AddAnimatorLayerChanges(VRC_AnimatorLayerControl control, + AnimatorLayerMap animatorLayerWeightChanged) { - if (!(control.playable.ToAnimLayerType() is VRCAvatarDescriptor.AnimLayerType layer)) + if (control.playable.ToAnimLayerType() is not { } layer) { BuildLog.LogWarning( "AnimatorParser:AnimatorLayerControl:UnknownBlendablePlayableLayer", @@ -70,4 +68,4 @@ private static void AddAnimatorLayerChanges([NotNull] VRC_AnimatorLayerControl c } } -#endif \ No newline at end of file +#endif diff --git a/Editor/Utils/VRCSDKUtils.cs b/Editor/Utils/VRCSDKUtils.cs index f7499073a..f24a1335c 100644 --- a/Editor/Utils/VRCSDKUtils.cs +++ b/Editor/Utils/VRCSDKUtils.cs @@ -80,4 +80,4 @@ public static int BoneChainLength(this VRCPhysBoneBase physBoneBase) } } -#endif \ No newline at end of file +#endif diff --git a/Editor/com.anatawa12.avatar-optimizer.editor.asmdef b/Editor/com.anatawa12.avatar-optimizer.editor.asmdef index babd8b8e8..aabdfdcf5 100644 --- a/Editor/com.anatawa12.avatar-optimizer.editor.asmdef +++ b/Editor/com.anatawa12.avatar-optimizer.editor.asmdef @@ -53,26 +53,6 @@ "expression": "", "define": "AAO_VRCSDK3_AVATARS" }, - { - "name": "com.vrchat.avatars", - "expression": "3.5.1", - "define": "AAO_VRCSDK3_AVATARS_IMPOSTER_SETTINGS" - }, - { - "name": "com.vrchat.avatars", - "expression": "3.5.2-beta.2", - "define": "AAO_VRCSDK3_AVATARS_HEAD_CHOP" - }, - { - "name": "com.vrchat.avatars", - "expression": "3.5.2", - "define": "AAO_VRCSDK3_AVATARS_ANIMATOR_PLAY_AUDIO" - }, - { - "name": "com.vrchat.avatars", - "expression": "3.6.2-constraints.4", - "define": "AAO_VRCSDK3_AVATARS_CONSTRAINTS" - }, { "name": "com.vrmc.univrm", "expression": "", diff --git a/Editor/csc.rsp b/Editor/csc.rsp deleted file mode 100644 index f4e21157e..000000000 --- a/Editor/csc.rsp +++ /dev/null @@ -1,2 +0,0 @@ -#"Shared csc.rsp file. origin is at Editor/csc.rsp. symlinked to Runtime/csc.rsp and other assemblies of AAO" --langversion:7.3 diff --git a/Editor/csc.rsp b/Editor/csc.rsp new file mode 120000 index 000000000..fa12e2b6d --- /dev/null +++ b/Editor/csc.rsp @@ -0,0 +1 @@ +../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/AnimatorOptimizer/EntryExitToBlendTree.cs b/Internal/AnimatorOptimizer/EntryExitToBlendTree.cs index 87d603b43..d6ec5b396 100644 --- a/Internal/AnimatorOptimizer/EntryExitToBlendTree.cs +++ b/Internal/AnimatorOptimizer/EntryExitToBlendTree.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; @@ -399,7 +398,7 @@ bool AddToStateValues(AnimatorState state, IntOrBool value) exitValues.RemoveWhere(value => value.IntValue.HasValue ? conditions.All(c => c.SatisfiesInt(value.IntValue.Value) == true) : - conditions.All(c => c.SatisfiesBool(value.BoolValue.Value) == true)); + conditions.All(c => c.SatisfiesBool(value.BoolValue!.Value) == true)); } if (exitValues.Count != 0) return null; @@ -460,7 +459,7 @@ public IntOrBool(bool value) public override int GetHashCode() => HashCode.Combine(IntValue, BoolValue); public bool Equals(IntOrBool other) => IntValue == other.IntValue && BoolValue == other.BoolValue; - public override bool Equals(object obj) => obj is IntOrBool other && Equals(other); + public override bool Equals(object? obj) => obj is IntOrBool other && Equals(other); public static bool operator ==(IntOrBool left, IntOrBool right) => left.Equals(right); public static bool operator !=(IntOrBool left, IntOrBool right) => !left.Equals(right); @@ -556,12 +555,12 @@ void AddFrames(int before, Motion beforeMotion, int after, Motion afterMotion) if (states.All(x => x.value.IntValue.HasValue)) { // sort increasing order - states.Sort((x, y) => x.value.IntValue.Value.CompareTo(y.value.IntValue.Value)); + states.Sort((x, y) => x.value.IntValue!.Value.CompareTo(y.value.IntValue!.Value)); { // first frame: add defaultMotion before first state var (value, motion) = states[0]; - AddFrames(value.IntValue.Value - 1, defaultMotion, + AddFrames(value.IntValue!.Value - 1, defaultMotion, value.IntValue.Value, motion); } @@ -571,7 +570,7 @@ void AddFrames(int before, Motion beforeMotion, int after, Motion afterMotion) var (prevValue, prevMotion) = states[i - 1]; var (currentValue, currentMotion) = states[i]; - if (currentValue.IntValue.Value - prevValue.IntValue.Value > 1) + if (currentValue.IntValue!.Value - prevValue.IntValue!.Value > 1) { AddFrames(prevValue.IntValue.Value, prevMotion, prevValue.IntValue.Value + 1, defaultMotion); @@ -588,7 +587,7 @@ void AddFrames(int before, Motion beforeMotion, int after, Motion afterMotion) { // last frame: add last state to defaultMotion var (value, motion) = states[^1]; - AddFrames(value.IntValue.Value, motion, + AddFrames(value.IntValue!.Value, motion, value.IntValue.Value + 1, defaultMotion); } } diff --git a/Internal/AnimatorOptimizer/Wrappers.cs b/Internal/AnimatorOptimizer/Wrappers.cs index f44ba4ea7..6e823ad43 100644 --- a/Internal/AnimatorOptimizer/Wrappers.cs +++ b/Internal/AnimatorOptimizer/Wrappers.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEditor.Animations; using UnityEngine; diff --git a/Internal/AnimatorOptimizer/com.anatawa12.avatar-optimizer.internal.animator-optimizer.asmdef b/Internal/AnimatorOptimizer/com.anatawa12.avatar-optimizer.internal.animator-optimizer.asmdef index 50bbe10dc..4f0daa58f 100644 --- a/Internal/AnimatorOptimizer/com.anatawa12.avatar-optimizer.internal.animator-optimizer.asmdef +++ b/Internal/AnimatorOptimizer/com.anatawa12.avatar-optimizer.internal.animator-optimizer.asmdef @@ -19,9 +19,7 @@ "System.Memory.dll" ], "autoReferenced": false, - "defineConstraints": [ - "UNITY_2021_3_OR_NEWER" - ], + "defineConstraints": [], "versionDefines": [], "noEngineReferences": false } \ No newline at end of file diff --git a/Internal/AnimatorOptimizer/csc.rsp b/Internal/AnimatorOptimizer/csc.rsp deleted file mode 100644 index 673363864..000000000 --- a/Internal/AnimatorOptimizer/csc.rsp +++ /dev/null @@ -1 +0,0 @@ -/nullable:enable diff --git a/Internal/AnimatorOptimizer/csc.rsp b/Internal/AnimatorOptimizer/csc.rsp new file mode 120000 index 000000000..f8076d40e --- /dev/null +++ b/Internal/AnimatorOptimizer/csc.rsp @@ -0,0 +1 @@ +../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/Localization/Editor/AAOL10N.cs b/Internal/Localization/Editor/AAOL10N.cs index ef0b2e0e2..04fa10637 100644 --- a/Internal/Localization/Editor/AAOL10N.cs +++ b/Internal/Localization/Editor/AAOL10N.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using JetBrains.Annotations; using nadena.dev.ndmf.localization; using nadena.dev.ndmf.ui; using UnityEditor; @@ -25,10 +24,9 @@ public static class AAOL10N }); - [NotNull] public static string Tr(string key) => Localizer.GetLocalizedString(key); + public static string Tr(string key) => Localizer.GetLocalizedString(key); - [CanBeNull] - public static string TryTr(string descriptionKey) + public static string? TryTr(string descriptionKey) { if (Localizer.TryGetLocalizedString(descriptionKey, out var result)) return result; diff --git a/Internal/Localization/Editor/InheritingDrawer.cs b/Internal/Localization/Editor/InheritingDrawer.cs index 0bad59123..321afd95c 100644 --- a/Internal/Localization/Editor/InheritingDrawer.cs +++ b/Internal/Localization/Editor/InheritingDrawer.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Reflection; using System.Text.RegularExpressions; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -12,7 +11,7 @@ namespace Anatawa12.AvatarOptimizer // originally at https://github.com/anatawa12/CustomLocalization4EditorExtension/blob/b4f4447e0169fed3bee47fff596fbc1ea7c582df/Editor/CustomLocalization4EditorExtension.Editor.cs#L409 abstract class InheritingDrawer : PropertyDrawer where TAttr : PropertyAttribute { - private PropertyDrawer _upstreamDrawer; + private PropertyDrawer? _upstreamDrawer; private bool _initialized; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) @@ -65,9 +64,9 @@ protected void InitializeUpstream(SerializedProperty property) _initialized = true; } - private void HandleDrawnType(SerializedProperty property, Type drawnType, PropertyAttribute attr) + private void HandleDrawnType(SerializedProperty property, Type drawnType, PropertyAttribute? attr) { - Type forPropertyAndType = Reflections.GetDrawerTypeForPropertyAndType(property, drawnType); + Type? forPropertyAndType = Reflections.GetDrawerTypeForPropertyAndType(property, drawnType); if (forPropertyAndType == null) return; if (typeof(PropertyDrawer).IsAssignableFrom(forPropertyAndType)) @@ -154,10 +153,10 @@ private static bool HasVisibleChildFields(SerializedProperty property) static class Reflections { - [NotNull] private static readonly MethodInfo GetDrawerTypeForPropertyAndTypeInfo; - [NotNull] private static readonly FieldInfo FieldInfoInfo; - [NotNull] private static readonly FieldInfo AttributeInfo; - [NotNull] private static readonly MethodInfo DefaultPropertyFieldInfo; + private static readonly MethodInfo GetDrawerTypeForPropertyAndTypeInfo; + private static readonly FieldInfo FieldInfoInfo; + private static readonly FieldInfo AttributeInfo; + private static readonly MethodInfo DefaultPropertyFieldInfo; static Reflections() { @@ -183,10 +182,10 @@ static Reflections() null) ?? throw new InvalidOperationException(); } - public static Type GetDrawerTypeForPropertyAndType(SerializedProperty property, Type type) => - (Type)GetDrawerTypeForPropertyAndTypeInfo.Invoke(null, new object[] { property, type }); + public static Type? GetDrawerTypeForPropertyAndType(SerializedProperty property, Type type) => + (Type?)GetDrawerTypeForPropertyAndTypeInfo.Invoke(null, new object[] { property, type }); - public static void SetFieldAndAttribute(PropertyDrawer drawer, FieldInfo fieldInfo, PropertyAttribute attribute) + public static void SetFieldAndAttribute(PropertyDrawer drawer, FieldInfo fieldInfo, PropertyAttribute? attribute) { FieldInfoInfo.SetValue(drawer, fieldInfo); AttributeInfo.SetValue(drawer, attribute); diff --git a/Internal/Localization/Editor/LocalizedAttributeDrawer.cs b/Internal/Localization/Editor/LocalizedAttributeDrawer.cs index 67473964c..ab366571f 100644 --- a/Internal/Localization/Editor/LocalizedAttributeDrawer.cs +++ b/Internal/Localization/Editor/LocalizedAttributeDrawer.cs @@ -7,8 +7,8 @@ namespace Anatawa12.AvatarOptimizer [CustomPropertyDrawer(typeof(AAOLocalizedAttribute))] class LocalizedAttributeDrawer : InheritingDrawer { - private AAOLocalizedAttribute _attribute; - private string _localeCode; + private AAOLocalizedAttribute _attribute = null!; // initialized in Initialize method + private string? _localeCode; private GUIContent _label = new GUIContent(); public override float GetPropertyHeight(SerializedProperty property, GUIContent label) @@ -41,4 +41,4 @@ private void Update(bool force = false) } } } -} \ No newline at end of file +} diff --git a/Internal/Localization/Editor/csc.rsp b/Internal/Localization/Editor/csc.rsp index dfd3cdce1..9276f64c5 120000 --- a/Internal/Localization/Editor/csc.rsp +++ b/Internal/Localization/Editor/csc.rsp @@ -1 +1 @@ -../../../Editor/csc.rsp \ No newline at end of file +../../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/Localization/Runtime/Runtime.cs b/Internal/Localization/Runtime/Runtime.cs index fba668300..33a4506ae 100644 --- a/Internal/Localization/Runtime/Runtime.cs +++ b/Internal/Localization/Runtime/Runtime.cs @@ -1,17 +1,16 @@ using System; -using JetBrains.Annotations; using UnityEngine; namespace Anatawa12.AvatarOptimizer { public sealed class AAOLocalizedAttribute : PropertyAttribute { - [NotNull] public string LocalizationKey { get; } - [CanBeNull] public string TooltipKey { get; } + public string LocalizationKey { get; } + public string? TooltipKey { get; } - public AAOLocalizedAttribute([NotNull] string localizationKey) : this(localizationKey, null) {} + public AAOLocalizedAttribute(string localizationKey) : this(localizationKey, null) {} - public AAOLocalizedAttribute([NotNull] string localizationKey, [CanBeNull] string tooltipKey) + public AAOLocalizedAttribute(string localizationKey, string? tooltipKey) { LocalizationKey = localizationKey ?? throw new ArgumentNullException(nameof(localizationKey)); TooltipKey = tooltipKey; diff --git a/Internal/Localization/Runtime/csc.rsp b/Internal/Localization/Runtime/csc.rsp index dfd3cdce1..9276f64c5 120000 --- a/Internal/Localization/Runtime/csc.rsp +++ b/Internal/Localization/Runtime/csc.rsp @@ -1 +1 @@ -../../../Editor/csc.rsp \ No newline at end of file +../../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/MeshInfo2/MeshInfo2.cs b/Internal/MeshInfo2/MeshInfo2.cs index ce323187b..65704f8f1 100644 --- a/Internal/MeshInfo2/MeshInfo2.cs +++ b/Internal/MeshInfo2/MeshInfo2.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using nadena.dev.ndmf; using Unity.Burst; using Unity.Collections; @@ -19,12 +18,12 @@ namespace Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes { public class MeshInfo2 { - [NotNull] public readonly Renderer SourceRenderer; - [NotNull] public Transform RootBone; + public readonly Renderer SourceRenderer; + public Transform? RootBone; public Bounds Bounds; public readonly List Vertices = new List(0); - private readonly Mesh _originalMesh; + private readonly Mesh? _originalMesh; // TexCoordStatus which is 3 bits x 8 = 24 bits private uint _texCoordStatus; @@ -47,7 +46,7 @@ public MeshInfo2(SkinnedMeshRenderer renderer) { var originalMeshImporter = GetImporter(ObjectRegistry.GetReference(mesh).Object as Mesh); - ModelImporter GetImporter(Mesh importingMesh) + ModelImporter? GetImporter(Mesh? importingMesh) { if (!importingMesh) return null; var path = AssetDatabase.GetAssetPath(importingMesh); @@ -75,7 +74,7 @@ void AutoFix() using (ErrorReport.WithContextObject(renderer)) { - if (mesh) + if (mesh != null) ReadSkinnedMesh(mesh); var updateWhenOffscreen = renderer.updateWhenOffscreen; @@ -86,7 +85,7 @@ void AutoFix() renderer.updateWhenOffscreen = updateWhenOffscreen; RootBone = renderer.rootBone ? renderer.rootBone : renderer.transform; - if (mesh) + if (mesh != null) { for (var i = 0; i < mesh.blendShapeCount; i++) BlendShapes[i] = (BlendShapes[i].name, renderer.GetBlendShapeWeight(i)); @@ -109,16 +108,16 @@ public MeshInfo2(MeshRenderer renderer) using (ErrorReport.WithContextObject(renderer)) { var meshFilter = renderer.GetComponent(); - var mesh = _originalMesh = meshFilter ? meshFilter.sharedMesh : null; + var mesh = _originalMesh = meshFilter != null ? meshFilter.sharedMesh : null; if (mesh != null && !mesh.isReadable && EditorApplication.isPlaying) { BuildLog.LogError("MeshInfo2:error:MeshNotReadable", mesh); return; } - if (mesh) + if (mesh != null) ReadStaticMesh(mesh); - if (mesh) + if (mesh != null) Bounds = mesh.bounds; RootBone = renderer.transform; @@ -152,7 +151,7 @@ private void SetMaterials(Renderer renderer) for (int i = SubMeshes.Count - 1, j = 0; i < sourceMaterials.Length; i++, j++) lastMeshMaterials[j] = sourceMaterials[i]; - SubMeshes[SubMeshes.Count - 1].SharedMaterials = lastMeshMaterials; + SubMeshes[^1].SharedMaterials = lastMeshMaterials; } } @@ -180,7 +179,7 @@ public void MakeBoned() vertex.BoneWeights.Add((Bones[0], 1f)); } - public void ReadSkinnedMesh([NotNull] Mesh mesh) + public void ReadSkinnedMesh(Mesh mesh) { ReadStaticMesh(mesh); @@ -193,7 +192,7 @@ public void ReadSkinnedMesh([NotNull] Mesh mesh) Profiler.EndSample(); } - private void ReadBones([NotNull] Mesh mesh) + private void ReadBones(Mesh mesh) { Bones.Clear(); Bones.Capacity = Math.Max(Bones.Capacity, mesh.bindposes.Length); @@ -212,7 +211,7 @@ private void ReadBones([NotNull] Mesh mesh) } } - private void ReadBlendShapes([NotNull] Mesh mesh) + private void ReadBlendShapes(Mesh mesh) { BlendShapes.Clear(); Profiler.BeginSample("Prepare shared buffers"); @@ -325,7 +324,7 @@ bool IsMeaningful(NativeSlice frames) } } - public void ReadStaticMesh([NotNull] Mesh mesh) + public void ReadStaticMesh(Mesh mesh) { Profiler.BeginSample($"Read Static Mesh Part"); Vertices.Capacity = Math.Max(Vertices.Capacity, mesh.vertexCount); @@ -758,13 +757,13 @@ public List Triangles public List Vertices { get; } = new List(); - public Material SharedMaterial + public Material? SharedMaterial { get => SharedMaterials[0]; set => SharedMaterials[0] = value; } - public Material[] SharedMaterials = { null }; + public Material?[] SharedMaterials = { null }; public SubMesh() { @@ -773,15 +772,15 @@ public SubMesh() public SubMesh(List vertices) => Vertices = vertices; public SubMesh(List vertices, Material sharedMaterial) => (Vertices, SharedMaterial) = (vertices, sharedMaterial); - public SubMesh(Material sharedMaterial) => SharedMaterial = sharedMaterial; - public SubMesh(Material sharedMaterial, MeshTopology topology) => + public SubMesh(Material? sharedMaterial) => SharedMaterial = sharedMaterial; + public SubMesh(Material? sharedMaterial, MeshTopology topology) => (SharedMaterial, Topology) = (sharedMaterial, topology); - public SubMesh(SubMesh subMesh, Material triangles) + public SubMesh(SubMesh subMesh, Material? material) { Topology = subMesh.Topology; Vertices = new List(subMesh.Vertices); - SharedMaterial = triangles; + SharedMaterial = material; } public SubMesh(List vertices, List triangles, SubMeshDescriptor descriptor) @@ -1053,7 +1052,7 @@ public Vector3 ComputeActualPosition(MeshInfo2 meshInfo2, Func (Bindpose, Transform) = (bindPose, transform); + public Bone(Matrix4x4 bindPose, Transform? transform) => (Bindpose, Transform) = (bindPose, transform); } public enum TexCoordStatus diff --git a/Internal/MeshInfo2/MeshInfo2ContextExtensions.cs b/Internal/MeshInfo2/MeshInfo2ContextExtensions.cs index a7e4dd734..df9ef1a4b 100644 --- a/Internal/MeshInfo2/MeshInfo2ContextExtensions.cs +++ b/Internal/MeshInfo2/MeshInfo2ContextExtensions.cs @@ -1,7 +1,6 @@ using System; using Anatawa12.AvatarOptimizer.Processors; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; @@ -9,14 +8,14 @@ namespace Anatawa12.AvatarOptimizer { public static class MeshInfo2ContextExtensions { - [NotNull] - private static MeshInfo2Holder GetHolder([NotNull] this BuildContext context) + private static MeshInfo2Holder GetHolder(this BuildContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); - return context.Extension().Holder; + // it's activated so it's not null + return context.Extension().Holder!; } - public static MeshInfo2 GetMeshInfoFor([NotNull] this BuildContext context, SkinnedMeshRenderer renderer) => + public static MeshInfo2 GetMeshInfoFor(this BuildContext context, SkinnedMeshRenderer renderer) => context.GetHolder().GetMeshInfoFor(renderer); } -} \ No newline at end of file +} diff --git a/Internal/MeshInfo2/MeshInfo2Holder.cs b/Internal/MeshInfo2/MeshInfo2Holder.cs index c8d777f39..d5a432d4a 100644 --- a/Internal/MeshInfo2/MeshInfo2Holder.cs +++ b/Internal/MeshInfo2/MeshInfo2Holder.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; -using JetBrains.Annotations; using nadena.dev.ndmf; using UnityEngine; using UnityEngine.Profiling; @@ -12,7 +11,7 @@ namespace Anatawa12.AvatarOptimizer.Processors { public class MeshInfo2Context : IExtensionContext { - internal MeshInfo2Holder Holder { get; private set; } + internal MeshInfo2Holder? Holder { get; private set; } public void OnActivate(BuildContext context) { Holder = new MeshInfo2Holder(context.AvatarRootObject); @@ -20,7 +19,7 @@ public void OnActivate(BuildContext context) public void OnDeactivate(BuildContext context) { - Debug.Assert(Holder != null, nameof(Holder) + " != null"); + if (Holder == null) throw new InvalidOperationException("Not activated"); // avoid Array index (n) is out of bounds (size=m) error // by assigning null to AnimatorController before changing blendShapes count // and assigning back after changing blendShapes count. diff --git a/Internal/MeshInfo2/csc.rsp b/Internal/MeshInfo2/csc.rsp index c6acf2e0a..f8076d40e 120000 --- a/Internal/MeshInfo2/csc.rsp +++ b/Internal/MeshInfo2/csc.rsp @@ -1 +1 @@ -../../Editor/csc.rsp \ No newline at end of file +../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/PrefabSafeSet/Editor/BasicTypeEditors.cs b/Internal/PrefabSafeSet/Editor/BasicTypeEditors.cs index 6be9444f4..1b3be447c 100644 --- a/Internal/PrefabSafeSet/Editor/BasicTypeEditors.cs +++ b/Internal/PrefabSafeSet/Editor/BasicTypeEditors.cs @@ -1,13 +1,12 @@ using System; using System.Reflection; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; namespace Anatawa12.AvatarOptimizer.PrefabSafeSet { - abstract class BasicEditorBase : EditorBase + abstract class BasicEditorBase : EditorBase where T : notnull { private protected override float GetAddRegionSize() => EditorGUIUtility.singleLineHeight; @@ -53,7 +52,7 @@ protected override string Field(Rect position, GUIContent label, string value) = class ObjectEditorImpl : EditorBase { - [CanBeNull] private readonly Type _elementType; + private readonly Type? _elementType; public ObjectEditorImpl(SerializedProperty property, Type fieldType, int nestCount) : base(property, nestCount) { @@ -103,7 +102,7 @@ private protected override void OnGUIAddRegion(Rect position) protected override float FieldHeight(GUIContent label) => EditorGUI.GetPropertyHeight(SerializedPropertyType.ObjectReference, label); - protected override Object Field(Rect position, GUIContent label, Object value) + protected override Object Field(Rect position, GUIContent label, Object? value) { bool allowSceneObjects = false; var targetObject = FakeSlot.serializedObject.targetObject; @@ -164,14 +163,14 @@ public void HandleDragEvent(Rect position, int lastControlId, Event @event) } } - private static readonly MethodInfo ValidateObjectFieldAssignmentMethod = + private static readonly MethodInfo? ValidateObjectFieldAssignmentMethod = typeof(EditorGUI).GetMethod("ValidateObjectFieldAssignment", BindingFlags.Static | BindingFlags.NonPublic); - private static readonly Type ObjectFieldValidatorOptionsType = + private static readonly Type? ObjectFieldValidatorOptionsType = typeof(EditorGUI).Assembly.GetType("UnityEditor.EditorGUI+ObjectFieldValidatorOptions"); - private static Object ValidateObjectFieldAssignment(Object[] references, - Type elementType, + private static Object? ValidateObjectFieldAssignment(Object[] references, + Type? elementType, SerializedProperty property) { if (ValidateObjectFieldAssignmentMethod == null) @@ -192,4 +191,4 @@ private static Object ValidateObjectFieldAssignment(Object[] references, new[] { references, elementType, property, Enum.ToObject(ObjectFieldValidatorOptionsType, 0) }) as Object; } } -} \ No newline at end of file +} diff --git a/Internal/PrefabSafeSet/Editor/EditorUtil.PrefabModification.cs b/Internal/PrefabSafeSet/Editor/EditorUtil.PrefabModification.cs index 8ef4f1272..17c9945fb 100644 --- a/Internal/PrefabSafeSet/Editor/EditorUtil.PrefabModification.cs +++ b/Internal/PrefabSafeSet/Editor/EditorUtil.PrefabModification.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; @@ -29,12 +29,12 @@ public ArraySizeCheck(SerializedProperty prop) private sealed class PrefabModification : EditorUtil { - [NotNull] private readonly List _elements; + private readonly List _elements; private bool _needsUpstreamUpdate; private int _upstreamElementCount; - [NotNull] private readonly SerializedProperty _rootProperty; - [CanBeNull] private SerializedProperty _currentRemoves; - [CanBeNull] private SerializedProperty _currentAdditions; + private readonly SerializedProperty _rootProperty; + private SerializedProperty? _currentRemoves; + private SerializedProperty? _currentAdditions; private int _currentRemovesSize; private int _currentAdditionsSize; @@ -47,7 +47,7 @@ private sealed class PrefabModification : EditorUtil private readonly ArraySizeCheck[] _layerRemoves; private readonly ArraySizeCheck[] _layerAdditions; - public PrefabModification([NotNull] SerializedProperty property, int nestCount, + public PrefabModification(SerializedProperty property, int nestCount, Func getValue, Action setValue) : base(getValue, setValue) { @@ -273,7 +273,7 @@ public override void Clear() _currentAdditionsSize = _currentAdditions.arraySize = 0; } - protected override IElement NewSlotElement([NotNull] T value) + protected override IElement NewSlotElement(T value) { if (value == null) throw new ArgumentNullException(nameof(value)); return ElementImpl.NewSlot(this, value); @@ -310,10 +310,10 @@ public bool Contains } } - public SerializedProperty ModifierProp { get; internal set; } + public SerializedProperty? ModifierProp { get; internal set; } private ElementImpl(PrefabModification container, int indexInModifier, T value, ElementStatus status, - int sourceNestCount, SerializedProperty modifierProp) + int sourceNestCount, SerializedProperty? modifierProp) { if (value == null) throw new ArgumentNullException(nameof(value)); _container = container; @@ -329,14 +329,14 @@ public static ElementImpl Natural(PrefabModification container, T value, int nes public static ElementImpl NewElement(PrefabModification container, T value, int i) { - Debug.Assert(container._currentAdditions != null, "container._currentAdditions != null"); + if (container._currentAdditions == null) throw new InvalidOperationException("_container._currentAdditions == null"); return new ElementImpl(container, i, value, ElementStatus.NewElement, -1, container._currentAdditions.GetArrayElementAtIndex(i)); } public static ElementImpl FakeRemoved(PrefabModification container, T value, int i) { - Debug.Assert(container._currentRemoves != null, "container._currentRemoves != null"); + if (container._currentRemoves == null) throw new InvalidOperationException("_container._currentRemoves == null"); return new ElementImpl(container, i, value, ElementStatus.FakeRemoved, -1, container._currentRemoves.GetArrayElementAtIndex(i)); } @@ -460,7 +460,7 @@ internal void Revert() public void MarkRemovedAt(int index) { - Debug.Assert(_container._currentRemoves != null, "_container._currentRemoves != null"); + if (_container._currentRemoves == null) throw new InvalidOperationException("_container._currentRemoves == null"); IndexInModifier = index; ModifierProp = _container._currentRemoves.GetArrayElementAtIndex(index); Status = ElementStatus.Removed; @@ -468,7 +468,7 @@ public void MarkRemovedAt(int index) public void MarkAddedTwiceAt(int index) { - Debug.Assert(_container._currentAdditions != null, "_container._currentAdditions != null"); + if (_container._currentAdditions == null) throw new InvalidOperationException("_container._currentAdditions == null"); IndexInModifier = index; ModifierProp = _container._currentAdditions.GetArrayElementAtIndex(index); Status = ElementStatus.AddedTwice; @@ -534,10 +534,10 @@ public bool IsPrefabOverride() private (int indexInModifier, SerializedProperty modifierProp) AddToModifications(T value, ref int currentModificationSize, - ref SerializedProperty currentModifications) + ref SerializedProperty? currentModifications) { InitCurrentLayer(true); - Debug.Assert(currentModifications != null, "currentModifications != null"); + if (currentModifications == null) throw new InvalidOperationException("currentModifications is null (force init failed)"); var indexInModifier = currentModifications.arraySize; var modifierProp = AddArrayElement(currentModifications); _setValue(modifierProp, value); @@ -546,11 +546,11 @@ public bool IsPrefabOverride() } private void RemoveAdditionsAt(int indexInModifier) => - RemoveModificationsAt(indexInModifier, ref _currentAdditionsSize, _currentAdditions, + RemoveModificationsAt(indexInModifier, ref _currentAdditionsSize, _currentAdditions!, ElementStatus.NewElement, ElementStatus.AddedTwice); private void RemoveRemovesAt(int indexInModifier) => - RemoveModificationsAt(indexInModifier, ref _currentRemovesSize, _currentRemoves, + RemoveModificationsAt(indexInModifier, ref _currentRemovesSize, _currentRemoves!, ElementStatus.Removed, ElementStatus.FakeRemoved); private void RemoveModificationsAt(int indexInModifier, @@ -750,17 +750,16 @@ private static List GetApplyTargets( private static GameObject GetGameObject(Object componentOrGameObject) { var gameObject = componentOrGameObject as GameObject; - if (gameObject) + if (gameObject != null) return gameObject; var component = componentOrGameObject as Component; - return component ? component.gameObject : null; + if (component != null) + return component.gameObject; + throw new InvalidOperationException($"componentOrGameObject is not GameObject nor Component ({componentOrGameObject.name})"); } - private static GameObject GetRootGameObject(Object componentOrGameObject) - { - var gameObject = GetGameObject(componentOrGameObject); - return gameObject == null ? null : gameObject.transform.root.gameObject; - } + private static GameObject GetRootGameObject(Object componentOrGameObject) => + GetGameObject(componentOrGameObject).transform.root.gameObject; private static void ForceRebuildInspectors() { @@ -770,11 +769,15 @@ private static void ForceRebuildInspectors() null, Type.EmptyTypes, null); - Debug.Assert(method != null, nameof(method) + " != null"); + if (method == null) + { + UnityEngine.Debug.LogError("ForceRebuildInspectors not found"); + return; + } method.Invoke(null, null); } - private static T ObjectOrCorrespondingObject(T value) + private static T? ObjectOrCorrespondingObject(T? value) { if (!(value is Object obj)) return value; if (EditorUtility.IsPersistent(obj)) return value; diff --git a/Internal/PrefabSafeSet/Editor/EditorUtil.Root.cs b/Internal/PrefabSafeSet/Editor/EditorUtil.Root.cs index e6a3fb27b..952e00995 100644 --- a/Internal/PrefabSafeSet/Editor/EditorUtil.Root.cs +++ b/Internal/PrefabSafeSet/Editor/EditorUtil.Root.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor; namespace Anatawa12.AvatarOptimizer.PrefabSafeSet @@ -10,8 +9,8 @@ public abstract partial class EditorUtil { private sealed class Root : EditorUtil { - private List _list; - [NotNull] private readonly SerializedProperty _mainSet; + private List? _list; + private readonly SerializedProperty _mainSet; public override int Count => _mainSet.arraySize; public Root(SerializedProperty property, Func getValue, @@ -33,9 +32,10 @@ public override IReadOnlyList> Elements } } + // Caller's responsibility to ensure _list is not null private void ReIndexAll() { - for (var i = 0; i < _list.Count; i++) + for (var i = 0; i < _list!.Count; i++) _list[i].UpdateIndex(i); } @@ -58,7 +58,7 @@ private class ElementImpl : IElement public T Value { get; } public ElementStatus Status => Contains ? ElementStatus.Natural : ElementStatus.NewSlot; public bool Contains => _index >= 0; - public SerializedProperty ModifierProp { get; private set; } + public SerializedProperty? ModifierProp { get; private set; } private readonly Root _container; private int _index; @@ -86,7 +86,8 @@ public void Add() if (Contains) return; _index = _container._mainSet.arraySize; _container._setValue(ModifierProp = AddArrayElement(_container._mainSet), Value); - _container._list.Add(this); + // ElementImpl instance will not exist unless _list is not null + _container._list!.Add(this); //_container.ReIndexAll(); // appending does not change index so no reindex is required } @@ -98,7 +99,8 @@ public void Remove() _container.RemoveArrayElementAt(_container._mainSet, _index); _index = -1; ModifierProp = null; - _container._list.Remove(this); + // ElementImpl instance will not exist unless _list is not null + _container._list!.Remove(this); _container.ReIndexAll(); } diff --git a/Internal/PrefabSafeSet/Editor/EditorUtil.cs b/Internal/PrefabSafeSet/Editor/EditorUtil.cs index d52718c83..abca9743d 100644 --- a/Internal/PrefabSafeSet/Editor/EditorUtil.cs +++ b/Internal/PrefabSafeSet/Editor/EditorUtil.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using JetBrains.Annotations; using UnityEditor; namespace Anatawa12.AvatarOptimizer.PrefabSafeSet @@ -10,11 +10,11 @@ namespace Anatawa12.AvatarOptimizer.PrefabSafeSet /// Utility to edit PrefabSafeSet in CustomEditor with SerializedProperty /// /// - public abstract partial class EditorUtil + public abstract partial class EditorUtil where T : notnull { // common property; - [NotNull] private readonly Func _getValue; - [NotNull] private readonly Action _setValue; + private readonly Func _getValue; + private readonly Action _setValue; public abstract IReadOnlyList> Elements { get; } public abstract int ElementsCount { get; } @@ -66,7 +66,7 @@ private void RemoveArrayElementAt(SerializedProperty array, int index) array.arraySize -= 1; } - private T[] ToArray([CanBeNull] SerializedProperty array) + private T[] ToArray(SerializedProperty? array) { if (array == null) return Array.Empty(); var result = new T[array.arraySize]; @@ -76,13 +76,13 @@ private T[] ToArray([CanBeNull] SerializedProperty array) } } - public interface IElement + public interface IElement where T : notnull { EditorUtil Container { get; } T Value { get; } ElementStatus Status { get; } bool Contains { get; } - SerializedProperty ModifierProp { get; } + SerializedProperty? ModifierProp { get; } void EnsureAdded(); void Add(); void EnsureRemoved(); diff --git a/Internal/PrefabSafeSet/Editor/OnBeforeSerializeImpl.cs b/Internal/PrefabSafeSet/Editor/OnBeforeSerializeImpl.cs index e5e9ed1fb..61dd0bba3 100644 --- a/Internal/PrefabSafeSet/Editor/OnBeforeSerializeImpl.cs +++ b/Internal/PrefabSafeSet/Editor/OnBeforeSerializeImpl.cs @@ -36,7 +36,7 @@ private static void GeneralCheck(PrefabSafeSet self, int nestCount) { var context = new PrefabSafeSetUtil.NullOrMissingContext(self.OuterObject); - void ReplaceMissingWithNull(T[] array) + void ReplaceMissingWithNull(T?[] array) { for (var i = 0; i < array.Length; i++) if (array[i].IsNullOrMissing(context)) @@ -52,7 +52,7 @@ void ReplaceMissingWithNull(T[] array) } } - void DistinctCheckArray(ref T[] source, ref T[] checkedArray, Func filter) + void DistinctCheckArray(ref T[] source, ref T[]? checkedArray, Func filter) { if (checkedArray == source && source.All(filter)) return; var array = source.Distinct().Where(filter).ToArray(); diff --git a/Internal/PrefabSafeSet/Editor/PrefabSafeSetEditor.cs b/Internal/PrefabSafeSet/Editor/PrefabSafeSetEditor.cs index a797d9550..0658fdc5a 100644 --- a/Internal/PrefabSafeSet/Editor/PrefabSafeSetEditor.cs +++ b/Internal/PrefabSafeSet/Editor/PrefabSafeSetEditor.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Reflection; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; @@ -10,7 +9,7 @@ namespace Anatawa12.AvatarOptimizer.PrefabSafeSet { internal static class EditorStatics { - private static GUIContent WithLocalization(GUIContent content, string key, string tooltip = null) + private static GUIContent WithLocalization(GUIContent content, string key, string? tooltip = null) { content.text = AAOL10N.Tr(key); if (tooltip != null) @@ -48,11 +47,9 @@ internal class ObjectsEditor : PropertyDrawer private int GetNestCount(Object obj) => _nestCountCache != -1 ? _nestCountCache : _nestCountCache = PrefabSafeSetUtil.PrefabNestCount(obj); - private readonly Dictionary _caches = - new Dictionary(); + private readonly Dictionary _caches = new (); - [CanBeNull] - private EditorBase GetCache(SerializedProperty property) + private EditorBase? GetCache(SerializedProperty property) { if (!_caches.TryGetValue(property.propertyPath, out var cached)) { @@ -65,7 +62,7 @@ private EditorBase GetCache(SerializedProperty property) return cached; } - private static EditorBase GetEditorImpl(SerializedPropertyType type, SerializedProperty property, + private static EditorBase? GetEditorImpl(SerializedPropertyType type, SerializedProperty property, Type fieldType, int nestCount) { switch (type) @@ -198,9 +195,9 @@ internal abstract class EditorBase public abstract bool HasPrefabOverride(); } - internal abstract class EditorBase : EditorBase + internal abstract class EditorBase : EditorBase where T : notnull { - [NotNull] protected readonly SerializedProperty FakeSlot; + protected readonly SerializedProperty FakeSlot; internal readonly EditorUtil EditorUtil; public EditorBase(SerializedProperty property, int nestCount) @@ -232,7 +229,7 @@ public override void OnGUI(Rect position) var newLabel = new GUIContent(""); // to avoid changes in for loop - Action action = null; + Action? action = null; foreach (var element in EditorUtil.Elements) { diff --git a/Internal/PrefabSafeSet/Editor/PropertyScope.cs b/Internal/PrefabSafeSet/Editor/PropertyScope.cs index f86bbf26c..7e3d22e91 100644 --- a/Internal/PrefabSafeSet/Editor/PropertyScope.cs +++ b/Internal/PrefabSafeSet/Editor/PropertyScope.cs @@ -4,9 +4,9 @@ namespace Anatawa12.AvatarOptimizer.PrefabSafeSet { - public readonly struct PropertyScope : IDisposable + public readonly struct PropertyScope : IDisposable where T : notnull { - private readonly SerializedProperty _property; + private readonly SerializedProperty? _property; private readonly Rect _totalPosition; public readonly IElement Element; public readonly GUIContent Label; diff --git a/Internal/PrefabSafeSet/Editor/Utils.cs b/Internal/PrefabSafeSet/Editor/Utils.cs index 853d550e5..22d524a64 100644 --- a/Internal/PrefabSafeSet/Editor/Utils.cs +++ b/Internal/PrefabSafeSet/Editor/Utils.cs @@ -50,8 +50,8 @@ public static bool IsNullOrMissing(this T self, NullOrMissingContext context) public readonly struct NullOrMissingContext { - internal Transform RootTransform { get; } - internal bool IsPartOfPrefabAsset => (object)RootTransform != null; + internal Transform? RootTransform { get; } + internal bool IsPartOfPrefabAsset => (object?)RootTransform != null; public NullOrMissingContext(Object context) { diff --git a/Internal/PrefabSafeSet/Editor/csc.rsp b/Internal/PrefabSafeSet/Editor/csc.rsp new file mode 120000 index 000000000..9276f64c5 --- /dev/null +++ b/Internal/PrefabSafeSet/Editor/csc.rsp @@ -0,0 +1 @@ +../../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/PrefabSafeSet/Editor/csc.rsp.meta b/Internal/PrefabSafeSet/Editor/csc.rsp.meta new file mode 100644 index 000000000..1f5ff7a8b --- /dev/null +++ b/Internal/PrefabSafeSet/Editor/csc.rsp.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a483ae9593dda47828301f0739550886 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs b/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs index ef080e221..02d93f041 100644 --- a/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs +++ b/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using JetBrains.Annotations; using UnityEngine; using UnityEngine.Animations; using Object = UnityEngine.Object; @@ -42,12 +41,14 @@ static PrefabSafeSetRuntimeUtil() assembly.GetType("Anatawa12.AvatarOptimizer.PrefabSafeSet.OnBeforeSerializeImpl`2"); if (OnBeforeSerializeImplType != null) return; } + if (OnBeforeSerializeImplType == null) + throw new InvalidOperationException("OnBeforeSerializeImpl`2 not found"); } public static MethodInfo GetOnBeforeSerializeCallbackMethod(Type tType, Type tLayerType, Type setType) { var implType = OnBeforeSerializeImplType.MakeGenericType(tType, tLayerType); - return implType.GetMethod("Impl", BindingFlags.Public | BindingFlags.Static, null, new[] { setType }, null); + return implType.GetMethod("Impl", BindingFlags.Public | BindingFlags.Static, null, new[] { setType }, null)!; } #endif } @@ -76,10 +77,10 @@ public abstract class PrefabSafeSetApi [SerializeField] internal TLayer[] prefabLayers = Array.Empty(); #if UNITY_EDITOR - [SerializeField, HideInInspector] internal T fakeSlot; + [SerializeField, HideInInspector] internal T? fakeSlot; internal readonly Object OuterObject; - internal T[] CheckedCurrentLayerRemoves; - internal T[] CheckedCurrentLayerAdditions; + internal T[]? CheckedCurrentLayerRemoves; + internal T[]? CheckedCurrentLayerAdditions; private static MethodInfo _onBeforeSerializeCallback = PrefabSafeSetRuntimeUtil .GetOnBeforeSerializeCallbackMethod(typeof(T), typeof(TLayer), typeof(PrefabSafeSet)); #endif @@ -256,7 +257,7 @@ public class PrefabLayer [SerializeField] internal T[] removes = Array.Empty(); [SerializeField] internal T[] additions = Array.Empty(); - public void ApplyTo(HashSet result, [CanBeNull] List list = null) + public void ApplyTo(HashSet result, List? list = null) { foreach (var remove in removes) if (remove.IsNotNull() && result.Remove(remove)) @@ -269,8 +270,8 @@ public void ApplyTo(HashSet result, [CanBeNull] List list = null) internal readonly struct ListSet { - [NotNull] private readonly List _list; - [NotNull] private readonly HashSet _set; + private readonly List _list; + private readonly HashSet _set; public ListSet(T[] initialize) { _list = new List(initialize); diff --git a/Internal/PrefabSafeSet/Runtime/csc.rsp b/Internal/PrefabSafeSet/Runtime/csc.rsp new file mode 120000 index 000000000..9276f64c5 --- /dev/null +++ b/Internal/PrefabSafeSet/Runtime/csc.rsp @@ -0,0 +1 @@ +../../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/PrefabSafeSet/Runtime/csc.rsp.meta b/Internal/PrefabSafeSet/Runtime/csc.rsp.meta new file mode 100644 index 000000000..da8283254 --- /dev/null +++ b/Internal/PrefabSafeSet/Runtime/csc.rsp.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2138c109b4401482395afe301c9cceac +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Internal/TraceAndOptimizeBase/csc.rsp b/Internal/TraceAndOptimizeBase/csc.rsp index c6acf2e0a..f8076d40e 120000 --- a/Internal/TraceAndOptimizeBase/csc.rsp +++ b/Internal/TraceAndOptimizeBase/csc.rsp @@ -1 +1 @@ -../../Editor/csc.rsp \ No newline at end of file +../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Internal/Utils/ACUtils.GetControllerAndOverrides.cs b/Internal/Utils/ACUtils.GetControllerAndOverrides.cs index 3d04625e7..ca223944c 100644 --- a/Internal/Utils/ACUtils.GetControllerAndOverrides.cs +++ b/Internal/Utils/ACUtils.GetControllerAndOverrides.cs @@ -1,6 +1,6 @@ +using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using UnityEditor.Animations; using UnityEngine; @@ -9,8 +9,9 @@ namespace Anatawa12.AvatarOptimizer static partial class ACUtils { public static (AnimatorController, IReadOnlyDictionary) GetControllerAndOverrides( - [NotNull] RuntimeAnimatorController runtimeController) + RuntimeAnimatorController runtimeController) { + if (runtimeController == null) throw new ArgumentNullException(nameof(runtimeController)); if (runtimeController is AnimatorController originalController) return (originalController, Utils.EmptyDictionary()); diff --git a/Internal/Utils/ACUtils.cs b/Internal/Utils/ACUtils.cs index 2b570ac6a..f7957df45 100644 --- a/Internal/Utils/ACUtils.cs +++ b/Internal/Utils/ACUtils.cs @@ -1,5 +1,5 @@ +using System; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEditor.Animations; using UnityEngine; @@ -7,9 +7,7 @@ namespace Anatawa12.AvatarOptimizer { public static partial class ACUtils { - [ItemNotNull] - [NotNull] - public static IEnumerable AllStateMachines([CanBeNull] AnimatorStateMachine stateMachine) + public static IEnumerable AllStateMachines(AnimatorStateMachine? stateMachine) { if (stateMachine == null) yield break; yield return stateMachine; @@ -19,9 +17,7 @@ public static IEnumerable AllStateMachines([CanBeNull] Ani yield return machine; } - [ItemNotNull] - [NotNull] - public static IEnumerable AllStates([CanBeNull] AnimatorStateMachine stateMachine) + public static IEnumerable AllStates(AnimatorStateMachine? stateMachine) { if (stateMachine == null) yield break; foreach (var state in stateMachine.states) @@ -32,9 +28,7 @@ public static IEnumerable AllStates([CanBeNull] AnimatorStateMach yield return state; } - [ItemNotNull] - [NotNull] - public static IEnumerable AllTransitions([CanBeNull] AnimatorStateMachine stateMachine) + public static IEnumerable AllTransitions(AnimatorStateMachine? stateMachine) { if (stateMachine == null) yield break; @@ -56,9 +50,7 @@ public static IEnumerable AllTransitions([CanBeNull] Ani } } - [NotNull] - [ItemNotNull] - public static IEnumerable AllClips([CanBeNull] Motion motion) + public static IEnumerable AllClips(Motion? motion) { switch (motion) { @@ -75,11 +67,10 @@ public static IEnumerable AllClips([CanBeNull] Motion motion) } } - [NotNull] - [ItemNotNull] public static IEnumerable StateMachineBehaviours( - [NotNull] RuntimeAnimatorController runtimeController) + RuntimeAnimatorController runtimeController) { + if (runtimeController == null) throw new ArgumentNullException(nameof(runtimeController)); var (controller, _) = GetControllerAndOverrides(runtimeController); foreach (var layer in controller.layers) @@ -94,10 +85,10 @@ public static IEnumerable StateMachineBehaviours( } } - [NotNull] - [ItemNotNull] - public static IEnumerable StateMachineBehaviours([NotNull] AnimatorStateMachine stateMachineIn) + public static IEnumerable StateMachineBehaviours( + AnimatorStateMachine stateMachineIn) { + if (stateMachineIn == null) throw new ArgumentNullException(nameof(stateMachineIn)); var queue = new Queue(); queue.Enqueue(stateMachineIn); @@ -117,41 +108,30 @@ public static IEnumerable StateMachineBehaviours([NotNull } } - public static int ComputeLayerCount([NotNull] this RuntimeAnimatorController controller) + public static int ComputeLayerCount(this RuntimeAnimatorController controller) { + if (controller == null) throw new ArgumentNullException(nameof(controller)); while (controller is AnimatorOverrideController overrideController) controller = overrideController.runtimeAnimatorController; return ((AnimatorController)controller).layers.Length; } - public static bool? SatisfiesInt(this AnimatorCondition condition, int value) - { - switch (condition.mode) + public static bool? SatisfiesInt(this AnimatorCondition condition, int value) => + condition.mode switch { - case AnimatorConditionMode.Equals: - return value == (int)condition.threshold; - case AnimatorConditionMode.NotEqual: - return value != (int)condition.threshold; - case AnimatorConditionMode.Greater: - return value > condition.threshold; - case AnimatorConditionMode.Less: - return value < condition.threshold; - default: - return null; - } - } - - public static bool? SatisfiesBool(this AnimatorCondition condition, bool value) - { - switch (condition.mode) + AnimatorConditionMode.Equals => value == (int)condition.threshold, + AnimatorConditionMode.NotEqual => value != (int)condition.threshold, + AnimatorConditionMode.Greater => value > condition.threshold, + AnimatorConditionMode.Less => value < condition.threshold, + _ => null + }; + + public static bool? SatisfiesBool(this AnimatorCondition condition, bool value) => + condition.mode switch { - case AnimatorConditionMode.If: - return value; - case AnimatorConditionMode.IfNot: - return !value; - default: - return null; - } - } + AnimatorConditionMode.If => value, + AnimatorConditionMode.IfNot => !value, + _ => null + }; } } diff --git a/Internal/Utils/AnimatorWeightChange.cs b/Internal/Utils/AnimatorWeightChange.cs index 0f497384b..19491a39c 100644 --- a/Internal/Utils/AnimatorWeightChange.cs +++ b/Internal/Utils/AnimatorWeightChange.cs @@ -80,4 +80,4 @@ public enum AnimatorWeightChange EitherZeroOrOne, Variable } -} \ No newline at end of file +} diff --git a/Internal/Utils/CachedGuidLoader.cs b/Internal/Utils/CachedGuidLoader.cs index a2991c4ad..f03308df5 100644 --- a/Internal/Utils/CachedGuidLoader.cs +++ b/Internal/Utils/CachedGuidLoader.cs @@ -6,7 +6,7 @@ namespace Anatawa12.AvatarOptimizer public struct CachedGuidLoader where T : Object { private readonly string _guid; - private T _cached; + private T? _cached; public CachedGuidLoader(string guid) { @@ -15,7 +15,7 @@ public CachedGuidLoader(string guid) } public T Value => - _cached + _cached != null ? _cached : _cached = AssetDatabase.LoadAssetAtPath( @@ -23,7 +23,6 @@ public CachedGuidLoader(string guid) public bool IsValid => _guid != null; - public static implicit operator CachedGuidLoader(string guid) => - new CachedGuidLoader(guid); + public static implicit operator CachedGuidLoader(string guid) => new(guid); } } diff --git a/Internal/Utils/DeepCloneHelper.cs b/Internal/Utils/DeepCloneHelper.cs index bbee53d8f..c7ec6b3b9 100644 --- a/Internal/Utils/DeepCloneHelper.cs +++ b/Internal/Utils/DeepCloneHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using nadena.dev.ndmf; using UnityEditor; using UnityEngine; @@ -21,7 +22,7 @@ public T MapObject(T obj) where T : Object // https://github.com/bdunderscore/modular-avatar/blob/db49e2e210bc070671af963ff89df853ae4514a5/Packages/nadena.dev.modular-avatar/Editor/AnimatorMerger.cs#L199-L241 // Originally under MIT License // Copyright (c) 2022 bd_ - protected abstract Object CustomClone(Object o); + protected abstract Object? CustomClone(Object o); protected enum ComponentSupport { @@ -58,7 +59,8 @@ public void Dispose() // https://github.com/bdunderscore/modular-avatar/blob/db49e2e210bc070671af963ff89df853ae4514a5/Packages/nadena.dev.modular-avatar/Editor/AnimatorMerger.cs#LL242-L340C10 // Originally under MIT License // Copyright (c) 2022 bd_ - protected T DeepClone(T original) where T : Object + [return:NotNullIfNotNull("original")] + protected T? DeepClone(T? original) where T : Object { if (original == null) return null; diff --git a/Internal/Utils/DestroyTracker.cs b/Internal/Utils/DestroyTracker.cs index e4bc1c7d2..d498b4314 100644 --- a/Internal/Utils/DestroyTracker.cs +++ b/Internal/Utils/DestroyTracker.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; using nadena.dev.ndmf; using Object = UnityEngine.Object; @@ -11,9 +10,9 @@ namespace Anatawa12.AvatarOptimizer /// public class DestroyTracker { - [CanBeNull] private static DestroyTracker _tracker; + private static DestroyTracker? _tracker; - private readonly Dictionary> _handlers = new Dictionary>(); + private readonly Dictionary?> _handlers = new (); public static void Track(Object obj, Action handler) { @@ -47,7 +46,7 @@ public static void DestroyImmediate(Object obj) { if (tracker._handlers.TryGetValue(instanceId, out var handler)) { - handler.Invoke(instanceId); + handler?.Invoke(instanceId); tracker._handlers.Remove(instanceId); } } diff --git a/Internal/Utils/EqualsHashSet.cs b/Internal/Utils/EqualsHashSet.cs index dd580c240..9a1cb9a15 100644 --- a/Internal/Utils/EqualsHashSet.cs +++ b/Internal/Utils/EqualsHashSet.cs @@ -1,18 +1,16 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; namespace Anatawa12.AvatarOptimizer { public sealed class EqualsHashSet : IEquatable> { - [NotNull] public readonly HashSet backedSet; + public readonly HashSet backedSet; - public EqualsHashSet([NotNull] HashSet backedSet) + public EqualsHashSet(HashSet backedSet) { if (backedSet == null) throw new ArgumentNullException(nameof(backedSet)); - System.Diagnostics.Debug.Assert( - backedSet == null || Equals(backedSet.Comparer, EqualityComparer.Default)); + System.Diagnostics.Debug.Assert(Equals(backedSet.Comparer, EqualityComparer.Default)); this.backedSet = backedSet; } @@ -20,24 +18,17 @@ public EqualsHashSet(IEnumerable collection) : this(new HashSet(collection { } - public int Count => backedSet?.Count ?? 0; + public int Count => backedSet.Count; - public override int GetHashCode() - { - // we use XOR to make the hashcode order-independent - var hash = backedSet.Count; - foreach (var item in backedSet) - hash ^= item.GetHashCode(); - return hash; - } + public override int GetHashCode() => backedSet.GetSetHashCode(); public bool Equals(EqualsHashSet other) => !ReferenceEquals(null, other) && (ReferenceEquals(this, other) || backedSet.SetEquals(other.backedSet)); - public override bool Equals(object obj) => + public override bool Equals(object? obj) => ReferenceEquals(this, obj) || obj is EqualsHashSet other && Equals(other); - public static bool operator ==(EqualsHashSet left, EqualsHashSet right) => Equals(left, right); - public static bool operator !=(EqualsHashSet left, EqualsHashSet right) => !Equals(left, right); + public static bool operator ==(EqualsHashSet? left, EqualsHashSet? right) => Equals(left, right); + public static bool operator !=(EqualsHashSet? left, EqualsHashSet? right) => !Equals(left, right); } } diff --git a/Internal/Utils/Matrix3x3.cs b/Internal/Utils/Matrix3x3.cs index 9fde67e0e..ac48ce395 100644 --- a/Internal/Utils/Matrix3x3.cs +++ b/Internal/Utils/Matrix3x3.cs @@ -187,19 +187,17 @@ public Matrix3x3( public override int GetHashCode() { - unchecked - { - var hashCode = m00.GetHashCode(); - hashCode = (hashCode * 397) ^ m10.GetHashCode(); - hashCode = (hashCode * 397) ^ m20.GetHashCode(); - hashCode = (hashCode * 397) ^ m01.GetHashCode(); - hashCode = (hashCode * 397) ^ m11.GetHashCode(); - hashCode = (hashCode * 397) ^ m21.GetHashCode(); - hashCode = (hashCode * 397) ^ m02.GetHashCode(); - hashCode = (hashCode * 397) ^ m12.GetHashCode(); - hashCode = (hashCode * 397) ^ m22.GetHashCode(); - return hashCode; - } + var hashCode = new HashCode(); + hashCode.Add(m00); + hashCode.Add(m10); + hashCode.Add(m20); + hashCode.Add(m01); + hashCode.Add(m11); + hashCode.Add(m21); + hashCode.Add(m02); + hashCode.Add(m12); + hashCode.Add(m22); + return hashCode.ToHashCode(); } public bool Equals(Matrix3x3 other) => @@ -207,6 +205,6 @@ public bool Equals(Matrix3x3 other) => m01.Equals(other.m01) && m11.Equals(other.m11) && m21.Equals(other.m21) && m02.Equals(other.m02) && m12.Equals(other.m12) && m22.Equals(other.m22); - public override bool Equals(object obj) => obj is Matrix3x3 other && Equals(other); + public override bool Equals(object? obj) => obj is Matrix3x3 other && Equals(other); } -} \ No newline at end of file +} diff --git a/Internal/Utils/Matrix4x4.cs b/Internal/Utils/Matrix4x4.cs index e05c4490f..0161399ba 100644 --- a/Internal/Utils/Matrix4x4.cs +++ b/Internal/Utils/Matrix4x4.cs @@ -165,4 +165,4 @@ public Matrix4x4(Vector4 column0, Vector4 column1, Vector4 column2, Vector4 colu public static Matrix4x4 TRS(Vector3 pos, Quaternion rot, Vector3 scale) => UnityMatrix4x4.TRS(pos, rot, scale); public static Matrix4x4 TRS(Transform t) => UnityMatrix4x4.TRS(t.localPosition, t.localRotation, t.localScale); } -} \ No newline at end of file +} diff --git a/Internal/Utils/MultiDimensionalNativeArray.cs b/Internal/Utils/MultiDimensionalNativeArray.cs index ef50b8afb..d2e88d3f7 100644 --- a/Internal/Utils/MultiDimensionalNativeArray.cs +++ b/Internal/Utils/MultiDimensionalNativeArray.cs @@ -54,4 +54,4 @@ public NativeArray3(int firstDimension, int secondDimension, int thirdDimension, public void Dispose() => _array.Dispose(); } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.CastDic.cs b/Internal/Utils/Utils.CastDic.cs index 30680feab..d054b2c1f 100644 --- a/Internal/Utils/Utils.CastDic.cs +++ b/Internal/Utils/Utils.CastDic.cs @@ -42,4 +42,4 @@ public bool TryGetValue(TKey key, out TValueCasted value) } } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.CopyDataFrom.cs b/Internal/Utils/Utils.CopyDataFrom.cs index 086d6e1af..98d5d1dda 100644 --- a/Internal/Utils/Utils.CopyDataFrom.cs +++ b/Internal/Utils/Utils.CopyDataFrom.cs @@ -137,4 +137,4 @@ void CopyBetweenTwoValue(SerializedProperty src, SerializedProperty dst) } } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.Float.cs b/Internal/Utils/Utils.Float.cs index eb9959f84..85a19709d 100644 --- a/Internal/Utils/Utils.Float.cs +++ b/Internal/Utils/Utils.Float.cs @@ -1,4 +1,3 @@ - using System; using UnityEngine; @@ -62,9 +61,9 @@ public static float NextFloat(float x) if (x == 0) return float.Epsilon; // rest is normal or subnormal number - var asInt = SingleToInt32Bits(x); + var asInt = BitConverter.SingleToInt32Bits(x); asInt += asInt < 0 ? -1 : 1; - return Int32BitsToSingle(asInt); + return BitConverter.Int32BitsToSingle(asInt); } public static float PreviousFloat(float x) @@ -76,21 +75,11 @@ public static float PreviousFloat(float x) if (x == 0) return -float.Epsilon; // rest is normal or subnormal number - var asInt = SingleToInt32Bits(x); + var asInt = BitConverter.SingleToInt32Bits(x); asInt -= asInt < 0 ? -1 : 1; - return Int32BitsToSingle(asInt); + return BitConverter.Int32BitsToSingle(asInt); } - // Int32BitsToSingle / SingleToInt32Bits is not available in .NET Framework 4.x - // so I implemented it. -#if UNITY_2022_3_OR_NEWER - public static int SingleToInt32Bits(float value) => BitConverter.SingleToInt32Bits(value); - public static float Int32BitsToSingle(int value) => BitConverter.Int32BitsToSingle(value); -#else - public static int SingleToInt32Bits(float value) => BitConverter.ToInt32(BitConverter.GetBytes(value), 0); - public static float Int32BitsToSingle(int value) => BitConverter.ToSingle(BitConverter.GetBytes(value), 0); -#endif - public static bool IsFinite(float x) => !float.IsNaN(x) && !float.IsInfinity(x); public static float Modulo(float x, float y) => x - y * Mathf.Floor(x / y); } diff --git a/Internal/Utils/Utils.GetHashCode2.cs b/Internal/Utils/Utils.GetHashCode2.cs index f2327e54c..c1f7f3f80 100644 --- a/Internal/Utils/Utils.GetHashCode2.cs +++ b/Internal/Utils/Utils.GetHashCode2.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using UnityEngine; namespace Anatawa12.AvatarOptimizer @@ -14,34 +13,37 @@ public static int GetHashCode2(this AnimationCurve curve) // according to https://docs.unity3d.com/2022.3/Documentation/ScriptReference/AnimationCurve.GetHashCode.html, // hashcode is calculated by KeyFrames var array = curve.keys; - return array.Aggregate(array.Length, (current, val) => unchecked(current * 314159 + val.GetHashCode2())); + HashCode code = default; + foreach (var keyframe in array) + code.Add(keyframe.GetHashCode2()); + return code.ToHashCode(); } // KeyFrame doesn't implement GetHashCode so it will be extremely slow so provide our implementation public static int GetHashCode2(this Keyframe curve) { - var hash = 0; - hash = unchecked(hash * 314159 + curve.time.GetHashCode()); - hash = unchecked(hash * 314159 + curve.value.GetHashCode()); - hash = unchecked(hash * 314159 + curve.inTangent.GetHashCode()); - hash = unchecked(hash * 314159 + curve.outTangent.GetHashCode()); + HashCode code = default; + code.Add(curve.time); + code.Add(curve.value); + code.Add(curve.inTangent); + code.Add(curve.outTangent); #pragma warning disable CS0618 // Type or member is obsolete - hash = unchecked(hash * 314159 + curve.tangentMode.GetHashCode()); + code.Add(curve.tangentMode); #pragma warning restore CS0618 // Type or member is obsolete - hash = unchecked(hash * 314159 + curve.weightedMode.GetHashCode()); - hash = unchecked(hash * 314159 + curve.inWeight.GetHashCode()); - hash = unchecked(hash * 314159 + curve.outWeight.GetHashCode()); - return hash; + code.Add(curve.weightedMode); + code.Add(curve.inWeight); + code.Add(curve.outWeight); + return code.ToHashCode(); } - // The HashSet doesn't implement HashCode - public static int GetHashCode2(this HashSet set) + // Create a hashcode for a order-independent set + public static int GetSetHashCode(this ICollection collection) { // we use XOR to make the hashcode order-independent - var hash = set.Count; - foreach (var item in set) - hash ^= item.GetHashCode(); + var hash = collection.Count; + foreach (var item in collection) + hash ^= HashCode.Combine(item); return hash; } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.ObjectReferencePropertiesEnumerable.cs b/Internal/Utils/Utils.ObjectReferencePropertiesEnumerable.cs index c1159ec89..b5e74ee13 100644 --- a/Internal/Utils/Utils.ObjectReferencePropertiesEnumerable.cs +++ b/Internal/Utils/Utils.ObjectReferencePropertiesEnumerable.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEditor; @@ -13,7 +14,7 @@ public static ObjectReferencePropertiesEnumerable ObjectReferenceProperties(this { private readonly SerializedObject _obj; - public ObjectReferencePropertiesEnumerable(SerializedObject obj) => _obj = obj; + public ObjectReferencePropertiesEnumerable(SerializedObject obj) => _obj = obj ?? throw new ArgumentNullException(nameof(obj)); public Enumerator GetEnumerator() => new Enumerator(_obj); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -87,4 +88,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.TransformDirectChildrenEnumerable.cs b/Internal/Utils/Utils.TransformDirectChildrenEnumerable.cs index fc70df1b4..6c9533fe9 100644 --- a/Internal/Utils/Utils.TransformDirectChildrenEnumerable.cs +++ b/Internal/Utils/Utils.TransformDirectChildrenEnumerable.cs @@ -41,4 +41,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.TransformParentEnumerable.cs b/Internal/Utils/Utils.TransformParentEnumerable.cs index 6f3b36bb3..8cc529353 100644 --- a/Internal/Utils/Utils.TransformParentEnumerable.cs +++ b/Internal/Utils/Utils.TransformParentEnumerable.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEngine; namespace Anatawa12.AvatarOptimizer @@ -16,16 +15,16 @@ public static TransformParentEnumerable ParentEnumerable(this Transform transfor // root is exclusive public static TransformParentEnumerable ParentEnumerable(this Transform transform, - Transform root, bool includeMe = false) => + Transform? root, bool includeMe = false) => new TransformParentEnumerable(transform, root, includeMe); public readonly struct TransformParentEnumerable : IEnumerable { private readonly Transform _transform; - private readonly Transform _root; + private readonly Transform? _root; private readonly bool _includeMe; - public TransformParentEnumerable(Transform transform, Transform root, bool includeMe) => + public TransformParentEnumerable(Transform transform, Transform? root, bool includeMe) => (_transform, _root, _includeMe) = (transform, root, includeMe); public Enumerator GetEnumerator() => new Enumerator(_transform, _root, _includeMe); @@ -35,16 +34,16 @@ public TransformParentEnumerable(Transform transform, Transform root, bool inclu public struct Enumerator : IEnumerator { object IEnumerator.Current => Current; - [NotNull] public Transform Current => _current ? _current : throw new Exception("invalid state"); + public Transform Current => _current != null ? _current : throw new Exception("invalid state"); private readonly Transform _initial; - private readonly Transform _root; + private readonly Transform? _root; private readonly bool _includeMe; private bool _beforeFirst; - private Transform _current; + private Transform? _current; - public Enumerator(Transform transform, Transform root, bool includeMe) + public Enumerator(Transform transform, Transform? root, bool includeMe) { _current = null; _initial = transform; @@ -76,4 +75,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/Internal/Utils/Utils.cs b/Internal/Utils/Utils.cs index cb7cac798..ff66dcf14 100644 --- a/Internal/Utils/Utils.cs +++ b/Internal/Utils/Utils.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -41,9 +41,8 @@ public static void FlattenMapping(this Dictionary self) } } - [ContractAnnotation("root:null => notnull")] - [ContractAnnotation("root:notnull => canbenull")] - public static string RelativePath(Transform root, Transform child) + [return:NotNullIfNotNull("root")] + public static string? RelativePath(Transform? root, Transform child) { if (root == child) return ""; @@ -143,27 +142,26 @@ public static void Deconstruct(this KeyValuePair key value = keyValuePair.Value; } - public static IEnumerable> ZipByKey( + public static IEnumerable> ZipByKey( this IReadOnlyDictionary first, IReadOnlyDictionary second) { foreach (var key in first.Keys.ToArray()) { if (!second.TryGetValue(key, out var secondValue)) secondValue = default; - yield return new KeyValuePair(key, (first[key], secondValue)); + yield return new KeyValuePair(key, (first[key], secondValue)); } foreach (var key in second.Keys.ToArray()) if (!first.ContainsKey(key)) - yield return new KeyValuePair(key, (default, second[key])); + yield return new KeyValuePair(key, (default, second[key])); } - [CanBeNull] - public static Type GetTypeFromName(string name) => + public static Type? GetTypeFromName(string name) => AppDomain.CurrentDomain.GetAssemblies().Select(assembly => assembly.GetType(name)) .FirstOrDefault(type => !(type == null)); - public static T DistinctSingleOrDefaultIfNoneOrMultiple(this IEnumerable enumerable) + public static T? DistinctSingleOrDefaultIfNoneOrMultiple(this IEnumerable enumerable) { using (var enumerator = enumerable.GetEnumerator()) { @@ -182,7 +180,7 @@ public static T DistinctSingleOrDefaultIfNoneOrMultiple(this IEnumerable e } } - public static T RemoveLast([NotNull] this IList list) + public static T RemoveLast(this IList list) { if (list == null) throw new ArgumentNullException(nameof(list)); var lastIndex = list.Count - 1; @@ -191,10 +189,10 @@ public static T RemoveLast([NotNull] this IList list) return last; } - public static EqualsHashSet ToEqualsHashSet([NotNull] this IEnumerable enumerable) => + public static EqualsHashSet ToEqualsHashSet(this IEnumerable enumerable) => new EqualsHashSet(new HashSet(enumerable)); - public static EqualsHashSet ToEqualsHashSet([NotNull] this HashSet hashSet) => + public static EqualsHashSet ToEqualsHashSet(this HashSet hashSet) => new EqualsHashSet(hashSet); } } diff --git a/Internal/Utils/csc.rsp b/Internal/Utils/csc.rsp index c6acf2e0a..f8076d40e 120000 --- a/Internal/Utils/csc.rsp +++ b/Internal/Utils/csc.rsp @@ -1 +1 @@ -../../Editor/csc.rsp \ No newline at end of file +../../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Localization/en-us.po b/Localization/en-us.po index f3b833e57..c10e9ca9e 100644 --- a/Localization/en-us.po +++ b/Localization/en-us.po @@ -679,9 +679,6 @@ msgstr "Automatically Remove Zero Sized Polygons" msgid "TraceAndOptimize:OptimizePhysBone:UnknownPhysBoneColliderShape" msgstr "Unknown PhysBone Collider Shape '{0}' is specified." -msgid "TraceAndOptimize:OptimizeAnimator:Unity2019" -msgstr "Most features of Optimize Animator is not supported on Unity 2019. Please consider use Unity 2021 or later." - # endregion #region ApplyObjectMapping diff --git a/Localization/ja-jp.po b/Localization/ja-jp.po index 2e1f663c1..d20df3162 100644 --- a/Localization/ja-jp.po +++ b/Localization/ja-jp.po @@ -590,9 +590,6 @@ msgstr "面積がゼロのポリゴンを自動的に削除する" msgid "TraceAndOptimize:OptimizePhysBone:UnknownPhysBoneColliderShape" msgstr "未知のPhysBone Collider形状'{0}'が指定されています。" -msgid "TraceAndOptimize:OptimizeAnimator:Unity2019" -msgstr "Unity 2019では、Optimize Animatorの多くの機能がサポートされていません。Unity 2021以降に更新するのをご検討ください。" - # endregion #region ApplyObjectMapping diff --git a/Localization/zh-cn.po b/Localization/zh-cn.po index dba0de566..389c20901 100644 --- a/Localization/zh-cn.po +++ b/Localization/zh-cn.po @@ -574,9 +574,6 @@ msgstr "自动删除面积为零的多边形" msgid "TraceAndOptimize:OptimizePhysBone:UnknownPhysBoneColliderShape" msgstr "指定了未知的PhysBone Collider形状'{0}'。" -msgid "TraceAndOptimize:OptimizeAnimator:Unity2019" -msgstr "在Unity 2019中,“优化动画控制器”的许多功能不受支持。请考虑更新到Unity 2021或更高版本。" - # endregion #region ApplyObjectMapping diff --git a/Localization/zh-hant.po b/Localization/zh-hant.po index d125a3ac0..a345aa916 100644 --- a/Localization/zh-hant.po +++ b/Localization/zh-hant.po @@ -601,9 +601,6 @@ msgstr "自動移除面積為零的多邊形" msgid "TraceAndOptimize:OptimizePhysBone:UnknownPhysBoneColliderShape" msgstr "指定了未知的 PhysBone Collider 形狀:「{0}」。" -msgid "TraceAndOptimize:OptimizeAnimator:Unity2019" -msgstr "「優化 Animator」的大部分功能已不支援 Unity 2019。請考慮使用 Unity 2021 或更高版本。" - # endregion #region ApplyObjectMapping diff --git a/Runtime/API/PrefabSafeSetAccessor.cs b/Runtime/API/PrefabSafeSetAccessor.cs index 8849add94..89e536549 100644 --- a/Runtime/API/PrefabSafeSetAccessor.cs +++ b/Runtime/API/PrefabSafeSetAccessor.cs @@ -6,7 +6,7 @@ namespace Anatawa12.AvatarOptimizer.API { [PublicAPI] - public readonly struct PrefabSafeSetAccessor : ICollection + public readonly struct PrefabSafeSetAccessor : ICollection where T : notnull { private readonly PrefabSafeSetApi _set; diff --git a/Runtime/InternalAutoFreezeMeaninglessBlendShape.cs b/Runtime/InternalAutoFreezeMeaninglessBlendShape.cs index 6c303fe64..fc446b574 100644 --- a/Runtime/InternalAutoFreezeMeaninglessBlendShape.cs +++ b/Runtime/InternalAutoFreezeMeaninglessBlendShape.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using JetBrains.Annotations; using UnityEngine; using UnityEngine.Animations; diff --git a/Runtime/MakeChildren.cs b/Runtime/MakeChildren.cs index 3115917f6..cde9b38a0 100644 --- a/Runtime/MakeChildren.cs +++ b/Runtime/MakeChildren.cs @@ -12,5 +12,10 @@ internal class MakeChildren : AvatarTagComponent public bool executeEarly; [NotKeyable, AAOLocalized("MakeChildren:prop:children")] public PrefabSafeSet.TransformSet children; + + internal MakeChildren() + { + children = new PrefabSafeSet.TransformSet(this); + } } } diff --git a/Runtime/MergePhysBone.cs b/Runtime/MergePhysBone.cs index 5f1cada06..6898391f4 100644 --- a/Runtime/MergePhysBone.cs +++ b/Runtime/MergePhysBone.cs @@ -118,6 +118,7 @@ public struct Curve0To180Config public Curve0To180Config(float value) : this() { this.value = value; + curve = new AnimationCurve(); } } @@ -132,6 +133,7 @@ public struct Curve0To90Config public Curve0To90Config(float value) : this() { this.value = value; + curve = new AnimationCurve(); } } @@ -251,4 +253,4 @@ internal enum CollidersSettings } } -#endif \ No newline at end of file +#endif diff --git a/Runtime/csc.rsp b/Runtime/csc.rsp index a31032be9..fa12e2b6d 120000 --- a/Runtime/csc.rsp +++ b/Runtime/csc.rsp @@ -1 +1 @@ -../Editor/csc.rsp \ No newline at end of file +../.csc.rsp.nullsafe \ No newline at end of file diff --git a/Test~/AnimatorOptimizer/com.anatawa12.avatar-optimizer.test.animator-optimizer.asmdef b/Test~/AnimatorOptimizer/com.anatawa12.avatar-optimizer.test.animator-optimizer.asmdef index 94149e5b7..b4d26e400 100644 --- a/Test~/AnimatorOptimizer/com.anatawa12.avatar-optimizer.test.animator-optimizer.asmdef +++ b/Test~/AnimatorOptimizer/com.anatawa12.avatar-optimizer.test.animator-optimizer.asmdef @@ -16,9 +16,7 @@ "overrideReferences": true, "precompiledReferences": [], "autoReferenced": false, - "defineConstraints": [ - "UNITY_2021_3_OR_NEWER" - ], + "defineConstraints": [], "versionDefines": [], "noEngineReferences": false } \ No newline at end of file diff --git a/Test~/Basic/csc.rsp b/Test~/Basic/csc.rsp index c6acf2e0a..a412015d1 120000 --- a/Test~/Basic/csc.rsp +++ b/Test~/Basic/csc.rsp @@ -1 +1 @@ -../../Editor/csc.rsp \ No newline at end of file +../../.csc.rsp.nullunsafe \ No newline at end of file diff --git a/package.json b/package.json index 84bf98f49..4991b0132 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,6 @@ "license": "MIT", "vpmDependencies": { "nadena.dev.ndmf": "^1.3.0", - "com.vrchat.avatars": ">=3.3.0 <3.8.0" + "com.vrchat.avatars": ">=3.7.0 <3.8.0" } }