> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XGameSaveCreateUpdate

> XGameSaveCreateUpdate

# XGameSaveCreateUpdate

Crea una actualización que se enviará más adelante llamando a [XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate).

## Sintaxis

```cpp theme={null}
HRESULT XGameSaveCreateUpdate(  
         XGameSaveContainerHandle container,  
         const char* containerDisplayName,  
         XGameSaveUpdateHandle* updateContext  
)  
```

### Parámetros

*container*   \_In\_\
Tipo: XGameSaveContainerHandle

Identificador del XGameSaveContainer que se va a actualizar.

*containerDisplayName*   \_In\_z\_\
Tipo: char\*

Nombre para mostrar del contenedor que se va a actualizar.

*updateContext*   \_Outptr\_result\_nullonfailure\_\
Tipo: XGameSaveUpdateHandle\*

Identificador del XGameSaveUpdate que se va a crear.

### Valor devuelto

Tipo: HRESULT

Resultado de la función.

## Comentarios

<Note>No es seguro llamar a esta función en un subproceso con dependencia temporal. Para obtener más información, consulte [Subprocesos con dependencia temporal](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads).</Note>

La parte de almacenamiento de esta API está diseñada para transferir fácilmente datos del juego al almacenamiento persistente de forma segura, confiable y transaccional. Queremos asegurarnos de que los datos de respaldo de un contenedor sean siempre coherentes y, por lo tanto, queremos que toda la operación se realice correctamente o falle de forma atómica. No queremos tener una actualización parcial en la que algunos datos de blob sean incoherentes con otros datos dentro del contenedor. Para lograrlo, proporcionamos un contexto de actualización al que se envían las escrituras y eliminaciones de blobs y, cuando está listo, se envía el contexto completo. En la práctica, esto se ve de la siguiente manera:

Un **XGameSaveUpdate** se rellenará con acciones de escritura (Write) y eliminación (Delete) que se llevarán a cabo en los blobs dentro del contenedor mediante [XGameSaveSubmitBlobWrite](/reference/system/xgamesave/functions/xgamesavesubmitblobwrite) y [XGameSaveSubmitBlobDelete](/reference/system/xgamesave/functions/xgamesavesubmitblobdelete). Una actualización se completa llamando a [XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate).

Cuando haya terminado con un **XGameSaveUpdate**, ciérrelo con [XGameSaveCloseUpdate](/reference/system/xgamesave/functions/xgamesavecloseupdate).

El siguiente ejemplo de C++ muestra una actualización sincrónica de XGameSave.

<a id="example" />

```cpp theme={null}
// SYNC Write - should not be called on a time sensitive thread 
//              as this will block until the operation is complete 
void Sample::_SaveDataSync(const char* containerName, const char* containerDisplayName) 
{ 
    HRESULT hr; 
    XGameSaveContainerHandle containerContext; 
    XGameSaveUpdateHandle updateContext; 
  
    hr = XGameSaveCreateContainer(_provider, containerName, &containerContext); 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateUpdate(containerContext, containerDisplayName, &updateContext); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "WorldState", _worldState.data(), _worldState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "PlayerState", _playerState.data(), _playerState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "PlayerInventory", _playerInventory.data(), _playerInventory.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        if (_clearLevelProgress) 
        { 
            hr = XGameSaveSubmitBlobDelete(updateContext, "LevelProgress"); 
        } 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitUpdate(updateContext); 
    } 
  
    if (updateContext) 
    { 
        XGameSaveCloseUpdate(updateContext); 
    } 
    if (containerContext) 
    { 
        XGameSaveCloseContainer(containerContext); 
    } 
  
    _HandleContainerUpdateErrors(hr); 
} 
  
  
void Sample::_HandleContainerUpdateErrors(HRESULT hr) 
{ 
    switch (hr) 
    { 
    case E_GS_INVALID_CONTAINER_NAME: 
        // tried to access a container with an invalid name 
        break; 
    case E_GS_OUT_OF_LOCAL_STORAGE: 
        // storage location is full, let the user know that saves won't work till this is fixed 
        break; 
    case E_GS_UPDATE_TOO_BIG: 
        // the blob that we provided was too big, can't be larger than GS_MAX_BLOB_SIZE 
        break; 
    case E_GS_QUOTA_EXCEEDED: 
        // the update we did was larger than our overall quota, need to track that! (see XGameSaveQueryRemainingQuota & XGameSaveQueryRemainingQuotaAsync) 
        break; 
    case E_GS_CONTAINER_NOT_IN_SYNC: 
    case E_GS_CONTAINER_SYNC_FAILED: 
        // need to sync and we are offline ? 
        break; 
    case E_GS_HANDLE_EXPIRED: 
        // need to re-initialize since another device has taken 
        // ownership while we were suspended and/or busy 
        break; 
    } 
}
```

El siguiente ejemplo de C++ muestra una actualización asincrónica de XGameSave.

```cpp theme={null}
// ASYNC Write - can be kicked off from a time sensitive thread 
//               actual work and completion will be scheduled base upon 
//               the configuration of the async_queue tied to the XAsyncBlock. 
void Sample::_SaveDataAsync(const char* containerName, const char* containerDisplayName) 
{ 
    struct SaveContext 
    { 
        SaveContext(Sample* s) : self(s), containerContext(nullptr), updateContext(nullptr) {} 
        ~SaveContext() 
        { 
            if (updateContext) 
            { 
                XGameSaveCloseUpdate(updateContext); 
            } 
            if (containerContext) 
            { 
                XGameSaveCloseContainer(containerContext); 
            } 
        } 
  
        XAsyncBlock async; 
        XGameSaveContainerHandle containerContext; 
        XGameSaveUpdateHandle updateContext; 
        Sample* self; 
    }; 
  
    HRESULT hr; 
    SaveContext* saveContext = new SaveContext(this); 
    if (saveContext == nullptr) 
    { 
        hr = E_OUTOFMEMORY; 
    } 
    if (SUCCEEDED(hr)) 
    { 
        saveContext->async.context = saveContext; 
        saveContext->async.callback = [](XAsyncBlock* async) 
        { 
            auto ctx = reinterpret_cast<SaveContext*>(async->context); 
            auto self = ctx->self; 
            HRESULT hr = XGameSaveSubmitUpdateResult(async); 
            self->_HandleContainerUpdateErrors(hr); 
            delete ctx; 
        }; 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateContainer(_provider, containerName, &saveContext->containerContext); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateUpdate(saveContext->containerContext, containerDisplayName, &saveContext->updateContext); 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "WorldState", _worldState.data(), _worldState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "PlayerState", _playerState.data(), _playerState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "PlayerInventory", _playerInventory.data(), _playerInventory.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        if (_clearLevelProgress) 
        { 
            hr = XGameSaveSubmitBlobDelete(saveContext->updateContext, "LevelProgress"); 
        } 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitUpdateAsync(saveContext->updateContext, &saveContext->async); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        // context is now owned by the async 
        saveContext = nullptr; 
    } 
  
    // if there was any error we need to cleanup the saveContext 
    if (saveContext) 
    { 
        delete saveContext; 
    } 
  
} 
```

## Requisitos

**Encabezado:** XGameSave.h

**Biblioteca:** xgameruntime.lib

**Plataformas compatibles:** Windows, consolas de la familia XBOX One y consolas XBOX Series

## Documentación conceptual

* [Subprocesos con dependencia temporal](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## Consulte también

[XGameSave](/reference/system/xgamesave/xgamesave_members)\
[XGameSaveSubmitBlobWrite](/reference/system/xgamesave/functions/xgamesavesubmitblobwrite)\
[XGameSaveSubmitBlobDelete](/reference/system/xgamesave/functions/xgamesavesubmitblobdelete)\
[XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate)\
[XGameSaveCloseUpdate](/reference/system/xgamesave/functions/xgamesavecloseupdate)
[Depuración de partidas guardadas](/build/core-features/common/game-save/game-saves-debugging)


## Related topics

- [XGameSaveCloseUpdate](/es/reference/system/xgamesave/functions/xgamesavecloseupdate.md)
- [XGameSaveSubmitUpdate](/es/reference/system/xgamesave/functions/xgamesavesubmitupdate.md)
- [XGameSaveSubmitUpdateAsync](/es/reference/system/xgamesave/functions/xgamesavesubmitupdateasync.md)
- [XGameSaveSubmitBlobDelete](/es/reference/system/xgamesave/functions/xgamesavesubmitblobdelete.md)
- [XGameSaveSubmitBlobWrite](/es/reference/system/xgamesave/functions/xgamesavesubmitblobwrite.md)
