

Avviso di fine del supporto: il 20 maggio 2026, AWS terminerà il supporto per AWS SimSpace Weaver. Dopo il 20 maggio 2026, non potrai più accedere alla SimSpace Weaver console o SimSpace Weaver alle risorse. Per ulteriori informazioni, consulta [AWS SimSpace Weaver Fine del supporto](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Lavorare con SimSpace Weaver
<a name="working-with"></a>

Questo capitolo fornisce informazioni e linee guida per aiutarti a creare le tue applicazioni in SimSpace Weaver.

**Topics**
+ [Configurazione della simulazione](working-with_configuring-simulation.md)
+ [Durata massima di una simulazione](working-with_max-duration.md)
+ [Sviluppo di app](working-with_developing-apps.md)
+ [Sviluppo di applicazioni client](working-with_developing-client-applications.md)
+ [Ottieni l'indirizzo IP e il numero di porta di un'app personalizzata](working-with_get-ip.md)
+ [Avvio del client di visualizzazione Unreal Engine](working-with_unreal-client.md)
+ [Sviluppo locale in SimSpace Weaver](working-with_local-development.md)
+ [AWS SimSpace Weaver SDK dell'app](working-with_app-sdk.md)
+ [AWS SimSpace Weaver quadro dimostrativo](working-with_demo-framework.md)
+ [Utilizzo delle quote di servizio](working-with_quotas.md)
+ [Simulazioni di debug](working-with_debugging.md)
+ [Contenitori personalizzati](working-with_custom-containers.md)
+ [Uso di Python](working-with_python.md)
+ [Support per altri motori](working-with_engines.md)
+ [Utilizzo di software concesso in licenza con AWS SimSpace Weaver](working-with_byol.md)
+ [Gestisci le tue risorse con AWS CloudFormation](working-with_cloudformation.md)
+ [Snapshot](working-with_snapshots.md)
+ [Messaggistica](working-with_messaging.md)

# Configurazione della simulazione
<a name="working-with_configuring-simulation"></a>

Uno **schema (o **schema**) di simulazione** è YAML-file di testo in formato che specifica la configurazione per una simulazione. È possibile utilizzare lo stesso schema per avviare più simulazioni. Il file dello schema si trova nella cartella del progetto per la simulazione. È possibile utilizzare qualsiasi editor di testo per modificare il file. SimSpace Weaver legge lo schema solo quando avvia la simulazione. Tutte le modifiche apportate a un file di schema influiscono solo sulle nuove simulazioni avviate dopo le modifiche. 

Per configurare la simulazione, modifica il file dello schema di simulazione (usa il separatore di percorso appropriato per il tuo sistema operativo):

```
project-folder\tools\project-name-schema.yaml
```

Lo schema di simulazione viene caricato quando si crea una nuova simulazione. Lo script di supporto per l'avvio rapido del progetto caricherà lo schema come parte del processo di creazione della simulazione: 

```
project-folder\tools\windows\quick-start.py
```

Per ulteriori informazioni sull'esecuzione dello script di avvio rapido, consulta il [Nozioni di base](getting-started.md) capitolo di [Tutorial dettagliato](getting-started_detailed.md) questa guida.

## Parametri di configurazione della simulazione
<a name="working-with_configuring-simulation_config-parameters"></a>

Lo schema di simulazione contiene informazioni di bootstrap, tra cui:
+ **Proprietà di simulazione**[: versione SDK e configurazione di calcolo (tipo e numero di lavoratori)](w2aac51.md#glossary_worker)
+ **Orologi: frequenza di ticchettio** e tolleranze
+ **Strategie di partizionamento** spaziale: topologia spaziale (come una griglia), limiti e gruppi di posizionamento (raggruppamento delle partizioni spaziali sui lavoratori)
+ **Domini e relative app: app bucket**, path e comandi di avvio

SimSpace Weaver utilizza la configurazione dello schema per configurare e disporre le partizioni spaziali, avviare app e far avanzare la simulazione alla frequenza specificata. 

**Nota**  
Lo script di creazione del progetto nell'SDK dell' SimSpace Weaver app genererà automaticamente uno schema di simulazione basato sull'applicazione di esempio.

I seguenti argomenti descrivono i parametri dello schema di simulazione. Per una descrizione completa dello schema di simulazione, vedere. [SimSpace Weaver riferimento allo schema di simulazione](schema-reference.md) 

**Topics**
+ [Parametri di configurazione della simulazione](#working-with_configuring-simulation_config-parameters)
+ [Versione SDK](working-with_configuring-simulation_sdk-version.md)
+ [Proprietà di simulazione](working-with_configuring-simulation_simulation-properties.md)
+ [Worker](working-with_configuring-simulation_workers.md)
+ [Orologio](working-with_configuring-simulation_clock.md)
+ [Strategie di partizionamento](working-with_configuring-simulation_partitioning-strategies.md)
+ [Domini](working-with_configuring-simulation_domains.md)

# Versione SDK
<a name="working-with_configuring-simulation_sdk-version"></a>

Il `sdk_version` campo specifica la versione per SimSpace Weaver cui è formattato lo schema. Valori validi: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**Importante**  
Il valore di include `sdk_version` solo il numero della versione principale e il numero della prima versione secondaria. Ad esempio, il valore `1.12` specifica tutte le versioni`1.12.x`, ad esempio `1.12.0``1.12.1`, e`1.12.2`.

# Proprietà di simulazione
<a name="working-with_configuring-simulation_simulation-properties"></a>

La `simulation_properties` sezione dello schema specifica la configurazione di registrazione e un tipo di dati per il campo indice (in genere la posizione spaziale) delle entità.

```
simulation_properties:
  log_destination_service: "logs"
  log_destination_resource_name: "MySimulationLogs"
  default_entity_index_key_type: "Vector3<f32>"
```

Il valore di `log_destination_service` determina l'interpretazione del valore di. `log_destination_resource_name` Attualmente, l'unico valore supportato è `logs`. Ciò significa che il valore di `log_destination_resource_name` è il nome di un gruppo di log in Amazon CloudWatch Logs

**Nota**  
La registrazione è facoltativa. Se non configuri le proprietà di destinazione dei log, la simulazione non produrrà log.

È obbligatoria solo la proprietà `default_entity_index_key_type`. L'unico valore valido è `Vector3<f32>`.

# Worker
<a name="working-with_configuring-simulation_workers"></a>

La `workers` sezione specifica il tipo e il numero di lavoratori che desideri per la simulazione. SimSpace Weaver utilizza i propri tipi di worker mappati ai tipi di EC2 istanze Amazon. 

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 1
```

## Abilitazione di simulazioni con più lavoratori
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

È possibile creare una simulazione che utilizzi più di un lavoratore. Per impostazione predefinita, le simulazioni utilizzano 1 lavoratore. È necessario modificare lo schema di simulazione prima di iniziare la simulazione. 

**Nota**  
Non è possibile modificare una simulazione già iniziata. Se desideri abilitare multiworker per una simulazione in esecuzione, devi prima interrompere ed eliminare la simulazione.

Per utilizzare più di un worker, imposta il `desired` numero di istanze di calcolo su un valore maggiore di 1. È previsto un numero massimo di app per ogni lavoratore. Per ulteriori informazioni, vedere[SimSpace Endpoint e quote Weaver](service-quotas.md). SimSpace Weaver utilizzerà più di 1 worker solo quando il numero di app su un worker supera questo limite. SimSpace Weaver può inserire un'app su uno qualsiasi dei lavoratori disponibili. Il posizionamento dell'app su un lavoratore specifico non è garantito. 

Il seguente frammento di schema mostra una configurazione per una simulazione che richiede 2 lavoratori. SimSpace Weaver tenterà di assegnare il secondo lavoratore se il numero di app supera il numero massimo di app per 1 lavoratore.

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 2
```

# Orologio
<a name="working-with_configuring-simulation_clock"></a>

La `clock` sezione specifica le proprietà dell'orologio di simulazione. Attualmente, puoi solo configurare la **frequenza dei tick** (il numero di tick al secondo che l'orologio invia alle app). Il tick-rate è il tasso massimo. La percentuale di tick effettiva potrebbe essere inferiore perché tutte le operazioni (come gli aggiornamenti delle entità) relative a un segno di spunta devono essere completate prima che possa iniziare il tick successivo. **Il tick rate è anche chiamato clock rate.**

I valori validi per `tick_rate` dipendono da quelli `sdk_version` specificati nello schema.

**Valori validi per il tick-rate**
+ Versioni precedenti a`"1.14"`:
  + `10`
  + `15`
  + `30`
+ Versione `"1.14"` o successiva:
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Per ulteriori informazioni, consulta [Tick rate illimitato](#working-with_configuring-simulation_clock_unlimited).

**Importante**  
Per gli schemi `"1.14"` il cui valore `sdk_version` precedente a `tick_rate` è un **numero intero**, ad esempio. `30`
Per gli schemi con un `sdk_version` `"1.14"` o successivo, il valore di `tick_rate` è una **stringa**, ad esempio. `"30"` Il valore **deve includere le virgolette doppie**.  
Se si converte una versione `"1.12"` o `"1.13"` uno schema in una versione `"1.14"` o successiva, è necessario racchiudere il valore di `tick_rate` tra virgolette doppie.

## Tick rate illimitato
<a name="working-with_configuring-simulation_clock_unlimited"></a>

Puoi impostare to per consentire `tick_rate` `"unlimited"` alla simulazione di funzionare alla stessa velocità di esecuzione del codice. Con una frequenza di selezione illimitata, SimSpace Weaver invia il segno di spunta successivo immediatamente dopo che tutte le app hanno completato i commit per il segno di spunta corrente.

**Importante**  
La frequenza di selezione illimitata non è supportata nelle versioni precedenti alla 1.14.0. SimSpace Weaver Il valore minimo di `sdk_version` nello schema è. `"1.14"`

**Tick rate illimitato in SimSpace Weaver Local**  
SimSpace Weaver Localimplementa `"unlimited"` come se lo schema specificasse una frequenza di tick di 10 kHz (10000). L'effetto è lo stesso di una frequenza di tick illimitata in. Cloud AWS Lo specifichi ancora `tick_rate: "unlimited"` nel tuo schema. Per ulteriori informazioni su SimSpace Weaver Local, consultare [Sviluppo locale in SimSpace Weaver](working-with_local-development.md).

## Domande frequenti sull'orologio
<a name="working-with_configuring-simulation_clock_faq"></a>

### D1. Posso modificare una simulazione STARTED per utilizzare un tick rate diverso?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

Non è possibile modificare il tick rate di una simulazione già esistente in qualsiasi Cloud AWS fase del suo ciclo di vita. Inoltre, non puoi modificare il tick rate di una simulazione in corso. SimSpace Weaver Local Puoi impostarlo `tick_rate` nello schema e iniziare una nuova simulazione da quello schema.

### D2. Posso eseguire la mia simulazione con un tick rate illimitato in una versione precedente alla 1.14?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

No, il tick rate illimitato non è supportato nelle versioni precedenti alla 1.14.0.

## Risoluzione degli errori dell'orologio
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Se la simulazione non si avvia, puoi controllare il valore di `"StartError"` nell'output dell'**DescribeSimulation**API. Un `tick_rate` valore non valido nello schema produrrà i seguenti errori.

**Nota**  
L'output di errore mostrato qui viene visualizzato su più righe per migliorare la leggibilità. L'output di errore effettivo è una singola riga.
+ `sdk_version`è precedente a `"1.14"` e il valore di `tick_rate` è un numero intero non valido. Valori validi: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ `sdk_version`è precedente a `"1.14"` e il valore di `tick_rate` è una stringa. Valori validi: `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"},
      {\"errorType\":\"SchemaFormatInvalid\",
      \"errorMessage\":\"$.clock.tick_rate: string found, integer expected\"}]"
  ```
+ `sdk_version`è `"1.14"` o successivo e il valore di `tick_rate` è una stringa non valida. Valori validi: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"}]"
  ```
+ `sdk_version`È `"1.14"` o successivo e il valore di `tick_rate` è un numero intero. Valori validi: `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"},
      {\"errorType\":\"SchemaFormatInvalid\",
      \"errorMessage\":\"$.clock.tick_rate: integer found, string expected\"}]"
  ```

# Strategie di partizionamento
<a name="working-with_configuring-simulation_partitioning-strategies"></a>

La `partitioning_strategies` sezione specifica le proprietà di configurazione per le partizioni delle app spaziali. È possibile fornire il proprio nome per una strategia di partizionamento (un insieme di proprietà in questa sezione) e utilizzarlo nella configurazione dell'app spaziale.

```
partitioning_strategies:
  MyGridPartitioning:
    topology: "Grid"
    aabb_bounds:
      x: [0, 1000]
      y: [0, 1000]
    grid_placement_groups:
      x: 1
      y: 1
```

La `topology` proprietà specifica il tipo di sistema di coordinate utilizzato dalla simulazione. Il valore `Grid` specifica una griglia bidimensionale (2D).

Per una `Grid` topologia, lo spazio di simulazione è modellato come un riquadro di delimitazione allineato agli assi (AABB). Specificate i limiti delle coordinate per ogni asse del vostro AABB nella proprietà. `aabb_bounds` Tutte le entità che esistono spazialmente nella simulazione devono avere una posizione all'interno dell'AABB.

## Gruppi di posizionamento sulla griglia
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

Un **gruppo di collocamento** è una raccolta di partizioni spaziali di app che si desidera SimSpace Weaver posizionare sullo stesso lavoratore. È possibile specificare il numero e la disposizione dei gruppi di collocamento (in una griglia) nella `grid_placement_groups` proprietà. SimSpace Weaver tenterà di distribuire uniformemente le partizioni tra i gruppi di posizionamento. Le aree di proprietà delle app spaziali con partizioni nello stesso gruppo di posizionamento saranno spazialmente adiacenti.

Si consiglia che x \$1 y sia uguale al numero di lavoratori desiderato. Se non è uguale, SimSpace Weaver cercheremo di bilanciare i gruppi di collocamento tra i lavoratori disponibili.

Se non specifichi una configurazione del gruppo di collocamento, ne SimSpace Weaver calcolerà una per te.

# Domini
<a name="working-with_configuring-simulation_domains"></a>

Fornisci un nome per un set di proprietà di configurazione per un dominio. L'impostazione di avvio per le app in un dominio determina il tipo di dominio:
+ **`launch_apps_via_start_app_call`**— dominio personalizzato
+ **`launch_apps_by_partitioning_strategy`**— dominio spaziale
+ **`launch_apps_per_worker`**(non incluso nell'applicazione di esempio) — dominio di servizio

**Importante**  
SimSpace Weaver supporta fino a 5 domini per ogni simulazione. Ciò include tutti i domini spaziali, personalizzati e di servizio.

```
domains:
  MyViewDomain:
    launch_apps_via_start_app_call: {}
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 7000
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

**Nota**  
SimSpace Weaver I progetti app SDK versione 1.12.x utilizzano bucket separati per i file.zip dell'app e lo schema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -schemi- *lowercase-project-name* *account-number* *region*

**Topics**
+ [Configurazione dell'app](working-with_configuring-simulation_domains_app-config.md)
+ [Configurazione dei domini spaziali](working-with_configuring-simulation_domains_spatial.md)
+ [Endpoint di rete](working-with_configuring-simulation_domains_endpoints.md)
+ [Configurazione dei domini di servizio](working-with_configuring-simulation_domains_service-domains.md)

# Configurazione dell'app
<a name="working-with_configuring-simulation_domains_app-config"></a>

Specificate la configurazione di un'app (`app_config`) come parte della configurazione per il relativo dominio. Tutti i tipi di domini utilizzano le stesse proprietà di configurazione dell'app.

```
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
```

**Nota**  
SimSpace Weaver I progetti app SDK versione 1.12.x utilizzano bucket separati per i file.zip dell'app e lo schema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -schemi- *lowercase-project-name* *account-number* *region*

La `package` proprietà specifica l'URI S3 di un file zip in un bucket S3. Il file zip contiene l'eseguibile dell'app (chiamato anche *binario*) e tutte le altre risorse di cui ha bisogno (come le librerie). Ogni istanza dell'eseguibile dell'app viene eseguita in un Docker contenitore su un worker. 

La `launch_command` proprietà specifica il nome dell'eseguibile e le eventuali opzioni della riga di comando per eseguire l'app. Il valore di `launch_command` è un array. Ogni token dell'intera stringa di comando di avvio è un elemento dell'array.

**Esempio**
+ Per il comando di avvio: `MyTestApp --option1 value1`
+ Specificare: `launch_command: ["MyTestApp", "-option1", "value1"]`

La `required_resource_units` proprietà specifica il numero di unità di risorse di calcolo da SimSpace Weaver allocare a questa app. Un'unità di risorse di calcolo è una quantità fissa di capacità di elaborazione (vCPU) e memoria (RAM) su un lavoratore. È possibile aumentare questo valore per aumentare la quantità di potenza di calcolo disponibile per l'app quando viene eseguita su un worker. Esiste un numero limitato di unità di risorse di calcolo per ogni lavoratore. Per ulteriori informazioni, consulta [SimSpace Endpoint e quote Weaver](service-quotas.md).

# Configurazione dei domini spaziali
<a name="working-with_configuring-simulation_domains_spatial"></a>

Per i domini spaziali, è necessario specificare un. `partitioning_strategy` Il valore di questa proprietà è il nome assegnato a una strategia di partizionamento definita in un'altra parte dello schema. 

```
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

**Nota**  
SimSpace Weaver I progetti app SDK versione 1.12.x utilizzano bucket separati per i file.zip dell'app e lo schema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -schemi- *lowercase-project-name* *account-number* *region*

Una strategia di partizionamento con una `Grid` topologia (l'unica topologia supportata in questa versione) consente di disporre le partizioni spaziali delle app di questo SimSpace Weaver dominio in una griglia. La `grid_partition` proprietà specifica il numero di righe e colonne della griglia di partizione. 

SimSpace Weaver avvierà 1 istanza dell'app spaziale per ogni cella nella griglia di partizione. Ad esempio, se un dominio spaziale ha `grid_partition` valori `x: 2` e `y: 2` ci sono 2 \$1 2 = 4 partizioni nel dominio spaziale. SimSpace Weaver avvierà 4 istanze dell'app configurate nel dominio spaziale e assegnerà 1 partizione a ciascuna istanza dell'app.

**Argomenti**
+ [Requisiti di risorse per i domini spaziali](#working-with_configuring-simulation_domains_spatial_resources)
+ [Domini spaziali multipli](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Domande frequenti sui domini spaziali](#working-with_configuring-simulation_domains_spatial_faq)
+ [Risoluzione dei problemi relativi ai domini spaziali](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Requisiti di risorse per i domini spaziali
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

È possibile assegnare fino a 17 unità di risorse di calcolo per ogni lavoratore. Specificate il numero di unità di risorse di calcolo utilizzate da ogni app spaziale nella `app_config` sezione del vostro dominio spaziale.

**Example frammento di schema che mostra le unità di risorse di calcolo per un'app spaziale**  

```
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
```

Per calcolare il numero di unità di risorse di calcolo richieste da un dominio, moltiplica il numero di celle nella griglia (nel tuo`grid_partition`, `x` \$1`y`) per il numero di unità di risorse di calcolo assegnate alle app spaziali.

Nell'esempio precedente, il dominio specifica: `MySpatialDomain`
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

La griglia per `MySpatialDomain` ha 2\$1 2 = 4 celle. Il dominio spaziale richiede 4\$1 1 = 4 unità di risorse di calcolo.

Il numero totale di unità di risorse di calcolo per tutti i domini specificati nello schema deve essere inferiore o uguale al numero di worker moltiplicato per il `desired` numero massimo di unità di risorse di calcolo per ogni lavoratore (17).

## Domini spaziali multipli
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

È possibile configurare la simulazione per utilizzare più di un dominio spaziale. Ad esempio, puoi utilizzare 1 dominio spaziale per controllare gli attori principali di una simulazione (come persone e automobili) e un dominio spaziale diverso per controllare l'ambiente.

Puoi anche utilizzare più domini spaziali per assegnare risorse diverse a diverse parti della simulazione. Ad esempio, se la simulazione ha un tipo di entità che ha 10 volte più istanze di entità rispetto a un altro tipo, è possibile creare domini diversi per gestire ciascun tipo di entità e allocare più risorse per il dominio con più entità.

**Importante**  
SimSpace Weaver le versioni precedenti alla 1.14.0 non supportano più domini spaziali.

**Importante**  
AWS SimSpace Weaver Localattualmente non supporta più domini spaziali. Per ulteriori informazioni su SimSpace Weaver Local, consultare [Sviluppo locale in SimSpace Weaver](working-with_local-development.md).

**Importante**  
SimSpace Weaver supporta fino a 5 domini per ogni simulazione. Ciò include tutti i domini spaziali, personalizzati e di servizio.

### Configura più domini spaziali
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Per configurare più di un dominio spaziale, aggiungi le altre definizioni di dominio spaziale come sezioni denominate separate nello schema. Ogni dominio deve specificare la chiave. `launch_apps_by_partitioning_strategy` Vedi lo schema di esempio seguente.

```
sdk_version: "1.14"
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 1
clock:
  tick_rate: "30"
partitioning_strategies:
  MyGridPartitioning:
    topology: Grid
    aabb_bounds:
      x: [0, 1000]
      y: [0, 1000]
domains:
  MySpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp.zip"
      launch_command: ["MySpatialApp"]
      required_resource_units:
        compute: 1
  MySecondSpatialDomain:
    launch_apps_by_partitioning_strategy:
      partitioning_strategy: "MyGridPartitioning"
      grid_partition:
        x: 2
        y: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-artifacts-us-west-2/MySpatialApp2.zip"
      launch_command: ["MySpatialApp2"]
      required_resource_units:
        compute: 1
```

### Collocazione di domini spaziali
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

In alcuni scenari, potresti voler posizionare le partizioni per un dominio spaziale sui worker accanto alle partizioni di un altro dominio. Ciò può migliorare le caratteristiche prestazionali se tali partizioni creano sottoscrizioni tra domini diversi.

Aggiungi la chiave `placement_constraints` di primo livello allo schema per specificare quali domini SimSpace Weaver devono essere messi insieme. La `on_workers` chiave richiesta deve fare riferimento a una `workers` configurazione denominata nello schema.

**Example frammento di schema che mostra i domini spaziali messi insieme**  

```
workers:
  MyComputeWorkers:
    type: "sim.c5.24xlarge"
    desired: 2
placement_constraints:
  - placed_together: ["MySpatialDomain", "MySecondSpatialDomain"]
    on_workers: ["MyComputeWorkers"]
```

**Importante**  
Se si utilizzano gruppi di collocamento:  
Assicurati che x \$1 y sia un multiplo del numero di lavoratori.
Assicurati che i valori del gruppo di posizionamento siano divisori comuni per le dimensioni della griglia dei domini che metti insieme.
Se **non utilizzi** i gruppi di collocamento:  
Assicurati che 1 asse delle griglie del dominio spaziale abbia un divisore comune uguale al numero di lavoratori.
Per ulteriori informazioni sui gruppi di collocamento, vedere. [Strategie di partizionamento](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups)

## Domande frequenti sui domini spaziali
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### D1. Come posso aggiungere un altro dominio spaziale a una simulazione esistente?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Per una simulazione in esecuzione**: non è possibile modificare la configurazione di una simulazione di esecuzione. Modifica la configurazione del dominio nello schema, carica lo schema e gli zip dell'app e avvia una nuova simulazione.
+ **Per una nuova simulazione**: aggiungi la configurazione del dominio allo schema, carica lo schema e gli zip dell'app e avvia la nuova simulazione.

## Risoluzione dei problemi relativi ai domini spaziali
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

È possibile che venga visualizzato il seguente errore quando si tenta di avviare la simulazione ma la configurazione del dominio non è valida.

```
"StartError": "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
    \"We were unable to determine an arrangement of your domains that would fit 
    within the provided set of workers. This can generally be resolved by 
    increasing the number of workers if able, decreasing your domains\u0027 
    [\u0027\u0027grid_partition\u0027\u0027] values, or adjusting the 
    dimensions of your [\u0027\u0027grid_placement_groups\u0027\u0027].\"}]"
```

**Cause potenziali**
+ Lo schema alloca per le app un numero di unità di risorse di calcolo superiore a quello disponibile per i worker.
+ SimSpace Weaver non è in grado di stabilire una disposizione per l'assegnazione dei domini ai lavoratori. Ciò accade quando si specificano più domini spaziali ma non esiste un divisore o un multiplo comune tra le griglie di dominio, ad esempio tra una griglia 2x4 e una griglia 3x5).

# Endpoint di rete
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Le app personalizzate e di servizio possono avere endpoint di rete a cui i client esterni possono connettersi. Si specifica un elenco di numeri di porta come valore per `ingress_ports` in. `endpoint_config` Questi numeri di porta sono sia TCP che UDP. L'app personalizzata o di servizio deve essere associata ai numeri di porta specificati in. `ingress_ports` SimSpace Weaver alloca dinamicamente i numeri di porta in fase di esecuzione e associa queste porte alle porte dinamiche. Puoi chiamare l'**describe-app**API dopo che le tue app hanno iniziato a trovare i numeri di porta dinamici (effettivi). Per ulteriori informazioni, [Ottieni l'indirizzo IP e il numero di porta di un'app personalizzataOttieni l'indirizzo IP e il numero di porta](working-with_get-ip.md) consulta il tutorial di avvio rapido.

```
domains:
  MyViewDomain:
    launch_apps_via_start_app_call: {}
    app_config:
      package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip"
      launch_command: ["MyViewApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 7000
```

**Nota**  
SimSpace Weaver I progetti app SDK versione 1.12.x utilizzano bucket separati per i file.zip dell'app e lo schema:  
weaver- - -app-zips- *lowercase-project-name* *account-number* *region*
weaver- - -schemi- *lowercase-project-name* *account-number* *region*

**Nota**  
`endpoint_config`è una proprietà opzionale per app personalizzate e app di servizio. Se non specifichi un`endpoint_config`, l'app non avrà un endpoint di rete.

# Configurazione dei domini di servizio
<a name="working-with_configuring-simulation_domains_service-domains"></a>

La presenza di `launch_apps_per_worker:` in una configurazione di dominio indica che si tratta di un dominio di servizio con app di servizio. SimSpace Weaver avvia e arresta automaticamente le app di servizio. Quando SimSpace Weaver avvia e arresta un'app, si considera che l'app abbia un *ciclo di vita gestito*. SimSpace Weaver attualmente supporta l'avvio di 1 o 2 app di servizio su ogni lavoratore. 

**Example Esempio di dominio configurato per avviare 1 app di servizio su ogni lavoratore**  

```
domains:
  MyServiceDomain:
    launch_apps_per_worker:
      count: 1
    app_config:
      package: "s3://weaver-myproject-111122223333-app-zips-us-west-2/PlayerConnectionServiceApp.zip"
      launch_command: ["PlayerConnectionServiceApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 9000
          - 9001
```

**Example Esempio di dominio configurato per avviare 2 app di servizio su ciascun lavoratore**  

```
domains:
  MyServiceDomain:
    launch_apps_per_worker:
      count: 2
    app_config:
      package: "s3://weaver-myproject-111122223333-app-zips-us-west-2/PlayerConnectionServiceApp.zip"
      launch_command: ["PlayerConnectionServiceApp"]
      required_resource_units:
        compute: 1
      endpoint_config:
        ingress_ports:
          - 9000
          - 9001
```

# Durata massima di una simulazione
<a name="working-with_max-duration"></a>

Ogni simulazione AWS SimSpace Weaver ha un'impostazione di *durata massima* che specifica il tempo massimo di esecuzione della simulazione. La durata massima viene fornita come parametro quando si avvia una simulazione. L'[interfaccia di programmazione dell'`StartSimulation`applicazione (API)](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) ha un parametro `MaximumDuration` opzionale. Il valore del parametro è un numero di minuti (m o M), ore (h o H) o giorni (d o D). Ad esempio, `1h` o `1H` significa 1 ora. SimSpace Weaver interrompe la simulazione quando raggiunge questo limite.

## Valore massimo
<a name="working-with_max-duration_max-value"></a>

Il valore più alto valido per `MaximumDuration` è`14D`, o il suo equivalente in ore (`336H`) o minuti (`20160M`).

## Valore predefinito
<a name="working-with_max-duration_default-value"></a>

Il parametro `MaximumDuration` è facoltativo. Se non fornisci un valore, SimSpace Weaver utilizza un valore di`14D`.

## Valore minimo
<a name="working-wtih_max-duration_min-value"></a>

Il valore più basso valido per `MaximumDuration` è un valore numericamente equivalente a`0`. Ad esempio, i valori`0M`, e `0H``0D`, sono tutti equivalenti numericamente a. `0`

Se si fornisce il valore minimo per la durata massima, la simulazione passa immediatamente allo `STOPPING` stato non appena raggiunge lo stato. `STARTED`

## Avvio di una simulazione tramite la console
<a name="working-with_max-duration_console"></a>

[È possibile fornire un valore per la **durata massima** quando si avvia una simulazione nella SimSpace Weaver console.](https://console.aws.amazon.com/simspaceweaver) Inserisci il valore nel campo **Durata massima** del modulo **Impostazioni di simulazione** quando scegli **Avvia** simulazione.

**Importante**  
Se non fornite un valore per **Durata massima**, SimSpace Weaver utilizza il [valore predefinito](#working-with_max-duration_default-value) ()`14D`.

## Lo stato di una simulazione che raggiunge la sua durata massima
<a name="working-with_max-duration_sim-state"></a>

Quando interrompe SimSpace Weaver automaticamente una simulazione che raggiunge la sua durata massima, lo **stato** della simulazione è `STOPPING` (se in corso) o. `STOPPED` Nella [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver), lo **stato di destinazione** della simulazione è fisso`STARTED`, poiché quello era l'ultimo stato richiesto da un utente.

# Sviluppo di app
<a name="working-with_developing-apps"></a>

SimSpace Weaver lo sviluppo richiede un Amazon Linux 2 (AL2) ambiente in cui creare app perché le tue simulazioni vengono eseguite su Amazon Linux nel AWS Cloud. Se stai usando Windows, puoi utilizzare gli script nell'SDK dell' SimSpace Weaver app per creare e avviare un Docker contenitore che funziona AL2 con le dipendenze necessarie per creare SimSpace Weaver app. Puoi anche lanciare un AL2 ambiente utilizzando Windows Subsystem for Linux (WSL)o usa un nativo AL2 sistema. Per ulteriori informazioni, consulta [Configura il tuo ambiente locale per SimSpace Weaver](setting-up_local.md).

**Nota**  
Indipendentemente da come configuri il tuo ambiente di sviluppo locale, le tue app vengono eseguite in Docker contenitori quando li carichi per eseguirli in Cloud AWS. **Le tue app non hanno accesso diretto al sistema operativo host**.

**Flusso generale di un' SimSpace Weaver app**

1. Crea un'applicazione di .

1. Ciclo continuo:

   1. Inizia l'aggiornamento creando un`Transaction`.

      1. Esci dal loop se la simulazione si sta chiudendo.

   1. Elabora gli eventi delle entità di sottoscrizione e proprietà.

   1. Aggiorna la simulazione.

   1. Impegnati `Transaction` a terminare l'aggiornamento.

1. Distruggi l'applicazione.

## App spaziali
<a name="working-with_developing-apps_spatial-apps"></a>

Ogni app spaziale ha un'area di proprietà che è una regione spaziale del mondo della simulazione. Le entità situate nell'area di proprietà di un'app spaziale vengono archiviate nella partizione assegnata all'app. La singola app spaziale ha la piena proprietà (autorizzazioni di lettura e scrittura) su tutte le entità all'interno della partizione assegnata. Nessun'altra app può scrivere su tali entità. L'app spaziale fa avanzare lo stato delle sue entità. Ogni app spaziale possiede solo 1 partizione. SimSpace Weaver utilizza la posizione spaziale di un'entità per indicizzarla e assegnarla a una partizione spaziale dell'app.

L'SDK dell' SimSpace Weaver app fornisce un'applicazione di esempio. Puoi trovare il codice sorgente per l'app spaziale dell'applicazione di esempio nella seguente cartella (usa il separatore di percorso corretto per il tuo sistema operativo): 

```
sdk-folder\Samples\PathfindingSample\src\SpatialApp
```

## App personalizzate
<a name="working-with_developing-apps_custom-apps"></a>

Puoi creare e utilizzare app personalizzate per interagire con la simulazione. 

**Le app personalizzate possono**
+ Creare entità
+ Sottoscrivi ad altre partizioni
+ Conferma le modifiche

**Flusso generale di un'app personalizzata**

1. Crea un'applicazione di .

1. Iscriviti a una regione specifica della simulazione:

   1. Crea un file `Transaction` per iniziare il primo aggiornamento.

   1. Crea un abbonamento per la regione specifica.

   1. `Transaction`Impegnati a terminare il primo aggiornamento.

1. Ciclo continuo:

   1. Crea un `Transaction` file per iniziare l'aggiornamento.

      1. Esci dal loop se la simulazione si sta chiudendo.

   1. Modifiche allo stato del processo.

   1. `Transaction`Impegnati a terminare l'aggiornamento.

1. Distruggi l'applicazione.

Dopo che un'app personalizzata ha creato un'entità, deve trasferirla in un dominio spaziale affinché l'entità esista spazialmente all'interno della simulazione. SimSpace Weaver utilizza la posizione spaziale dell'entità per posizionarla nella partizione spaziale appropriata dell'app. L'app personalizzata che ha creato l'entità non può aggiornare o eliminare l'entità dopo averla trasferita in un dominio spaziale. 

L'SDK SimSpace Weaver dell'app fornisce un'applicazione di esempio. Puoi utilizzare le app personalizzate incluse nell'applicazione di esempio come modelli per le tue app personalizzate. Puoi trovare il codice sorgente per l'app view (un'app personalizzata) dell'applicazione di esempio nella seguente cartella (usa il separatore di percorso corretto per il tuo sistema operativo):

```
sdk-folder\Samples\PathfindingSample\src\ViewApp
```

# Sviluppo di applicazioni client
<a name="working-with_developing-client-applications"></a>

Alcuni dei motivi per cui potresti voler connettere un client a una simulazione includono:
+ Inserisci informazioni sul traffico in tempo reale in una simulazione su scala urbana.
+ Crea *human-in-the-loop*simulazioni, in cui un operatore umano controlla alcuni aspetti della simulazione.
+ Consenti agli utenti di interagire con la simulazione, ad esempio per una simulazione di addestramento.

Le app personalizzate in questi esempi fungono da interfaccia tra lo stato di simulazione e il mondo esterno. I client si connettono alle app personalizzate per interagire con la simulazione. 

SimSpace Weaver non gestisce le applicazioni client e la loro comunicazione con le app personalizzate. Sei responsabile della progettazione, della creazione, del funzionamento e della sicurezza delle tue applicazioni client e della loro comunicazione con le tue app personalizzate. SimSpace Weaver espone solo un indirizzo IP e un numero di porta per ciascuna delle tue app personalizzate in modo che i client possano connettersi ad esse. 

L'SDK SimSpace Weaver dell'app fornisce client per la sua applicazione di esempio. È possibile utilizzare questi client come modelli per le proprie applicazioni client. È possibile trovare il codice sorgente per i client applicativi di esempio nella seguente cartella: 

------
#### [ Docker ]

```
sdk-folder\packaging-tools\clients\PathfindingSampleClients
```

------
#### [ WSL ]

**Importante**  
Forniamo queste istruzioni per facilitarvi l'uso. Sono destinate all'uso con Windows Subsystem for Linux (WSL)e non sono supportati. Per ulteriori informazioni, consulta [Configura il tuo ambiente locale per SimSpace Weaver](setting-up_local.md).

```
sdk-folder/packaging-tools/clients/PathfindingSampleClients
```

------

Per ulteriori informazioni sulla creazione e l'utilizzo dei client applicativi di esempio, consulta i tutorial in. [Guida introduttiva con SimSpace Weaver](getting-started.md) 

# Ottieni l'indirizzo IP e il numero di porta di un'app personalizzata
<a name="working-with_get-ip"></a>

Per visualizzare la simulazione, devi creare un'app personalizzata e connetterti ad essa con un client. Per ulteriori informazioni, consulta i tutorial in. [Guida introduttiva con SimSpace Weaver](getting-started.md) È possibile utilizzare la procedura seguente per ottenere l'indirizzo IP e il numero di porta dell'app personalizzata. Utilizzate il separatore di percorso appropriato per il vostro sistema operativo (ad esempio, `\` in Windows e `/` Linux).

**Per ottenere l'indirizzo IP e il numero di porta**

1. Usa l'** ListSimulations**API per ottenere il nome della tua simulazione.

   ```
   aws simspaceweaver list-simulations
   ```

   Output di esempio:

   ```
   {
       "Simulations": [
           {
               "Status": "STARTED",
               "CreationTime": 1664921418.09,
               "Name": "MyProjectSimulation_22-10-04_22_10_15",
               "Arn": "arn:aws:simspaceweaver:us-west-2: 111122223333:simulation/MyProjectSimulation_22-10-04_22_10_15",
               "TargetStatus": "STARTED"
           }
       ]
   
   }
   ```

1. Usa l'** DescribeSimulation**API per ottenere un elenco di domini nella tua simulazione.

   ```
   aws simspaceweaver describe-simulation --simulation simulation-name
   ```

   Cerca la `Domains` sezione nella `LiveSimulationState` sezione dell'output.

   Output di esempio:

   ```
       "LiveSimulationState": {
           "Domains": [
               {
                   "Type": "",
                   "Name": "MySpatialSimulation",
                   "Lifecycle": "Unknown"
               },
               {
                   "Type": "",
                   "Name": "MyViewDomain",
                   "Lifecycle": "ByRequest"
               }
           ],
   ```

1. Usa l'** ListApps**API per ottenere un elenco di app personalizzate in un dominio. Ad esempio, il nome di dominio per l'app di visualizzazione (personalizzata) nel progetto di esempio è`MyViewDomain`. Cerca il nome dell'app nell'output.

   ```
   aws simspaceweaver list-apps --simulation simulation-name --domain domain-name
   ```

   Output di esempio:

   ```
    
   {
       "Apps": [
           {
               "Status": "STARTED",
               "Domain": "MyViewDomain",
               "TargetStatus": "STARTED",
               "Name": "ViewApp",
               "Simulation": "MyProjectSimulation_22-10-04_22_10_15"
           }
       ]
   }
   ```

1. Usa l'** DescribeApp**API per ottenere l'indirizzo IP e il numero di porta. Per il progetto di esempio, il nome di dominio è `MyViewDomain` e il nome dell'app è`ViewApp`. 

   ```
   aws simspaceweaver describe-app --simulation simulation-name --domain domain-name --app app-name
   ```

   L'indirizzo IP e il numero di porta si trovano nel `EndpointInfo` blocco dell'output. L'indirizzo IP è il valore di `Address` e il numero di porta è il valore di`Actual`.

   Output di esempio:

   ```
   {
       "Status": "STARTED",
       "Domain": "MyViewDomain",
       "TargetStatus": "STARTED",
       "Simulation": "MyProjectSimulation_22-10-04_22_10_15",
       "LaunchOverrides": {
           "LaunchCommands": []
       },
       "EndpointInfo": {
           "IngressPortMappings": [
               {
                   "Declared": 7000,
                   "Actual": 4321
               }
           ],
           "Address": "198.51.100.135"
       },
       "Name": "ViewApp"
   }
   ```
**Nota**  
Il valore di `Declared` è il numero di porta a cui deve essere associato il codice dell'app. Il valore di `Actual` è il numero di porta che SimSpace Weaver i client possono connettersi alla tua app. SimSpace Weaver mappa la `Declared` porta alla `Actual` porta.

# Avvio del client di visualizzazione Unreal Engine
<a name="working-with_unreal-client"></a>

 Vai a: 

```
sdk-folder/Samples/PathfindingSample/tools/cloud
```

1. Eseguire uno dei seguenti comandi:
   + Docker: `python quick-start.py`
   + WSL: `python quick-start.py --al2`

1. Ottieni l'indirizzo IP e il numero di porta «effettivo». Questi saranno presenti nell'output della console dopo l'esecuzione di quick-start.py, oppure li otterrete seguendo le procedure riportate in[Ottieni l'indirizzo IP e il numero di porta di un'app personalizzataOttieni l'indirizzo IP e il numero di porta](working-with_get-ip.md).

1.  Vai a: 

   ```
   sdk-folder/Clients/TCP/UnrealClient/lib
   ```

1.  Esegui i seguenti comandi per creare la libreria NNG: 

   ```
   cmake -S . -B build 
   cmake --build build --config RelWithDebInfo 
   cmake --install build
   ```

1.  In un **editor di testo**, apri`view_app_url.txt`. 

1.  Aggiorna l'URL con l'indirizzo IP e il numero di porta dell'app View: `tcp://ip-address:actual-port-number` (dovrebbe apparire così`tcp://198.51.100.135:1234`). 

1.  Nell'**editor di Unreal**, scegli **play**. 

## Risoluzione dei problemi
<a name="working-with_unreal-client_troubleshooting"></a>
+  **La fase di CMake installazione di NNG fallisce con «Forse sono necessari i privilegi amministrativi «:** 

  ```
  CMake Error at build/_deps/nng-build/src/cmake_install.cmake:39 (file):
    file cannot create directory: C:/Program Files
    (x86)/ThirdPartyNngBuild/lib.  Maybe need administrative privileges.
  Call Stack (most recent call first):
    build/_deps/nng-build/cmake_install.cmake:37 (include)
    build/cmake_install.cmake:73 (include)
  ```
  +  **Risoluzione:** se `nng.lib` o `nng.so` esiste nella directory UnrealClient /lib, questo errore può essere tranquillamente ignorato. In caso contrario, prova a eseguire i comandi cmake build in un terminale con privilegi di amministratore. 
+  **«CMake per trovare un file di configurazione del pacchetto fornito da nng»:** 

  ```
  CMake Error at CMakeLists.txt:23 (find_package):
  By not providing "Findnng.cmake" in CMAKE_MODULE_PATH this project has
   asked CMake to find a package configuration file provided by "nng", but
   CMake did not find one.
  ```
  +  **Risoluzione:** CMake ha problemi a trovare il `Findnng.cmake` file. Quando costruisci con CMake, aggiungi l'argomento`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Assicurati che il `Findnng.cmake` file sia ancora nella `ThirdParty` directory prima di eseguire nuovamente la build. CMake 

    ```
    cmake -S . -B build -DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty
    cmake --build build --config RelWithDebInfo 
    cmake --install build
    ```

# Sviluppo locale in SimSpace Weaver
<a name="working-with_local-development"></a>

Puoi distribuire SimSpace Weaver le tue applicazioni localmente per test e debug rapidi.

**Requisiti**
+ Completa le fasi descritte in [Configurazione per SimSpace Weaver](setting-up.md).

**Topics**
+ [Fase 1: Avvia la simulazione locale](working-with_local_launch.md)
+ [Fase 2: Visualizza la simulazione locale](working-with_local-development_view.md)
+ [Passaggio 3: Interrompi la simulazione locale (opzionale su Windows)](working-with_local-development_stop-sim.md)
+ [Risoluzione dei problemi di sviluppo locale in SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Fase 1: Avvia la simulazione locale
<a name="working-with_local_launch"></a>

1. Vai a

   ```
   cd sdk-folder/Samples/sample-name/tools/local
   ```

1. Esegui il seguente comando per creare e avviare la simulazione localmente.

   ```
   python quick-start.py
   ```

   Questo script eseguirà le seguenti operazioni:

   1. Compilare il progetto.
      +  `quick-start.py`chiama la `build_project` funzione definita in build.py. Questo passaggio varierà a seconda del progetto. Per il PathfindingSample, CMake viene utilizzato. Il comando CMake and Docker per cui è disponibile in build.py. 

   1. Avvia la tua simulazione locale
      + Lo script avvierà un processo locale per ogni partizione spaziale definita nello schema.
      + Lo script avvierà un processo per ogni app personalizzata definita nello schema.
      + Le app spaziali verranno avviate per prime, seguite dalle app personalizzate, ciascuna nell'ordine in cui appaiono nello schema.

**Importante**  
Quando si avvia in un ambiente che non supporta la GUI, ad esempio una sessione SSH della console, utilizza l'`--noappwindow`opzione per reindirizzare tutto l'output al terminale corrente.

**Importante**  
Per gli utenti Linux, lo script presuppone che il sistema disponga del comando. `xterm` Se la vostra distribuzione Linux non dispone del `xterm` comando, utilizzate l'`--noappwindow`opzione per reindirizzare tutto l'output al terminale corrente.
+  -h, --help 
  +  Elenca questi parametri. 
+  --clean 
  +  Elimina il contenuto della cartella di compilazione prima della compilazione. 
+  --nobuild 
  +  Salta la ricostruzione del progetto. 
+  --nessuna finestra dell'app 
  +  Non aprire una nuova finestra per ogni app. Invece, reindirizza lo stdout al terminale corrente. 
+  --logfile 
  +  Scrive l'output della console in un file di registro. 
+  --consoleclient 
  +  Connetti automaticamente il client della console elencato nella configurazione. 
+  SCHEMA --schema
  + Quale schema utilizzerà questa invocazione. Il valore predefinito è 'SCHEMA' in config.py. 

# Fase 2: Visualizza la simulazione locale
<a name="working-with_local-development_view"></a>

Per visualizzare la simulazione locale, puoi utilizzare uno qualsiasi dei client inclusi in. SimSpaceWeaverAppSdkDistributable Per ulteriori informazioni sulla creazione e l'utilizzo dei client di esempio, consulta i tutorial in. [Guida introduttiva con SimSpace Weaver](getting-started.md)

È necessario aggiornare l'indirizzo IP e il numero di porta nel client per connettersi all'app View per la simulazione locale. Usa sempre i seguenti valori con SimSpace Weaver Local:

```
tcp://127.0.0.1:7000
```

A seconda del client selezionato, è possibile aggiornare l'indirizzo IP e il numero di porta come segue:
+ **Unreal**: modifica l'URL sulla riga 1 di `view_app_url.txt`
+ **Console**: avvia il client con l'indirizzo IP e il numero di porta (URL) come parametro

# Passaggio 3: Interrompi la simulazione locale (opzionale su Windows)
<a name="working-with_local-development_stop-sim"></a>

**Nota**  
Questo passaggio è obbligatorio su Linux ma facoltativo su Windows.

1.  Vai a: 

   ```
   sdk-folder/Samples/sample-name/tools/local
   ```

1.  Esegui il comando seguente per interrompere la simulazione locale ed eliminare tutte le risorse di memoria condivisa. 

   ```
   python stop-and-delete.py
   ```

    Questo script eseguirà le seguenti operazioni: 
   +  Arresta i processi locali. 
   +  Elimina l'oggetto di memoria condivisa (necessario solo su Linux). 

**stop-and-deleteparametri.py**
+  -h, --help 
  +  Elenca questi parametri. 
+  --stop 
  +  Tenta solo di fermare i processi. 
+  --delete 
  +  Tenta solo di eliminare le risorse di memoria condivise. 
+  --process 
  +  Il nome del processo da interrompere. Utilizzatelo se il nome del processo non corrisponde al nome del pacchetto nello schema. 
+  SCHEMA --schema 
  +  Quale schema utilizzerà questa invocazione. Il valore predefinito è 'SCHEMA' in config.py. 

# Risoluzione dei problemi di sviluppo locale in SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux: comando xterm non trovato/impossibile aprire** 
  + Gli script locali presuppongono che il comando xterm esista quando viene eseguito su Linux. Se non hai il comando xterm o sei in esecuzione in un ambiente che non supporta la GUI, usa l'`--noappwindow`opzione quando esegui lo script di avvio rapido.
+  **Nessuna finestra dell'app si apre\$1** 
  +  Ciò accade quando la simulazione locale si blocca immediatamente. Per vedere l'output della console dopo l'arresto anomalo, usa le `--logfile` opzioni `--noappwindow` o quando esegui lo script di avvio rapido. 
+  **La simulazione non funziona dopo l'avvio dell'app di visualizzazione o la visualizzazione delle connessioni del client\$1** 
  +  L'esecuzione con l'`—noappwindow`opzione in genere risolve questo tipo di problemi. In caso contrario, anche il riavvio alcune volte ha esito positivo (sebbene a una velocità molto inferiore). 

# AWS SimSpace Weaver SDK dell'app
<a name="working-with_app-sdk"></a>

L'SDK SimSpace Weaver dell'app consente APIs di controllare le entità della simulazione e rispondere agli eventi. SimSpace Weaver Include il seguente spazio dei nomi: 
+ **API**: definizioni principali dell'API e del suo utilizzo

Collegamento con la seguente libreria:
+ `libweaver_app_sdk_cxx_v1_full.so`

**Importante**  
La libreria è disponibile per il collegamento dinamico quando esegui le app in. Cloud AWS Non è necessario caricarla con le app.

**Nota**  
L'SDK SimSpace Weaver dell'app APIs controlla i dati all'interno della simulazione. Questi APIs sono separati dal SimSpace Weaver servizio APIs, che controlla le risorse SimSpace Weaver del servizio (come simulazioni, app e orologi). AWS Per ulteriori informazioni, consulta [SimSpace Weaver Riferimenti API](api-reference.md).

**Topics**
+ [I metodi API restituiscono un Result](working-with_app-sdk_return-result.md)
+ [Interazione con l'SDK dell'app al livello più alto](working-with_app-sdk_top-level.md)
+ [Gestione della simulazione](working-with_app-sdk_sim.md)
+ [Sottoscrizioni](working-with_app-sdk_sub.md)
+ [Entità](working-with_app-sdk_ent.md)
+ [eventi dell'entità](working-with_app-sdk_events.md)
+ [Result e gestione degli errori](working-with_app-sdk_result.md)
+ [Generici e tipi di dominio](working-with_app-sdk_generics.md)
+ [Operazioni varie dell'SDK dell'app](working-with_app-sdk_misc.md)

# I metodi API restituiscono un Result
<a name="working-with_app-sdk_return-result"></a>

La maggior parte delle funzioni SimSpace Weaver API ha un tipo di ritorno`Aws::WeaverRuntime::Result<T>`. Se la funzione è stata eseguita correttamente, `Result` contiene`T`. Altrimenti, `Result` contiene un file `Aws::WeaverRuntime::ErrorCode` che rappresenta un codice di errore proveniente da Rust App SDK.

**Example Esempio**  

```
Result<Transaction> BeginUpdate(Application& app)
```

Questo metodo:
+ Restituisce `Transaction` se `BeginUpdate()` viene eseguito correttamente.
+ Restituisce `Aws::WeaverRuntime::ErrorCode` se `BeginUpdate()` fallisce.

# Interazione con l'SDK dell'app al livello più alto
<a name="working-with_app-sdk_top-level"></a>

**Ciclo di vita**
+ L'SDK SimSpace Weaver dell'app gestisce il ciclo di vita dell'app. Non è necessario leggere o scrivere lo stato del ciclo di vita di un'app.

**Partizioni**
+ Usalo `Result <PartitionSet> AssignedPartitions(Transaction& txn);` per ottenere partizioni di proprietà.
+ Usa `Result <PartitionSet> AllPartitions(Transaction& txn);` per ottenere tutte le partizioni della simulazione.

# Gestione della simulazione
<a name="working-with_app-sdk_sim"></a>

Questa sezione descrive le soluzioni per le attività più comuni di gestione della simulazione.

**Topics**
+ [Avvia una simulazione](working-with_app-sdk_sim_start.md)
+ [Aggiorna una simulazione](working-with_app-sdk_sim_update.md)
+ [Termina una simulazione](working-with_app-sdk_sim_terminate.md)

# Avvia una simulazione
<a name="working-with_app-sdk_sim_start"></a>

Utilizzalo `CreateApplication()` per creare un'app.

**Example Esempio**  

```
Result<Application> applicationResult = Api::CreateApplication();

if (!applicationResult)
{
    ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(applicationResult);

    std::cout << "Failed to create application. Error code " <<
        static_cast<std::underlying_type_t<ErrorCode>>(errorCode) <<
        " Last error message "<< Api::LastErrorMessage() << ".";

    return 1;
}

/**
* Run simulation
*/
RunSimulation(std::move(applicationResult.assume_value()));
```

# Aggiorna una simulazione
<a name="working-with_app-sdk_sim_update"></a>

Utilizza le seguenti `BeginUpdate` funzioni per aggiornare l'app:
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`— ti dice se `BeginUpdate()` bloccherà o non bloccherà.

Si usa `Result<void> Commit(Transaction& txn)` per confermare le modifiche.

**Example Esempio**  

```
Result<void> AppDriver::RunSimulation(Api::Application app) noexcept
{
    while (true)
    {
        {
            bool willBlock;

            do
            {
                WEAVERRUNTIME_TRY(willBlock, Api::BeginUpdateWillBlock(m_app));
            } while (willBlock);
        }

        WEAVERRUNTIME_TRY(Transaction transaction, Api::BeginUpdate(app));

        /**
         * Simulate app.
         */
        WEAVERRUNTIME_TRY(Simulate(transaction));
        WEAVERRUNTIME_TRY(Api::Commit(std::move(transaction)));
    }

    return Success();
}
```

# Termina una simulazione
<a name="working-with_app-sdk_sim_terminate"></a>

Utilizzare `Result<void> DestroyApplication(Application&& app)` per terminare l'app e la simulazione.

Altre app scoprono che la simulazione si interrompe quando ricevono `ErrorCode::ShuttingDown` chiamate verso o. `BeginUpdateWillBlock()` `BeginUpdate()` Quando un'app riceve`ErrorCode::ShuttingDown`, può chiamare `Result<void> DestroyApplication(Application&& app)` per terminarsi da sola.

**Example Esempio**  

```
Result<void> AppDriver::EncounteredAppError(Application&& application) noexcept
{
    const ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(runAppResult);

    switch (errorCode)
    {
    case ErrorCode::ShuttingDown:
        {
            // insert custom shutdown process here.

            WEAVERRUNTIME_TRY(Api::DestroyApplication(std::move(application)));
            return Success();
        }
    default:
        {
            OnAppError(errorCode);
            return errorCode;
        }
    }
}
```

**Importante**  
Chiama solo `Result<void> DestroyApplication(Application&& app)` dopo`Api::Commit()`. La distruzione di un'applicazione durante un aggiornamento può causare un comportamento indefinito.

**Importante**  
È necessario effettuare una chiamata `DestroyApplication()` prima della chiusura del programma per assicurarsi che l'applicazione riporti la chiusura con successo.  
La mancata chiamata alla `DestroyApplication()` chiusura del programma farà sì che lo stato venga considerato uguale. `FATAL`

# Sottoscrizioni
<a name="working-with_app-sdk_sub"></a>

Crei un abbonamento con un'area di abbonamento e un ID di dominio. L'ID di dominio rappresenta il dominio che possiede quell'area di sottoscrizione. A `BoundingBox2F32` descrive l'area di sottoscrizione. Utilizza la seguente funzione per creare un abbonamento:

```
Result<SubscriptionHandle> CreateSubscriptionBoundingBox2F32(Transaction& txn, DomainId id, const BoundingBox2F32& boundingBox)
```

**Example Esempio**  

```
Result<void> CreateSubscriptionInSpatialDomain(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(Api::PartitionSet partitionSet, Api::AllPartitions(transaction)); 
    
    Api::DomainId spatialDomainId;

    for (const Api::Partition& partition : partitionSet.partitions)
    {
        if (partition.domain_type == Api::DomainType::Spatial)
        {
            /**
            * Get the spatial domain ID.
            */
            spatialDomainId = partition.domain_id;
            break;
        }
    }
    
    constexpr Api::BoundingBox2F32 subscriptionBounds { 
        /* min */ { /* x */ 0, /* y */ 0 }, 
        /* max */ { /* x */ 1000, /* y */ 1000 } }

    WEAVERRUNTIME_TRY(
        Api::SubscriptionHandle subscriptionHandle,
        Api::CreateSubscriptionBoundingBox2F32(
        transaction,
        spatialDomainId,
        subscriptionBounds));
        
    return Success();
}
```

È possibile utilizzare il comando `Api::SubscriptionHandle` restituito da `CreateSubscriptionBoundingBox2F32()` per modificare l'abbonamento. Lo si passa come argomento alle seguenti funzioni:

```
Result<void> ModifySubscriptionBoundingBox2F32(Transaction& txn, SubscriptionHandle handle, const BoundingBox2F32& boundingBox)
```

```
Result<void> DeleteSubscription(Transaction& txn, SubscriptionHandle handle)
```

# Entità
<a name="working-with_app-sdk_ent"></a>

L'`Store`evento di cambio `Api:Entity` di proprietà `Result<Api::Entity>` restituito o `Load` APIs utilizzato viene richiamato quando un'entità entra nell'area di sottoscrizione dell'app (per ulteriori informazioni, consulta[eventi dell'entità](working-with_app-sdk_events.md)). `CreateEntity()` Ti consigliamo di tracciare i tuoi `Api::Entity` oggetti in modo da poterli utilizzare con questi APIs.

**Topics**
+ [Crea entità](working-with_app-sdk_ent_create.md)
+ [Trasferisci un'entità in un dominio spaziale](working-with_app-sdk_ent_transfer.md)
+ [Scrivi e leggi i dati dei campi dell'entità](working-with_app-sdk_ent_readwrite.md)
+ [Memorizza la posizione di un'entità](working-with_app-sdk_ent_store-position.md)
+ [Carica la posizione di un'entità](working-with_app-sdk_ent_load-position.md)

# Crea entità
<a name="working-with_app-sdk_ent_create"></a>

Usa `CreateEntity()` per creare un'entità. Siete voi a definire il significato di `Api::TypeId` ciò che passate a questa funzione.

```
Namespace
{
    constexpr Api::TypeId k_entityTypeId { /* value */ 512 };
}

Result<void> CreateEntity(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(
        Api::Entity entity,
        Api::CreateEntity(
            transaction, Api::BuiltinTypeIdToTypeId(k_entityTypeId )));
}
```

**Nota**  
I valori 0-511 per `Api::BuiltinTypeId` sono riservati. La tua entità TypeID (`k_entityTypeId`in questo esempio) deve avere un valore pari o superiore a 512.

# Trasferisci un'entità in un dominio spaziale
<a name="working-with_app-sdk_ent_transfer"></a>

Dopo che un'app o un'app di servizio personalizzata ha creato un'entità, l'app deve trasferire l'entità in un dominio spaziale affinché l'entità esista spazialmente nella simulazione. Le entità in un dominio spaziale possono essere lette da altre app e aggiornate da un'app spaziale. Usa l'`ModifyEntityDomain()`API per trasferire un'entità in un dominio spaziale.

```
AWS_WEAVERRUNTIME_API Result<void> ModifyEntityDomain(Transaction& txn, const Entity& entity, DomainId domainId) noexcept;
```

Se `DomainId` non corrisponde a quello assegnato `Partition` dall'app chiamante, `DomainId` deve essere per un `DomainType::Spatial``Domain`. Il trasferimento della proprietà alla nuova `Domain` avviene durante il`Commit(Transaction&&)`.Parametri

`txn`  
La corrente`Transaction`.

`entity`  
L'obiettivo `Entity` per il cambio di`Domain`.

`domainId`  
`DomainId`La destinazione `Domain` per`Entity`.

Questa API restituisce `Success` se il dominio dell'entità è stato modificato con successo.

# Scrivi e leggi i dati dei campi dell'entità
<a name="working-with_app-sdk_ent_readwrite"></a>

Tutti i campi di dati delle entità sono di tipo blob. È possibile scrivere fino a 1.024 byte di dati su un'entità. Ti consigliamo di mantenere i blob il più piccoli possibile perché dimensioni maggiori ridurranno le prestazioni. Quando si scrive su un blob, si passa SimSpace Weaver un puntatore ai dati e alla loro lunghezza. Quando si legge da un blob, SimSpace Weaver fornisce un puntatore e una lunghezza da leggere. Tutte le letture devono essere completate prima che l'app effettui una chiamata. `Commit()` I puntatori restituiti da una chiamata di lettura vengono invalidati quando l'app chiama. `Commit()`

**Importante**  
La lettura da un puntatore blob memorizzato nella cache dopo a non `Commit()` è supportata e può causare il fallimento della simulazione.
La scrittura su un puntatore blob restituito da una chiamata di lettura non è supportata e può causare il fallimento della simulazione.

**Topics**
+ [Memorizza i dati del campo di un'entità](working-with_app-sdk_ent_readwrite_store.md)
+ [Carica i dati del campo di un'entità](working-with_app-sdk_ent_readwrite_load.md)
+ [Caricamento dei dati di campo delle entità rimosse](working-with_app-sdk_ent_readwrite_load-removed.md)

# Memorizza i dati del campo di un'entità
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Gli esempi seguenti mostrano come è possibile archiviare (scrivere nello State Fabric) i dati del campo di un'entità di proprietà dell'app. Questi esempi utilizzano la seguente funzione:

```
AWS_WEAVERRUNTIME_API Result<void> StoreEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t* src,
    std::size_t length) noexcept;
```

Il `Api::TypeId keyTypeId` parametro rappresenta il tipo di dati dei dati trasmessi.

Il `Api::TypeId keyTypeId` parametro deve ricevere il modulo corrispondente `Api::TypeId``Api::BuiltinTypeId`. Se non esiste una conversione appropriata, puoi usare`Api::BuiltinTypeId::Dynamic`.

Per tipi di dati complessi, usa`Api::BuiltInTypeId::Dynamic`.

**Nota**  
Il valore di `FieldIndex index` deve essere maggiore di 0. Il valore 0 è riservato alla chiave dell'indice (vedi`StoreEntityIndexKey()`).

**Example Esempio di utilizzo di tipi di dati primitivi**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    bool value = true;
    
    auto* src = reinterpret_cast<std::int8_t*>(value);
    size_t length = sizeof(*value);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        src,
        length));
}
```

**Example Esempio di utilizzo di un struct per contenere i dati**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Data data = { /* boolData */ false, /* floatData */ -25.93 };
    
    auto* src = reinterpret_cast<std::int8_t*>(data);
    size_t length = sizeof(*data);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        src,
        length));
}
```

# Carica i dati del campo di un'entità
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Gli esempi seguenti mostrano come caricare (leggere dallo state fabric) i dati del campo di un'entità. Questi esempi utilizzano la seguente funzione:

```
Result<std::size_t> LoadEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t** dest) noexcept;
```

Il `Api::TypeId keyTypeId` parametro dovrebbe ricevere il corrispondente `Api::TypeId` da`Api::BuiltinTypeId`. Se non esiste una conversione appropriata, puoi usare`Api::BuiltinTypeId::Dynamic`.

**Nota**  
Il valore dell'`FieldIndex`indice deve essere maggiore di 0. Il valore 0 è riservato alla chiave dell'indice (vedi`StoreEntityIndexKey()`).

**Example Esempio di utilizzo di tipi di dati primitivi**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        &dest));
    
    bool isTrueValue = *reinterpret_cast<bool*>(dest);
}
```

**Example Esempio di utilizzo di un struct per contenere i dati**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        &dest));
    
    Data dataValue = *reinterpret_cast<Data*>(dest);
}
```

# Caricamento dei dati di campo delle entità rimosse
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

Non puoi caricare (leggere dallo State Fabric) i dati dei campi di entità per le entità che sono state rimosse dalle aree di proprietà e abbonamento dell'app. L'esempio seguente genera un errore perché richiama `Api::LoadIndexKey()` un'entità come risultato di un`Api::ChangeListAction::Remove`. Il secondo esempio mostra un modo corretto per archiviare e caricare i dati delle entità direttamente nell'app.

**Example Esempio di codice errato**  

```
Result<void> ProcessSubscriptionChanges(Transaction& transaction)
{
    /* ... */
    
    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));
    
    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Remove:
            {
                std::int8_t* dest = nullptr;
    
                /**
                 * Error!
                 * This calls LoadEntityIndexKey on an entity that
                 * has been removed from the subscription area.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));
    
                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                break;
            }
        }
 
    }

    /* ... */
}
```

**Example Esempio di un modo corretto per archiviare e caricare i dati delle entità nell'app**  

```
Result<void> ReadAndSaveSubscribedEntityPositions(Transaction& transaction)
{
    static std::unordered_map<Api::EntityId, AZ::Vector3> 
        positionsBySubscribedEntity;

    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));

    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Add:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Add the position when the entity is added.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity.emplace(
                    event.entity.descriptor->id, position);

                break;
            }
        case Api::ChangeListAction::Update:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Update the position when the entity is updated.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity[event.entity.descriptor->id] = 
                    position;

                break;
            }
        case Api::ChangeListAction::Remove:
            {
                /**
                 * Load the position when the entity is removed.
                 */
                AZ::Vector3 position = positionsBySubscribedEntity[
                    event.entity.descriptor->id];

                /**
                 * Do something with position...
                 */
                break;
            }
        }
    }
    
    /* ... */
}
```

# Memorizza la posizione di un'entità
<a name="working-with_app-sdk_ent_store-position"></a>

È possibile memorizzare (scrivere nel tessuto statale) la posizione di un'entità utilizzando una struttura di dati intera. Questi esempi utilizzano la seguente funzione:

```
Result<void> StoreEntityIndexKey(
    Transaction& txn, 
    const Entity& entity, 
    TypeId keyTypeId, 
    std::int8_t* src, 
    std::size_t length)
```

**Nota**  
È necessario fornire `Api::BuiltinTypeId::Vector3F32` a`Api::StoreEntityIndexKey()`, come illustrato negli esempi seguenti.

**Example Esempio di utilizzo di un array per rappresentare la posizione**  

```
Result<void> SetEntityPositionByFloatArray(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::array<float, 3> position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(position.data());
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

**Example Esempio di utilizzo di un struct per rappresentare la posizione**  

```
struct Position 
{
   float x;
   float y;
   float z;
};

Result<void> SetEntityPositionByStruct(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Position position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(&position);
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

# Carica la posizione di un'entità
<a name="working-with_app-sdk_ent_load-position"></a>

È possibile caricare (leggere dalla struttura degli stati) la posizione di un'entità utilizzando una struttura di dati intera. Questi esempi utilizzano la seguente funzione:

**Nota**  
È necessario fornire `Api::BuiltinTypeId::Vector3F32` a`Api::LoadEntityIndexKey()`, come illustrato negli esempi seguenti.

**Example Esempio di utilizzo di un array per rappresentare la posizione**  

```
Result<void> GetEntityPosition(Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    std::array<float, 3> position = 
        *reinterpret_cast<std::array<float, 3>*>(dest);
}
```

**Example Esempio di utilizzo di un struct per rappresentare la posizione**  

```
struct Position 
{struct
   float x;
   float y;
   float z;
};

Result<void> GetEntityPosition(Api::Entity& entity, Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    Position position = *reinterpret_cast<Position*>(dest);
}
```

# eventi dell'entità
<a name="working-with_app-sdk_events"></a>

Puoi utilizzare le seguenti funzioni nell'SDK dell' SimSpace Weaver app per ottenere tutti gli eventi di proprietà e abbonamento:
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

È possibile utilizzare il framework SimSpace Weaver demo se è necessaria l'elaborazione di eventi di entità basata su callback. Per ulteriori informazioni, consulta il seguente file di intestazione:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

Puoi anche creare l'elaborazione degli eventi della tua entità.

**Topics**
+ [Esegui iterazioni tra gli eventi per le entità di proprietà](working-with_app-sdk_events_own.md)
+ [Esegui un'iterazione tra gli eventi per le entità sottoscritte](working-with_app-sdk_events_sub.md)
+ [Esegui un'iterazione degli eventi di cambio di proprietà delle entità](working-with_app-sdk_events_change.md)

# Esegui iterazioni tra gli eventi per le entità di proprietà
<a name="working-with_app-sdk_events_own"></a>

`OwnershipChanges()`Utilizzalo per ottenere un elenco di eventi per le entità di proprietà (entità nell'area di proprietà dell'app). La funzione ha la seguente firma:

```
Result<OwnershipChangeList> OwnershipChanges(Transaction& txn)
```

Quindi esegui un'iterazione tra le entità con un ciclo, come illustrato nell'esempio seguente.

**Example Esempio**  

```
WEAVERRUNTIME_TRY(Result<Api::OwnershipChangeList> ownershipChangesResult, Api::OwnershipChanges(transaction));

for (const Api::OwnershipChange& event : ownershipChangeList.changes)
{
    Api::Entity entity = event.entity;
    Api::ChangeListAction action = event.action;

    switch (action)
    {
    case Api::ChangeListAction::None:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Remove:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Add:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Update:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Reject:
        // insert code to handle the event
        break;
    }
}
```

**Event types (Tipi di evento)**
+ `None`— L'entità si trova nell'area e i dati relativi alla posizione e al campo non sono stati modificati.
+ `Remove`— L'entità è stata rimossa dall'area.
+ `Add`— L'entità è stata aggiunta all'area.
+ `Update`— L'entità si trova nell'area ed è stata modificata.
+ `Reject`— L'app non è riuscita a rimuovere l'entità dall'area.

**Nota**  
In caso di `Reject` evento, l'app tenterà nuovamente il trasferimento con il segno di spunta successivo.

# Esegui un'iterazione tra gli eventi per le entità sottoscritte
<a name="working-with_app-sdk_events_sub"></a>

Utilizzalo `AllSubscriptionEvents()` per ottenere un elenco di eventi per le entità sottoscritte (entità nell'area di iscrizione dell'app). La funzione ha la seguente firma:

```
Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn)
```

Quindi esegui un'iterazione tra le entità con un ciclo, come illustrato nell'esempio seguente.

**Example Esempio**  

```
WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, Api::AllSubscriptionEvents(transaction));

for (const Api::SubscriptionEvent& event : subscriptionChangeList.changes)
{
    Api::Entity entity = event.entity;
    Api::ChangeListAction action = event.action;

    switch (action)
    {
    case Api::ChangeListAction::None:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Remove:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Add:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Update:
        // insert code to handle the event
        break;
    case Api::ChangeListAction::Reject:
        // insert code to handle the event
        break;
    }
}
```

**Event types (Tipi di evento)**
+ `None`— L'entità si trova nell'area e i dati relativi alla posizione e al campo non sono stati modificati.
+ `Remove`— L'entità è stata rimossa dall'area.
+ `Add`— L'entità è stata aggiunta all'area.
+ `Update`— L'entità si trova nell'area ed è stata modificata.
+ `Reject`— L'app non è riuscita a rimuovere l'entità dall'area.

**Nota**  
In caso di `Reject` evento, l'app tenterà nuovamente il trasferimento con il segno di spunta successivo.

# Esegui un'iterazione degli eventi di cambio di proprietà delle entità
<a name="working-with_app-sdk_events_change"></a>

Per visualizzare gli eventi in cui un'entità si sposta tra un'area di proprietà e un'area di sottoscrizione, confronta le modifiche tra gli eventi di proprietà e sottoscrizione dell'entità correnti e precedenti.

Puoi gestire questi eventi leggendo:
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

È quindi possibile confrontare le modifiche con i dati precedentemente memorizzati.

L'esempio seguente mostra come gestire gli eventi di modifica della proprietà delle entità. Questo esempio presuppone che per le entità che passano dall'essere entità sottoscritte a entità possedute (in entrambe le direzioni), l'remove/add event occurs first followed by the subscription remove/addevento di proprietà sia visualizzato nel segno di spunta successivo. 

**Example Esempio**  

```
Result<void> ProcessOwnershipEvents(Transaction& transaction)
{
    using EntityIdsByAction =
        std::unordered_map<Api::ChangeListAction, 
        std::vector<Api::EntityId>>;
    using EntityIdSetByAction =
        std::unordered_map<Api::ChangeListAction, 
        std::unordered_set<Api::EntityId>>;
   
    static EntityIdsByAction m_entityIdsByPreviousOwnershipAction;
    
    EntityIdSetByAction entityIdSetByAction;
   
    /**
     * Enumerate Api::SubscriptionChangeList items 
     * and store Add and Remove events.
     */ 
    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionEvents, 
        Api::AllSubscriptionEvents(transaction));
   
    for (const Api::SubscriptionEvent& event : subscriptionEvents.changes)
    {
        const Api::ChangeListAction action = event.action;
    
        switch (action)
        {
        case Api::ChangeListAction::Add:
        case Api::ChangeListAction::Remove:
    
            {
                entityIdSetByAction[action].insert(
                    event.entity.descriptor->id);
                break;
            }
        case Api::ChangeListAction::None:
        case Api::ChangeListAction::Update:
        case Api::ChangeListAction::Reject:
            {
                break;
            }
        }
    }
    
    EntityIdsByAction entityIdsByAction;
    
    /**
     * Enumerate Api::OwnershipChangeList items 
     * and store Add and Remove events.
     */
    
    WEAVERRUNTIME_TRY(Api::OwnershipChangeList ownershipChangeList, 
        Api::OwnershipChanges(transaction));
   
    for (const Api::OwnershipChange& event : ownershipChangeList.changes)
    {
        const Api::ChangeListAction action = event.action;
    
        switch (action)
        {
        case Api::ChangeListAction::Add:
        case Api::ChangeListAction::Remove:
            {
                entityIdsByAction[action].push_back(
                    event.entity.descriptor->id);
                break;
            }
        case Api::ChangeListAction::None:
        case Api::ChangeListAction::Update:
        case Api::ChangeListAction::Reject:
            {
                break;
            }
        }
    
    }
      
    std::vector<Api::EntityId> fromSubscribedToOwnedEntities;
    std::vector<Api::EntityId> fromOwnedToSubscribedEntities;
   
    /**
     * Enumerate the *previous* Api::OwnershipChangeList Remove items
     * and check if they are now in 
     * the *current* Api::SubscriptionChangeList Add items.
     *
     * If true, then that means 
     * OnEntityOwnershipChanged(bool isOwned = false)
     */ 
    for (const Api::EntityId& id : m_entityIdsByPreviousOwnershipAction[
        Api::ChangeListAction::Remove])
    {
        if (entityIdSetBySubscriptionAction[
            Api::ChangeListAction::Add].find(id) !=
                entityIdSetBySubscriptionAction[
                Api::ChangeListAction::Add].end())
        {
            fromOwnedToSubscribedEntities.push_back(id);
        }
    }
    
   
    /**
     * Enumerate the *previous* Api::OwnershipChangeList Add items
     * and check if they are now in 
     * the *current* Api::SubscriptionChangeList Remove items.
     *
     * If true, then that means 
     * OnEntityOwnershipChanged(bool isOwned = true)
     */ 
    for (const Api::EntityId& id : m_entityIdsByPreviousOwnershipAction[
        Api::ChangeListAction::Add])
    {
        if (entityIdSetBySubscriptionAction[
            Api::ChangeListAction::Remove].find(id) !=
            
                entityIdSetBySubscriptionAction[
                Api::ChangeListAction::Remove].end())
        {
            fromSubscribedToOwnedEntities.push_back(id);
        }
    }
    
    m_entityIdsByPreviousOwnershipAction = entityIdsByOwnershipAction;
    
    return Success();
}
```

# Result e gestione degli errori
<a name="working-with_app-sdk_result"></a>

La `Aws::WeaverRuntime::Result<T>` classe utilizza una `Outcome` libreria di terze parti. È possibile utilizzare lo schema seguente per verificare gli errori `Result` e catch restituiti dalle chiamate API.

```
void DoBeginUpdate(Application& app)
{
    Result<Transaction> transactionResult = Api::BeginUpdate(app);
    
    if (transactionResult)
    {
        Transaction transaction = 
            std::move(transactionResult).assume_value();
        
        /**
         * Do things with transaction ...
         */
    }
    else
    {     
        ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(transactionResult);
        /**
         * Macro compiles to:
         * ErrorCode errorCode = transactionResult.assume_error();
         */
    }
}
```

## Result istruzione di controllo, macro
<a name="working-with_app-sdk_result_macro"></a>

All'interno di una funzione con un tipo restituito`Aws::WeaverRuntime::Result<T>`, è possibile utilizzare la `WEAVERRUNTIME_TRY` macro anziché lo schema di codice precedente. La macro eseguirà la funzione che le è stata passata. Se la funzione passata fallisce, la macro farà in modo che la funzione di inclusione restituisca un errore. Se la funzione passata ha esito positivo, l'esecuzione passa alla riga successiva. L'esempio seguente mostra una riscrittura della funzione precedente. `DoBeginUpdate()` Questa versione utilizza la `WEAVERRUNTIME_TRY` macro anziché if-else struttura di controllo. Nota che il tipo restituito dalla funzione è`Aws::WeaverRuntime::Result<void>`.

```
Aws::WeaverRuntime::Result<void> DoBeginUpdate(Application& app)
{
    /**
     * Execute Api::BeginUpdate() 
     * and return from DoBeginUpdate() if BeginUpdate() fails.
     * The error is available as part of the Result.
     */
    WEAVERRUNTIME_TRY(Transaction transaction, Api::BeginUpdate(m_app));
    
    /**
     * Api::BeginUpdate executed successfully.
     *
     * Do things here.
     */
    
    return Aws::Success();
}
```

Se `BeginUpdate()` fallisce, la macro `DoBeginUpdate()` restituisce anticipatamente con un errore. È possibile utilizzare la `WEAVERRUNTIME_EXPECT_ERROR` macro per ottenere il file `Aws::WeaverRuntime::ErrorCode` da`BeginUpdate()`. L'esempio seguente mostra come la `Update()` funzione chiama `DoBeginUpdate()` e ottiene il codice di errore in caso di errore.

```
void Update(Application& app)
{
    Result<void> doBeginUpdateResult = DoBeginUpdate(app);
    
    if (doBeginUpdateResult)
    {
        /**
         * Successful.
         */
    }
    else
    {    
        /**
         * Get the error from Api::BeginUpdate().
         */ 
        ErrorCode errorCode = WEAVERRUNTIME_EXPECT_ERROR(doBeginUpdateResult);

    }
}
```

È possibile rendere `BeginUpdate()` disponibile il codice di errore per una funzione che chiama `Update()` modificando il tipo restituito da `Update()` to`Aws::WeaverRuntime::Result<void>`. È possibile ripetere questo processo per continuare a inviare il codice di errore più in basso nello stack di chiamate.

# Generici e tipi di dominio
<a name="working-with_app-sdk_generics"></a>

L'SDK SimSpace Weaver dell'app fornisce i tipi di dati a precisione singola `Api::Vector2F32` e`Api::BoundingBox2F32`, a doppia precisione e. `Api::Vector2F64` `Api::BoundingBox2F64` Questi tipi di dati sono strutture di dati passive prive di metodi pratici. Tieni presente che l'API utilizza solo `Api::Vector2F32` e`Api::BoundingBox2F32`. Puoi utilizzare questi tipi di dati per creare e modificare abbonamenti.

Il framework SimSpace Weaver demo fornisce una versione minima di AzCore libreria matematica, che contiene `Vector3` e`Aabb`. Per ulteriori informazioni, consulta i file di intestazione in:
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Operazioni varie dell'SDK dell'app
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents e OwnershipChanges contengono gli eventi dell'ultima chiamata](working-with_app-sdk_misc_events-from-last-call.md)
+ [Rilascia i blocchi di lettura dopo l'elaborazione SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Crea un'istanza di app autonoma per il test](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents e OwnershipChanges contengono gli eventi dell'ultima chiamata
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

I valori restituiti dalle chiamate a `Api::AllSubscriptionEvents()` e `Api::OwnershipChanges()` contengono gli eventi dell'ultima chiamata, **non l'ultimo segno di spunta**. Nell'esempio seguente, `secondSubscriptionEvents` e `secondOwnershipChangeList` sono vuoti perché le relative funzioni vengono richiamate immediatamente dopo le prime chiamate.

Se attendi 10 tick e poi chiami `Api::AllSubscriptionEvents()` and`Api::OwnershipChanges()`, i risultati conterranno sia gli eventi che le modifiche rispetto agli ultimi 10 tick (non all'ultimo segno di spunta).

**Example Esempio**  

```
Result<void> ProcessOwnershipChanges(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(
        Api::SubscriptionChangeList firstSubscriptionEvents,
        Api::AllSubscriptionEvents(transaction));
    WEAVERRUNTIME_TRY(
        Api::OwnershipChangeList firstOwnershipChangeList,
        Api::OwnershipChanges(transaction));
    
    WEAVERRUNTIME_TRY(
        Api::SubscriptionChangeList secondSubscriptionEvents,
        Api::AllSubscriptionEvents(transaction));
    WEAVERRUNTIME_TRY(
        Api::OwnershipChangeList secondOwnershipChangeList,
        Api::OwnershipChanges(transaction));
    
    /**
     * secondSubscriptionEvents and secondOwnershipChangeList are 
     * both empty because there are no changes since the last call.
     */
}
```

**Nota**  
**La funzione `AllSubscriptionEvents()` è implementata ma la funzione non `SubscriptionEvents()` è implementata.**

# Rilascia i blocchi di lettura dopo l'elaborazione SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Quando si avvia un aggiornamento, sono presenti segmenti di memoria condivisa per i dati salvati in altre partizioni relative al segno di spunta precedente. Questi segmenti di memoria condivisa potrebbero essere bloccati dai lettori. Un'app non può eseguire il commit completo finché tutti i lettori non hanno rilasciato i lucchetti. Come ottimizzazione, un'app dovrebbe chiamare `Api::ReleaseReadLeases()` per rilasciare i blocchi dopo aver `Api::SubscriptionChangelist` elaborato gli elementi. Ciò riduce le contese al momento del commit. `Api::Commit()`rilascia i lease di lettura per impostazione predefinita, ma è consigliabile rilasciarli manualmente dopo l'elaborazione degli aggiornamenti dell'abbonamento.

**Example Esempio**  

```
Result<void> ProcessSubscriptionChanges(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(ProcessSubscriptionChanges(transaction));
    
    /**
     * Done processing Api::SubscriptionChangeList items.
     * Release read locks. 
     */
        
    WEAVERRUNTIME_EXPECT(Api::ReleaseReadLeases(transaction));
    
    ...
}
```

# Crea un'istanza di app autonoma per il test
<a name="working-with_app-sdk_misc_testing-app"></a>

Puoi utilizzarla `Api::CreateStandaloneApplication()` per creare un'app autonoma per testare la logica dell'app prima di eseguire il codice in una simulazione effettiva.

**Example Esempio**  

```
int main(int argc, char* argv[])
{
    Api::StandaloneRuntimeConfig config = { 
        /* run_for_seconds (the lifetime of the app) */ 3,
        /* tick_hertz (the app clock rate) */ 10 };
    
    Result<Application> applicationResult =
        Api::CreateStandaloneApplication(config);

    ...
}
```

# AWS SimSpace Weaver quadro dimostrativo
<a name="working-with_demo-framework"></a>

Il framework AWS SimSpace Weaver demo (framework demo) è una libreria di utilità che puoi utilizzare per sviluppare SimSpace Weaver app.

**Il framework demo fornisce**
+ Esempi di codice e modelli di programmazione da utilizzare ed esaminare
+ Astrazioni e funzioni di utilità che semplificano lo sviluppo di app semplici
+ Un modo più semplice per testare le funzionalità sperimentali dell'SDK dell'app SimSpace Weaver 

Abbiamo progettato l'SDK SimSpace Weaver dell'app con accesso a basso livello per offrire SimSpace Weaver APIs prestazioni più elevate. Al contrario, abbiamo progettato il framework demo per fornire astrazioni di livello superiore e un accesso a APIs ciò più facile da usare. SimSpace Weaver Il costo della facilità d'uso è un livello di prestazioni inferiore rispetto all'utilizzo diretto dell'SDK dell' SimSpace Weaver app. Le simulazioni in grado di tollerare prestazioni inferiori (ad esempio quelle senza requisiti di prestazioni in tempo reale) potrebbero essere buone candidate per utilizzare il framework demo. Ti consigliamo di utilizzare la funzionalità nativa dell'SDK dell' SimSpace Weaver app per applicazioni complesse, poiché il framework demo non è un toolkit completo.

**Il framework demo include**
+ Esempi di codice funzionanti che supportano e dimostrano:
  + Gestione del flusso delle app
  + Elaborazione di eventi di entità basata su callback
+ Un set di librerie di utilità di terze parti:
  + spdlog (una libreria di registrazione)
  + Una versione minimale di AZCore (una libreria matematica) che contiene solo:
    + Vector3
    + Aabb
  + cxxopts (una libreria di analisi delle opzioni a riga di comando)
+ Funzioni di utilità specifiche per SimSpace Weaver

Il framework demo è composto da una libreria, file sorgente e CMakeLists. I file sono inclusi nel pacchetto distribuibile dell' SimSpace Weaver app SDK.

# Utilizzo delle quote di servizio
<a name="working-with_quotas"></a>

Questa sezione descrive come utilizzare le quote di servizio per. SimSpace Weaver**Le quote** **sono anche chiamate limiti.** Per un elenco delle quote di servizio, vedere. [SimSpace Endpoint e quote Weaver](service-quotas.md) I APIs contenuti in questa sezione provengono dal set di **app APIs**. APIsLe app sono diverse dal servizio APIs. Le app APIs fanno parte dell'SDK dell' SimSpace Weaver app. Puoi trovare la documentazione dell'app APIs nella cartella SDK dell'app sul tuo sistema locale:

```
sdk-folder\SimSpaceWeaverAppSdk-sdk-version\documentation\index.html
```

**Topics**
+ [Ottieni i limiti per un'app](#working-with_quotas_get-app-limits)
+ [Ottieni la quantità di risorse utilizzate da un'app](#working-with_quotas_get-app-resources)
+ [Reimposta le metriche](#working-with_quotas_reset-metrics)
+ [Superamento di un limite](#working-with_quotas_exceed-limit)
+ [Memoria a corto di memoria](#working-with_quotas_out-of-memory)
+ [Best practice](#working-with_quotas_best-practices)

## Ottieni i limiti per un'app
<a name="working-with_quotas_get-app-limits"></a>

Puoi utilizzare l'API dell'**RuntimeLimits**app per interrogare i limiti di un'app.

```
Result<Limit> RuntimeLimit(Application& app, LimitType type)
```Parameters

**Application& app**  
Un riferimento all'app.

**LimitType tipo**  
Un enum con i seguenti tipi di limite:  

```
enum LimitType {
    Unset = 0,
    EntitiesPerPartition = 1,
    RemoteEntityTransfers = 2,
    LocalEntityTransfers = 3
};
```

L'esempio seguente interroga il limite di conteggio delle entità.

```
WEAVERRUNTIME_TRY(auto entity_limit,
    Api::RuntimeLimit(m_app, Api::LimitType::EntitiesPerPartition))
Log::Info("Entity count limit", entity_limit.value);
```

## Ottieni la quantità di risorse utilizzate da un'app
<a name="working-with_quotas_get-app-resources"></a>

Puoi chiamare l'API **RuntimeMetrics** dell'app per ottenere la quantità di risorse utilizzate da un'app:

```
Result<std::reference_wrapper<const AppRuntimeMetrics>> RuntimeMetrics(Application& app) noexcept
```Parameters

**Application& app**  
Un riferimento all'app.

L'API restituisce un riferimento a un struct che contiene le metriche. Una metrica contatore contiene un valore totale corrente e non fa che aumentare. Una metrica dell'indicatore contiene un valore che può aumentare o diminuire. Il runtime dell'applicazione aggiorna un contatore ogni volta che un evento aumenta il valore. Il runtime aggiorna gli indicatori solo quando si chiama l'API. SimSpace Weaver garantisce che il riferimento sia valido per tutta la durata dell'app. Le chiamate ripetute all'API non modificheranno il riferimento.

```
struct AppRuntimeMetrics {
    uint64_t total_committed_ticks_gauge,

    uint32_t active_entity_gauge,
    uint32_t ticks_since_reset_counter,

    uint32_t load_field_counter,
    uint32_t store_field_counter,

    uint32_t created_entity_counter,
    uint32_t deleted_entity_counter,

    uint32_t entered_entity_counter,
    uint32_t exited_entity_counter,

    uint32_t rejected_incoming_transfer_counter,
    uint32_t rejected_outgoing_transfer_counter
}
```

## Reimposta le metriche
<a name="working-with_quotas_reset-metrics"></a>

L'API **ResetRuntimeMetrics** dell'app reimposta i valori in. `AppRuntimeMetrics` struct

```
Result<void> ResetRuntimeMetrics(Application& app) noexcept
```

L'esempio seguente mostra come puoi chiamare la tua **ResetRuntimeMetrics** app.

```
if (ticks_since_last_report > 100)
{
    auto metrics = WEAVERRUNTIME_EXPECT(Api::RuntimeMetrics(m_app));
    Log::Info(metrics);

    ticks_since_last_report = 0;

    WEAVERRUNTIME_EXPECT(Api::ResetRuntimeMetrics(m_app));
}
```

## Superamento di un limite
<a name="working-with_quotas_exceed-limit"></a>

Una chiamata all'API dell'app che supera un limite restituirà un`ErrorCode::CapacityExceeded`, ad eccezione dei trasferimenti di entità. SimSpace Weaver gestisce i trasferimenti di entità in modo asincrono nell'ambito delle operazioni **Commit** e delle API dell'**BeginUpdate**app, quindi non esiste un'operazione specifica che restituisca un errore se un trasferimento non riesce a causa del limite di trasferimento delle entità. Per rilevare gli errori di trasferimento, puoi confrontare i valori correnti di `rejected_incoming_transfer_counter` e `rejected_outgoing_transfer_counter` (in `AppRuntimeMetrics`struct) con i valori precedenti. Le entità rifiutate non saranno presenti nella partizione, ma l'app può comunque simularle.

## Memoria a corto di memoria
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver utilizza un processo Garbage Collector per ripulire e liberare la memoria liberata. È possibile scrivere dati più velocemente di quanto il Garbage Collector riesca a liberare memoria. In tal caso, le operazioni di scrittura potrebbero superare il limite di memoria riservata dell'app. SimSpace Weaver restituirà un errore interno con un messaggio che contiene `OutOfMemory` (e dettagli aggiuntivi). Per ulteriori informazioni, consulta [Diffondi le scritture nel tempo](#working-with_quotas_best-practices_spread-writes).

## Best practice
<a name="working-with_quotas_best-practices"></a>

Le seguenti best practice sono linee guida generali per progettare le app in modo da evitare il superamento dei limiti. Potrebbero non essere applicabili al design specifico della tua app.

### Monitora frequentemente e rallenta
<a name="working-with_quotas_best-practices_monitor"></a>

È necessario monitorare frequentemente le metriche e rallentare le operazioni che stanno per raggiungere un limite.

### Evita di superare i limiti di abbonamento e i limiti di trasferimento
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Se possibile, progetta la simulazione per ridurre il numero di abbonamenti remoti e trasferimenti di entità. È possibile utilizzare i gruppi di collocamento per posizionare più partizioni sullo stesso lavoratore e ridurre la necessità di trasferimenti di entità remote tra lavoratori. 

### Diffondi le scritture nel tempo
<a name="working-with_quotas_best-practices_spread-writes"></a>

Il numero e la dimensione degli aggiornamenti in un colpo di spunta possono avere un impatto significativo sul tempo e sulla memoria necessari per eseguire una transazione. I requisiti di memoria elevati possono causare l'esaurimento della memoria nel runtime dell'applicazione. È possibile distribuire le scritture nel tempo per ridurre la dimensione totale media degli aggiornamenti per segno di spunta. Questo può aiutare a migliorare le prestazioni ed evitare il superamento dei limiti. Ti consigliamo di non scrivere più di una media di 12 MB per segno di spunta o 1,5 KB per ogni entità. 

# Simulazioni di debug
<a name="working-with_debugging"></a>

È possibile utilizzare i seguenti metodi per ottenere informazioni sulle simulazioni.

**Argomenti**
+ [Utilizzo SimSpace Weaver Local e guarda l'output della console](#working-with_debugging_use-local)
+ [Guarda i tuoi log in Amazon CloudWatch Logs](#working-with_debugging_logs)
+ [Utilizzo **describe** Chiamate API](#working-with_debugging_api)
+ [Connect a client](#working-with_debugging_client)

## Utilizzo SimSpace Weaver Local e guarda l'output della console
<a name="working-with_debugging_use-local"></a>

Ti consigliamo di sviluppare prima le simulazioni localmente e poi di eseguirle Cloud AWS in. È possibile visualizzare l'output della console direttamente quando si esegue con SimSpace Weaver Local. Per ulteriori informazioni, vedere[Sviluppo locale in SimSpace Weaver](working-with_local-development.md).

## Guarda i tuoi log in Amazon CloudWatch Logs
<a name="working-with_debugging_logs"></a>

Quando esegui la simulazione nella console, Cloud AWS l'output delle tue app viene inviato ai flussi di log in Amazon CloudWatch Logs. La tua simulazione scrive anche altri dati di log. È necessario abilitare la registrazione nello schema di simulazione se si desidera che la simulazione scriva dati di registro. Per ulteriori informazioni, consulta [SimSpace Weaver accessi in Amazon CloudWatch Logs](cloudwatch-logs.md).

**avvertimento**  
La simulazione può produrre grandi quantità di dati di registro. I dati di registro possono crescere molto rapidamente. È necessario monitorare attentamente i log e interrompere le simulazioni quando non è più necessario eseguirle. La registrazione può comportare costi elevati.

## Utilizzo **describe** Chiamate API
<a name="working-with_debugging_api"></a>

È possibile utilizzare il seguente servizio APIs per ottenere informazioni sulle simulazioni in. Cloud AWS
+ **ListSimulations**— ottieni un elenco di tutte le tue simulazioni in. Cloud AWS  
**Example Esempio**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**— ottieni dettagli su una simulazione.  
**Example Esempio**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**— ottieni dettagli su un'app.  
**Example Esempio**  

  ```
  aws simspaceweaver describe-app --simulation MySimulation --domain MyCustomDomain --app MyCustomApp
  ```

Per ulteriori informazioni su SimSpace Weaver APIs, vedere[SimSpace Weaver Riferimenti API](api-reference.md).

## Connect a client
<a name="working-with_debugging_client"></a>

Puoi connettere un client a un'app personalizzata o di servizio `endpoint_config` in esecuzione definita con uno schema di simulazione. L'SDK SimSpace Weaver dell'app include client di esempio che puoi utilizzare per visualizzare l'applicazione di esempio. Puoi esaminare il codice sorgente di questi client di esempio e l'applicazione di esempio per vedere come creare i tuoi client. Per ulteriori informazioni su come creare ed eseguire i client di esempio, consulta i tutorial in. [Guida introduttiva con SimSpace Weaver](getting-started.md)

Puoi trovare il codice sorgente per i client di esempio nella seguente cartella:
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Eseguire il debug di simulazioni locali
<a name="working-with_debugging_local"></a>

Puoi eseguire il debug delle tue SimSpace Weaver Local app con. Microsoft Visual Studio [Per ulteriori informazioni su come eseguire il debug conVisual Studio, consulta. Microsoft Visual Studio documentation](https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour) 

**Per eseguire il debug della simulazione locale**

1. Assicurati che `schema.yaml` sia nella tua directory di lavoro.

1. In **Visual Studio**, apri il menu contestuale per ogni app di cui desideri eseguire il debug (ad esempio `PathfindingSampleLocalSpatial` o`PathfindingSampleLocalView`) e imposta la directory di lavoro nella sezione di debug.

1. **Apri il menu contestuale dell'app di cui desideri eseguire il debug e seleziona Imposta come progetto di avvio.**

1. Scegli F5 di avviare il debug dell'app.

I requisiti per eseguire il debug di una simulazione sono gli stessi necessari per eseguire una simulazione normalmente. È necessario avviare il numero di app spaziali specificato nello schema. Ad esempio, se lo schema specifica una griglia 2x2 e si avvia un'app spaziale in modalità debug, la simulazione non verrà eseguita finché non si avviano altre 3 app spaziali (in modalità debug o non in modalità debug).

Per eseguire il debug di un'app personalizzata, devi prima avviare le app spaziali e quindi avviare l'app personalizzata nel debugger.

Tieni presente che la simulazione viene eseguita in blocco. Non appena un'app raggiunge un punto di interruzione, tutte le altre app verranno messe in pausa. Dopo aver proseguito da quel punto di interruzione, le altre app continueranno.

# Contenitori personalizzati
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver le app vengono eseguite in ambienti containerizzati Amazon Linux 2 (AL2). Nel Cloud AWS, SimSpace Weaver esegue le simulazioni in contenitori Docker creati a partire da un'`amazonlinux:2`immagine fornita da Amazon Elastic Container Registry (Amazon ECR). Puoi creare un'immagine Docker personalizzata, archiviarla in Amazon ECR e utilizzare quell'immagine per la tua simulazione anziché l'immagine Docker predefinita che forniamo.

Puoi utilizzare un contenitore personalizzato per gestire le dipendenze software e includere componenti software aggiuntivi che non sono presenti nell'immagine Docker standard. Ad esempio, puoi aggiungere al contenitore le librerie software disponibili pubblicamente utilizzate dall'app e inserire il codice personalizzato solo nel file zip dell'app.

**Importante**  
Supportiamo solo immagini AL2 Docker ospitate nei repository Amazon ECR, in Amazon ECR Public Gallery o nel tuo registro Amazon ECR privato. Non supportiamo immagini Docker ospitate al di fuori di Amazon ECR. Per ulteriori informazioni su Amazon ECR, consulta la *[documentazione di Amazon Elastic Container Registry](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Crea un contenitore personalizzato](working-with_custom-containers_create.md)
+ [Modifica un progetto per utilizzare un contenitore personalizzato](working-with_custom-containers_modify-project.md)
+ [Domande frequenti sui contenitori personalizzati](working-with_custom-containers_faq.md)
+ [Risoluzione dei problemi relativi ai contenitori personalizzati](working-with_custom-containers_troubleshooting.md)

# Crea un contenitore personalizzato
<a name="working-with_custom-containers_create"></a>

Queste istruzioni presuppongono che tu sappia usare Docker e Amazon Elastic Container Registry (Amazon ECR). Per ulteriori informazioni su Amazon ECR, consulta la *[Guida per l'utente di Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Prerequisiti**
+ L'identità IAM (uso o ruolo) che usi per eseguire queste azioni dispone delle autorizzazioni corrette per utilizzare Amazon ECR
+ Docker è installato sul tuo sistema locale

**Per creare un contenitore personalizzato**

1. Crea un `Dockerfile`.

   Un' AWS SimSpace Weaver app `Dockerfile` per eseguire inizia con l'Amazon Linux 2immagine in Amazon ECR.

   ```
   # parent image required to run AWS SimSpace Weaver apps
   FROM public.ecr.aws/amazonlinux/amazonlinux:2
   ```

1. Crea il tuo. `Dockerfile`

1. Carica l'immagine del contenitore su Amazon ECR.
   + [Usa il. Console di gestione AWS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Usa il AWS Command Line Interface.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**Nota**  
Se ricevi un `AccessDeniedException` errore quando tenti di caricare l'immagine del contenitore su Amazon ECR, la tua identità IAM (utente o ruolo) potrebbe non disporre delle autorizzazioni necessarie per utilizzare Amazon ECR. Puoi collegare la policy `AmazonEC2ContainerRegistryPowerUser` AWS gestita alla tua identità IAM e riprovare. Per ulteriori informazioni su come allegare una policy, consulta [Aggiungere e rimuovere le autorizzazioni di identità IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) nella *Guida per l'AWS Identity and Access Management utente*.

# Modifica un progetto per utilizzare un contenitore personalizzato
<a name="working-with_custom-containers_modify-project"></a>

Queste istruzioni presuppongono che tu sappia già come usarle AWS SimSpace Weaver e che desideri rendere Cloud AWS più efficienti i flussi di lavoro di archiviazione e sviluppo delle app.

**Prerequisiti**
+ Hai un contenitore personalizzato in Amazon Elastic Container Registry (Amazon ECR). Per ulteriori informazioni sulla creazione di un contenitore personalizzato, consulta[Crea un contenitore personalizzato](working-with_custom-containers_create.md).

**Per modificare il progetto in modo da utilizzare un contenitore personalizzato**

1. Aggiungi le autorizzazioni al ruolo dell'app di simulazione del tuo progetto per utilizzare Amazon ECR.

   1. Se non disponi già di una policy IAM con le seguenti autorizzazioni, crea la policy. Ti suggeriamo il nome `simspaceweaver-ecr` della policy. Per ulteriori informazioni su come creare una policy IAM, consulta [Creazione di policy IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) nella *Guida per l'AWS Identity and Access Management utente*.

      ```
      {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "Statement",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:BatchGetImage",
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:GetAuthorizationToken"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

   1. Trova il nome del ruolo dell'app di simulazione del tuo progetto:

      1. In un editor di testo, apri il CloudFormation modello:

         ```
         sdk-folder\PackagingTools\sample-stack-template.yaml
         ```

      1. Trova la `RoleName` proprietà sotto`WeaverAppRole`. Il valore è il nome del ruolo dell'app di simulazione del progetto.  
**Example**  

         ```
         AWSTemplateFormatVersion: "2010-09-09"
         Resources:
           WeaverAppRole:
             Type: 'AWS::IAM::Role'
             Properties:
               RoleName: 'weaver-MySimulation-app-role'
               AssumeRolePolicyDocument:
                 Version: "2012-10-17"		 	 	 
                 Statement:
                 - Effect: Allow
                   Principal:
                     Service:
                       - 'simspaceweaver.amazonaws.com'
         ```

   1. Allega la `simspaceweaver-ecr` policy al ruolo dell'app di simulazione del progetto. Per ulteriori informazioni su come allegare una policy, consulta [Aggiungere e rimuovere le autorizzazioni di identità IAM nella Guida](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) per l'*AWS Identity and Access Management utente*. 

   1. Vai al seguente comando `sdk-folder` ed esegui il seguente comando per aggiornare lo SimSpace Weaver stack di esempio:

      ```
      python setup.py --cloudformation
      ```

1. Specificate le immagini del contenitore nello schema di simulazione del progetto.
   + Puoi aggiungere la `default_image` proprietà opzionale in `simulation_properties` per specificare un'immagine contenitore personalizzata predefinita per tutti i domini.
   + Aggiungi la `image` proprietà nel campo `app_config` per il dominio in cui desideri utilizzare un'immagine contenitore personalizzata. Specificare l'URI del repository Amazon ECR come valore. Puoi specificare un'immagine diversa per ogni dominio.
     + Se `image` non è specificato per un dominio e `default_image` viene specificato, le app di quel dominio utilizzano l'immagine predefinita.
     + Se `image` non è specificato per un dominio e `default_image` non è specificato, le app di quel dominio vengono eseguite in un SimSpace Weaver contenitore standard.  
**Example Frammento di schema che include impostazioni personalizzate del contenitore**  

   ```
   sdk_version: "1.17.0"
   simulation_properties:
     log_destination_service: "logs"
     log_destination_resource_name: "MySimulationLogs"
     default_entity_index_key_type: "Vector3<f32>"
     default_image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # image to use if no image specified for a domain
   domains:
     MyCustomDomain:
       launch_apps_via_start_app_call: {}
       app_config:
         package: "s3://weaver-myproject-111122223333-us-west-2/MyViewApp.zip" 
         launch_command: ["MyViewApp"]  
         required_resource_units:
           compute: 1
         endpoint_config:
           ingress_ports:
             - 7000
         image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # custom container image to use for this domain 
     MySpatialDomain:
       launch_apps_by_partitioning_strategy:
         partitioning_strategy: "MyGridPartitioning"
         grid_partition:
           x: 2
           y: 2
       app_config:
         package: "s3://weaver-myproject-111122223333-us-west-2/MySpatialApp.zip" 
         launch_command: ["MySpatialApp"] 
         required_resource_units:
           compute: 1
         image: "111122223333.dkr.ecr.us-west-2.amazonaws.com/my-ecr-repository:latest" # custom container image to use for this domain
   ```

1. Crea e carica il tuo progetto come al solito.

# Domande frequenti sui contenitori personalizzati
<a name="working-with_custom-containers_faq"></a>

## D1. Cosa devo fare se voglio modificare il contenuto del mio contenitore?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Per una simulazione di esecuzione**: non è possibile cambiare il contenitore per una simulazione di esecuzione. È necessario creare un nuovo contenitore e avviare una nuova simulazione che utilizzi quel contenitore.
+ **Per una nuova simulazione**: crea un nuovo contenitore, caricalo su Amazon Elastic Container Registry (Amazon ECR) e avvia una nuova simulazione che utilizzi quel contenitore.

## D2. Come posso modificare l'immagine del contenitore per la mia simulazione?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Per una simulazione in esecuzione**: non è possibile modificare il contenitore per una simulazione in esecuzione. È necessario avviare una nuova simulazione che utilizzi il nuovo contenitore.
+ **Per una nuova simulazione**: specifica la nuova immagine del contenitore nello schema di simulazione del progetto. Per ulteriori informazioni, consulta [Modifica un progetto per utilizzare un contenitore personalizzato](working-with_custom-containers_modify-project.md).

# Risoluzione dei problemi relativi ai contenitori personalizzati
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException quando carichi l'immagine su Amazon Elastic Container Registry (Amazon ECR)](working-with_custom-containers_troubleshooting_access-denied.md)
+ [Una simulazione che utilizza un contenitore personalizzato non riesce ad avviarsi](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException quando carichi l'immagine su Amazon Elastic Container Registry (Amazon ECR)
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Se ricevi un `AccessDeniedException` errore quando tenti di caricare l'immagine del contenitore su Amazon ECR, la tua identità IAM (utente o ruolo) potrebbe non disporre delle autorizzazioni necessarie per utilizzare Amazon ECR. Puoi collegare la policy `AmazonEC2ContainerRegistryPowerUser` AWS gestita alla tua identità IAM e riprovare. Per ulteriori informazioni su come allegare una policy, consulta [Aggiungere e rimuovere le autorizzazioni di identità IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) nella *Guida per l'AWS Identity and Access Management utente*.

# Una simulazione che utilizza un contenitore personalizzato non riesce ad avviarsi
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Suggerimenti per la risoluzione dei problemi**
+ Se la registrazione è abilitata per la simulazione, controlla i log degli errori.
+ Testa la tua simulazione senza un contenitore personalizzato.
+ Testa la tua simulazione localmente. Per ulteriori informazioni, consulta [Sviluppo locale in SimSpace Weaver](working-with_local-development.md).

# Uso di Python
<a name="working-with_python"></a>

Puoi usare Python per le tue SimSpace Weaver app e il tuo client. Il kit di sviluppo software Python (Python SDK) è incluso come parte del pacchetto distribuibile SDK per app standard SimSpace Weaver . Lo sviluppo con Python funziona in modo simile allo sviluppo negli altri linguaggi supportati.

**Importante**  
SimSpace Weaver supporta solo la versione 3.9 di Python.

**Importante**  
SimSpace Weaver il supporto per Python richiede la SimSpace Weaver versione 1.15.0 o successiva.

**Topics**
+ [Creare un progetto Python](working-with_python_create-project.md)
+ [Avvio di una simulazione in Python](working-with_python_start-sim.md)
+ [Il client Python di esempio](working-with_python_client.md)
+ [Domande frequenti sull'uso di Python](working-with_python_faq.md)
+ [Risoluzione dei problemi relativi a Python](working-with_python_troubleshooting.md)

# Creare un progetto Python
<a name="working-with_python_create-project"></a>

## Contenitore personalizzato Python
<a name="working-with_python_create-project_container"></a>

Per eseguire la SimSpace Weaver simulazione basata su Python in Cloud AWS, puoi creare un contenitore personalizzato che includa le dipendenze necessarie. Per ulteriori informazioni, consulta [Contenitori personalizzati](working-with_custom-containers.md). 

Un contenitore personalizzato in Python deve includere quanto segue:
+ gcc
+ openssl-devel
+ bzip2-devel
+ libffi-devel
+ wget
+ tar
+ gzip
+ make
+ Python (versione 3.9)

Se usi il `PythonBubblesSample` modello per creare il tuo progetto, puoi eseguire lo `quick-start.py` script (che si trova nella `tools` cartella del progetto) per creare un'immagine Docker con le dipendenze necessarie. Lo script carica l'immagine su Amazon Elastic Container Registry (Amazon ECR).

Lo `quick-start.py` script utilizza quanto segue: `Dockerfile`

```
FROM public.ecr.aws/amazonlinux/amazonlinux:2
RUN yum -y install gcc openssl-devel bzip2-devel libffi-devel 
RUN yum -y install wget
RUN yum -y install tar
RUN yum -y install gzip
RUN yum -y install make
WORKDIR /opt
RUN wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz 
RUN tar xzf Python-3.9.0.tgz
WORKDIR /opt/Python-3.9.0
RUN ./configure --enable-optimizations
RUN make altinstall
COPY requirements.txt ./
RUN python3.9 -m pip install --upgrade pip
RUN pip3.9 install -r requirements.txt
```

Puoi aggiungere le tue dipendenze a: `Dockerfile`

```
RUN yum -y install dependency-name
```

Il `requirements.txt` file contiene un elenco di pacchetti Python necessari per la simulazione di `PythonBubblesSample` esempio:

```
Flask==2.1.1
```

Puoi aggiungere le tue dipendenze dei pacchetti Python a: `requirements.txt`

```
package-name==version-number
```

I `Dockerfile` e `requirements.txt` si trovano nella `tools` cartella del tuo progetto.

**Importante**  
Tecnicamente non è necessario utilizzare un contenitore personalizzato con la simulazione Python, ma consigliamo vivamente di utilizzare un contenitore personalizzato. Il contenitore Amazon Linux 2 (AL2) standard che forniamo non ha Python. Pertanto, se non utilizzi un contenitore personalizzato con Python, devi includere Python e le dipendenze richieste in ogni file zip dell'app in cui carichi. SimSpace Weaver

# Avvio di una simulazione in Python
<a name="working-with_python_start-sim"></a>

Puoi iniziare la tua simulazione basata su Python allo stesso modo di una normale SimSpace Weaver simulazione, sia in SimSpace Weaver Local e in. SimSpace Weaver Cloud AWS Per ulteriori informazioni, consulta i tutorial in. [Guida introduttiva con SimSpace Weaver](getting-started.md)

`PythonBubblesSample`Include il proprio client di esempio Python. Per ulteriori informazioni, consulta [Il client Python di esempio](working-with_python_client.md). 

# Il client Python di esempio
<a name="working-with_python_client"></a>

Se usi il `PythonBubblesSample` modello per creare un progetto, il progetto contiene un client di esempio Python. È possibile utilizzare il client di esempio per visualizzare la `PythonBubblesSample` simulazione. Puoi anche usare il client di esempio come punto di partenza per creare il tuo client Python.

La procedura seguente presuppone che tu abbia creato un `PythonBubblesSample` progetto e ne abbia avviato la simulazione.

**Per avviare il client Python**

1. In una **finestra del prompt dei** comandi, vai alla cartella del progetto `PyBubbleClient` di esempio.

   ```
   cd sdk-folder\Clients\HTTP\PyBubbleClient
   ```

1. Esegui il client Python.

   ```
   python tkinter_client.py --host ip-address --port port-number
   ```

**Parametri**  
**host**  
L'indirizzo IP della simulazione. Per una simulazione iniziata in Cloud AWS, puoi trovare l'indirizzo IP della simulazione nella [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver) o utilizzare la procedura descritta nel tutorial [Ottieni l'indirizzo IP e il numero di porta di un'app personalizzataOttieni l'indirizzo IP e il numero di porta](working-with_get-ip.md) di avvio rapido. Per una simulazione locale, usa `127.0.0.1` come indirizzo IP.  
**port**  
Il numero di porta della simulazione. Per una simulazione iniziata in Cloud AWS, questo è il numero di `Actual` porta. Puoi trovare il numero di porta della simulazione nella [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver) o utilizzare la procedura [Ottieni l'indirizzo IP e il numero di porta di un'app personalizzataOttieni l'indirizzo IP e il numero di porta](working-with_get-ip.md) del tutorial di avvio rapido. Per una simulazione locale, usa `7000` come numero di porta.  
**simsize**  
Il numero massimo di entità da visualizzare nel client.

# Domande frequenti sull'uso di Python
<a name="working-with_python_faq"></a>

## D1. Quali versioni di Python sono supportate?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver supporta solo la versione 3.9 di Python.

# Risoluzione dei problemi relativi a Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Errore durante la creazione di contenitori personalizzati](working-with_python_troubleshooting_create-container-failure.md)
+ [La tua simulazione in Python non si avvia](working-with_python_troubleshooting_no-start.md)
+ [Un client di simulazione o visualizzazione in Python genera un errore ModuleNotFound](working-with_python_troubleshooting_module-not-found.md)

# Errore durante la creazione di contenitori personalizzati
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Se ricevi un errore `no basic auth credentials` dopo l'esecuzione`quick-start.py`, potrebbe esserci un problema con le tue credenziali temporanee per Amazon ECR. Esegui il comando seguente con il tuo Regione AWS ID e il numero di AWS account:

```
aws ecr get-login-password --region region | docker login --username AWS --password-stdin account_id.dkr.ecr.region.amazonaws.com
```

**Example**  

```
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.region.amazonaws.com
```

**Importante**  
Assicurati che Regione AWS quello specificato sia lo stesso che usi per la simulazione. Usa uno dei SimSpace Weaver supporti Regioni AWS supportati. Per ulteriori informazioni, consulta [SimSpace Endpoint e quote Weaver](service-quotas.md).

Dopo aver eseguito il `aws ecr` comando, esegui `quick-start.py` di nuovo.

**Altre risorse per la risoluzione dei problemi da verificare**
+ [Risoluzione dei problemi relativi ai contenitori personalizzati](working-with_custom-containers_troubleshooting.md)
+ [Risoluzione dei problemi di Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) nella *Amazon ECR* User Guide
+ [Configurazione con Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) nella Amazon ECR *User Guide*

# La tua simulazione in Python non si avvia
<a name="working-with_python_troubleshooting_no-start"></a>

Potresti visualizzare un `Unable to start app` errore nel registro di gestione della simulazione. Questo può accadere se la creazione del contenitore personalizzato non è riuscita. Per ulteriori informazioni, consulta [Errore durante la creazione di contenitori personalizzati](working-with_python_troubleshooting_create-container-failure.md). Per ulteriori informazioni sui log, consulta [SimSpace Weaver accessi in Amazon CloudWatch Logs](cloudwatch-logs.md).

Se sei sicuro che non ci sia nulla di sbagliato nel tuo contenitore, controlla il codice sorgente Python dell'app. È possibile utilizzare… SimSpace Weaver Local per testare la tua app. Per ulteriori informazioni, consulta [Sviluppo locale in SimSpace Weaver](working-with_local-development.md).

# Un client di simulazione o visualizzazione in Python genera un errore ModuleNotFound
<a name="working-with_python_troubleshooting_module-not-found"></a>

Python genera un `ModuleNotFound` errore quando non riesce a trovare un pacchetto Python richiesto.

Se la tua simulazione è in Cloud AWS, assicurati che il tuo contenitore personalizzato abbia tutte le dipendenze richieste elencate nel tuo. `requirements.txt` Ricordati di eseguirlo di `quick-start.py` nuovo se apporti modifiche. `requirements.txt`

Se ricevi l'errore relativo al `PythonBubblesSample` client, usa `pip` per installare il pacchetto indicato:

```
pip install package-name==version-number
```

# Support per altri motori
<a name="working-with_engines"></a>

Puoi usare il tuo personalizzato C\$1\$1 motore con SimSpace Weaver. Attualmente stiamo sviluppando il supporto per i seguenti motori. Esiste una documentazione separata per ciascuno di questi motori.

**Importante**  
Le integrazioni con i motori elencati qui sono sperimentali. Sono disponibili in anteprima.

**Motori**
+ [Unità](#working-with_engines_unity)(versione minima 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal)(versione minima 5.0)

## Unità
<a name="working-with_engines_unity"></a>

È necessario disporre del Unity ambiente di sviluppo già installato prima di creare SimSpace Weaver simulazioni con Unity. Per ulteriori informazioni, consulta le istruzioni separate:

```
sdk-folder\Unity-Guide.pdf
```

## Unreal Engine
<a name="working-with_engines_unreal"></a>

È necessario creare un Unreal Engine server dedicato dal codice sorgente. SimSpaceWeaverAppSdkDistributable Include una versione PathfindingSample del Unreal Engine. Per ulteriori informazioni, consulta le istruzioni separate: 

```
sdk-folder\Unreal-Engine-Guide.pdf
```

# Utilizzo di software concesso in licenza con AWS SimSpace Weaver
<a name="working-with_byol"></a>

AWS SimSpace Weaver ti consente di creare simulazioni con il motore di simulazione e i contenuti che preferisci. In relazione all'utilizzo di SimSpace Weaver, l'utente è responsabile dell'ottenimento, della manutenzione e del rispetto delle condizioni di licenza di qualsiasi software o contenuto utilizzato nelle simulazioni. Verifica che il contratto di licenza ti consenta di distribuire software e contenuti in un ambiente ospitato virtuale.

# Gestisci le tue risorse con AWS CloudFormation
<a name="working-with_cloudformation"></a>

Puoi usarlo AWS CloudFormation per gestire le tue AWS SimSpace Weaver risorse. CloudFormation è un AWS servizio separato che consente di specificare, fornire e gestire l' AWS infrastruttura come codice. *[Con CloudFormation te crei un file JSON o YAML, chiamato modello.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)* Il modello specifica i dettagli della tua infrastruttura. CloudFormation utilizza il modello per effettuare il provisioning dell'infrastruttura come una singola unità, denominata *[stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)*. Quando elimini lo stack, puoi fare in modo che CloudFormation tutti gli elementi dello stack vengano eliminati contemporaneamente. Puoi gestire il tuo modello utilizzando processi standard di gestione del codice sorgente (ad esempio, tracciandolo in un sistema di controllo della versione come [Git](https://git-scm.com/)). Per ulteriori informazioni in merito CloudFormation, consulta la [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**La tua risorsa di simulazione**  
In AWS, una *risorsa* è un'entità con cui puoi lavorare. Gli esempi includono un' EC2 istanza Amazon, un bucket Amazon S3 o un ruolo IAM. La tua SimSpace Weaver simulazione è una risorsa. Nelle configurazioni, di solito si specifica una AWS risorsa nel modulo. `AWS::service::resource` Infatti SimSpace Weaver, si specifica la risorsa di simulazione come. `AWS::SimSpaceWeaver::Simulation` Per ulteriori informazioni sulla risorsa di simulazione in CloudFormation, consulta la [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)sezione della Guida per l'*AWS CloudFormation utente*.

**Come posso usare CloudFormation con SimSpace Weaver?**  
È possibile creare un CloudFormation modello che specifichi le AWS risorse che si desidera fornire. Il modello può specificare un'intera architettura, parte di un'architettura o una piccola soluzione. Ad esempio, puoi specificare un'architettura per la tua SimSpace Weaver soluzione che includa bucket Amazon S3, autorizzazioni IAM, un database di supporto in Amazon Relational Database Service o Amazon DynamoDB e la tua risorsa. `Simulation` Puoi quindi utilizzarle CloudFormation per fornire tutte queste risorse come unità e contemporaneamente.

**Example modello che crea risorse IAM e avvia una simulazione**  
Il seguente modello di esempio crea un ruolo IAM e le autorizzazioni SimSpace Weaver necessarie per eseguire azioni nel tuo account. Gli script SDK dell' SimSpace Weaver app creano il ruolo e le autorizzazioni in uno specifico Regione AWS quando crei un progetto, ma puoi utilizzare un CloudFormation modello per distribuire la simulazione su un altro Regione AWS senza eseguire nuovamente gli script. Ad esempio, puoi farlo per configurare una simulazione di backup a scopo di disaster recovery.  
In questo esempio, il nome originale della simulazione è. `MySimulation` Un bucket per lo schema esiste già nel file Regione AWS dove CloudFormation verrà creato lo stack. Il bucket contiene una versione dello schema configurata correttamente per eseguire la simulazione in esso. Regione AWS Ricorda che lo schema specifica la posizione dei file zip dell'app, che è un bucket Amazon S3 Regione AWS uguale alla simulazione. Il bucket e i file dell'app zip devono già esistere nello stack Regione AWS when CloudFormation build the stack, altrimenti la simulazione non verrà avviata. Nota che il nome del bucket in questo esempio include Regione AWS, ma ciò non determina dove si trovi effettivamente il bucket. Devi assicurarti che il bucket si trovi effettivamente al suo interno Regione AWS (puoi controllare le proprietà del bucket nella console Amazon S3, con Amazon S3 o con i APIs comandi Amazon S3 in). AWS CLI  
Questo esempio utilizza alcune funzioni e parametri incorporati per eseguire la sostituzione delle variabili. CloudFormation *Per ulteriori informazioni, vedete Riferimento alla [funzione intrinseca e Riferimento](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) agli [pseudo parametri](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) nella Guida per l'utente.AWS CloudFormation *  

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  WeaverAppRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: SimSpaceWeaverAppRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Principal:
            Service:
              - simspaceweaver.amazonaws.com
          Action:
            - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: SimSpaceWeaverAppRolePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
            - Effect: Allow
              Action:
                - logs:PutLogEvents
                - logs:DescribeLogGroups
                - logs:DescribeLogStreams
                - logs:CreateLogGroup
                - logs:CreateLogStream
              Resource: *
            - Effect: Allow
              Action:
                - cloudwatch:PutMetricData
              Resource: *
            - Effect: Allow
              Action:
                - s3:ListBucket
                - s3:PutObject
                - s3:GetObject
              Resource: *
  MyBackupSimulation:
    Type: AWS::SimSpaceWeaver::Simulation
    Properties:
      Name: !Sub 'mySimulation-${AWS::Region}'
      RoleArn: !GetAtt WeaverAppRole.Arn
      SchemaS3Location:
        BucketName: !Sub 'weaver-mySimulation-${AWS::AccountId}-schemas-${AWS::Region}'
        ObjectKey: !Sub 'schema/mySimulation-${AWS::Region}-schema.yaml'
```

# Utilizzo di istantanee con AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

Un'[istantanea](working-with_snapshots.md) è il backup di una simulazione. L'esempio seguente avvia una nuova simulazione da un'istantanea anziché da uno schema. L'istantanea in questo esempio è stata creata da una simulazione di progetto SDK di un' SimSpace Weaver app. CloudFormation crea la nuova risorsa di simulazione e la inizializza con i dati dell'istantanea. La nuova simulazione può avere una simulazione diversa `MaximumDuration` da quella originale.

Ti consigliamo di creare e utilizzare una copia del ruolo dell'app della simulazione originale. Il ruolo dell'app della simulazione originale potrebbe essere eliminato se elimini lo stack di quella simulazione. CloudFormation 

```
Description: "Example - Start a simulation from a snapshot"
Resources:
  MyTestSimulation:
    Type: "AWS::SimSpaceWeaver::Simulation"
    Properties:
      MaximumDuration: "2D"
      Name: "MyTestSimulation_from_snapshot"
      RoleArn: "arn:aws:iam::111122223333:role/weaver-MyTestSimulation-app-role-copy"   
      SnapshotS3Location:
        BucketName: "weaver-mytestsimulation-111122223333-artifacts-us-west-2"
        ObjectKey: "snapshot/MyTestSimulation_22-12-15_12_00_00-230428-1207-13.zip"
```

# Snapshot
<a name="working-with_snapshots"></a>

È possibile creare un'*istantanea* per eseguire il backup dei dati dell'entità di simulazione in qualsiasi momento. SimSpace Weaver crea un file.zip in un bucket Amazon S3. Puoi creare una nuova simulazione con lo snapshot. SimSpace Weaver inizializza lo State Fabric della nuova simulazione con i dati dell'entità memorizzati nell'istantanea, avvia le app spaziali e di servizio che erano in esecuzione al momento della creazione dell'istantanea e imposta l'orologio sul segno di spunta appropriato. SimSpace Weaver ottiene la configurazione della simulazione dall'istantanea anziché da un file di schema. I file.zip dell'app devono trovarsi nella stessa posizione in Amazon S3 in cui si trovavano nella simulazione originale. Tutte le app personalizzate devono essere avviate separatamente.

**Argomenti**
+ [Casi d'uso per le istantanee](#working-with_snapshots_use-cases)
+ [Usa la SimSpace Weaver console per lavorare con le istantanee](working-with_snapshots_console.md)
+ [Usa il AWS CLI per lavorare con le istantanee](working-with_snapshots_cli.md)
+ [Utilizzo di istantanee con AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Domande frequenti sulle istantanee](working-with_snapshots_faq.md)

## Casi d'uso per le istantanee
<a name="working-with_snapshots_use-cases"></a>

### Ritorna allo stato precedente ed esplora gli scenari ramificati
<a name="working-with_snapshots_use-case_branching"></a>

Puoi creare un'istantanea della simulazione per salvarla in uno stato specifico. È quindi possibile creare più nuove simulazioni da quell'istantanea ed esplorare diversi scenari che potrebbero derivare da quello stato.

### Migliori pratiche di disaster recovery e sicurezza
<a name="working-with_snapshots_use-cases_best-practice"></a>

Si consiglia di eseguire regolarmente il backup della simulazione, in particolare per le simulazioni che durano più di un'ora o che utilizzano più lavoratori. I backup possono aiutarti a riprenderti da disastri e incidenti di sicurezza. Le istantanee consentono di eseguire il backup della simulazione. Le istantanee richiedono che i file.zip dell'app esistano nella stessa posizione in Amazon S3 in cui si trovavano in precedenza. Se devi poter spostare i file.zip dell'app in un'altra posizione, devi utilizzare una soluzione di backup personalizzata. 

Per ulteriori informazioni su altre best practice, consulta [Procedure consigliate quando si lavora con SimSpace Weaver](best-practices.md) e[Le migliori pratiche di sicurezza per SimSpace Weaver](security_best-practices.md).

### Estendi la durata della simulazione
<a name="working-with_snapshots_use-cases_extend-duration"></a>

La tua *risorsa di simulazione* è la rappresentazione della tua simulazione in. SimSpace Weaver Tutte le risorse di simulazione hanno un'impostazione. `MaximumDuration` Una risorsa di simulazione si interrompe automaticamente quando raggiunge il suo valore. `MaximumDuration` Il valore massimo di `MaximumDuration` è `14D` (14 giorni). 

Se è necessario che la simulazione persista più a lungo `MaximumDuration` della relativa risorsa di simulazione, è possibile creare un'istantanea prima che la risorsa di simulazione raggiunga il suo valore. `MaximumDuration` Puoi iniziare una nuova simulazione (creare una nuova risorsa di simulazione) con la tua istantanea. SimSpace Weaver inizializza i dati dell'entità dall'istantanea, avvia le stesse app spaziali e di servizio eseguite in precedenza e ripristina l'orologio. Puoi avviare le tue app personalizzate ed eseguire qualsiasi inizializzazione personalizzata aggiuntiva. È possibile impostare la nuova risorsa `MaximumDuration` di simulazione su un valore diverso all'avvio.

# Usa la SimSpace Weaver console per lavorare con le istantanee
<a name="working-with_snapshots_console"></a>

È possibile utilizzare la SimSpace Weaver console per creare un'istantanea della simulazione.

**Topics**
+ [Creazione di una snapshot](#working-with_snapshots_console_create)
+ [Avvia una simulazione da un'istantanea](#working-with_snapshots_console_start)

## Usa la console per creare un'istantanea
<a name="working-with_snapshots_console_create"></a>

**Per creare una snapshot**

1. Accedi a Console di gestione AWS e connettiti alla [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver).

1. Scegli **Simulazioni** dal pannello di navigazione.

1. Seleziona il pulsante radio accanto al nome della simulazione. **Lo stato** **della simulazione deve essere Avviato.** 

1. Nella parte superiore della pagina, scegli **Crea istantanea**.

1. In **Impostazioni snapshot**, per **destinazione Snapshot**, inserisci l'URI Amazon S3 di un bucket o di un bucket e della cartella in cui desideri SimSpace Weaver creare la tua istantanea. Puoi scegliere **Browse S3 se preferisci sfogliare** i bucket disponibili e selezionare una posizione.
**Importante**  
Il bucket Amazon S3 deve essere Regione AWS uguale alla simulazione.
**Nota**  
SimSpace Weaver crea una `snapshot` cartella all'interno della destinazione dello snapshot selezionato. SimSpace Weaver crea il file snapshot .zip in quella cartella. `snapshot`

1. Scegli **Create snapshot (Crea snapshot)**.

## Usa la console per avviare una simulazione da un'istantanea
<a name="working-with_snapshots_console_start"></a>

Per avviare una simulazione da uno snapshot, il file snapshot .zip deve esistere in un bucket Amazon S3 a cui la simulazione può accedere. La simulazione utilizza le autorizzazioni definite nel ruolo dell'app selezionato all'avvio della simulazione. Tutti i file.zip dell'app della simulazione originale devono esistere nelle stesse posizioni in cui è stata creata l'istantanea.

**Per avviare una simulazione da un'istantanea**

1. [Accedi a Console di gestione AWS e connettiti alla SimSpace Weaver console.](https://console.aws.amazon.com/simspaceweaver)

1. Scegli **Simulazioni** dal pannello di navigazione.

1. Nella parte superiore della pagina, scegli **Avvia simulazione**.

1. In **Impostazioni di simulazione**, inserisci un nome e una descrizione opzionale per la simulazione. Il nome della simulazione deve essere univoco nel tuo. Account AWS

1. Per il **metodo di avvio della simulazione**, scegli **Usa uno snapshot in Amazon S3**.

1. Per l'**URI di Amazon S3 per snapshot**, inserisci l'URI Amazon S3 del tuo file di snapshot oppure scegli **Browse S3 per sfogliare** e selezionare il file.
**Importante**  
Il bucket Amazon S3 deve essere Regione AWS uguale alla simulazione.

1. Per il **ruolo IAM**, seleziona il ruolo dell'app che verrà utilizzato dalla simulazione.

1. Per **Durata massima**, inserisci il periodo di tempo massimo per cui la risorsa di simulazione deve essere eseguita. Il valore massimo è `14D`. [Per ulteriori informazioni sulla durata massima, vedere.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. In **Tag, *facoltativo***, scegli **Aggiungi nuovo tag** se desideri aggiungere un tag.

1. Scegli **Avvia simulazione.**

# Usa il AWS CLI per lavorare con le istantanee
<a name="working-with_snapshots_cli"></a>

È possibile utilizzare il AWS CLI per chiamarli SimSpace Weaver APIs da un prompt dei comandi. È necessario che AWS CLI sia installato e configurato correttamente. Per ulteriori informazioni, consulta [Installazione o aggiornamento della versione più recente della AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) nella *Guida per l'AWS Command Line Interface utente per la versione 2*.

**Topics**
+ [Creazione di una snapshot](#working-with_snapshots_cli_create)
+ [Avvia una simulazione da un'istantanea](#working-with_snapshots_cli_start)

## Utilizzate il AWS CLI per creare un'istantanea
<a name="working-with_snapshots_cli_create"></a>

**Per creare una snapshot**
+ Al **prompt dei comandi**, richiama l'`CreateSnapshot`API.

  ```
  aws simspaceweaver create-snapshot --simulation simulation-name —destination s3-destination
  ```

  **Parametri**  
simulazione  
Il nome di una simulazione iniziata. Puoi usarlo `aws simspaceweaver list-simulations` per vedere i nomi e gli stati delle tue simulazioni.  
destinazione  
Una stringa che specifica il bucket Amazon S3 di destinazione e il prefisso opzionale della chiave oggetto per il file di snapshot. Il prefisso della chiave oggetto è in genere una cartella nel bucket. SimSpace Weaver crea la tua istantanea all'interno di una `snapshot` cartella in questa destinazione.   
Il bucket Amazon S3 deve essere Regione AWS uguale alla simulazione.

  **Esempio**

  ```
  aws simspaceweaver create-snapshot —simulation MyProjectSimulation_23-04-29_12_00_00 —destination BucketName=weaver-myproject-111122223333-artifacts-us-west-2,ObjectKeyPrefix=myFolder
  ```

*Per ulteriori informazioni sull'`CreateSnapshot`API, consulta l'API [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)Reference.AWS SimSpace Weaver *

## Utilizzate il AWS CLI per avviare una simulazione da un'istantanea
<a name="working-with_snapshots_cli_start"></a>

**Per avviare una simulazione da un'istantanea**
+ Al **prompt dei comandi**, richiama l'API. `StartSimulation`

  ```
  aws simspaceweaver start-simulation --name simulation-name --role-arn role-arn --snapshot-s3-location s3-location
  ```

  **Parametri**  
name  
Il nome della nuova simulazione. Il nome della simulazione deve essere univoco nel tuo. Account AWS Puoi usarlo `aws simspaceweaver list-simulations` per vedere i nomi delle tue simulazioni esistenti.  
ruolo-arn  
L'Amazon Resource Name (ARN) del ruolo dell'app che verrà utilizzato dalla simulazione.  
snapshot-s3-location  
Una stringa che specifica il bucket Amazon S3 e la chiave oggetto del file snapshot.  
Il bucket Amazon S3 deve essere Regione AWS uguale alla simulazione.

  **Esempio**

  ```
  aws simspaceweaver start-simulation —name MySimulation —role-arn arn:aws:iam::111122223333:role/weaver-MyProject-app-role —snapshot-s3-location BucketName=weaver-myproject-111122223333-artifacts-us-west-2,ObjectKey=myFolder/snapshot/MyProjectSimulation_23-04-29_12_00_00-230429-1530-27.zip
  ```

*Per ulteriori informazioni sull'`StartSimulation`API, consulta l'API [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)Reference.AWS SimSpace Weaver *

# Domande frequenti sulle istantanee
<a name="working-with_snapshots_faq"></a>

**La mia simulazione continua a essere eseguita durante un'istantanea?**  
Le tue risorse di simulazione continuano a funzionare durante un'istantanea e continui a ricevere addebiti di fatturazione per quel periodo. Il tempo viene conteggiato ai fini della durata massima della simulazione. Le tue app non ricevono segni di spunta mentre l'istantanea è in corso. Se lo stato dell'orologio era `STARTED` quando è iniziata la creazione dell'istantanea, l'orologio continuerà a indicare lo stato. `STARTED` Le tue app ricevono nuovamente i segni di spunta al termine dell'istantanea. Se lo stato dell'orologio era, `STOPPED` lo stato dell'orologio rimarrà invariato. `STOPPED` Tieni presente che una simulazione con uno `STARTED` stato è in esecuzione anche se lo stato dell'orologio è`STOPPED`.

**Cosa succede se è in corso un'istantanea e la mia simulazione raggiunge la sua durata massima?**  
La simulazione completerà l'istantanea e poi si interromperà non appena il processo di istantanea termina (con successo o meno). Ti consigliamo di testare prima il processo di istantanea per scoprire quanto tempo impiega, la dimensione del file di istantanea che puoi aspettarti e se il processo deve essere completato correttamente.

**Cosa succede se interrompo una simulazione in cui è in corso un'istantanea?**  
Un'istantanea in corso si interrompe immediatamente quando si interrompe la simulazione. Non creerà un file di istantanea.

**Come posso interrompere un'istantanea in corso?**  
L'unico modo per fermare un'istantanea in corso è interrompere la simulazione. **Non è possibile riavviare una simulazione dopo averla interrotta.**

**Quanto tempo ci vorrà per completare la mia istantanea?**  
Il tempo necessario per creare un'istantanea dipende dalla simulazione. Ti consigliamo di testare prima il processo di istantanea per scoprire quanto tempo impiegherà per la simulazione.

**Quanto sarà grande il mio file di istantanea?**  
La dimensione di un file di istantanea dipende dalla simulazione. Ti consigliamo di testare prima il processo di istantanea per scoprire quanto potrebbe essere grande il file per la tua simulazione.

# Messaggistica
<a name="working-with_messaging"></a>

L'API di messaggistica semplifica la comunicazione tra applicazioni all'interno della simulazione. APIs per inviare e ricevere messaggi fa parte dell'SDK dell' SimSpace Weaver app. La messaggistica attualmente utilizza un approccio ottimale per inviare e ricevere messaggi. SimSpace Weaver tenta di send/receive inviare messaggi alla prossima simulazione, ma non ci sono garanzie sull'orario di consegna, ordinazione o arrivo.

**Argomenti**
+ [Casi d'uso per la messaggistica](#working-with_messaging_use-cases)
+ [Utilizzo della messaggistica APIs](working-with_messaging_using.md)
+ [Quando usare la messaggistica](working-with_messaging_when-to-use.md)
+ [Suggerimenti per l'utilizzo della messaggistica](working-with_messaging_tips.md)
+ [Errori di messaggistica e risoluzione dei problemi](working-with_messaging_troubleshooting.md)

## Casi d'uso per la messaggistica
<a name="working-with_messaging_use-cases"></a>

**Comunica tra applicazioni di simulazione**  
Utilizza l'API di messaggistica per comunicare tra le applicazioni della simulazione. Usala per modificare lo stato delle entità a distanza, modificare il comportamento delle entità o trasmettere informazioni all'intera simulazione.

**Conferma della ricezione di un messaggio**  
I messaggi inviati contengono informazioni sul mittente nell'intestazione del messaggio. Utilizza queste informazioni per inviare una risposta di conferma alla ricezione di un messaggio.

**Inoltra i dati ricevuti da un'app personalizzata ad altre app all'interno della simulazione**  
La messaggistica non sostituisce il modo in cui i client si connettono alle app personalizzate in esecuzione in SimSpace Weaver. Tuttavia, la messaggistica consente agli utenti un metodo per inoltrare i dati dalle app personalizzate che ricevono i dati dei client ad altre app che non dispongono di una connessione esterna. Il flusso di messaggi può funzionare anche in senso inverso, consentendo alle app senza connessione esterna di inoltrare i dati a un'app personalizzata e quindi a un client. 

# Utilizzo della messaggistica APIs
<a name="working-with_messaging_using"></a>

I messaggi APIs sono contenuti nell'SDK dell' SimSpace Weaver app (versione minima 1.16.0). La messaggistica è supportata in C\$1\$1, Python e nelle nostre integrazioni con Unreal Engine 5 e Unity.

Esistono due funzioni che gestiscono le transazioni di messaggi: e. `SendMessage` `ReceiveMessages` Tutti i messaggi inviati contengono una destinazione e un payload. L'`ReceiveMessages`API restituisce un elenco di messaggi attualmente presenti nella coda dei messaggi in entrata di un'app.

------
#### [ C\$1\$1 ]

**Invia messaggio**

```
AWS_WEAVERRUNTIME_API Result<void> SendMessage(
    Transaction& txn,
    const MessagePayload& payload,
    const MessageEndpoint& destination,
    MessageDeliveryType deliveryType = MessageDeliveryType::BestEffort
    ) noexcept;
```

**Ricevi messaggi**

```
AWS_WEAVERRUNTIME_API Result<MessageList> ReceiveMessages(
    Transaction& txn) noexcept;
```

------
#### [ Python ]

**Inviare un messaggio**

```
api.send_message(
 txn, # Transaction
 payload, # api.MessagePayload
 destination, # api.MessageDestination
 api.MessageDeliveryType.BestEffort # api.MessageDeliveryType
)
```

**Ricevi messaggi**

```
api.receive_messages(
 txn, # Transaction
) -> api.MessageList
```

------

**Argomenti**
+ [Invio di messaggi](#working-with_messaging_using_send)
+ [Ricezione di messaggi](#working-with_messaging_using_receive)
+ [Rispondere al mittente](#working-with_messaging_using_reply)

## Invio di messaggi
<a name="working-with_messaging_using_send"></a>

I messaggi sono costituiti da una transazione (simile ad altre chiamate dell'API Weaver), un payload e una destinazione.

### Payload del messaggio
<a name="working-with_messaging_using_send_payload"></a>

Il payload dei messaggi è una struttura dati flessibile fino a 256 byte. Consigliamo quanto segue come best practice per creare i payload dei messaggi.

**Per creare il payload dei messaggi**

1. Crea una struttura di dati (ad esempio `struct` in C\$1\$1) che definisca il contenuto del messaggio.

1. Crea il payload del messaggio che contiene i valori da inviare nel messaggio.

1. Crea l’oggetto `MessagePayload`.

### Destinazione del messaggio
<a name="working-with_messaging_using_send_destination"></a>

La destinazione di un messaggio è definita dall'`MessageEndpoint`oggetto. Ciò include sia un tipo di endpoint che un ID di endpoint. L'unico tipo di endpoint attualmente supportato è`Partition`, che consente di indirizzare messaggi ad altre partizioni nella simulazione. L'ID endpoint è l'ID di partizione della destinazione di destinazione.

Puoi fornire solo 1 indirizzo di destinazione in un messaggio. Crea e invia più messaggi se desideri inviare messaggi a più di 1 partizione contemporaneamente.

Per indicazioni su come risolvere un endpoint di messaggio da una posizione, vedere. [Suggerimenti per l'utilizzo della messaggistica](working-with_messaging_tips.md)

### Inviare il messaggio
<a name="working-with_messaging_using_send_send"></a>

È possibile utilizzare l'`SendMessage`API dopo aver creato gli oggetti di destinazione e di payload.

------
#### [ C\$1\$1 ]

```
Api::SendMessage(transaction, payload, destination, MessageDeliveryType::BestEffort);
```

------
#### [ Python ]

```
api.send_message(txn, payload, destination, api.MessageDeliveryType.BestEffort)
```

------

**Esempio completo di invio di messaggi**  
L'esempio seguente mostra come è possibile costruire e inviare un messaggio generico. Questo esempio invia 16 messaggi singoli. Ogni messaggio contiene un payload con un valore compreso tra 0 e 15 e il segno di spunta di simulazione corrente.

**Example**  

```
// Message struct definition
struct MessageTickAndId
{
    uint32_t id;
    uint32_t tick;
};

Aws::WeaverRuntime::Result<void> SendMessages(Txn& txn) noexcept
{
     // Fetch the destination MessageEndpoint with the endpoint resolver
    WEAVERRUNTIME_TRY(
        Api::MessageEndpoint destination,
        Api::Utils::MessageEndpointResolver::ResolveFromPosition(
        txn,
            "MySpatialSimulation",
            Api::Vector2F32 {231.3, 654.0}
        )
    );
    Log::Info("destination: ", destination);

    WEAVERRUNTIME_TRY(auto tick, Api::CurrentTick(txn));

    uint16_t numSentMessages = 0;
    for (std::size_t i=0; i<16; i++)
    {
        // Create the message that'll be serialized into payload
        MessageTickAndId message {i, tick.value};
        
        // Create the payload out of the struct
        const Api::MessagePayload& payload = Api::Utils::CreateMessagePayload(
            reinterpret_cast<const std::uint8_t*>(&message), 
            sizeof(MessageTickAndId)
        );
        
        // Send the payload to the destination
        Result<void> result = Api::SendMessage(txn, payload, destination);
        if (result.has_failure())
        {
            // SendMessage has failure modes, log them
            auto error = result.as_failure().error();
            std::cout<< "SendMessage failed, ErrorCode: " << error << std::endl;
            continue;
        }
        
        numSentMessages++;
    }

    std::cout << numSentMessages << " messages is sent to endpoint" 
       << destination << std::endl;
    return Aws::WeaverRuntime::Success();
}
```

```
# Message data class
@dataclasses.dataclass
class MessageTickAndId:
    tick: int = 0
    id: int = 0
    
# send messages
def _send_messages(self, txn):
    tick = api.current_tick(txn)
    num_messages_to_send = 16

    # Fetch the destination MessageEndpoint with the endpoint resolver
    destination = api.utils.resolve_endpoint_from_domain_name_position(
       txn,
       "MySpatialSimulation",
       pos
   )
    Log.debug("Destination_endpoint = %s", destination_endpoint)

   for id in range(num_messages_to_send):
       # Message struct that'll be serialized into payload
        message_tick_and_id = MessageTickAndId(id = id, tick = tick.value)
        
       # Create the payload out of the struct
        message_tick_and_id_data = struct.pack(
           '<ii',
           message_tick_and_id.id,
           message_tick_and_id.tick
       )
        payload = api.MessagePayload(list(message_tick_and_id_data))

        # Send the payload to the destination
        Log.debug("Sending message: %s, endpoint: %s",
           message_tick_and_id,
           destination
       )
        api.send_message(
           txn,
           payload,
           destination,
           api.MessageDeliveryType.BestEffort
       )

    Log.info("Sent %s messages to %s", num_messages_to_send, destination)
    return True
```

## Ricezione di messaggi
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver consegna i messaggi nella coda dei messaggi in entrata di una partizione. Utilizza l'`ReceiveMessages`API per ottenere un `MessageList` oggetto che contiene i messaggi dalla coda. Elabora ogni messaggio con l'`ExtractMessage`API per ottenere i dati del messaggio.

**Example**  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
     // Fetch all the messages sent to the partition owned by the app
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    std::cout << "Received" << messages.messages.size() << " messages" << std::endl;
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;

         // Deserialize payload to the message struct
        const MessageTickAndId& receivedMessage 
            = Api::Utils::ExtractMessage<MessageTickAndId>(message);
        std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id 
            <<", Tick: " << receivedMessage.tick << std::endl;
    }

    return Aws::WeaverRuntime::Success();
}
```

```
# process incoming messages
def _process_incoming_messages(self, txn):
    messages = api.receive_messages(txn)
    for message in messages:
        payload_list = message.payload.data
        payload_bytes = bytes(payload_list)
        message_tick_and_id_data_struct 
           = MessageTickAndId(*struct.unpack('<ii', payload_bytes))

        Log.debug("Received message. Header: %s, message: %s", 
                    message.header, message_tick_and_id_data_struct)

    Log.info("Received %s messages", len(messages))
    return True
```

## Rispondere al mittente
<a name="working-with_messaging_using_reply"></a>

Ogni messaggio ricevuto contiene un'intestazione del messaggio con informazioni sul mittente originale del messaggio. Puoi usare message.header.source\$1endpoint per inviare una risposta.

**Example**  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
     // Fetch all the messages sent to the partition owned by the app
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    std::cout << "Received" << messages.messages.size() << " messages" << std::endl;
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;

         // Deserialize payload to the message struct
        const MessageTickAndId& receivedMessage 
            = Api::Utils::ExtractMessage<MessageTickAndId>(message);
        std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id 
            <<", Tick: " << receivedMessage.tick << std::endl;
        
        // Get the sender endpoint and payload to bounce the message back
        Api::MessageEndpoint& sender = message.header.source_endpoint;
        Api::MessagePayload& payload = message.payload;
        Api::SendMessage(txn, payload, sender);
    }

    return Aws::WeaverRuntime::Success();
}
```

```
# process incoming messages
def _process_incoming_messages(self, txn):
    messages = api.receive_messages(txn)
    for message in messages:
        payload_list = message.payload.data
        payload_bytes = bytes(payload_list)
        message_tick_and_id_data_struct 
           = MessageTickAndId(*struct.unpack('<ii', payload_bytes))

        Log.debug("Received message. Header: %s, message: %s", 
                    message.header, message_tick_and_id_data_struct)
       # Get the sender endpoint and payload 
       # to bounce the message back
       sender = message.header.source_endpoint
       payload = payload_list
       api.send_message(
           txn,
           payload_list,
           sender,
           api.MessageDeliveryType.BestEffort

    Log.info("Received %s messages", len(messages))
    return True
```

# Quando usare la messaggistica
<a name="working-with_messaging_when-to-use"></a>

La messaggistica in SimSpace Weaver offre un altro modello per lo scambio di informazioni tra applicazioni di simulazione. Gli abbonamenti forniscono un meccanismo pull per leggere i dati da applicazioni o aree specifiche della simulazione; i messaggi forniscono un meccanismo push per inviare dati ad applicazioni o aree specifiche della simulazione.

Di seguito sono riportati due casi d'uso in cui è più utile inviare dati utilizzando la messaggistica piuttosto che estrarre o leggere i dati tramite un abbonamento.

**Example 1: Invio di un comando a un'altra app per modificare la posizione di un'entità**  

```
// Message struct definition
struct MessageMoveEntity
{
     uint64_t entityId;
    std::array<float, 3> destinationPos;
};

// Create the message 
MessageMoveEntity message {45, {236.67, 826.22, 0.0} };

// Create the payload out of the struct
const Api::MessagePayload& payload = Api::Utils::CreateMessagePayload(
    reinterpret_cast<const std::uint8_t*>(&message), 
    sizeof(MessageTickAndId)
);

// Grab the MessageEndpoint of the recipient app.
Api::MessageEndpoint destination = ...

// One way is to resolve it from the domain name and position
WEAVERRUNTIME_TRY(
    Api::MessageEndpoint destination,
    Api::Utils::MessageEndpointResolver::ResolveFromPosition(
    txn,
        "MySpatialSimulation",
        Api::Vector2F32 {200.0, 100.0}
    )
);

// Then send the message 
Api::SendMessage(txn, payload, destination);
```
Sul lato ricevente, l'app aggiorna la posizione dell'entità e la scrive nello State Fabric.  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
    WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn));
    for (Api::Message& message : messages.messages)
    {
        std::cout << "Received message: " << message << std::endl;
         // Deserialize payload to the message struct
        const MessageMoveEntity& receivedMessage 
            = Api::Utils::ExtractMessage<MessageMoveEntity>(message);
            
        ProcessMessage(txn, receivedMessage);
    }

    return Aws::WeaverRuntime::Success();
}

void ProcessMessage(Txn& txn, const MessageMoveEntity& receivedMessage)
{
     // Get the entity corresponding to the entityId
    Entity entity = EntityFromEntityId (receivedMessage.entityId);
    
    // Update the position and write to StateFabric
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
            txn,
            entity,
            k_vector3f32TypeId, // type id of the entity
            reinterpret_cast<std::int8_t*>(&receivedMessage.destinationPos),
            sizeof(receivedMessage.destinationPos)));
    
}
```

**Example 2: Invio di un messaggio di creazione dell'entità a un'app spaziale**  

```
struct WeaverMessage
{
    const Aws::WeaverRuntime::Api::TypeId messageTypeId;
};

const Aws::WeaverRuntime::Api::TypeId k_createEntityMessageTypeId = { 1 };

struct CreateEntityMessage : WeaverMessage
{
    const Vector3 position;
   const Aws::WeaverRuntime::Api::TypeId typeId;
}; 


CreateEntityMessage messageData { 
    k_createEntityMessageTypeId,                           
    Vector3{ position.GetX(), position.GetY(), position.GetZ() },
    Api::TypeId { 0 }
}

WEAVERRUNTIME_TRY(Api::MessageEndpoint destination, Api::Utils::MessageEndpointResolver::ResolveFromPosition(
    transaction, "MySpatialDomain", DemoFramework::ToVector2F32(position)
));

Api::MessagePayload payload = Api::Utils::CreateMessagePayload(
    reinterpret_cast<const uint8_t*>(&messageData),
    sizeof(CreateEntityMessage));
        
Api::SendMessage(transaction, payload, destination);
```
Sul lato ricevente, l'app crea una nuova entità nello State Fabric e ne aggiorna la posizione.  

```
Result<void> ReceiveMessages(Txn& txn) noexcept
{
    WEAVERRUNTIME_TRY(auto messageList, Api::ReceiveMessages(transaction));
    WEAVERRUNTIME_TRY(auto tick, Api::CurrentTick(transaction));
    for (auto& message : messageList.messages)
    {
        // cast to base WeaverMessage type to determine MessageTypeId
        WeaverMessage weaverMessageBase = Api::Utils::ExtractMessage<WeaverMessage>(message);
        if (weaverMessageBase.messageTypeId == k_createEntityMessageTypeId)
        {
            CreateEntityMessage createEntityMessageData =
                Api::Utils::ExtractMessage<CreateEntityMessage>(message);
        CreateActorFromMessage(transaction, createEntityMessageData));
        }
        else if (weaverMessageBase.messageTypeId == k_tickAndIdMessageTypeId)
        {
            ...
        }
    }
}

void ProcessMessage(Txn& txn, const CreateEntityMessage& receivedMessage)
{
    // Create entity
    WEAVERRUNTIME_TRY(
        Api::Entity entity,
        Api::CreateEntity(transaction, receivedMessage.typeId)
    );
    
    // Update the position and write to StateFabric
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        receivedMessage.typeId,
        reinterpret_cast<std::int8_t*>(&receivedMessage.position),
        sizeof(receivedMessage.position)));
}
```

# Suggerimenti per l'utilizzo della messaggistica
<a name="working-with_messaging_tips"></a>

## Risolvi un endpoint da una posizione o dal nome dell'app
<a name="working-with_messaging_tips_resolve-endpoint"></a>

È possibile utilizzare la `AllPartitions` funzione per ottenere i limiti spaziali e l'ID di dominio necessari per determinare la partizione IDs e le destinazioni dei messaggi. Tuttavia, se conosci la posizione in cui desideri inviare il messaggio, ma non il relativo ID di partizione, puoi utilizzare la funzione. MessageEndpointResolver 

```
/**
* Resolves MessageEndpoint's from various inputs
**/
class MessageEndpointResolver
{
    public:
    /**
    * Resolves MessageEndpoint from position information
    **/
    Result<MessageEndpoint> ResolveEndpointFromPosition(
        const DomainId& domainId,
        const weaver_vec3_f32_t& pos);

    /**
    * Resolves MessageEndpoint from custom app name
    **/
    Result<MessageEndpoint> ResolveEndpointFromCustomAppName(
        const DomainId& domainId,
        const char* agentName);
};
```

## Serializzazione e deserializzazione del payload del messaggio
<a name="working-with_messaging_tips_serialize-payload"></a>

È possibile utilizzare le seguenti funzioni per creare e leggere i payload dei messaggi. Per ulteriori informazioni, consulta MessagingUtils .h nella libreria SDK dell'app sul tuo sistema locale.

```
/**
* Utility function to create MessagePayload from a custom type
*
* @return The @c MessagePayload.
*/
template <class T>
AWS_WEAVERRUNTIME_API MessagePayload CreateMessagePayload(const T& message) noexcept
{
    const std::uint8_t* raw_data = reinterpret_cast<const std::uint8_t*>(&message);

    MessagePayload payload;
    std::move(raw_data, raw_data + sizeof(T), std::back_inserter(payload.data));

    return payload;
}

/**
* Utility function to convert MessagePayload to custom type
*/
template <class T>
AWS_WEAVERRUNTIME_API T ExtractMessage(const MessagePayload& payload) noexcept
{
    return *reinterpret_cast<const T*>(payload.data.data());
}
```

# Errori di messaggistica e risoluzione dei problemi
<a name="working-with_messaging_troubleshooting"></a>

È possibile che si verifichino i seguenti errori quando si utilizza la messaggistica APIs.

## Errori di risoluzione degli endpoint
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Questi errori possono verificarsi prima che un'app invii un messaggio.

### Controllo del nome di dominio
<a name="working-with_messaging_troubleshooting_dns-check"></a>

L'invio di un messaggio a un dispositivo non valido genera il seguente errore:

```
ManifoldError::InvalidArgument {"No DomainId found for the given domain name" }
```

Questo può accadere quando si tenta di inviare un messaggio a un'app personalizzata e tale app personalizzata non ha ancora partecipato alla simulazione. Usa l'`DescribeSimulation`API per assicurarti che l'app personalizzata sia stata lanciata prima di inviarle un messaggio. Questo comportamento è lo stesso in SimSpace Weaver Local e in Cloud AWS.

### Controllo della posizione
<a name="working-with_messaging_troubleshooting_position-check"></a>

Il tentativo di risolvere un endpoint con un nome di dominio valido ma una posizione non valida genera il seguente errore.

```
ManifoldError::InvalidArgument {"Could not resolve endpoint from domain : DomainId { value: domain-id } and position: Vector2F32 { x: x-position, y: y-position}" }
```

Ti consigliamo di utilizzarlo `MessageEndpointResolver` nella `MessageUtils` libreria contenuta nell'SDK dell' SimSpace Weaver app.

## Errori di invio dei messaggi
<a name="working-with_messaging_troubleshooting_message-sending"></a>

I seguenti errori possono verificarsi quando un'app invia un messaggio.

### È stato superato il limite di invio di messaggi per app, per segno di spunta
<a name="working-with_messaging_troubleshooting_send-limit"></a>

Il limite attuale per il numero di messaggi che possono essere inviati per app per segno di simulazione è 128. Le chiamate successive con lo stesso segno di spunta falliranno con il seguente errore: 

```
ManifoldError::CapacityExceeded {"At Max Outgoing Message capacity: {}", 128}
```

SimSpace Weaver tenta di inviare messaggi non inviati con il segno di spunta successivo. Riduci la frequenza di invio per risolvere il problema. Combina payload di messaggi inferiori al limite di 256 byte per ridurre il numero di messaggi in uscita.

Questo comportamento è lo stesso in SimSpace Weaver Local e in. Cloud AWS

### Il limite di dimensione del payload dei messaggi è stato superato
<a name="working-with_messaging_troubleshooting_size-limit"></a>

Il limite attuale per la dimensione del payload dei messaggi è di 256 byte sia in che SimSpace Weaver Local in. Cloud AWS L'invio di un messaggio con un payload superiore a 256 byte genera il seguente errore:

```
ManifoldError::CapacityExceeded {"Message data too large! Max size: {}", 256}
```

SimSpace Weaver controlla ogni messaggio e rifiuta solo quelli che superano il limite. Ad esempio, se l'app tenta di inviare 10 messaggi e 1 non supera il controllo, solo quel messaggio viene rifiutato. SimSpace Weaver invia gli altri 9 messaggi.

Questo comportamento è lo stesso in SimSpace Weaver Local e in Cloud AWS.

### La destinazione è la stessa della fonte
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Le app non possono inviare messaggi alle partizioni di cui sono proprietarie. Se un'app invia un messaggio a una partizione di sua proprietà, viene visualizzato il seguente errore.

```
ManifoldError::InvalidArgument { "Destination is the same as source" }
```

Questo comportamento è lo stesso in SimSpace Weaver Local e in. Cloud AWS

### Messaggistica con il massimo impegno
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver non garantisce la consegna dei messaggi. Il servizio cercherà di completare la consegna dei messaggi al successivo segno di spunta di simulazione, ma i messaggi potrebbero andare persi o subire ritardi.