Skip to content

Commit

Permalink
1.3.0
Browse files Browse the repository at this point in the history
Added context menus to create the custom scriptable objects and the other scripts that use it
  • Loading branch information
App24 committed Apr 24, 2023
1 parent a0da8a0 commit 6c28792
Show file tree
Hide file tree
Showing 32 changed files with 649 additions and 219 deletions.
172 changes: 172 additions & 0 deletions Assets/RicUtils/Editor/ClassBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RicUtils.Editor
{
public sealed class ClassBuilder
{
private string namespaceName;

private int indentation;
private ClassData classData;
private List<string> usings = new List<string>();

public ClassBuilder SetNamespace(string namespaceName)
{
this.namespaceName = namespaceName;
return this;
}

/*public ClassBuilder AddIndentation(int amount = 1)
{
indentation += amount;
return this;
}
public ClassBuilder RemoveIndentation(int amount = 1)
{
indentation -= amount;
return this;
}*/

public ClassBuilder SetClassName(AccessModifier accessModifier, Keyword keyword, string name, string baseClass = "")
{
classData = new ClassData(accessModifier, keyword, name, ClassType.Class, baseClass);
return this;
}

public ClassBuilder AddUsing(string usingName)
{
usings.Add(usingName);
return this;
}

public string Build()
{
string toReturn = "";

foreach (var @using in usings)
{
toReturn += $"using {@using}";
AddEndLine(ref toReturn);
AddNewLine(ref toReturn);
}

AddNewLine(ref toReturn);

if (!string.IsNullOrEmpty(namespaceName))
{
toReturn += $"namespace {namespaceName}";
AddNewLine(ref toReturn);
AddOpenCurlyBrackets(ref toReturn);
indentation++;
}

{
toReturn += AddIndentation(classData.accessModifier.ToString().ToLower() + " ");
if (classData.keyword != Keyword.None)
{
toReturn += classData.keyword.ToString().ToLower() + " ";
}
toReturn += classData.type.ToString().ToLower() + " ";
toReturn += classData.name;
if (!string.IsNullOrEmpty(classData.baseClass))
{
toReturn += " : " + classData.baseClass;
}
AddNewLine(ref toReturn);
AddOpenCurlyBrackets(ref toReturn);
indentation++;
}

while (indentation > 0)
{
indentation--;
AddCloseCurlyBrackets(ref toReturn);
}

return toReturn;
}

private string AddIndentation(string toAdd)
{
var text = "";
for (int i = 0; i < indentation; i++)
{
text += "\t";
}
return text + toAdd;
}

private void AddNewLine(ref string text)
{
text += Environment.NewLine;
}

private void AddEndLine(ref string text)
{
text += ";";
}

private void AddOpenCurlyBrackets(ref string text, bool addNewLine = true)
{
text += AddIndentation("{");
if (addNewLine)
{
AddNewLine(ref text);
}
}

private void AddCloseCurlyBrackets(ref string text, bool addNewLine = true)
{
text += AddIndentation("}");
if (addNewLine)
{
AddNewLine(ref text);
}
}
}

public enum AccessModifier
{
Public,
Private,
Protected,
Internal,
}

public enum Keyword
{
None,
Static,
Abstract
}

internal enum ClassType
{
Class,
Enum,
Struct,
Interface,
}

internal struct ClassData
{
public AccessModifier accessModifier;
public Keyword keyword;
public string name;
public ClassType type;
public string baseClass;

public ClassData(AccessModifier accessModifier, Keyword keyword, string name, ClassType type, string baseClass)
{
this.accessModifier = accessModifier;
this.keyword = keyword;
this.name = name;
this.type = type;
this.baseClass = baseClass;
}
}
}
11 changes: 11 additions & 0 deletions Assets/RicUtils/Editor/ClassBuilder.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/RicUtils/Editor/ContextMenus.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions Assets/RicUtils/Editor/ContextMenus/CreateAvailableContextMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using UnityEditor;
using UnityEngine;

namespace RicUtils.Editor
{
public static class CreateAvailableContextMenu
{
[MenuItem("Assets/Create/Available Scriptable Object", priority = -9)]
public static void Create()
{
var mono = Selection.activeObject as MonoScript;

string className = $"Available{mono.GetClass().Name}";

ToolUtilities.TryGetActiveFolderPath(out string path);

string defaultNewFileName = Path.Combine(path, className + ".cs");

string templatePath = "Assets/RicUtils/Editor/Templates/Script-NewAvailableScriptableObject.cs.txt";

var endAction = ScriptableObject.CreateInstance<DoCreateAvailableAsset>();

endAction.scriptableObject = mono.GetClass().Name;

ToolUtilities.CreateNewScript(endAction, defaultNewFileName, templatePath);
}

[MenuItem("Assets/Create/Available Scriptable Object", true)]
public static bool IsValid()
{
if (!(Selection.activeObject is MonoScript mono)) return false;
if (mono.GetClass() == null) return false;
if (!mono.GetClass().IsSubclassOf(typeof(GenericScriptableObject))) return false;
return true;
}
}

internal class DoCreateAvailableAsset : DoCreateScriptAsset
{
internal string scriptableObject;

protected override string CustomReplaces(string content)
{
content = content.Replace("#SCRIPTABLEOBJECT#", scriptableObject);
return content;
}
}
}
91 changes: 91 additions & 0 deletions Assets/RicUtils/Editor/ContextMenus/CreateEditorContextMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace RicUtils.Editor
{
public static class CreateEditorContextMenu
{

[MenuItem("Assets/Create/Editor Window", priority = -8)]
public static void Create()
{
string scriptableObject = "";
string availableScriptableObject = "";

foreach (var obj in Selection.objects)
{
var mono = obj as MonoScript;
var @class = mono.GetClass();
if (@class.IsSubclassOf(typeof(GenericScriptableObject))) scriptableObject = @class.Name;
else if (IsSubclassOfRawGeneric(typeof(AvailableScriptableObject<>), @class)) availableScriptableObject = @class.Name;
}

string className = $"{scriptableObject}EditorWindow";

ToolUtilities.TryGetActiveFolderPath(out string path);

string defaultNewFileName = Path.Combine(path, className + ".cs");

string templatePath = "Assets/RicUtils/Editor/Templates/Script-NewGenericEditorWindow.cs.txt";

var endAction = ScriptableObject.CreateInstance<DoCreateEditorAsset>();

endAction.scriptableObject = scriptableObject;
endAction.availableScriptableObject = availableScriptableObject;

ToolUtilities.CreateNewScript(endAction, defaultNewFileName, templatePath);
}

[MenuItem("Assets/Create/Editor Window", true)]
public static bool IsValid()
{
if (Selection.objects.Length < 2) return false;

bool hasGenericScriptableObject = false;
bool hasAvailableScriptableObject = false;

foreach (var obj in Selection.objects)
{
if (obj is not MonoScript) return false;
var mono = obj as MonoScript;
var @class = mono.GetClass();
if (mono.GetClass() == null) continue;
if (@class.IsSubclassOf(typeof(GenericScriptableObject))) hasGenericScriptableObject = true;
else if (IsSubclassOfRawGeneric(typeof(AvailableScriptableObject<>), @class)) hasAvailableScriptableObject = true;
}

return hasGenericScriptableObject && hasAvailableScriptableObject;
}

// https://stackoverflow.com/questions/457676/check-if-a-class-is-derived-from-a-generic-class
private static bool IsSubclassOfRawGeneric(System.Type generic, System.Type toCheck)
{
while (toCheck != null && toCheck != typeof(object))
{
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur)
{
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
}

internal class DoCreateEditorAsset : DoCreateScriptAsset
{
internal string scriptableObject;
internal string availableScriptableObject;

protected override string CustomReplaces(string content)
{
content = content.Replace("#SCRIPTABLEOBJECT#", scriptableObject);
content = content.Replace("#AVAILABLESCRIPTABLEOBJECT#", availableScriptableObject);
return content;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEditor.ProjectWindowCallback;
using UnityEditorInternal;
using UnityEngine;

namespace RicUtils.Editor
{
public static class CreateScriptableObjectContextMenu
{

[MenuItem("Assets/Create/Generic Scriptable Object", priority = -10)]
public static void Create()
{
ToolUtilities.TryGetActiveFolderPath(out string path);

string defaultNewFileName = Path.Combine(path, "NewGenericScriptableObject.cs");

string templatePath = "Assets/RicUtils/Editor/Templates/Script-NewGenericScriptableObject.cs.txt";

ToolUtilities.CreateNewScript(defaultNewFileName, templatePath);

//ProjectWindowUtil.CreateScriptAssetFromTemplateFile("Assets/RicUtils/Editor/Templates/Script-NewGenericScriptableObject.cs.txt", Path.Combine(path, "NewGenericScriptableObject.cs"));

}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6c28792

Please sign in to comment.