You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
778 lines
28 KiB
778 lines
28 KiB
5 years ago
|
// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Text;
|
||
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Fungus.EditorUtils
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Helper script that auto generates the required script for FungusVariables that wrap existing classes.
|
||
|
///
|
||
|
/// Intended to speed up the creation of fungus wrappers of unity builtin types and custom user types.
|
||
|
/// </summary>
|
||
|
public class VariableScriptGenerator
|
||
|
{
|
||
|
public string NamespaceUsingDeclare { get; set; }
|
||
|
|
||
|
public bool PreviewOnly { get; set; }
|
||
|
private string _category = "Other";
|
||
|
public string Category { get { return _category; } set { _category = value; } }
|
||
|
|
||
|
public List<Type> types { get; private set; }
|
||
|
|
||
|
public bool generateVariableClass = true,
|
||
|
generatePropertyCommand = true,
|
||
|
generateVariableDataClass = true,
|
||
|
generateOnlyDeclaredMembers = true;
|
||
|
|
||
|
public string ClassName { get { return TargetType.Name; } }
|
||
|
public string CamelCaseClassName { get { return Char.ToLowerInvariant(ClassName[0]) + ClassName.Substring(1); } }
|
||
|
|
||
|
public string GenClassName { get { return ClassName + "Variable"; } }
|
||
|
|
||
|
public string VariableFileName { get { return VaraibleScriptLocation + ClassName + "Variable.cs"; } }
|
||
|
public string VariableEditorFileName { get { return EditorScriptLocation + ClassName + "VariableDrawer.cs"; } }
|
||
|
public string PropertyFileName { get { return PropertyScriptLocation + ClassName + "Property.cs"; } }
|
||
|
|
||
|
private Type _targetType;
|
||
|
|
||
|
public Type TargetType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return _targetType;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
_targetType = value;
|
||
|
ExistingGeneratedClass = null;
|
||
|
ExistingGeneratedDrawerClass = null;
|
||
|
ExistingGeneratedPropCommandClass = null;
|
||
|
|
||
|
if (_targetType != null)
|
||
|
{
|
||
|
ExistingGeneratedClass = types.Find(x => x.Name == GenClassName);
|
||
|
ExistingGeneratedDrawerClass = types.Find(x => x.Name == (ClassName + "VariableDrawer"));
|
||
|
ExistingGeneratedPropCommandClass = types.Find(x => x.Name == (ClassName + "Property"));
|
||
|
if (ExistingGeneratedPropCommandClass != null)
|
||
|
{
|
||
|
var nested = ExistingGeneratedPropCommandClass.GetNestedTypes().ToList();
|
||
|
ExistingGeneratedPropEnumClass = nested.Find(x => x.Name == "Property");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Type ExistingGeneratedClass { get; private set; }
|
||
|
public Type ExistingGeneratedDrawerClass { get; private set; }
|
||
|
public Type ExistingGeneratedPropCommandClass { get; private set; }
|
||
|
public Type ExistingGeneratedPropEnumClass { get; private set; }
|
||
|
|
||
|
private StringBuilder getBuilder, setBuilder;// = new StringBuilder("switch (property)\n{");
|
||
|
private List<string> enumBuilder = new List<string>();
|
||
|
|
||
|
//data and helper for a single native to single fungus type
|
||
|
public class FungusVariableTypeHelper
|
||
|
{
|
||
|
private HashSet<Type> usedTypes = new HashSet<Type>();
|
||
|
private List<TypeHandler> handlers = new List<TypeHandler>();
|
||
|
|
||
|
public class TypeHandler
|
||
|
{
|
||
|
public TypeHandler(Type native, Type fungusType, string localName, string nativeAsString = null, string fungusTypeAsString = null)
|
||
|
{
|
||
|
NativeType = native;
|
||
|
NativeTypeString = string.IsNullOrEmpty(nativeAsString) ? native.Name : nativeAsString;
|
||
|
FungusType = fungusType;
|
||
|
FungusTypeString = string.IsNullOrEmpty(fungusTypeAsString) ? fungusType.Name : fungusTypeAsString;
|
||
|
LocalVariableName = localName;
|
||
|
}
|
||
|
|
||
|
public Type NativeType { get; set; }
|
||
|
public Type FungusType { get; set; }
|
||
|
public string NativeTypeString { get; set; }
|
||
|
public string FungusTypeString { get; set; }
|
||
|
public string LocalVariableName { get; set; }
|
||
|
|
||
|
public string GetLocalVariableNameWithDeclaration()
|
||
|
{
|
||
|
return "var " + LocalVariableName + " = inOutVar as " + FungusTypeString + ';';
|
||
|
}
|
||
|
|
||
|
public string GetVarPropText()
|
||
|
{
|
||
|
return "typeof(" + FungusTypeString + ")";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void AddHandler(TypeHandler t)
|
||
|
{
|
||
|
if (handlers.Find(x => x.NativeType == t.NativeType || x.LocalVariableName == t.LocalVariableName) != null)
|
||
|
{
|
||
|
Debug.LogError("AddHandler rejected due to duplicate native field or local variable name");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
handlers.Add(t);
|
||
|
}
|
||
|
|
||
|
public bool IsTypeHandled(Type t)
|
||
|
{
|
||
|
return handlers.Find(x => x.NativeType == t) != null;
|
||
|
}
|
||
|
|
||
|
public string GetSpecificVariableVarientFromType(Type t)
|
||
|
{
|
||
|
usedTypes.Add(t);
|
||
|
|
||
|
var loc = handlers.Find(x => x.NativeType == t);
|
||
|
if (loc != null)
|
||
|
{
|
||
|
return loc.LocalVariableName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return "ERROR - Unsupprted type requested";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public string GetUsedTypeVars()
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
|
||
|
foreach (Type t in usedTypes)
|
||
|
{
|
||
|
var loc = handlers.Find(x => x.NativeType == t);
|
||
|
if (loc != null)
|
||
|
{
|
||
|
sb.Append(" ");
|
||
|
sb.AppendLine(loc.GetLocalVariableNameWithDeclaration());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
|
||
|
public string GetVariablePropertyTypeOfs()
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
|
||
|
foreach (Type t in usedTypes)
|
||
|
{
|
||
|
var loc = handlers.Find(x => x.NativeType == t);
|
||
|
if (loc != null)
|
||
|
{
|
||
|
if (sb.Length > 0)
|
||
|
{
|
||
|
sb.AppendLine(",");
|
||
|
sb.Append(" ");
|
||
|
}
|
||
|
sb.Append(loc.GetVarPropText());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private FungusVariableTypeHelper helper = new FungusVariableTypeHelper();
|
||
|
|
||
|
#region consts
|
||
|
|
||
|
// need to also track if they are preview only
|
||
|
static public readonly string[] AllGeneratedVariableTypeClassNames =
|
||
|
{
|
||
|
"Animator",
|
||
|
"AudioSource",
|
||
|
//"Boolean",
|
||
|
"Color",
|
||
|
"Collection",
|
||
|
"Collider",
|
||
|
"Collider2D",
|
||
|
"Collision",
|
||
|
"Collision2D",
|
||
|
"ControllerColliderHit",
|
||
|
//"Float",
|
||
|
"GameObject",
|
||
|
//"Integer",
|
||
|
"Material",
|
||
|
"Matrix4x4",
|
||
|
//"Object",
|
||
|
"Quaternion",
|
||
|
"Rigidbody",
|
||
|
"Rigidbody2D",
|
||
|
"Sprite",
|
||
|
//"String",
|
||
|
"Texture",
|
||
|
"Transform",
|
||
|
"Vector2",
|
||
|
"Vector3",
|
||
|
"Vector4"};
|
||
|
|
||
|
private const string ScriptLocation = "./Assets/Fungus/Scripts/";
|
||
|
private const string PropertyScriptLocation = ScriptLocation + "Commands/Property/";
|
||
|
private const string VaraibleScriptLocation = ScriptLocation + "VariableTypes/";
|
||
|
private const string EditorScriptLocation = ScriptLocation + "Editor/VariableTypes/";
|
||
|
|
||
|
private const string EditorDataDrawerScriptTemplate = @"// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
/*This script has been, partially or completely, generated by the Fungus.GenerateVariableWindow*/
|
||
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Fungus.EditorUtils
|
||
|
{{
|
||
|
[CustomPropertyDrawer(typeof({0}Data))]
|
||
|
public class {0}DataDrawer : VariableDataDrawer<{0}Variable>
|
||
|
{{ }}
|
||
|
}}";
|
||
|
|
||
|
//0 ClassName
|
||
|
//1 NamespaceOfClass
|
||
|
//2 lowerClassName
|
||
|
//3 Category
|
||
|
//4 previewOnly
|
||
|
//5 full name
|
||
|
|
||
|
private const string VariableAndDataScriptTemplate = @"// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
/*This script has been, partially or completely, generated by the Fungus.GenerateVariableWindow*/
|
||
|
using UnityEngine;
|
||
|
{1}
|
||
|
|
||
|
namespace Fungus
|
||
|
{{
|
||
|
/// <summary>
|
||
|
/// {0} variable type.
|
||
|
/// </summary>
|
||
|
[VariableInfo(""{3}"", ""{0}""{4})]
|
||
|
[AddComponentMenu("""")]
|
||
|
[System.Serializable]
|
||
|
public class {0}Variable : VariableBase<{5}>
|
||
|
{{ }}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Container for a {0} variable reference or constant value.
|
||
|
/// </summary>
|
||
|
[System.Serializable]
|
||
|
public struct {0}Data
|
||
|
{{
|
||
|
[SerializeField]
|
||
|
[VariableProperty(""<Value>"", typeof({0}Variable))]
|
||
|
public {0}Variable {2}Ref;
|
||
|
|
||
|
[SerializeField]
|
||
|
public {5} {2}Val;
|
||
|
|
||
|
public static implicit operator {5}({0}Data {0}Data)
|
||
|
{{
|
||
|
return {0}Data.Value;
|
||
|
}}
|
||
|
|
||
|
public {0}Data({5} v)
|
||
|
{{
|
||
|
{2}Val = v;
|
||
|
{2}Ref = null;
|
||
|
}}
|
||
|
|
||
|
public {5} Value
|
||
|
{{
|
||
|
get {{ return ({2}Ref == null) ? {2}Val : {2}Ref.Value; }}
|
||
|
set {{ if ({2}Ref == null) {{ {2}Val = value; }} else {{ {2}Ref.Value = value; }} }}
|
||
|
}}
|
||
|
|
||
|
public string GetDescription()
|
||
|
{{
|
||
|
if ({2}Ref == null)
|
||
|
{{
|
||
|
return {2}Val.ToString();
|
||
|
}}
|
||
|
else
|
||
|
{{
|
||
|
return {2}Ref.Key;
|
||
|
}}
|
||
|
}}
|
||
|
}}
|
||
|
}}";
|
||
|
|
||
|
//0 ClassName
|
||
|
//1 NamespaceOfClass
|
||
|
//2 lowerClassName
|
||
|
//3 Category
|
||
|
//4 previewOnly
|
||
|
//5 full name
|
||
|
|
||
|
private const string VariableOnlyScriptTemplate = @"// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
/*This script has been, partially or completely, generated by the Fungus.GenerateVariableWindow*/
|
||
|
using UnityEngine;
|
||
|
{1}
|
||
|
|
||
|
namespace Fungus
|
||
|
{{
|
||
|
/// <summary>
|
||
|
/// {0} variable type.
|
||
|
/// </summary>
|
||
|
[VariableInfo(""{3}"", ""{0}""{4})]
|
||
|
[AddComponentMenu("""")]
|
||
|
[System.Serializable]
|
||
|
public class {0}Variable : VariableBase<{5}>
|
||
|
{{ }}
|
||
|
}}";
|
||
|
|
||
|
//0 typeo
|
||
|
//1 prop enum
|
||
|
//2 lower class name
|
||
|
//3 get generated
|
||
|
//4 set generated
|
||
|
//5 used vars
|
||
|
//6 variableProperty Type of
|
||
|
//7 null check summary
|
||
|
private const string DataBasedPropertyScriptTemplate = @"// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
/*This script has been, partially or completely, generated by the Fungus.GenerateVariableWindow*/
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Fungus
|
||
|
{{
|
||
|
// <summary>
|
||
|
/// Get or Set a property of a {0} component
|
||
|
/// </summary>
|
||
|
[CommandInfo(""Property"",
|
||
|
""{0}"",
|
||
|
""Get or Set a property of a {0} component"")]
|
||
|
[AddComponentMenu("""")]
|
||
|
public class {0}Property : BaseVariableProperty
|
||
|
{{
|
||
|
//generated property
|
||
|
{1}
|
||
|
|
||
|
[SerializeField]
|
||
|
protected Property property;
|
||
|
|
||
|
[SerializeField]
|
||
|
protected {0}Data {2}Data;
|
||
|
|
||
|
[SerializeField]
|
||
|
[VariableProperty({6})]
|
||
|
protected Variable inOutVar;
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{{
|
||
|
{5}
|
||
|
|
||
|
var target = {2}Data.Value;
|
||
|
|
||
|
switch (getOrSet)
|
||
|
{{
|
||
|
case GetSet.Get:
|
||
|
{3}
|
||
|
break;
|
||
|
|
||
|
case GetSet.Set:
|
||
|
{4}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}}
|
||
|
|
||
|
Continue();
|
||
|
}}
|
||
|
|
||
|
public override string GetSummary()
|
||
|
{{{7}
|
||
|
if (inOutVar == null)
|
||
|
{{
|
||
|
return ""Error: no variable set to push or pull data to or from"";
|
||
|
}}
|
||
|
|
||
|
return getOrSet.ToString() + "" "" + property.ToString();
|
||
|
}}
|
||
|
|
||
|
public override Color GetButtonColor()
|
||
|
{{
|
||
|
return new Color32(235, 191, 217, 255);
|
||
|
}}
|
||
|
|
||
|
public override bool HasReference(Variable variable)
|
||
|
{{
|
||
|
if ({2}Data.{2}Ref == variable || inOutVar == variable)
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}}
|
||
|
}}
|
||
|
}}";
|
||
|
|
||
|
//0 typeo
|
||
|
//1 prop enum
|
||
|
//2 lower class name
|
||
|
//3 get generated
|
||
|
//4 set generated
|
||
|
//5 used vars
|
||
|
//6 variableProperty Type of
|
||
|
//7 null check summary
|
||
|
private const string VariableOnlyPropertyScriptTemplate = @"// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
/*This script has been, partially or completely, generated by the Fungus.GenerateVariableWindow*/
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Fungus
|
||
|
{{
|
||
|
// <summary>
|
||
|
/// Get or Set a property of a {0} component
|
||
|
/// </summary>
|
||
|
[CommandInfo(""Property"",
|
||
|
""{0}"",
|
||
|
""Get or Set a property of a {0} component"")]
|
||
|
[AddComponentMenu("""")]
|
||
|
public class {0}Property : BaseVariableProperty
|
||
|
{{
|
||
|
//generated property
|
||
|
{1}
|
||
|
|
||
|
[SerializeField]
|
||
|
protected Property property;
|
||
|
|
||
|
[SerializeField]
|
||
|
[VariableProperty(typeof({0}Variable))]
|
||
|
protected {0}Variable {2}Var;
|
||
|
|
||
|
[SerializeField]
|
||
|
[VariableProperty({6})]
|
||
|
protected Variable inOutVar;
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{{
|
||
|
{5}
|
||
|
|
||
|
var target = {2}Var.Value;
|
||
|
|
||
|
switch (getOrSet)
|
||
|
{{
|
||
|
case GetSet.Get:
|
||
|
{3}
|
||
|
break;
|
||
|
|
||
|
case GetSet.Set:
|
||
|
{4}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}}
|
||
|
|
||
|
Continue();
|
||
|
}}
|
||
|
|
||
|
public override string GetSummary()
|
||
|
{{{7}
|
||
|
if (inOutVar == null)
|
||
|
{{
|
||
|
return ""Error: no variable set to push or pull data to or from"";
|
||
|
}}
|
||
|
|
||
|
return getOrSet.ToString() + "" "" + property.ToString();
|
||
|
}}
|
||
|
|
||
|
public override Color GetButtonColor()
|
||
|
{{
|
||
|
return new Color32(235, 191, 217, 255);
|
||
|
}}
|
||
|
|
||
|
public override bool HasReference(Variable variable)
|
||
|
{{
|
||
|
if ({2}Var == variable || inOutVar == variable)
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}}
|
||
|
}}
|
||
|
}}";
|
||
|
|
||
|
private const string DefaultCaseFailure = @" default:
|
||
|
Debug.Log(""Unsupported get or set attempted"");
|
||
|
break;
|
||
|
}";
|
||
|
|
||
|
private const string DataNullCheckSummary = @"
|
||
|
if ({0}Data.Value == null)
|
||
|
{{
|
||
|
return ""Error: no {0} set"";
|
||
|
}}";
|
||
|
|
||
|
private const string VariableOnlyNullCheckSummary = @"
|
||
|
if ({0}Var == null)
|
||
|
{{
|
||
|
return ""Error: no {0}Var set"";
|
||
|
}}";
|
||
|
|
||
|
#endregion consts
|
||
|
|
||
|
public VariableScriptGenerator()
|
||
|
{
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Animator), typeof(AnimatorVariable), "ioani"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(AudioSource), typeof(AudioSourceVariable), "ioaud"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(bool), typeof(BooleanVariable), "iob"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Collider2D), typeof(Collider2DVariable), "ioc2d"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Collider), typeof(ColliderVariable), "ioc"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Collection), typeof(CollectionVariable), "iocollect"));
|
||
|
//we don't need to do collision varaibles
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Color), typeof(ColorVariable), "iocol"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(float), typeof(FloatVariable), "iof"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(GameObject), typeof(GameObjectVariable), "iogo"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(int), typeof(IntegerVariable), "ioi"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Material), typeof(MaterialVariable), "iomat"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Matrix4x4), typeof(Matrix4x4Variable), "iom4"));
|
||
|
//we skip object
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Quaternion), typeof(QuaternionVariable), "ioq"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Rigidbody2D), typeof(Rigidbody2DVariable), "iorb2d"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Rigidbody), typeof(RigidbodyVariable), "iorb"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Sprite), typeof(SpriteVariable), "iospr"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(string), typeof(StringVariable), "ios"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Texture), typeof(TextureVariable), "iotex"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Transform), typeof(TransformVariable), "iot"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Vector2), typeof(Vector2Variable), "iov2"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Vector3), typeof(Vector3Variable), "iov"));
|
||
|
helper.AddHandler(new FungusVariableTypeHelper.TypeHandler(typeof(Vector4), typeof(Vector4Variable), "iov4"));
|
||
|
|
||
|
types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).ToList();
|
||
|
}
|
||
|
|
||
|
public void Generate()
|
||
|
{
|
||
|
if (TargetType == null)
|
||
|
throw new Exception("No type given");
|
||
|
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, "Starting", 0);
|
||
|
try
|
||
|
{
|
||
|
if (generateVariableClass)
|
||
|
{
|
||
|
Func<string> lam = () =>
|
||
|
{
|
||
|
var usingDec = !string.IsNullOrEmpty(NamespaceUsingDeclare) ? ("using " + NamespaceUsingDeclare + ";") : string.Empty;
|
||
|
return string.Format(generateVariableDataClass ? VariableAndDataScriptTemplate : VariableOnlyScriptTemplate,
|
||
|
ClassName, usingDec, CamelCaseClassName, Category, PreviewOnly ? ", IsPreviewedOnly = true" : "", TargetType.FullName);
|
||
|
};
|
||
|
FileSaveHelper("Variable", VaraibleScriptLocation, VariableFileName, lam);
|
||
|
}
|
||
|
|
||
|
if (generateVariableClass && generateVariableDataClass)
|
||
|
{
|
||
|
Func<string> lam = () => { return string.Format(EditorDataDrawerScriptTemplate, ClassName); };
|
||
|
FileSaveHelper("VariableDrawer", EditorScriptLocation, VariableEditorFileName, lam);
|
||
|
}
|
||
|
|
||
|
if (generatePropertyCommand)
|
||
|
{
|
||
|
GeneratePropertyCommand();
|
||
|
}
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Debug.LogError(e.Message);
|
||
|
}
|
||
|
|
||
|
EditorUtility.ClearProgressBar();
|
||
|
}
|
||
|
|
||
|
private void GeneratePropertyCommand()
|
||
|
{
|
||
|
enumBuilder.Add("public enum Property \n { \n");
|
||
|
getBuilder = new StringBuilder("switch (property)\n {\n".Replace("\n", System.Environment.NewLine));
|
||
|
setBuilder = new StringBuilder("switch (property)\n {\n".Replace("\n", System.Environment.NewLine));
|
||
|
|
||
|
AddAllExistingEnumNames();
|
||
|
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, "Property", 0);
|
||
|
int numAdded = PropertyFieldLogic();
|
||
|
numAdded += PropertyPropLogic();
|
||
|
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, "Property Building", 0);
|
||
|
|
||
|
//finalise buidlers
|
||
|
setBuilder.AppendLine(DefaultCaseFailure);
|
||
|
var setcontents = setBuilder.ToString();
|
||
|
|
||
|
getBuilder.AppendLine(DefaultCaseFailure);
|
||
|
var getcontents = getBuilder.ToString();
|
||
|
|
||
|
enumBuilder.Add(" }\n");
|
||
|
var enumgen = String.Join(null, enumBuilder.ToArray());
|
||
|
enumgen = enumgen.Replace("\n", System.Environment.NewLine);
|
||
|
|
||
|
var typeVars = helper.GetUsedTypeVars();
|
||
|
var variablePropertyTypes = helper.GetVariablePropertyTypeOfs();
|
||
|
|
||
|
string nullCheck = "";
|
||
|
|
||
|
if (TargetType.IsClass)
|
||
|
{
|
||
|
nullCheck = string.Format(generateVariableDataClass ? DataNullCheckSummary : VariableOnlyNullCheckSummary, CamelCaseClassName);
|
||
|
}
|
||
|
|
||
|
//write to file
|
||
|
Func<string> propContentOp = () =>
|
||
|
{
|
||
|
return string.Format(generateVariableDataClass ? DataBasedPropertyScriptTemplate : VariableOnlyPropertyScriptTemplate,
|
||
|
ClassName, enumgen, CamelCaseClassName, getcontents, setcontents, typeVars, variablePropertyTypes, nullCheck);
|
||
|
};
|
||
|
|
||
|
//only generate the file if we actually found variables to get and or set
|
||
|
if (numAdded > 0)
|
||
|
{
|
||
|
FileSaveHelper("Property", PropertyScriptLocation, PropertyFileName, propContentOp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Debug.LogWarning("Attempted to generate property class for " + ClassName + " but found no variables to get or set");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void AddAllExistingEnumNames()
|
||
|
{
|
||
|
if (ExistingGeneratedPropEnumClass != null)
|
||
|
{
|
||
|
if (ExistingGeneratedPropEnumClass.IsEnum)
|
||
|
{
|
||
|
var res = Enum.GetNames(ExistingGeneratedPropEnumClass);
|
||
|
for (int i = 0; i < res.Length; i++)
|
||
|
{
|
||
|
AddToEnum(res[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private System.Reflection.BindingFlags GetBindingFlags()
|
||
|
{
|
||
|
if (generateOnlyDeclaredMembers)
|
||
|
return System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
|
||
|
return System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
|
||
|
}
|
||
|
|
||
|
private int PropertyFieldLogic()
|
||
|
{
|
||
|
int retval = 0;
|
||
|
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, "Property Scanning Fields", 0);
|
||
|
var fields = TargetType.GetFields(GetBindingFlags());
|
||
|
for (int i = 0; i < fields.Length; i++)
|
||
|
{
|
||
|
if (helper.IsTypeHandled(fields[i].FieldType))
|
||
|
{
|
||
|
var actualName = fields[i].Name;
|
||
|
var upperCaseName = Char.ToUpperInvariant(actualName[0]) + actualName.Substring(1);
|
||
|
//add it to the enum
|
||
|
AddToEnum(upperCaseName);
|
||
|
|
||
|
//add it to the get
|
||
|
AddToGet(fields[i].FieldType, upperCaseName, actualName);
|
||
|
|
||
|
//add it to the set
|
||
|
AddToSet(fields[i].FieldType, upperCaseName, actualName);
|
||
|
retval++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
private int PropertyPropLogic()
|
||
|
{
|
||
|
int retval = 0;
|
||
|
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, "Property Scanning Props", 0);
|
||
|
var props = TargetType.GetProperties(GetBindingFlags());
|
||
|
for (int i = 0; i < props.Length; i++)
|
||
|
{
|
||
|
if (helper.IsTypeHandled(props[i].PropertyType) && props[i].GetIndexParameters().Length == 0 && !IsObsolete(props[i].GetCustomAttributes(false)))
|
||
|
{
|
||
|
var actualName = props[i].Name;
|
||
|
var upperCaseName = Char.ToUpperInvariant(actualName[0]) + actualName.Substring(1);
|
||
|
//add it to the enum
|
||
|
AddToEnum(upperCaseName);
|
||
|
|
||
|
if (props[i].CanRead)
|
||
|
{
|
||
|
//add it to the get
|
||
|
AddToGet(props[i].PropertyType, upperCaseName, actualName);
|
||
|
}
|
||
|
if (props[i].CanWrite)
|
||
|
{
|
||
|
//add it to the set
|
||
|
AddToSet(props[i].PropertyType, upperCaseName, actualName);
|
||
|
}
|
||
|
|
||
|
if (props[i].CanRead || props[i].CanWrite)
|
||
|
retval++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
private void AddToSet(Type fieldType, string nameEnum, string nameVariable)
|
||
|
{
|
||
|
setBuilder.Append(" case Property.");
|
||
|
setBuilder.Append(nameEnum);
|
||
|
setBuilder.AppendLine(":");
|
||
|
setBuilder.Append(" target.");
|
||
|
setBuilder.Append(nameVariable);
|
||
|
setBuilder.Append(" = ");
|
||
|
setBuilder.Append(helper.GetSpecificVariableVarientFromType(fieldType));
|
||
|
setBuilder.AppendLine(".Value;");
|
||
|
setBuilder.AppendLine(" break;");
|
||
|
}
|
||
|
|
||
|
private void AddToGet(Type fieldType, string nameEnum, string nameVariable)
|
||
|
{
|
||
|
getBuilder.Append(" case Property.");
|
||
|
getBuilder.Append(nameEnum);
|
||
|
getBuilder.AppendLine(":");
|
||
|
getBuilder.Append(" " + helper.GetSpecificVariableVarientFromType(fieldType));
|
||
|
getBuilder.Append(".Value = target.");
|
||
|
getBuilder.Append(nameVariable);
|
||
|
getBuilder.AppendLine(";");
|
||
|
getBuilder.AppendLine(" break;");
|
||
|
}
|
||
|
|
||
|
private void AddToEnum(string name)
|
||
|
{
|
||
|
if (enumBuilder.IndexOf(name) == -1)
|
||
|
{
|
||
|
enumBuilder.Add(" ");
|
||
|
enumBuilder.Add(name);
|
||
|
enumBuilder.Add(", \n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private bool IsObsolete(object[] attrs)
|
||
|
{
|
||
|
if (attrs.Length > 0)
|
||
|
return attrs.FirstOrDefault(x => x.GetType() == typeof(ObsoleteAttribute)) != null;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private void FileSaveHelper(string op, string loc, string filename, Func<string> opLambda)
|
||
|
{
|
||
|
EditorUtility.DisplayProgressBar("Generating " + ClassName, op, 0);
|
||
|
var scriptContents = opLambda();
|
||
|
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(loc));
|
||
|
System.IO.File.WriteAllText(filename, scriptContents);
|
||
|
Debug.Log("Created " + filename);
|
||
|
}
|
||
|
}
|
||
|
}
|