Comportements - machine d'état sans maux de tête

L'approche standard pour décrire la séquence des entrées et des réactions des utilisateurs (par exemple, lors du contrôle d'un personnage dans un jeu) est une machine à états. Cependant, cela conduit souvent à des programmes lourds, dont la compréhension nécessite des efforts considérables, voire des croquis sur papier. Dans cet article, je propose un petit changement dans la description, ce qui économise de l'espace d'écran et des ressources cérébrales.


image

Le changement de description est l'utilisation de la technique de la coroutine. Pour appliquer cette technique, il est nécessaire d'imaginer le type de comportement que nous attendons de l'ordinateur en conséquence. Par conséquent, j'ai appelé la petite bibliothèque que j'ai créée pour cette tâche - Comportements.

Lorsque l'utilisateur interagit avec le programme, l'ordinateur attend une certaine action et répond à l'entrée d'une certaine manière. Les comportements primitifs et leurs combinaisons peuvent remplacer les machines à états encombrantes, qui se trouvent souvent de manière formelle ou informelle dans les programmes. Par exemple, lorsqu'un programme est dans un état d'attente pour qu'une certaine touche soit pressée, nous pouvons dire qu'il exécute le comportement waitForKey (...). La commodité est que les comportements sont combinés sous une forme facile à lire, contrairement aux machines d'état. Un exemple simple de Drag & Drop:

* DragAndDrop = * draggedObject =  MouseDown  -  * First *  MouseUp * Forever *  MouseMove *  draggedObject 

Le comportement a un début, une fin et peut renvoyer une valeur. Les comportements sont exécutés dans l'ordre ou peuvent être exécutés en parallèle à l'aide de combinateurs. Par exemple, le premier combinateur exécute plusieurs comportements en parallèle et se termine lorsque l'un des comportements est terminé, renvoyant son résultat. Forever - répète l'exécution d'un comportement spécifique à l'infini. Contrairement à l'exécution de fonctions, le comportement ne bloque pas le thread principal d'exécution, donc les comportements infinis peuvent être très utiles.

J'ai implémenté des comportements en utilisant des fonctions qui reçoivent des événements primitifs (comme MouseDown, MouseUp, MouseMove, ...) en tant que paramètre et produisent un objet de la forme:

 { done: true|false, value: result value } 

Vous pouvez voir l'implémentation ici: behavior.js sur GitHub et l'exemple Drag & Drop ici: jsFiddle .

Où les comportements peuvent-ils être utilisés?

  • Jeux informatiques - il est très pratique d'écrire de la logique et de l'IA, parfois je fais tout avec des comportements, y compris l'animation et le mouvement d'objets, mais vous devez surveiller les performances
  • Tutoriel dans le frontend (tour des nouvelles fonctionnalités) - afficher les informations, attendre l'interaction de l'utilisateur, continuer en fonction de l'entrée, tout le code en un seul endroit et lire presque comme un pseudo code
  • L'analyseur de langage orienté sujet est un code idiomatique, il n'est pas nécessaire de «regarder vers l'avant» en entrée, car vous pouvez exécuter plusieurs comportements en parallèle

Photo: comportement par Nick Youngson CC BY-SA 3.0 Alpha Stock Images

Source: https://habr.com/ru/post/fr436972/


All Articles