diff --git a/src/KappaDuck.Quack/Interop/SDL/SDL3.System.cs b/src/KappaDuck.Quack/Interop/SDL/SDL3.System.cs index 5306149..b242478 100644 --- a/src/KappaDuck.Quack/Interop/SDL/SDL3.System.cs +++ b/src/KappaDuck.Quack/Interop/SDL/SDL3.System.cs @@ -1,10 +1,16 @@ // Copyright (c) KappaDuck. // Licensed under the MIT license. +using KappaDuck.Quack.System; + namespace KappaDuck.Quack.Interop.SDL; internal static partial class SDL3 { + [LibraryImport(nameof(SDL3), EntryPoint = "SDL_GetPowerInfo")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + internal static partial PowerState GetPowerInfo(out int seconds, out int percent); + [LibraryImport(nameof(SDL3), EntryPoint = "SDL_OpenURL", StringMarshalling = StringMarshalling.Utf8)] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [return: MarshalAs(UnmanagedType.U1)] diff --git a/src/KappaDuck.Quack/System/PowerInfo.cs b/src/KappaDuck.Quack/System/PowerInfo.cs new file mode 100644 index 0000000..b72a811 --- /dev/null +++ b/src/KappaDuck.Quack/System/PowerInfo.cs @@ -0,0 +1,86 @@ +// Copyright (c) KappaDuck. +// Licensed under the MIT license. + +namespace KappaDuck.Quack.System; + +/// +/// Provides a snapshot of the system's power supply, e.g. laptop battery status. +/// +public readonly record struct PowerInfo +{ + private PowerInfo(PowerState state, int? percentage, TimeSpan? remaining) + { + State = state; + Percentage = percentage; + Remaining = remaining; + } + + /// + /// Gets a snapshot of the current power supply. + /// + /// + /// + /// You should never take the power status for granted. Batteries (especially failing ones) can + /// report incorrect values, and the values reported here are best estimates based on what the + /// hardware reports. It's not uncommon for older batteries to lose stored power much faster than + /// reported, or completely drain when reporting it has 20% left, etc. + /// + /// + /// Battery status can change at any time, so if your application depends on accurate power status, + /// refresh the values by reading this property again, and perhaps ignore changes until they seem + /// stable for a few seconds. A platform may only report battery percentage or time left, not both. + /// + /// + /// On some platforms retrieving power details can be expensive; for continuous display, read it + /// about once a minute rather than every frame. + /// + /// + public static PowerInfo Current + { + get + { + PowerState state = SDL3.GetPowerInfo(out int seconds, out int percent); + + int? percentage = percent < 0 ? null : percent; + TimeSpan? remaining = seconds < 0 ? null : TimeSpan.FromSeconds(seconds); + + return new PowerInfo(state, percentage, remaining); + } + } + + /// + /// Gets the power state of the system. + /// + public PowerState State { get; } + + /// + /// Gets the battery charge between 0 and 100, or if it can't be determined. + /// + public int? Percentage { get; } + + /// + /// Gets the estimated battery life remaining, or if it can't be determined. + /// + public TimeSpan? Remaining { get; } + + /// + /// Gets a value indicating whether the system is running on battery (not plugged in). + /// + public bool IsOnBattery => State == PowerState.OnBattery; + + /// + /// Gets a value indicating whether the battery is charging. + /// + public bool IsCharging => State == PowerState.Charging; + + /// + /// Gets a value indicating whether the battery is fully charged. + /// + public bool IsCharged => State == PowerState.Charged; + + /// + /// Gets a value indicating whether a battery is present. + /// + public bool HasBattery => State is PowerState.OnBattery or PowerState.Charging or PowerState.Charged; + +} diff --git a/src/KappaDuck.Quack/System/PowerState.cs b/src/KappaDuck.Quack/System/PowerState.cs new file mode 100644 index 0000000..c97290d --- /dev/null +++ b/src/KappaDuck.Quack/System/PowerState.cs @@ -0,0 +1,40 @@ +// Copyright (c) KappaDuck. +// Licensed under the MIT license. + +namespace KappaDuck.Quack.System; + +/// +/// Represents the current power state. +/// +public enum PowerState +{ + /// + /// An error occurred while determining the power state. + /// + Error = -1, + + /// + /// The power state could not be determined (e.g., no battery). + /// + Unknown = 0, + + /// + /// The system is running on battery power. + /// + OnBattery = 1, + + /// + /// The system is plugged in but does not have a battery available. + /// + NoBattery = 2, + + /// + /// The system is plugged in and charging the battery. + /// + Charging = 3, + + /// + /// The system is plugged in and the battery is fully charged. + /// + Charged = 4 +}