//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Threading.Tasks;

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// Critical (unbreakable) code-block
/// </summary>
/// <remarks>
/// Any exception inside critical code will cause fatal error, that means OS-process termination or throwing of “EFatalError” (depending on fatal error configuration).
/// </remarks>
public static partial class critical {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static string CauseMessage =>
   "Unexpected exception in critical (unbreakable) code-block has occured.";

//==================================================================================================

[u.fatal_error_on_failure]
public static void Do( Action body )
{
   try {
      body();
   }
   catch ( Exception e ) {
      throw RaiseError( e );
   }
}

[u.fatal_error_on_failure]
public static R Do<R>( Func<R> bodyFN )
{
   try {
      return bodyFN();
   }
   catch ( Exception e ) {
      throw RaiseError( e );
   }
}

//==================================================================================================

[u.fatal_error_on_failure]
public static async Task Do_A( Func<Task> actionA )
{
   try {
      await actionA().ConfigureAwait(false);
   }
   catch ( Exception e ) {
      throw RaiseError( e );
   }
}

[u.fatal_error_on_failure]
public static async Task<R> Do_A<R>( Func<Task<R>> functionA )
{
   try {
      return await functionA().ConfigureAwait(false);
   }
   catch ( Exception e ) {
      throw RaiseError( e );
   }
}

//==================================================================================================

public static EFake RaiseError( Exception e ) =>
   throw u.fatal.RaiseError( CauseMessage, e );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // critical

} // user_rtx (.wasm)
