Add engine fatal error types handling
Add general out-of-memory handling Add safety memory buffer for crash or out of memory handling Refactor Globals exit/error state to be in Engine class
This commit is contained in:
@@ -71,6 +71,9 @@ Action Engine::Draw;
|
||||
Action Engine::Pause;
|
||||
Action Engine::Unpause;
|
||||
Action Engine::RequestingExit;
|
||||
FatalErrorType Engine::FatalError = FatalErrorType::None;
|
||||
bool Engine::IsRequestingExit = false;
|
||||
int32 Engine::ExitCode = 0;
|
||||
Window* Engine::MainWindow = nullptr;
|
||||
|
||||
int32 Engine::Main(const Char* cmdLine)
|
||||
@@ -201,7 +204,7 @@ int32 Engine::Main(const Char* cmdLine)
|
||||
PROFILE_CPU_NAMED("Platform.Tick");
|
||||
Platform::Tick();
|
||||
}
|
||||
|
||||
|
||||
// Update game logic
|
||||
if (Time::OnBeginUpdate(time))
|
||||
{
|
||||
@@ -236,12 +239,13 @@ int32 Engine::Main(const Char* cmdLine)
|
||||
FileSystem::DeleteDirectory(Globals::TemporaryFolder);
|
||||
}
|
||||
|
||||
return Globals::ExitCode;
|
||||
return ExitCode;
|
||||
}
|
||||
|
||||
void Engine::Exit(int32 exitCode)
|
||||
void Engine::Exit(int32 exitCode, FatalErrorType error)
|
||||
{
|
||||
ASSERT(IsInMainThread());
|
||||
FatalError = error;
|
||||
|
||||
// Call on exit event
|
||||
OnExit();
|
||||
@@ -250,23 +254,23 @@ void Engine::Exit(int32 exitCode)
|
||||
exit(exitCode);
|
||||
}
|
||||
|
||||
void Engine::RequestExit(int32 exitCode)
|
||||
void Engine::RequestExit(int32 exitCode, FatalErrorType error)
|
||||
{
|
||||
if (Globals::IsRequestingExit)
|
||||
if (IsRequestingExit)
|
||||
return;
|
||||
#if USE_EDITOR
|
||||
// Send to editor (will leave play mode if need to)
|
||||
if (Editor::Managed->OnAppExit())
|
||||
{
|
||||
Globals::IsRequestingExit = true;
|
||||
Globals::ExitCode = exitCode;
|
||||
RequestingExit();
|
||||
}
|
||||
#else
|
||||
if (!Editor::Managed->OnAppExit())
|
||||
return;
|
||||
#endif
|
||||
IsRequestingExit = true;
|
||||
ExitCode = exitCode;
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS;
|
||||
Globals::IsRequestingExit = true;
|
||||
Globals::ExitCode = exitCode;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS;
|
||||
FatalError = error;
|
||||
RequestingExit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Engine::OnFixedUpdate()
|
||||
@@ -407,7 +411,7 @@ bool Engine::IsReady()
|
||||
|
||||
bool Engine::ShouldExit()
|
||||
{
|
||||
return Globals::IsRequestingExit;
|
||||
return IsRequestingExit;
|
||||
}
|
||||
|
||||
bool Engine::IsEditor()
|
||||
|
||||
@@ -14,9 +14,9 @@ class JsonAsset;
|
||||
/// </summary>
|
||||
API_CLASS(Static) class FLAXENGINE_API Engine
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Engine);
|
||||
public:
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Engine);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The engine start time (local time).
|
||||
/// </summary>
|
||||
@@ -38,7 +38,6 @@ public:
|
||||
API_FIELD(ReadOnly) static uint64 FrameCount;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Event called on engine fixed update.
|
||||
/// </summary>
|
||||
@@ -84,8 +83,22 @@ public:
|
||||
/// </summary>
|
||||
API_EVENT() static Action RequestingExit;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The current state of the fatal error. Set to None if no error occurred yet.
|
||||
/// </summary>
|
||||
API_FIELD(ReadOnly) static FatalErrorType FatalError;
|
||||
|
||||
/// <summary>
|
||||
/// Flags set to true if engine needs to be closed (exit is pending). Use FatalError to determinate the exit reason (specific error or normal shutdown).
|
||||
/// </summary>
|
||||
API_FIELD(ReadOnly) static bool IsRequestingExit;
|
||||
|
||||
/// <summary>
|
||||
/// The current process exit code (pending to return).
|
||||
/// </summary>
|
||||
static int32 ExitCode;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The main engine function (must be called from platform specific entry point).
|
||||
/// </summary>
|
||||
@@ -97,16 +110,17 @@ public:
|
||||
/// Exits the engine.
|
||||
/// </summary>
|
||||
/// <param name="exitCode">The exit code.</param>
|
||||
API_FUNCTION(Attributes="DebugCommand") static void Exit(int32 exitCode = -1);
|
||||
/// <param name="error">The fatal error type (or None on graceful exit).</param>
|
||||
API_FUNCTION(Attributes="DebugCommand") static void Exit(int32 exitCode = -1, FatalErrorType error = FatalErrorType::None);
|
||||
|
||||
/// <summary>
|
||||
/// Requests normal engine exit.
|
||||
/// </summary>
|
||||
/// <param name="exitCode">The exit code.</param>
|
||||
API_FUNCTION() static void RequestExit(int32 exitCode = 0);
|
||||
/// <param name="error">The fatal error type (or None on graceful exit).</param>
|
||||
API_FUNCTION() static void RequestExit(int32 exitCode = 0, FatalErrorType error = FatalErrorType::None);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Fixed update callback used by the physics simulation (fixed stepping).
|
||||
/// </summary>
|
||||
@@ -138,7 +152,6 @@ public:
|
||||
static void OnExit();
|
||||
|
||||
public:
|
||||
|
||||
// Returns true if engine is running without main window (aka headless mode).
|
||||
API_PROPERTY() static bool IsHeadless();
|
||||
|
||||
@@ -184,7 +197,6 @@ public:
|
||||
API_PROPERTY() static bool HasGameViewportFocus();
|
||||
|
||||
private:
|
||||
|
||||
static void OnPause();
|
||||
static void OnUnpause();
|
||||
};
|
||||
|
||||
@@ -18,9 +18,11 @@ String Globals::ProjectContentFolder;
|
||||
#if USE_MONO
|
||||
String Globals::MonoPath;
|
||||
#endif
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS;
|
||||
bool Globals::FatalErrorOccurred;
|
||||
bool Globals::IsRequestingExit;
|
||||
int32 Globals::ExitCode;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS;
|
||||
uint64 Globals::MainThreadID;
|
||||
String Globals::EngineVersion(TEXT(FLAXENGINE_VERSION_TEXT));
|
||||
int32 Globals::EngineBuildNumber = FLAXENGINE_VERSION_BUILD;
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
/// </summary>
|
||||
API_CLASS(Static, Attributes="DebugCommand") class FLAXENGINE_API Globals
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
|
||||
|
||||
public:
|
||||
// Paths
|
||||
|
||||
// Main engine directory path.
|
||||
@@ -34,7 +35,6 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
|
||||
API_FIELD(ReadOnly) static String BinariesFolder;
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
// Project specific cache folder path (editor-only).
|
||||
API_FIELD(ReadOnly) static String ProjectCacheFolder;
|
||||
|
||||
@@ -43,43 +43,60 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
|
||||
|
||||
// Game source code directory path (editor-only).
|
||||
API_FIELD(ReadOnly) static String ProjectSourceFolder;
|
||||
|
||||
#endif
|
||||
|
||||
// Project content directory path
|
||||
// Project content directory path.
|
||||
API_FIELD(ReadOnly) static String ProjectContentFolder;
|
||||
|
||||
#if USE_MONO
|
||||
// Mono library folder path
|
||||
// Mono library folder path.
|
||||
API_FIELD(ReadOnly) static String MonoPath;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// State
|
||||
|
||||
// True if fatal error occurred (engine is exiting)
|
||||
static bool FatalErrorOccurred;
|
||||
// True if fatal error occurred (engine is exiting).
|
||||
// [Deprecated in v1.10]
|
||||
static DEPRECATED("Use Engine::FatalError instead.") bool FatalErrorOccurred;
|
||||
|
||||
// True if engine needs to be closed
|
||||
static bool IsRequestingExit;
|
||||
// True if engine needs to be closed.
|
||||
// [Deprecated in v1.10]
|
||||
static DEPRECATED("Use Engine::IsRequestingExit instead.") bool IsRequestingExit;
|
||||
|
||||
/// <summary>
|
||||
/// True if engine needs to be closed
|
||||
/// Flags set to true if engine needs to be closed (exit is pending).
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE static bool GetIsRequestingExit() { return IsRequestingExit; }
|
||||
API_PROPERTY() DEPRECATED("Use Engine::IsRequestingExit instead.") FORCE_INLINE static bool GetIsRequestingExit()
|
||||
{
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS;
|
||||
return IsRequestingExit;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if fatal error occurred (engine is exiting)
|
||||
/// Flags set to true if fatal error occurred (engine is exiting).
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE static bool GetFatalErrorOccurred() { return FatalErrorOccurred; }
|
||||
API_PROPERTY() DEPRECATED("Use Engine::FatalError instead.") FORCE_INLINE static bool GetFatalErrorOccurred()
|
||||
{
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS;
|
||||
return FatalErrorOccurred;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS;
|
||||
}
|
||||
|
||||
// Exit code
|
||||
static int32 ExitCode;
|
||||
// Process exit code (pending to return).
|
||||
// [Deprecated in v1.10]
|
||||
static DEPRECATED("Use Engine::ExitCode instead.") int32 ExitCode;
|
||||
|
||||
public:
|
||||
// Threading
|
||||
|
||||
// Main Engine thread id
|
||||
// Main Engine thread id.
|
||||
API_FIELD(ReadOnly) static uint64 MainThreadID;
|
||||
|
||||
public:
|
||||
// Config
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user