22using System . Reflection ;
33using HarmonyLib ;
44using NeoModLoader . constants ;
5-
65namespace NeoModLoader . services ;
7-
86[ AttributeUsage ( AttributeTargets . Method | AttributeTargets . Class ) ]
9- public class DebugAttribute : Attribute { }
7+ public class DoNotDebug : Attribute { }
108public static class DebugService
119{
12- static bool IsDebuggable ( MethodBase method )
10+ static DebugService ( )
11+ {
12+ Logger = new Debugger < Action < MethodBase , object [ ] > > ( AccessTools . Method ( typeof ( Hooks ) , nameof ( Hooks . loghook ) ) ) ;
13+ ExceptionHandler = new Debugger < Action < MethodBase , Exception > > ( null , null , AccessTools . Method ( typeof ( Hooks ) , nameof ( Hooks . finalizer ) ) ) ;
14+ Profiler = new Debugger < Action < MethodBase , long > > ( AccessTools . Method ( typeof ( Hooks ) , nameof ( Hooks . prefix ) ) , AccessTools . Method ( typeof ( Hooks ) , nameof ( Hooks . postfix ) ) ) ;
15+ }
16+ class Hooks
17+ {
18+ public static void loghook ( MethodBase __originalMethod , object [ ] __args )
19+ {
20+ Logger . Handler ( __originalMethod , __args ) ;
21+ }
22+ public static void prefix ( out long __state )
23+ {
24+ __state = Stopwatch . GetTimestamp ( ) ;
25+ }
26+ public static void postfix (
27+ MethodBase __originalMethod ,
28+ long __state )
29+ {
30+ Profiler . Handler ( __originalMethod , Stopwatch . GetTimestamp ( ) - __state ) ;
31+ }
32+ public static void finalizer ( Exception __exception , MethodBase __originalMethod )
33+ {
34+ if ( __exception is not null )
35+ ExceptionHandler . Handler ( __originalMethod , __exception ) ;
36+ }
37+ }
38+ public static bool IsDebuggable ( MethodBase method )
1339 {
1440 if ( method . IsAbstract || method . ContainsGenericParameters || method . IsSpecialName || method . Name . Contains ( "<" ) )
1541 {
1642 return false ;
1743 }
1844 return true ;
1945 }
20- public abstract class Debugger
46+ public class Debugger < T > where T : Delegate
2147 {
22- protected HarmonyMethod Prefix ;
23- protected HarmonyMethod Postfix ;
24- protected HarmonyMethod Finalizer ;
48+ public void AddHandler ( T handler )
49+ {
50+ Handler = ( T ) Delegate . Combine ( Handler , handler ) ;
51+ }
52+ public T Handler { get ; private set ; }
53+ public Debugger ( MethodInfo Prefix = null , MethodInfo Postfix = null , MethodInfo Finalizer = null )
54+ {
55+ if ( Prefix is not null )
56+ {
57+ this . Prefix = new HarmonyMethod ( Prefix ) ;
58+ }
59+ if ( Postfix is not null )
60+ {
61+ this . Postfix = new HarmonyMethod ( Postfix ) ;
62+ }
63+ if ( Finalizer is not null )
64+ {
65+ this . Finalizer = new HarmonyMethod ( Finalizer ) ;
66+ }
67+ }
68+ HarmonyMethod Prefix ;
69+ HarmonyMethod Postfix ;
70+ HarmonyMethod Finalizer ;
2571 public void Attach ( Assembly assembly , Func < MethodBase , bool > predicate = null )
2672 {
2773 foreach ( var Type in assembly . GetTypes ( ) )
@@ -31,7 +77,7 @@ public void Attach(Assembly assembly, Func<MethodBase, bool> predicate = null)
3177 }
3278 public void Attach ( Type Type , Func < MethodBase , bool > predicate = null )
3379 {
34- predicate ??= Default ;
80+ predicate ??= DefaultPredicate ;
3581 foreach ( var method in Type . GetMethods (
3682 BindingFlags . Public |
3783 BindingFlags . NonPublic |
@@ -63,59 +109,9 @@ public void Attach(MethodBase method)
63109 }
64110 }
65111 }
66- public class LogDebugger : Debugger
67- {
68- static void prefix ( MethodBase __originalMethod )
69- {
70- LogService . Log ( __originalMethod . ToString ( ) ) ;
71- }
72- public LogDebugger ( )
73- {
74- Prefix = new HarmonyMethod ( AccessTools . Method ( typeof ( LogDebugger ) , nameof ( prefix ) ) ) ;
75- }
76- }
77- public class ProfilerDebugger : Debugger
78- {
79- static Stopwatch stopwatch = new ( ) ;
80- public static void prefix ( out long __state )
81- {
82- __state = Stopwatch . GetTimestamp ( ) ;
83- }
84- public static void postfix (
85- MethodBase __originalMethod ,
86- long __state )
87- {
88- LogService . Log (
89- $ "{ __originalMethod . Name } took { Stopwatch . GetTimestamp ( ) - __state } ") ;
90- }
91- public ProfilerDebugger ( )
92- {
93- Prefix = new HarmonyMethod ( AccessTools . Method ( typeof ( ProfilerDebugger ) , nameof ( prefix ) ) ) ;
94- Postfix = new HarmonyMethod ( AccessTools . Method ( typeof ( ProfilerDebugger ) , nameof ( postfix ) ) ) ;
95- }
96- }
97- public class ExceptionDebugger : Debugger
98- {
99- static void finalizer ( Exception __exception , MethodBase __original )
100- {
101- if ( __exception is not null )
102- handler ? . Invoke ( __exception , __original ) ;
103- }
104- public ExceptionDebugger ( )
105- {
106- Finalizer = new HarmonyMethod ( AccessTools . Method ( typeof ( ExceptionDebugger ) , nameof ( finalizer ) ) ) ;
107- }
108- public static void AddHandler ( ExceptionHandler Handler )
109- {
110- handler += Handler ;
111- }
112- public delegate void ExceptionHandler ( Exception Exception , MethodBase Method ) ;
113- public static event ExceptionHandler handler ;
114- }
115- static readonly Harmony Patcher = new Harmony ( Others . harmony_id ) ;
116- public static readonly LogDebugger Logger = new ( ) ;
117- public static readonly ProfilerDebugger Profiler = new ( ) ;
118- public static readonly ExceptionDebugger ExceptionHandler = new ( ) ;
119- public static readonly Func < MethodBase , bool > Default = _ => true ;
120- public static readonly Func < MethodBase , bool > Attribute = method => method . IsDefined ( typeof ( DebugAttribute ) , true ) || method . DeclaringType ? . IsDefined ( typeof ( DebugAttribute ) , true ) == true ;
112+ static readonly Harmony Patcher = new ( Others . harmony_id ) ;
113+ public static readonly Debugger < Action < MethodBase , object [ ] > > Logger ;
114+ public static readonly Debugger < Action < MethodBase , Exception > > ExceptionHandler ;
115+ public static readonly Debugger < Action < MethodBase , long > > Profiler ;
116+ public static readonly Func < MethodBase , bool > DefaultPredicate = method => ! method . IsDefined ( typeof ( DoNotDebug ) , true ) && ! method . DeclaringType ! . IsDefined ( typeof ( DoNotDebug ) , true ) ;
121117}
0 commit comments