Un lanceur Qt pour Windows, et un assemblage partage
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Assemblage commun aux deux lanceurs (`app.py` Cocoa, `lanceur_qt.py` Qt/Windows).
|
||||
|
||||
Avant ce module, `app.py` était le SEUL endroit qui savait choisir le système,
|
||||
prendre le verrou d'instance, construire le transcripteur et l'overlay, puis
|
||||
câbler le tout dans un `ZonzaController`. Un second lanceur qui recopierait
|
||||
cette séquence créerait deux copies vouées à diverger en silence — exactement
|
||||
le défaut déjà résorbé entre `engine.py` et `systeme/macos.py` (cf journal du
|
||||
projet). Les deux lanceurs appellent donc les deux fonctions d'ici ; ce qui
|
||||
reste propre à chacun (boucle d'événements, icône de barre, menu) reste dans
|
||||
`app.py` et `lanceur_qt.py`.
|
||||
|
||||
Tout est injectable (`plateforme`, `run_on_main`...) pour rester testable sans
|
||||
jamais ouvrir de fenêtre ni de micro : la construction du transcripteur charge
|
||||
un vrai modèle, donc les tests injectent un `moteur.detecter_moteur`/
|
||||
`moteur.choisir_transcripteur` doublés plutôt que de laisser tourner le vrai.
|
||||
"""
|
||||
import os
|
||||
|
||||
import moteur
|
||||
from controller import ZonzaController
|
||||
from core import CONFIG, modele_retenu, validate_config
|
||||
from interface import classe_overlay_pour
|
||||
from systeme import choisir_systeme
|
||||
|
||||
|
||||
def acquerir_verrou(systeme, chemin_verrou=None):
|
||||
"""Prend le verrou d'instance unique ; rend le handle, ou None si pris.
|
||||
|
||||
Une seule instance à la fois : sinon deux modèles en RAM et la même
|
||||
hotkey captée deux fois (cf systeme.acquerir_verrou_instance). Le chemin
|
||||
est injectable : les tests et les essais manuels d'un lanceur doivent
|
||||
pouvoir viser un fichier qui n'est PAS celui de l'instance déjà en cours
|
||||
de l'utilisateur.
|
||||
"""
|
||||
chemin = chemin_verrou or os.path.join(systeme.dossier_donnees(), "instance.lock")
|
||||
return systeme.acquerir_verrou_instance(chemin)
|
||||
|
||||
|
||||
def construire(plateforme=None, run_on_main=None, on_state=None,
|
||||
detecter_moteur=None, choisir_transcripteur=None):
|
||||
"""Construit le système, le transcripteur, l'overlay et le contrôleur.
|
||||
|
||||
Ne prend PAS le verrou (c'est le rôle d'`acquerir_verrou`, appelée à part
|
||||
par le lanceur, qui décide seul de ce qu'il fait d'un refus). Ne valide
|
||||
la config qu'une fois, ici, pour que les deux lanceurs en bénéficient
|
||||
sans avoir à y penser.
|
||||
|
||||
`detecter_moteur`/`choisir_transcripteur` sont injectables : ils
|
||||
permettent aux tests de construire l'assemblage entier sans charger un
|
||||
vrai modèle de transcription (opération lourde, et qui échouerait sans
|
||||
matériel/poids téléchargés).
|
||||
"""
|
||||
detecter_moteur = detecter_moteur or moteur.detecter_moteur
|
||||
choisir_transcripteur = choisir_transcripteur or moteur.choisir_transcripteur
|
||||
|
||||
validate_config(CONFIG)
|
||||
systeme = choisir_systeme(plateforme)
|
||||
moteur_nom = detecter_moteur()
|
||||
transcripteur = choisir_transcripteur(
|
||||
nom=moteur_nom,
|
||||
modele=modele_retenu(moteur_nom, CONFIG["model"]),
|
||||
langue=CONFIG["language"],
|
||||
amorce=CONFIG["initial_prompt"],
|
||||
)
|
||||
overlay = classe_overlay_pour(plateforme)()
|
||||
controller = ZonzaController(
|
||||
CONFIG, overlay, transcripteur, systeme, on_state=on_state,
|
||||
run_on_main=run_on_main,
|
||||
)
|
||||
return {
|
||||
"systeme": systeme,
|
||||
"transcripteur": transcripteur,
|
||||
"overlay": overlay,
|
||||
"controller": controller,
|
||||
}
|
||||
Reference in New Issue
Block a user