

Avis de fin de support : le 20 mai 2026, AWS le support de AWS SimSpace Weaver. Après le 20 mai 2026, vous ne pourrez plus accéder à la SimSpace Weaver console ni aux SimSpace Weaver ressources. Pour plus d'informations, voir [AWS SimSpace Weaver fin du support](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html). 

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Travailler avec SimSpace Weaver
<a name="working-with"></a>

Ce chapitre fournit des informations et des conseils pour vous aider à créer vos propres applications dans SimSpace Weaver.

**Topics**
+ [Configuration de votre simulation](working-with_configuring-simulation.md)
+ [Durée maximale d'une simulation](working-with_max-duration.md)
+ [Développement d'applications](working-with_developing-apps.md)
+ [Développement d'applications clientes](working-with_developing-client-applications.md)
+ [Obtenez l'adresse IP et le numéro de port d'une application personnalisée](working-with_get-ip.md)
+ [Lancement du client de visualisation Unreal Engine](working-with_unreal-client.md)
+ [Développement local en SimSpace Weaver](working-with_local-development.md)
+ [AWS SimSpace Weaver SDK de l'application](working-with_app-sdk.md)
+ [AWS SimSpace Weaver framework de démonstration](working-with_demo-framework.md)
+ [Utilisation des quotas de service](working-with_quotas.md)
+ [Simulations de débogage](working-with_debugging.md)
+ [Conteneurs personnalisés](working-with_custom-containers.md)
+ [Travail avec Python](working-with_python.md)
+ [Support pour d'autres moteurs](working-with_engines.md)
+ [Utilisation de logiciels sous licence avec AWS SimSpace Weaver](working-with_byol.md)
+ [Gérez vos ressources avec AWS CloudFormation](working-with_cloudformation.md)
+ [Instantanés](working-with_snapshots.md)
+ [Messagerie](working-with_messaging.md)

# Configuration de votre simulation
<a name="working-with_configuring-simulation"></a>

Un **schéma (ou **schéma**) de simulation** est YAML-fichier texte formaté qui spécifie la configuration d'une simulation. Vous pouvez utiliser le même schéma pour démarrer plusieurs simulations. Le fichier de schéma se trouve dans le dossier du projet pour votre simulation. Vous pouvez utiliser n'importe quel éditeur de texte pour modifier le fichier. SimSpace Weaver lit votre schéma uniquement lorsqu'il démarre la simulation. Les modifications que vous apportez à un fichier de schéma n'affectent que les nouvelles simulations que vous commencez après les modifications. 

Pour configurer votre simulation, modifiez le fichier de schéma de simulation (utilisez le séparateur de chemin approprié pour votre système d'exploitation) :

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

Vous chargez le schéma de simulation lorsque vous créez une nouvelle simulation. Le script d'aide au démarrage rapide de votre projet téléchargera le schéma dans le cadre du processus de création de votre simulation : 

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

Pour plus d'informations sur l'exécution du script de démarrage rapide, consultez [Tutoriel détaillé](getting-started_detailed.md) le [Premiers pas](getting-started.md) chapitre de ce guide.

## Paramètres de configuration de simulation
<a name="working-with_configuring-simulation_config-parameters"></a>

Le schéma de simulation contient des informations d'amorçage, notamment :
+ **Propriétés de simulation** : version du SDK et configuration de calcul (type et nombre de [travailleurs](w2aac51.md#glossary_worker))
+ **Horloges** : taux de tic-tac et tolérances
+ **Stratégies de partitionnement** spatial : topologie spatiale (telle qu'une grille), limites et groupes de placement (regroupement de partitions spatiales sur les travailleurs)
+ **Domaines et applications associées** : compartiment d'applications, chemin et commande (s) de lancement

SimSpace Weaver utilise la configuration de votre schéma pour configurer et organiser les partitions spatiales, lancer des applications et faire avancer la simulation au rythme que vous avez spécifié. 

**Note**  
Le script de création de projet du SDK de l' SimSpace Weaver application génère automatiquement un schéma de simulation pour vous, sur la base de l'exemple d'application.

Les rubriques suivantes décrivent les paramètres du schéma de simulation. Pour une description complète du schéma de simulation, voir[SimSpace Weaver référence du schéma de simulation](schema-reference.md). 

**Topics**
+ [Paramètres de configuration de simulation](#working-with_configuring-simulation_config-parameters)
+ [Version de SDK](working-with_configuring-simulation_sdk-version.md)
+ [Propriétés de simulation](working-with_configuring-simulation_simulation-properties.md)
+ [Workers](working-with_configuring-simulation_workers.md)
+ [Horloge](working-with_configuring-simulation_clock.md)
+ [Stratégies de partitionnement](working-with_configuring-simulation_partitioning-strategies.md)
+ [Domains](working-with_configuring-simulation_domains.md)

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

Le `sdk_version` champ indique la version pour SimSpace Weaver laquelle le schéma est formaté. Valeurs valides: `1.17`, `1.16`, `1.15`, `1.14`, `1.13`, `1.12`

**Important**  
La valeur de inclut `sdk_version` uniquement le numéro de version majeure et le numéro de première version secondaire. Par exemple, la valeur `1.12` spécifie toutes les versions`1.12.x`, telles que `1.12.0``1.12.1`, et`1.12.2`.

# Propriétés de simulation
<a name="working-with_configuring-simulation_simulation-properties"></a>

La `simulation_properties` section de votre schéma indique la configuration de journalisation et le type de données pour le champ d'index (généralement l'emplacement spatial) des entités.

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

La valeur de `log_destination_service` détermine l'interprétation de la valeur de`log_destination_resource_name`. À l’heure actuelle, la seule valeur prise en charge est `logs`. Cela signifie que la valeur de `log_destination_resource_name` est le nom d'un groupe de journaux dans Amazon CloudWatch Logs

**Note**  
La journalisation est facultative. Si vous ne configurez pas les propriétés de destination des journaux, votre simulation ne produira pas de journaux.

Seule la propriété `default_entity_index_key_type` est obligatoire. La seule valeur valide est `Vector3<f32>`.

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

La `workers` section indique le type et le nombre de travailleurs que vous souhaitez utiliser pour votre simulation. SimSpace Weaver utilise ses propres types de travail qui correspondent aux types d' EC2 instances Amazon. 

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

## Permettre des simulations multi-opérateurs
<a name="working-with_configuring-simulation_workers_multi-worker"></a>

Vous pouvez créer une simulation qui utilise plus d'un travailleur. Par défaut, les simulations utilisent 1 travailleur. Vous devez modifier le schéma de simulation avant de démarrer la simulation. 

**Note**  
Vous ne pouvez pas modifier une simulation qui a déjà commencé. Si vous souhaitez activer le mode multitravail pour une simulation en cours, vous devez d'abord arrêter et supprimer la simulation.

Pour utiliser plusieurs travailleurs, définissez le `desired` nombre d'instances de calcul sur une valeur supérieure à 1. Il existe un nombre maximum d'applications pour chaque collaborateur. Pour plus d'informations, consultez[SimSpace Points de terminaison et quotas Weaver](service-quotas.md). SimSpace Weaver n'utilisera plus d'un travailleur que lorsque le nombre d'applications d'un travailleur dépasse cette limite. SimSpace Weaver peut placer une application sur n'importe lequel des travailleurs disponibles. Le placement de l'application sur un collaborateur en particulier n'est pas garanti. 

L'extrait de schéma suivant illustre une configuration pour une simulation qui demande 2 travailleurs. SimSpace Weaver tentera d'allouer le deuxième travailleur si le nombre d'applications dépasse le nombre maximum d'applications pour 1 travailleur.

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

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

La `clock` section définit les propriétés de l'horloge de simulation. Actuellement, vous pouvez uniquement configurer le **taux de ticks** (le nombre de ticks par seconde que l'horloge envoie aux applications). Le taux de ticks est un taux maximum. Le taux de ticks effectif peut être inférieur car toutes les opérations (telles que les mises à jour d'entités) associées à un tick doivent être terminées avant que le prochain tick puisse commencer. Le taux de tic-tac est également appelé **fréquence d'horloge**.

Les valeurs valides pour `tick_rate` dépendent de celles `sdk_version` spécifiées dans votre schéma.

**Valeurs valides pour le taux de ticking**
+ Versions antérieures à `"1.14"` :
  + `10`
  + `15`
  + `30`
+ Version `"1.14"` ou ultérieure :
  + `"10"`
  + `"15"`
  + `"30"`
  + `"unlimited"`

    Pour de plus amples informations, veuillez consulter [Taux de ticks illimité](#working-with_configuring-simulation_clock_unlimited).

**Important**  
Pour les schémas dont la valeur est `sdk_version` antérieure à `"1.14"` la valeur de `tick_rate` est un **entier**, tel que`30`.
Pour les schémas dotés d'un `"1.14"` ou `sdk_version` d'une version ultérieure, la valeur de `tick_rate` est une **chaîne**, telle que`"30"`. La valeur **doit inclure les guillemets**.  
Si vous convertissez une version `"1.12"` ou un `"1.13"` schéma en version `"1.14"` ou ultérieure, vous devez placer la valeur de entre `tick_rate` guillemets.

## Taux de ticks illimité
<a name="working-with_configuring-simulation_clock_unlimited"></a>

Vous pouvez définir la valeur `tick_rate` sur `"unlimited"` pour permettre à votre simulation de s'exécuter aussi vite que votre code peut s'exécuter. Avec un taux de ticks illimité, SimSpace Weaver envoie le prochain tick immédiatement après que toutes les applications ont terminé les validations pour le tick en cours.

**Important**  
Le taux de ticks illimité n'est pas pris en charge dans SimSpace Weaver les versions antérieures à la version 1.14.0. La valeur minimale de `sdk_version` dans le schéma est`"1.14"`.

**Taux de ticks illimité dans SimSpace Weaver Local**  
SimSpace Weaver Localimplémente `"unlimited"` comme si le schéma spécifiait un taux de tic-tac de 10 kHz (10000). L'effet est le même qu'un taux de ticks illimité dans le AWS Cloud. Vous le spécifiez toujours `tick_rate: "unlimited"` dans votre schéma. Pour plus d’informations sur SimSpace Weaver Local, consultez [Développement local en SimSpace Weaver](working-with_local-development.md).

## Questions fréquemment posées sur l'horloge
<a name="working-with_configuring-simulation_clock_faq"></a>

### Q1. Puis-je modifier une simulation STARTED pour utiliser un taux de réussite différent ?
<a name="working-with_configuring-simulation_clock_faq_q1"></a>

Vous ne pouvez modifier le taux de réussite d'une simulation qui existe déjà AWS Cloud à aucun stade de son cycle de vie. Vous ne pouvez pas non plus modifier le taux de réussite d'une simulation en cours d'exécutionSimSpace Weaver Local. Vous pouvez le définir `tick_rate` dans le schéma et démarrer une nouvelle simulation à partir de ce schéma.

### Q2. Puis-je exécuter ma simulation avec un taux de clics illimité dans une version antérieure à la version 1.14 ?
<a name="working-with_configuring-simulation_clock_faq_q2"></a>

Non, le taux de ticking illimité n'est pas pris en charge dans les versions antérieures à la version 1.14.0.

## Résolution des erreurs d'horloge
<a name="working-with_configuring-simulation_clock_troubleshooting"></a>

Si votre simulation ne démarre pas, vous pouvez vérifier la valeur de `"StartError"` dans la sortie de l'**DescribeSimulation**API. Une `tick_rate` valeur non valide dans votre schéma produira les erreurs suivantes.

**Note**  
Le résultat d'erreur affiché ici est affiché sur plusieurs lignes pour améliorer la lisibilité. La sortie d'erreur réelle est une seule ligne.
+ Le `sdk_version` est antérieur à `"1.14"` et la valeur de `tick_rate` est un entier non valide. Valeurs valides : `10`, `15`, `30`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30]\"}]"
  ```
+ Le `sdk_version` est antérieur à `"1.14"` et la valeur de `tick_rate` est une chaîne. Valeurs valides : `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\"}]"
  ```
+ La chaîne `sdk_version` est `"1.14"` ou ultérieure et la valeur de `tick_rate` est une chaîne non valide. Valeurs valides : `"10"`, `"15"`, `"30"`, `"unlimited"`

  ```
  "[{\"errorType\":\"SchemaFormatInvalid\",\"errorMessage\":
      \"$.clock.tick_rate: does not have a value in the enumeration [10, 15, 30, unlimited]\"}]"
  ```
+ La valeur `sdk_version` est `"1.14"` ou ultérieure et la valeur de `tick_rate` est un entier. Valeurs valides : `"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\"}]"
  ```

# Stratégies de partitionnement
<a name="working-with_configuring-simulation_partitioning-strategies"></a>

La `partitioning_strategies` section définit les propriétés de configuration pour les partitions des applications spatiales. Vous indiquez votre propre nom pour une stratégie de partitionnement (un ensemble de propriétés dans cette section) et vous l'utilisez dans la configuration de votre application spatiale.

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

La `topology` propriété indique le type de système de coordonnées utilisé par votre simulation. La valeur `Grid` indique une grille bidimensionnelle (2D).

Pour une `Grid` topologie, l'espace de simulation est modélisé sous la forme d'un cadre de délimitation aligné sur un axe (AABB). Vous spécifiez les limites de coordonnées pour chaque axe de votre AABB dans la propriété. `aabb_bounds` Toutes les entités qui existent dans l'espace dans votre simulation doivent avoir une position dans l'AABB.

## Groupes de placement de grilles
<a name="working-with_configuring-simulation_partitioning-strategies_placement-groups"></a>

Un **groupe de placement** est un ensemble de partitions d'applications spatiales que vous SimSpace Weaver souhaitez placer sur le même travailleur. Vous spécifiez le nombre et la disposition des groupes de placement (dans une grille) dans la `grid_placement_groups` propriété. SimSpace Weaver essaiera de répartir uniformément les partitions entre les groupes de placement. Les zones de propriété des applications spatiales dont les partitions appartiennent au même groupe de placement seront adjacentes dans l'espace.

Nous recommandons que x \$1 y soit égal au nombre de travailleurs souhaité. Si ce n'est pas le cas, SimSpace Weaver vous essaierez d'équilibrer vos groupes de placement entre les travailleurs disponibles.

Si vous ne spécifiez pas de configuration de groupe de placement, SimSpace Weaver nous en calculerons une pour vous.

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

Vous fournissez un nom pour un ensemble de propriétés de configuration pour un domaine. Le paramètre de lancement des applications d'un domaine détermine le type de domaine :
+ **`launch_apps_via_start_app_call`**— domaine personnalisé
+ **`launch_apps_by_partitioning_strategy`**— domaine spatial
+ **`launch_apps_per_worker`**(non inclus dans l'exemple d'application) — domaine de service

**Important**  
SimSpace Weaver prend en charge jusqu'à 5 domaines pour chaque simulation. Cela inclut tous les domaines spatiaux, personnalisés et de service.

```
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
```

**Note**  
SimSpace Weaver Les projets du SDK d'application version 1.12.x utilisent des compartiments distincts pour les fichiers .zip de l'application et le schéma :  
tisserand- *lowercase-project-name* - *account-number* -app-zips- *region*
tisserand- *lowercase-project-name* - *account-number* -schemas- *region*

**Topics**
+ [Configuration de l'application](working-with_configuring-simulation_domains_app-config.md)
+ [Configuration de domaines spatiaux](working-with_configuring-simulation_domains_spatial.md)
+ [Points de terminaison réseau](working-with_configuring-simulation_domains_endpoints.md)
+ [Configuration des domaines de service](working-with_configuring-simulation_domains_service-domains.md)

# Configuration de l'application
<a name="working-with_configuring-simulation_domains_app-config"></a>

Vous spécifiez la configuration d'une application (`app_config`) dans le cadre de la configuration de son domaine. Tous les types de domaines utilisent les mêmes propriétés de configuration d'application.

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

**Note**  
SimSpace Weaver Les projets du SDK d'application version 1.12.x utilisent des compartiments distincts pour les fichiers .zip de l'application et le schéma :  
tisserand- *lowercase-project-name* - *account-number* -app-zips- *region*
tisserand- *lowercase-project-name* - *account-number* -schemas- *region*

La `package` propriété spécifie l'URI S3 d'un fichier zip dans un compartiment S3. Le fichier zip contient le fichier exécutable de l'application (également appelé *binaire*) et toutes les autres ressources dont elle a besoin (telles que les bibliothèques). Chaque instance de l'exécutable de l'application s'exécute dans un Docker conteneur sur un worker. 

La `launch_command` propriété indique le nom de l'exécutable et les options de ligne de commande permettant d'exécuter l'application. La valeur de `launch_command` est un tableau. Chaque jeton de la chaîne de commande de lancement complète est un élément du tableau.

**Exemple**
+ Pour la commande de lancement : `MyTestApp --option1 value1`
+ Spécifiez : `launch_command: ["MyTestApp", "-option1", "value1"]`

La `required_resource_units` propriété indique le nombre d'unités de ressources de calcul qui SimSpace Weaver doivent être allouées à cette application. Une unité de ressource informatique est une quantité fixe de capacité de traitement (vCPU) et de mémoire (RAM) d'un travailleur. Vous pouvez augmenter cette valeur pour augmenter la puissance de calcul disponible pour l'application lorsqu'elle est exécutée sur un utilisateur. Le nombre d'unités de ressources de calcul par travailleur est limité. Pour de plus amples informations, veuillez consulter [SimSpace Points de terminaison et quotas Weaver](service-quotas.md).

# Configuration de domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial"></a>

Pour les domaines spatiaux, vous devez spécifier un`partitioning_strategy`. La valeur de cette propriété est le nom que vous avez donné à une stratégie de partitionnement que vous avez définie dans une autre partie du schéma. 

```
  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
```

**Note**  
SimSpace Weaver Les projets du SDK d'application version 1.12.x utilisent des compartiments distincts pour les fichiers .zip de l'application et le schéma :  
tisserand- *lowercase-project-name* - *account-number* -app-zips- *region*
tisserand- *lowercase-project-name* - *account-number* -schemas- *region*

Une stratégie de partitionnement avec une `Grid` topologie (la seule topologie prise en charge dans cette version) indique d' SimSpace Weaver organiser les partitions d'applications spatiales de ce domaine dans une grille. La `grid_partition` propriété indique le nombre de lignes et de colonnes de la grille de partition. 

SimSpace Weaver démarrera 1 instance de l'application spatiale pour chaque cellule de la grille de partition. Par exemple, si un domaine spatial comporte `x: 2` `y: 2` des `grid_partition` valeurs et qu'il comporte 2 \$1 2 = 4 partitions. SimSpace Weaver démarrera 4 instances de l'application configurées dans le domaine spatial et attribuera une partition à chaque instance d'application.

**Rubriques**
+ [Besoins en ressources pour les domaines spatiaux](#working-with_configuring-simulation_domains_spatial_resources)
+ [Domaines spatiaux multiples](#working-with_configuring-simulation_domains_spatial_multiple)
+ [Questions fréquemment posées sur les domaines spatiaux](#working-with_configuring-simulation_domains_spatial_faq)
+ [Résolution des problèmes liés aux domaines spatiaux](#working-with_configuring-simulation_domains_spatial_troubleshooting)

## Besoins en ressources pour les domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial_resources"></a>

Vous pouvez attribuer jusqu'à 17 unités de ressources de calcul à chaque travailleur. Vous spécifiez le nombre d'unités de ressources de calcul utilisées par chaque application spatiale dans la `app_config` section de votre domaine spatial.

**Example extrait de schéma montrant les unités de ressources de calcul pour une application spatiale**  

```
  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
```

Pour calculer le nombre d'unités de ressources de calcul requises par un domaine, multipliez le nombre de cellules de votre grille (dans votre`grid_partition`, `x` \$1`y`) par le nombre d'unités de ressources de calcul attribuées aux applications spatiales.

Dans l'exemple précédent, le domaine `MySpatialDomain` spécifie :
+ `x`: `2`
+ `y`: `2`
+ `compute`: `1`

La grille pour `MySpatialDomain` comporte 2 \$1 2 = 4 cellules. Le domaine spatial nécessite 4 \$1 1 = 4 unités de ressources de calcul.

Le nombre total d'unités de ressources de calcul pour tous les domaines spécifiés dans votre schéma doit être inférieur ou égal au `desired` nombre de travailleurs multiplié par le nombre maximum d'unités de ressources de calcul pour chaque travailleur (17).

## Domaines spatiaux multiples
<a name="working-with_configuring-simulation_domains_spatial_multiple"></a>

Vous pouvez configurer votre simulation pour utiliser plusieurs domaines spatiaux. Par exemple, vous pouvez utiliser un domaine spatial pour contrôler les principaux acteurs d'une simulation (tels que les personnes et les voitures) et un autre domaine spatial pour contrôler l'environnement.

Vous pouvez également utiliser plusieurs domaines spatiaux pour affecter différentes ressources aux différentes parties de votre simulation. Par exemple, si votre simulation comporte un type d'entité qui possède 10 fois plus d'instances d'entités qu'un autre type, vous pouvez créer différents domaines pour gérer chaque type d'entité et allouer plus de ressources au domaine comportant plus d'entités.

**Important**  
SimSpace Weaver les versions antérieures à la version 1.14.0 ne prennent pas en charge plusieurs domaines spatiaux.

**Important**  
AWS SimSpace Weaver Localne prend actuellement pas en charge plusieurs domaines spatiaux. Pour plus d’informations sur SimSpace Weaver Local, consultez [Développement local en SimSpace Weaver](working-with_local-development.md).

**Important**  
SimSpace Weaver prend en charge jusqu'à 5 domaines pour chaque simulation. Cela inclut tous les domaines spatiaux, personnalisés et de service.

### Configuration de plusieurs domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial_multiple_configure"></a>

Pour configurer plusieurs domaines spatiaux, ajoutez les autres définitions de domaines spatiaux sous forme de sections nommées distinctes dans votre schéma. Chaque domaine doit spécifier la `launch_apps_by_partitioning_strategy` clé. Consultez l'exemple de schéma suivant.

```
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
```

### Regroupement de domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial_multiple_placement"></a>

Dans certains scénarios, vous souhaiterez peut-être placer les partitions d'un domaine spatial sur des serveurs à côté des partitions d'un autre domaine. Cela peut améliorer les performances si ces partitions créent des abonnements interdomaines les unes aux autres.

Ajoutez la clé de niveau supérieur `placement_constraints` à votre schéma pour spécifier les domaines à SimSpace Weaver placer ensemble. La `on_workers` clé requise doit faire référence à une `workers` configuration nommée dans le schéma.

**Example extrait de schéma montrant les domaines spatiaux placés ensemble**  

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

**Important**  
Si vous utilisez des groupes de placement :  
Assurez-vous que x \$1 y est un multiple du nombre de travailleurs.
Assurez-vous que les valeurs des groupes de placement sont des diviseurs communs pour les dimensions de la grille des domaines que vous placez ensemble.
Si vous **n'utilisez pas** de groupes de placement :  
Assurez-vous qu'un axe de vos grilles de domaine spatial possède un diviseur commun égal au nombre de travailleurs.
Pour plus d'informations sur les groupes de placement, consultez[Stratégies de partitionnement](working-with_configuring-simulation_partitioning-strategies.md#working-with_configuring-simulation_partitioning-strategies_placement-groups).

## Questions fréquemment posées sur les domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial_faq"></a>

### Q1. Comment puis-je ajouter un autre domaine spatial à une simulation existante ?
<a name="working-with_configuring-simulation_domains_spatial_faq_q1"></a>
+ **Pour une simulation en cours d'exécution** : vous ne pouvez pas modifier la configuration d'une simulation en cours d'exécution. Modifiez la configuration du domaine dans le schéma, téléchargez le schéma et les fichiers compressés de l'application, puis lancez une nouvelle simulation.
+ **Pour une nouvelle simulation** : ajoutez la configuration du domaine au schéma, téléchargez le schéma et les fichiers compressés de l'application, puis lancez la nouvelle simulation.

## Résolution des problèmes liés aux domaines spatiaux
<a name="working-with_configuring-simulation_domains_spatial_troubleshooting"></a>

L'erreur suivante peut s'afficher lorsque vous essayez de démarrer votre simulation mais que la configuration de votre domaine n'est pas valide.

```
"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].\"}]"
```

**Causes potentielles**
+ Le schéma alloue plus d'unités de ressources de calcul aux applications que celles disponibles pour les travailleurs.
+ SimSpace Weaver Impossible de déterminer un arrangement pour placer les domaines ensemble entre les mains des travailleurs. Cela se produit lorsque vous spécifiez plusieurs domaines spatiaux mais qu'il n'existe pas de diviseur commun (ou multiple entre les grilles de domaines, par exemple entre une grille 2x4 et une grille 3x5).

# Points de terminaison réseau
<a name="working-with_configuring-simulation_domains_endpoints"></a>

Les applications personnalisées et de service peuvent comporter des points de terminaison réseau auxquels les clients externes peuvent se connecter. Vous spécifiez une liste de numéros de port comme valeur pour `ingress_ports``endpoint_config`. Ces numéros de port sont à la fois TCP et UDP. L'application personnalisée ou de service doit être liée aux numéros de port que vous spécifiez dans`ingress_ports`. SimSpace Weaver alloue dynamiquement les numéros de port lors de l'exécution et mappe ces ports aux ports dynamiques. Vous pouvez appeler l'**describe-app**API une fois que vos applications ont commencé à rechercher les numéros de port dynamiques (réels). Pour plus d'informations, consultez le didacticiel [Obtenez l'adresse IP et le numéro de port d'une application personnaliséeObtenez l'adresse IP et le numéro de port](working-with_get-ip.md) de démarrage rapide.

```
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
```

**Note**  
SimSpace Weaver Les projets du SDK d'application version 1.12.x utilisent des compartiments distincts pour les fichiers .zip de l'application et le schéma :  
tisserand- *lowercase-project-name* - *account-number* -app-zips- *region*
tisserand- *lowercase-project-name* - *account-number* -schemas- *region*

**Note**  
`endpoint_config`est une propriété facultative pour les applications personnalisées et les applications de service. Si vous n'en spécifiez pas`endpoint_config`, l'application n'aura pas de point de terminaison réseau.

# Configuration des domaines de service
<a name="working-with_configuring-simulation_domains_service-domains"></a>

La présence de `launch_apps_per_worker:` dans une configuration de domaine indique qu'il s'agit d'un domaine de service qui possède des applications de service. SimSpace Weaver démarre et arrête les applications de service pour vous. Lors du SimSpace Weaver démarrage et de l'arrêt d'une application, celle-ci est considérée comme ayant un *cycle de vie géré*. SimSpace Weaver prend actuellement en charge le démarrage d'une ou deux applications de service pour chaque travailleur. 

**Example Exemple de domaine configuré pour lancer une application de service sur chaque travailleur**  

```
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 Exemple de domaine configuré pour lancer 2 applications de service sur chaque travailleur**  

```
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
```

# Durée maximale d'une simulation
<a name="working-with_max-duration"></a>

Chaque simulation AWS SimSpace Weaver possède un paramètre de *durée maximale* qui indique la durée maximale pendant laquelle la simulation peut s'exécuter. Vous indiquez la durée maximale en tant que paramètre lorsque vous lancez une simulation. L'[interface de programmation d'`StartSimulation`applications (API)](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html) possède un paramètre facultatif`MaximumDuration`. La valeur du paramètre est un nombre de minutes (m ou M), d'heures (h ou H) ou de jours (d ou D). Par exemple, `1h` ou `1H` signifie 1 heure. SimSpace Weaver arrête votre simulation lorsqu'elle atteint cette limite.

## Valeur maximale
<a name="working-with_max-duration_max-value"></a>

La valeur valide la plus élevée pour `MaximumDuration` est`14D`, ou son équivalent en heures (`336H`) ou minutes (`20160M`).

## Valeur par défaut
<a name="working-with_max-duration_default-value"></a>

Le paramètre `MaximumDuration` est facultatif. Si vous ne fournissez pas de valeur, SimSpace Weaver utilise une valeur de`14D`.

## Valeur minimale
<a name="working-wtih_max-duration_min-value"></a>

La valeur valide la plus basse pour `MaximumDuration` est une valeur numériquement équivalente à`0`. Par exemple, les valeurs `0M` `0H``0D`, et sont toutes numériquement équivalentes à`0`.

Si vous indiquez la valeur minimale pour une durée maximale, votre simulation passe immédiatement à l'`STOPPING`état dès qu'elle atteint `STARTED` cet état.

## Lancer une simulation à l'aide de la console
<a name="working-with_max-duration_console"></a>

Vous pouvez fournir une valeur pour la **durée maximale** lorsque vous lancez une simulation dans la [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver). Entrez la valeur dans le champ **Durée maximale** du formulaire des **paramètres de simulation** lorsque vous choisissez **Démarrer la simulation**.

**Important**  
Si vous ne fournissez pas de valeur pour la **durée maximale**, SimSpace Weaver utilise la [valeur par défaut](#working-with_max-duration_default-value) (`14D`).

## État d'une simulation qui atteint sa durée maximale
<a name="working-with_max-duration_sim-state"></a>

Lorsque s'arrête SimSpace Weaver automatiquement une simulation qui atteint sa durée maximale, le **statut** de la simulation est `STOPPING` (si elle est en cours) ou`STOPPED`. Dans la [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver), l'**état cible** de la simulation est toujours`STARTED`, car il s'agit du dernier état demandé par un utilisateur.

# Développement d'applications
<a name="working-with_developing-apps"></a>

SimSpace Weaver le développement nécessite un Amazon Linux 2 (AL2) environnement pour créer des applications car vos simulations s'exécutent sur Amazon Linux dans le AWS Cloud. Si vous utilisez Windows, vous pouvez utiliser des scripts dans le SDK de SimSpace Weaver l'application pour créer et lancer un Docker conteneur qui fonctionne AL2 avec les dépendances dont vous avez besoin pour créer des SimSpace Weaver applications. Vous pouvez également lancer un AL2 environnement utilisant Windows Subsystem for Linux (WSL), ou utilisez un natif AL2 système. Pour de plus amples informations, veuillez consulter [Configurez votre environnement local pour SimSpace Weaver](setting-up_local.md).

**Note**  
Quelle que soit la façon dont vous configurez votre environnement de développement local, vos applications s'exécutent dans Docker conteneurs lorsque vous les téléchargez pour qu'ils s'exécutent dans le AWS Cloud. **Vos applications n'ont pas d'accès direct au système d'exploitation hôte**.

**Flux général d'une SimSpace Weaver application**

1. Créez une application 

1. Boucle :

   1. Commencez la mise à jour en créant un`Transaction`.

      1. Quittez la boucle si la simulation s'arrête.

   1. Traitez les événements liés à l'abonnement et à l'entité propriétaire.

   1. Mettez à jour la simulation.

   1. Validez le `Transaction` pour mettre fin à la mise à jour.

1. Détruisez l'application.

## Applications spatiales
<a name="working-with_developing-apps_spatial-apps"></a>

Chaque application spatiale possède une zone de propriété qui est une région spatiale du monde de la simulation. Les entités situées dans la zone de propriété d'une application spatiale sont stockées dans la partition attribuée à l'application. L'application spatiale unique possède la pleine propriété (autorisations de lecture et d'écriture) de toutes les entités au sein de la partition qui lui est attribuée. Aucune autre application ne peut écrire dans ces entités. L'application spatiale améliore l'état de ses entités. Chaque application spatiale ne possède qu'une seule partition. SimSpace Weaver utilise l'emplacement spatial d'une entité pour l'indexer et l'attribuer à une partition spatiale d'application.

Le SDK de SimSpace Weaver l'application fournit un exemple d'application. Le code source de l'application spatiale de l'exemple d'application se trouve dans le dossier suivant (utilisez le séparateur de chemin adapté à votre système d'exploitation) : 

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

## Apps personnalisées
<a name="working-with_developing-apps_custom-apps"></a>

Vous créez et utilisez des applications personnalisées pour interagir avec la simulation. 

**Les applications personnalisées peuvent**
+ Création d'entités
+ S'abonner à d'autres partitions
+ Valider les modifications

**Flux général d'une application personnalisée**

1. Créez une application 

1. Abonnez-vous à une région spécifique dans la simulation :

   1. Créez un `Transaction` pour commencer la première mise à jour.

   1. Créez un abonnement pour la région spécifique.

   1. Validez le `Transaction` pour mettre fin à la première mise à jour.

1. Boucle :

   1. Créez un `Transaction` pour commencer la mise à jour.

      1. Quittez la boucle si la simulation s'arrête.

   1. Modifications de l'état du processus.

   1. Validez le `Transaction` pour mettre fin à la mise à jour.

1. Détruisez l'application.

Une fois qu'une application personnalisée a créé une entité, elle doit la transférer dans un domaine spatial pour que l'entité existe spatialement dans la simulation. SimSpace Weaver utilise l'emplacement spatial de l'entité pour placer l'entité dans la partition spatiale d'application appropriée. L'application personnalisée qui a créé l'entité ne peut ni mettre à jour ni supprimer l'entité après l'avoir transférée dans un domaine spatial. 

Le SDK de SimSpace Weaver l'application fournit un exemple d'application. Vous pouvez utiliser les applications personnalisées incluses dans l'exemple d'application comme modèles pour vos propres applications personnalisées. Vous trouverez le code source de l'application View (une application personnalisée) de l'exemple d'application dans le dossier suivant (utilisez le séparateur de chemin adapté à votre système d'exploitation) :

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

# Développement d'applications clientes
<a name="working-with_developing-client-applications"></a>

Parmi les raisons pour lesquelles vous souhaiterez peut-être connecter un client à une simulation, citons :
+ Injectez des informations de trafic en temps réel dans une simulation à l'échelle d'une ville.
+ Créez *human-in-the-loop*des simulations dans lesquelles un opérateur humain contrôle certains aspects de la simulation.
+ Permettez aux utilisateurs d'interagir avec la simulation, par exemple pour une simulation d'entraînement.

Les applications personnalisées présentées dans ces exemples font office d'interface entre l'état de simulation et le monde extérieur. Les clients se connectent aux applications personnalisées pour interagir avec la simulation. 

SimSpace Weaver ne gère pas les applications clientes et leur communication avec vos applications personnalisées. Vous êtes responsable de la conception, de la création, du fonctionnement et de la sécurité de vos applications clientes, ainsi que de leur communication avec vos applications personnalisées. SimSpace Weaver expose uniquement une adresse IP et un numéro de port pour chacune de vos applications personnalisées afin que les clients puissent s'y connecter. 

Le SDK de SimSpace Weaver l'application fournit des clients pour son exemple d'application. Vous pouvez utiliser ces clients comme modèles pour vos propres applications clientes. Le code source des exemples de clients d'applications se trouve dans le dossier suivant : 

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

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

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

**Important**  
Nous vous fournissons ces instructions pour vous faciliter la tâche. Ils sont destinés à être utilisés avec Windows Subsystem for Linux (WSL), et ne sont pas pris en charge. Pour de plus amples informations, veuillez consulter [Configurez votre environnement local pour SimSpace Weaver](setting-up_local.md).

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

------

Pour plus d'informations sur la création et l'utilisation des exemples de clients d'applications, consultez les didacticiels dans[Commencer avec SimSpace Weaver](getting-started.md). 

# Obtenez l'adresse IP et le numéro de port d'une application personnalisée
<a name="working-with_get-ip"></a>

Pour visualiser votre simulation, vous créez une application personnalisée et vous vous y connectez avec un client. Pour plus d'informations, consultez les didacticiels dans[Commencer avec SimSpace Weaver](getting-started.md). Vous pouvez utiliser la procédure suivante pour obtenir l'adresse IP et le numéro de port de votre application personnalisée. Utilisez le séparateur de chemin adapté à votre système d'exploitation (par exemple, `\` sous Windows et `/` sous Linux).

**Pour obtenir votre adresse IP et votre numéro de port**

1. Utilisez l'** ListSimulations**API pour obtenir le nom de votre simulation.

   ```
   aws simspaceweaver list-simulations
   ```

   Exemple de sortie :

   ```
   {
       "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. Utilisez l'** DescribeSimulation**API pour obtenir la liste des domaines de votre simulation.

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

   Recherchez la `Domains` section dans la `LiveSimulationState` section de la sortie.

   Exemple de sortie :

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

1. Utilisez l'** ListApps**API pour obtenir la liste des applications personnalisées d'un domaine. Par exemple, le nom de domaine de l'application d'affichage (personnalisée) dans l'exemple de projet est`MyViewDomain`. Recherchez le nom de l'application dans le résultat.

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

   Exemple de sortie :

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

1. Utilisez l'** DescribeApp**API pour obtenir l'adresse IP et le numéro de port. Pour l'exemple de projet, le nom de domaine est `MyViewDomain` et le nom de l'application est`ViewApp`. 

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

   L'adresse IP et le numéro de port se trouvent dans le `EndpointInfo` bloc de sortie. L'adresse IP est la valeur de `Address` et le numéro de port est la valeur de`Actual`.

   Exemple de sortie :

   ```
   {
       "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"
   }
   ```
**Note**  
La valeur de `Declared` est le numéro de port auquel le code de votre application doit être lié. La valeur de `Actual` est le numéro de port qui SimSpace Weaver permet aux clients de se connecter à votre application. SimSpace Weaver mappe le `Declared` port par `Actual` rapport au port.

# Lancement du client de visualisation Unreal Engine
<a name="working-with_unreal-client"></a>

 Naviguez vers : 

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

1. Exécutez une des commandes suivantes :
   + Docker : `python quick-start.py`
   + WSL : `python quick-start.py --al2`

1. Obtenez l'adresse IP et le numéro de port « réel ». Ils figureront dans la sortie de console après l'exécution de quick-start.py, ou obtenez-les en suivant les procédures sur[Obtenez l'adresse IP et le numéro de port d'une application personnaliséeObtenez l'adresse IP et le numéro de port](working-with_get-ip.md).

1.  Naviguez vers : 

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

1.  Exécutez les commandes suivantes pour créer la bibliothèque NNG : 

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

1.  Dans un **éditeur de texte**, ouvrez`view_app_url.txt`. 

1.  Mettez à jour l'URL avec l'adresse IP et le numéro de port de votre application View : `tcp://ip-address:actual-port-number` (cela devrait ressembler à`tcp://198.51.100.135:1234`). 

1.  Dans l'**éditeur Unreal**, choisissez **Play**. 

## Résolution des problèmes
<a name="working-with_unreal-client_troubleshooting"></a>
+  **L'étape d' CMake installation de NNG échoue avec le message « Peut-être avez-vous besoin de privilèges administratifs » :** 

  ```
  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)
  ```
  +  **Résolution :** si elle `nng.lib` `nng.so` existe dans le répertoire UnrealClient /lib, cette erreur peut être ignorée en toute sécurité. Sinon, essayez d'exécuter les commandes cmake build dans un terminal avec des privilèges d'administrateur. 
+  **« CMake  pour trouver un fichier de configuration de package fourni par 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.
  ```
  +  **Résolution : vous** CMake ne parvenez pas à trouver le `Findnng.cmake` fichier. Lorsque vous créez avec CMake, ajoutez l'argument`-DTHIRD_PARTY_LIB_PATH sdk-folder/ThirdParty`. Assurez-vous que le `Findnng.cmake` fichier se trouve toujours dans le `ThirdParty` répertoire avant de relancer la CMake compilation. 

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

# Développement local en SimSpace Weaver
<a name="working-with_local-development"></a>

Vous pouvez déployer vos SimSpace Weaver applications localement pour des tests et un débogage rapides.

**Prérequis**
+ Suivez les étapes de [Configuration pour SimSpace Weaver](setting-up.md).

**Topics**
+ [Étape 1 : Lancez votre simulation locale](working-with_local_launch.md)
+ [Étape 2 : Afficher votre simulation locale](working-with_local-development_view.md)
+ [Étape 3 : Arrêtez votre simulation locale (facultatif sous Windows)](working-with_local-development_stop-sim.md)
+ [Résolution des problèmes liés au développement local dans SimSpace Weaver](working-with_local-development_troubleshooting.md)

# Étape 1 : Lancez votre simulation locale
<a name="working-with_local_launch"></a>

1. Naviguez vers

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

1. Exécutez la commande suivante pour créer et lancer votre simulation localement.

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

   Ce script effectuera les opérations suivantes :

   1. Générez le projet.
      +  `quick-start.py`appelle la `build_project` fonction définie dans le fichier build.py. Cette étape varie en fonction du projet. Pour le PathfindingSample, CMake est utilisé. La commande CMake et Docker pour laquelle se trouve dans le fichier build.py. 

   1. Lancez votre simulation locale
      + Le script lancera un processus local pour chaque partition spatiale définie dans le schéma.
      + Le script lancera un processus pour chaque application personnalisée définie dans le schéma.
      + Les applications spatiales seront lancées en premier, suivies des applications personnalisées, chacune dans l'ordre dans lequel elle apparaît dans le schéma.

**Important**  
Lors du lancement dans un environnement qui ne prend pas en charge l'interface graphique, tel qu'une session SSH de console, utilisez l'`--noappwindow`option permettant de rediriger toutes les sorties vers le terminal actuel.

**Important**  
Pour les utilisateurs de Linux, le script suppose que votre système possède la `xterm` commande. Si votre distribution Linux ne dispose pas de cette `xterm` commande, utilisez l'`--noappwindow`option pour rediriger toutes les sorties vers le terminal actuel.
+  -h, --help 
  +  Répertoriez ces paramètres. 
+  --propre 
  +  Supprimez le contenu du répertoire de construction avant de le compiler. 
+  --aucune construction 
  +  Ignorez la reconstruction du projet. 
+  --aucune fenêtre d'application 
  +  N'ouvrez pas de nouvelle fenêtre pour chaque application. Redirigez plutôt la sortie standard vers le terminal actuel. 
+  --fichier journal 
  +  Écrire le résultat de la console dans un fichier journal. 
+  --client de console 
  +  Connectez automatiquement le client de console répertorié dans la configuration. 
+  --schema SCHÉMA
  + Quel schéma utilisera cette invocation. La valeur par défaut est « SCHEMA » dans le fichier config.py. 

# Étape 2 : Afficher votre simulation locale
<a name="working-with_local-development_view"></a>

Pour visualiser votre simulation locale, vous pouvez utiliser n'importe quel client inclus dans le SimSpaceWeaverAppSdkDistributable. Pour plus d'informations sur la création et l'utilisation des exemples de clients, consultez les didacticiels dans[Commencer avec SimSpace Weaver](getting-started.md).

Vous devez mettre à jour l'adresse IP et le numéro de port du client pour vous connecter à l'application View pour votre simulation locale. Utilisez toujours les valeurs suivantes avec SimSpace Weaver Local:

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

En fonction du client sélectionné, vous pouvez mettre à jour l'adresse IP et le numéro de port comme suit :
+ **Unreal** — Modifiez l'URL à la ligne 1 de `view_app_url.txt`
+ **Console** — Lance le client avec l'adresse IP et l'URL du numéro de port comme paramètre

# Étape 3 : Arrêtez votre simulation locale (facultatif sous Windows)
<a name="working-with_local-development_stop-sim"></a>

**Note**  
Cette étape est obligatoire sous Linux mais facultative sous Windows.

1.  Naviguez vers : 

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

1.  Exécutez la commande suivante pour arrêter votre simulation locale et supprimer toutes les ressources de mémoire partagée. 

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

    Ce script effectuera les opérations suivantes : 
   +  Arrêtez les processus locaux. 
   +  Supprimez l'objet de mémoire partagée (uniquement nécessaire sous Linux). 

**stop-and-deleteparamètres .py**
+  -h, --help 
  +  Répertoriez ces paramètres. 
+  --arrête 
  +  Essayez uniquement d'arrêter les processus. 
+  --supprimer 
  +  Essayez uniquement de supprimer les ressources de mémoire partagée. 
+  --processus 
  +  Nom du processus à arrêter. Utilisez-le si le nom de votre processus ne correspond pas au nom du package indiqué dans le schéma. 
+  --schema SCHÉMA 
  +  Quel schéma utilisera cette invocation. La valeur par défaut est « SCHEMA » dans le fichier config.py. 

# Résolution des problèmes liés au développement local dans SimSpace Weaver
<a name="working-with_local-development_troubleshooting"></a>
+  **Linux : commande xterm introuvable/impossible d'ouvrir** 
  + Les scripts locaux supposent que la commande xterm existe lorsqu'elle est exécutée sous Linux. Si vous ne disposez pas de la commande xterm ou si vous utilisez un environnement qui ne prend pas en charge l'interface graphique, utilisez cette `--noappwindow` option lors de l'exécution du script de démarrage rapide.
+  **Aucune fenêtre d'application ne s'ouvre \$1** 
  +  Cela se produit lorsque la simulation locale se bloque immédiatement. Pour voir le résultat de la console après le crash, utilisez les `--logfile` options `--noappwindow` ou lorsque vous exécutez le script de démarrage rapide. 
+  **La simulation ne démarre pas une fois que l'application View démarre ou que le client View se connecte \$1** 
  +  L'utilisation de `—noappwindow` cette option permet généralement de résoudre ce type de problèmes. Sinon, le redémarrage à quelques reprises est également un succès (bien qu'à un rythme beaucoup plus faible). 

# AWS SimSpace Weaver SDK de l'application
<a name="working-with_app-sdk"></a>

Le SDK de SimSpace Weaver l'application APIs vous permet de contrôler les entités de votre simulation et de répondre aux SimSpace Weaver événements. Il inclut l'espace de noms suivant : 
+ **API** — définitions fondamentales de l'API et de son utilisation

Lien vers la bibliothèque suivante :
+ `libweaver_app_sdk_cxx_v1_full.so`

**Important**  
La bibliothèque est disponible pour les liens dynamiques lorsque vous exécutez vos applications dans le AWS Cloud. Vous n'avez pas besoin de le télécharger avec vos applications.

**Note**  
Le SDK de SimSpace Weaver l'application APIs contrôle les données de votre simulation. Ils APIs sont distincts du SimSpace Weaver service APIs, qui contrôlent les ressources de votre SimSpace Weaver service (telles que les simulations, les applications et les horloges). AWS Pour de plus amples informations, veuillez consulter [SimSpace Weaver Références d'API](api-reference.md).

**Topics**
+ [Les méthodes d'API renvoient un Result](working-with_app-sdk_return-result.md)
+ [Interaction avec le SDK de l'application au plus haut niveau](working-with_app-sdk_top-level.md)
+ [Gestion des simulations](working-with_app-sdk_sim.md)
+ [Abonnements](working-with_app-sdk_sub.md)
+ [Entités](working-with_app-sdk_ent.md)
+ [Événements organisés par les entités](working-with_app-sdk_events.md)
+ [Result et gestion des erreurs](working-with_app-sdk_result.md)
+ [Génériques et types de domaines](working-with_app-sdk_generics.md)
+ [Opérations diverses du SDK de l'application](working-with_app-sdk_misc.md)

# Les méthodes d'API renvoient un Result
<a name="working-with_app-sdk_return-result"></a>

La majorité des fonctions d' SimSpace Weaver API ont un type de retour`Aws::WeaverRuntime::Result<T>`. Si la fonction s'est exécutée avec succès, le `Result` contient`T`. Dans le cas contraire, `Aws::WeaverRuntime::ErrorCode` il `Result` contient un code d'erreur provenant du Rust App SDK.

**Example exemple**  

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

Cette méthode :
+ Renvoie `Transaction` si l'`BeginUpdate()`exécution est réussie.
+ Renvoie en `Aws::WeaverRuntime::ErrorCode` cas d'`BeginUpdate()`échec.

# Interaction avec le SDK de l'application au plus haut niveau
<a name="working-with_app-sdk_top-level"></a>

**Cycle de vie**
+ Le SDK de SimSpace Weaver l'application gère le cycle de vie de l'application. Il n'est pas nécessaire de lire ou d'écrire l'état du cycle de vie d'une application.

**Partitions**
+ `Result <PartitionSet> AssignedPartitions(Transaction& txn);`À utiliser pour obtenir des partitions possédées.
+ `Result <PartitionSet> AllPartitions(Transaction& txn);`À utiliser pour obtenir toutes les partitions de la simulation.

# Gestion des simulations
<a name="working-with_app-sdk_sim"></a>

Cette section décrit les solutions pour les tâches courantes de gestion de simulation.

**Topics**
+ [Lancer une simulation](working-with_app-sdk_sim_start.md)
+ [Mettre à jour une simulation](working-with_app-sdk_sim_update.md)
+ [Mettre fin à une simulation](working-with_app-sdk_sim_terminate.md)

# Lancer une simulation
<a name="working-with_app-sdk_sim_start"></a>

`CreateApplication()`À utiliser pour créer une application.

**Example exemple**  

```
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()));
```

# Mettre à jour une simulation
<a name="working-with_app-sdk_sim_update"></a>

Utilisez les `BeginUpdate` fonctions suivantes pour mettre à jour l'application :
+ `Result<Transaction> BeginUpdate(Application& app)`
+ `Result<bool> BeginUpdateWillBlock(Application& app)`— vous indique si vous `BeginUpdate()` allez bloquer ou non.

`Result<void> Commit(Transaction& txn)`À utiliser pour valider les modifications.

**Example exemple**  

```
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();
}
```

# Mettre fin à une simulation
<a name="working-with_app-sdk_sim_terminate"></a>

`Result<void> DestroyApplication(Application&& app)`À utiliser pour mettre fin à l'application et à la simulation.

D'autres applications découvrent que la simulation s'arrête lorsqu'elles reçoivent `ErrorCode::ShuttingDown` des appels vers `BeginUpdateWillBlock()` ou`BeginUpdate()`. Lorsqu'une application reçoit`ErrorCode::ShuttingDown`, elle peut appeler `Result<void> DestroyApplication(Application&& app)` pour se terminer elle-même.

**Example exemple**  

```
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;
        }
    }
}
```

**Important**  
N'appelez qu'`Result<void> DestroyApplication(Application&& app)`après`Api::Commit()`. La destruction d'une application lors d'une mise à jour peut entraîner un comportement indéfini.

**Important**  
Vous devez appeler `DestroyApplication()` avant la fin du programme pour vous assurer que l'application indique qu'elle s'est terminée correctement.  
Si `DestroyApplication()` vous n'appelez pas à la fin du programme, le statut sera considéré comme`FATAL`.

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

Vous créez un abonnement avec un espace d'abonnement et un identifiant de domaine. L'ID de domaine représente le domaine propriétaire de cette zone d'abonnement. A `BoundingBox2F32` décrit la zone d'abonnement. Utilisez la fonction suivante pour créer un abonnement :

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

**Example exemple**  

```
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();
}
```

Vous pouvez utiliser le `Api::SubscriptionHandle` code renvoyé `CreateSubscriptionBoundingBox2F32()` pour modifier l'abonnement. Vous le transmettez en argument aux fonctions suivantes :

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

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

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

Vous appelez le `Store` et `Load` APIs en utilisant `Api:Entity` l'événement `Result<Api::Entity>` renvoyé par ou depuis `CreateEntity()` un changement de propriétaire lorsqu'une entité entre dans la zone d'abonnement de l'application (pour plus d'informations, voir[Événements organisés par les entités](working-with_app-sdk_events.md)). Nous vous recommandons de suivre vos `Api::Entity` objets afin de pouvoir les utiliser avec eux APIs.

**Topics**
+ [Création d'entités](working-with_app-sdk_ent_create.md)
+ [Transférer une entité vers un domaine spatial](working-with_app-sdk_ent_transfer.md)
+ [Écrire et lire les données des champs d'entités](working-with_app-sdk_ent_readwrite.md)
+ [Mémoriser la position d'une entité](working-with_app-sdk_ent_store-position.md)
+ [Charger la position d'une entité](working-with_app-sdk_ent_load-position.md)

# Création d'entités
<a name="working-with_app-sdk_ent_create"></a>

`CreateEntity()`À utiliser pour créer une entité. Vous définissez le sens de ce `Api::TypeId` que vous transmettez à cette fonction.

```
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 )));
}
```

**Note**  
Les valeurs 0 à 511 pour `Api::BuiltinTypeId` sont réservées. Votre entité TypeID (`k_entityTypeId`dans cet exemple) doit avoir une valeur supérieure ou égale à 512.

# Transférer une entité vers un domaine spatial
<a name="working-with_app-sdk_ent_transfer"></a>

Une fois qu'une application ou une application de service personnalisée a créé une entité, l'application doit transférer l'entité vers un domaine spatial pour que l'entité existe spatialement dans la simulation. Les entités d'un domaine spatial peuvent être lues par d'autres applications et mises à jour par une application spatiale. Utilisez l'`ModifyEntityDomain()`API pour transférer une entité vers un domaine spatial.

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

Si le `DomainId` ne correspond pas à celui attribué par `Partition` l'application d'appel, cela `DomainId` doit être pour un `DomainType::Spatial``Domain`. Le transfert de propriété vers le nouveau `Domain` a lieu pendant le`Commit(Transaction&&)`.Paramètres

`txn`  
Le courant`Transaction`.

`entity`  
L'objectif `Entity` du changement de`Domain`.

`domainId`  
Le `DomainId` de la destination `Domain` pour le`Entity`.

Cette API est renvoyée `Success` si le domaine de l'entité a été modifié avec succès.

# Écrire et lire les données des champs d'entités
<a name="working-with_app-sdk_ent_readwrite"></a>

Tous les champs de données d'entité sont de type blob. Vous pouvez écrire jusqu'à 1 024 octets de données dans une entité. Nous vous recommandons de réduire au maximum la taille des blobs, car des tailles plus importantes réduiront les performances. Lorsque vous écrivez dans un blob, vous passez SimSpace Weaver un pointeur sur les données et leur longueur. Lorsque vous lisez à partir d'un blob, il vous SimSpace Weaver fournit un pointeur et une longueur à lire. Toutes les lectures doivent être terminées avant l'appel de l'application`Commit()`. Les pointeurs renvoyés par un appel de lecture sont invalidés lorsque l'application appelle. `Commit()`

**Important**  
La lecture à partir d'un pointeur blob mis en cache après a `Commit()` n'est pas prise en charge et peut entraîner l'échec de la simulation.
L'écriture sur un pointeur blob renvoyé par un appel de lecture n'est pas prise en charge et peut entraîner l'échec de la simulation.

**Topics**
+ [Stocker les données de champ d'une entité](working-with_app-sdk_ent_readwrite_store.md)
+ [Charger les données de champ d'une entité](working-with_app-sdk_ent_readwrite_load.md)
+ [Chargement des données de champ des entités supprimées](working-with_app-sdk_ent_readwrite_load-removed.md)

# Stocker les données de champ d'une entité
<a name="working-with_app-sdk_ent_readwrite_store"></a>

Les exemples suivants montrent comment stocker (écrire dans le State Fabric) les données de champ d'une entité détenue par l'application. Ces exemples utilisent la fonction suivante :

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

Le `Api::TypeId keyTypeId` paramètre représente le type de données des données transmises.

Le `Api::TypeId keyTypeId` paramètre doit recevoir le formulaire correspondant `Api::TypeId``Api::BuiltinTypeId`. S'il n'y a pas de conversion appropriée, vous pouvez utiliser`Api::BuiltinTypeId::Dynamic`.

Pour les types de données complexes, utilisez`Api::BuiltInTypeId::Dynamic`.

**Note**  
La valeur de `FieldIndex index` doit être supérieure à 0. La valeur 0 est réservée à la clé d'index (voir`StoreEntityIndexKey()`).

**Example Exemple d'utilisation de types de données primitifs**  

```
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 Exemple utilisant un struct pour conserver les données**  

```
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));
}
```

# Charger les données de champ d'une entité
<a name="working-with_app-sdk_ent_readwrite_load"></a>

Les exemples suivants montrent comment charger (lire depuis le State Fabric) les données de champ d'une entité. Ces exemples utilisent la fonction suivante :

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

Le `Api::TypeId keyTypeId` paramètre doit recevoir le formulaire correspondant `Api::TypeId``Api::BuiltinTypeId`. S'il n'y a pas de conversion appropriée, vous pouvez utiliser`Api::BuiltinTypeId::Dynamic`.

**Note**  
La valeur de l'`FieldIndex`index doit être supérieure à 0. La valeur 0 est réservée à la clé d'index (voir`StoreEntityIndexKey()`).

**Example Exemple d'utilisation de types de données primitifs**  

```
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 Exemple utilisant un struct pour conserver les données**  

```
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);
}
```

# Chargement des données de champ des entités supprimées
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

Vous ne pouvez pas charger (lire depuis le State Fabric) les données des champs d'entité pour les entités qui ont été supprimées des zones de propriété et d'abonnement de l'application. L'exemple suivant génère une erreur car il appelle `Api::LoadIndexKey()` une entité à la suite d'un`Api::ChangeListAction::Remove`. Le deuxième exemple montre une méthode correcte pour stocker et charger les données d'entité directement dans l'application.

**Example Exemple de code incorrect**  

```
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 Exemple de méthode correcte pour stocker et charger les données d'entité dans l'application**  

```
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;
            }
        }
    }
    
    /* ... */
}
```

# Mémoriser la position d'une entité
<a name="working-with_app-sdk_ent_store-position"></a>

Vous pouvez enregistrer (écrire dans le State Fabric) la position d'une entité à l'aide d'une structure de données entière. Ces exemples utilisent la fonction suivante :

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

**Note**  
Vous devez fournir `Api::BuiltinTypeId::Vector3F32` à`Api::StoreEntityIndexKey()`, comme indiqué dans les exemples suivants.

**Example Exemple d'utilisation d'un tableau pour représenter la position**  

```
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 Exemple utilisant un struct pour représenter la position**  

```
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));
}
```

# Charger la position d'une entité
<a name="working-with_app-sdk_ent_load-position"></a>

Vous pouvez charger (lire à partir de la structure d'état) la position d'une entité à l'aide d'une structure de données entière. Ces exemples utilisent la fonction suivante :

**Note**  
Vous devez fournir `Api::BuiltinTypeId::Vector3F32` à`Api::LoadEntityIndexKey()`, comme indiqué dans les exemples suivants.

**Example Exemple d'utilisation d'un tableau pour représenter la position**  

```
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 Exemple utilisant un struct pour représenter la position**  

```
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);
}
```

# Événements organisés par les entités
<a name="working-with_app-sdk_events"></a>

Vous pouvez utiliser les fonctions suivantes du SDK de l' SimSpace Weaver application pour obtenir tous les événements relatifs à la propriété et à l'abonnement :
+ `Result<OwnershipChangeList> OwnershipChanges(Transaction& txn) `
+ `Result<SubscriptionChangeList> AllSubscriptionEvents(Transaction& txn) `

Vous pouvez utiliser le framework de SimSpace Weaver démonstration si vous avez besoin d'un traitement des événements d'entité piloté par rappel. Pour plus d'informations, consultez le fichier d'en-tête suivant :
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/DemoFramework/EntityEventProcessor.h`

Vous pouvez également créer votre propre traitement des événements d'entité.

**Topics**
+ [Parcourez les événements pour les entités détenues](working-with_app-sdk_events_own.md)
+ [Parcourez les événements pour les entités abonnées](working-with_app-sdk_events_sub.md)
+ [Itérer à travers les événements de changement de propriétaire pour les entités](working-with_app-sdk_events_change.md)

# Parcourez les événements pour les entités détenues
<a name="working-with_app-sdk_events_own"></a>

`OwnershipChanges()`Utilisez-le pour obtenir une liste des événements relatifs aux entités détenues (entités situées dans la zone de propriété de l'application). La fonction possède la signature suivante :

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

Effectuez ensuite une itération sur les entités à l'aide d'une boucle, comme illustré dans l'exemple suivant.

**Example exemple**  

```
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;
    }
}
```

**Types d’événements**
+ `None`— L'entité se trouve dans la zone et ses données de position et de champ n'ont pas été modifiées.
+ `Remove`— L'entité a été supprimée de la zone.
+ `Add`— L'entité a été ajoutée à la zone.
+ `Update`— L'entité se trouve dans la zone et a été modifiée.
+ `Reject`— L'application n'a pas réussi à supprimer l'entité de la zone.

**Note**  
Dans le cas d'un `Reject` événement, l'application tentera à nouveau le transfert à la prochaine case.

# Parcourez les événements pour les entités abonnées
<a name="working-with_app-sdk_events_sub"></a>

Permet `AllSubscriptionEvents()` d'obtenir une liste des événements pour les entités abonnées (entités situées dans la zone d'abonnement de l'application). La fonction possède la signature suivante :

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

Effectuez ensuite une itération sur les entités à l'aide d'une boucle, comme illustré dans l'exemple suivant.

**Example exemple**  

```
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;
    }
}
```

**Types d’événements**
+ `None`— L'entité se trouve dans la zone et ses données de position et de champ n'ont pas été modifiées.
+ `Remove`— L'entité a été supprimée de la zone.
+ `Add`— L'entité a été ajoutée à la zone.
+ `Update`— L'entité se trouve dans la zone et a été modifiée.
+ `Reject`— L'application n'a pas réussi à supprimer l'entité de la zone.

**Note**  
Dans le cas d'un `Reject` événement, l'application tentera à nouveau le transfert à la prochaine case.

# Itérer à travers les événements de changement de propriétaire pour les entités
<a name="working-with_app-sdk_events_change"></a>

Pour obtenir les événements dans lesquels une entité passe d'une zone de propriété à une zone d'abonnement, comparez les modifications entre les événements de propriété et d'abonnement actuels et précédents de l'entité.

Vous pouvez gérer ces événements en lisant :
+ `Api::SubscriptionChangeList`
+ `Api::OwnershipEvents`

Vous pouvez ensuite comparer les modifications aux données enregistrées précédemment.

L'exemple suivant montre comment gérer les événements de changement de propriétaire d'une entité. Cet exemple suppose que pour les entités faisant la transition entre des entités abonnées et des entités détenues (dans les deux sens), l'remove/add event occurs first followed by the subscription remove/addévénement de propriété est coché à la case suivante. 

**Example exemple**  

```
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 et gestion des erreurs
<a name="working-with_app-sdk_result"></a>

La `Aws::WeaverRuntime::Result<T>` classe utilise une `Outcome` bibliothèque tierce. Vous pouvez utiliser le modèle suivant pour vérifier `Result` et détecter les erreurs renvoyées par les appels d'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 macro d'instruction de contrôle
<a name="working-with_app-sdk_result_macro"></a>

Dans une fonction avec un type de retour`Aws::WeaverRuntime::Result<T>`, vous pouvez utiliser la `WEAVERRUNTIME_TRY` macro au lieu du modèle de code précédent. La macro exécutera la fonction qui lui a été transmise. Si la fonction transmise échoue, la macro fera en sorte que la fonction englobante renvoie une erreur. Si la fonction transmise réussit, l'exécution passe à la ligne suivante. L'exemple suivant montre une réécriture de la `DoBeginUpdate()` fonction précédente. Cette version utilise la `WEAVERRUNTIME_TRY` macro au lieu du if-else structure de commande. Notez que le type de retour de la fonction est`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();
}
```

En cas d'`BeginUpdate()`échec, la macro `DoBeginUpdate()` revient plus tôt en cas d'échec. Vous pouvez utiliser la `WEAVERRUNTIME_EXPECT_ERROR` macro pour `Aws::WeaverRuntime::ErrorCode` obtenir `BeginUpdate()` le L'exemple suivant montre comment la `Update()` fonction appelle `DoBeginUpdate()` et obtient le code d'erreur en cas d'échec.

```
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);

    }
}
```

Vous pouvez rendre le code d'erreur `BeginUpdate()` accessible à une fonction qui appelle `Update()` en modifiant le type de retour `Update()` en`Aws::WeaverRuntime::Result<void>`. Vous pouvez répéter ce processus pour continuer à envoyer le code d'erreur plus bas dans la pile d'appels.

# Génériques et types de domaines
<a name="working-with_app-sdk_generics"></a>

Le SDK de SimSpace Weaver l'application fournit les types de données à simple précision `Api::Vector2F32` et`Api::BoundingBox2F32`, ainsi que les types de données à double `Api::Vector2F64` précision et. `Api::BoundingBox2F64` Ces types de données sont des structures de données passives dépourvues de méthodes pratiques. Notez que l'API utilise uniquement `Api::Vector2F32` et`Api::BoundingBox2F32`. Vous pouvez utiliser ces types de données pour créer et modifier des abonnements.

Le framework de SimSpace Weaver démonstration fournit une version minimale du AzCore bibliothèque mathématique, qui contient `Vector3` et`Aabb`. Pour plus d'informations, consultez les fichiers d'en-tête dans :
+ `sdk-folder/packaging-tools/samples/ext/DemoFramework/include/AzCore/Math`

# Opérations diverses du SDK de l'application
<a name="working-with_app-sdk_misc"></a>

**Topics**
+ [AllSubscriptionEvents and OwnershipChanges contenir les événements du dernier appel](working-with_app-sdk_misc_events-from-last-call.md)
+ [Relâchez les verrous de lecture après le traitement SubscriptionChangeList](working-with_app-sdk_misc_release-locks.md)
+ [Création d'une instance d'application autonome à des fins de test](working-with_app-sdk_misc_testing-app.md)

# AllSubscriptionEvents and OwnershipChanges contenir les événements du dernier appel
<a name="working-with_app-sdk_misc_events-from-last-call"></a>

Les valeurs renvoyées par les appels vers `Api::AllSubscriptionEvents()` et `Api::OwnershipChanges()` contenant des événements survenus lors du dernier appel, et **non de la dernière coche**. Dans l'exemple suivant, `secondSubscriptionEvents` et `secondOwnershipChangeList` sont vides car leurs fonctions sont appelées immédiatement après les premiers appels.

Si vous attendez 10 ticks puis que vous appelez `Api::AllSubscriptionEvents()` et`Api::OwnershipChanges()`, leurs résultats contiendront à la fois les événements et les changements survenus lors des 10 derniers ticks (et non le dernier).

**Example exemple**  

```
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.
     */
}
```

**Note**  
La fonction `AllSubscriptionEvents()` est implémentée, mais elle ne l'`SubscriptionEvents()`est **pas**.

# Relâchez les verrous de lecture après le traitement SubscriptionChangeList
<a name="working-with_app-sdk_misc_release-locks"></a>

Lorsque vous commencez une mise à jour, des segments de mémoire partagée contiennent des segments de mémoire partagée pour les données validées dans d'autres partitions lors de la vérification précédente. Ces segments de mémoire partagée peuvent être verrouillés par les lecteurs. Une application ne peut pas être entièrement validée tant que tous les lecteurs n'ont pas relâché les verrous. À titre d'optimisation, une application doit appeler `Api::ReleaseReadLeases()` pour libérer les verrous après le traitement des `Api::SubscriptionChangelist` éléments. Cela réduit le contentieux au moment de la validation. `Api::Commit()`publie les baux de lecture par défaut, mais il est recommandé de les publier manuellement après le traitement des mises à jour des abonnements.

**Example exemple**  

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

# Création d'une instance d'application autonome à des fins de test
<a name="working-with_app-sdk_misc_testing-app"></a>

Vous pouvez l'utiliser `Api::CreateStandaloneApplication()` pour créer une application autonome afin de tester la logique de l'application avant d'exécuter le code dans une simulation réelle.

**Example exemple**  

```
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 framework de démonstration
<a name="working-with_demo-framework"></a>

Le framework de AWS SimSpace Weaver démonstration (framework de démonstration) est une bibliothèque d'utilitaires que vous pouvez utiliser pour développer des SimSpace Weaver applications.

**Le framework de démonstration fournit**
+ Exemples de code et modèles de programmation que vous pouvez utiliser et examiner
+ Abstractions et fonctions utilitaires qui rationalisent le développement d'applications simples
+ Un moyen plus simple de tester les fonctionnalités expérimentales du SDK de l' SimSpace Weaver application

Nous avons conçu le SDK de SimSpace Weaver l'application avec un accès de bas niveau SimSpace Weaver APIs afin d'offrir de meilleures performances. En revanche, nous avons conçu le framework de démonstration pour fournir des abstractions de haut niveau et un accès à celles-ci pour en APIs SimSpace Weaver faciliter l'utilisation. Le coût de la facilité d'utilisation est un niveau de performance inférieur à celui de l'utilisation directe du SDK de l' SimSpace Weaver application. Les simulations qui peuvent tolérer des performances inférieures (telles que celles qui ne sont pas soumises à des exigences de performance en temps réel) peuvent être de bonnes candidates pour utiliser le framework de démonstration. Nous vous recommandons d'utiliser les fonctionnalités natives du SDK de l' SimSpace Weaver application pour les applications complexes, car le framework de démonstration n'est pas une boîte à outils complète.

**Le framework de démonstration inclut**
+ Exemples de code de travail qui prennent en charge et démontrent :
  + Gestion du flux d'applications
  + Traitement des événements d'entité piloté par le rappel
+ Un ensemble de bibliothèques d'utilitaires tierces :
  + spdlog (une bibliothèque de journalisation)
  + Une version minimale de AZCore (une bibliothèque mathématique) qui contient uniquement :
    + Vector3
    + Aabb
  + cxxopts (une bibliothèque d'analyseurs d'options en ligne de commande)
+ Fonctions utilitaires spécifiques à SimSpace Weaver

Le framework de démonstration se compose d'une bibliothèque, de fichiers sources et CMakeLists. Les fichiers sont inclus dans le package distribuable du SDK de SimSpace Weaver l'application.

# Utilisation des quotas de service
<a name="working-with_quotas"></a>

Cette section décrit comment utiliser les quotas de service pour SimSpace Weaver. Les **quotas** sont également appelés **limites**. Pour obtenir la liste des quotas de service, consultez[SimSpace Points de terminaison et quotas Weaver](service-quotas.md). Les APIs éléments de cette section proviennent de l'ensemble de **l'application APIs**. APIsLes applications sont différentes du service APIs. L'application APIs fait partie du SDK de l' SimSpace Weaver application. Vous trouverez la documentation de l'application APIs dans le dossier du SDK de l'application sur votre système local :

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

**Topics**
+ [Déterminer les limites d'une application](#working-with_quotas_get-app-limits)
+ [Obtenez la quantité de ressources utilisées par une application](#working-with_quotas_get-app-resources)
+ [Réinitialiser les métriques](#working-with_quotas_reset-metrics)
+ [Dépassement d'une limite](#working-with_quotas_exceed-limit)
+ [À court de mémoire](#working-with_quotas_out-of-memory)
+ [Bonnes pratiques](#working-with_quotas_best-practices)

## Déterminer les limites d'une application
<a name="working-with_quotas_get-app-limits"></a>

Vous pouvez utiliser l'API de **RuntimeLimits** l'application pour demander les limites d'une application.

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

**Applicationet application**  
Une référence à l'application.

**LimitType type**  
Une énumération avec les types de limites suivants :  

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

L'exemple suivant interroge la limite du nombre d'entités.

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

## Obtenez la quantité de ressources utilisées par une application
<a name="working-with_quotas_get-app-resources"></a>

Vous pouvez appeler l'API de **RuntimeMetrics** l'application pour connaître la quantité de ressources utilisées par une application :

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

**Applicationet application**  
Une référence à l'application.

L'API renvoie une référence à un struct qui contient les métriques. Une contre-métrique contient une valeur totale cumulée et ne fait qu'augmenter. Une métrique de jauge contient une valeur qui peut augmenter ou diminuer. Le moteur d'exécution de l'application met à jour un compteur chaque fois qu'un événement augmente la valeur. Le moteur d'exécution met à jour les jauges uniquement lorsque vous appelez l'API. SimSpace Weaver garantit que la référence est valide pendant toute la durée de vie de l'application. Les appels répétés à l'API ne modifieront pas la référence.

```
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
}
```

## Réinitialiser les métriques
<a name="working-with_quotas_reset-metrics"></a>

L'API de l'**ResetRuntimeMetrics**application réinitialise les valeurs du `AppRuntimeMetrics`struct.

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

L'exemple suivant montre comment vous pouvez appeler **ResetRuntimeMetrics** votre application.

```
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));
}
```

## Dépassement d'une limite
<a name="working-with_quotas_exceed-limit"></a>

Un appel d'API d'application qui dépasse une limite renverra un`ErrorCode::CapacityExceeded`, sauf pour les transferts d'entités. SimSpace Weaver gère les transferts d'entités de manière asynchrone dans le cadre des opérations de **validation** et d'API d'**BeginUpdate**application. Aucune opération spécifique ne renvoie donc d'erreur si un transfert échoue en raison de la limite de transfert d'entités. Pour détecter les échecs de transfert, vous pouvez comparer les valeurs actuelles de `rejected_incoming_transfer_counter` et `rejected_outgoing_transfer_counter` (dans le `AppRuntimeMetrics`struct) avec leurs valeurs précédentes. Les entités rejetées ne figureront pas dans la partition, mais l'application peut toujours les simuler.

## À court de mémoire
<a name="working-with_quotas_out-of-memory"></a>

SimSpace Weaver utilise un processus de collecte des déchets pour nettoyer et libérer la mémoire libérée. Il est possible d'écrire des données plus rapidement que le ramasse-miettes ne peut libérer de la mémoire. Dans ce cas, les opérations d'écriture risquent de dépasser la limite de mémoire réservée de l'application. SimSpace Weaver renverra une erreur interne avec un message contenant `OutOfMemory` (et des détails supplémentaires). Pour de plus amples informations, veuillez consulter [Répartissez les écritures dans le temps](#working-with_quotas_best-practices_spread-writes).

## Bonnes pratiques
<a name="working-with_quotas_best-practices"></a>

Les bonnes pratiques suivantes sont des directives générales pour concevoir vos applications afin d'éviter de dépasser les limites. Ils peuvent ne pas s'appliquer à la conception spécifique de votre application.

### Surveillez fréquemment et ralentissez
<a name="working-with_quotas_best-practices_monitor"></a>

Vous devez surveiller fréquemment vos indicateurs et ralentir les opérations qui approchent d'une limite.

### Évitez de dépasser les limites d'abonnement et les limites de transfert
<a name="working-with_quotas_best-practices_subscription-and-xfer"></a>

Si possible, concevez votre simulation de manière à réduire le nombre d'abonnements à distance et de transferts d'entités. Vous pouvez utiliser des groupes de placement pour placer plusieurs partitions sur le même travailleur et réduire le besoin de transferts d'entités à distance entre les travailleurs. 

### Répartissez les écritures dans le temps
<a name="working-with_quotas_best-practices_spread-writes"></a>

Le nombre et la taille des mises à jour contenues dans un tick peuvent avoir un impact significatif sur le temps et la mémoire nécessaires pour valider une transaction. Des besoins de mémoire importants peuvent entraîner une pénurie de mémoire lors de l'exécution de l'application. Vous pouvez répartir les écritures dans le temps afin de réduire la taille totale moyenne des mises à jour par tick. Cela peut contribuer à améliorer les performances et à éviter de dépasser les limites. Nous vous recommandons de ne pas écrire plus de 12 Mo en moyenne sur chaque case ou 1,5 Ko pour chaque entité. 

# Simulations de débogage
<a name="working-with_debugging"></a>

Vous pouvez utiliser les méthodes suivantes pour obtenir des informations sur vos simulations.

**Rubriques**
+ [Utiliser SimSpace Weaver Local et regardez la sortie de la console](#working-with_debugging_use-local)
+ [Consultez vos journaux dans Amazon CloudWatch Logs](#working-with_debugging_logs)
+ [Utiliser **describe** Appels d’API](#working-with_debugging_api)
+ [Connect un client](#working-with_debugging_client)

## Utiliser SimSpace Weaver Local et regardez la sortie de la console
<a name="working-with_debugging_use-local"></a>

Nous vous recommandons de développer d'abord vos simulations localement, puis de les exécuter dans le AWS Cloud. Vous pouvez afficher la sortie de la console directement lorsque vous exécutez avec SimSpace Weaver Local. Pour plus d'informations, consultez[Développement local en SimSpace Weaver](working-with_local-development.md).

## Consultez vos journaux dans Amazon CloudWatch Logs
<a name="working-with_debugging_logs"></a>

Lorsque vous exécutez votre simulation dans la console, AWS Cloud la sortie de vos applications est envoyée aux flux de CloudWatch journaux dans Amazon Logs. Votre simulation écrit également d'autres données de journal. Vous devez activer la journalisation dans votre schéma de simulation si vous souhaitez que votre simulation écrive des données de journal. Pour de plus amples informations, veuillez consulter [SimSpace Weaver journaux dans Amazon CloudWatch Logs](cloudwatch-logs.md).

**Avertissement**  
Votre simulation peut produire de grandes quantités de données de log. Les données du journal peuvent augmenter très rapidement. Vous devez surveiller attentivement vos journaux et arrêter vos simulations lorsque vous n'en avez plus besoin. L'exploitation forestière peut entraîner des coûts importants.

## Utiliser **describe** Appels d’API
<a name="working-with_debugging_api"></a>

Vous pouvez utiliser le service suivant APIs pour obtenir des informations sur vos simulations dans le AWS Cloud.
+ **ListSimulations**— obtenez une liste de toutes vos simulations dans le AWS Cloud.  
**Example exemple**  

  ```
  aws simspaceweaver list-simulations
  ```
+ **DescribeSimulation**— obtenir des informations sur une simulation.  
**Example exemple**  

  ```
  aws simspaceweaver describe-simulation --simulation MySimulation
  ```
+ **DescribeApp**— obtenir des informations sur une application.  
**Example exemple**  

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

Pour plus d'informations sur le SimSpace Weaver APIs, consultez[SimSpace Weaver Références d'API](api-reference.md).

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

Vous pouvez connecter un client à une application personnalisée ou de service en cours d'exécution que vous avez définie `endpoint_config` dans votre schéma de simulation. Le SDK de SimSpace Weaver l'application inclut des exemples de clients que vous pouvez utiliser pour visualiser l'exemple d'application. Vous pouvez consulter le code source de ces exemples de clients et de l'exemple d'application pour voir comment créer vos propres clients. Pour plus d'informations sur la création et l'exécution des exemples de clients, consultez les didacticiels dans[Commencer avec SimSpace Weaver](getting-started.md).

Le code source des exemples de clients se trouve dans le dossier suivant :
+ `sdk-folder\packaging-tools\clients\PathfindingSampleClients\`

# Débogage de simulations locales
<a name="working-with_debugging_local"></a>

Vous pouvez déboguer vos SimSpace Weaver Local applications avecMicrosoft Visual Studio. [Pour plus d'informations sur la procédure de débogage avecVisual Studio, consultez leMicrosoft Visual Studio documentation.](https://learn.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour) 

**Pour déboguer votre simulation locale**

1. Assurez-vous que vous vous `schema.yaml` trouvez dans votre répertoire de travail.

1. Dans **Visual Studio**, ouvrez le menu contextuel de chaque application que vous souhaitez déboguer (par exemple `PathfindingSampleLocalSpatial` ou`PathfindingSampleLocalView`) et définissez le répertoire de travail dans la section de débogage.

1. Ouvrez le menu contextuel de l'application que vous souhaitez déboguer et sélectionnez **Définir comme projet de démarrage**.

1. Choisissez F5 de démarrer le débogage de l'application.

Les conditions requises pour débugger une simulation sont les mêmes que celles requises pour exécuter une simulation normalement. Vous devez démarrer le nombre d'applications spatiales spécifié dans le schéma. Par exemple, si votre schéma spécifie une grille 2x2 et que vous lancez une application spatiale en mode débogage, la simulation ne s'exécutera pas tant que vous n'aurez pas démarré 3 autres applications spatiales (en mode débogage ou non en mode débogage).

Pour déboguer une application personnalisée, vous devez d'abord démarrer vos applications spatiales, puis démarrer l'application personnalisée dans le débogueur.

Notez que votre simulation s'exécute en mode « lock step ». Dès qu'une application atteint un point d'arrêt, toutes les autres applications s'interrompent. Une fois que vous aurez continué à partir de ce point d'arrêt, les autres applications continueront.

# Conteneurs personnalisés
<a name="working-with_custom-containers"></a>

AWS SimSpace Weaver les applications s'exécutent dans des environnements conteneurisés Amazon Linux 2 (AL2). Dans le AWS Cloud, SimSpace Weaver exécute vos simulations dans des conteneurs Docker créés à partir d'une `amazonlinux:2` image fournie par Amazon Elastic Container Registry (Amazon ECR). Vous pouvez créer une image Docker personnalisée, la stocker dans Amazon ECR et utiliser cette image pour votre simulation au lieu de l'image Docker par défaut que nous fournissons.

Vous pouvez utiliser un conteneur personnalisé pour gérer vos dépendances logicielles et inclure des composants logiciels supplémentaires qui ne figurent pas dans l'image Docker standard. Par exemple, vous pouvez ajouter au conteneur les bibliothèques logicielles accessibles au public utilisées par votre application et ne placer votre code personnalisé que dans le fichier zip de l'application.

**Important**  
Nous prenons uniquement en charge les images AL2 Docker hébergées dans les référentiels Amazon ECR, que ce soit dans la galerie publique Amazon ECR ou dans votre registre Amazon ECR privé. Nous ne prenons pas en charge les images Docker hébergées en dehors d'Amazon ECR. Pour plus d'informations sur Amazon ECR, consultez la *[documentation Amazon Elastic Container Registry](https://docs.aws.amazon.com/ecr)*.

**Topics**
+ [Création d'un conteneur personnalisé](working-with_custom-containers_create.md)
+ [Modifier un projet pour utiliser un conteneur personnalisé](working-with_custom-containers_modify-project.md)
+ [Questions fréquemment posées sur les conteneurs personnalisés](working-with_custom-containers_faq.md)
+ [Résolution des problèmes liés aux conteneurs personnalisés](working-with_custom-containers_troubleshooting.md)

# Création d'un conteneur personnalisé
<a name="working-with_custom-containers_create"></a>

Ces instructions supposent que vous savez comment utiliser Docker et Amazon Elastic Container Registry (Amazon ECR). Pour plus d'informations sur la sécurité dans Amazon ECR, veuillez consulter le *[Guide de l'utilisateur Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide)*.

**Conditions préalables**
+ L'identité IAM (utilisation ou rôle) que vous utilisez pour effectuer ces actions dispose des autorisations appropriées pour utiliser Amazon ECR
+ Docker est installé sur votre système local

**Pour créer un conteneur personnalisé**

1. Créez votre `Dockerfile`.

   `Dockerfile`Pour exécuter des AWS SimSpace Weaver applications, commencez par l'Amazon Linux 2image dans Amazon ECR.

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

1. Construisez votre`Dockerfile`.

1. Téléchargez l'image de votre conteneur sur Amazon ECR.
   + [Utilisez le AWS Management Console.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html)
   + [Utilisez le AWS Command Line Interface.](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)
**Note**  
Si un `AccessDeniedException` message d'erreur s'affiche lorsque vous essayez de télécharger votre image de conteneur sur Amazon ECR, il est possible que votre identité IAM (utilisateur ou rôle) ne dispose pas des autorisations nécessaires pour utiliser Amazon ECR. Vous pouvez associer la politique `AmazonEC2ContainerRegistryPowerUser` AWS gérée à votre identité IAM et réessayer. Pour plus d'informations sur la façon d'associer une politique, consultez la section [Ajout et suppression d'autorisations d'identité IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) dans le *Guide de l'Gestion des identités et des accès AWS utilisateur*.

# Modifier un projet pour utiliser un conteneur personnalisé
<a name="working-with_custom-containers_modify-project"></a>

Ces instructions supposent que vous savez déjà comment utiliser vos processus de stockage AWS SimSpace Weaver et de développement d'applications et que vous souhaitez les rendre AWS Cloud plus efficaces.

**Conditions préalables**
+ Vous avez un conteneur personnalisé dans Amazon Elastic Container Registry (Amazon ECR). Pour plus d'informations sur la création d'un conteneur personnalisé, consultez[Création d'un conteneur personnalisé](working-with_custom-containers_create.md).

**Pour modifier votre projet afin d'utiliser un conteneur personnalisé**

1. Ajoutez des autorisations au rôle d'application de simulation de votre projet pour utiliser Amazon ECR.

   1. Si vous ne disposez pas encore d'une stratégie IAM avec les autorisations suivantes, créez-la. Nous suggérons le nom de la politique`simspaceweaver-ecr`. Pour plus d'informations sur la création d'une stratégie IAM, consultez la section [Création de politiques IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) dans le Guide de l'*Gestion des identités et des accès AWS utilisateur*.

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

   1. Trouvez le nom du rôle de l'application de simulation de votre projet :

      1. Dans un éditeur de texte, ouvrez le CloudFormation modèle :

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

      1. Trouvez la `RoleName` propriété ci-dessous`WeaverAppRole`. La valeur est le nom du rôle de l'application de simulation de votre projet.  
**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. Associez la `simspaceweaver-ecr` politique au rôle d'application de simulation du projet. Pour plus d'informations sur la façon d'associer une politique, consultez la section [Ajout et suppression d'autorisations d'identité IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) dans le *Guide de l'Gestion des identités et des accès AWS utilisateur*. 

   1. Accédez à la pile d'échantillons `sdk-folder` et exécutez-la pour mettre à jour la SimSpace Weaver pile d'échantillons :

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

1. Spécifiez les images de vos conteneurs dans le schéma de simulation du projet.
   + Vous pouvez ajouter la `default_image` propriété facultative ci-dessous `simulation_properties` pour spécifier une image de conteneur personnalisée par défaut pour tous les domaines.
   + Ajoutez la `image` propriété dans le `app_config` pour le domaine dans lequel vous souhaitez utiliser une image de conteneur personnalisée. Spécifiez l'URI du référentiel Amazon ECR comme valeur. Vous pouvez spécifier une image différente pour chaque domaine.
     + Si `image` ce n'est pas spécifié pour un domaine mais si `default_image` c'est le cas, les applications de ce domaine utilisent l'image par défaut.
     + Si `image` ce n'est pas spécifié pour un domaine et `default_image` ne l'est pas, les applications de ce domaine s'exécutent dans un SimSpace Weaver conteneur standard.  
**Example Extrait de schéma incluant des paramètres de conteneur personnalisés**  

   ```
   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. Créez et téléchargez votre projet comme d'habitude.

# Questions fréquemment posées sur les conteneurs personnalisés
<a name="working-with_custom-containers_faq"></a>

## Q1. Que dois-je faire si je souhaite modifier le contenu de mon contenant ?
<a name="working-with_custom-containers_faq_q1"></a>
+ **Pour une simulation en cours d'exécution** : vous ne pouvez pas modifier le conteneur d'une simulation en cours d'exécution. Vous devez créer un nouveau conteneur et démarrer une nouvelle simulation utilisant ce conteneur.
+ **Pour une nouvelle simulation** : créez un nouveau conteneur, chargez-le sur Amazon Elastic Container Registry (Amazon ECR) et lancez une nouvelle simulation utilisant ce conteneur.

## Q2. Comment puis-je modifier l'image du conteneur pour ma simulation ?
<a name="working-with_custom-containers_faq_q2"></a>
+ **Pour une simulation en cours d'exécution** : vous ne pouvez pas modifier le conteneur d'une simulation en cours d'exécution. Vous devez démarrer une nouvelle simulation utilisant le nouveau conteneur.
+ **Pour une nouvelle simulation** : spécifiez la nouvelle image du conteneur dans le schéma de simulation de votre projet. Pour de plus amples informations, veuillez consulter [Modifier un projet pour utiliser un conteneur personnalisé](working-with_custom-containers_modify-project.md).

# Résolution des problèmes liés aux conteneurs personnalisés
<a name="working-with_custom-containers_troubleshooting"></a>

**Topics**
+ [AccessDeniedException lors du chargement de votre image sur Amazon Elastic Container Registry (Amazon ECR)](working-with_custom-containers_troubleshooting_access-denied.md)
+ [Une simulation utilisant un conteneur personnalisé ne démarre pas](working-with_custom-containers_troubleshooting_no-start.md)

# AccessDeniedException lors du chargement de votre image sur Amazon Elastic Container Registry (Amazon ECR)
<a name="working-with_custom-containers_troubleshooting_access-denied"></a>

Si un `AccessDeniedException` message d'erreur s'affiche lorsque vous essayez de télécharger votre image de conteneur sur Amazon ECR, il est possible que votre identité IAM (utilisateur ou rôle) ne dispose pas des autorisations nécessaires pour utiliser Amazon ECR. Vous pouvez associer la politique `AmazonEC2ContainerRegistryPowerUser` AWS gérée à votre identité IAM et réessayer. Pour plus d'informations sur la façon d'associer une politique, consultez la section [Ajout et suppression d'autorisations d'identité IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) dans le *Guide de l'Gestion des identités et des accès AWS utilisateur*.

# Une simulation utilisant un conteneur personnalisé ne démarre pas
<a name="working-with_custom-containers_troubleshooting_no-start"></a>

**Conseils pour le dépannage**
+ Si la journalisation est activée pour votre simulation, consultez vos journaux d'erreurs.
+ Testez votre simulation sans conteneur personnalisé.
+ Testez votre simulation localement. Pour de plus amples informations, veuillez consulter [Développement local en SimSpace Weaver](working-with_local-development.md).

# Travail avec Python
<a name="working-with_python"></a>

Vous pouvez utiliser Python pour vos SimSpace Weaver applications et vos clients. Le kit de développement logiciel Python (SDK Python) est inclus dans le package distribuable standard du SDK d' SimSpace Weaver applications. Le développement avec Python fonctionne de la même manière que le développement dans les autres langages pris en charge.

**Important**  
SimSpace Weaver ne supporte que la version 3.9 de Python.

**Important**  
SimSpace Weaver le support de Python nécessite SimSpace Weaver la version 1.15.0 ou ultérieure.

**Topics**
+ [Création d'un projet Python](working-with_python_create-project.md)
+ [Démarrage d'une simulation Python](working-with_python_start-sim.md)
+ [Exemple de client Python](working-with_python_client.md)
+ [Questions fréquemment posées sur l'utilisation de Python](working-with_python_faq.md)
+ [Résolution des problèmes liés à Python](working-with_python_troubleshooting.md)

# Création d'un projet Python
<a name="working-with_python_create-project"></a>

## Conteneur personnalisé en Python
<a name="working-with_python_create-project_container"></a>

Pour exécuter votre SimSpace Weaver simulation basée sur Python dans le AWS Cloud, vous pouvez créer un conteneur personnalisé qui inclut les dépendances nécessaires. Pour de plus amples informations, veuillez consulter [Conteneurs personnalisés](working-with_custom-containers.md). 

Un conteneur personnalisé Python doit inclure les éléments suivants :
+ gcc
+ openssl-devel
+ bzip2-devel
+ libffi-devel
+ wget
+ tar
+ gzip
+ make
+ Python (version 3.9)

Si vous utilisez le `PythonBubblesSample` modèle pour créer votre projet, vous pouvez exécuter le `quick-start.py` script (situé dans le `tools` dossier de votre projet) pour créer une image Docker avec les dépendances nécessaires. Le script télécharge l'image sur Amazon Elastic Container Registry (Amazon ECR).

Le `quick-start.py` script utilise les éléments suivants `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
```

Vous pouvez ajouter vos propres dépendances aux éléments suivants `Dockerfile` :

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

Le `requirements.txt` fichier contient la liste des packages Python requis pour l'`PythonBubblesSample`exemple de simulation :

```
Flask==2.1.1
```

Vous pouvez ajouter vos propres dépendances de package Python aux éléments suivants `requirements.txt` :

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

Les `Dockerfile` et `requirements.txt` se trouvent dans le `tools` dossier de votre projet.

**Important**  
Techniquement, vous n'êtes pas obligé d'utiliser un conteneur personnalisé avec votre simulation Python, mais nous vous recommandons vivement d'utiliser un conteneur personnalisé. Le conteneur Amazon Linux 2 (AL2) standard que nous fournissons ne contient pas Python. Par conséquent, si vous n'utilisez pas de conteneur personnalisé contenant Python, vous devez inclure Python et les dépendances requises dans chaque fichier zip d'application vers lequel vous le téléchargez SimSpace Weaver. 

# Démarrage d'une simulation Python
<a name="working-with_python_start-sim"></a>

Vous pouvez démarrer votre simulation basée sur Python de la même manière qu'une SimSpace Weaver simulation classique, à la fois dans SimSpace Weaver Local et SimSpace Weaver dans le AWS Cloud. Pour plus d'informations, consultez les didacticiels dans[Commencer avec SimSpace Weaver](getting-started.md).

`PythonBubblesSample`Il inclut son propre exemple de client Python. Pour de plus amples informations, veuillez consulter [Exemple de client Python](working-with_python_client.md). 

# Exemple de client Python
<a name="working-with_python_client"></a>

Si vous utilisez le `PythonBubblesSample` modèle pour créer un projet, celui-ci contient un exemple de client Python. Vous pouvez utiliser l'exemple de client pour visualiser la `PythonBubblesSample` simulation. Vous pouvez également utiliser l'exemple de client comme point de départ pour créer votre propre client Python.

La procédure suivante part du principe que vous avez créé un `PythonBubblesSample` projet et lancé sa simulation.

**Pour démarrer le client Python**

1. Dans une **fenêtre d'invite de commande**, accédez au dossier `PyBubbleClient` d'exemple de projet.

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

1. Exécutez le client Python.

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

**Paramètres**  
**host**  
L'adresse IP de votre simulation. Pour une simulation démarrée dans le AWS Cloud, vous pouvez trouver l'adresse IP de votre simulation dans la [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver) ou utiliser la procédure décrite dans le didacticiel [Obtenez l'adresse IP et le numéro de port d'une application personnaliséeObtenez l'adresse IP et le numéro de port](working-with_get-ip.md) de démarrage rapide. Pour une simulation locale, `127.0.0.1` utilisez-le comme adresse IP.  
**port**  
Le numéro de port de votre simulation. Pour une simulation démarrée dans le AWS Cloud, il s'agit du numéro de `Actual` port. Vous pouvez trouver le numéro de port de votre simulation dans la [SimSpace Weaver console](https://console.aws.amazon.com/simspaceweaver) ou utiliser la procédure décrite dans le didacticiel [Obtenez l'adresse IP et le numéro de port d'une application personnaliséeObtenez l'adresse IP et le numéro de port](working-with_get-ip.md) de démarrage rapide. Pour une simulation locale, utilisez-le `7000` comme numéro de port.  
**simsize**  
Le nombre maximum d'entités à afficher dans le client.

# Questions fréquemment posées sur l'utilisation de Python
<a name="working-with_python_faq"></a>

## Q1. Quelles sont les versions de Python prises en charge ?
<a name="working-with_python_faq_q1"></a>

SimSpace Weaver ne supporte que la version 3.9 de Python.

# Résolution des problèmes liés à Python
<a name="working-with_python_troubleshooting"></a>

**Topics**
+ [Échec lors de la création d'un conteneur personnalisé](working-with_python_troubleshooting_create-container-failure.md)
+ [Votre simulation Python ne démarre pas](working-with_python_troubleshooting_no-start.md)
+ [Un client de visualisation ou de simulation Python génère une ModuleNotFound erreur](working-with_python_troubleshooting_module-not-found.md)

# Échec lors de la création d'un conteneur personnalisé
<a name="working-with_python_troubleshooting_create-container-failure"></a>

Si un message d'erreur s'affiche `no basic auth credentials` après l'exécution`quick-start.py`, il se peut qu'il y ait un problème avec vos informations d'identification temporaires pour Amazon ECR. Exécutez la commande suivante avec votre Région AWS identifiant et votre numéro de AWS compte :

```
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
```

**Important**  
Assurez-vous que celui que Région AWS vous spécifiez est le même que celui que vous utilisez pour votre simulation. Utilisez l'un Régions AWS des SimSpace Weaver supports. Pour de plus amples informations, veuillez consulter [SimSpace Points de terminaison et quotas Weaver](service-quotas.md).

Après avoir exécuté la `aws ecr` commande, exécutez-la `quick-start.py` à nouveau.

**Autres ressources de résolution des problèmes à vérifier**
+ [Résolution des problèmes liés aux conteneurs personnalisés](working-with_custom-containers_troubleshooting.md)
+ [Résolution des problèmes liés à Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/troubleshooting.html) dans le guide de l'*utilisateur Amazon ECR*
+ [Configuration avec Amazon ECR dans le guide](https://docs.aws.amazon.com/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html) de l'*utilisateur Amazon ECR*

# Votre simulation Python ne démarre pas
<a name="working-with_python_troubleshooting_no-start"></a>

Il se peut qu'une `Unable to start app` erreur apparaisse dans le journal de gestion de votre simulation. Cela peut se produire si la création de votre conteneur personnalisé a échoué. Pour de plus amples informations, veuillez consulter [Échec lors de la création d'un conteneur personnalisé](working-with_python_troubleshooting_create-container-failure.md). Pour de plus amples informations sur les journaux, veuillez consulter [SimSpace Weaver journaux dans Amazon CloudWatch Logs](cloudwatch-logs.md).

Si vous êtes certain qu'il n'y a aucun problème avec votre conteneur, vérifiez le code source Python de votre application. Vous pouvez utiliser … SimSpace Weaver Local pour tester votre application. Pour de plus amples informations, veuillez consulter [Développement local en SimSpace Weaver](working-with_local-development.md).

# Un client de visualisation ou de simulation Python génère une ModuleNotFound erreur
<a name="working-with_python_troubleshooting_module-not-found"></a>

Python génère une `ModuleNotFound` erreur lorsqu'il ne parvient pas à localiser le package Python requis.

Si votre simulation se trouve dans le AWS Cloud, assurez-vous que votre conteneur personnalisé possède toutes les dépendances requises répertoriées dans votre`requirements.txt`. N'oubliez pas de l'exécuter `quick-start.py` à nouveau si vous modifiez`requirements.txt`.

Si le message d'erreur s'affiche pour le `PythonBubblesSample` client, utilisez `pip` pour installer le package indiqué :

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

# Support pour d'autres moteurs
<a name="working-with_engines"></a>

Vous pouvez utiliser votre propre coutume C\$1\$1 moteur avec SimSpace Weaver. Nous développons actuellement le support pour les moteurs suivants. Il existe une documentation distincte pour chacun de ces moteurs.

**Important**  
Les intégrations avec les moteurs listés ici sont expérimentales. Ils sont disponibles en avant-première.

**Moteurs**
+ [Unity](#working-with_engines_unity)(version minimale 2022.3.19.F1)
+ [Unreal Engine](#working-with_engines_unreal)(version minimale 5.0)

## Unity
<a name="working-with_engines_unity"></a>

Vous devez avoir le Unity environnement de développement déjà installé avant de créer SimSpace Weaver des simulations avec Unity. Pour plus d'informations, consultez les instructions séparées :

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

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

Vous devez construire un Unreal Engine serveur dédié à partir du code source. SimSpaceWeaverAppSdkDistributable Il inclut une version du PathfindingSample pour Unreal Engine. Pour plus d'informations, consultez les instructions séparées : 

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

# Utilisation de logiciels sous licence avec AWS SimSpace Weaver
<a name="working-with_byol"></a>

AWS SimSpace Weaver vous permet de créer des simulations avec le moteur de simulation et le contenu de votre choix. Dans le cadre de votre utilisation de SimSpace Weaver, vous êtes responsable de l'obtention, de la maintenance et du respect des termes de licence de tout logiciel ou contenu que vous utilisez dans vos simulations. Vérifiez que votre contrat de licence vous permet de déployer votre logiciel et votre contenu dans un environnement hébergé virtuel.

# Gérez vos ressources avec AWS CloudFormation
<a name="working-with_cloudformation"></a>

Vous pouvez l'utiliser AWS CloudFormation pour gérer vos AWS SimSpace Weaver ressources. CloudFormation est un AWS service distinct qui vous aide à spécifier, à approvisionner et à gérer votre AWS infrastructure sous forme de code. Avec CloudFormation vous, créez un fichier JSON ou YAML, appelé *[modèle](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-templates template)*. Votre modèle précise les détails de votre infrastructure. CloudFormation utilise votre modèle pour provisionner votre infrastructure sous la forme d'une unité unique, appelée *[pile](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#w2ab1b5c15b9)*. Lorsque vous supprimez votre pile, vous pouvez avoir à CloudFormation supprimer tous les éléments de la pile en même temps. Vous pouvez gérer votre modèle à l'aide de processus de gestion de code source standard (par exemple, en le suivant dans un système de contrôle de version tel que [Git](https://git-scm.com/)). Pour plus d'informations CloudFormation, consultez le [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide).

**Votre ressource de simulation**  
Dans AWS, une *ressource* est une entité avec laquelle vous pouvez travailler. Les exemples incluent une EC2 instance Amazon, un compartiment Amazon S3 ou un rôle IAM. Votre SimSpace Weaver simulation est une ressource. Dans les configurations, vous spécifiez généralement une AWS ressource dans le formulaire`AWS::service::resource`. Pour SimSpace Weaver, vous spécifiez votre ressource de simulation en tant que`AWS::SimSpaceWeaver::Simulation`. Pour plus d'informations sur votre ressource de simulation dans CloudFormation, consultez la [SimSpace Weaver](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-simspaceweaver-simulation.html)section du *guide de l'AWS CloudFormation utilisateur*.

**Comment puis-je l'utiliser CloudFormation avec SimSpace Weaver ?**  
Vous pouvez créer un CloudFormation modèle qui indique les AWS ressources que vous souhaitez mettre en service. Votre modèle peut spécifier une architecture complète, une partie d'une architecture ou une petite solution. Par exemple, vous pouvez spécifier une architecture pour votre SimSpace Weaver solution qui inclut des compartiments Amazon S3, des autorisations IAM, une base de données compatible dans Amazon Relational Database Service ou Amazon DynamoDB, ainsi que votre ressource. `Simulation` Vous pouvez ensuite utiliser CloudFormation pour fournir toutes ces ressources en tant qu'unité, et en même temps.

**Example modèle qui crée des ressources IAM et lance une simulation**  
L'exemple de modèle suivant crée un rôle IAM et des autorisations SimSpace Weaver nécessaires pour effectuer des actions dans votre compte. Les scripts du SDK de l' SimSpace Weaver application créent le rôle et les autorisations d'un projet spécifique Région AWS , mais vous pouvez utiliser un CloudFormation modèle pour déployer la simulation sur un autre Région AWS sans exécuter à nouveau les scripts. Par exemple, vous pouvez le faire pour configurer une simulation de sauvegarde à des fins de reprise après sinistre.  
Dans cet exemple, le nom de la simulation d'origine est`MySimulation`. Un compartiment pour le schéma existe déjà dans le répertoire Région AWS où CloudFormation sera construite la pile. Le bucket contient une version du schéma correctement configurée pour exécuter la simulation dans celui-ci Région AWS. N'oubliez pas que le schéma indique l'emplacement des fichiers zip de votre application, qui sont un compartiment Amazon S3 Région AWS identique à celui de la simulation. L'application zips bucket et les fichiers doivent déjà exister dans le fichier Région AWS when CloudFormation build the stack, sinon votre simulation ne démarrera pas. Notez que le nom du compartiment dans cet exemple inclut le Région AWS, mais cela ne détermine pas où se trouve réellement le compartiment. Vous devez vous assurer que le compartiment s'y trouve réellement Région AWS (vous pouvez vérifier les propriétés du compartiment dans la console Amazon S3, avec Amazon S3 APIs ou avec les commandes Amazon S3 dans le AWS CLI).  
Cet exemple utilise des fonctions et des paramètres intégrés CloudFormation pour effectuer une substitution de variables. Pour plus d'informations, reportez-vous aux sections [Référence intrinsèque aux fonctions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) et [Référence aux pseudo-paramètres](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) dans le *Guide de AWS CloudFormation l'utilisateur*.  

```
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'
```

# Utilisation d'instantanés avec AWS CloudFormation
<a name="working-with_cloudformation_snapshots"></a>

Un [instantané](working-with_snapshots.md) est une sauvegarde d'une simulation. L'exemple suivant démarre une nouvelle simulation à partir d'un instantané plutôt que d'un schéma. L'instantané de cet exemple a été créé à partir d'une simulation de projet du SDK d' SimSpace Weaver application. CloudFormation crée la nouvelle ressource de simulation et l'initialise avec les données de l'instantané. La nouvelle simulation peut être `MaximumDuration` différente de la simulation d'origine.

Nous vous recommandons de créer et d'utiliser une copie du rôle d'application de votre simulation d'origine. Le rôle d'application de la simulation d'origine peut être supprimé si vous supprimez la CloudFormation pile de cette simulation.

```
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"
```

# Instantanés
<a name="working-with_snapshots"></a>

Vous pouvez créer un *instantané* pour sauvegarder les données de vos entités de simulation à tout moment. SimSpace Weaver crée un fichier .zip dans un compartiment Amazon S3. Vous pouvez créer une nouvelle simulation avec l'instantané. SimSpace Weaver initialise le State Fabric de votre nouvelle simulation avec les données d'entité stockées dans l'instantané, démarre les applications spatiales et de service qui étaient en cours d'exécution lorsque le cliché a été créé et met l'horloge sur le tic-tac approprié. SimSpace Weaver obtient la configuration de votre simulation à partir de l'instantané plutôt que d'un fichier de schéma. Les fichiers .zip de votre application doivent se trouver au même emplacement dans Amazon S3 que dans la simulation d'origine. Vous devez démarrer les applications personnalisées séparément.

**Rubriques**
+ [Cas d'utilisation pour les instantanés](#working-with_snapshots_use-cases)
+ [Utiliser la SimSpace Weaver console pour travailler avec des instantanés](working-with_snapshots_console.md)
+ [Utilisez le AWS CLI pour travailler avec des instantanés](working-with_snapshots_cli.md)
+ [Utilisation d'instantanés avec AWS CloudFormation](working-with_cloudformation_snapshots.md)
+ [Questions fréquemment posées sur les instantanés](working-with_snapshots_faq.md)

## Cas d'utilisation pour les instantanés
<a name="working-with_snapshots_use-cases"></a>

### Revenez à un état précédent et explorez les scénarios de branchement
<a name="working-with_snapshots_use-case_branching"></a>

Vous pouvez créer un instantané de votre simulation pour l'enregistrer dans un état spécifique. Vous pouvez ensuite créer plusieurs nouvelles simulations à partir de cet instantané et explorer différents scénarios susceptibles de découler de cet état.

### Meilleures pratiques en matière de reprise après sinistre et de sécurité
<a name="working-with_snapshots_use-cases_best-practice"></a>

Nous vous recommandons de sauvegarder régulièrement votre simulation, en particulier pour les simulations qui s'exécutent pendant plus d'une heure ou qui font appel à plusieurs intervenants. Les sauvegardes peuvent vous aider à vous remettre en cas de sinistre ou d'incident de sécurité. Les instantanés vous permettent de sauvegarder votre simulation. Les instantanés nécessitent que les fichiers .zip de votre application existent au même emplacement dans Amazon S3 qu'auparavant. Si vous devez être en mesure de déplacer les fichiers .zip de votre application vers un autre emplacement, vous devez utiliser une solution de sauvegarde personnalisée. 

Pour plus d'informations sur les autres meilleures pratiques, consultez [Bonnes pratiques en matière de travail avec SimSpace Weaver](best-practices.md) et[Bonnes pratiques en matière de sécurité pour SimSpace Weaver](security_best-practices.md).

### Prolongez la durée de votre simulation
<a name="working-with_snapshots_use-cases_extend-duration"></a>

Votre *ressource de simulation* est la représentation de votre simulation dans SimSpace Weaver. Toutes les ressources de simulation ont un `MaximumDuration` paramètre. Une ressource de simulation s'arrête automatiquement lorsqu'elle atteint sa valeur`MaximumDuration`. La valeur maximale de `MaximumDuration` est `14D` (14 jours). 

Si vous souhaitez que votre simulation persiste plus longtemps que sa ressource `MaximumDuration` de simulation, vous pouvez créer un instantané avant que la ressource de simulation n'atteigne sa limite`MaximumDuration`. Vous pouvez démarrer une nouvelle simulation (créer une nouvelle ressource de simulation) avec votre instantané. SimSpace Weaver initialise les données de votre entité à partir de l'instantané, lance les mêmes applications spatiales et de service que celles qui s'exécutaient auparavant et rétablit l'horloge. Vous pouvez démarrer vos applications personnalisées et effectuer toute initialisation personnalisée supplémentaire. Vous pouvez définir une valeur différente pour la nouvelle ressource de simulation lorsque vous la démarrez. `MaximumDuration`

# Utiliser la SimSpace Weaver console pour travailler avec des instantanés
<a name="working-with_snapshots_console"></a>

Vous pouvez utiliser la SimSpace Weaver console pour créer un instantané de votre simulation.

**Topics**
+ [Créer un instantané](#working-with_snapshots_console_create)
+ [Lancer une simulation à partir d'un instantané](#working-with_snapshots_console_start)

## Utiliser la console pour créer un instantané
<a name="working-with_snapshots_console_create"></a>

**Pour créer un instantané**

1. Connectez-vous à la [SimSpace Weaver console AWS Management Console et connectez-vous à celle-ci](https://console.aws.amazon.com/simspaceweaver).

1. Choisissez **Simulations** dans le volet de navigation.

1. Sélectionnez le bouton radio à côté du nom de la simulation. Le **statut** de votre simulation doit être **démarré**. 

1. En haut de la page, choisissez **Créer un instantané**.

1. Dans **Paramètres des instantanés**, pour **Destination des instantanés**, entrez l'URI Amazon S3 d'un compartiment ou d'un compartiment et d'un dossier dans lesquels vous SimSpace Weaver souhaitez créer votre instantané. Vous pouvez choisir **Browse S3** si vous préférez parcourir les compartiments disponibles et sélectionner un emplacement.
**Important**  
Le compartiment Amazon S3 doit se trouver dans le même emplacement Région AWS que celui de la simulation.
**Note**  
SimSpace Weaver crée un `snapshot` dossier dans la destination de capture d'écran que vous avez sélectionnée. SimSpace Weaver crée le fichier .zip de capture d'écran dans ce `snapshot` dossier.

1. Choisissez **Créer un instantané**.

## Utiliser la console pour démarrer une simulation à partir d'un instantané
<a name="working-with_snapshots_console_start"></a>

Pour démarrer une simulation à partir d'un instantané, votre fichier .zip d'instantané doit exister dans un compartiment Amazon S3 auquel votre simulation peut accéder. Votre simulation utilise les autorisations définies dans le rôle d'application que vous sélectionnez lorsque vous démarrez la simulation. Tous les fichiers .zip de l'application issus de la simulation d'origine doivent se trouver au même emplacement que lors de la création de l'instantané.

**Pour démarrer une simulation à partir d'un instantané**

1. Connectez-vous à la [SimSpace Weaver console AWS Management Console et connectez-vous à celle-ci](https://console.aws.amazon.com/simspaceweaver).

1. Choisissez **Simulations** dans le volet de navigation.

1. En haut de la page, choisissez **Démarrer la simulation**.

1. Sous **Paramètres de simulation**, entrez un nom et une description facultative pour votre simulation. Le nom de votre simulation doit être unique dans votre Compte AWS.

1. Pour la **méthode de démarrage de la simulation**, choisissez **Utiliser un instantané dans Amazon S3**.

1. Pour l'**URI Amazon S3 pour le snapshot**, entrez l'URI Amazon S3 de votre fichier de snapshot, ou choisissez **Browse S3** pour parcourir et sélectionner le fichier.
**Important**  
Le compartiment Amazon S3 doit se trouver dans le même emplacement Région AWS que celui de la simulation.

1. Pour le **rôle IAM**, sélectionnez le rôle d'application que votre simulation utilisera.

1. Dans **Durée maximale**, entrez la durée maximale pendant laquelle votre ressource de simulation doit s'exécuter. La valeur maximale est `14D`. Pour plus d'informations sur la durée maximale, consultez[.](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)

1. Sous **Balises - *facultatif***, choisissez **Ajouter une nouvelle étiquette** si vous souhaitez ajouter une étiquette.

1. Choisissez **Démarrer la simulation**.

# Utilisez le AWS CLI pour travailler avec des instantanés
<a name="working-with_snapshots_cli"></a>

Vous pouvez utiliser le AWS CLI pour appeler le SimSpace Weaver APIs depuis une invite de commande. Vous devez l'avoir AWS CLI installé et configuré correctement. Pour plus d'informations, consultez la section [Installation ou mise à jour de la dernière version de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) dans le *guide de AWS Command Line Interface l'utilisateur pour la version 2*.

**Topics**
+ [Créer un instantané](#working-with_snapshots_cli_create)
+ [Lancer une simulation à partir d'un instantané](#working-with_snapshots_cli_start)

## Utilisez le AWS CLI pour créer un instantané
<a name="working-with_snapshots_cli_create"></a>

**Pour créer un instantané**
+ À l'**invite de commande**, appelez l'`CreateSnapshot`API.

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

  **Paramètres**  
simulation  
Le nom d'une simulation démarrée. Vous pouvez l'utiliser `aws simspaceweaver list-simulations` pour voir les noms et les statuts de vos simulations.  
destination  
Chaîne qui indique le compartiment Amazon S3 de destination et le préfixe de clé d'objet facultatif pour votre fichier de capture instantanée. Le préfixe de votre clé d'objet est généralement un dossier de votre bucket. SimSpace Weaver crée votre instantané dans un `snapshot` dossier à cette destination.   
Le compartiment Amazon S3 doit se trouver dans le même emplacement Région AWS que celui de la simulation.

  **Exemple**

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

Pour plus d'informations sur l'`CreateSnapshot`API, consultez [CreateSnapshot](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_CreateSnapshot.html)la *référence de l'AWS SimSpace Weaver API*.

## Utilisez le AWS CLI pour démarrer une simulation à partir d'un instantané
<a name="working-with_snapshots_cli_start"></a>

**Pour démarrer une simulation à partir d'un instantané**
+ À l'**invite de commande**, appelez l'`StartSimulation`API.

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

  **Paramètres**  
nom  
Nom de la nouvelle simulation. Le nom de la simulation doit être unique dans votre Compte AWS. Vous pouvez l'utiliser `aws simspaceweaver list-simulations` pour voir les noms de vos simulations existantes.  
role-arn  
Le nom de ressource Amazon (ARN) du rôle d'application que votre simulation utilisera.  
emplacement de snapshot-s3  
Chaîne qui spécifie le compartiment Amazon S3 et la clé d'objet de votre fichier de capture instantanée.  
Le compartiment Amazon S3 doit se trouver dans le même emplacement Région AWS que celui de la simulation.

  **Exemple**

  ```
  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
  ```

Pour plus d'informations sur l'`StartSimulation`API, consultez [StartSimulation](https://docs.aws.amazon.com/simspaceweaver/latest/APIReference/API_StartSimulation.html)la *référence de l'AWS SimSpace Weaver API*.

# Questions fréquemment posées sur les instantanés
<a name="working-with_snapshots_faq"></a>

**Ma simulation continue-t-elle de s'exécuter pendant un instantané ?**  
Vos ressources de simulation continuent de s'exécuter pendant un instantané et vous continuez à recevoir des frais de facturation pour cette période. Le temps est pris en compte dans la durée maximale de votre simulation. Vos applications ne reçoivent pas de ticks lorsque l'instantané est en cours de création. Si l'état de votre horloge était `STARTED` celui où la création de l'instantané a commencé, votre horloge indiquera toujours `STARTED` l'état. Vos applications reçoivent à nouveau des coches une fois l'instantané terminé. Si l'état de votre horloge était le `STOPPED` même, votre état d'horloge restera le même`STOPPED`. Notez qu'une simulation avec un `STARTED` statut est en cours d'exécution même si son état d'horloge l'est`STOPPED`.

**Que se passe-t-il si un instantané est en cours et que ma simulation atteint sa durée maximale ?**  
Votre simulation terminera l'instantané, puis s'arrêtera dès que le processus de capture d'écran sera terminé (avec ou sans succès). Nous vous recommandons de tester le processus de capture d'écran au préalable pour déterminer sa durée, la taille du fichier de capture à laquelle vous pouvez vous attendre et s'il doit s'exécuter correctement.

**Que se passe-t-il si j'arrête une simulation dont un instantané est en cours ?**  
Un instantané en cours s'arrête immédiatement lorsque vous arrêtez la simulation. Cela ne créera pas de fichier instantané.

**Comment puis-je arrêter un instantané en cours ?**  
Le seul moyen d'arrêter un instantané en cours est d'arrêter la simulation. **Vous ne pouvez pas redémarrer une simulation après l'avoir arrêtée.**

**Combien de temps me faudra-t-il pour terminer mon instantané ?**  
Le temps nécessaire pour créer un instantané dépend de votre simulation. Nous vous recommandons de tester le processus de capture d'écran au préalable pour savoir combien de temps prendra votre simulation.

**Quelle sera la taille de mon fichier de capture d'écran ?**  
La taille d'un fichier de capture dépend de votre simulation. Nous vous recommandons de tester le processus de capture d'écran au préalable afin de déterminer la taille du fichier pour votre simulation.

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

L'API de messagerie simplifie la communication entre applications dans le cadre de la simulation. APIs pour envoyer et recevoir des messages font partie du SDK de l' SimSpace Weaver application. La messagerie utilise actuellement une approche basée sur le meilleur effort pour envoyer et recevoir des messages. SimSpace Weaver essaie d'envoyer send/receive des messages lors de la prochaine simulation, mais aucune garantie n'est donnée quant à l'heure de livraison, de commande ou d'arrivée.

**Rubriques**
+ [Cas d'utilisation de la messagerie](#working-with_messaging_use-cases)
+ [Utilisation de la messagerie APIs](working-with_messaging_using.md)
+ [Quand utiliser la messagerie](working-with_messaging_when-to-use.md)
+ [Conseils relatifs à l'utilisation de la messagerie](working-with_messaging_tips.md)
+ [Erreurs de messagerie et résolution des problèmes](working-with_messaging_troubleshooting.md)

## Cas d'utilisation de la messagerie
<a name="working-with_messaging_use-cases"></a>

**Communiquez entre les applications de simulation**  
Utilisez l'API de messagerie pour communiquer entre les applications de votre simulation. Utilisez-le pour modifier l'état des entités à distance, modifier le comportement des entités ou diffuser des informations sur l'ensemble de la simulation.

**Accusez réception d'un message**  
Les messages envoyés contiennent des informations sur l'expéditeur dans l'en-tête du message. Utilisez ces informations pour renvoyer un accusé de réception à la réception d'un message.

**Transférer les données reçues par une application personnalisée vers d'autres applications dans le cadre de la simulation**  
La messagerie ne remplace pas la façon dont les clients se connectent aux applications personnalisées en cours d'exécution SimSpace Weaver. Cependant, la messagerie permet aux utilisateurs de transférer des données depuis des applications personnalisées recevant des données client vers d'autres applications qui ne disposent pas d'une connexion externe. Le flux de messages peut également fonctionner en sens inverse, permettant aux applications sans connexion externe de transférer des données vers une application personnalisée puis vers un client. 

# Utilisation de la messagerie APIs
<a name="working-with_messaging_using"></a>

Les messages APIs sont contenus dans le SDK de l' SimSpace Weaver application (version minimale 1.16.0). La messagerie est prise en charge en C\$1\$1, Python et dans nos intégrations avec Unreal Engine 5 et Unity.

Deux fonctions gèrent les transactions de messages : `SendMessage` et`ReceiveMessages`. Tous les messages envoyés contiennent une destination et une charge utile. L'`ReceiveMessages`API renvoie une liste des messages actuellement présents dans la file d'attente des messages entrants d'une application.

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

**Envoyer un message**

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

**Recevoir des messages**

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

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

**Envoyer un message**

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

**Recevoir des messages**

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

------

**Rubriques**
+ [Envoi de messages](#working-with_messaging_using_send)
+ [Réception de messages](#working-with_messaging_using_receive)
+ [Répondre à l'expéditeur](#working-with_messaging_using_reply)

## Envoi de messages
<a name="working-with_messaging_using_send"></a>

Les messages se composent d'une transaction (similaire aux autres appels d'API Weaver), d'une charge utile et d'une destination.

### Charge utile du message
<a name="working-with_messaging_using_send_payload"></a>

La charge utile des messages est une structure de données flexible de 256 octets maximum. Nous vous recommandons de suivre les bonnes pratiques suivantes pour créer les charges utiles de vos messages.

**Pour créer la charge utile du message**

1. Créez une structure de données (telle qu'une structure `struct` en C\$1\$1) qui définit le contenu du message.

1. Créez la charge utile du message qui contient les valeurs à envoyer dans votre message.

1. Créez l’objet `MessagePayload`.

### Destination du message
<a name="working-with_messaging_using_send_destination"></a>

La destination d'un message est définie par l'`MessageEndpoint`objet. Cela inclut à la fois un type de point de terminaison et un identifiant de point de terminaison. Le seul type de point de terminaison actuellement pris en charge est `Partition` celui qui vous permet d'adresser des messages à d'autres partitions dans la simulation. L'ID du point de terminaison est l'ID de partition de votre destination cible.

Vous ne pouvez fournir qu'une seule adresse de destination dans un message. Créez et envoyez plusieurs messages si vous souhaitez envoyer des messages à plusieurs partitions en même temps.

Pour obtenir des conseils sur la résolution d'un point de terminaison de message à partir d'une position, consultez[Conseils relatifs à l'utilisation de la messagerie](working-with_messaging_tips.md).

### Envoyer le message
<a name="working-with_messaging_using_send_send"></a>

Vous pouvez utiliser l'`SendMessage`API après avoir créé les objets de destination et de charge utile.

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

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

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

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

------

**Exemple complet d'envoi de messages**  
L'exemple suivant montre comment créer et envoyer un message générique. Cet exemple envoie 16 messages individuels. Chaque message contient une charge utile d'une valeur comprise entre 0 et 15, et la simulation en cours fonctionne.

**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
```

## Réception de messages
<a name="working-with_messaging_using_receive"></a>

SimSpace Weaver envoie les messages dans la file d'attente des messages entrants d'une partition. Utilisez l'`ReceiveMessages`API pour obtenir un `MessageList` objet contenant les messages de la file d'attente. Traitez chaque message avec l'`ExtractMessage`API pour obtenir les données du message.

**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
```

## Répondre à l'expéditeur
<a name="working-with_messaging_using_reply"></a>

Chaque message reçu contient un en-tête contenant des informations sur l'expéditeur d'origine du message. Vous pouvez utiliser le message.header.source\$1endpoint pour envoyer une réponse.

**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
```

# Quand utiliser la messagerie
<a name="working-with_messaging_when-to-use"></a>

La messagerie SimSpace Weaver entrante offre un autre modèle d'échange d'informations entre les applications de simulation. Les abonnements fournissent un mécanisme d'extraction pour lire les données provenant d'applications ou de domaines spécifiques de la simulation ; les messages fournissent un mécanisme d'extraction pour envoyer des données à des applications ou à des domaines spécifiques de la simulation.

Vous trouverez ci-dessous deux cas d'utilisation dans lesquels il est plus utile d'envoyer des données par messagerie plutôt que d'extraire ou de lire des données via un abonnement.

**Example 1 : Envoi d'une commande à une autre application pour modifier la position d'une 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);
```
Du côté récepteur, l'application met à jour la position de l'entité et l'écrit dans 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 : Envoyer un message de création d'entité à une application spatiale**  

```
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);
```
Du côté récepteur, l'application crée une nouvelle entité dans le State Fabric et met à jour sa position.  

```
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)));
}
```

# Conseils relatifs à l'utilisation de la messagerie
<a name="working-with_messaging_tips"></a>

## Résoudre un point de terminaison à partir d'une position ou d'un nom d'application
<a name="working-with_messaging_tips_resolve-endpoint"></a>

Vous pouvez utiliser cette `AllPartitions` fonction pour obtenir les limites spatiales et l'ID de domaine dont vous avez besoin pour déterminer la partition IDs et les destinations des messages. Toutefois, si vous connaissez la position à laquelle vous souhaitez envoyer un message, mais pas son ID de partition, vous pouvez utiliser la MessageEndpointResolver fonction.

```
/**
* 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);
};
```

## Sérialisation et désérialisation de la charge utile des messages
<a name="working-with_messaging_tips_serialize-payload"></a>

Vous pouvez utiliser les fonctions suivantes pour créer et lire des charges utiles de messages. Pour plus d'informations, consultez MessagingUtils .h dans la bibliothèque du SDK de l'application sur votre système local.

```
/**
* 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());
}
```

# Erreurs de messagerie et résolution des problèmes
<a name="working-with_messaging_troubleshooting"></a>

Les erreurs suivantes peuvent se produire lorsque vous utilisez la messagerie APIs.

## Erreurs de résolution des terminaux
<a name="working-with_messaging_troubleshooting_endpoint-resolution"></a>

Ces erreurs peuvent se produire avant qu'une application n'envoie un message.

### Vérification du nom de domaine
<a name="working-with_messaging_troubleshooting_dns-check"></a>

L'envoi d'un message à un point de terminaison non valide entraîne l'erreur suivante :

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

Cela peut se produire lorsque vous essayez d'envoyer un message à une application personnalisée et que cette application personnalisée n'a pas encore rejoint la simulation. Utilisez l'`DescribeSimulation`API pour vous assurer que votre application personnalisée a été lancée avant de lui envoyer un message. Ce comportement est le même dans SimSpace Weaver Local et dans le AWS Cloud.

### Contrôle de position
<a name="working-with_messaging_troubleshooting_position-check"></a>

La tentative de résolution d'un point de terminaison avec un nom de domaine valide mais une position non valide entraîne l'erreur suivante.

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

Nous vous suggérons d'utiliser le `MessageEndpointResolver` dans la `MessageUtils` bibliothèque contenue dans le SDK de SimSpace Weaver l'application.

## Erreurs d'envoi de messages
<a name="working-with_messaging_troubleshooting_message-sending"></a>

Les erreurs suivantes peuvent se produire lorsqu'une application envoie un message.

### Limite d'envoi de messages par application, par tick, dépassée
<a name="working-with_messaging_troubleshooting_send-limit"></a>

La limite actuelle du nombre de messages pouvant être envoyés par application et par test de simulation est de 128. Les appels suivants sur la même case échoueront avec l'erreur suivante : 

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

SimSpace Weaver essaie d'envoyer des messages non envoyés à la prochaine case. Réduisez la fréquence d'envoi pour résoudre ce problème. Combinez des charges utiles de messages inférieures à la limite de 256 octets pour réduire le nombre de messages sortants.

Ce comportement est le même dans SimSpace Weaver Local et dans le AWS Cloud. 

### Limite de charge utile des messages dépassée
<a name="working-with_messaging_troubleshooting_size-limit"></a>

La limite actuelle de la taille de la charge utile des messages est de 256 octets à la fois SimSpace Weaver Local dans le AWS Cloud. L'envoi d'un message dont la charge utile est supérieure à 256 octets entraîne l'erreur suivante :

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

SimSpace Weaver vérifie chaque message et rejette uniquement ceux qui dépassent la limite. Par exemple, si votre application essaie d'envoyer 10 messages et que l'un d'entre eux échoue, seul ce message est rejeté. SimSpace Weaver envoie les 9 autres messages.

Ce comportement est le même dans SimSpace Weaver Local et dans le AWS Cloud.

### La destination est la même que la source
<a name="working-with_messaging_troubleshooting_dst-src-same"></a>

Les applications ne peuvent pas envoyer de messages aux partitions qu'elles possèdent. L'erreur suivante s'affiche si une application envoie un message à une partition dont elle est propriétaire.

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

Ce comportement est le même dans SimSpace Weaver Local et dans le AWS Cloud.

### Messagerie basée sur le meilleur effort
<a name="working-with_messaging_troubleshooting_best-effort"></a>

SimSpace Weaver ne garantit pas la livraison du message. Le service essaiera de terminer la livraison des messages lors de la simulation suivante, mais les messages risquent de se perdre ou d'être retardés.