Exemple #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);
            }
        }
Exemple #2
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();
        }