4 using System.Collections.Generic;
     7 using System.Text.RegularExpressions;
    17     protected static string       destination, type;
    18     private          List<string> sources = 
new List<string>();
    19     protected        string       Label   = 
"BuildCustomAsset";
    21     [SerializeField, Tooltip(
"Optional: Overrides default project directory")]
    22     protected Jit<string> selectedPathInProjectView = Jit<string>.Instance(getProjectFolder);
    23     private static readonly Func<bool, string> getProjectFolder = _ => AssetDb.ProjectFolder();
    25     protected void CreateAssets(
string assetName, 
string assetType, 
string basePath) {
    28       SetDestination(basePath);
    30       ProcessAllFiles(
@"cs|txt");
    31       AssetDatabase.ImportAsset(
    32         Path.GetDirectoryName(destination)
    33       , ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport |
    34         ImportAssetOptions.ImportRecursive);
    36       if (sources.Count > 0) {
    37         foreach (
string source 
in sources) {
    38           var asset = AssetDb.Load<MonoScript>(source);
    39           AssetDb.Labels(asset, Label);
    41         Debug.Log($
"      Please wait while compiling scripts in `{destination}`");
    45     protected virtual void ProcessAllFiles(
string textAssetTypes) {
    46       string[] guids                                  = AssetDatabase.FindAssets(
"", 
new[] {TemplatePath()});
    47       for (
int i = 0; i < guids.Length; i++) guids[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
    48       ProcessFiles(textAssetTypes, guids);
    51     protected void ProcessFiles(
string textAssetTypes, params 
string[] files) {
    52       Regex textAssetTypesRegex = 
new Regex($
@"\.({textAssetTypes})$");
    53       using (var 
template = Template.Instance) {
    54         for (
int i = 0; i < files.Length; i++) {
    55           if (File.Exists(files[i])) {
    56             var fileName = Path.GetFileName(files[i]) ?? 
"";
    57             var filePath = fileName.StartsWith(name) ? $
"{destination}/{fileName}" : $
"{destination}/{name}{fileName}";
    58             if (textAssetTypesRegex.IsMatch(files[i])) {
    59               if (File.Exists(filePath) && (filePath != files[i]))
    60                 Fatal($
"{filePath} already exists. Select a different name or directory");
    61               var text = FillTemplate(
template, File.ReadAllText(files[i]));
    62               if (files[i].EndsWith(
".cs") && text.Contains(
"  [CreateAssetMenu(")) sources.Add(filePath);
    63               File.WriteAllText(filePath, text);
    65               if (File.Exists(filePath)) Fatal($
"{filePath} already exists. Select a different name or directory");
    66               File.Copy(files[i], filePath);
    73     protected virtual string FillTemplate(Template 
template, 
string text) => 
template.From(text).Result();
    75     protected virtual string TemplatePath() => 
throw new NotImplementedException();
    77     protected string AskForDestinationPath(
string basePath) {
    78       destination = EditorUtility.SaveFilePanel($
"Location for your new asset", basePath, 
"", 
"");
    79       name        = Path.GetFileNameWithoutExtension(destination) ?? 
"UNKNOWN";
    83     private string SetDestination(
string path) {
    84       if (!path.EndsWith(name)) path            = $
"{path}/{name}";
    85       if (path.Contains(
"Assets/Askowl/")) path = path.Substring(path.IndexOf(
"Assets/", StringComparison.Ordinal));
    86       AssetDb.Instance.CreateFolders(path);
    87       return destination = path;
    90     protected void Fatal(
string msg) => 
throw new Exception(msg);
    92     protected string[] ToDefinitions(
string text) => csRegex.Split(text);
    94     protected string ToTuple(
string fields) {
    95       var pairs = ToDefinitions(fields);
    96       if (pairs.Length == 0) 
return null;
    97       if (pairs.Length == 1) 
return pairs[0];
    99       if ((pairs.Length < 4) || ((pairs.Length % 2) != 0))
   100         throw new Exception($
"'{fields}' must be single type or pairs of (type, name)");
   102       builder.Clear().Append(
"(");
   103       builder.Append($
"{pairs[0]} {pairs[1]}");
   104       for (
int i = 2; i < pairs.Length; i += 2) builder.Append($
",{pairs[i]} {pairs[i + 1]}");
   105       return builder.Append(
")").ToString();
   107     private readonly        StringBuilder builder = 
new StringBuilder();
   108     private static readonly Regex         csRegex = 
new Regex(
@"\s*;\s*|\s*,\s*|\s+", RegexOptions.Singleline);
   111       public override void OnInspectorGUI() {
   112         GUI.SetNextControlName(
"FirstWizardField");
   113         if (GUILayout.Button(
"Clear")) {
   115           GUI.FocusControl(null);
   117         serializedObject.Update();
   118         DrawDefaultInspector();
   119         if (GUILayout.Button(
"Create")) ((
AssetWizard) target).Create();
   120         serializedObject.ApplyModifiedProperties();
   123     public virtual void Create() => 
throw new NotImplementedException();
   124     public virtual void Clear()  => 
throw new NotImplementedException();