Example #1
0
        /// <summary>
        /// Generate new Atoms based on the input data.
        /// </summary>
        /// <param name="valueType">The type of Atom to generate.abstract Eg. double, byte, MyStruct, MyClass.</param>
        /// <param name="baseWritePath">Base write path (relative to the Asset folder) where the Atoms are going to be written to.</param>
        /// <param name="isEquatable">Is the `type` provided implementing `IEquatable`?</param>
        /// <param name="atomTypesToGenerate">A list of `AtomType`s to be generated.</param>
        /// <param name="typeNamespace">If the `type` provided is defined under a namespace, provide that namespace here.</param>
        /// <param name="subUnityAtomsNamespace">By default the Atoms that gets generated will be under the namespace `UnityAtoms`. If you for example like it to be under `UnityAtoms.MyNamespace` you would then enter `MyNamespace` in this field.</param>
        /// <example>
        /// <code>
        /// namespace MyNamespace
        /// {
        ///     public struct MyStruct
        ///     {
        ///         public string Text;
        ///         public int Number;
        ///     }
        /// }
        /// var generator = new Generator();
        /// generator.Generate("MyStruct", "", false, new List&lt;AtomType&gt;() { AtomTypes.ACTION }, "MyNamespace", ""); // Generates an Atom Action of type MyStruct
        /// </code>
        /// </example>
        public static void Generate(AtomReceipe atomReceipe, string baseWritePath, string[] templatePaths, List <string> templateConditions, Dictionary <string, string> templateVariables)
        {
            var(atomType, valueType) = atomReceipe;

            // TODO: More validation of that the type exists / is correct.
            if (string.IsNullOrEmpty(valueType))
            {
                Debug.LogWarning($"{Runtime.Constants.LOG_PREFIX} You need to specify a value type. Aborting!");
                return;
            }
            if (string.IsNullOrEmpty(baseWritePath) || !Directory.Exists(baseWritePath))
            {
                Debug.LogWarning($"{Runtime.Constants.LOG_PREFIX} You need to specify a valid base write path. Aborting!");
                return;
            }

            Debug.Log($"{Runtime.Constants.LOG_PREFIX} Generating atom {atomType.Name} for value type {valueType}");

            List <Tuple <string, string> > filesToGenerate = new List <Tuple <string, string> >()
            {
                new Tuple <string, string>(atomType.TemplateName, atomType.RelativeFileNameAndPath)
            };

            if (atomType.HasDrawerTemplate)
            {
                filesToGenerate.Add(new Tuple <string, string>(atomType.DrawerTemplateName, atomType.RelativeDrawerFileNameAndPath));
            }
            if (atomType.HasEditorTemplate)
            {
                filesToGenerate.Add(new Tuple <string, string>(atomType.EditorTemplateName, atomType.RelativeEditorFileNameAndPath));
            }

            foreach (var(templateName, relativeFilePath) in filesToGenerate)
            {
                var templatePath = templatePaths.FirstOrDefault((path) => path.EndsWith(templateName));

                if (string.IsNullOrEmpty(templatePath))
                {
                    Debug.Log($"{Runtime.Constants.LOG_PREFIX} Template {templateName} for {atomType.DisplayName} not found. Skipping!");
                    return;
                }

                var resolvedRelativeFilePath = Templating.ResolveVariables(templateVariables: templateVariables, toResolve: relativeFilePath);
                var template      = File.ReadAllText(templatePath);
                var filePath      = Path.Combine(baseWritePath, resolvedRelativeFilePath);
                var fileDirectory = Path.GetDirectoryName(filePath);

                // Create write directory
                Directory.CreateDirectory(fileDirectory);

                // Adjust content
                var content = Templating.ResolveVariables(templateVariables: templateVariables, toResolve: template);
                content = Templating.ResolveConditionals(template: content, trueConditions: templateConditions);
                content = RemoveDuplicateNamespaces(template: content);

                // Write to file
                File.WriteAllText(filePath, content);
                AssetDatabase.ImportAsset(filePath);
            }
        }
Example #2
0
        /// <summary>
        /// Resolve file name based on input data.
        /// </summary>
        /// <param name="templateVariables">Template variables. </param>
        /// <param name="templateName">Template name.</param>
        /// <param name="lastIndexOfDoubleUnderscore">Last index of double underscore.</param>
        /// <param name="capitalizedType">Capitalized type.</param>
        /// <param name="capitalizedAtomType">Capitalized Atom type (string).</param>
        /// <param name="typeOccurrences">Number of occurrences of the type.</param>
        /// <returns>The filename to use.</returns>
        private static string ResolveFileName(Dictionary <string, string> templateVariables, string templateName, int lastIndexOfDoubleUnderscore, string capitalizedType, string capitalizedAtomType, int typeOccurrences)
        {
            if (templateName.Contains("Set{TYPE_NAME}VariableValue"))
            {
                return(Templating.ResolveVariables(templateVariables: templateVariables, toResolve: $"{capitalizedAtomType}.cs"));
            }

            string fileName;

            if (templateName.Contains("AtomDrawer"))
            {
                fileName = $"{capitalizedType.Repeat(typeOccurrences)}{capitalizedAtomType}Drawer.cs";
            }
            else if (templateName.Contains("AtomEditor"))
            {
                fileName = $"{capitalizedType.Repeat(typeOccurrences)}{capitalizedAtomType}Editor.cs";
            }
            else
            {
                fileName = $"{capitalizedType.Repeat(typeOccurrences)}{capitalizedAtomType}.cs";
            }

            return(Templating.ResolveVariables(templateVariables: templateVariables, toResolve: fileName));
        }
Example #3
0
        /// <summary>
        /// Generate new Atoms based on the input data.
        /// </summary>
        /// <param name="type">The type of Atom to generate.abstract Eg. double, byte, MyStruct, MyClass.</param>
        /// <param name="baseWritePath">Base write path (relative to the Asset folder) where the Atoms are going to be written to.</param>
        /// <param name="isEquatable">Is the `type` provided implementing `IEquatable`?</param>
        /// <param name="atomTypesToGenerate">A list of `AtomType`s to be generated.</param>
        /// <param name="typeNamespace">If the `type` provided is defined under a namespace, provide that namespace here.</param>
        /// <param name="subUnityAtomsNamespace">By default the Atoms that gets generated will be under the namespace `UnityAtoms`. If you for example like it to be under `UnityAtoms.MyNamespace` you would then enter `MyNamespace` in this field.</param>
        /// <example>
        /// <code>
        /// namespace MyNamespace
        /// {
        ///     public struct MyStruct
        ///     {
        ///         public string Text;
        ///         public int Number;
        ///     }
        /// }
        /// var generator = new Generator();
        /// generator.Generate("MyStruct", "", false, new List&lt;AtomType&gt;() { AtomTypes.ACTION }, "MyNamespace", ""); // Generates an Atom Action of type MyStruct
        /// </code>
        /// </example>
        public void Generate(string type, string baseWritePath, bool isEquatable, List <AtomType> atomTypesToGenerate, string typeNamespace, string subUnityAtomsNamespace)
        {
            // TODO: More validation of that the type exists / is correct.
            if (string.IsNullOrEmpty(type))
            {
                Debug.LogWarning($"{Runtime.Constants.LOG_PREFIX} You need to specify a type name. Aborting!");
                return;
            }
            if (string.IsNullOrEmpty(baseWritePath))
            {
                Debug.LogWarning($"{Runtime.Constants.LOG_PREFIX} You need to specify a write path. Aborting!");
                return;
            }

            Debug.Log($"{Runtime.Constants.LOG_PREFIX} Generating " + type);

            // Create directories in path if they don't exists
            Directory.CreateDirectory(baseWritePath);

            // Recursively search for template files. TODO: Is there a better way to find and load templates?
            var templateSearchPath = Runtime.IsUnityAtomsRepo ?
                                     Directory.GetParent(Directory.GetParent(Application.dataPath).FullName).FullName :
                                     Directory.GetParent(Application.dataPath).FullName;
            var templatePaths      = Directory.GetFiles(templateSearchPath, "UA_Template*.txt", SearchOption.AllDirectories);
            var templateConditions = new List <string>();

            if (isEquatable)
            {
                templateConditions.Add("EQUATABLE");
            }
            if (!string.IsNullOrEmpty(typeNamespace))
            {
                templateConditions.Add("TYPE_HAS_NAMESPACE");
            }
            if (!string.IsNullOrEmpty(subUnityAtomsNamespace))
            {
                templateConditions.Add("HAS_SUB_UA_NAMESPACE");
            }
            var capitalizedType   = Capitalize(type);
            var templateVariables = new Dictionary <string, string>()
            {
                { "TYPE_NAME", capitalizedType }, { "TYPE", type }
            };

            if (!string.IsNullOrEmpty(typeNamespace))
            {
                templateVariables.Add("TYPE_NAMESPACE", typeNamespace);
            }
            if (!string.IsNullOrEmpty(subUnityAtomsNamespace))
            {
                templateVariables.Add("SUB_UA_NAMESPACE", subUnityAtomsNamespace);
            }

            foreach (var templatePath in templatePaths)
            {
                var templateNameStartIndex      = templatePath.LastIndexOf(Path.DirectorySeparatorChar) + 1;
                var fileExtLength               = 4;
                var templateName                = templatePath.Substring(templateNameStartIndex, templatePath.Length - templateNameStartIndex - fileExtLength);
                var lastIndexOfDoubleUnderscore = templateName.LastIndexOf("__");
                var atomType            = templateName.Substring(lastIndexOfDoubleUnderscore + 2);
                var capitalizedAtomType = Capitalize(atomType);
                var typeOccurrences     = templateName.Substring(lastIndexOfDoubleUnderscore - 1, 1).ToInt(def: 1);

                if (ShouldSkipTemplate(atomTypesToGenerate, capitalizedAtomType, typeOccurrences))
                {
                    continue;
                }

                var template = File.ReadAllText(templatePath);

                // Create write directory
                var dirPath = ResolveDirPath(baseWritePath, capitalizedAtomType, templateName, atomType);
                Directory.CreateDirectory(dirPath);

                // Adjust content
                var content = Templating.ResolveVariables(templateVariables: templateVariables, toResolve: template);
                content = Templating.ResolveConditionals(template: content, trueConditions: templateConditions);
                content = RemoveDuplicateNamespaces(content);

                // Write to file
                var fileName = ResolveFileName(templateVariables, templateName, lastIndexOfDoubleUnderscore, capitalizedType, capitalizedAtomType, typeOccurrences);
                var filePath = Path.Combine(dirPath, fileName);
                File.WriteAllText(filePath, content);

                AssetDatabase.ImportAsset(filePath);
            }

            AssetDatabase.Refresh();
        }
Example #4
0
        public void Generate()
        {
            var type = Type.GetType($"{FullQualifiedName}");

            if (type == null)
            {
                throw new TypeLoadException($"Type could not be found ({FullQualifiedName})");
            }
            var isValueTypeEquatable = type.GetInterfaces().Contains(typeof(IEquatable <>));

            var templateVariables    = Generator.CreateTemplateVariablesMap(BaseType, Namespace, "BaseAtoms");
            var capitalizedValueType = BaseType.Capitalize();
            var templates            = Generator.GetTemplatePaths();
            var templateConditions   =
                Generator.CreateTemplateConditions(isValueTypeEquatable, Namespace, "BaseAtoms", BaseType);
            var baseWritePath =
                Path.Combine((Path.GetDirectoryName(AssetDatabase.GetAssetPath(this.GetInstanceID()))) ?? "Assets/",
                             "Generated");

            Directory.CreateDirectory(baseWritePath);

            Scripts.Clear();
            var t   = GenerationOptions;
            var idx = 0;

            while (t > 0)
            {
                if (t % 2 == 1)
                {
                    var atomType = AtomTypes.ALL_ATOM_TYPES[idx];

                    templateVariables["VALUE_TYPE_NAME"] =
                        atomType.IsValuePair ? $"{capitalizedValueType}Pair" : capitalizedValueType;
                    var valueType = atomType.IsValuePair ? $"{capitalizedValueType}Pair" : BaseType;
                    templateVariables["VALUE_TYPE"] = valueType;

                    var resolvedRelativeFilePath = Templating.ResolveVariables(templateVariables: templateVariables,
                                                                               toResolve: atomType.RelativeFileNameAndPath);
                    var targetPath = Path.Combine(baseWritePath, resolvedRelativeFilePath);

                    var newCreated = !File.Exists(targetPath);

                    Generator.Generate(new AtomReceipe(atomType, valueType), baseWritePath, templates,
                                       templateConditions, templateVariables);

                    if (newCreated)
                    {
                        AssetDatabase.ImportAsset(targetPath);
                    }
                    var ms = AssetDatabase.LoadAssetAtPath <MonoScript>(targetPath);
                    Scripts.Add(ms);
                }
                else
                {
                    Scripts.Add(null);
                }

                idx++;
                t >>= 1;
            }
        }