MCC à l’écoute d’un répertoire
15 sujets de 1 à 15 (sur un total de 15)
-
Bonjour,
Mon problème est le suivant :
Comment permettre à une classe custom MUI d’être notifiée simplement de toute modification dans en répertoire ?
Le mécanisme de notification des modifications d’un répertoire est dans la librairie DOS. Il est composé de la NotifyRequest et des fonctions StartNotify()/EndNotify().
Solutions envisagées :
1) Utiliser le handler d’événement de la classe mère Area
Mais ce handler n’est prévu que pour l’écoute de messages IntuiMessage d’Intuition et non pour l’écoute d’une NotifyRequest du DOS.
2) Mettre la classe custom à l’écoute du signal utilisé pour la NotifyRequest
Mais je ne vois pas quel moyen permet d’implémenter ce type d’écoute dans une classe custom MUI.
3) Notifier la classe custom par une méthode
Ajouter une méthode permettant à l’application de notifier la classe custom et gérer l’écoute dans l’application.
Mais l’application devient un intermédiaire inévitable.
4) Une autre solution …
Merci pour vos avis et commentaires.
Salut, j’ai toujours trouvé hallucinant le fait que les posts à tendance « flamesque » (cherchez c’est un nouveau mot qui ne sera que dans le robert version 2009 obtenaient à une vitesse proche de celle de la lumière des dizaines de réponses tandis que des posts à vocation plus sérieuse (comme le tiens ou ceux de gilloo par exemple) n’en obtiennent aucune !
Bref je te propose de poser ta question sur Guru-meditation (ha bhein tiens non ça doit plus exister) et si tu ne crains pas l’anglais va sur UtilityBase tu aura plus de chances d’avoir une réponse.
gurumed n’est pas en forme
C’est vrai que les sujets comme ceux là ont rarement de réponses : il faut la compétence, il faut prendre le temps d’investiguer éventuellement, … pourtant c’est sur ces posts qu’il faut se mobiliser si on veut que ça porte ses fruits.
Pour le problème posé, le plus simple serait à mon avis de commencer par obtenir la notification dans un programme normal qui irait appeler une méthode de la classe MUI.
Peut-être que la classe MUI pourrait créer un process qui se chargerait de ce boulot …
Il faudrait demander sur la ML MUI ou sur utilitybase …
@Alex Heureusement que toutes les questions n’ont pas de réponse… il n’y aurait plus de chercheur
@Rmais96 Je ne pratique pas les classes… mais je peux peut être t’aider avec ce qui suit:En regardant les includes dos/notify.h, intuition/intuition.h et les autodoc ad hoc,
tout s’explique facilement.
Si on compare un IntuiMessage à un NotifyMessage, on s’aperçoit que les 3 premiers
éléments nm_ExecMessage <=> ExecMessage, nm_Class <=> Class, nm_Code <=> Code sont communs.
Le reste de la structure est différente, mn_NReq est une addresse sur un NotifyRequest,
mais quelquefois on a bien une addresse dans le IAddress d’un IntuiMessage.
De plus les classes NOTIFY_CLASS=0x4000000 et code NOTIFY_CODE=0x1234 ne correspondent
pas à un IDCMP.
Alors pourquoi pas utiliser la classe NOTIFY_CLASS dans la boucle de traitement des messages IDCMP?
Petit exemple:
#include stdio.h
#include stdlib.h
#include string.h
#include dos/notify.h
#include intuition/intuition.h
#include proto/exec.h
#include proto/dos.h
#include proto/intuition.h
int main(int argc, char *argv[])
{
struct Window *w ;
struct IntuiMessage imessage, *imsg ;
struct NotifyRequest mynotifyrequest ;
BOOL loop ;
w = OpenWindowTags(NULL,
WA_Width, 400,
WA_Height, 100,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_Title, (ULONG) »StartNotify/EndNotify »,
WA_IDCMP, IDCMP_CLOSEWINDOW,
TAG_DONE) ;
if (w != NULL)
{
memset(&mynotifyrequest, 0, sizeof(mynotifyrequest)) ;
mynotifyrequest.nr_Name = « ram:filou.txt » ;
mynotifyrequest.nr_Flags = NRF_SEND_MESSAGE ;
mynotifyrequest.nr_stuff.nr_Msg.nr_Port = w->UserPort ;
StartNotify(&mynotifyrequest) ;
printf(« Start notification for « %s »n », mynotifyrequest.nr_Name) ;
loop = TRUE ;
do
{
WaitPort(w->UserPort) ;
imsg = (struct IntuiMessage*)GetMsg(w->UserPort) ;
if (imsg != NULL)
{
imessage = *imsg ;
ReplyMsg((struct Message*)imsg) ;
switch(imessage.Class)
{
case IDCMP_CLOSEWINDOW :
{
loop = FALSE ;
break ;
}
case NOTIFY_CLASS :
{
struct NotifyMessage *mynotifymessage = (struct NotifyMessage *)&imessage ;
/* Le NotifyMessage est plus petit que l’intuimessage : pas propre mais on s’en tape */
printf(« Notify !!n ») ;
if (mynotifymessage->nm_NReq != NULL)
{
printf( » Class 0x%08lxn », mynotifymessage->nm_Class) ;
printf( » Code 0x%04lxn », mynotifymessage->nm_Code) ;
printf( » Name « %s »n », mynotifymessage->nm_NReq->nr_Name) ;
printf( » FullName: »%s »n », mynotifymessage->nm_NReq->nr_FullName) ;
}
break ;
}
}
}
} while (loop) ;
printf(« End notification for « %s »n », mynotifyrequest.nr_Name) ;
EndNotify(&mynotifyrequest) ;
CloseWindow(w) ;
}
return 0 ;
}
A partir de ce petit programme, on peut créer un fichier ou un répertoire dans ram:filou.txt
On recevra une notification à chaque création/mise à jour/déplacement/suppression du fichier.
Le hic c’est que l’on s’attendrait à savoir ce que ce bougre d’utilisateur a fait avec ce fichier.
Or j’ai bien l’impression que l’on ne peut pas le savoir…
Cela doit être utile pour savoir qu’un fichier de paramètres à été modifié.
J’ai enlevé les fioritures des includes mais vous saurez bien les remettre…
A dodo et soyez sages sinon Sébastien Chabal va venir vous gronder…
Alors, un post qui ne fait que résumer…
La 1ère solution peut probablement marcher au sein d’un event handler classique avec ce qu’a écrit Gillou, bien que je trouve ça limite comme détournement, mais pourquoi pas.
La 2nde solution peut être réalisée en utilisant un sous process qui implèmenterait lui même la boucle d’attente du signal, comme l’a suggéré corto, mais c’est peut être un peu compliqué à mettre en oeuvre niveau synchronisa
La 3ème solution est évidemment très simple à réaliser mais peu adaptée pour une mcc. Pour exemple, Ambient gère le dosnotify en écoutant dans la boucle principale (entre autres) le signal associé au port sur lequel le message dosnotify est envoyé, et agit en conséquence lors de son activation.
Et sinon, il n’y a en effet pas de moyen de connaitre la nature de l’opération effectuée sur le fichier, et c’est bien regrettable. Ca pourrait être une évolution intéressante de l’API sur les OS encore développés.
Fab1 a écrit :
La 1ère solution peut probablement marcher au sein d’un event handler classique avec ce qu’a écrit Gillou, bien que je trouve ça limite comme détournement, mais pourquoi pas.
Certes, je programme comme je joue au rugby… mais si un NotifyMessage ressemble à un IntuiMessage ce n’est pas uniquement pour des pruneaux: ca sert à ça et il faut bien spécifier que l’on veut un message et pas un signal lors de la notification.
Dans ma jeunesse j’avais même réussi à détourner les messages wb avec AlohaWorkbench() dans le userport d’une fenêtre, mais ça ne fonctionne plus à partir du 2.0
Comme ça je pouvais déplacer une icône de projet dans une de mes fenêtres et afficher le fichier correspondant bien avant que windows ou OS2 ne fasse de même, huhuhu
Parfait cette émulation autour du sujet. Les limites de chaque solution se précisent et montrent que la solution n’est pas simple.
1) En effet, la ressemblance des messages soulignée par Gilloo est intéressante. Il reste a trouver comment obtenir le port utilisé par un EventHandler MUI afin d’initier l’écoute avec pour que la classe puisse recevoir la notification.
2) De prime abord un autre process pour l’écoute semble une solution séduisante. Cependant comme l’indique Fab1 la notification entre ce process et la classe MUI n’est pas évidente. Une notification par message ramènerait au cas 1 mais avec un process intermédiaire en plus. La notification par appel a une méthode de la classe paraît incertaine car la classe serait alors soumise aux accès concurrents de plusieurs process et je ne pense pas que MUI soit prévu pour cela.
3) Cette solution reste le dernier recours car elle revient à externaliser l’écoute. Elle y implique l’application qui doit jouer un rôle d’intermédiaire sans véritable plus-value.
En ce qui concerne la nature de la modification effectué sur le répertoire écouté, elle ne m’est pas vraiment nécessaire. Mais cela reste une limitation de l’OS.
En effet Feelin utilise la solution 2 avec une notification de la classe par appel à une méthode. Les classes de Feelin sont certainement prévues pour supporter les accès concurrents de plusieurs processes.
Je ne sais pas ce que cela peut donner avec MUI.
Quelqu’un a-t-il déjà tester des accès concurrents de plusieurs processes sur un objet MUI ?
Le multithreading et MUI s’entendent bien. La seule « contrainte » est d’utiliser un pushmethod pour agir sur l’objet depuis un thread. Pushmethod, dont la taille de la file est limitée.
Mais par exemple, sur ambient, je me suis amusé à faire intervenir jusqu’à 6 threads simultanés qui agissent sur les différentes colonnes des listers (icones, filetypes, md5, version, taille des répertoires, preview vidéo).
sans compter qu’avec le pushmethod le thread ne sait pas a quel moment la methode a bien ete execute, donc oblige de creer egalement dans le thread, une file d’objets a envoyer, pas moyen d’utiliser la meme carcasse a chaque envoit(et meme, on ne sait pas a quel moment on peut s’en debarrasser)
a part pour dire a une classe de s’auto-disposer je trouve le pushmethod plutot bancal et risque
le « mieu » reste encore une communication classique avec des ports et des messages et des waits partout pour synchroniser ( et gerer les mixage des messages de type synchro et de type « ordre » si on veut que ce meme thread puisse etre appele asynchronement plusieurs fois depuis le gui)
Oui, pushmethod est totalement asynchrone, mais il y a quand même moyen d’annuler une requête pushmethod (qui renvoie un id) avec un killpushmethod, avant de nettoyer. Avec MUI4, il existe de nouveaux tags, comme MUIF_PUSHMETHOD_VERIFY, MUIF_PUSHMETHOD_NOTLAGGING, MUIF_PUSHMETHOD_SINGLE, MUIV_PushMethod_Delay, dont un qui vérifie que l’object destination est toujours vivant.
Dans ambient, on a un methodstack_push[sync]() qui est bien pratique (pas limité en nb d’arguments et nombre de requêtess), et la possibilité d’avoir un comportement synchrone, donc.
Au sujet de la classe DOSNotify de Feelin :
Lorsque la classe est crée, elle créee un Thread qui sera utilisé pour recevoir les messages de notification émis par le DOS. Lorsque le thread reçoit un message, tout ce qu’il fait c’est mettre l’attribut Update de l’objet correspondant au nom du fichier/dossier en audit.
Au développeur d’ajouter la notification qui lui convient sur l’attribut de l’objet DOSNotify.
En ce qui concerne la concurrence, ce n’est que dans des cas très précis et heureusement rares qu’elle intervient. Pour bloquer une objet il suffit d’utiliser la méthode Lock et pour le libérer la méthode Unlock. C’est pas bien compliqué.
Bref, n’hésite pas à utiliser mon code, il est pas open-source pour rien
15 sujets de 1 à 15 (sur un total de 15)
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › MCC à l’écoute d’un répertoire