Getting title-managed Achievements
This topic covers the following:
- Getting the achievements list
- Getting the next page of achievements results
- Getting a single achievement
Getting the achievements list
To get the achievements for the running title, call XblAchievementsGetAchievementsForTitleIdAsync, as follows.
Calling XblAchievementsGetAchievementsForTitleIdAsync
C++
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of XAsyncBlock*.
XblAchievementsResultHandle resultHandle;
auto hr = XblAchievementsGetAchievementsForTitleIdResult(asyncBlock, &resultHandle);
if (SUCCEEDED(hr))
{
const XblAchievement* achievements = nullptr;
size_t achievementsCount = 0;
hr = XblAchievementsResultGetAchievements(resultHandle, &achievements, &achievementsCount);
for (size_t i = 0; i < achievementsCount; i++)
{
LogToScreen("Achievement %s: %s = %s",
achievements[i].id,
achievements[i].name,
(achievements[i].progressState == XblAchievementProgressState::Achieved) ? "Achieved" : "Not achieved");
}
XblAchievementsResultCloseHandle(resultHandle); // When you're done with the handle, close it.
achievements = nullptr; // Clear the array after calling XblAchievementsResultCloseHandle to the pointer to freed memory.
// Instead, you couldn't close the handle and store it. Then,
// if you needed to copy the handle, call XblAchievementsResultDuplicateHandle().
}
};
HRESULT hr = XblAchievementsGetAchievementsForTitleIdAsync(
xboxLiveContext,
xboxUserId,
titleId,
achievementType,
unlockedOnly,
orderBy,
skipItems,
maxItems,
asyncBlock.get()
);
if (SUCCEEDED(hr))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
// If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
asyncBlock.release();
}
For more information, see the following:
- XAsyncBlock
- XblAchievement
- XblAchievementProgressState
- XblAchievementsGetAchievementsForTitleIdAsync
- XblAchievementsGetAchievementsForTitleIdResult
- XblAchievementsResultCloseHandle
- XblAchievementsResultDuplicateHandle
- XblAchievementsResultGetAchievements
Return to the top of this topic.
Getting the next page of achievements results
There might be more pages of achievements. To check, call XblAchievementsResultHasNext and then call XblAchievementsResultGetNextAsync.
Calling XblAchievementsResultHasNext
Flat C API
HRESULT hr = S_OK;
bool hasNext = false;
if (achievementsResult != nullptr)
{
hr = XblAchievementsResultHasNext(achievementsResult, &hasNext);
}
For more information, see XblAchievementsResultHasNext.
Calling XblAchievementsResultGetNextAsync
To get the next page of achievements, call XblAchievementsResultGetNextAsync, as follows.
C++
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of XAsyncBlock*.
XblAchievementsResultHandle resultHandle;
auto hr = XblAchievementsResultGetNextResult(asyncBlock, &resultHandle);
if (SUCCEEDED(hr))
{
const XblAchievement* achievements = nullptr;
size_t achievementsCount = 0;
hr = XblAchievementsResultGetAchievements(resultHandle, &achievements, &achievementsCount);
for (size_t i = 0; i < achievementsCount; i++)
{
LogToScreen("Achievement %s: %s = %s",
achievements[i].id,
achievements[i].name,
(achievements[i].progressState == XblAchievementProgressState::Achieved) ? "Achieved" : "Not achieved");
}
XblAchievementsResultCloseHandle(resultHandle); // When you're done with the handle, close it.
achievements = nullptr; // Clear the array after calling XblAchievementsResultCloseHandle to the pointer to freed memory.
}
};
HRESULT hr = XblAchievementsResultGetNextAsync(
achievementsResult,
maxItems,
asyncBlock.get()
);
if (SUCCEEDED(hr))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
// If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
asyncBlock.release();
}
For more information, see the following:
- XAsyncBlock
- XblAchievement
- XblAchievementProgressState
- XblAchievementsResultCloseHandle
- XblAchievementsResultGetAchievements
- XblAchievementsResultGetNextAsync
- XblAchievementsResultGetNextResult
Return to the top of this topic.
Getting a single achievement
To get a single achievement, call XblAchievementsGetAchievementAsync, as follows.
Flat C API
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of XAsyncBlock*.
XblAchievementsResultHandle resultHandle;
auto hr = XblAchievementsGetAchievementResult(asyncBlock, &resultHandle);
if (SUCCEEDED(hr))
{
const XblAchievement* achievements = nullptr;
size_t achievementsCount = 0;
hr = XblAchievementsResultGetAchievements( resultHandle, &achievements, &achievementsCount );
// Use the achievements array to read the achievement data.
XblAchievementsResultCloseHandle(resultHandle); // When you're done with the handle, close it.
achievements = nullptr; // Clear the array after calling XblAchievementsResultCloseHandle to avoid the pointer to freed memory.
}
};
HRESULT hr = XblAchievementsGetAchievementAsync(
xboxLiveContext,
xboxUserId,
scid,
achievementId.c_str(),
asyncBlock.get()
);
if (SUCCEEDED(hr))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
// If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
asyncBlock.release();
}
For more information, see the following: