게임에서 간소화 래퍼 저장
기존 XGameSave
API를 이용하면 개발자가 게임 시스템을 최고로 관리할 수 있습니다. API는 성능, 스레딩, 동기화 정책, 트랜잭션 업데이트를 완벽하게 제어할 수 있습니다. 이 같은 제어가 필요하지 않으며 게임에 로밍 가능한 저장만 통합하는 방법만 필요한 게임에 대해서는 API가 훨씬 더 간단한 C++ 래퍼를 제공합니다.
간소화된 래퍼는 .spp 파일 %GRDKLatest%GameKit\Include\xgamesavewrappers.hpp로 제공되며 게임에 통합 가능합니다.
게임은 XGameSave XGameSave
API나 간소화된 래퍼 중에서 사용하려는 솔루션을 선택해야 합니다.
게임에서 .hpp 파일의 소스 코드를 수정하지 않는 한 두 솔루션을 혼합하면 안됩니다.
간소화된 래퍼는 XGameSave API를 사용하여 구현되므로 전체 XGameSave
API의 모든 제한 사항이 적용됩니다.
래퍼 사용
래퍼를 사용하는 것은 다음 단계에 표시된 것처럼 매우 간단합니다.
- 프로젝트에 xgamesavewrappers.hpp를 넣습니다.
- 새 Provider 클래스를 만듭니다. 게임이 진행되는 동안 포인터가 이 개체를 계속 가리키도록 해야 합니다.
- Provider::Initialize를 호출하여 게임의 사용자 저장을 동기화합니다. 이 작업은 다른 게임 저장 래퍼 API를 호출하기 전에 수행해야 합니다. 이 호출로 UI가 차단되고 표시될 수도 있으므로 게임의 UI 스레드에서는 호출하면 안 됩니다.
XGameSave
전체 API와 마찬가지로, 게임 저장은 단일 저장소 공간의 일부를 차지합니다. 저장소 공간은 여러 컨테이너로 구성되며 게임에서 정의할 수 있습니다. 각 컨테이너는 여러 개의 Blob으로 이루어질 수 있습니다. 이 Blob은 게임이 읽고 쓰는 데이터입니다.
Provider
클래스를 초기화하면 게임에서는 다음을 어떻게든 조합해 사용할 수 있습니다.
- Provider::QueryContainers 또는 Provider::QueryContainerBlobs를 사용하여 컨테이너와 Blob을 열거합니다.
- Provider::Load를 사용하여 Blob(파일)을 로드합니다.
- Provider::Save를 사용하여 새 Blob(파일)을 업데이트하거나 만듭니다.
- 컨테이너를 내용과 함께 삭제하거나 컨테이너 내에서 일부 Blob을 삭제합니다.
- Provider::GetQuota를 호출하여 남아 있는 공간을 확인합니다.
Load 메서드의 예
다음 코드 예시는 Load
를 사용하는 방법을 보여 줍니다.
using Microsoft::Xbox::Wrappers::GameSave;
Provider provider = new Provider();
// NOTE: Initialize will throw an exception if called on the UI thread.
if(SUCCEEDED(provider->Initialize(userHandle, mySCID))
{
// Note that container names can't contain spaces.
std::vector<std::string> containers = provider->QueryContainers("Save_slot_1");
if(containers.size() == 1)
{
BlobData data = provider->Load("Save_slot_1", "progress");
if(!data.empty())
{
// Read the data into the game.
}
else
{
// This is unexpected in this use case because the sample
// code assumes that there is just one blob in the
// container.
}
}
}
저장 기능의 예
다음 샘플 코드는 Save
기능을 사용하는 방법을 보여 줍니다.
using Microsoft::Xbox::Wrappers::GameSave;
std::vector<uint8_t> saveData; // Contains the user's data.
Provider provider = new Provider();
// NOTE: Initialize will throw an exception if called on the UI thread.
if(SUCCEEDED(provider->Initialize(userHandle, mySCID))
{
// Note that container names can't contain spaces.
HRESULT hr = provider->Save("Save_slot_1", "progress", saveData.size(), saveData.data());
if(FAILED(hr))
{
if(hr == E_GS_QUOTA_EXCEEDED)
{
// Message that the user must clear out saves for this game.
}
else if(hr == E_GS_OUT_OF_LOCAL_STORAGE)
{
// Message to the user that they have run out of save space on the local device.
}
else if(hr == E_GS_UPDATE_TOO_BIG)
{
// This is really a development-time item to catch. Your save size was too
// big for a given call to save. Each such call is limited to 16 MB (GS_MAX_BLOB_SIZE).
}
else if(hr == E_GS_HANDLE_EXPIRED)
{
// Need to re-create the provider and try again.
}
else
{
// Log error.
}
}
}