// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Engine/Platform/Types.h" #include "Engine/Core/Types/BaseTypes.h" #include struct Guid; struct Version; struct CPUInfo; struct MemoryStats; struct ProcessMemoryStats; struct CreateProcessSettings; struct CreateWindowSettings; struct BatteryInfo; // ReSharper disable CppFunctionIsNotImplemented /// /// Network connection types for device. /// API_ENUM() enum class NetworkConnectionType { /// /// No connection. /// None, /// /// The unknown connection type. /// Unknown, /// /// The airplane mode. /// AirplaneMode, /// /// The cell connection. /// Cell, /// /// The WiFi connection. /// WiFi, /// /// The Bluetooth connection. /// Bluetooth, /// /// The Ethernet cable connection (LAN). /// Ethernet, }; extern FLAXENGINE_API const Char* ToString(NetworkConnectionType value); /// /// The device screen orientation types (eg. portrait, landscape, etc.). /// API_ENUM() enum class ScreenOrientationType { /// /// The unknown orientation type. /// Unknown, /// /// The portrait screen orientation with device bottom on the bottom side of the screen. /// Portrait, /// /// The portrait screen orientation but upside down with device bottom on the top side of the screen. /// PortraitUpsideDown, /// /// The landscape screen orientation with device bottom on the right side of the screen (device rotated to the left from the portrait). /// LandscapeLeft, /// /// The landscape screen orientation with device bottom on the left side of the screen (device rotated to the right from the portrait). /// LandscapeRight, }; extern FLAXENGINE_API const Char* ToString(ScreenOrientationType value); /// /// Thread priority levels. /// enum class ThreadPriority { /// /// The normal level. /// Normal, /// /// The above normal level. /// AboveNormal, /// /// The below normal level. /// BelowNormal, /// /// The highest level. /// Highest, /// /// The lowest level. /// Lowest, }; extern FLAXENGINE_API const Char* ToString(ThreadPriority value); /// /// Possible fatal error types that cause engine exit. /// API_ENUM() enum class FatalErrorType { // No fatal error set. None, // Not defined or custom error. Unknown, // Runtime exception caught by the handler (eg. stack overflow, invalid memory address access). Exception, // Data assertion failed (eg. invalid value or code usage). Assertion, // Program run out of memory to allocate. OutOfMemory, // The graphics device crashed, has been removed or restarted. GPUCrash, // The graphics device stopped responding (eg. incorrect rendering code or bug in driver). GPUHang, // The graphics device run out of video memory to allocate. GPUOutOfMemory, }; API_INJECT_CODE(cpp, "#include \"Engine/Platform/Platform.h\""); /// /// Runtime platform service. /// API_CLASS(Static, Name="Platform", Tag="NativeInvokeUseName") class FLAXENGINE_API PlatformBase { DECLARE_SCRIPTING_TYPE_MINIMAL(PlatformBase); /// /// Initializes the runtime platform service. Called on very beginning pf the engine startup. /// /// True if failed ot initialize platform, otherwise false. static bool Init(); /// /// Writes the platform info to the log. Called after platform and logging service init but before engine services initialization. /// static void LogInfo(); /// /// Called just before main game loop start. /// static void BeforeRun(); /// /// Tick platform from game loop by main thread. /// static void Tick(); /// /// Called before engine exit to pre dispose platform service. /// static void BeforeExit(); /// /// Called after engine exit to shutdown platform service. /// static void Exit(); public: /// /// Application windows class name. /// static const Char* ApplicationClassName; public: /// /// Copy memory region /// /// Destination memory address. Must not be null, even if size is zero. /// Source memory address. Must not be null, even if size is zero. /// Size of the memory to copy in bytes FORCE_INLINE static void MemoryCopy(void* dst, const void* src, uint64 size) { memcpy(dst, src, static_cast(size)); } /// /// Set memory region with given value /// /// Destination memory address. Must not be null, even if size is zero. /// Size of the memory to set in bytes /// Value to set FORCE_INLINE static void MemorySet(void* dst, uint64 size, int32 value) { memset(dst, value, static_cast(size)); } /// /// Clear memory region with zeros /// /// Destination memory address. Must not be null, even if size is zero. /// Size of the memory to clear in bytes FORCE_INLINE static void MemoryClear(void* dst, uint64 size) { memset(dst, 0, static_cast(size)); } /// /// Compare two blocks of the memory. /// /// The first buffer address. Must not be null, even if size is zero. /// The second buffer address. Must not be null, even if size is zero. /// Size of the memory to compare in bytes. FORCE_INLINE static int32 MemoryCompare(const void* buf1, const void* buf2, uint64 size) { return memcmp(buf1, buf2, static_cast(size)); } /// /// Creates a hardware memory barrier (fence) that prevents the CPU from re-ordering read and write operations /// static void MemoryBarrier() = delete; /// /// Sets a 64-bit variable to the specified value as an atomic operation. The function prevents more than one thread from using the same variable simultaneously. /// /// A pointer to the first operand. This value will be replaced with the result of the operation. /// The value to exchange. /// The original value of the dst parameter. static int64 InterlockedExchange(int64 volatile* dst, int64 exchange) = delete; /// /// Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison. /// /// The function compares the dst value with the comperand value. If the dst value is equal to the comperand value, the value value is stored in the address specified by dst. Otherwise, no operation is performed. /// A pointer to the first operand. This value will be replaced with the result of the operation. /// The value to exchange. /// The value to compare to destination. /// The original value of the dst parameter. static int32 InterlockedCompareExchange(int32 volatile* dst, int32 exchange, int32 comperand) = delete; /// /// Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison. /// /// The function compares the dst value with the comperand value. If the dst value is equal to the comperand value, the value value is stored in the address specified by dst. Otherwise, no operation is performed. /// A pointer to the first operand. This value will be replaced with the result of the operation. /// The value to exchange. /// The value to compare to destination. /// The original value of the dst parameter. static int64 InterlockedCompareExchange(int64 volatile* dst, int64 exchange, int64 comperand) = delete; /// /// Increments (increases by one) the value of the specified variable as an atomic operation. /// /// A pointer to the variable to be incremented. /// The incremented value of the dst parameter. static int64 InterlockedIncrement(int64 volatile* dst) = delete; /// /// Decrements (decreases by one) the value of the specified variable as an atomic operation. /// /// A pointer to the variable to be decremented. /// The decremented value of the decremented parameter. static int64 InterlockedDecrement(int64 volatile* dst) = delete; /// /// Adds value to the value of the specified variable as an atomic operation. /// /// A pointer to the first operand. This value will be replaced with the result of the operation. /// The second operand. /// The result value of the operation. static int64 InterlockedAdd(int64 volatile* dst, int64 value) = delete; /// /// Performs an atomic 32-bit variable read operation on the specified values. /// /// A pointer to the destination value. /// The function returns the value of the destination parameter. static int32 AtomicRead(int32 const volatile* dst) = delete; /// /// Performs an atomic 64-bit variable read operation on the specified values. /// /// A pointer to the destination value. /// The function returns the value of the destination parameter. static int64 AtomicRead(int64 const volatile* dst) = delete; /// /// Sets a 32-bit variable to the specified value as an atomic operation. /// /// A pointer to the value to be exchanged. /// The value to be set. static void AtomicStore(int32 volatile* dst, int32 value) = delete; /// /// Sets a 64-bit variable to the specified value as an atomic operation. /// /// A pointer to the value to be exchanged. /// The value to be set. static void AtomicStore(int64 volatile* dst, int64 value) = delete; /// /// Indicates to the processor that a cache line will be needed in the near future. /// /// The address of the cache line to be loaded. This address is not required to be on a cache line boundary. static void Prefetch(void const* ptr) = delete; #if COMPILE_WITH_PROFILER static void OnMemoryAlloc(void* ptr, uint64 size); static void OnMemoryFree(void* ptr); #endif /// /// Allocates memory on a specified alignment boundary. /// /// The size of the allocation (in bytes). /// The memory alignment (in bytes). Must be an integer power of 2. /// The pointer to the allocated chunk of the memory. The pointer is a multiple of alignment. static void* Allocate(uint64 size, uint64 alignment) = delete; /// /// Frees a block of allocated memory. /// /// A pointer to the memory block to deallocate. static void Free(void* ptr) = delete; /// /// Allocates pages memory block. /// /// The number of pages to allocate. /// The size of single page. Use Platform::GetCPUInfo().PageSize or provide compatible, custom size. /// The pointer to the allocated pages in memory. static void* AllocatePages(uint64 numPages, uint64 pageSize); /// /// Frees allocated pages memory block. /// /// The pointer to the pages to deallocate. static void FreePages(void* ptr); public: /// /// Returns the current runtime platform type. It's compile-time constant. /// API_PROPERTY() static PlatformType GetPlatformType(); /// /// Returns the display server name on Linux. /// API_PROPERTY() static String GetDisplayServer() = delete; /// /// Returns true if is running 64 bit application (otherwise 32 bit). It's compile-time constant. /// API_PROPERTY() static bool Is64BitApp(); /// /// Returns true if running on 64-bit computer /// /// True if running on 64-bit computer, otherwise false. API_PROPERTY() static bool Is64BitPlatform() = delete; /// /// Gets the name of the operating system. /// API_PROPERTY() static String GetSystemName() = delete; /// /// Gets the version of the operating system version. /// API_PROPERTY() static Version GetSystemVersion() = delete; /// /// Gets the CPU information. /// /// The CPU info. API_PROPERTY() static CPUInfo GetCPUInfo() = delete; /// /// Gets the CPU cache line size. /// [Deprecated in v1.10] /// /// The cache line size. API_PROPERTY() DEPRECATED("Use CacheLineSize field from CPUInfo.") static int32 GetCacheLineSize(); /// /// Gets the current memory stats. /// /// The memory stats. API_PROPERTY() static MemoryStats GetMemoryStats() = delete; /// /// Gets the process current memory stats. /// /// The process memory stats. API_PROPERTY() static ProcessMemoryStats GetProcessMemoryStats() = delete; /// /// Gets the current process unique identifier. /// /// The process id. API_PROPERTY() static uint64 GetCurrentProcessId() = delete; /// /// Gets the current thread unique identifier. /// /// The thread id. API_PROPERTY() static uint64 GetCurrentThreadID() = delete; /// /// Sets the current thread priority. /// /// The priority. static void SetThreadPriority(ThreadPriority priority) = delete; /// /// Sets a processor affinity mask for the specified thread. /// /// /// A thread affinity mask is a bit vector in which each bit represents a logical processor that a thread is allowed to run on. A thread affinity mask must be a subset of the process affinity mask for the containing process of a thread. A thread can only run on the processors its process can run on. Therefore, the thread affinity mask cannot specify a 1 bit for a processor when the process affinity mask specifies a 0 bit for that processor. /// /// The affinity mask for the thread. static void SetThreadAffinityMask(uint64 affinityMask) = delete; /// /// Suspends the execution of the current thread until the time-out interval elapses /// /// The time interval for which execution is to be suspended, in milliseconds. static void Sleep(int32 milliseconds) = delete; public: /// /// Gets the current time in seconds. /// /// The current time. API_PROPERTY() static double GetTimeSeconds() = delete; /// /// Gets the current time as CPU cycles counter. /// /// The CPU cycles counter value. API_PROPERTY() static uint64 GetTimeCycles() = delete; /// /// Gets the system clock frequency. /// /// The clock frequency. API_PROPERTY() static uint64 GetClockFrequency() = delete; /// /// Gets current system time based on current computer settings. /// /// The result year value. /// The result month value. /// The result day of the week value. /// The result day value. /// The result hour value. /// The result minute value. /// The result second value. /// The result millisecond value. static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond) = delete; /// /// Gets current UTC time based on local computer settings. /// /// The result year value. /// The result month value. /// The result day of the week value. /// The result day value. /// The result hour value. /// The result minute value. /// The result second value. /// The result millisecond value. static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond) = delete; public: /// /// Shows the fatal error message to the user. /// /// The message content. /// The platform-dependent context for the stack trace collecting (eg. platform exception info). /// The fatal error type. API_FUNCTION() static void Fatal(const StringView& msg, void* context, FatalErrorType error = FatalErrorType::Unknown); /// /// Shows the fatal error message to the user. /// /// The message content. /// The fatal error type. API_FUNCTION() static void Fatal(const StringView& msg, FatalErrorType error = FatalErrorType::Unknown); /// /// Shows the error message to the user. /// /// The message content. API_FUNCTION() static void Error(const StringView& msg); /// /// Shows the warning message to the user. /// /// The message content. API_FUNCTION() static void Warning(const StringView& msg); /// /// Shows the information message to the user. /// /// The message content. API_FUNCTION() static void Info(const StringView& msg); /// /// Logs the specified message to the platform-dependant logging stream. /// /// The message. static void Log(const StringView& msg); /// /// Checks whenever program is running with debugger attached. /// /// True if debugger is present, otherwise false. static bool IsDebuggerPresent(); public: /// /// Performs a fatal crash. /// /// The source line. /// The source file. NO_RETURN static void Crash(int32 line, const char* file); /// /// Performs a fatal crash occurred on memory allocation fail. /// /// The source line. /// The source file. NO_RETURN static void OutOfMemory(int32 line = -1, const char* file = nullptr); /// /// Performs a fatal crash due to code not being implemented. /// /// The source line. /// The source file. /// The additional info. NO_RETURN static void MissingCode(int32 line, const char* file, const char* info); /// /// Performs a fatal crash due to assertion fail. /// /// The assertion message. /// The source line. /// The source file. NO_RETURN static void Assert(const char* message, const char* file, int line); /// /// Performs a error message log due to runtime value check fail. /// /// The assertion message. /// The source line. /// The source file. static void CheckFailed(const char* message, const char* file, int line); public: /// /// Sets the High DPI awareness. /// static void SetHighDpiAwarenessEnabled(bool enable); /// /// Gets the battery information. /// API_PROPERTY() static BatteryInfo GetBatteryInfo(); /// /// Gets the primary monitor's DPI setting. /// API_PROPERTY() static int32 GetDpi(); /// /// Gets the primary monitor's DPI setting scale factor (1 is default). Includes custom DPI scale. /// API_PROPERTY() static float GetDpiScale(); /// /// The custom DPI scale factor to apply globally. Can be used to adjust the User Interface scale (resolution). /// API_FIELD() static float CustomDpiScale; /// /// Gets the current network connection type. /// API_PROPERTY() static NetworkConnectionType GetNetworkConnectionType(); /// /// Gets the current screen orientation type. /// API_PROPERTY() static ScreenOrientationType GetScreenOrientationType(); /// /// Gets the current locale culture (eg. "pl-PL" or "en-US"). /// API_PROPERTY() static String GetUserLocaleName() = delete; /// /// Gets the computer machine name. /// API_PROPERTY() static String GetComputerName() = delete; /// /// Gets the user name. /// API_PROPERTY() static String GetUserName(); /// /// Returns true if app has user focus. /// API_PROPERTY() static bool GetHasFocus() = delete; /// /// Returns true if app is paused. Engine ticking (update/physics/drawing) is disabled in that state, only platform is updated until app end or resume. /// static bool GetIsPaused(); /// /// Creates the unique identifier. /// /// The result. static void CreateGuid(Guid& result); public: /// /// The list of users. /// API_FIELD(ReadOnly) static Array> Users; /// /// Event called when user gets added (eg. logged in). /// API_EVENT() static Delegate UserAdded; /// /// Event called when user gets removed (eg. logged out). /// API_EVENT() static Delegate UserRemoved; public: /// /// Returns a value indicating whether can open a given URL in a web browser. /// /// The URI to assign to web browser. /// True if can open URL, otherwise false. API_FUNCTION() static bool CanOpenUrl(const StringView& url); /// /// Launches a web browser and opens a given URL. /// /// The URI to assign to web browser. API_FUNCTION() static void OpenUrl(const StringView& url); public: /// /// Gets the mouse cursor position in screen-space coordinates. /// /// Mouse cursor coordinates. API_PROPERTY() static Float2 GetMousePosition(); /// /// Sets the mouse cursor position in screen-space coordinates. /// /// Cursor position to set. API_PROPERTY() static void SetMousePosition(const Float2& position); /// /// Gets the origin position and size of the monitor at the given screen-space location. /// /// The screen position (in pixels). /// The monitor bounds. API_FUNCTION() static Rectangle GetMonitorBounds(const Float2& screenPos); /// /// Gets size of the primary desktop. /// /// Desktop size. API_PROPERTY() static Float2 GetDesktopSize() = delete; /// /// Gets virtual bounds of the desktop made of all the monitors outputs attached. /// /// Whole desktop size. API_PROPERTY() static Rectangle GetVirtualDesktopBounds(); /// /// Gets virtual size of the desktop made of all the monitors outputs attached. /// API_PROPERTY() static Float2 GetVirtualDesktopSize(); public: /// /// Gets full path of the main engine directory. /// /// Main engine directory path API_PROPERTY() static String GetMainDirectory() = delete; /// /// Gets full path of the main engine executable file. /// /// The main engine executable file path. API_PROPERTY() static String GetExecutableFilePath() = delete; /// /// Gets the (almost) unique ID of the current user device. /// /// ID of the current user device API_PROPERTY() static Guid GetUniqueDeviceId() = delete; /// /// Gets the current working directory of the process. /// /// The workspace directory path. API_PROPERTY() static String GetWorkingDirectory() = delete; /// /// Sets the current working directory of the process. /// /// The directory to set. /// True if failed, otherwise false. static bool SetWorkingDirectory(const String& path); public: /// /// Gets the process environment variables (pairs of key and value). /// /// The result. static void GetEnvironmentVariables(Dictionary& result); /// /// Gets the environment variable value. /// /// The variable name. /// The result value. /// True if failed, otherwise false. static bool GetEnvironmentVariable(const String& name, String& value); /// /// Sets the environment variable value. /// /// The variable name. /// The value to assign. /// True if failed, otherwise false. static bool SetEnvironmentVariable(const String& name, const String& value); public: /// /// Starts a new process (runs app). /// [Deprecated in v1.6] /// /// The path to the executable file. /// Custom arguments for command line /// The custom name of the working directory /// True if start process with hidden window /// True if wait for process competition /// Retrieves the termination status of the specified process. Valid only if processed ended. API_FUNCTION() DEPRECATED("Use CreateProcess instead") static int32 StartProcess(const StringView& filename, const StringView& args, const StringView& workingDir, bool hiddenWindow = false, bool waitForEnd = false); /// /// Starts a new process (runs commandline). Waits for it's end and captures its output. /// [Deprecated in v1.6] /// /// Command line to execute /// The custom path of the working directory. /// True if start process with hidden window. /// Retrieves the termination status of the specified process. Valid only if processed ended. API_FUNCTION() DEPRECATED("Use CreateProcess instead") static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, bool hiddenWindow = true); /// /// Starts a new process (runs commandline). Waits for it's end and captures its output. /// [Deprecated in v1.6] /// /// Command line to execute /// The custom path of the working directory. /// The process environment variables. If null the current process environment is used. /// True if start process with hidden window. /// Retrieves the termination status of the specified process. Valid only if processed ended. API_FUNCTION() DEPRECATED("Use CreateProcess instead") static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary& environment, bool hiddenWindow = true); /// /// Creates a new process. /// /// The process settings. /// Retrieves the termination status of the specified process. Valid only if processed ended. API_FUNCTION() static int32 CreateProcess(API_PARAM(Ref) CreateProcessSettings& settings); /// /// Creates the window. /// /// The window settings. /// The created native window object or null if failed. API_FUNCTION() static Window* CreateWindow(API_PARAM(Ref) CreateWindowSettings& settings) = delete; /// /// Loads the library. /// /// The filename of the library to load (relative to workspace or absolute path). /// The loaded library handle (native) or null if failed. static void* LoadLibrary(const Char* filename) = delete; /// /// Frees the library. /// /// The loaded library handle. static void FreeLibrary(void* handle) = delete; /// /// Gets the address of an exported function or variable from the specified library. /// /// The library handle. /// The name of the symbol to locate (exported function or a variable). /// The address of the exported symbol, or null if failed. static void* GetLibraryExportSymbol(void* handle, const char* symbol) = delete; /// /// Stack trace frame location. /// struct StackFrame { char ModuleName[256]; char FunctionName[256]; char FileName[256]; int32 LineNumber; void* ProgramCounter; }; /// /// Gets current native stack trace information. /// /// The amount of stack frames to skip from the beginning. Can be used to skip the callee function from the trace (eg. in crash handler). /// The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception. /// The platform-dependent context for the stack trace collecting (eg. platform exception info). /// The collected stack trace frames. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build). static Array GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); /// /// Gets current native stack trace information as string. /// /// The amount of stack frames to skip from the beginning. Can be used to skip the callee function from the trace (eg. in crash handler). /// The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception. /// The platform-dependent context for the stack trace collecting (eg. platform exception info). /// The collected stack trace printed into string. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build). static String GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); // Crash dump data handling static void CollectCrashData(const String& crashDataFolder, void* context = nullptr); }; extern FLAXENGINE_API const Char* ToString(PlatformType type); extern FLAXENGINE_API const Char* ToString(ArchitectureType type);