11using System ;
22using System . Collections . Generic ;
3- using System . Collections . ObjectModel ;
43using System . Linq ;
4+ using EliteAPI . Events ;
55using EliteAPI . Journals ;
66using EliteAPI . Json ;
77using EliteAPI . Watcher ;
8+ using Newtonsoft . Json ;
89
9- namespace EliteApi ;
10+ namespace EliteAPI ;
1011
1112public class EliteDangerousApi
1213{
1314 private readonly List < FileWatcher > _watchers ;
1415
16+ private readonly List < Action < IEvent > > _typedGlobalEventHandlers = [ ] ;
17+ private readonly List < Action < ( string eventName , string json ) > > _untypedGlobalEventHandlers = [ ] ;
18+ private readonly Dictionary < string , List < Action < IEvent > > > _typedEventHandlers = [ ] ;
19+ private readonly Dictionary < string , List < Action < ( string eventName , string json ) > > > _untypedEventHandlers = [ ] ;
20+
1521 public EliteDangerousApi ( )
1622 {
1723 var journalDirectory = JournalUtils . GetJournalsDirectory ( ) ;
@@ -34,20 +40,162 @@ public EliteDangerousApi()
3440
3541 public void Start ( )
3642 {
43+ _watchers . ForEach ( w => w . OnContentChanged ( json => Invoke ( json ) ) ) ;
3744 _watchers . ForEach ( w => w . StartWatching ( ) ) ;
3845 }
3946
40- public void OnPathsChanged ( Action < ( string command , List < JsonPath > variables ) > onPathsChanged )
47+ /// <summary>
48+ /// Listens for a specific event of <typeparamref name="TEvent"/>.
49+ /// </summary>
50+ public void On < TEvent > ( Action < TEvent > handler )
51+ where TEvent : IEvent
52+ {
53+ var eventName = typeof ( TEvent ) . GetType ( ) . Name ;
54+
55+ // remove "Event" suffix
56+ if ( eventName . EndsWith ( "Event" ) )
57+ eventName = eventName [ ..^ 5 ] ;
58+
59+ // initialize list if not exists
60+ if ( ! _typedEventHandlers . ContainsKey ( eventName ) )
61+ _typedEventHandlers [ eventName ] = [ ] ;
62+
63+ // add handler
64+ _typedEventHandlers [ eventName ] . Add ( e => handler ( ( TEvent ) e ) ) ;
65+ }
66+
67+ /// <summary>
68+ /// Listens for a specific event with the event name of <paramref name="eventName"/> and provides the raw JSON.
69+ /// </summary>
70+ public void OnJson ( string eventName , Action < ( string eventName , string json ) > handler )
71+ {
72+ // remove "Event" suffix
73+ if ( eventName . EndsWith ( "Event" ) )
74+ eventName = eventName [ ..^ 5 ] ;
75+
76+ // initialize list if not exists
77+ if ( ! _untypedEventHandlers . ContainsKey ( eventName ) )
78+ _untypedEventHandlers [ eventName ] = [ ] ;
79+
80+ // add handler
81+ _untypedEventHandlers [ eventName ] . Add ( handler ) ;
82+ }
83+
84+ /// <summary>
85+ /// Listens for all events which are typed.
86+ /// </summary>
87+ public void OnAll ( Action < IEvent > handler )
88+ {
89+ _typedGlobalEventHandlers . Add ( handler ) ;
90+ }
91+
92+ /// <summary>
93+ /// Listens for all events with raw JSON
94+ /// </summary>
95+ public void OnAllJson ( Action < ( string eventName , string json ) > handler )
96+ {
97+ _untypedGlobalEventHandlers . Add ( handler ) ;
98+ }
99+
100+ internal void Invoke ( IEvent @event )
101+ {
102+ Invoke ( JsonConvert . SerializeObject ( @event ) , @event ) ;
103+ }
104+
105+ internal void Invoke ( string json ) => Invoke ( json , null ) ;
106+
107+ internal void Invoke ( string json , IEvent ? @event )
41108 {
42- _watchers . ForEach ( w =>
109+ var eventName = JsonUtils . GetEventName ( json ) ;
110+ if ( string . IsNullOrEmpty ( eventName ) )
111+ {
112+ // TODO: proper logging system for this
113+ Console . WriteLine ( "Skipping invalid event with no name." ) ;
114+ return ;
115+ }
116+
117+ if ( @event == null && _typedEventHandlers . ContainsKey ( eventName ) )
118+ {
119+ var eventType = _typedEventHandlers [ eventName ] . First ( ) . Method . GetParameters ( ) [ 0 ] . ParameterType ;
120+ @event = JsonConvert . DeserializeObject ( json , eventType ) as IEvent ;
121+
122+ if ( @event == null )
123+ {
124+ // TODO: proper logging
125+ Console . WriteLine ( $ "Failed to deserialize event { eventName } to type { eventType . Name } .") ;
126+ return ;
127+ }
128+ }
129+
130+ // invoke untyped handlers
131+ if ( _untypedEventHandlers . ContainsKey ( eventName ) )
132+ {
133+ foreach ( var handler in _untypedEventHandlers [ eventName ] )
134+ {
135+ try
136+ {
137+ handler ( ( eventName , json ) ) ;
138+ }
139+ catch ( Exception ex )
140+ {
141+ // TODO: proper logging
142+ Console . WriteLine ( $ "Error invoking handler for event { eventName } : { ex } ") ;
143+ }
144+ }
145+ }
146+
147+ // invoke global untyped handlers
148+ foreach ( var handler in _untypedGlobalEventHandlers )
149+ {
150+ try
151+ {
152+ handler ( ( eventName , json ) ) ;
153+ }
154+ catch ( Exception ex )
155+ {
156+ // TODO: proper logging
157+ Console . WriteLine ( $ "Error invoking global untyped handler: { ex } ") ;
158+ }
159+ }
160+
161+ if ( @event != null )
43162 {
44- w . OnContentChanged ( async json =>
163+ // invoke typed handlers
164+ if ( _typedEventHandlers . ContainsKey ( eventName ) )
45165 {
46- var paths = JournalUtils . ToPaths ( json ) ;
47- var command = JournalUtils . GetEventName ( json ) ;
166+ foreach ( var handler in _typedEventHandlers [ eventName ] )
167+ {
168+ try
169+ {
170+ handler ( @event ) ;
171+ }
172+ catch ( Exception ex )
173+ {
174+ // TODO: proper logging
175+ Console . WriteLine ( $ "Error invoking handler for event { eventName } : { ex } ") ;
176+ }
177+ }
178+ }
48179
49- onPathsChanged ( ( command , paths ) ) ;
50- } ) ;
51- } ) ;
180+ // invoke global typed handlers
181+ foreach ( var handler in _typedGlobalEventHandlers )
182+ {
183+ try
184+ {
185+ handler ( @event ) ;
186+ }
187+ catch ( Exception ex )
188+ {
189+ // TODO: proper logging
190+ Console . WriteLine ( $ "Error invoking global typed handler: { ex } ") ;
191+ }
192+ }
193+ }
194+ }
195+
196+ public void OnJson ( Action < object , object > value )
197+ {
198+ throw new NotImplementedException ( ) ;
52199 }
53200}
201+
0 commit comments