private static void PopulateClass(TypeSafeDataUnit dataUnit, CodeTypeDeclaration container) { foreach (var nestedUnit in dataUnit.NestedUnits) { string className; if (!CompilerUtil.GetSafeNameAndVerifyNotDuplicate(nestedUnit.ClassName, container, out className)) { continue; } if (className == container.Name) { TSLog.LogWarning(LogCategory.Compile, Strings.Warning_NameCannotBeSameAsParent); className = "_" + className; // Check for duplicates again after having added the '_' if (!CompilerUtil.GetSafeNameAndVerifyNotDuplicate(className, container, out className)) { continue; } } var nestedContainer = CompilerUtil.CreateStaticType(className); PopulateClass(nestedUnit, nestedContainer); container.Members.Add(nestedContainer); } PopulateClassMembers(dataUnit, container); }
public CodeCompileUnit Compile(TypeSafeDataUnit dataUnit) { var compileUnit = new CodeCompileUnit(); compileUnit.UserData.Add(Strings.CompileUnitUserDataKey, dataUnit.FileName); CompilerUtil.WriteHeader(compileUnit); var ns = new CodeNamespace(Namespace); compileUnit.Namespaces.Add(ns); var className = CompilerUtil.GetSafeName(dataUnit.ClassName, false, false); if (className != dataUnit.ClassName) { TSLog.LogWarning(LogCategory.Compile, string.Format("Class name was modified to conform to C# standards ({0} -> {1})", dataUnit.ClassName, className)); } var container = CompilerUtil.CreateStaticType(className); CompilerUtil.AddTypeSafeTag(container); PopulateClass(dataUnit, container); ns.Types.Add(container); return(compileUnit); }
public TypeSafeDataUnit GetTypeSafeDataUnit() { var rootUnit = new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.AudioMixersName) , typeof(float), new List <TypeSafeDataEntry>(), false, "AudioMixers"); var mixers = Settings.Instance.AudioMixers; foreach (var guid in mixers) { var assetPath = AssetDatabase.GUIDToAssetPath(guid); var asset = AssetDatabase.LoadAssetAtPath <AudioMixer>(assetPath); TSLog.Log(LogCategory.Trace, string.Format("AudioMixer: {0}", assetPath), asset); rootUnit.NestedUnits.Add(CreateMixerDataUnit(new AudioMixerControllerWrapper(asset))); } return(rootUnit); }
private TypeSafeDataUnit CreateAnimatorDataUnit(AnimatorController controller) { var unit = new TypeSafeDataUnit(controller.name, typeof(string)); var parametersUnit = new TypeSafeDataUnit("Parameters", typeof(int)); foreach (var param in controller.parameters) { TSLog.Log(LogCategory.Trace, string.Format("Parameter: {0} ({1})", param.name, param.nameHash)); if (parametersUnit.Data.Any(p => p.PropertyName == param.name)) { TSLog.LogWarning(LogCategory.Compile, string.Format("[AnimatorController] Duplicate parameter name ({0}).", param.name), controller); continue; } parametersUnit.Data.Add(new TypeSafeDataEntry(param.name, new object[] { param.nameHash })); } var layersUnit = new TypeSafeDataUnit("Layers", typeof(int)); for (var i = 0; i < controller.layers.Length; i++) { var layer = controller.layers[i]; TSLog.Log(LogCategory.Trace, string.Format("Layer: {0}, Index: {1}", layer.name, i)); if (layersUnit.Data.Any(p => p.PropertyName == layer.name)) { TSLog.LogWarning(LogCategory.Compile, string.Format("[AnimatorController] Duplicate layer name ({0}).", layer.name), controller); continue; } layersUnit.Data.Add(new TypeSafeDataEntry(layer.name, new object[] { i })); } unit.NestedUnits.Add(parametersUnit); unit.NestedUnits.Add(layersUnit); return(unit); }
private TypeSafeDataUnit CreateMixerDataUnit(AudioMixerControllerWrapper wrapper) { var unit = new TypeSafeDataUnit(wrapper.Mixer.name, typeof(string)); var parametersUnit = new TypeSafeDataUnit("Parameters", typeof(string)); foreach (var param in wrapper.exposedParameters) { TSLog.Log(LogCategory.Trace, string.Format("Parameter: {0}", param.name)); if (parametersUnit.Data.Any(p => p.PropertyName == param.name)) { TSLog.LogWarning(LogCategory.Compile, string.Format("[AudioMixer] Duplicate parameter name ({0}).", param.name), wrapper.Mixer); continue; } parametersUnit.Data.Add(new TypeSafeDataEntry(param.name, new object[] { param.name })); } var snapshotsUnit = new TypeSafeDataUnit("Snapshots", typeof(string)); foreach (var snapshot in wrapper.snapshots) { TSLog.Log(LogCategory.Trace, string.Format("Snapshot: {0}", snapshot.name)); if (snapshotsUnit.Data.Any(p => p.PropertyName == snapshot.name)) { TSLog.LogWarning(LogCategory.Compile, string.Format("[AudioMixer] Duplicate snapshot name ({0}).", snapshot.name), wrapper.Mixer); continue; } snapshotsUnit.Data.Add(new TypeSafeDataEntry(snapshot.name, new object[] { snapshot.name })); } unit.NestedUnits.Add(parametersUnit); unit.NestedUnits.Add(snapshotsUnit); return(unit); }
public TypeSafeDataUnit GetTypeSafeDataUnit() { var unit = new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.TagsTypeName), typeof(string)); var tags = InternalEditorUtility.tags; foreach (var tag in tags) { var ignore = string.IsNullOrEmpty(tag) || tag.Trim().Length == 0; TSLog.Log(LogCategory.Scanner, string.Format("Tag: {0}, (ignore={1})", tag, ignore)); if (!ignore) { unit.Data.Add(new TypeSafeDataEntry(tag, new object[] { tag })); } } unit.EnableAllProperty = true; unit.FileName = "Tags"; return(unit); }
private static void PopulateClassMembers(TypeSafeDataUnit unit, CodeTypeDeclaration container) { // Create the list type that is used to store the internal array (not used when All list is disabled) var valueListType = new CodeTypeReference(typeof(IList <>)) { TypeArguments = { unit.DataType } }; // Set up the default type for members var dataType = new CodeTypeReference(unit.DataType); // Use global references CompilerUtil.SetTypeGlobalReference(dataType); CompilerUtil.SetTypeGlobalReference(valueListType); // Expression to make the internal list (not used when All list is disabled) var arrayExpression = new CodeArrayCreateExpression(dataType); //TSLog.Log(LogCategory.Trace, $"[DataUnitCompiler] Populating {container.Name}"); foreach (var c in unit.Data) { // Can't override type if using the All property method (since can't store non-compatible types in the list) if (unit.EnableAllProperty && c.OverrideType != null) { throw new InvalidOperationException("Cannot override type when using All list."); } var name = c.PropertyName; string memberName; if ( !CompilerUtil.GetSafeNameAndVerifyNotDuplicate(name, container, out memberName, !c.OverrideRestrictedNames)) { continue; } // Create the expression to initialize this member var entryExpression = GetCreateExpression(c, c.OverrideType != null ? c.OverrideType : unit.DataType); var isObsolete = !string.IsNullOrEmpty(c.ObsoleteWarning); //TSLog.Log(LogCategory.Trace, $"[DataUnitCompiler] Member (name={memberName}, isObsolete={isObsolete})"); // Exclude obsolete members from the _all array if (unit.EnableAllProperty && !isObsolete) { // Add the initializer expression to the internal _all array arrayExpression.Initializers.Add(entryExpression); } CodeTypeMember member; // Create a field if one of the following criteria matches: // - Entry is a primitive or string. We duplicate the data (include in _all array and const field) so that const uses are faster // - All property is disabled, so we don't have an internal _all array to access // - Entry has an obsolete warning and so isn't included in the internal _all array. if (!unit.EnableAllProperty || unit.DataType.IsPrimitive || unit.DataType == typeof(string) || isObsolete) { //TSLog.Log(LogCategory.Trace, $"[DataUnitCompiler] Member handled as field"); var entryTypeReference = dataType; var attributes = MemberAttributes.Public; if (c.OverrideType != null) { entryTypeReference = new CodeTypeReference(c.OverrideType); } if (CompilerUtil.IsPrimitiveType(unit.DataType)) { attributes |= MemberAttributes.Const; } else { attributes |= MemberAttributes.Static; entryTypeReference = new CodeTypeReference("readonly global::" + entryTypeReference.BaseType); } // Duplicate data and create a field for data entry member = new CodeMemberField { Name = memberName, Type = entryTypeReference, Attributes = attributes, InitExpression = entryExpression }; if (isObsolete) { //TSLog.Log(LogCategory.Trace, $"[DataUnitCompiler] Adding obsolete warning: {c.ObsoleteWarning}"); member.CustomAttributes.Add(CompilerUtil.GetObsoleteAttribute(c.ObsoleteWarning, false)); } } else { //TSLog.Log(LogCategory.Trace, $"[DataUnitCompiler] Member handled as property"); // Otherwise create a property getter to access the internal _all array element member = new CodeMemberProperty { Name = memberName, Type = dataType, HasSet = false, HasGet = true, Attributes = MemberAttributes.Static | MemberAttributes.Public, GetStatements = { new CodeMethodReturnStatement(new CodeArrayIndexerExpression( new CodeVariableReferenceExpression("__all"), new CodePrimitiveExpression(arrayExpression.Initializers.Count - 1))) } }; } container.Members.Add(member); } if (unit.EnableAllProperty) { var all = new CodeMemberField(valueListType, "__all") { InitExpression = new CodeObjectCreateExpression( new CodeTypeReference(typeof(ReadOnlyCollection <>), CodeTypeReferenceOptions.GlobalReference) { TypeArguments = { dataType } }, arrayExpression), Attributes = MemberAttributes.Private | MemberAttributes.Static }; container.Members.Add(all); var allPublic = new CodeMemberProperty { Name = "All", Type = valueListType, GetStatements = { new CodeMethodReturnStatement(new CodeFieldReferenceExpression { FieldName = "__all" }) }, HasGet = true, Attributes = MemberAttributes.Public | MemberAttributes.Static }; container.Members.Add(allPublic); } }