1+ using Sandbox . ModAPI ;
2+ using System ;
3+ using System . Collections . Generic ;
4+ using VRage . Game . ModAPI ;
5+
6+ namespace StealthSystem
7+ {
8+ internal class StealthAPI
9+ {
10+ /// Returns true if drive status was toggled successfully.
11+ /// <param name="force">Ignore power requirements and overheat.</param>
12+ public bool ToggleStealth ( IMyTerminalBlock drive , bool force ) => _toggleStealth ? . Invoke ( drive , force ) ?? false ;
13+
14+ /// Returns status of drive. 0 = Ready, 1 = Active, 2 = Cooldown, 3 = Not enough power, 4 = Offline
15+ public int GetStatus ( IMyTerminalBlock drive ) => _getStatus ? . Invoke ( drive ) ?? 4 ;
16+
17+ /// Returns remaining duration of stealth/cooldown.
18+ public int GetDuration ( IMyTerminalBlock drive ) => _getDuration ? . Invoke ( drive ) ?? 0 ;
19+
20+ /// Retuns active stealth drive on grid if one exists, otherwise returns null.
21+ public IMyTerminalBlock GetMainDrive ( IMyCubeGrid grid ) => _getMainDrive ? . Invoke ( grid ) ;
22+
23+ /// <param name="sinks">Collection to populate with heat sinks on grid.</param>
24+ public void GetHeatSinks ( IMyCubeGrid grid , ICollection < IMyTerminalBlock > sinks ) => _getHeatSinks ? . Invoke ( grid , sinks ) ;
25+
26+
27+
28+ private const long CHANNEL = 2172757427 ;
29+ private bool _isRegistered ;
30+ private bool _apiInit ;
31+ private Action _readyCallback ;
32+
33+ private Func < IMyTerminalBlock , bool , bool > _toggleStealth ;
34+ private Func < IMyTerminalBlock , int > _getStatus ;
35+ private Func < IMyTerminalBlock , int > _getDuration ;
36+ private Func < IMyCubeGrid , IMyTerminalBlock > _getMainDrive ;
37+ private Action < IMyCubeGrid , ICollection < IMyTerminalBlock > > _getHeatSinks ;
38+
39+ public bool IsReady { get ; private set ; }
40+
41+
42+ /// <summary>
43+ /// Ask CoreSystems to send the API methods.
44+ /// <para>Throws an exception if it gets called more than once per session without <see cref="Unload"/>.</para>
45+ /// </summary>
46+ /// <param name="readyCallback">Method to be called when CoreSystems replies.</param>
47+ public void Load ( Action readyCallback = null )
48+ {
49+ if ( _isRegistered )
50+ throw new Exception ( $ "{ GetType ( ) . Name } .Load() should not be called multiple times!") ;
51+
52+ _readyCallback = readyCallback ;
53+ _isRegistered = true ;
54+ MyAPIGateway . Utilities . RegisterMessageHandler ( CHANNEL , HandleMessage ) ;
55+ MyAPIGateway . Utilities . SendModMessage ( CHANNEL , "ApiEndpointRequest" ) ;
56+ }
57+
58+ public void Unload ( )
59+ {
60+ MyAPIGateway . Utilities . UnregisterMessageHandler ( CHANNEL , HandleMessage ) ;
61+
62+ ApiAssign ( null ) ;
63+
64+ _isRegistered = false ;
65+ _apiInit = false ;
66+ IsReady = false ;
67+ }
68+
69+ private void HandleMessage ( object obj )
70+ {
71+ if ( _apiInit || obj is string
72+ ) // the sent "ApiEndpointRequest" will also be received here, explicitly ignoring that
73+ return ;
74+
75+ var dict = obj as IReadOnlyDictionary < string , Delegate > ;
76+
77+ if ( dict == null )
78+ return ;
79+
80+ ApiAssign ( dict ) ;
81+
82+ IsReady = true ;
83+ _readyCallback ? . Invoke ( ) ;
84+ }
85+
86+ public void ApiAssign ( IReadOnlyDictionary < string , Delegate > delegates )
87+ {
88+ _apiInit = ( delegates != null ) ;
89+ /// base methods
90+ AssignMethod ( delegates , "ToggleStealth" , ref _toggleStealth ) ;
91+ AssignMethod ( delegates , "GetStatus" , ref _getStatus ) ;
92+ AssignMethod ( delegates , "GetDuration" , ref _getDuration ) ;
93+ AssignMethod ( delegates , "GetMainDrive" , ref _getMainDrive ) ;
94+ AssignMethod ( delegates , "GetHeatSinks" , ref _getHeatSinks ) ;
95+ }
96+
97+ private void AssignMethod < T > ( IReadOnlyDictionary < string , Delegate > delegates , string name , ref T field )
98+ where T : class
99+ {
100+ if ( delegates == null )
101+ {
102+ field = null ;
103+ return ;
104+ }
105+
106+ Delegate del ;
107+ if ( ! delegates . TryGetValue ( name , out del ) )
108+ throw new Exception ( $ "{ GetType ( ) . Name } :: Couldn't find { name } delegate of type { typeof ( T ) } ") ;
109+
110+ field = del as T ;
111+
112+ if ( field == null )
113+ throw new Exception (
114+ $ "{ GetType ( ) . Name } :: Delegate { name } is not type { typeof ( T ) } , instead it's: { del . GetType ( ) } ") ;
115+ }
116+
117+ }
118+
119+ }
0 commit comments