Files
rudder-csharp-sdk/Services/LeaderboardsService.cs
T

74 lines
2.7 KiB
C#
Raw Permalink Normal View History

2026-08-12 14:04:55 +03:00
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using RudderSdk.Core.Models.Leaderboards;
namespace RudderSdk.Core;
/// <summary>
/// Leaderboards. Resolve a board with <see cref="FindBySlug"/> and work through
/// the returned <see cref="LeaderboardHandle"/>.
/// </summary>
public sealed class LeaderboardsService
{
private readonly RudderClient _client;
private readonly Dictionary<string, LeaderboardHandle> _cache = new();
internal LeaderboardsService(RudderClient client) => _client = client;
/// <summary>Returns the (cached) handle for the leaderboard with the given slug.</summary>
public LeaderboardHandle FindBySlug(string slug)
{
if (!_cache.TryGetValue(slug, out var leaderboard))
{
leaderboard = new LeaderboardHandle(slug, this);
_cache[slug] = leaderboard;
}
return leaderboard;
}
internal Task<GetRankingResponse> GetRankingAsync(string slug, int limit, CancellationToken cancellationToken)
=> _client.SendAsync<GetRankingResponse>(
"GET",
"/sdk/v1/leaderboards/" + Url.Encode(slug) + "/ranking" + Url.Query(("limit", limit > 0 ? limit.ToString() : null)),
cancellationToken);
internal Task SubmitScoreAsync(string slug, double score, CancellationToken cancellationToken)
=> _client.SendAsync(
"POST",
"/sdk/v1/leaderboards/" + Url.Encode(slug) + "/submit-score",
new SubmitScoreRequest { Slug = slug, Score = score },
cancellationToken);
}
/// <summary>Operations on one leaderboard.</summary>
public sealed class LeaderboardHandle
{
private readonly LeaderboardsService _service;
internal LeaderboardHandle(string slug, LeaderboardsService service)
{
Slug = slug;
_service = service;
}
/// <summary>Leaderboard slug.</summary>
public string Slug { get; }
/// <summary>Entries fetched by the last <see cref="ListAsync"/> call.</summary>
public IReadOnlyList<RankEntry> Entries { get; private set; } = new List<RankEntry>();
/// <summary>Submits a score for the current player.</summary>
public Task SubmitAsync(double score, CancellationToken cancellationToken = default)
=> _service.SubmitScoreAsync(Slug, score, cancellationToken);
/// <summary>Fetches the top entries and caches them in <see cref="Entries"/>.</summary>
public async Task<IReadOnlyList<RankEntry>> ListAsync(int limit = 100, CancellationToken cancellationToken = default)
{
var response = await _service.GetRankingAsync(Slug, limit, cancellationToken).ConfigureAwait(false);
Entries = response?.Entries ?? new List<RankEntry>();
return Entries;
}
}