XGameSaveEnumerateBlobInfo
检索 XGameSaveContainer 内容的 blob 信息。
语法
HRESULT XGameSaveEnumerateBlobInfo(
XGameSaveContainerHandle container,
void* context,
XGameSaveBlobInfoCallback* callback
)
参数
container _In_
类型:XGameSaveContainerHandle
包含要枚举的 blob 的 XGameSaveContainer 的句柄。
context _In_opt_
类型:void*
将传递到回调函数中的指针。
callback _In_
类型:XGameSaveBlobInfoCallback*
要为容器中的每个 blob 调用的函数,返回 false 可停止枚举。
返回值
类型:HRESULT
函数结果。
备注
注意
尽管此函数在时间敏感线程中调用是安全的,但 XGameSaveBlobInfoCallback 可能会导致延迟,具体取决于游戏在回调中所执行的操作。 例如,可以从回调复制数据;但是,执行任何非时间敏感调用可能会延迟回调的返回。 有关详细信息,请参阅时间敏感线程。
Blob 包含组成容器的实际可检索数据。 枚举 blob 将允许您查看在容器内可用的所有数据。 可以使用 XGameSaveEnumerateBlobInfoByName 枚举与某个前缀匹配的 blob。
// wrapper for calling a method on each item in the XGameSaveContainerInfo
HRESULT Sample::_ForEachBlob(_In_ const XGameSaveContainerInfo* container, _In_ void* context, _In_ XGameSaveBlobInfoCallback* callback)
{
// create the container handle so we can inspect the contents
XGameSaveContainerHandle containerContext = nullptr;
HRESULT hr = XGameSaveCreateContainer(_provider, container->name, &containerContext);
if (SUCCEEDED(hr))
{
// for each item in the container invoke the callback
hr = XGameSaveEnumerateBlobInfo(containerContext, context, callback);
}
if (containerContext != nullptr)
{
// make sure we close the context handle or we will leak memory
XGameSaveCloseContainer(containerContext);
}
return hr;
}
// check to see if the container has the minimum blobs we need to load a save
HRESULT Sample::_CheckForRequiredBlobs(_In_ XGameSaveContainerInfo* container)
{
const char* blobNames[] = {
"WorldState",
"PlayerState",
"PlayerInventory"
};
return _CheckContainerForRequiredBlobs(container, blobNames, _countof(blobNames));
}
//confirm this container has the blobs the caller is looking for
HRESULT Sample::_CheckContainerForRequiredBlobs(
_In_ XGameSaveContainerInfo* container,
_In_z_count_(countOfBlobs) const char** expectedBlobNames,
_In_ uint32_t countOfBlobs)
{
HRESULT hr;
struct QueryContext
{
QueryContext(const char** blobNames, uint32_t countOfBlobs) :
expectedCount(countOfBlobs), expectedBlobNames(blobNames), hitCount(0)
{}
uint32_t expectedCount;
const char** expectedBlobNames;
uint32_t hitCount;
};
QueryContext qc{ expectedBlobNames, countOfBlobs };
// simple check to see if we just see each of the blob names in the container
// a more robust check would identify which blob was missing to inform the caller
auto callback = [](_In_ const XGameSaveBlobInfo* info, _In_ void* context)
{
QueryContext* qc = reinterpret_cast<QueryContext*>(context);
for (uint32_t i = 0; i < qc->expectedCount; i++)
{
if (strcmp(qc->expectedBlobNames[i], info->name) == 0)
{
if (++qc->hitCount == qc->expectedCount)
{
// all the expected names are here, can stop enum
return false;
}
}
}
// keep enumerating
return true;
};
hr = _ForEachBlob(container, &qc, callback);
if (SUCCEEDED(hr))
{
if (qc.hitCount != qc.expectedCount)
{
printf("missing blobs from container!");
hr = E_UNEXPECTED;
}
}
return hr;
}
// find the size of a set of blobs in a container
HRESULT Sample::_GetContainerBlobsDataSize(
_In_ const XGameSaveContainerInfo* container,
_In_z_count_(countOfBlobs) const char** blobNames,
_In_ uint32_t countOfBlobs,
_Out_ size_t* containerSize)
{
*containerSize = 0;
struct BlobSize {
size_t size;
const char** blobNames;
uint32_t countOfBlobs;
};
BlobSize blobSize = { 0, blobNames, countOfBlobs };
HRESULT hr = _ForEachBlob(container, &blobSize,
[](const XGameSaveBlobInfo* info, void* ctx)
{
BlobSize* size = reinterpret_cast<BlobSize*>(ctx);
for (uint32_t i = 0; i < size->countOfBlobs; i++)
{
if (strcmp(info->name, size->blobNames[i]) == 0)
{
size->size += strlen(info->name) + 1; // length + null
size->size += info->size + sizeof(XGameSaveBlob);
break;
}
}
return true;
});
if (SUCCEEDED(hr))
{
*containerSize = blobSize.size;
}
return hr;
}
要求
头文件:XGameSave.h
库:xgameruntime.lib
支持平台:Windows、Xbox One 系列主机和 Xbox Series 主机
另请参阅
XGameSave
XGameSaveBlobInfo
XGameSaveEnumerateBlobInfoByName
游戏保存错误