Dynamo 2.0 est une version majeure et certaines API ont été modifiées ou supprimées. L’un des changements les plus importants qui affectera les auteurs de nœuds et de packages est le passage au format de fichier JSON.
Dans la plupart des cas, les auteurs de nœuds Zero-Touch n’auront que peu ou pas de travail à faire pour que leurs packages fonctionnent dans la version 2.0.
Les nœuds d’interface utilisateur et les nœuds qui dérivent directement de NodeModel nécessiteront plus de travail pour fonctionner dans la version 2.x.
Les auteurs d’extensions peuvent également avoir des changements potentiels à faire selon la quantité d’API de Dynamo Core qu’ils utilisent dans leurs extensions.
n’intégrez pas les fichiers .dll de Dynamo ou de Dynamo Revit dans votre package. Ces fichiers .dll seront déjà chargés par Dynamo. Si vous intégrez une version différente de celle que l’utilisateur a chargée (p. ex. vous distribuez sur Dynamo Core 1.3 mais l’utilisateur exécute votre package sur Dynamo 2.0), des bogues d’exécution inattendus se produiront. Cela inclut les fichiers .dll tels que DynamoCore.dll
, DynamoServices.dll
, DSCodeNodes.dll
, ProtoGeometry.dll
;
évitez d’intégrer et de distribuer des newtonsoft.json.net
avec votre package si vous pouvez l’éviter. Ce fichier .dll sera également chargé par Dynamo 2.x. Le même problème que ci-dessus peut se produire ;
évitez d’intégrer et de distribuer des CEFSharp
avec votre package si vous pouvez l’éviter. Ce fichier .dll sera également chargé par Dynamo 2.x. Le même problème que ci-dessus peut se produire ;
de manière générale, évitez de partager des dépendances avec Dynamo ou Revit si vous avez besoin de contrôler la version de cette dépendance.
1) Lors de l’ouverture d’un graphique, certains nœuds ont plusieurs ports portant le même nom, mais le graphique semble correct lors de l’enregistrement. Ce problème peut avoir plusieurs causes.
La cause principale est que le nœud a été créé à l’aide d’un constructeur qui a recréé les ports. Au lieu de cela, il aurait fallu utiliser un constructeur capable de charger les ports. Ces constructeurs sont généralement marqués [JsonConstructor]
. Voir les exemples ci-dessous
Cela peut se produire pour les raisons suivantes :
il n’y avait tout simplement pas de [JsonConstructor]
correspondant, ou il n’a pas été transmis par les fichiers Inports
et Outports
du fichier JSON .dyn ;
deux versions de JSON.net ont été chargées simultanément dans le même processus, ce qui a entraîné une erreur au niveau de l’exécution .net, de sorte que l’attribut [JsonConstructor]
n’a pas pu être utilisé correctement pour marquer le constructeur ;
une version de DynamoServices.dll différente de la version actuelle de Dynamo a été incluse dans le package et provoque l’échec de l’exécution .net à identifier l’attribut [MultiReturn]
, de sorte que les nœuds Zero-Touch marqués avec divers attributs ne pourront pas être appliqués. Il se peut qu’un nœud renvoie une seule sortie de dictionnaire au lieu de plusieurs ports.
2) Des nœuds sont complètement absents lors du chargement du graphique avec des erreurs dans la console.
Cela peut se produire si votre désérialisation a échoué pour une raison quelconque. Il est recommandé de ne sérialiser que les propriétés dont vous avez besoin. Nous pouvons utiliser [JsonIgnore]
sur les propriétés complexes que vous n’avez pas besoin de charger ou d’enregistrer pour les ignorer. Il s’agit de propriétés telles que function pointer, delegate, action,
ou event
etc. Elles ne doivent pas être sérialisées car elles échoueront généralement à la désérialisation et provoqueront une erreur d’exécution.
Organiser les nœuds personnalisés dans librarie.js
Problèmes connus :
un nom de nœud personnalisé et un nom de catégorie coïncidant au même niveau dans librarie.js provoque un comportement inattendu. QNTM-3653 : évitez d’utiliser les mêmes noms pour la catégorie et les nœuds ;
les commentaires seront transformés en commentaires de bloc au lieu de commentaires de ligne ;
les noms de type abrégés seront remplacés par des noms complets. Par exemple, si vous n’avez pas spécifié de type lorsque vous chargez à nouveau le nœud personnalisé, var[]..[]
s’affiche, car il s’agit du type par défaut.
Dans Dynamo 2.0, les types Liste et Dictionnaire ont été divisés et la syntaxe pour créer des listes et des dictionnaires a été modifiée. Les listes sont initialisées à l’aide de []
tandis que les dictionnaires utilisent {}
.
Si vous utilisiez auparavant l’attribut DefaultArgument
pour marquer les paramètres de vos nœuds Zero-Touch et utilisiez la syntaxe de liste par défaut pour une liste spécifique telle que someFunc([DefaultArgument("{0,1,2}")])
, ceci ne sera plus valable et vous devrez modifier l’extrait de code DesignScript pour utiliser la nouvelle syntaxe d’initialisation pour les listes.
Comme indiqué ci-dessus, ne distribuez pas de fichiers .dll Dynamo avec vos packages. (DynamoCore
, DynamoServices
, etc.).
Les nœuds de modèle de nœud nécessitent le plus de travail pour passer à Dynamo 2.x. De manière générale, vous devez implémenter des constructeurs qui seront utilisés uniquement pour charger vos nœuds à partir de json, en plus des constructeurs nodeModel standard utilisés pour instancier de nouvelles instances de vos types de nœud. Pour les différencier, vous devez marquer les constructeurs de chargement à l’aide de l’attribut [JsonConstructor]
de newtonsoft.Json.net.
Les noms des paramètres du constructeur doivent généralement correspondre aux noms des propriétés JSON, bien que ce mappage soit plus compliquée si vous remplacez les noms sérialisés à l’aide d’attributs [JsonProperty]. Pour plus d’informations, reportez-vous à la documentation de Json.net.
La modification la plus courante requise pour mettre à jour les nœuds dérivés de la classe de base NodeModel
(ou d’autres classes de base Dynamo Core, par exemple DSDropDownBase
) est la nécessité d’ajouter un constructeur JSON à votre classe.
Votre constructeur original sans paramètre gérera toujours l’initialisation d’un nouveau nœud créé au sein de Dynamo (via la bibliothèque par exemple). Le constructeur JSON est requis pour initialiser un nœud désérialisé (chargé) à partir d’un fichier .dyn ou .dyf enregistré.
Le constructeur JSON diffère du constructeur de base, car il possède des paramètres PortModel
pour les inPorts
et les outPorts
, fournis par la logique de chargement JSON. L’appel pour enregistrer les ports pour le nœud n’est pas requis ici, car les données existent dans le fichier .dyn. Voici un exemple de constructeur JSON :
using Newtonsoft.Json; //New dependency for Json
………
[JsonConstructor] //Attribute required to identity the Json constructor
//Minimum constructor implementation. Note that the base method invocation must also be present.
FooNode(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts) { }
Cette syntaxe :base(Inports,outPorts){}
appelle le constructeur de base nodeModel
et lui transmet les ports désérialisés.
Il n’est pas nécessaire de répéter dans ce constructeur toute logique spéciale qui existait dans le constructeur de la classe et qui impliquait l’initialisation de données spécifiques sérialisées dans le fichier .dyn (par exemple la définition de l’enregistrement du port, la stratégie de combinaison, etc.), car ces valeurs peuvent être lues à partir du JSON.
C’est la principale différence entre le constructeur JSON et les constructeurs non-JSON pour vos nodeModels. Les constructeurs JSON sont appelés lors du chargement à partir d’un fichier et les données chargées sont transmises. D’autres éléments de la logique utilisateur doivent cependant être dupliqués dans le constructeur JSON (par exemple, l’initialisation des gestionnaires d’événements pour le nœud ou l’association).
Des exemples sont disponibles dans le dépôt DynamoSamples -> ButtonCustomNodeModel, DropDown ou SliderCustomNodeModel.
Auparavant, un développeur pouvait sérialiser et désérialiser des données de modèle spécifiques dans le document XML à l’aide des méthodes SerializeCore
et DeserializeCore
. Ces méthodes existent toujours dans l’API, mais seront abandonnées dans une version ultérieure de Dynamo (un exemple est disponible ici). Avec l’implémentation JSON.NET, les propriétés public
de la classe dérivée NodeModel peuvent être sérialisées directement dans le fichier .dyn. JSON.Net fournit plusieurs attributs pour contrôler la façon dont la propriété est sérialisée.
Cet exemple qui spécifie un PropertyName
se trouve ici dans le dépôt Dynamo.
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
Remarque
Si vous créez votre propre classe de convertisseur JSON.net, Dynamo ne dispose pas actuellement d’un mécanisme qui vous permet de l’injecter dans les méthodes de chargement et d’enregistrement. Ainsi, même si vous marquez votre classe avec l’attribut [JsonConverter]
, elle ne peut pas être utilisée, à la place vous pouvez appeler votre convertisseur directement dans votre setter ou getter. //À FAIRE : avoir la confirmation de cette limitation. Toute preuve est la bienvenue.
Un exemple qui spécifie une méthode de sérialisation pour convertir la propriété en chaîne est disponible ici dans le dépôt Dynamo.
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
Les propriétés public
qui ne sont pas destinées à la sérialisation doivent être accompagnées de l’attribut [JsonIgnore]
. Lorsque les nœuds sont enregistrés dans le fichier .dyn, cela garantit que ces données sont ignorées par le mécanisme de sérialisation et qu’elles n’auront pas de conséquences inattendues lorsque le graphique sera ouvert à nouveau. Vous pouvez en trouver un exemple ici, dans le dépôt Dynamo.
Comme indiqué ci-dessus, les méthodes SerializeCore
et DeserializeCore
étaient utilisées dans le passé pour enregistrer et charger des nœuds dans le fichier xml .dyn. En outre, elles étaient également utilisées pour enregistrer et charger l’état des nœuds pour annuler/rétabliret le sont toujours ! Si vous souhaitez mettre en œuvre une fonctionnalité complexe Annuler/Rétablir pour votre nœud de l’interface utilisateur nodeModel, vous devrez mettre en œuvre ces méthodes et sérialiser dans l’objet document XML fourni en tant que paramètre de ces méthodes. Il s’agit d’un cas d’utilisation rare, sauf pour les nœuds complexes de l’interface utilisateur.
L’enregistrement du port dans le constructeur du nœud est un phénomène courant dans les nœuds nodeModel concernés par les modifications de l’API 2.0. Si vous avez déjà regardé des exemples dans le dépôt Dynamo ou DynamoSamples, il est possible que vous ayez utilisé les méthodes InPortData.Add()
ou OutPortData.Add()
. Auparavant, dans l’API Dynamo, les propriétés publiques InPortData
et OutPortData
étaient marquées comme étant obsolètes. Dans la version 2.0, ces propriétés ont été supprimées. Les développeurs doivent maintenant utiliser les méthodes InPorts.Add()
et OutPorts.Add()
. En outre, ces deux méthodes Add()
ont des signatures légèrement différentes :
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
comparé à
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
Des exemples de code converti sont disponibles dans le dépôt Dynamo -> DynamoConvert.cs ou FileSystem.cs
L’autre cas d’utilisation courant affecté par les modifications de l’API 2.0 est lié aux méthodes couramment utilisées dans la méthode BuildAst()
pour déterminer le comportement du nœud en fonction de la présence ou de l’absence de connecteurs de port. Auparavant, HasConnectedInput(index)
était utilisé pour valider un état de port connecté. Les développeurs doivent maintenant utiliser la propriété InPorts[0].IsConnected
pour vérifier l’état de la connexion au port. Un exemple de ceci peut être trouvé dans ColorRange.cs dans le dépôt Dynamo.
Nous allons voir comment mettre à jour un nœud d’interface utilisateur 1.3 vers Dynamo 2.x.
Pour charger et enregistrer correctement cette classe nodeModel
dans la version 2.0, il suffit d’ajouter un jsonConstructor pour gérer le chargement des ports. Nous passons simplement les ports au constructeur de base et cette implémentation est vide.
Remarque : n’appelez pas RegisterPorts()
ou une variante de ce paramètre dans votre JsonConstructor. Cela utilisera les attributs des paramètres d’entrée et de sortie de votre classe de nœuds pour construire de nouveaux ports ! Ce n’est pas ce que nous souhaitons, puisque nous voulons utiliser les ports chargés qui sont passés au constructeur.
Cet exemple ajoute le constructeur JSON le moins chargé possible. Mais qu’en est-il si nous avons besoin d’une logique de construction plus complexe, comme la mise en place d’écouteurs pour la gestion des événements à l’intérieur du constructeur. L’échantillon suivant, tiré du
dépôt DynamoSamples, est lié ci-dessus dans la JsonConstructors Section
de ce document.
Voici un constructeur plus complexe pour un nœud d’interface utilisateur :
Lorsque nous ajoutons un constructeur JSON pour charger ce nœud à partir d’un fichier, nous devons recréer une partie de cette logique, mais notez que nous n’incluons pas le code qui crée les ports, définit la combinaison ou les valeurs par défaut des propriétés que nous pouvons charger à partir du fichier.
Notez que les autres propriétés publiques qui ont été sérialisées dans le JSON comme ButtonText
et WindowText
ne devront pas être ajoutées en tant que paramètres explicites au constructeur. Elles sont définies automatiquement par JSON.net en utilisant les setters pour ces propriétés.