Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#126 Le 16/01/2018, à 17:05

Dafyd

Re : /* Topic des codeurs [9] */

Le problème c'est qu'après des années à faire du Python, du Java (beurk) et du C++, j'ai un peu de mal à penser mon code autrement qu'en OO.

Hors ligne

#127 Le 17/01/2018, à 11:56

Dafyd

Re : /* Topic des codeurs [9] */

Salut à tous,

Quelqu’un connaîtrait une bonne ressource (livre ou net) sur le C++ moderne ? Du genre move semantic, raii, smart pointers, etc etc ? J’avoue nager un peu dans tout ca...

Merci

Hors ligne

#128 Le 19/01/2018, à 09:22

grim7reaper

Re : /* Topic des codeurs [9] */

Salut,

La plupart des bouquins de référence ont été mis à jour, donc tu peux utiliser :

Pour des trucs plus orienté C++11/C++14 il y a :

Pour des sujets plus spécifique :

Hors ligne

#129 Le 19/09/2018, à 22:04

Dafyd

Re : /* Topic des codeurs [9] */

Et ben... plus de codeurs sur ce forum ?

Hors ligne

#130 Le 19/09/2018, à 23:04

Elzen

Re : /* Topic des codeurs [9] */

J'peux continuer à poser des questions techniques autour de Touhy auxquelles personnes ne va répondre, si tu veux tongue

(Blague à part, j'ai proposé une conf' à Capitole sur Touhy et quelques uns des choix de dev que j'ai fais dessus, je tâcherai p't'être de vous exposer ça un de ces jours)

Hors ligne

#131 Le 20/09/2018, à 10:06

grim7reaper

Re : /* Topic des codeurs [9] */

Si si, on est encore là.

Hors ligne

#132 Le 23/09/2018, à 01:32

Dafyd

Re : /* Topic des codeurs [9] */

Bah moi perso, après quelques projets jamais aboutis, dans différents langages, pour différentes raisons, j'ai décidé de réfléchir à quelque chose de plus sérieux avant de me mettre à coder sans but précis et donc ne rien produire wink j'ai quelques idées !

Hors ligne

#133 Le 23/09/2018, à 06:57

Pylades

Re : /* Topic des codeurs [9] */

Encore là, mais ça fait un moment que j'ai plus eu le temps de toucher à du code…


“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
                Linus Torvalds – 12 janvier 2003

Hors ligne

#134 Le 25/09/2018, à 18:32

grim7reaper

Re : /* Topic des codeurs [9] */

Ha, Pylades!
L’un des pères fondateurs du TdC

Ça prend plus de temps de débugger des humains que du C hein tongue

Hors ligne

#135 Le 26/09/2018, à 12:14

vv221

Re : /* Topic des codeurs [9] */

Dafyd a écrit :

Et ben... plus de codeurs sur ce forum ?

Bah si, mais on code, ce qui laisse peu de temps pour bavarder tongue


Jouer sur Ubuntu ? Facile !

Hors ligne

#136 Le 30/09/2018, à 21:31

The Uploader

Re : /* Topic des codeurs [9] */

Dafyd a écrit :

Et ben... plus de codeurs sur ce forum ?

Si, si !

Un exemple en C89 (toolkit MSVC, Win32 x86, Pentium II ou ultérieur requis car j'aime prendre en charge aussi les vieux coucous sous Windows XP) (j'ai pas tout écrit, c'est un fork) :

Windows Multimedia CD Audio OGG player wrapper, un wrapper pour le sous-ensemble de l'API WinMM (API héritée de l'ère Windows 3.X/9.X pour le multimédia dans Windows) concernant la lecture des musiques CD à l'aide du périphérique MCI pour les CD audio.

Permet d'avoir les musiques CD sans le CD, et de corriger souvent l'usage de l'API WinMM (le jeu ne prévoyait pas la répétition des musiques, par exemple. Ou il mettait le volume du son à 0 donc pas de musique. Ou il ne détecte pas de CD à l'aide du vrai WinMM, et n'envoie pas de commandes pour lire la musique... Bon là je modifie le comportement de l'exe du jeu avec OllyDbg pour qu'il passe outre, et pas le wrapper).

Un des derniers développements fut la prise en charge de mciSendStringA (la version ANSI et basé sur des chaînes de caractères de mciSendCommand). Au menu : reconnaissance de tokens, parsing, le tout avec les version sécurisées de strtok et consorts. Bon c'est une adaptation/modification d'un patch existant, mais ça a permis de prendre en charge les rares jeux utilisant mciSendStringA, tel que le port PC de The House of the Dead.

Ça a l'air plus suivi que les autres développements (tous arrêtés ou presque) de Ogg-Winmm sur GitHub, et ça c'est cool.
* Une star (surveillance ? Je sais toujours pas trop ce que c'est !) par juanitogan, l'auteur de plein de fan-patchs super avancées sur des jeux Sierra (de la rétro-ingénierie de dingue)
* Un premier fork de mon fork il y a quelques jours (identique pour le moment)
* Une demande de support pour le jeu DOS/Windows (deux versions sur le CD, comme ça se faisait souvent à l'époque) Ignition reçue à l'instant par mail. On dirait un autre cas rare d'un jeu développé par des gens qui se haïssent (ils utilisent mciSendString plutôt que son équivalent "binaire" mciSendCommand)

Autre exemple en Delphi 1 (un fork là aussi) :

RUNEXITW

github a écrit :

Fork of RUNEXIT (http://www.shdon.com/software/tools) for games that use an executable file which launches another executable

Description : (from http://www.shdon.com/software/tools)

"A simple 16-bit Windows utility intended to run a single application and immediately closing down Windows after that application quits. For example, the command win c:\runexit\runexit.exe notepad would start Windows 3.1 with Notepad open and return to the DOS prompt when Notepad is closed."

How to modify it:

    Get Windows 3.11 inside DOSBox : http://www.vogons.org/viewtopic.php?t=9405
    Install Borland Delphi 1 : https://winworldpc.com/product/delphi
    Clone source
    ??? profit!

Contexte :
Quand on automatise un jeu Windows 3 (qui peut être 16 bit, ou 32 bit à l'aide de Win32s), on veut pouvoir 1.le lancer, 2.Quitter Windows dès que jeu a fini (ce qui ferme DOSBox). Or, pas mal de jeux utilise un exécutable qui ne fait que lancer un autre exécutable avant de quitter. Il faut alors changer de stratégie : 1.Lancer l'exe, 2.Chercher une fenêtre, 3.Attendre que la fenêtre ne soit plus avant de quitter Windows.

Bon rien de super compliqué, à part se taper Delphi 1, l' "IDE" qui va avec, le tout dans DOSBox, et le peu de l'API Win16 auquel on a accès pour atteindre l'objectif (seule route : D'abord ShellExecute, ensuite WindowFromPoint, IsWIndow, ExitWindows, et puis c'est tout)

Dernier exemple (Win32s, C89, Microsoft VIsual C++ 4.1 de juin 1996) :

J'avais appelé ce projet "RUNCOLD". 30 lignes de code tout mouillé, mais chaque ligne n'est pas là sans raison. C'est intégré à la version automatique de Donald In Cold Shadow, apparue hier avec la fiche.
Adapté quelque peu plus tard pour la version automatique de The Amazon Trail

En gros :
- J'avais besoin que le jeu s'exécute dès le départ en plein-écran. Impossible de le modifier avec OllyDbg, car le jeu utilise une bibliothèque qui utilise des API non-documentées du kernel Windows 3.X/9.X (le jeu est compatible Windows 3.X et 95/98 et cible ces deux versions de Windows) pour remplacer entièrement GDI, chose qui d'ailleurs ne fonctionne pas sur d'autres Windows. Enfin, modifier le jeu pour le mettre en plein-écran via ce biais était pas impossible, mais ça plantait...
- On est en 32 bit car j'avais besoin d'utiliser PostMessageA, et même si sous Windows 3.X tout se passe dans le même espace d'adressage, ça ne permet pas d'aller poster un message sur la boucle des appels d'une fenêtre Win32 depuis une application Win16. Donc impossible d'adapter RUNEXITW. Apparemment, le thunking ça ne marche que dans un sens (code 32 bit vers code 16 bit), ou quelque chose comme ça. En tout cas, rien n'y faisait.
- On s'exécute là aussi dans DOSBox + Windows 3.11, mais on est 32 bit grâce à Win32s
- Microsoft Visual C++ 4.1 (même pas l'antédiluvien MSVC++ 6 !) est le dernier IDE de MS à prendre en charge Win32s. Fonctionne toujours parfaitement sous Windows 10 ! Pour la gestion des sources (perdues depuis), j'utilisais tout de même git.

- Processus du programme :
* CreateProcessA (avec chemin en dur, car dans l'environnement émulé, ce sera toujours C:\DISNEY\CLDSHADW\CLDSHADW.EXE le chemin. Gestion des strings en C évité. tongue )
* WaitForInputIdle (on attend que la fenêtre existe, et soit prête à recevoir des messages)
* FindWindow (recherche de la fenêtre du jeu à l'aide de sa classe spécifique. Pas moyen d'avoir la mauvaise fenêtre, dans l'environnement émulé, à part le gestionnaire de programmes, seul le jeu a une fenêtre. Nom de la classe définie par le jeu découverte grâce à OllyDbg)
* SetForegroundWindow (on la met au premier plan)
* SetActiveWindow (pour pouvoir la rendre active)
* PostMessageA (pour pouvoir lui envoyer un message, simulant l'usage de l'entrée Fullscreen du menu Screen). Cet entrée porte un ID. Il est interne, mais a été découvert grâce à Resource Hacker, le dialogue décrivant les menus de la fenêtre étant une ressource de l'exécutable)
* On attend que la fenêtre n'existe plus avant de quitter (polling avec FindWindow + Sleep. Il est recommandé d’utiliser plutôt WaitForSingleObject, mais ça n'a jamais voulu fonctionner).

Pour déboguer ça, il faut lancer DOSBox, Windows 3.11, et lancer notre programme depuis DOSBox. C'est pas instantané, et la moindre erreur résulte en une General Protection Fault ou autre message inexploitable. big_smile

Alors y'a une modif de l'exe du jeu sur Old-Games.Ru pour qu'il utilise autrement WinDirect (la bibliothèque qui remplace GDI) et s'exécute nativement. Mais on perd le mode plein-écran, et le jeu s'exécute toujours par défaut dans une toute petite fenêtre en 320x200. Au mieux en 640x400 en allant dans le menu Screen. Sur un écran HD, c'est pas très lisible.

En gardant DOSBox, on garde la compatibilité avec les manettes modernes (important pour un jeu de plateformes), la possibilité d'utiliser des scalers (HQ2X, HQ3X, Super2xSAI ...), la pérennité de la solution quel que soit la variante de Windows, et le mode plein-écran. On peut aussi utiliser une variante de DOSBox pour Linux, OS/2, ou autre. Et WinDirect peut toujours remplacer GDI avec ses appels à des fonctions non-documentées du kernel Windows de l'ère 16 bit s'il veut.

Le jeu est maintenant en plein-écran dans l'émulateur, comme les versions SNES ou Megadrive, au lieu d'être dans une fenêtre en 320x200 dans la fenêtre par défaut en 640x480 de DOSBox. Non mais oh ! Et les commits sur le SVN de DOSBox évoque la prise en charge des écrans HiDPI...

Le mode plein-écran est aussi le seul mode du jeu où le scrolling est parfait (pas de déchirures lors des mouvements). Là encore, comme sur les versions console. Et au contraire des versions console, le port PC bénéficie de musiques CD.

Enfin, tout ça, c'est pour les versions automatiques d'Abandonware France, auxquelles je participe beaucoup depuis des années.

Rien de super compliqué (j'en suis pas encore à écrire mon propre wrapper DirectDraw/Glide/OpenGl/Direct3D - et heureusement pour mes cheveux ! -, pour ça je m'appuie sur ddrawCompat ou dgVoodoo2, voire l'Application Compatibility Toolkit qui permet d'activer des shims avancées du genre ForceDirectDrawEmulation), mais je m'amuse beaucoup.

Et sinon, DOSBox v0.75 va sortir ! (la v0.74 a 8 ans déjà !) \o/

Voilà, je retourne dans ma grotte.

Dernière modification par The Uploader (Le 01/10/2018, à 08:57)


- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10

Hors ligne

#137 Le 02/10/2018, à 09:10

grim7reaper

Re : /* Topic des codeurs [9] */

@The Uploader: toujours aussi fan de DOS apparemment smile

Hors ligne

#138 Le 13/12/2019, à 16:36

Elzen

Re : /* Topic des codeurs [9] */

yikes Tiens, au fait, j'en ai causé sur Debian-Facile, mais pas ici…

Je viens pour le fun de commencer un script Python visant à permettre d'afficher tout et n'importe quoi dans un terminal.
(Pour les gens qui se rappellent du CLFB, j'envisage d'en coder un, et d'utiliser ce truc comme visualiseur par défaut dedans)

Pour l'instant, ça sait lire depuis :
– Un fichier sur le disque,
– Un lien http(s) ou ftp,
– Un presse-papier,
– L'entrée standard (si aucune adresse n'a été indiquée)
que le fichier soit à plat, ou (à condition que les exécutables correspondants soient présents) {g,b,x}zippé.

Et ça sait afficher :
– Le contenu d'un répertoire,
– Un fichier texte brut (ou n'importe quoi qui puisse être lu comme du texte brut),
– Tous les formats d'images supportés par PIL, plus le SVG,
– Une page HTML qui sera dûment formatée.
À terme, ce serait pas mal que ça gère des trucs du genre mettre la coloration syntaxique sur du code, afficher correctement le contenu (texte et pièces jointes) d'un mail, rendre un PDF de façon pas trop trop moche, afficher un beau calendrier pour un fichier ICS, lister voire afficher le contenu des fichiers d'une archive, etc.

Dépendances requises (sous Debian/Ubuntu, débrouillez-vous sinon) :
– python3-magic (identifier les contenus, seule dépendance requise par tout le programme),
– python3-pil (lire les images, tous formats)
– python3-cairosvg (supplément pour lire les SVG)
– python3-bs4 et python3-cssutils (parser le HTML)
– python3-xlib (lire depuis un presse-papier)
À part magic, s'il en manque une, le bout de code correspondant sera simplement désactivé, le reste marchera.

Options disponibles :
– « background=COULEUR » : indique au programme la couleur de fond du terminal (pour la transparence),
– « lines=X », « columns=X » : force la taille, utile notamment pour les images quand la sortie standard est redirigée,
– « prompt=X » : indique le nombre de lignes dans le prompt, pour réduire la hauteur dispo si besoin.
– « shuffle » : affiche les fichiers demandés dans le désordre (ça peut être fun pour afficher plein d'images)
– « (no-)format » : force l'utilisation ou pas des couleurs et assimilées (par défaut, c'est coloré ssi pas redirigé)
– « graphlib=xlib » : force la bibliothèque utilisée pour le presse-papier. Il n'y a que le code utilisant la XLib dans ce git-ci.
– « pager=PAGER » : choisit le format de sortie. Trois valeurs pour PAGER sont disponibles actuellement :
        – « none » (par défaut si redirigé) : les fichiers sont affichés à plat les uns à la suite des autres.
        – « wait » (par défaut si pas redirigé) : attend que l'utilisateur demande à passer à la suite entre chaque fichier.
        – « less » : utilise le programme du même nom pour afficher le contenu de chaque fichier de façon scrollable.
J'envisagerais bien d'en ajouter un de plus qui permette d'afficher sur la sortie standard si le nombre de lignes est inférieur à la taille du terminal et de passer sur less dans le cas contraire, mais ça m'embête un peu parce que l'action attendue pour passer d'un fichier à l'autre ne serait du coup pas forcément toujours la même, donc pas glop niveau cohérence…

En plus de ça, on peut préciser ce qu'on veut afficher exactement du fichier, en terminant son adresse par « [MACHIN] ».
Le MACHIN en question variant selon le type de fichier, sont actuellement gérés :
– « raw » : affiche le contenu brut du fichier (donc le code XML plutôt que le rendu si c'est du SVG/HTML),
– « metadata » : affiche les métadonées disponibles pour ce fichier,
– « text » : pour du HTML, affiche le contenu rendu d'après les CSS de base,
– « full » : pour du HTML, affiche le contenu en lisant les infos de style fournies,
– « links » : pour du HTML, affiche la liste des liens contenus dans le fichier.
– Pour un presse-papier, on peut préciser une cible spécifique à lire dedans.
Bien sûr, on peut afficher plusieurs contenus d'un coup avec « [MACHIN1:MACHIN2:MACHIN3] ».
Pour afficher un contenu particulier d'un autre contenu (par exemple, les liens d'un texte HTML lu depuis le presse-papier, ou bien à terme le code XML d'un SVG présent en pièce-jointe d'un mail, ou autres de ce style), on fait « [MACHIN#SOUS-MACHIN] ».

Le git est là :

git clone git://fadrienn.irlnc.org/elzapps/show

Et juste pour le plaisir, deux petites images de l'Orient Express, l'une étant l'image d'origine, l'autre celle rendue par le script :
1576173760.png 1576173798.png

Voilà voilà smile
Tout(e) retour/suggestion/coup de main bienvenu(e) !

Hors ligne

#139 Le 23/12/2019, à 00:11

grim7reaper

Re : /* Topic des codeurs [9] */

Impressionnant!
Ça me fait un peu penser à tycat de Terminology, le terminal de Enlightenment.

Hors ligne

#140 Le 12/01/2020, à 22:20

Dafyd

Re : /* Topic des codeurs [9] */

Très beau projet ! Et sinon Elzen, où en est Touhy ? A mon souvenir c’était du beau travail et ça marchait pas mal du tout, tu as avancé dessus ?

Dernière modification par Dafyd (Le 12/01/2020, à 23:58)

Hors ligne

#141 Le 17/01/2020, à 19:31

Elzen

Re : /* Topic des codeurs [9] */

Merci smile

Concernant Touhy, j'ai… beaucoup reculé, mais c'est pour mieux avancer ensuite smile

Actuellement, j'utilise sur mon poste perso une version intermédiaire loin d'être complète, mais assez utilisable pour que je puisse m'occuper tranquillement du reste. À ma connaissance, il n'y en a pas de version qui tourne ailleurs (et les dépôts git sur mon serveur sont notoirement à la bourre sur ma version locale).

J'ai énormément cogité sur la structure du projet, perdu pas mal de temps à repartir plus ou moins de zéro (enfin, façon de parler, avec quand même de très gros copiers collers un peu réadaptés d'un morceau sur l'autre) plusieurs fois (l'état actuel de show sur le dépôt est par exemple basé sur l'avant-dernière version, mais j'ai encore rechangé pas mal depuis), mais je pense être arrivé sur une structure qui me plaît bien (m'enfin comme c'est aussi ce que je me suis dit les deux-trois dernières fois, c'est sans garantie :-°)

D'ailleurs, vu que tu me poses la question et qu'après tout ce topic sert à ça, je vais poser ici tout ce qui me passe par la tête comme choix d'implem, comme ça vous pourrez me donner votre avis et râler sur tout ce qui ne va pas smile

Alors, d'abord, l'idée générale: le but est de pouvoir faire facilement des logiciels indépendants les uns des autres, mais qui vont pouvoir bien s'intégrer ensemble, et qui vont avoir le moins possibles de dépendance à une bibliothèque graphique en particulier (pour que le jour où je trouve quelque chose qui me va mieux que GTK, je puisse changer avec le moins de recodage possible).

Pour ça, chaque appli est dans son dépôt propre, contenant deux répertoires de base, « nom_de_lappli » contenant son code spécifique, et un répertoire « elzlibs » contenant autant de code commun que possible, ainsi que quelques  répertoires supplémentaires « _elzlibs_gtk3 », « _nom_de_lappli_xlib », etc, contenant le code spécifique à une bibli graphique en particulier. J'ai un dépôt principal qui contient le code commun et permet de tout synchroniser et de tout installer au même endroit (avec un petit script shell qui, à grand coup de greps sur le répertoire d'une appli, va faire des liens physiques dans le dépôt de ladite appli pour qu'elle ait les fichiers du code commun dont elle a besoin, et seulement ceux-là).

Le cœur commun de la elzlibs, c'est trois fichiers et deux dossiers :

  • utils.py contient plein de machins pour me rendre le codage python plus facile, par exemple des décorateurs pour ajouter des fonctions génériques aux classes, tout ça)

  • calls.py contient toute la mécanique pour avoir un fonctionnement événementiel et multithreadé de façon transparente,

  • shared.py contient les fonctions de base pour récupérer les contenus et surveiller les modifications de fichiers, et pour communiquer via des sockets.

  • types/ contient un ensemble de fonctions pour parser tout et n'importe quoi, que ce soit sur les types de base (tu peux mettre des numéros en chiffres romains dans les fichiers de conf' si ça t'amuse, ça passera) et quelques types supplémentaires utiles (couleurs, polices, etc.)

  • config/ contient de quoi lire les différents fichiers de configuration. J'utilise principalement un format INI un peu étendu, le principe est que tu définis dans ton code quelle structure tu attends dans les fichiers de conf', et ensuite, ça surveille tout seul les modifs que tu fais, et ça peut complètement t'auto-générer une popup pour configurer le programme.
    (Le répertoire de configuration contient aussi les autres formats de fichiers de conf' lus, à savoir, pour le moment, les fichiers d'internationalisation (INI-based aussi mais plus spécialisés), les menus, et les thèmes d'icônes, je n'exclue pas de rajouter d'autres choses ensuite)

En plus de ça, donc, j'ai quelques bibliothèques supplémentaires pas-systématiquement-utilisées-mais-presque que je vais détailler un peu plus :

  • daemon.py contient la mécanique pour avoir une appli unique facilement.
    Le principe est ici que quand tu lances une commande, ça contacte un daemon à l'arrière-plan (en le lançant s'il ne tourne pas déjà), qui s'occupe de tout, mais tout les retours qu'il fait sur les sorties standard et d'erreur sont dupliquées en sortie de ton programme de base. De cette façon, tu peux avoir un comportement cohérent si tu scriptes quelque chose avec une de mes applis⁽¹⁾.
    Pour ça, le daemon crée un fichier socket sur le disque, et les autres instances du programme n'ont qu'à s'y connecter : à la connexion, le daemon récupère les arguments/PWD/environnement du programme se connectant et peut donc les traiter comme si c'était les siens, et utilise la socket pour balancer les retours à afficher pour l'instance appelante.

  • images/ contient la mécanique pour charger/modifier/afficher des images.
    Gère le chargement/la modif d'images avec plusieurs bibliothèques différentes (présentement, je peux utiliser cairo.ImageSurface, Gdk.Pixbuf, et j'ai commencé à ajouter un support pour PIL.Image). Le principe est que tu indiques l'image que tu veux à partir d'une description, par exemple une de celles-ci :

    #file(render):/mon/fichier.svg
    #negative:#theme(gnome-dust):#icon(folder)
    #widget(button):#text:Texte
    #empty
    #clock(2:10)

    et la bibliothèque se débrouille pour te sortir l'image le plus simplement possible à la taille et au format demandé (je suis assez content de moi là-dessus, même s'il reste vraisemblablement des trucs à corriger dedans). J'ai un code commun de pas mal de fonctions de base sur les images (charger depuis un fichier, tourner, colorer, etc.), ainsi qu'un mécanisme de partage, les applis fournissant des images spécifiques ouvrant une socket pour permettre à d'autres de les leur demander.

  • entities/ contient le mécanisme central pour l'intéropérabilité des applis de Touhy : les entités.
    Une entité, c'est à peu près tout et n'importe quoi pourvu que ça ait un nom et une icône, et qu'on puisse éventuellement lui demander gentiment de faire des choses. Ça peut être aussi bien du matériel (batterie, carte son, manettes de jeu…), des éléments de l'environnement (fenêtres, processus, presse-papiers…), ou que ce que vont gérer mes logiciels (fichier en cours d'édition, morceau en train d'être joué…)
    Le principe est que toutes les entités vont être posées au même endroit, et que chaque appli va ensuite pouvoir aller chercher celles dont il a besoin pour te les afficher (si tu veux l'indicateur d'état de la batterie et l'horloge dans la barre d'outil de ton lecteur média, par exemple, bah ça se configure super-simplement).
    Pour cette version (c'est le dernier truc que j'ai modifié dans la structure générale), chaque entité est représentée par un répertoire sur le disque, contenant conventionnellement un fichier « status » (fichier plat contenant les informations si ça risque de ne pas bouger souvent, socket s'il risque d'y avoir besoin d'un suivi plus actif), des fichiers « {16,24,32,48}.png » contenant des cache de l'icône actuelle (pour les éventuelles applis n'ayant pas ma bibli de chargement d'images), et éventuellement une socket « request » permettant d'envoyer des demandes (pour demander à régler le volume audio, ou à une fenêtre de se maximiser, ou autre). Ainsi éventuellement que quelques fichiers supplémentaires pour certains types d'entitiés précis (le principe est que l'utilisation simple peut se faire directement, mais que certains trucs en plus peuvent utiliser du code supplémentaires, par exemple la bibli pour les entités presse-papier permet de rajouter au module shared.py le code qui va bien pour lire/écrire dans le presse-papier de façon aussi transparente que dans les fichiers).

Tous les fichiers créés par ces trois biblis sont placés par défaut dans le répertoire /tmp/elzapps-$USER/, vu qu'il s'agit de pas mal de fichiers volatiles et pas volumineux, il est recommandé que ce soit un tmpfs (en fait, dans l'idéal, j'aimerais bien en faire un filesystem spécifique comme le /proc, mais bon, c'est un poil trop ambitieux pour moi pour l'instant big_smile)
Les répertoires _elzlibs_gtk3 et _elzlibs_xlib (ce dernier étant évidemment beaucoup plus incomplet, tout coup de main pour remplir celui-là un peu plus ou pour en ajouter d'autres pour d'autres biblis graphiques sera le bienvenu ^^) suivent grosso-modo la même structure : en fait, j'utilise un décorateur spécial, @graphical, faisant qu'une fonction donnée va, au premier lancement, être automatiquement remplacée par son équivalent dans l'une des bibliothèques graphiques activées dans la conf', s'il y en a une.
Comme ça, de manière transparente, des trucs « simples » comme le suivi des fenêtres, le presse-papier, etc., utilisent le code directement intégré à la bibli graphique utilisée s'il est dispo, et sinon se rabattent sur l'équivalent fourni par les entités.

Pour le moment (je m'y suis remis il n'y a pas longtemps), je bosse sur sencol (sensors collection), qui est une appli chargée de faire la compatibilité entre les fonctions classiques du systèmes et mon mécanisme d'entités. Le principe est que pour chaque entité désirée parmi les trucs dont ce serait con d'intégrer du code spécifique dans toutes les applis (comme la batterie, la gestion du volume, tout ça), j'ai un bout de code avec ses dépendances spécifiques qui me génère une entité, et comme ça je peux laisser sencol tourner en arrière-plan et le reste des applis n'auront plus qu'à utiliser ça s'il y a besoin (d'ailleurs, il y a enfin une version de python-wicd compatible Python 3 dans le dépôt expérimental de Debian, donc j'ai enfin pu arrêter de coder cette appli-là en Python 2 ^^ C'était plus ou moins la dernière à y être coincée).
Ensuite, les deux premières applis que je recoderai seront sans doute gemetic (le gestionnaire de bureau, donc ce qu'on voit principalement sur les captures d'écran), et midote, le lecteur media, parce que j'ai du code frais à adapter et que ce ne sera pas trop long, et puis ça me permet de poser les briques qui manquent pour la suite. Notamment le système de fenêtres : le principe est que le code pour les fenêtres (barres d'outils, menus, etc.) peut être fait de façon complètement générique, et qu'il n'y aura donc, pour la partie graphique spécifique d'une appli donnée, qu'à coder le widget chargé d'afficher une entité donnée (lequel peut d'ailleurs parfaitement ensuite être intégrée dans une autre appli avec un petit coup d'XEmbed).

Voilà, je pense que ça fait beaucoup trop d'infos par rapport à ce que tu demandais, mais vu où j'en suis, je suis preneur sur tout retour sur la structure générale, donc n'hésitez pas smile (Et s'il y a des trucs pas clairs, demandez-moi de préciser, c'est le premier semblant de doc' que je rédige sur le sujet)

(1) Un truc qui m'embête, avec les applis « uniques » classiques, c'est que tu ne peux pas lancer une action, par exemple éditer graphiquement un fichier donné ou lire un morceau particulier dans la playlist, attendre que cette action-là se termine, puis reprendre la main : soit l'appli tournait déjà et tu reprends la main avant que ce soit fait, soit tu ne récupéreras la main qu'une fois qu'elle aura tout terminé et pas seulement ton action, donc si tu relances autre chose entre temps ça bloque ton script aussi.
Le principe chez moi est que par défaut, ça ne bloque jamais, mais, chaque fois que ça aura du sens, je rajouterai une option --wait qui permet de bloquer jusqu'à ce que le daemon est terminé l'action demandée et uniquement celle-la.

Edit : bah tiens, pour que vous puissiez vous faire une idée et parce qu'au bout d'un moment il faut commencer à poser des trucs, je vous ai mis ça là :

git clone git://fadrienn.irlnc.org/elzapps/sencol

Pour l'instant, il manque le code pour la config graphique, donc le truc risque fort de planter au démarrage (puisque quand rien n'est configuré, il est censé demander à l'utilisateur d'activer sa conf favorite…), mais ça moins ça vous permet d'aller jeter un œil à tout ce que je raconte ci-dessus. Et je tâche de faire en sorte que ça devienne utilisable d'ici peu, pour les gens qui voudraient tester pour de vrai ^^)

Edit bis : bon, ça y est, j'ai quand même rectifié les énormes machins qui n'allaient pas hier soir ^^
Donc, j'ai restauré l'outil de configuration automatique de GTK 3. Tout n'est pas encore fini dedans (par exemple, si vous activez la gestion des manettes, la configuration de celles-ci doit encore être faite dans le fichier de conf'), mais ça peut déjà vous donner une meilleure idée de ce que c'est censé donner smile

Le sencol présent dans le dépôt contient donc maintenant deux capteurs utilisables : le suivi des manettes de jeu avec SFML, et le suivi du presse-papier avec GTK 3 (et aussi un peu d'XLib, puisque certains bindings manquent dans GTK 3). En revanche, il semble que ce dernier ait quelques petits soucis (il arrive de manière aléatoire des erreurs X et des segfaults dont je n'ai pas encore trouvé la cause), donc je déconseille son utilisation pour le moment, d'autant que les presse-papiers sont des entités que toute appli graphique est capable de gérer directement. M'enfin, ça fait déjà ça pour voir à quoi ressemble le projet, et je suis déjà en train de rajouter les capteurs supplémentaires.

Donc, tous retours bienvenus sur tout ça smile Merci !

Dernière modification par Elzen (Le 18/01/2020, à 16:06)

Hors ligne

#142 Le 23/01/2020, à 18:14

Elzen

Re : /* Topic des codeurs [9] */

Bon, je double-poste vu que personne n'a répondu tongue

Finalement, je me suis attaqué tout de suite à midote, qui était plus sympa que sencol à coder et qui surtout permet de PoCer à peu près tout ce qu'il y a de chouette dans ma bibli, donc voilà. Comme je n'ai pas encore eu la foi de rédiger un readme en anglais, voici un petit briefing de ce qu'il y a à savoir dessus, pour le cas où des gens voudraient y jeter un œil.

D'abord, le dépôt pour tester ça est là :

git clone git://fadrienn.irlnc.org/elzapps/midote

L'organisation globale du fonctionnement est à peu près la même que celle décrite ci-dessus (j'ai quand même ajusté quelques bricoles, par exemple, je favorise /dev/shm plutôt que /tmp pour fiche les sockets et le reste, dans la mesure où il s'agit forcément d'un tmpfs s'il est présent). Mais la grosse différence, c'est que midote a besoin de fenêtres, donc j'ai ajouté ça smile
Comme précisé dans le message d'avant, j'utilise un bon coup d'XEmbed pour faciliter l'éventuelle intégration à d'autres applis (et je trouve que ça permet une façon de coder cool, au passage). Le principe, c'est qu'une appli qui va pouvoir gérer du contenu graphique pour un composant particulier va créer une socket pour se signaler.
L'appli qui veut afficher du contenu graphique va donc ouvrir une fenêtre en lui indiquant l'entité à afficher et le type de contenu désiré, et cette fenêtre envoie un message à la socket concernée en précisant l'identifiant de cette entité et l'XID où s'intégrer, et paf !, ça marche.
La partie extérieure des fenêtres (barres d'outils…) est donc totalement générique (et configurable, même si ce n'est pas intégré à mon outil de configuration auto pour l'instant, 'faut que j'y travaille…) : elle manipule une entité comme n'importe quelle autre, tandis que le contenu est possiblement géré par une autre appli.

Donc, là, dans mes biblis communes, j'ai rajouté une entité « media » qui permet de jouer un fichier audio (voire vidéo si possible). N'importe quelle appli peut donc utiliser ça, et midote pourra le prendre en charge.
Midote elle-même utilise cette entitié pour jouer du son, mais peut aussi servir à contrôler d'autres sortes de lecteurs médias pour peu qu'on lui ajoute la couche de compatibilité adéquate. Par exemple, en l'état, ça intègre une gestion MPD, je compte en rajouter plus tard pour les différents lecteurs média contrôlables via DBus.

Une fenêtre de midote peut fournir deux vues : un affichage (où va se mettre une vidéo s'il y en a une, sinon ça reste noir par défaut, mais on peut le configurer pour que ça affiche un écran de veille XScreenSaver pour avoir quelque chose à regarder), toujours présent, et, pour les lecteurs pour lesquels c'est possible, une liste de lecture éditable (La possibilité de visualiser/modifier la liste de lecture est fournie pour les lecteurs locaux et pour les clients MPD, pas pour les entités gérées par d'autres applis).
Par contre, GTK n'a pas l'air très content de ma façon de l'utiliser, je ne sais pas si c'est le fait de passer par XEmbed ou bien parce que je le fais tourner dans un thread à part plutôt que de laisser prendre la main sur l'ensemble du truc, mais j'ai des clignotements étranges pendant le scroll et des messages d'erreurs moches en sortie console, et parfois des segfaults ou autres erreurs cryptiques qui ferment le programme d'un coup -_- Ces dernières sont rares, heureusement, mais si quelqu'un veut m'aider à résoudre ça, ce sera avec plaisir.

Bien sûr, on peut aussi contrôler l'appli en ligne de commande. Les options (en vrac et dans le désordre) sont les suivantes :

  • --quit ferme le programme

  • --daemon force le fait de tourner au premier plan

  • --player=X où X est soit « new », soit le numéro de l'entité media à sélectionner, qui permet évidemment de choisir ce qu'on va contrôler. En cas de création d'un nouveau lecteur, midote en profite pour nettoyer ceux qui n'ont plus l'air de servir.

  • --wait force le processus à attendre jusqu'à ce que la lecture se soit arrêtée (stop, pas seulement pause), même si c'est une autre appli qui gère la lecture.

  • --single empêche le lecteur de passer au morceau suivant (--single=False ou --no-single pour inverser)

  • --repeat fait redémarrer la lecture lorsqu'elle se termine (--repeat=False ou --no-repeat pour inverser)

  • --jump=X passe directement au morceau X de la liste de lecture.

  • --seek=X se décale à la seconde X du morceau, si le lecteur gère cette possibilité.

  • --window ouvre une nouvelle fenêtre pour le lecteur. On peut spécifier le type de fenêtre à utiliser avec --window=X, pas comme pour l'instant, il n'y a qu'un seul type de fenêtres codé…

  • --play joue le morceau, ou redémarre la lecture au début du morceau en cours s'il était déjà en train de jouer (contrairement à --seek=0, ceci devrait marcher systématiquement).

  • --stop arrête la lecture.

  • --next passe au morceau suivant.

  • --prev ou --previous passe au morceau précédent.

  • --clear efface la liste de lecture si elle est gérée.

  • --pause met le morceau en pose s'il était en train d'être joué.

  • --toggle démarre la lecture si le lecteur était arrêté ou en pause, ou met en pause si c'était en train de jouer.

  • --notify affiche une petite notification sur l'état de la lecture.

  • --configure ouvre la fenêtre de configuration.

Tout autre paramètre (éventuellement précédé par --then= pour éviter les parsages non désirés) est considéré comme un morceau supplémentaire à ajouter à la liste de lecture si celle-ci est gérable. (Notez que, en vrai, vous pouvez mettre autant de - que vous voulez, zéro compris, pour les options, mon parseur commence par les virer).

Oh, et une fonctionnalité qui pour moi participe beaucoup à l'intérêt du truc : au moment où vous lancez la lecture d'un morceau, tout autre lecteur qui était en train de jouer se met automatiquement en pause.

Pour le reste, les dépendances (en paquets .deb pour Debian ou Ubuntu, je vous laisse voir pour l'équivalent chez vous si vous utilisez autre chose) pour les gens qui auraient envie de tester ça :

  • Le daemon a besoin de python3-psutil pour lire les arguments des autres commandes (requis).

  • Le module de lecture d'images a besoin de python3-magic pour savoir comment charger les icônes (ça devrait marcher s'il n'est pas là, mais vous aurez probablement des icônes très moches un peu partout). Avoir python3-cairo est très vraisemblablement une bonne idée aussi.

  • La partie graphique en GTK (la seule codée pour l'instant, donc, mais je n'exclue pas de faire une version avec une autre bibli graphique un jour, au contraire) utilise python3-gi, avec les paquets qui vont bien pour gérer du GTK par ça.

  • La lecture de vidéos demande d'avoir en plus GStreamer, toujours accessible par le même python3-gi avec quelques paquets en plus. Notez que, théoriquement, on pourra utiliser GStreamer avec une autre bibli graphique quand même sans problème, et que si GStreamer n'est pas dispo, qu'il y ait une interface graphique ou pas, ça fallback sur une lecture basée sur la commande « play » de SOX.

  • Et enfin, pour le support MPD, il faut bien sûr le paquet python3-mpd.

Pour ce dernier, le module de configuration graphique automatique ne fonctionnant pas encore (c'est normalement le cas pour toutes les autres options de configuration, ç'pour ça que je n'ai pas tellement détaillé ici), il faut aller faire ça à la main : ça se passe dans le fichier ~/.config/elzapps/midote/mpd.cfg, qui doit ressembler à ça :

[0]
host=localhost ; Nom d'hôte. « localhost » est utilisé si pas renseigné.
port=6600 ; Numéro de port. « 6600 » est utilisé si pas renseigné.
tint=#FF0000 ; Couleur de l'icône. #0000FF si pas renseigné.
library=/home/user/Musique/ ; Emplacement de la bibliothèque.
playlists=/home/user/Musique/ ; Emplacement du répertoire de playlists.

Les deux derniers éléments sont totalement optionnels : s'ils sont présents, ils permettent d'ajouter des morceaux à la liste de lecture courante depuis la ligne de commande, et ajoutent l'option d'enregistrer la liste de lecture courante ailleurs sur le disque pour qu'elle soit lue par autre chose que MPD, mais c'est à peu près tout.
Donc, strictement parlant, tout ce dont vous avez vraiment besoin pour activer la gestion de MPD par Midote, c'est le « [0] » du début. Et si vous voulez pouvoir gérer plusieurs clients MPD avec midote, faites en sorte que ce pavé soit présent autant de fois que nécessaire, en incrémentant le numéro de la section, tout simplement.

Voilà, je crois que j'ai à peu près fait le tour de tout ce qui me venait en tête, toute question/remarque/rapport de bug/lettre d'insulte/proposition de coup de main sera la bienvenue smile

Hors ligne

#143 Le 25/01/2020, à 00:20

Dafyd

Re : /* Topic des codeurs [9] */

Navré Elzen de ne pas t'avoir encore répondu, mais ç'est du beau pavé que tu nous as pondu là big_smile, je tâcherai de relire tout cela et d'y répondre demain !

Moi, je me pose une question à laquelle je n'ai pas trouvé de réponse claire :

En C89, stdout, stderr, et globalement tous les accès à des descripteurs de fichiers de type FILE* sont-ils thread-safe ? Partout ? J'ai lu qu'en POSIX 2001 oui, mais qu'en est-il de Windows ? Des autres OS non POSIX ? Ou POSIX < 2001 ? La norme spécifie-t-elle quelque chose à ce sujet ?

Car pour le moment je passe par des mutex, comme pour malloc et free, mais c'est lourd :

#include "MDKIO.h"


void MDKIO_init(void) {
    _ioMutex = MDKMutex_new();
}

void MDKIO_clear(void) {
    MDKMutex_delete(&_ioMutex);
}

void MDKIO_puts(const char* str) {
    MDKMutex_lock(_ioMutex);

    puts(str);

    MDKMutex_unlock(_ioMutex);
}

void MDKIO_printf(const char* fmt, ...) {
    va_list args;

    MDKMutex_lock(_ioMutex);

    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);

    MDKMutex_unlock(_ioMutex);
}

void MDKIO_fputs(const char* str, FILE* stream) {
    MDKMutex_lock(_ioMutex);

    fputs(str, stream);

    MDKMutex_unlock(_ioMutex);
}

Dernière modification par Dafyd (Le 25/01/2020, à 00:23)

Hors ligne

#144 Le 25/01/2020, à 14:06

Elzen

Re : /* Topic des codeurs [9] */

Pas de souci, et oui, en effet, y a du texte big_smile

En même temps, c'est le seul bout de doc digne de ce nom existant sur ce que je fais actuellement, donc ce n'est carrément pas assez, mais bon.

Je viens de mettre à jour le dépôt de sencol pour l'adapter aux dernières modifs de la bibliothèque ; mais je n'ai pas encore eu le courage de m'attaquer à la correction de la partie XLib/presse-papier, donc il n'y a que le suivi des manettes qui est fonctionnel sur le dépôt actuellement (ce qui ne vous arrange sans doute pas à grand chose puisque l'autre bout, le code spécialisé pour utiliser les manettes en utilisant SFML si dispo et activé, sinon en utilisant les infos fournies par sencol, n'est pas intégré dans ce dépôt-ci, il faudra que je partage ça un jour).

Donc, si vous voulez regarder à quoi ressemble ce sur quoi je travaille et comment ça s'utilise, je vous conseille le dépôt de midote plus que celui de sencol pour l'instant. Mais je vais compléter ça le plus vite possible smile


Pour ta question… perso, je n'en ai pas la moindre idée, mais grim7reaper saura peut-être ça ?

(S'il y a d'autres gens qui lisent ce qui se passe ici, n'hésitez pas à vous montrer, hein ^^)

Hors ligne

#145 Le 25/01/2020, à 19:16

Dafyd

Re : /* Topic des codeurs [9] */

Je vois que tu as vachement bossé sur l'architecture de Touhy. Très impressionnant je trouve. Tout comme l'utilisation d'une lib graphique ou d'une autre selon leur présence, le fallback sur différents systèmes audios, etc.. On voit la très grande force de Python pour cet usage... En C, ce serait galère, à grand coup de dlopen... 

Je me pose quelques questions :
-> Pourquoi ne pas utiliser les git submodules pour les elzlibs ? Chaque projet aurait son code, et un sous module pointant vers le dépôt d'elzlib. Ca pourrait te simplifier la vie en terme de déploiement par exemple...

-> Pourquoi ne pas utiliser de venv python ? Ce serait pratique pour mettre en place un environnement de dev ou de prod contenant les libs dont tu as besoin, etc... Avec pip et un fichier requirements.txt. Comme ça, n'importe qui ayant python3 n'a plus qu'à faire :

git clone ton dépot
cd ton dépot
python3 -m venv venv
. venv/bin/activate
pip install -f requirements.txt

Et hop, on peut bosser sur ton projet !

Sinon, chapeau. Surtout pour la longévité du projet, moi j'en ai plein qui ont avorté au bout de 2 mois... Le machin le plus abouti que j'ai c'est ça :
https://github.com/DubrulleKevin/WidgetSFML
C'est un toolkit C++ de widgets graphiques basé sur SFML. Le but original était de gérer des widgets dans un jeu, pour les menus, etc... Mais c'est très basique, pas très bien pensé, et finalement jamais fini... Il faut SFML >= 2.3 pour le compiler.

edit : il faut checkout le commit 8be885c9787d8dc16e67adf86e031947a988daed pour tester, les versions suivantes ne marchent qu'avec Flatpak.

Dernière modification par Dafyd (Le 25/01/2020, à 19:21)

Hors ligne

#146 Le 26/01/2020, à 00:18

grim7reaper

Re : /* Topic des codeurs [9] */

ha, de l’activité!!

@Elzen : faut que je prenne le temps de lire ça au calme, mais ça semble très intéressant.

@Dafyd : les FILE* sont clairement pas thread-safe en standard (parce que jusqu’a C11 y’avait même pas la notion de thread en standard). Tu entends quoi par thread-safe d’ailleurs?
De base, même en POSIX il me semble (mais si tu as une source qui dit le contraire je veux bien regarder), si tu as plusieurs thread qui écrivent en même temps en sortie tu va avoir un truc tout mélangé.

Hors ligne

#147 Le 26/01/2020, à 00:42

Dafyd

Re : /* Topic des codeurs [9] */

Dans le cas des FILE*, ce que j’entends par thread safe c’est justement que seul un thread peut écrire ou lire ce descripteur à la fois. Donc comme je le supposais, ce n’est pas le cas.
Pour POSIX, c’est spécifié ici :
https://pubs.opengroup.org/onlinepubs/9 … kfile.html

POSIX a écrit :

All functions that reference (FILE *) objects, except those with names ending in _unlocked, shall behave as if they use flockfile() and funlockfile() internally to obtain ownership of these (FILE *) objects.

Hors ligne

#148 Le 26/01/2020, à 09:46

grim7reaper

Re : /* Topic des codeurs [9] */

Ha bah en effet, POSIX garanti que les FILE* soient thread-safe (à un certain degré : ça ne garanti que l’atomicité d’un appel, pas plus), tiens je l’ignorais.
Mais comme tu dis, ça limite la portabilité (le support POSIX de Windows était partiel la dernière fois que j’avais regardé (il y a longtemps), et je ne parle pas de l’embarqué).

Cela dit, si les plateformes que tu vises ont flockfile/funlockfile (peut-être que Windows l’a??) alors tu peux peut-être utilisé ça au lieu des mutex.

Hors ligne

#149 Le 26/01/2020, à 11:12

Dafyd

Re : /* Topic des codeurs [9] */

Je vise les systèmes UNIX (même très vieux), les UNIX like (Linux, MacOS), et Windows. Pourquoi une telle contrainte ? Pour le challenge justement, de toute façon le sort que j’écris ne sert à rien du tout, c’est simplement ludique. Donc je veux réussir à le compiler sur mes Solaris et mes AIX du boulot ^^.

Je vais regarder pour flock, car en effet, la méthode Mutex que j’utilise actuellement est très naïve, elle lock toutes les IO. C’est très nul, il ne faut locker que le FILE* concerné.

Dernière modification par Dafyd (Le 26/01/2020, à 11:23)

Hors ligne

#150 Le 26/01/2020, à 11:22

Dafyd

Re : /* Topic des codeurs [9] */

Bon manifestement flockfile date de POSIX 2001, donc on le trouve depuis belle lurette sur UNIX et Linux. Je retiens ! Et pour Windows : https://docs.microsoft.com/en-us/window … i-lockfile

Hors ligne