ScriptTemplate

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
m (sections spacing)
(string.Equals vs string.Compare for performance since we are not interested in the diff)
 
Line 255: Line 255:
 
             ref ScriptTmplVar var = ref vars[ v ];
 
             ref ScriptTmplVar var = ref vars[ v ];
  
             if( String.Compare( token, var.token, StringComparison.Ordinal ) == 0 ) return true;
+
             if( string.Equals( token, var.token, StringComparison.Ordinal ) ) return true;
 
         }
 
         }
  

Latest revision as of 08:08, 19 October 2020

Author: Serge Billault

Contents

[edit] Download

ScriptTemplate.cs

[edit] Compatibility

. Unity versions: Unity 5.0 through Unity 2019.3.15f1 (Untested on Unity 2020+).
. Net compatibility level: 2.0 minimum - no dynamic methods.
. Unsafe code: None.
. Reflectivity: Yes.
. Networking: None.

[edit] Description

Script templates.

. Option files templates: Yes
. Option inlined templates: Yes
. Variables: User has priority over ScriptTemplate
. Autos: {CLASS_NAME}, {MENU_NAME}, {DATE_TIME}, {AUTHOR} (if also used by User, User definitions take precedence)

[edit] Usage

Copy script file in your Assets folder.

. Action required: none
. Setup required: none
. Scripting:

1) Declare your template

        [ ScriptTmpl( "Assets/Scripts/Templates/MyTemplate.txt" ) ] private sealed class MyTemplate
        {
            static public readonly ScriptTmplVar[] vars = new ScriptTmplVar[] {};
 
            public const string OPTIONAL_INLINED_TEMPLATE = "using UnityEngine;\n\npublic class {CLASS_NAME}\n{\n}\n";
        }

2) Declare your template menu

        [ MenuItem( "Scripts/Templates/Create MyTemplate", false, 0 ) ] static private void CreateScript() 
        { 
            ScriptTemplate.Create< MyTemplate >( MyTemplate.vars [, MyTemplate.OPTIONAL_INLINED_TEMPLATE ] ); 
        }


[edit] Code (ScriptTemplate.cs)

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
 
//****************************************************************************************************
//
//****************************************************************************************************
 
#if UNITY_EDITOR
 
using UnityEditor;
 
//****************************************************************************************************
//
//****************************************************************************************************
 
public struct ScriptTmplVar
{
    public string token;
 
    public string value;
 
    public ScriptTmplVar( string param_token, string param_value )
    {
        token = ( param_token != null ) ? param_token : string.Empty;
 
        value = ( param_value != null ) ? param_value : string.Empty;
    }
}
 
//****************************************************************************************************
//
//****************************************************************************************************
 
[ AttributeUsage( AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true ) ] 
 
public sealed class ScriptTmplAttribute : Attribute
{
    static public readonly string DEF_LOCATION = $"{ Application.dataPath }/Scripts/Templates/template.txt";
 
           public readonly string location;
 
 
    public ScriptTmplAttribute( string param_location ) 
    { 
        param_location = ( param_location   !=  null ) ? param_location.Trim() : string.Empty;
 
        location       = ( param_location.Length > 0 ) ? param_location        : DEF_LOCATION; 
    }
}
 
//****************************************************************************************************
//
//****************************************************************************************************
 
[ UnityEditor.InitializeOnLoad() ] static public class ScriptTemplate
{
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static private readonly ushort[] TO_UPPER = new ushort[]
    {
        0X00, 0X01, 0X02, 0X03, 0X04, 0X05, 0X06, 0X07, 0X08, 0X09, 0X0A, 0X0B, 0X0C, 0X0D, 0X0E, 0X0F, 
        0X10, 0X11, 0X12, 0X13, 0X14, 0X15, 0X16, 0X17, 0X18, 0X19, 0X1A, 0X1B, 0X1C, 0X1D, 0X1E, 0X1F, 
        0X20, 0X21, 0X22, 0X23, 0X24, 0X25, 0X26, 0X27, 0X28, 0X29, 0X2A, 0X2B, 0X2C, 0X2D, 0X2E, 0X2F, 
        0X30, 0X31, 0X32, 0X33, 0X34, 0X35, 0X36, 0X37, 0X38, 0X39, 0X3A, 0X3B, 0X3C, 0X3D, 0X3E, 0X3F, 
        0X40, 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 
        'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 
        0X60, 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 
        'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , 0X7B, 0X7C, 0X7D, 0X7E, 0X7F, 
        0X80, 0X81, 0X82, 0X83, 0X84, 0X85, 0X86, 0X87, 0X88, 0X89, 0X8A, 0X8B, 0X8C, 0X8D, 0X8E, 0X8F, 
        0X90, 0X91, 0X92, 0X93, 0X94, 0X95, 0X96, 0X97, 0X98, 0X99, 0X9A, 0X9B, 0X9C, 0X9D, 0X9E, 0X9F, 
        0XA0, 0XA1, 0XA2, 0XA3, 0XA4, 0XA5, 0XA6, 0XA7, 0XA8, 0XA9, 0XAA, 0XAB, 0XAC, 0XAD, 0XAE, 0XAF, 
        0XB0, 0XB1, 0XB2, 0XB3, 0XB4, 0XB5, 0XB6, 0XB7, 0XB8, 0XB9, 0XBA, 0XBB, 0XBC, 0XBD, 0XBE, 0XBF, 
        0XC0, 0XC1, 0XC2, 0XC3, 0XC4, 0XC5, 0XC6, 0XC7, 0XC8, 0XC9, 0XCA, 0XCB, 0XCC, 0XCD, 0XCE, 0XCF, 
        0XD0, 0XD1, 0XD2, 0XD3, 0XD4, 0XD5, 0XD6, 0XD7, 0XD8, 0XD9, 0XDA, 0XDB, 0XDC, 0XDD, 0XDE, 0XDF, 
        0XE0, 0XE1, 0XE2, 0XE3, 0XE4, 0XE5, 0XE6, 0XE7, 0XE8, 0XE9, 0XEA, 0XEB, 0XEC, 0XED, 0XEE, 0XEF, 
        0XF0, 0XF1, 0XF2, 0XF3, 0XF4, 0XF5, 0XF6, 0XF7, 0XF8, 0XF9, 0XFA, 0XFB, 0XFC, 0XFD, 0XFE, 0XFF 
    };
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static private readonly ushort[] TO_LOWER = new ushort[]
    {
        0X00, 0X01, 0X02, 0X03, 0X04, 0X05, 0X06, 0X07, 0X08, 0X09, 0X0A, 0X0B, 0X0C, 0X0D, 0X0E, 0X0F, 
        0X10, 0X11, 0X12, 0X13, 0X14, 0X15, 0X16, 0X17, 0X18, 0X19, 0X1A, 0X1B, 0X1C, 0X1D, 0X1E, 0X1F, 
        0X20, 0X21, 0X22, 0X23, 0X24, 0X25, 0X26, 0X27, 0X28, 0X29, 0X2A, 0X2B, 0X2C, 0X2D, 0X2E, 0X2F, 
        0X30, 0X31, 0X32, 0X33, 0X34, 0X35, 0X36, 0X37, 0X38, 0X39, 0X3A, 0X3B, 0X3C, 0X3D, 0X3E, 0X3F, 
        0X40, 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 
        'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 
        0X60, 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 
        'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , 0X7B, 0X7C, 0X7D, 0X7E, 0X7F, 
        0X80, 0X81, 0X82, 0X83, 0X84, 0X85, 0X86, 0X87, 0X88, 0X89, 0X8A, 0X8B, 0X8C, 0X8D, 0X8E, 0X8F, 
        0X90, 0X91, 0X92, 0X93, 0X94, 0X95, 0X96, 0X97, 0X98, 0X99, 0X9A, 0X9B, 0X9C, 0X9D, 0X9E, 0X9F, 
        0XA0, 0XA1, 0XA2, 0XA3, 0XA4, 0XA5, 0XA6, 0XA7, 0XA8, 0XA9, 0XAA, 0XAB, 0XAC, 0XAD, 0XAE, 0XAF, 
        0XB0, 0XB1, 0XB2, 0XB3, 0XB4, 0XB5, 0XB6, 0XB7, 0XB8, 0XB9, 0XBA, 0XBB, 0XBC, 0XBD, 0XBE, 0XBF, 
        0XC0, 0XC1, 0XC2, 0XC3, 0XC4, 0XC5, 0XC6, 0XC7, 0XC8, 0XC9, 0XCA, 0XCB, 0XCC, 0XCD, 0XCE, 0XCF, 
        0XD0, 0XD1, 0XD2, 0XD3, 0XD4, 0XD5, 0XD6, 0XD7, 0XD8, 0XD9, 0XDA, 0XDB, 0XDC, 0XDD, 0XDE, 0XDF, 
        0XE0, 0XE1, 0XE2, 0XE3, 0XE4, 0XE5, 0XE6, 0XE7, 0XE8, 0XE9, 0XEA, 0XEB, 0XEC, 0XED, 0XEE, 0XEF, 
        0XF0, 0XF1, 0XF2, 0XF3, 0XF4, 0XF5, 0XF6, 0XF7, 0XF8, 0XF9, 0XFA, 0XFB, 0XFC, 0XFD, 0XFE, 0XFF 
    };
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    private const string           SAVE_PNL_TITLE    = "New Script";
 
    private const string           SAVE_PNL_FILENAME = "MyScript";
 
    private const string           SAVE_PNL_EXT      = "cs";
 
    private const string           SAVE_PNL_MSG      = "Select the name of the script to create";
 
    static private readonly string SAVE_PNL_DIR      = $"{Application.dataPath}/Scripts";
 
 
    private const string           CONFIRM_TITLE     = "Script Creation";
 
    private const string           CONFIRM_YES       = "YES";
 
    private const string           CONFIRM_NO        = "NO";
 
 
    private const string           ERROR_TPL_TITLE   = "Script Template";
 
    private const string           ERROR_TPL_MSG     = "Could not load template";
 
    private const string           ERROR_TPL_ABORT   = "ABORT";
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    private const string KEYWORD_CLASS_NAME = "{CLASS_NAME}";
 
    private const string KEYWORD_MENU_NAME  = "{MENU_NAME}";
 
    private const string KEYWORD_DATE_TIME  = "{DATE_TIME}";
 
    private const string KEYWORD_AUTHOR     = "{AUTHOR}";
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static public string NormallizeName( string name )
    {
        if( string.IsNullOrEmpty( name ) ) return string.Empty;
 
 
        char[] chrs = name.TrimStart().TrimEnd().ToCharArray();
 
        chrs[ 0 ]   = ( char )TO_UPPER[ chrs[ 0 ] ];
 
 
        for( int c = 1, len = chrs.Length; c < len; ++c )
        {
                char prv =     chrs[ c - 1 ];
 
            ref char cur = ref chrs[ c     ];
 
            cur = ( prv != ' ' ) ? ( char )TO_LOWER[ cur ] : ( char )TO_UPPER[ cur ];
        }
 
        return new string( chrs );
    }
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static public string MenuName( string name )
    {
        return NormallizeName( name.Trim().Replace( '_', ' ' ) );
    }
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static private string GetTemplateLocation< T >()
    {
        ScriptTmplAttribute attr = typeof( T ).GetCustomAttribute< ScriptTmplAttribute >();
 
        return ( attr != null ) ? attr.location : ScriptTmplAttribute.DEF_LOCATION;
    }
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static private bool IsUserReserved( string token, ScriptTmplVar[] vars )
    {
        for( int v = 0, count = ( vars != null ) ? vars.Length : 0; v < count; ++v )
        {
            ref ScriptTmplVar var = ref vars[ v ];
 
            if( string.Equals( token, var.token, StringComparison.Ordinal ) ) return true;
        }
 
        return false;
    }
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static private string Load< T >()
    {
        string filename = GetTemplateLocation< T >();
 
        if( File.Exists( filename ) )
        {
            FileStream file = File.Open( filename, FileMode.Open );
 
            if( file.SafeFileHandle.IsInvalid == false )
            {
                string tmpl  = null;
 
                byte[] bytes = new byte[ file.Length ];
 
                file.Read( bytes, 0, bytes.Length );
 
                tmpl = System.Text.Encoding.UTF8.GetString( bytes );
 
                file.Close();
 
                return  tmpl;
            }
        }
 
        EditorUtility.DisplayDialog( ERROR_TPL_TITLE, $"{ ERROR_TPL_MSG } \'{ filename }\'", ERROR_TPL_ABORT );
 
        return null;
    }
 
    //************************************************************************************************
    //
    //************************************************************************************************
 
    static public void Create< T >( ScriptTmplVar[] vars, string template = null ) 
    {
        string filepath = EditorUtility.SaveFilePanelInProject( SAVE_PNL_TITLE, SAVE_PNL_FILENAME, SAVE_PNL_EXT, SAVE_PNL_MSG, SAVE_PNL_DIR );
 
        if( string.IsNullOrEmpty( filepath ) )
        {
            return;
        }
 
 
        string filename = Path.GetFileNameWithoutExtension( filepath );
 
        if( File.Exists( filepath ) )
        {
            if( EditorUtility.DisplayDialog( CONFIRM_TITLE, $"Overwrite { filename } ?", CONFIRM_YES, CONFIRM_NO ) == false )
            {
                return;
            }
        }
 
 
        string tmpl = string.IsNullOrEmpty( template ) ? Load< T >() : template;
 
        if( tmpl != null )
        {
            FileStream file = File.Open( filepath, FileMode.Create );
 
            if( file.SafeFileHandle.IsInvalid == false )
            {
                if( IsUserReserved( KEYWORD_CLASS_NAME, vars ) == false ) tmpl = tmpl.Replace( KEYWORD_CLASS_NAME, filename                );
 
                if( IsUserReserved( KEYWORD_MENU_NAME,  vars ) == false ) tmpl = tmpl.Replace( KEYWORD_MENU_NAME,  MenuName( filename )    );
 
                if( IsUserReserved( KEYWORD_DATE_TIME,  vars ) == false ) tmpl = tmpl.Replace( KEYWORD_DATE_TIME,  DateTime.Now.ToString() );
 
                if( IsUserReserved( KEYWORD_AUTHOR,     vars ) == false ) tmpl = tmpl.Replace( KEYWORD_AUTHOR,     Environment.UserName    );
 
 
                for( int v = 0, count = ( vars != null ) ? vars.Length : 0; v < count; ++v )
                {
                    ref ScriptTmplVar var = ref vars[ v ];
 
                    tmpl = tmpl.Replace( var.token, var.value );
                }
 
 
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes( tmpl );
 
                file.Write( bytes, 0, bytes.Length );
 
                file.Close();
 
                AssetDatabase.Refresh();
            }
        }
    }
}
 
//****************************************************************************************************
//
//****************************************************************************************************
 
namespace Default
{
    static public class ScriptTemplates
    {
        //********************************************************************************************
        //
        //********************************************************************************************
 
        [ ScriptTmpl( "Assets/Scripts/Templates/MonoBehaviour.txt" ) ] private sealed class MonoBehaviour 
        {
            static public readonly ScriptTmplVar[] vars = new ScriptTmplVar[] {};
 
            public const string OPTIONAL_INLINED_TEMPLATE = "using UnityEngine;\n\npublic class {CLASS_NAME} : MonoBehaviour\n{\n}\n";
        }
 
        //********************************************************************************************
        //
        //********************************************************************************************
 
        [ MenuItem( "Scripts/Templates/Enhanced MonoBehaviour", false, 0 ) ] static private void CreateMonoEnhanced() 
        { 
            ScriptTemplate.Create< MonoBehaviour >( MonoBehaviour.vars ); 
        }
 
        [ MenuItem( "Scripts/Templates/Simple MonoBehaviour",   false, 0 ) ] static private void CreateMonoSimple()   
        { 
            ScriptTemplate.Create< MonoBehaviour >( MonoBehaviour.vars, MonoBehaviour.OPTIONAL_INLINED_TEMPLATE ); 
        }
    }
}
 
#endif
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox