A tous ceux que réfléchissent à la meilleure façon de réaliser la description du réseau, je propose très humblement de regarder le principe que j’ai adopté pour faire cette description. J’en parle car j’ai moi aussi passé beaucoup, beaucoup de temps là-dessus, j’ai moi aussi passé beaucoup de temps à chercher, à regarder ce qui existait (dont le gestionnaire de Pierre). Et puis, j’ai trouvé une méthode qui est simple et surtout qui fonctionne. Alors, pourquoi ne pas la reprendre.
Je ne parle pas du processus de découverte avec les boutons et les switches dont j’ai parlé dans un autre post mais la méthode et la structure même du fichier de description. Cette structure de description qui a par ailleurs un énorme avantage pour la simplification de la programmation du gestionnaire par la suite.
Il est probable que cette méthode rencontrera un jour des limites (appareils de voies particuliers etc…) mais elle aura fonctionné pour tous les autres cas (nombreux) et je ne doute pas qu’avec de la réflexion, nous arriverons à les résoudre en temps voulu. Comme j’ai pu le dire par avant, commençons par résoudre les cas généraux avant les cas particuliers.
Je précise aussi que ce principe de description vaut tout autant pour des gestionnaires distribués comme j’ai pu le faire que pour des gestionnaires centralisés.
Il faut à la base poser un postulat qui est qu’un canton peut être relié directement à un nombre d’autres cantons que l’on fixe arbitrairement.
Ainsi, pour moi, j’ai fixé à 4 le nombre de cantons auxquels on peut accéder à horaire et le même nombre à anti-horaire. Soit 8 au total. Mais rien n’empêche de dire 10, 12, 16 ou plus. Seules apparaitront sans doute des limites de mémoire du système.
J’ai convenu de préfixer les cantons à horaires avec la lettre « p » pour plus et les cantons à anti horaire avec la lettre « m » pour moins bien sûr.
Voici comment sont nommé donc mes 8 cantons « potentiellement » voisins :
"p00":"null",
"p01":"null",
"p10":"null",
"p11":"null",
"m00":"null",
"m01":"null",
"m10":"null",
"m11":"null",
P00 désigne le canton accessible à horaire s’il n’y a pas d’aiguille ou si la ou les aiguilles sont droites
P01 (lisez cela comme des bits de droite vers la gauche), le canton accessible, 1° aiguille à horaire déviée
P10, canton accessible à horaire 1° aiguille (bit 0 à 0) droite, seconde aiguille déviée (bit 1 à 1)
Enfin P11, canton accessible à horaire 1° aiguille (bit 0 à 1) dévié, seconde aiguille déviée (bit 1 à 1)
Si j’avais choisi 6 aiguilles, j’aurais eu bien sûr une notation de type P010 par exemple qui fonctionne aussi parfaitement.
Alors, on voit écrit NULL dans le petit tableau ci-dessus extrait de mon fichier json de description. C’est parce que j’ai eu la flemme de modifier cela mais que cela va aussi aider à la compréhension de la suite.
TRES IMPORTANT : P00, P01 … P1111 et M00, M01 … M1111 sont toujours créés et « pointent » toujours sur une position constante d’un canton voisin sur le réseau. Ce canton peut exister et auquel cas, dans la programmation, P00 pointera sur une valeur non nulle ou ne pas exister, d’où un pointeur null !
On voit très bien que même si on devait le remplir à la main, il n’est pas très compliqué de renseigner un tel tableau.
Et en procédant ainsi, IL N’Y A RIEN D’AUTRE à renseigner. Les aiguilles sont par exemple créées automatiquement par le logiciel. Si P00 est non nul et P01 est non nul, le logiciel en déduit qu’il y a une aiguille. CQFD mon cher Wattson !
Et il en va de même des signaux et même des cibles à placer.
Et alors, en termes de programmation du gestionnaire maintenant, je peux vous assurer que les économies en temps de programmation et de débug sont considérables.
Les instances de ma classe Node qui représentent les satellites de cantons à l’intérieur du gestionnaire incluent un tableau de pointeurs nodePeriph.
Il s’entent que les instances sont créées elles aussi automatiquement par exemple au moment de l’import du fichier json de description.
class Node
{
private:
…
…
public:
Node();
Node *nodePeriph [nodePsize];
Aig *aig[aigSize];
Loco loco;
Sensor sensor[sensorSize];
Signal *signal[signalSize];
…
…
}
Et dans le constructeur :
for (byte i = 0; i < nodePsize; i++)
this->nodeP[i] = nullptr;
nodePsize, c'est le nombre de canton total (maximum) que l'on souhaite avoir.
C’est ensuite que l’on affecte ou non des valeurs à ces pointeurs selon que l’on ait ou non la présence de cantons.
Pour l’avoir expérimenté avec succès depuis plus de 9 mois maintenant, je vous assure que c’est redoutablement simple et puissant.
A votre disposition si vous souhaitez plus d’informations.
Christophe