Commit ec494ecfafa3f0142e2aeaf40b3aa078236d0c5f

gui, manager ja backend viilausta


Former-commit-id: a5beec0947637adc0d38d7c92de38c46f62fd3fc
sovellus/vs/Ajolabra/ALBackend/ALBackend.csproj
(1 / 1)
  
9494 <Compile Include="DeviceComponents\Shared\PipelineComponentRestarter.cs" />
9595 <Compile Include="DeviceComponents\IPipelineEvents.cs" />
9696 <Compile Include="DeviceComponents\Shared\AbstractPipelineComponent.cs" />
97 <Compile Include="DeviceComponents\Shared\CollectingObserver.cs" />
97 <Compile Include="DeviceComponents\Shared\CollatingObserver.cs" />
9898 <Compile Include="DeviceComponents\Shared\CSVRawLineSplitter.cs" />
9999 <Compile Include="CSVComponents\CSVTools.cs" />
100100 <Compile Include="DeviceComponents\Shared\CollectedDataExtensions.cs" />
sovellus/vs/Ajolabra/ALBackend/CSVComponents/CSVSchemaParser.cs
(0 / 1)
  
140140 extractedData.Add(stringEnumerator.Current);
141141 remaining--;
142142 }
143
144143 }
145144 }
146145 else
sovellus/vs/Ajolabra/ALBackend/CSVComponents/SchemaElements/CSVRLTimestamp.cs
(2 / 1)
  
117117 {
118118 // Should unify the use of format string in this
119119 // and DETimestamp's ToString() method
120 // We also need (in future) to check for proper DateTimeStyles and IFormatProviders
120 // We also need (in future) to check for proper
121 // DateTimeStyles and IFormatProviders
121122 if (DateTimeOffset.TryParseExact(
122123 rawStr,
123124 this.Format,
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/DS/DSReader.cs
(3 / 2)
  
22using Ajolabra.Backend.DataTypes.DataConversion;
33using Ajolabra.Backend.DataTypes.DataElements;
44using Ajolabra.Backend.DeviceComponents.Shared;
5using static Ajolabra.Backend.Synchronization.DataCombiner;
56using System;
67using System.Collections.Concurrent;
78using System.Collections.Generic;
89using System.Linq;
910using System.Threading;
10using static Ajolabra.Backend.Synchronization.DataCombiner;
1111
1212/// Copyright 2019 Mari Kasanen, Leevi Liimatainen, Marina Mustonen,
1313/// Juhani Sundell, Arttu Ylä-Sahra
207207 LRFlags.SkipEmptyLines);
208208
209209 // Create driving data CSV splitter
210 // Driving simulator provides a lot of data points, which makes for a slightly obtuse representation
210 // Driving simulator provides a lot of data points,
211 // which makes for a slightly obtuse representation
211212 this.csvSplitterNormal = new CSVRawLineSplitter(
212213 new BlockingCollection<Dictionary<string, IDataElement>>[]
213214 { normalCSVOutputCollection },
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/DS/DSTimeCalculationHelper.cs
(1 / 1)
  
11using Ajolabra.Backend.DataTypes.DataElements;
22using Ajolabra.Backend.DeviceComponents.Shared;
3using static Ajolabra.Backend.Synchronization.DataCombiner;
34using System;
45using System.Collections.Generic;
56using System.Linq;
6using static Ajolabra.Backend.Synchronization.DataCombiner;
77
88/// Copyright 2019 Mari Kasanen, Leevi Liimatainen, Marina Mustonen,
99/// Juhani Sundell, Arttu Ylä-Sahra
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/DS/DSWrapper.cs
(3 / 1)
  
9797 this.innerOutputCollection
9898 = new BlockingCollection<Dictionary<string, IDataElement>>();
9999 this.innerReader
100 = new DSReader(new BlockingCollection<Dictionary<string, IDataElement>>[] { this.innerOutputCollection }, port);
100 = new DSReader(new BlockingCollection<Dictionary<
101 string, IDataElement>>[]
102 { this.innerOutputCollection }, port);
101103
102104 // Add event passthrough
103105 this.innerReader.LogMessage += (obj, msg)
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/Shared/AbstractPipelineComponent.cs
(6 / 5)
  
367367 this._currentStatus = value;
368368
369369 // Next, report to observers
370 foreach (IObserver<PipelineStatus> observer
370 foreach (IObserver<PipelineStatus> observer
371371 in this._storedObservers)
372372 {
373373 observer.OnNext(value);
374374
375 if (this._currentStatus == PipelineStatus.Fault
375 if (this._currentStatus == PipelineStatus.Fault
376376 && this.LastException != null)
377377 {
378378 observer.OnError(this.LastException);
379379 }
380380 }
381
382381 }
383382 finally
384383 {
427427 }
428428
429429 /// <summary>
430 /// If this component has faulted for any reason, the thrown exception is stored here
430 /// If this component has faulted for any reason,
431 /// the thrown exception is stored here
431432 /// </summary>
432433 public Exception LastException
433434 {
926926 }
927927
928928 this.DataElementOutputQueues
929 = new ConcurrentBag<BlockingCollection<Dictionary<string, IDataElement>>>(dataElementOutputQueues);
929 = new ConcurrentBag<BlockingCollection<Dictionary<
930 string, IDataElement>>>(dataElementOutputQueues);
930931 }
931932
932933 }
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/Shared/CSVRawLineSplitter.cs
(1 / 1)
  
342342 }
343343 catch (KeyNotFoundException)
344344 {
345 // React appropriately, log a warning unless we have slienced them
345 // React appropriately, log a warning unless we have silenced them
346346 if (!this.Flags.HasFlag(
347347 CSVRLSFlags.NoWarnMissingReceivedAt))
348348 {
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/Shared/CollatingObserver.cs
(342 / 0)
  
1using System;
2using System.Collections.Generic;
3
4/// Copyright 2019 Mari Kasanen, Leevi Liimatainen, Marina Mustonen,
5/// Juhani Sundell, Arttu Ylä-Sahra
6///
7/// Redistribution and use in source and binary forms, with
8/// or without modification, are permitted provided that the
9/// following conditions are met:
10///
11/// 1. Redistributions of source code must retain the above copyright
12/// notice, this list of conditions and the following disclaimer.
13///
14/// 2. Redistributions in binary form must reproduce the above copyright
15/// notice, this list of conditions and the following disclaimer in the
16/// documentation and/or other materials provided with the distribution.
17///
18/// 3. Neither the name of the copyright holder nor the names of its
19/// contributors may be used to endorse or promote products derived from
20/// this software without specific prior written permission.
21///
22/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25/// FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26///
27/// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28/// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29/// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30/// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31/// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32/// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33/// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34/// POSSIBILITY OF SUCH DAMAGE.
35
36
37namespace Ajolabra.Backend.DeviceComponents.Shared
38{
39
40 public enum CDOEventType
41 {
42 NormalEvent,
43 Exception,
44 Completed
45 }
46
47 /// <summary>
48 /// A storage class for collated data as collected from many sources;
49 /// either holds data or an exception, as indicated by the inner type.
50 /// </summary>
51 /// <typeparam name="T">Inner type</typeparam>
52 public class CollatedObserverData<T>
53 {
54 public CollatedObserverData(object origin, T data)
55 {
56 this.Type = CDOEventType.NormalEvent;
57 this.Origin = origin
58 ?? throw new ArgumentNullException(
59 "origin",
60 "Origin may not be null"
61 );
62 this.Data = data;
63 this.Exception = null;
64 }
65
66 public CollatedObserverData(object origin, Exception exception)
67 {
68 this.Type = CDOEventType.Exception;
69 this.Origin = origin
70 ?? throw new ArgumentNullException(
71 "origin",
72 "Origin may not be null"
73 );
74 this.Data = default(T);
75 this.Exception = exception;
76 }
77
78 public CollatedObserverData(object origin)
79 {
80 this.Type = CDOEventType.Completed;
81 this.Origin = origin
82 ?? throw new ArgumentNullException(
83 "origin",
84 "Origin may not be null"
85 );
86 this.Data = default(T);
87 this.Exception = null;
88 }
89
90 public object Origin
91 {
92 get; private set;
93 }
94 public CDOEventType Type
95 {
96 get; private set;
97 }
98 public T Data
99 {
100 get; private set;
101 }
102 public Exception Exception
103 {
104 get; private set;
105 }
106 }
107
108 /// <summary>
109 /// A helper class; collects observer data from multiple origins,
110 /// and behaves outwardly as a single observer.
111 ///
112 /// It is crucial to note that this class does not keep strong bindings to
113 /// observables it observes. However, strong references are kept to its own
114 /// observers, for simplicity (assuming that instances of this class are
115 /// kept private and not leaked outside their owner, memory leaks
116 /// should not result).
117 ///
118 /// Unsubscribers for CO itself do not hold a strong reference to the
119 /// CollatingObserver, but hold a reference to the individual observer for
120 /// removal.
121 /// </summary>
122 public class CollatingObserver<T> : IObservable<CollatedObserverData<T>>
123 {
124 /// <summary>
125 /// Observers that we currently hold
126 /// </summary>
127 private readonly List<IObserver<CollatedObserverData<T>>> observers;
128
129 /// <summary>
130 /// Simple initializer, no observers added
131 /// </summary>
132 public CollatingObserver()
133 => this.observers = new List<IObserver<CollatedObserverData<T>>>();
134
135 /// <summary>
136 /// Includes a given observable to the collation, ensuring that it is
137 /// reported by this observer as long as the source exists.
138 ///
139 /// This observer has the crucial property that it does not hold a
140 /// strong reference to the observed object - ensure that this
141 /// reference exists somewhere else.
142 /// </summary>
143 /// <param name="observable">Observable to add</param>
144 /// <returns>Disposable for removing this observable</returns>
145 public IDisposable IncludeInObservation(IObservable<T> observable)
146 {
147 var iso = new InternalSingleObserver(observable, this);
148 return iso;
149 }
150
151 /// <summary>
152 /// Dispatches data onwards to our group of observers,
153 /// simultaneously locking the observer list
154 /// </summary>
155 /// <param name="data">Data to dispatch</param>
156 protected void Dispatch(CollatedObserverData<T> data)
157 {
158 if (data == null)
159 throw new ArgumentNullException("data");
160
161 lock (this.observers)
162 {
163 foreach (IObserver<CollatedObserverData<T>> observer
164 in this.observers)
165 {
166 observer.OnNext(data);
167 }
168 }
169 }
170
171 #region Observation support
172 /// <summary>
173 /// Subscribes an observer to this class,
174 /// and returns an unsubscriber object
175 /// </summary>
176 /// <param name="observer">Observer to add</param>
177 /// <returns>Unsubscriber in the form of an IDisposable </returns>
178 public IDisposable
179 Subscribe(IObserver<CollatedObserverData<T>> observer)
180 {
181 lock (this.observers)
182 {
183 this.observers.Add(
184 observer
185 ?? throw new
186 ArgumentNullException(
187 "observer",
188 "Observer may not be null"
189 )
190 );
191 return new COUnsubscriber(observer, this.observers);
192 }
193
194 }
195
196 /// <summary>
197 /// Helper class for unsubscribing from a CO
198 /// </summary>
199 private class COUnsubscriber : IDisposable
200 {
201 /// <summary>
202 /// Who is observing us?
203 /// </summary>
204 private IObserver<CollatedObserverData<T>> _observedBy;
205
206 /// <summary>
207 /// What collection we bind to?
208 /// </summary>
209 private readonly
210 WeakReference<List<IObserver<CollatedObserverData<T>>>>
211 _backingObserverCollection;
212
213 /// <summary>
214 /// Construct a new unsubscriber
215 /// </summary>
216 /// <param name="observed_by">Who observes</param>
217 /// <param name="collection">Where we hold observers?</param>
218 public COUnsubscriber(
219 IObserver<CollatedObserverData<T>> observed_by,
220 List<IObserver<CollatedObserverData<T>>> collection)
221 {
222 this._observedBy = observed_by;
223 this._backingObserverCollection
224 = new WeakReference<List<IObserver<CollatedObserverData<T>>>>(collection);
225 }
226
227 public void Dispose()
228 {
229 // Try to get reference to the collection of observers
230 // If we hold an observer, try to remove
231 if (this._observedBy != null
232 && this._backingObserverCollection.TryGetTarget(
233 out List<IObserver<CollatedObserverData<T>>>
234 strongCollection
235 ))
236 {
237 lock (strongCollection)
238 {
239 strongCollection.Remove(this._observedBy);
240 }
241 }
242
243 // We've done our job, set observer to null
244 this._observedBy = null;
245 }
246 }
247
248 #endregion
249
250 /// <summary>
251 /// An internal single observer; holds information about its origin
252 /// with a weak reference. However, the collating observer is held
253 /// with a strong reference.
254 /// </summary>
255 private class InternalSingleObserver : IObserver<T>, IDisposable
256 {
257 private readonly WeakReference<IObservable<T>> origin;
258 private readonly CollatingObserver<T> target;
259 private readonly IDisposable subscriptionDisposal;
260
261 private readonly bool disposed = false;
262 /// <summary>
263 /// Creates a new internal, single origin observer
264 /// </summary>
265 /// <param name="origin">What origin we report</param>
266 /// <param name="target">
267 /// What collecting delegate observer
268 /// is our target
269 /// </param>
270 public InternalSingleObserver(
271 IObservable<T> origin,
272 CollatingObserver<T> target
273 )
274 {
275 this.origin = new WeakReference<IObservable<T>>(origin);
276 this.subscriptionDisposal = origin.Subscribe(this);
277 this.target = target;
278 }
279
280 public void OnCompleted()
281 {
282
283 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
284 {
285 this.target.Dispatch(
286 new CollatedObserverData<T>(origin: strongOrigin)
287 );
288 }
289 else
290 {
291 // Lost our contact, dispose
292 this.Dispose();
293 }
294 }
295
296 public void OnError(Exception error)
297 {
298
299 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
300 {
301 this.target.Dispatch(
302 new CollatedObserverData<T>(
303 origin: strongOrigin,
304 exception: error
305 )
306 );
307 }
308 else
309 {
310 // Lost our contact, dispose
311 this.Dispose();
312 }
313 }
314
315 public void OnNext(T value)
316 {
317
318 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
319 {
320 this.target.Dispatch(
321 new CollatedObserverData<T>(
322 origin: strongOrigin,
323 data: value)
324 );
325 }
326 else
327 {
328 // Lost our contact, dispose
329 this.Dispose();
330 }
331 }
332
333 public void Dispose()
334 {
335 if (!this.disposed)
336 {
337 this.subscriptionDisposal.Dispose();
338 }
339 }
340 }
341 }
342}
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/Shared/CollectingObserver.cs
(0 / 343)
  
1using System;
2using System.Collections.Generic;
3
4/// Copyright 2019 Mari Kasanen, Leevi Liimatainen, Marina Mustonen,
5/// Juhani Sundell, Arttu Ylä-Sahra
6///
7/// Redistribution and use in source and binary forms, with
8/// or without modification, are permitted provided that the
9/// following conditions are met:
10///
11/// 1. Redistributions of source code must retain the above copyright
12/// notice, this list of conditions and the following disclaimer.
13///
14/// 2. Redistributions in binary form must reproduce the above copyright
15/// notice, this list of conditions and the following disclaimer in the
16/// documentation and/or other materials provided with the distribution.
17///
18/// 3. Neither the name of the copyright holder nor the names of its
19/// contributors may be used to endorse or promote products derived from
20/// this software without specific prior written permission.
21///
22/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25/// FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26///
27/// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28/// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29/// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30/// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31/// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32/// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33/// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34/// POSSIBILITY OF SUCH DAMAGE.
35
36
37namespace Ajolabra.Backend.DeviceComponents.Shared
38{
39
40 public enum CDOEventType
41 {
42 NormalEvent,
43 Exception,
44 Completed
45 }
46
47 /// <summary>
48 /// A storage class for collated data as collected from many sources;
49 /// either holds data or an exception, as indicated by the inner type.
50 /// </summary>
51 /// <typeparam name="T">Inner type</typeparam>
52 public class CollatedObserverData<T>
53 {
54 public CollatedObserverData(object origin, T data)
55 {
56 this.Type = CDOEventType.NormalEvent;
57 this.Origin = origin
58 ?? throw new ArgumentNullException(
59 "origin",
60 "Origin may not be null"
61 );
62 this.Data = data;
63 this.Exception = null;
64 }
65
66 public CollatedObserverData(object origin, Exception exception)
67 {
68 this.Type = CDOEventType.Exception;
69 this.Origin = origin
70 ?? throw new ArgumentNullException(
71 "origin",
72 "Origin may not be null"
73 );
74 this.Data = default(T);
75 this.Exception = exception;
76 }
77
78 public CollatedObserverData(object origin)
79 {
80 this.Type = CDOEventType.Completed;
81 this.Origin = origin
82 ?? throw new ArgumentNullException(
83 "origin",
84 "Origin may not be null"
85 );
86 this.Data = default(T);
87 this.Exception = null;
88 }
89
90 public object Origin
91 {
92 get; private set;
93 }
94 public CDOEventType Type
95 {
96 get; private set;
97 }
98 public T Data
99 {
100 get; private set;
101 }
102 public Exception Exception
103 {
104 get; private set;
105 }
106 }
107
108 /// <summary>
109 /// A helper class; collects observer data from multiple origins,
110 /// and behaves outwardly as a single observer.
111 ///
112 /// It is crucial to note that this class does not keep strong bindings to
113 /// observables it observes. However, strong references are kept to its own
114 /// observers, for simplicity (assuming that instances of this class are
115 /// kept private and not leaked outside their owner, memory leaks
116 /// should not result).
117 ///
118 /// Unsubscribers for CO itself do not hold a strong reference to the
119 /// CollatingObserver, but hold a reference to the individual observer for
120 /// removal.
121 /// </summary>
122 public class CollatingObserver<T> : IObservable<CollatedObserverData<T>>
123 {
124 /// <summary>
125 /// Observers that we currently hold
126 /// </summary>
127 private readonly List<IObserver<CollatedObserverData<T>>> observers;
128
129 /// <summary>
130 /// Simple initializer, no observers added
131 /// </summary>
132 public CollatingObserver()
133 => this.observers = new List<IObserver<CollatedObserverData<T>>>();
134
135 /// <summary>
136 /// Includes a given observable to the collation, ensuring that it is
137 /// reported by this observer as long as the source exists.
138 ///
139 /// This observer has the crucial property that it does not hold a
140 /// strong reference to the observed object - ensure that this
141 /// reference exists somewhere else.
142 /// </summary>
143 /// <param name="observable">Observable to add</param>
144 /// <returns>Disposable for removing this observable</returns>
145 public IDisposable IncludeInObservation(IObservable<T> observable)
146 {
147 var iso = new InternalSingleObserver(observable, this);
148 return iso;
149 }
150
151 /// <summary>
152 /// Dispatches data onwards to our group of observers,
153 /// simultaneously locking the observer list
154 /// </summary>
155 /// <param name="data">Data to dispatch</param>
156 protected void Dispatch(CollatedObserverData<T> data)
157 {
158 if (data == null)
159 throw new ArgumentNullException("data");
160
161 lock (this.observers)
162 {
163 foreach (IObserver<CollatedObserverData<T>> observer
164 in this.observers)
165 {
166 observer.OnNext(data);
167 }
168 }
169 }
170
171 #region Observation support
172 /// <summary>
173 /// Subscribes an observer to this class,
174 /// and returns an unsubscriber object
175 /// </summary>
176 /// <param name="observer">Observer to add</param>
177 /// <returns>Unsubscriber in the form of an IDisposable </returns>
178 public IDisposable
179 Subscribe(IObserver<CollatedObserverData<T>> observer)
180 {
181 lock (this.observers)
182 {
183 this.observers.Add(
184 observer
185 ?? throw new
186 ArgumentNullException(
187 "observer",
188 "Observer may not be null"
189 )
190 );
191 return new COUnsubscriber(observer, this.observers);
192 }
193
194 }
195
196 /// <summary>
197 /// Helper class for unsubscribing from a CO
198 /// </summary>
199 private class COUnsubscriber : IDisposable
200 {
201 /// <summary>
202 /// Who is observing us?
203 /// </summary>
204 private IObserver<CollatedObserverData<T>> _observedBy;
205
206 /// <summary>
207 /// What collection we bind to?
208 /// </summary>
209 private readonly
210 WeakReference<List<IObserver<CollatedObserverData<T>>>>
211 _backingObserverCollection;
212
213 /// <summary>
214 /// Construct a new unsubscriber
215 /// </summary>
216 /// <param name="observed_by">Who observes</param>
217 /// <param name="collection">Where we hold observers?</param>
218 public COUnsubscriber(
219 IObserver<CollatedObserverData<T>> observed_by,
220 List<IObserver<CollatedObserverData<T>>> collection)
221 {
222 this._observedBy = observed_by;
223 this._backingObserverCollection
224 = new WeakReference<List<IObserver<CollatedObserverData<T>>>>(collection);
225 }
226
227 public void Dispose()
228 {
229 // Try to get reference to the collection of observers
230 // If we hold an observer, try to remove
231 if (this._observedBy != null
232 && this._backingObserverCollection.TryGetTarget(
233 out List<IObserver<CollatedObserverData<T>>>
234 strongCollection
235 ))
236 {
237 lock (strongCollection)
238 {
239 strongCollection.Remove(this._observedBy);
240
241 }
242 }
243
244 // We've done our job, set observer to null
245 this._observedBy = null;
246 }
247 }
248
249 #endregion
250
251 /// <summary>
252 /// An internal single observer; holds information about its origin
253 /// with a weak reference. However, the collating observer is held
254 /// with a strong reference.
255 /// </summary>
256 private class InternalSingleObserver : IObserver<T>, IDisposable
257 {
258 private readonly WeakReference<IObservable<T>> origin;
259 private readonly CollatingObserver<T> target;
260 private readonly IDisposable subscriptionDisposal;
261
262 private readonly bool disposed = false;
263 /// <summary>
264 /// Creates a new internal, single origin observer
265 /// </summary>
266 /// <param name="origin">What origin we report</param>
267 /// <param name="target">
268 /// What collecting delegate observer
269 /// is our target
270 /// </param>
271 public InternalSingleObserver(
272 IObservable<T> origin,
273 CollatingObserver<T> target
274 )
275 {
276 this.origin = new WeakReference<IObservable<T>>(origin);
277 this.subscriptionDisposal = origin.Subscribe(this);
278 this.target = target;
279 }
280
281 public void OnCompleted()
282 {
283
284 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
285 {
286 this.target.Dispatch(
287 new CollatedObserverData<T>(origin: strongOrigin)
288 );
289 }
290 else
291 {
292 // Lost our contact, dispose
293 this.Dispose();
294 }
295 }
296
297 public void OnError(Exception error)
298 {
299
300 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
301 {
302 this.target.Dispatch(
303 new CollatedObserverData<T>(
304 origin: strongOrigin,
305 exception: error
306 )
307 );
308 }
309 else
310 {
311 // Lost our contact, dispose
312 this.Dispose();
313 }
314 }
315
316 public void OnNext(T value)
317 {
318
319 if (this.origin.TryGetTarget(out IObservable<T> strongOrigin))
320 {
321 this.target.Dispatch(
322 new CollatedObserverData<T>(
323 origin: strongOrigin,
324 data: value)
325 );
326 }
327 else
328 {
329 // Lost our contact, dispose
330 this.Dispose();
331 }
332 }
333
334 public void Dispose()
335 {
336 if (!this.disposed)
337 {
338 this.subscriptionDisposal.Dispose();
339 }
340 }
341 }
342 }
343}
sovellus/vs/Ajolabra/ALBackend/DeviceComponents/Shared/TCPUDPRawLineReader.cs
(5 / 9)
  
343343 /// <param name="inputPort">Port to connect to/listen to</param>
344344 /// <param name="hostname">Hostname to connect to. Must be null if not in TCPServer mode</param>
345345 /// <param name="flags">Flags to use</param>
346 public TCPUDPRawLineReader(BlockingCollection<Dictionary<string, IDataElement>>[] dataElementOutputQueues, LRReadMode mode, int inputPort, string hostname, LRFlags flags) : base(dataElementOutputQueues)
346 public TCPUDPRawLineReader(BlockingCollection<Dictionary<
347 string, IDataElement>>[] dataElementOutputQueues,
348 LRReadMode mode, int inputPort,
349 string hostname, LRFlags flags)
350 : base(dataElementOutputQueues)
347351 {
348352 this.Mode = mode;
349353 this.Port = inputPort;
527527 this.networkEndpoint?.Dispose();
528528 }
529529
530
531530 this.disposedValue = true;
532531 }
533532 }
534533
535 // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
536 // ~TCPUDPRawLineReader() {
537 // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
538 // Dispose(false);
539 // }
540
541534 // This code added to correctly implement the disposable pattern.
542535 public void Dispose()
543536 {
544537 // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
545538 this.Dispose(true);
546
547539 }
548540 #endregion
549541 }
sovellus/vs/Ajolabra/ALBackend/IModuleWrapper.cs
(3 / 1)
  
104104 /// This functionality provides an ability to do so, assuming we have
105105 /// data originated from this module available.
106106 ///
107 /// OBS!
107108 /// After redesign, this is no longer required by the interface,
108109 /// but has been left here for historical posterity.
109110 /// </summary>
110111 /// <param name="data">Data to synchronize</param>
111112 /// <returns>Appropriate canonical time determiner</returns>
112113 ///
113 /// Synchronization.DataCombiner.CanonicalTimeDeterminer GetCTDForDataset(IEnumerable<Dictionary<string, IDataElement>> data);
114 /// Synchronization.DataCombiner.CanonicalTimeDeterminer
115 /// GetCTDForDataset(IEnumerable<Dictionary<string, IDataElement>> data);
114116
115117 }
116118}