Le code directement réutilisable du projet est contenu dans le package labpyproject.core.

labpyproject
├── labpyproject.apps
└── labpyproject.core
    ├── labpyproject.core.app
    ├── labpyproject.core.io
    ├── labpyproject.core.net
    ├── labpyproject.core.patterns
    ├── labpyproject.core.pygame
    ├── labpyproject.core.queue
    └── labpyproject.core.random

Remarque:

labpyproject.core est totalement indépendant de labpyproject.apps.

Les sous packages labpyproject.core.io, labpyproject.core.patterns et labpyproject.core.random sont très embryonnaires, leur existence relève surtout d’une volonté de structurer le code.

2.1- Programmation parallèle

2.1.1- Système d’aiguillage de tâches

Deux threads en cours d’exécution ne pouvant communiquer directement entre eux, nous avons besoin d’un système de communication « tiers ». Celui-ci repose sur des piles de tâches (Queues). Chaque thread peut déposer une tâche dans une pile dédiée. Réciproquement il peut interroger cette pile pour en retirer une tâche.

Ce système d’échange est implémenté dans le module queue_tools du sous package labpyproject.core.queue.

Il s’appuye sur trois classes:

  • QueueManager: un singleton qui prend en charge la gestion des piles de tâches
  • QueueSimpleClient: un client associé à une pile entrante et une pile sortante
  • QueueSwitcher: un routeur de tâches, aiguillant les tâches entrantes et sortantes entre différents canaux

2.1.2- Ebauche de framework applicatif multi-thread

Ce prototype est implémenté dans le module app_components du sous package labpyproject.core.app.

Vis-à-vis des threads ce module distingue:

  • Le cas général dans lequel un composant peut générer son propre thread d’exécution (superclasse: ThreadableComp)
  • Le cas particulier des GUIs graphiques (Tkinter, Pygame,…) qui doivent absolument être créées dans le « scope __main__ » du script principal

Pour la communication inter-threads, ce module distingue:

  • Un composant héritant de QueueSwitcher (et de ThreadableComp), soit notre application APPComp
  • Des composants satellites héritant de QueueSimpleClient

Pour combiner ces deux aspects dans les satellites, on introduit des pseudos interfaces:

  • AbstractSatelliteComp: de laquelle dérivent
    • SatelliteComp: composant satellite héritant de ThreadableComp.
    • SatelliteCompNoThread: composant satellite particulier (cf « scope __main__ »)
  • AbstractGUIComp: de laquelle dérivent
    • GUIComp: composant d’interface héritant de SatelliteComp (console)
    • GUICompNoThread: composant d’interface héritant de SatelliteCompNoThread (Tkinter, Pygame,…)

Les composants réseau NETComp et métier BUSINESSComp dérivent tous deux de SatelliteComp.

Ce module crée également une hiérarchie d’objets d’échanges répondant à une série de besoins génériques d’interactions entre composants.

Dans la section suivante nous allons aborder des composants satellites finalisés, avec un client et un serveur dérivés tous deux de NETComp.

2.2- Prototype de framework réseau TCP

Le jeu devant proposer une version réseau TCP, j’ai essayé de proposer un prototype de framework client-serveur susceptible d’apporter des réponses aux questions soulevées dans l’article suivant de la documentation officielle python: https://docs.python.org/3/howto/sockets.html.

Si le résultat n’est pas totalement abouti, un prototype fonctionnel est présenté dans le module custom_TCP du sous package labpyproject.core.net.

Cette ébauche de framework s’appuye sur trois classes principales:

  • CustomRequestHelper: une classe statique portant des données de modélisation et assurant des services de traitement des requêtes (découpage, indexation, envoi, réception et analyse d’erreurs).
  • CustomTCPServerContainer: serveur “frontal” héritant de labpyproject.core.app.NETComp et utilisant par composition un serveur dérivé du package socket de l’api python.
  • CustomTCPThreadedClient: client “from scratch” héritant de labpyproject.core.app.NETComp.

Ces composants (client et serveur) sont utilisés tels quels dans la version réseau du jeu labpyrinthe.

2.3- Prototype de moteur de publication Pygame

Pour doter le jeu d’une interface graphique je me suis tout d’abord tourné vers Tkinter, l’outil le plus standard à priori de la distribution python. Si j’ai pu réaliser une maquette du jeu via Tkinter, je me suis confronté aux limites suivantes:

  • Limitations graphiques: bien que le box model de Tkinter soit puissant (via les gestionnaires de positionnement), il est plutôt destiné à des interfaces de type logicielles qu’à des interfaces extrêmement graphiques. Par exemple, on ne dispose pas nativement de coordonnées et de dimensions pouvant être exprimées en %. Par ailleurs les conteneurs imposent un fond opaque.
  • Problèmes de performances: en créant de nombreux objets graphiques à partir de widgets Tkinter j’ai créé une application lente, lenteur particulièrement sensible lors des phases de publication d’un labyrinthe ou d’un resize de la fenêtre.

Ces limites auraient probablement pu être en partie dépassées avec un investissement plus important sur cet outil. Notamment en créant des objets graphiques plus « bas niveau » beaucoup plus économes en traitements. Supposant que je me confronterai aux mêmes problématiques avec d’autres librairies graphiques de type widgets, j’ai expérimenté Pygame:

  • outil clairement orienté multimédia,
  • rapide (même avec des centaines de sprites affichés simultanément),
  • mais minimaliste dans son approche de box model et de publication.

En souvenir de mon ancienne activité de développeur flash/flex dans laquelle je développais des surcouches graphiques (moteurs de publication xml to flash), je me suis lancé le défi de développer un « moteur de publication » pygame en y ajoutant:

  • un box model 2.5D (plan + zindexs)
  • une logique de publication
  • une gestion basique des événements
  • un jeu minimaliste de widgets de publication

Le résultat de ce travail constitue le sous package labpyproject.core.pygame.

La part la plus importante du travail concerne les aspects box model, gestion dynamique des zindexs et publication. Elle est réalisée dans le module core du sous package.

La mécanique basique de gestion des événements est développée dans le module events.

En combinant ces deux modules, le module widgets propose un jeu de composants de publication basiques suffisant pour répondre aux besoins du jeu labpyrinthe.

Avec cette surcouche Pygame, je dispose d’un outil de publication orienté graphisme, au spectre limité mais plus adapté à mes besoins et plus réactif que Tkinter.