@@ -23,6 +23,8 @@ public enum UserDecision
2323 StartApp
2424 }
2525
26+ #region Private fields
27+
2628 private static readonly DebugLogger DebugLogger = new DebugLogger ( typeof ( Patcher ) ) ;
2729
2830 public static Patcher Instance { get ; private set ; }
@@ -35,7 +37,9 @@ public enum UserDecision
3537
3638 private App _app ;
3739
38- private bool _hasBeenDestroyed ;
40+ private bool _keepThreadAlive ;
41+
42+ private bool _isThreadBeingDestroyed ;
3943
4044 private UserDecision _userDecision = UserDecision . None ;
4145
@@ -49,10 +53,9 @@ public enum UserDecision
4953
5054 private CancellationTokenSource _cancellationTokenSource ;
5155
52- public PatcherData Data
53- {
54- get { return _data ; }
55- }
56+ #endregion
57+
58+ #region Events
5659
5760 public event Action < OverallStatus > UpdateAppStatusChanged ;
5861
@@ -66,23 +69,21 @@ public PatcherData Data
6669
6770 public event Action < bool > CanCheckInternetConnectionChanged ;
6871
72+ #endregion
73+
74+ #region Public fields
75+
6976 public string EditorAppSecret ;
7077
7178 public int EditorOverrideLatestVersionId ;
7279
7380 public PatcherConfiguration DefaultConfiguration ;
7481
75- private PatcherState _state = PatcherState . None ;
82+ #endregion
7683
77- public PatcherState State
78- {
79- get { return _state ; }
80- set
81- {
82- _state = value ;
83- OnStateChanged ( _state ) ;
84- }
85- }
84+ #region Public properties
85+
86+ #region Decisions availability
8687
8788 private bool _canUpdateApp ;
8889
@@ -123,9 +124,29 @@ public bool CanCheckInternetConnection
123124 }
124125 }
125126
126- private PatcherError _error ;
127+ #endregion
128+
129+ private PatcherState _state = PatcherState . None ;
130+
131+ public PatcherState State
132+ {
133+ get { return _state ; }
134+ set
135+ {
136+ _state = value ;
137+ OnStateChanged ( _state ) ;
138+ }
139+ }
140+
127141 private PatcherData _data ;
128142
143+ public PatcherData Data
144+ {
145+ get { return _data ; }
146+ }
147+
148+ private PatcherError _error ;
149+
129150 public PatcherError Error
130151 {
131152 get { return _error ; }
@@ -136,6 +157,10 @@ public PatcherError Error
136157 }
137158 }
138159
160+ #endregion
161+
162+ #region Public methods
163+
139164 public void SetUserDecision ( UserDecision userDecision )
140165 {
141166 DebugLogger . Log ( "Setting user deicision." ) ;
@@ -181,6 +206,10 @@ public void Cancel()
181206 }
182207 }
183208
209+ #endregion
210+
211+ #region Logging operations
212+
184213 private void LogSystemInfo ( )
185214 {
186215 DebugLogger . LogVariable ( Environment . Version , "Environment.Version" ) ;
@@ -204,16 +233,21 @@ private void LogPatcherInfo()
204233 DebugLogger . Log ( string . Format ( "Patcher version - {0}" , GetPatcherVersion ( ) ) ) ;
205234 }
206235
236+ #endregion
237+
238+ #region Unity events
239+
207240 private void Awake ( )
208241 {
209242 DebugLogger . Log ( "Awake Unity event." ) ;
210243
211- LogSystemInfo ( ) ;
212- LogPatcherInfo ( ) ;
213-
214244 Instance = this ;
215245 Dispatcher . Initialize ( ) ;
216246 Application . runInBackground = true ;
247+
248+ LogSystemInfo ( ) ;
249+ LogPatcherInfo ( ) ;
250+
217251 try
218252 {
219253 LoadPatcherData ( ) ;
@@ -232,57 +266,116 @@ private void Start()
232266 DebugLogger . Log ( "Start Unity event." ) ;
233267
234268 DebugLogger . Log ( "Starting patcher thread." ) ;
269+
270+ _keepThreadAlive = true ;
235271 _thread = new Thread ( ThreadFunc ) ;
236272 _thread . Start ( ) ;
237273 }
238274
275+ private void OnApplicationQuit ( )
276+ {
277+ DebugLogger . Log ( "OnApplicationQuit Unity event." ) ;
278+
279+ if ( _thread != null && _thread . IsAlive )
280+ {
281+ DebugLogger . Log ( "Cancelling quit because patcher thread is still alive." ) ;
282+
283+ Application . CancelQuit ( ) ;
284+ StartCoroutine ( DestroyPatcherThreadAndQuit ( ) ) ;
285+ }
286+ }
287+
239288 private void OnDestroy ( )
240289 {
241290 DebugLogger . Log ( "OnDestroy Unity event." ) ;
242291
243- if ( _app != null )
292+ if ( _thread != null && _thread . IsAlive )
244293 {
245- _app . Dispose ( ) ;
294+ DestroyPatcherThread ( ) ;
246295 }
296+ }
247297
248- DebugLogger . Log ( "Cleaning up thread." ) ;
249-
250- _hasBeenDestroyed = true ;
298+ private void DestroyPatcherThread ( )
299+ {
300+ DebugLogger . Log ( "Destroying patcher thread." ) ;
251301
252- if ( _thread != null && _thread . IsAlive )
302+ while ( _thread != null && _thread . IsAlive )
253303 {
254- while ( _thread . IsAlive )
255- {
256- Cancel ( ) ;
304+ DebugLogger . Log ( "Trying to safely destroy patcher thread." ) ;
305+
306+ _keepThreadAlive = false ;
307+ Cancel ( ) ;
308+ _thread . Interrupt ( ) ;
257309
258- DebugLogger . Log ( "Interrupting thread." ) ;
310+ _thread . Join ( 1000 ) ;
259311
260- _thread . Interrupt ( ) ;
261-
312+ if ( _thread . IsAlive )
313+ {
314+ DebugLogger . Log ( "Trying to force destroy patcher thread." ) ;
315+
316+ _thread . Abort ( ) ;
262317 _thread . Join ( 1000 ) ;
318+ }
319+ }
263320
264- if ( _thread . IsAlive )
265- {
266- while ( _thread . IsAlive )
267- {
268- DebugLogger . Log ( "Aborting thread." ) ;
321+ DebugLogger . Log ( "Patcher thread has been destroyed." ) ;
322+ }
269323
270- _thread . Abort ( ) ;
271- _thread . Join ( 1000 ) ;
272- }
324+ private IEnumerator DestroyPatcherThreadAndQuit ( )
325+ {
326+ DebugLogger . Log ( "Destroying patcher thread." ) ;
327+
328+ if ( _isThreadBeingDestroyed )
329+ {
330+ DebugLogger . Log ( "Patcher thread is already being destroyed." ) ;
331+ yield break ;
332+ }
333+
334+ _isThreadBeingDestroyed = true ;
335+
336+ while ( _thread != null && _thread . IsAlive )
337+ {
338+ DebugLogger . Log ( "Trying to safely destroy patcher thread." ) ;
339+
340+ _keepThreadAlive = false ;
341+ Cancel ( ) ;
342+ _thread . Interrupt ( ) ;
343+
344+ float startTime = Time . unscaledTime ;
345+ while ( Time . unscaledTime - startTime < 1.0f && _thread . IsAlive )
346+ {
347+ yield return null ;
348+ }
349+
350+ if ( _thread . IsAlive )
351+ {
352+ DebugLogger . Log ( "Trying to force destroy patcher thread." ) ;
353+
354+ _thread . Abort ( ) ;
355+ startTime = Time . unscaledTime ;
356+ while ( Time . unscaledTime - startTime < 1.0f && _thread . IsAlive )
357+ {
358+ yield return null ;
273359 }
274360 }
275361 }
362+
363+ DebugLogger . Log ( "Patcher thread has been destroyed. Quitting application." ) ;
364+ Application . Quit ( ) ;
276365 }
277366
367+ #endregion
368+
369+ #region Thread
370+
278371 private void ThreadFunc ( )
279372 {
280373 try
281374 {
282375 CheckInternetConnection ( ) ;
283376 LoadPatcherConfiguration ( ) ;
284377
285- while ( ! _hasBeenDestroyed )
378+ while ( _keepThreadAlive )
286379 {
287380 try
288381 {
@@ -307,6 +400,7 @@ private void ThreadFunc()
307400 }
308401 catch ( OperationCanceledException )
309402 {
403+ DebugLogger . Log ( "Patcher has been cancelled." ) ;
310404 }
311405 catch ( UnauthorizedAccessException )
312406 {
@@ -336,16 +430,25 @@ private void ThreadFunc()
336430 {
337431 DebugLogger . Log ( "Thread has been interrupted." ) ;
338432 }
339- catch ( ThreadAbortException )
433+ catch ( ThreadAbortException )
340434 {
341435 DebugLogger . Log ( "Thread has been aborted." ) ;
342436 }
343- catch ( Exception exception )
437+ catch ( Exception exception )
344438 {
345439 DebugLogger . LogException ( exception ) ;
346440 DebugLogger . LogError ( "Exception in patcher thread." ) ;
347441 Quit ( ) ;
348442 }
443+ finally
444+ {
445+ if ( _app != null )
446+ {
447+ _app . Dispose ( ) ;
448+ }
449+
450+ DebugLogger . Log ( "Patcher thread has been destroyed." ) ;
451+ }
349452 }
350453
351454 private void LoadPatcherData ( )
@@ -501,6 +604,10 @@ private void HandleErrorMessage(Exception exception)
501604 _errorMessageHandled . WaitOne ( ) ;
502605 }
503606
607+ #endregion
608+
609+ #region Event invokers
610+
504611 protected virtual void OnUpdateAppStatusChanged ( OverallStatus obj )
505612 {
506613 Dispatcher . Invoke ( ( ) =>
@@ -548,5 +655,7 @@ protected virtual void OnCanCheckInternetConnectionChanged(bool obj)
548655 if ( CanCheckInternetConnectionChanged != null ) CanCheckInternetConnectionChanged ( obj ) ;
549656 } ) ;
550657 }
658+
659+ #endregion
551660 }
552661}
0 commit comments