1- using System . Runtime . CompilerServices ;
2- using System . Runtime . InteropServices ;
3- using ImGuiNET ;
4- using StArray . ModManager . Manager ;
5- using StArray . ModManager . UI ;
6- using StArray . ModManager . Windows . Native ;
7-
8- namespace StArray . ModManager . Windows . UI ;
9-
10- public sealed unsafe class ImGuiDXRenderer : IImGuiRenderer
11- {
12- static ImGuiDXRenderer ? s_i ;
13- public static ImGuiDXRenderer Instance => s_i ?? throw new ( "Not installed" ) ;
14- public static bool Install ( ) => ( s_i = new ImGuiDXRenderer ( ) ) . InstallInstance ( ) ;
15-
16- static Action ? s_pending ;
17- public static event Action OnRender
18- {
19- add { if ( s_i != null ) s_i . _onRender += value ; else s_pending += value ; }
20- remove { if ( s_i != null ) s_i . _onRender -= value ; else s_pending -= value ; }
21- }
22-
23- bool _ok ; Action _onRender = ( ) => { } ;
24-
25- event Action IImGuiRenderer . OnRender { add => _onRender += value ; remove => _onRender -= value ; }
26- public bool IsInitialized => _ok ;
27- bool IImGuiRenderer . Install ( ) => InstallInstance ( ) ;
28-
29- unsafe bool InstallInstance ( )
30- {
31- try
32- {
33- int r = NativeApi . Init (
34- ( nint ) ( delegate * unmanaged[ Cdecl] < IntPtr > ) & InitCallback ,
35- ( nint ) ( delegate * unmanaged[ Cdecl] < void > ) & ShutdownCallback ,
36- ( nint ) ( delegate * unmanaged[ Cdecl] < void > ) & RenderCallback ) ;
37- Logger . Info ( nameof ( ImGuiDXRenderer ) , $ "NativeInit={ r } ") ;
38-
39- if ( s_pending != null ) { _onRender += s_pending ; s_pending = null ; }
40- _ok = true ; Logger . Info ( nameof ( ImGuiDXRenderer ) , "Ready (multi-backend)" ) ;
41- return true ;
42- }
43- catch ( Exception e ) { Logger . Error ( nameof ( ImGuiDXRenderer ) , $ "fail: { e . Message } ") ; return false ; }
44- }
45-
46- [ UnmanagedCallersOnly ( CallConvs = [ typeof ( CallConvCdecl ) ] ) ]
47- static IntPtr InitCallback ( )
48- {
49- Logger . Info ( nameof ( ImGuiDXRenderer ) , "Native Init" ) ;
50- if ( s_i != null )
51- ( s_i as IImGuiRenderer ) . InitImGui ( ) ;
52- return IntPtr . Zero ;
53- }
54-
55- [ UnmanagedCallersOnly ( CallConvs = [ typeof ( CallConvCdecl ) ] ) ]
56- static void ShutdownCallback ( )
57- {
58- Logger . Info ( nameof ( ImGuiDXRenderer ) , "Shutdown" ) ;
59- ImGui . DestroyContext ( ) ;
60- }
61-
62- [ UnmanagedCallersOnly ( CallConvs = [ typeof ( CallConvCdecl ) ] ) ]
63- static void RenderCallback ( )
64- {
65- if ( s_i == null ) return ;
66- ImGui . NewFrame ( ) ;
67- try { s_i . _onRender ( ) ; } catch ( Exception e ) { Logger . Error ( nameof ( ImGuiDXRenderer ) , $ "Render error: { e . Message } ") ; }
68- ImGui . EndFrame ( ) ;
69- ImGui . Render ( ) ;
70- }
1+ using System . Runtime . InteropServices ;
2+ using ImGuiNET ;
3+ using StArray . ModManager . Manager ;
4+ using StArray . ModManager . UI ;
5+ using StArray . ModManager . Windows . Native ;
6+
7+ namespace StArray . ModManager . Windows . UI ;
8+
9+ public sealed unsafe class ImGuiDXRenderer : IImGuiRenderer
10+ {
11+ static ImGuiDXRenderer ? s_i ;
12+ public static ImGuiDXRenderer Instance => s_i ?? throw new ( "Not installed" ) ;
13+ public static bool Install ( ) => ( s_i = new ImGuiDXRenderer ( ) ) . InstallInstance ( ) ;
14+
15+ static Action ? s_pending ;
16+ public static event Action OnRender
17+ {
18+ add { if ( s_i != null ) s_i . _onRender += value ; else s_pending += value ; }
19+ remove { if ( s_i != null ) s_i . _onRender -= value ; else s_pending -= value ; }
20+ }
21+
22+ bool _ok ; Action _onRender = ( ) => { } ;
23+
24+ static NativeApi . ImGuiInitCallback ? _sInit ;
25+ static NativeApi . ImGuiShutdownCallback ? _sShutdown ;
26+ static NativeApi . ImGuiRenderCallback ? _sRender ;
27+
28+ event Action IImGuiRenderer . OnRender { add => _onRender += value ; remove => _onRender -= value ; }
29+ public bool IsInitialized => _ok ;
30+ bool IImGuiRenderer . Install ( ) => InstallInstance ( ) ;
31+
32+ bool InstallInstance ( )
33+ {
34+ try
35+ {
36+ _sInit = InitCallback ;
37+ _sShutdown = ShutdownCallback ;
38+ _sRender = RenderCallback ;
39+
40+ int r = NativeApi . Init (
41+ Marshal . GetFunctionPointerForDelegate ( _sInit ) ,
42+ Marshal . GetFunctionPointerForDelegate ( _sShutdown ) ,
43+ Marshal . GetFunctionPointerForDelegate ( _sRender ) ) ;
44+ Logger . Info ( nameof ( ImGuiDXRenderer ) , $ "NativeInit={ r } ") ;
45+
46+ if ( s_pending != null ) { _onRender += s_pending ; s_pending = null ; }
47+ _ok = true ; Logger . Info ( nameof ( ImGuiDXRenderer ) , "Ready (multi-backend)" ) ;
48+ return true ;
49+ }
50+ catch ( Exception e ) { Logger . Error ( nameof ( ImGuiDXRenderer ) , $ "fail: { e . Message } ") ; return false ; }
51+ }
52+
53+ static IntPtr InitCallback ( )
54+ {
55+ Logger . Info ( nameof ( ImGuiDXRenderer ) , "Init" ) ;
56+ if ( s_i != null )
57+ ( s_i as IImGuiRenderer ) . InitImGui ( ) ;
58+ return IntPtr . Zero ;
59+ }
60+
61+ static void ShutdownCallback ( )
62+ {
63+ Logger . Info ( nameof ( ImGuiDXRenderer ) , "Shutdown" ) ;
64+ ImGui . DestroyContext ( ) ;
65+ }
66+
67+ static void RenderCallback ( )
68+ {
69+ if ( s_i == null ) return ;
70+ ImGui . NewFrame ( ) ;
71+ try { s_i . _onRender ( ) ; } catch ( Exception e ) { Logger . Error ( nameof ( ImGuiDXRenderer ) , $ "Render error: { e . Message } ") ; }
72+ ImGui . EndFrame ( ) ;
73+ ImGui . Render ( ) ;
74+ }
7175}
0 commit comments