using System.Collections; using System.Collections.Generic; using System.Text; using System; using System.Linq; using Godot; using Rokojori.Extensions; using Rokojori.Extensions; namespace Rokojori { [RokojoriActionCoreExport] public class RJLog { #if ROKOJORI_ACTION_CORE_GD public static string Stringify( object obj ) { GDGlue.InsertGDScript( "return str( obj ) "); } #elif ROKOJORI_ACTION_CORE public static string Stringify( object obj ) { return obj + ""; } #endif #if !ROKOJORI_ACTION_CORE_GD public static void WriteStringified( object obj, StringBuilder output ) { if ( obj == null ) { output.Append( "" ); return; } if ( obj is float ) { var floatValue = (float) obj; var doubleValue = (double) floatValue; output.Append( RegexUtility.NumberToString( doubleValue ) ); return; } if ( obj is double ) { output.Append( RegexUtility.NumberToString( (double)obj ) ); return; } if ( obj.GetType().IsArray ) { var array = (Array)obj; output.Append( "[" ); var first = true; foreach ( var it in array ) { if ( first ) { first = false; } else { output.Append( ", " ); } WriteStringified( it, output ); } output.Append( "]" ); return; } if ( obj is IList && obj.GetType().IsGenericType ) { var list = (IList)obj; output.Append( "[" ); var first = true; foreach ( var it in list ) { if ( first ) { first = false; } else { output.Append( ", " ); } WriteStringified( it, output ); } output.Append( "]" ); return; } output.Append( obj.ToString() ); } #endif #if ROKOJORI_ACTION_CORE static void _LogObjects( object obj, params object[] values ) { string message = obj + ""; for ( int i = 0; i < values.Length; i++ ) { message += " " + values[ i ]; } GD.Print( message ); } public static void Log( object obj, params object[] values ) { _LogObjects( obj, values ); } public static void Warn( object obj, params object[] values ) { _LogObjects( obj, values ); } public static void Error( object obj, params object[] values ) { _LogObjects( obj, values ); } #else public static string GetInfo( object obj, params object[] values ) { if ( obj == null ) { return ""; } var sb = new StringBuilder(); sb.Append( obj.GetType().Name ); sb.Append( "{ " ); for ( int i = 0; i < values.Length; i++ ) { if ( i != 0 ) { sb.Append( ", " ); } WriteStringified( values[ i ], sb ); } sb.Append( " }" ); return sb.ToString(); } public static string Stringify( object obj ) { var sb = new StringBuilder(); WriteStringified( obj, sb ); return sb.ToString(); } public static string Stringify( params object[] objects ) { return GetLogString( objects ); } static string counterSet = "0123456789ABCDEGFGHIJKLMNOPQRSTUVWXZ"; static int[] counters = [0,0,0]; static void IncrementCounter() { _IncrementCounter( 0 ); } static void _IncrementCounter( int position ) { if ( position == 2 ) { counters[ 0 ] = 0; counters[ 1 ] = 0; counters[ 2 ] = 0; return; } counters[ position ] ++; if ( counters[ position ] == counterSet.Length ) { counters[ position ] = 0; _IncrementCounter( position + 1 ); } } public static string GetCounterLabel() { return "" + counterSet[ counters[ 2 ] ] + counterSet[ counters[ 1 ] ] + counterSet[ counters[ 0 ] ]; } static void LogMessage( string message, int frameIndex = 3 ) { var counterLabel = "[color=#555555][font_size=10]" + GetCounterLabel() + "[/font_size][/color]"; IncrementCounter(); var trace = GetTrace( frameIndex ); var printMessage = "[b]" + message; GD.PrintRich( counterLabel + printMessage.SplitLines().Join( "\n" + counterLabel + " ") ); GD.PrintRich( counterLabel + trace.SplitLines().Join( "\n" + counterLabel + " ") ); } static void GDLogMessage( string message, string trace ) { trace = "[color=#888888] " + trace + "[/color]" ; GD.PrintRich("\n[b]" + message ); GD.PrintRich( trace ); } static void LogMessageWithFullTrace( string message ) { var trace = GetFullTrace(); GD.PrintRich("\n[b]" + message ); GD.PrintRich( trace ); } static void LogErrorWithFullTrace( string message ) { var trace = GetFullTrace(); GD.PrintErr("\n" + message ); GD.PrintRich( trace ); } static void LogErrorMessage( string message, int frameIndex = 3 ) { var counterLabelRaw = GetCounterLabel(); var counterLabel = "[color=#555555][font_size=10]" + counterLabelRaw + "[/font_size][/color]"; IncrementCounter(); var trace = GetTrace( frameIndex ); var printMessage = "\n"+ message; GD.PrintErr( "\n"+ counterLabelRaw + " " +printMessage.SplitLines().Join( "\n" + counterLabelRaw + " " ) ); GD.PrintRich( counterLabel + trace.SplitLines().Join( "\n" + counterLabel + " ") ); } static string GetFullTrace() { return ( new System.Diagnostics.StackTrace( true ) ).ToString(); } static string GetTrace( int frameIndex = 3 ) { var stackTrace = new System.Diagnostics.StackTrace( true ); var frame = stackTrace.GetFrame( frameIndex ); var className = frame.GetFileName(); if ( className != null ) { var slashIndex = -1; for ( int i = className.Length - 1; i >= 0 && slashIndex == -1; i-- ) { if ( className[ i ] == '\\' || className[ i ] == '/' ) { slashIndex = i; } } if ( slashIndex != -1 ) { var end = className.EndsWith( ".cs" ) ? className.Length - 3 : className.Length; className = className.Substring( slashIndex + 1, end - ( slashIndex + 1 ) ); } } if ( className == null ) { className =""; } var trace = className + "." + frame.GetMethod().Name + "() ln."+ frame.GetFileLineNumber(); return "[color=#888888] " + trace + "[/color]" ; } public static void LogWithFullTrace( params object[] objects) { LogMessageWithFullTrace( GetLogString( objects ) ); } public static void Log( params object[] objects ) { LogMessage( GetLogString( objects ) ); } public static void LogWithTraceOffset( int offset, params object[] objects ) { LogMessage( GetLogString( objects ), 3 + offset ); } public static void Log( Node node, params object[] objects) { LogMessage( "[color=#55aaff]" + HierarchyName.Of( node ) + "[/color]\n" + GetLogString( objects ), 4 ); } public static void Log( Resource resource, params object[] objects) { LogMessage( "[color=#55ffaa]" + HierarchyName.Of( resource ) + "[/color]\n" + GetLogString( objects ), 4 ); } public static void GDLog( string trace, Node node, params object[] objects) { GDLogMessage( "[color=#55aaff]" + HierarchyName.Of( node ) + "[/color]\n" + GetLogString( objects ), trace ); } public static void GDLog( string trace, Resource resource, params object[] objects) { GDLogMessage( "[color=#55ffaa]" + HierarchyName.Of( resource ) + "[/color]\n" + GetLogString( objects ), trace ); } public static void Error( params object[] objects) { LogErrorMessage( GetLogString( objects ) ); } public static void ErrorWithFullTrace( params object[] objects) { LogErrorWithFullTrace( GetLogString( objects ) ); } public static void Error( Node node, params object[] objects) { LogErrorMessage( "" + HierarchyName.Of( node ) + "\n" + GetLogString( objects ), 4 ); } public static void Error( Resource resource, params object[] objects) { LogErrorMessage( "" + HierarchyName.Of( resource ) + "\n" + GetLogString( objects ), 4 ); } public static void ErrorGD( GodotObject obj, params object[] objects) { if ( obj is Node n ) { Error( n, objects ); } else if ( obj is Resource r ) { Error( r, objects ); } else { LogErrorMessage( "" + obj + "\n" + GetLogString( objects ), 4 ); } } public static string GetLogString( object[] objects ) { var sb = new StringBuilder(); for ( int i = 0; i < objects.Length; i++ ) { if ( i != 0 ) { sb.Append( " " ); } WriteStringified( objects[ i ], sb ); } return sb.ToString(); } #endif } }