private static void DetectLimb(AvatarNaming.BoneType boneType, AvatarNaming.BoneSide boneSide, ref Transform firstBone, ref Transform secondBone, ref Transform lastBone, Transform[] transforms) { Transform[] limb = AvatarNaming.GetBonesOfTypeAndSide(boneType, boneSide, transforms); if (limb.Length < 3) { //Warning.Log("Unable to detect biped bones by bone names. Please manually assign bone references.", firstBone, true); return; } // Standard biped characters if (limb.Length == 3) { firstBone = limb[0]; secondBone = limb[1]; lastBone = limb[2]; } // For Bootcamp soldier type of characters with more than 3 limb bones if (limb.Length > 3) { firstBone = limb[0]; secondBone = limb[2]; lastBone = limb[limb.Length - 1]; } }
//[InlineData(typeof(IDisposable))] //[Trait("LongRunning", "true")] //[MemberData(nameof(GetTargetTypes))] //[Theory] public void GenerateCode(params Type[] types) { var code = @" using System; namespace Avatars.UnitTests { public class Test { public void Do() { var avatar = Avatar.Of<$$>(); Console.WriteLine(avatar.ToString()); } } }".Replace("$$", string.Join(", ", types.Select(t => t.GetFormattedName(TypeNameFormatOptions.Namespaces)))); var(diagnostics, compilation) = GetGeneratedOutput(code); Assert.Empty(diagnostics); var assembly = Emit(compilation); var name = AvatarNaming.GetFullName(types.First(), types.Skip(1).ToArray()); var type = assembly.GetType(name, true); var avatar = Activator.CreateInstance(type !); foreach (var t in types) { Assert.IsAssignableFrom(t, avatar); } }
/// <summary> /// Gets the runtime mock full name from its base type and implemented interfaces. /// </summary> public static string GetFullName(string rootNamespace, string suffix, Type baseType, params Type[] additionalInterfaces) => AvatarNaming.GetFullName(rootNamespace, suffix, baseType, additionalInterfaces);
/// <summary> /// Gets the runtime mock name from its base type and optional additional interfaces /// and the given <paramref name="suffix"/> appended to the type name. /// </summary> public static string GetName(string suffix, Type baseType, Type[] additionalInterfaces) => AvatarNaming.GetName(suffix, baseType, additionalInterfaces);
void DetectReferencesByNaming() { Transform[] children = transform.GetComponentsInChildren <Transform>(); DetectLimb(AvatarNaming.BoneType.Arm, AvatarNaming.BoneSide.Left, ref leftArm_UpperArm, ref leftArm_LowerArm, ref leftArm_Hand, children); DetectLimb(AvatarNaming.BoneType.Arm, AvatarNaming.BoneSide.Right, ref rightArm_UpperArm, ref rightArm_LowerArm, ref rightArm_Hand, children); DetectLimb(AvatarNaming.BoneType.Leg, AvatarNaming.BoneSide.Left, ref leftLeg_UpperLeg, ref leftLeg_LowerLeg, ref leftLeg_Foot, children); DetectLimb(AvatarNaming.BoneType.Leg, AvatarNaming.BoneSide.Right, ref rightLeg_UpperLeg, ref rightLeg_LowerLeg, ref rightLeg_Foot, children); if (leftLeg_Foot && leftLeg_Foot.childCount > 0) { leftLeg_Toes = leftLeg_Foot.GetChild(0); } if (rightLeg_Foot && rightLeg_Foot.childCount > 0) { rightLeg_Toes = rightLeg_Foot.GetChild(0); } head_Head = AvatarNaming.GetBone(children, AvatarNaming.BoneType.Head); body_LeftBreast = AvatarNaming.GetBone(children, AvatarNaming.BoneType.Breast, AvatarNaming.BoneSide.Left); body_RightBreast = AvatarNaming.GetBone(children, AvatarNaming.BoneType.Breast, AvatarNaming.BoneSide.Right); body_Hips = AvatarNaming.GetNamingMatch(children, AvatarNaming.pelvis); // If pelvis is not an ancestor of a leg, it is not a valid pelvis if (body_Hips == null || !AvatarHierarchy.IsAncestor(leftLeg_UpperLeg, body_Hips)) { if (leftLeg_UpperLeg != null) { body_Hips = leftLeg_UpperLeg; } if (rightLeg_UpperLeg != null) { body_Hips = rightLeg_UpperLeg; } } body_Chest = GetSameParent(leftArm_UpperArm, rightArm_UpperArm); if (body_Chest.parent != body_Hips) { body_Spine = body_Chest.parent; } else { body_Spine = body_Chest; body_Chest = null; } leftArm_Shoulder = GetParentBeforeSameParent(leftArm_UpperArm, rightArm_UpperArm); rightArm_Shoulder = GetParentBeforeSameParent(rightArm_UpperArm, leftArm_UpperArm); if (head_Head.parent != body_Hips && head_Head.parent != body_Spine && head_Head.parent != body_Chest) { head_Neck = head_Head.parent; } Transform[] eyes = AvatarNaming.GetBonesOfType(AvatarNaming.BoneType.Eye, children); if (eyes.Length > 1) { head_LeftEye = GetLeftest(eyes); head_RightEye = GetRightest(eyes); } MatchFingers(); }
#pragma warning disable IDE0079 // Remove unnecessary suppression #pragma warning disable CA1822 // Intended to be run by the ad-hoc TD.NET runner public void UpdateAvatars() { if (!Debugger.IsAttached) { throw new InvalidOperationException("This is intended to be run with the debugger attached."); } var code = @" using System; using Avatars; using Sample; namespace UnitTests { public class Test { public void Do() { _ = Avatar.Of<ICalculator>(); _ = Avatar.Of<ICalculator, IDisposable>(); _ = Avatar.Of<Calculator>(); _ = Avatar.Of<CalculatorBase>(); _ = Avatar.Of<ICalculatorMemory>(); _ = Avatar.Of<CalculatorMemory>(); _ = Avatar.Of<CalculatorMemoryBase>(); } } }"; var libs = new HashSet <string>(File.ReadAllLines("lib.txt"), StringComparer.OrdinalIgnoreCase) .ToDictionary(x => Path.GetFileName(x)); var args = CSharpCommandLineParser.Default.Parse( File.ReadAllLines("csc.txt"), ThisAssembly.Project.MSBuildProjectDirectory, sdkDirectory: null); var syntaxTree = CSharpSyntaxTree.ParseText( code, options: args.ParseOptions.WithLanguageVersion(LanguageVersion.Latest), path: Path.GetTempFileName(), encoding: Encoding.UTF8); var sources = new List <SyntaxTree> { syntaxTree }; var additionalSources = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { "Avatar.cs", "Avatar.StaticFactory.cs" }; foreach (var source in args.SourceFiles.Where(x => additionalSources.Contains(Path.GetFileName(x.Path)))) { var filePath = source.Path; var fileName = filePath.StartsWith(ThisAssembly.Project.MSBuildProjectDirectory) ? filePath.Substring(ThisAssembly.Project.MSBuildProjectDirectory.Length).TrimStart(Path.DirectorySeparatorChar) : filePath; sources.Add(CSharpSyntaxTree.ParseText( File.ReadAllText(filePath), options: args.ParseOptions.WithLanguageVersion(LanguageVersion.Latest), path: filePath, encoding: Encoding.UTF8)); } foreach (var thisAssemblyFile in Directory.EnumerateFiles( Path.Combine( ThisAssembly.Project.MSBuildProjectDirectory, ThisAssembly.Project.IntermediateOutputPath, "generated"), "ThisAssembly.*.cs", SearchOption.AllDirectories)) { sources.Add(CSharpSyntaxTree.ParseText( File.ReadAllText(thisAssemblyFile), options: args.ParseOptions.WithLanguageVersion(LanguageVersion.Latest), path: thisAssemblyFile, encoding: Encoding.UTF8)); } Compilation compilation = CSharpCompilation.Create( "ManualAvatars", sources, args.MetadataReferences.Select(x => libs.TryGetValue(Path.GetFileName(x.Reference), out var lib) ? MetadataReference.CreateFromFile(lib) : MetadataReference.CreateFromFile(x.Reference)), args.CompilationOptions.WithCryptoKeyFile(null).WithOutputKind(OutputKind.DynamicallyLinkedLibrary)); AssertCode.NoErrors(compilation); Predicate <Diagnostic> ignored = d => d.Severity == DiagnosticSeverity.Hidden || d.Severity == DiagnosticSeverity.Info; var diagnostics = compilation.GetDiagnostics().RemoveAll(ignored); var options = EditorConfigOptionsProvider.Create(Directory.EnumerateFiles( Path.Combine(ThisAssembly.Project.MSBuildProjectDirectory, ThisAssembly.Project.IntermediateOutputPath), "*.editorconfig", SearchOption.TopDirectoryOnly)); var driver = CSharpGeneratorDriver.Create( new[] { new AvatarGenerator() }, parseOptions: args.ParseOptions.WithLanguageVersion(LanguageVersion.Latest), optionsProvider: options); // Don't timeout if we're debugging. var token = Debugger.IsAttached ? default : new CancellationTokenSource(5000).Token; driver.RunGeneratorsAndUpdateCompilation(compilation, out var output, out diagnostics, token); diagnostics = diagnostics.RemoveAll(ignored); AssertCode.NoErrors(compilation); // Copy from intermediate output to manual avatars folder. var generatedDir = Path.Combine( ThisAssembly.Project.MSBuildProjectDirectory, ThisAssembly.Project.IntermediateOutputPath, "generated", nameof(AvatarGenerator)); var names = new[] { AvatarNaming.GetName(typeof(ICalculator)) + ".cs", AvatarNaming.GetName(typeof(ICalculator), typeof(IDisposable)) + ".cs", AvatarNaming.GetName(typeof(Calculator)) + ".cs", AvatarNaming.GetName(typeof(CalculatorBase)) + ".cs", AvatarNaming.GetName(typeof(ICalculatorMemory)) + ".cs", AvatarNaming.GetName(typeof(CalculatorMemory)) + ".cs", AvatarNaming.GetName(typeof(CalculatorMemoryBase)) + ".cs", }; foreach (var name in names) { File.Copy( Path.Combine(generatedDir, name), Path.Combine(ThisAssembly.Project.MSBuildProjectDirectory, @"..\ManualAvatars\Avatars", name), true); } }
private static void DetectLimb(AvatarNaming.BoneType boneType, AvatarNaming.BoneSide boneSide, ref Transform firstBone, ref Transform secondBone, ref Transform lastBone, Transform[] transforms) { Transform[] limb = AvatarNaming.GetBonesOfTypeAndSide(boneType, boneSide, transforms); if (limb.Length < 3) { //Warning.Log("Unable to detect biped bones by bone names. Please manually assign bone references.", firstBone, true); return; } // Standard biped characters if (limb.Length == 3) { firstBone = limb[0]; secondBone = limb[1]; lastBone = limb[2]; } // For Bootcamp soldier type of characters with more than 3 limb bones if (limb.Length > 3) { firstBone = limb[0]; secondBone = limb[2]; lastBone = limb[limb.Length - 1]; } }
public void GenericOfGenericName() { var name = AvatarNaming.GetName(typeof(ICollection <HashSet <ICalculator> >)); Assert.Equal($"ICollectionOfHashSetOf{nameof(ICalculator)}{AvatarNaming.DefaultSuffix}", name); }
public void GenericOfTwoGenericNames() { var name = AvatarNaming.GetName(typeof(ICollection <KeyValuePair <string, ICalculator> >)); Assert.Equal($"ICollectionOfKeyValuePairOfString{nameof(ICalculator)}{AvatarNaming.DefaultSuffix}", name); }
public void GenericConstructedName() { var name = AvatarNaming.GetName(typeof(HashSet <ICalculator>)); Assert.Equal($"HashSetOf{nameof(ICalculator)}{AvatarNaming.DefaultSuffix}", name); }
public void GenericName() { var name = AvatarNaming.GetName(typeof(IDictionary <,>)); Assert.Equal($"IDictionaryOfTKeyTValue{AvatarNaming.DefaultSuffix}", name); }
public void NamespaceForGlobalType() { var name = AvatarNaming.GetFullName(typeof(IGlobal)); Assert.Equal($"{AvatarNaming.DefaultRootNamespace}.{nameof(IGlobal)}{AvatarNaming.DefaultSuffix}", name); }
public void FullNameWithInterfaces() { var name = AvatarNaming.GetFullName(typeof(ICalculator), typeof(IDisposable), typeof(IServiceProvider)); Assert.Equal($"{AvatarNaming.DefaultRootNamespace}.{typeof(ICalculator).Namespace}.ICalculatorIDisposableIServiceProvider{AvatarNaming.DefaultSuffix}", name); }
public void FullNameWithNamespaceAndInterfaces() { var name = AvatarNaming.GetFullName("Test", typeof(ICalculator), typeof(IDisposable), typeof(IServiceProvider)); Assert.Equal($"Test.{typeof(ICalculator).Namespace}.ICalculatorIDisposableIServiceProvider" + AvatarNaming.DefaultSuffix, name); }
public void FullName() { var name = AvatarNaming.GetFullName(typeof(ICalculator)); Assert.Equal($"{AvatarNaming.DefaultRootNamespace}.{typeof(ICalculator).Namespace}.{nameof(ICalculator)}{AvatarNaming.DefaultSuffix}", name); }
public void SimpleName() { var name = AvatarNaming.GetName(typeof(ICalculator)); Assert.Equal(nameof(ICalculator) + AvatarNaming.DefaultSuffix, name); }