Added Achivement.GetIconAsync() (waits for load if not loaded)

This commit is contained in:
Garry Newman 2019-05-01 11:47:50 +01:00
parent 38a29c6059
commit ab535d367d
4 changed files with 57 additions and 3 deletions

View File

@ -13,7 +13,7 @@ namespace Steamworks
public class UserStatsTest public class UserStatsTest
{ {
[TestMethod] [TestMethod]
public void AchievementList() public async Task AchievementList()
{ {
foreach ( var a in SteamUserStats.Achievements ) foreach ( var a in SteamUserStats.Achievements )
{ {
@ -24,7 +24,7 @@ public void AchievementList()
Console.WriteLine( $" a.Description: {a.Description}" ); Console.WriteLine( $" a.Description: {a.Description}" );
Console.WriteLine( $" a.GlobalUnlocked: {a.GlobalUnlocked}" ); Console.WriteLine( $" a.GlobalUnlocked: {a.GlobalUnlocked}" );
var icon = a.GetIcon(); var icon = await a.GetIconAsync();
Console.WriteLine( $" a.Icon: {icon}" ); Console.WriteLine( $" a.Icon: {icon}" );
} }

View File

@ -43,8 +43,16 @@ internal static void InstallEvents()
UserStatsStored_t.Install( x => OnUserStatsStored?.Invoke( x.Result ) ); UserStatsStored_t.Install( x => OnUserStatsStored?.Invoke( x.Result ) );
UserAchievementStored_t.Install( x => OnAchievementProgress?.Invoke( x.AchievementName, (int) x.CurProgress, (int)x.MaxProgress ) ); UserAchievementStored_t.Install( x => OnAchievementProgress?.Invoke( x.AchievementName, (int) x.CurProgress, (int)x.MaxProgress ) );
UserStatsUnloaded_t.Install( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) ); UserStatsUnloaded_t.Install( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) );
UserAchievementIconFetched_t.Install( x => OnAchievementIconFetched( x.AchievementName, x.IconHandle ) );
} }
/// <summary>
/// called when the achivement icon is loaded
/// </summary>
internal static event Action<string, int> OnAchievementIconFetched;
/// <summary> /// <summary>
/// called when the latests stats and achievements have been received /// called when the latests stats and achievements have been received
/// from the server /// from the server

View File

@ -99,6 +99,8 @@ public static bool GetImageSize( int image, out uint width, out uint height )
/// </summary> /// </summary>
public static Data.Image? GetImage( int image ) public static Data.Image? GetImage( int image )
{ {
if ( image == 0 ) return null;
var i = new Data.Image(); var i = new Data.Image();
if ( !GetImageSize( image, out i.Width, out i.Height ) ) if ( !GetImageSize( image, out i.Width, out i.Height ) )

View File

@ -55,13 +55,57 @@ public DateTime? UnlockTime
} }
/// <summary> /// <summary>
/// Gets the icon of the achievement /// Gets the icon of the achievement. This can return a null image even though the image exists if the image
/// hasn't been downloaded by Steam yet. You can use GetIconAsync if you want to wait for the image to be downloaded.
/// </summary> /// </summary>
public Image? GetIcon() public Image? GetIcon()
{ {
return SteamUtils.GetImage( SteamUserStats.Internal.GetAchievementIcon( Value ) ); return SteamUtils.GetImage( SteamUserStats.Internal.GetAchievementIcon( Value ) );
} }
/// <summary>
/// Gets the icon of the achievement, waits for it to load if we have to
/// </summary>
public async Task<Image?> GetIconAsync( int timeout = 5000 )
{
var i = SteamUserStats.Internal.GetAchievementIcon( Value );
if ( i != 0 ) return SteamUtils.GetImage( i );
var ident = Identifier;
bool gotCallback = false;
Action<string, int> f = ( x, icon ) =>
{
if ( x != ident ) return;
i = icon;
gotCallback = true;
};
try
{
SteamUserStats.OnAchievementIconFetched += f;
int waited = 0;
while ( !gotCallback )
{
await Task.Delay( 10 );
waited += 10;
// Time out after x milliseconds
if ( waited > timeout )
return null;
}
if ( i == 0 ) return null;
return SteamUtils.GetImage( i );
}
finally
{
SteamUserStats.OnAchievementIconFetched -= f;
}
}
/// <summary> /// <summary>
/// Returns the fraction (0-1) of users who have unlocked the specified achievement, or -1 if no data available. /// Returns the fraction (0-1) of users who have unlocked the specified achievement, or -1 if no data available.
/// </summary> /// </summary>