PureBasic

Forums PureBasic
Nous sommes le Lun 20/Mai/2013 17:49

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 5 messages ] 
Auteur Message
 Sujet du message: Question de propreté de code... et de fonctionnement
MessagePosté: Lun 05/Mar/2012 22:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 25/Aoû/2004 15:14
Messages: 376
Localisation: Grenoble
Pour mon programme domotique, je souhaite avoir une fenêtre principale avec plusieurs gadgets (de l'ordre d'une centaine) : des graphes, des champs éditables, des boutons reflétant l'état des lampes, etc.

Je veux aussi utiliser un listicongadget pour indiquer les évènements à venir (allumage de lampe à 7h, volet roulant XX à 7h15,...) et comme je veux pouvoir changer cette programmation, un double-clic sur cette liste doit faire quelque chose : idéalement, éditer le champ sélectionné (mais la programmation employée sur les différents post me rebute un peu par la complexité et surtout le risque de non-compatibilité Win/linux) ou bien ouvrir une boite de dialogue.
Là, ça devient un peu moche car soit je rajoute mes constantes dans mon encart ENUM (ça commence à faire des constantes nombreuses), soit je peux utiliser des valeurs locales à ma procédure d'édition...
Enfin, durant mon édition, je souhaite que ce ne soit pas bloquant pour l'ensemble du programme (qui effectue des relevés de température par exemple, ou stocke les messages en provenance du BUS) : comment dois-je gérer cela ?

Actuellement, j'utilise des eventtimer

Code:
            If EventID=#PB_Event_Timer
               Select EventTimer()
                  Case 100
                     WriteTempFile()
                     GraphTemp()
                  Case 101
                     VelbusBPCalc()
                  Case 102
                     ClearOldMsg(4)
               EndSelect
            EndIf


Bref, une vision du bon fonctionnement m'intéresse pour ne pas être bloquant comme en automatisme :)

Pour le moment, j'ai une procédure qui est lancée en cas de double-clic pour afficher la fenêtre d'édition (très basique) :
Code:
Procedure EditEvent(ligne)
   OpenWindow(#EE_Window,50,50,200,120,"Editer événement",#PB_Window_ScreenCentered|#PB_Window_Normal)
   StringGadget(#EE_StrHM, 100, 10, 80, 18, GetGadgetItemText(#Editor_Reveil,ligne,2))
   StringGadget(#EE_StrDay, 100, 30, 80, 18, GetGadgetItemText(#Editor_Reveil,ligne,1))
   StringGadget(#EE_StrAdr, 100, 50, 80, 18, GetGadgetItemText(#Editor_Reveil,ligne,4))
   StringGadget(#EE_StrMod, 100, 70, 80, 18, GetGadgetItemText(#Editor_Reveil,ligne,5))
   ButtonGadget(#EE_ButtonOK,70,90,80,18,"OK")
EndProcedure



Puis dans ma boucle principale, je surveille le bouton
Code:
                  Case #EE_ButtonOK
                     ligne = GetGadgetState(#Editor_Reveil)
                     SetGadgetItemText(#Editor_Reveil,ligne,GetGadgetText(#EE_StrHM),2)
                     SetGadgetItemText(#Editor_Reveil,ligne,GetGadgetText(#EE_StrDay),1)
                     SetGadgetItemText(#Editor_Reveil,ligne,GetGadgetText(#EE_StrAdr),4)
                     SetGadgetItemText(#Editor_Reveil,ligne,GetGadgetText(#EE_StrMod),5)
                     
                     CloseWindow(#EE_Window)
               EndSelect

Ca me paraît très "crade" comme structure de codage mais je ne sais pas s'il y a d'autres moyens plus d'en "l'état de l'Art" :(

Merci

_________________
Purebasic 5.00 full sous Windows XP (x86) et Win7 (64 bits), parfois Linux. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/


Haut
 Profil  
 
 Sujet du message: Re: Question de propreté de code... et de fonctionnement
MessagePosté: Mar 06/Mar/2012 1:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 21/Mai/2005 17:50
Messages: 889
oula oula !!

Dans un prog de robotique, ne pas être bloquant et rester à l'écoute de ton interface est super important. (mais je crois que tu l'as dis ^^)
Pour ce que j'avais employé avec un prog communiquant avec un automate, j'avais utilisé les threads.

Ca a peut etre l'air compliqué comme ca, mais une fois que tu as compris c'est bon.

Un thread te lance une procedure qui va tourner en parallèle avec ton prog. Il faut bien sur gérer l'arret de cette procédure et prendre quelques précaution, mais je pense que c'est une approche viable.

Pour ce que tu décris avec tout tes gadgets, franchement si t'en as vraiment une centaine, je sais pas si ton interface est viable !! Utilise peut etre la création dynamique (#PB_Any) et gère les dynamiquements .., enfin ya pas de code je vois pas trop)

je te balance un code simple qui est en thread, j'ai fait des prog plus complexe mais trop gros (ou des projets complet) pour être posté et compris simplement.

Code:
Global IS_pointille.b = #False

Procedure Pointille(bla)
   a = 0
   
   Repeat
      SetGadgetText(0, LSet("Attente ", 8 + a, "."))
      
      a + 1
      If a = 5 : a = 0 : EndIf
      
      Delay(500)
   Until IS_pointille = #True
   
   SetGadgetText(0, "Le programme est fermé")
EndProcedure

Procedure LancementProgramme(*adresse_nom_prog)
   id_prog = RunProgram(PeekS(*adresse_nom_prog), "", "", #PB_Program_Open)
   
   If id_prog
      WaitProgram(id_prog)
   EndIf
   
EndProcedure


If OpenWindow(0, 0, 0, 140, 40, "blabla", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
   TextGadget(0, 10, 10, 120, 20, "Attente")
EndIf


; lancement des pointillés d'attente
thread_pointille = CreateThread(@Pointille(), 0)

; lancement du thread de lancement du programme
; prog.s = "C:\Windows\System32\calc.exe"
prog.s = "calc.exe"
thread_program = CreateThread(@LancementProgramme(), @prog)

Repeat
   event = WaitWindowEvent(100)
   
   If IsThread(thread_program) = 0
      IS_pointille = #True
   EndIf
   
Until event = #PB_Event_CloseWindow



End


et désolé je n'ai pas le temps de te bidouiller un code plus ciblé ><

_________________
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))


Haut
 Profil  
 
 Sujet du message: Re: Question de propreté de code... et de fonctionnement
MessagePosté: Mar 06/Mar/2012 15:35 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 334
Je pense aussi qu'il faut un thread pour les mesures et affichage domotique.

Quelque chose comme ça :
Code:
Enumeration
  #Fen
  #Text1
  #Text2
  #Text3
  #image
  #imagegadget
  #Listicongadget
  EndEnumeration



Procedure Mesure_affichage(Valeur)
  ;Debug Valeur
  Repeat
    StartDrawing(ImageOutput(#image))
    Box(0, 0, 200, 200, RGB(255, 255, 255))
    StopDrawing()
   
    For Width = 1 To 180 Step 5
      StartDrawing(ImageOutput(#image))
     
      Line(10, 10, Width, 180, RGB(Random(255), Random(255), Random(255)))
     
     
      StopDrawing()
     
      SetGadgetState(#imagegadget,ImageID(#image))
      Delay(50)
    Next Width
    StartDrawing(ImageOutput(#image))
    Box(0, 0, 200, 200, RGB(255, 255, 255))
    StopDrawing()
   
    For Width = 180 To 1 Step -5
      StartDrawing(ImageOutput(#image))
     
      Line(10, 10, Width, 180, RGB(Random(255), Random(255), Random(255)))
     
      StopDrawing()
      SetGadgetState(#imagegadget,ImageID(#image))
      Delay(50)
    Next Width
  ForEver
EndProcedure

Procedure Gestion_listicongadget()
  saisie$=InputRequester("Nouveau","Entrer le nouveau texte","Entrer le nouveau texte")
  SetGadgetItemText(#Listicongadget, GetGadgetState(#Listicongadget), saisie$)
 
EndProcedure



If OpenWindow(#Fen, 0, 0, 600, 400, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateImage(#image, 200, 200)
  ImageGadget(#imagegadget, 10, 10, 200, 200, ImageID(#image))
  TextGadget(#Text1, 10, 210, 200, 60, "Ici le Thread qui fait des mesures domotiques + Affichage des mesures...")
  TextGadget(#Text2, 250,  10, 300, 20, "Evènement à venir...")
  ListIconGadget(#Listicongadget,  250,  35, 300, 170, "Colonne 1", 100)
  SetGadgetItemAttribute(#Listicongadget, #PB_Ignore,  #PB_ListIcon_ColumnWidth, 250,0)
  For i= 0 To 2          ; ajouter 4 éléments à chaque ligne des listes avec icônes
    AddGadgetItem(#Listicongadget, b, "Elément " +Str(i))
  Next i
  TextGadget(#Text3, 250,  210, 200, 60, "...Et pendant ce temps on peut changer des évènements : double-clic !")
 
  CreateThread(@Mesure_Affichage(), 100) ; Création du thread "mesure domotique et affichage"
 
  Repeat
    ;et pendant ce temps, la boucle gère le listicon (en même temps que les mesures et affichage)

    Event = WaitWindowEvent()
    If Event=#PB_Event_Gadget
      If EventGadget()=#Listicongadget
                   Select EventType()
        ;              Case #PB_EventType_LeftClick        : Debug "Clic avec le bouton gauche de la souris"
        ;              Case #PB_EventType_RightClick       : Debug "Clic avec le bouton droit de la souris"
                     Case #PB_EventType_LeftDoubleClick  : Gestion_listicongadget()
                   EndSelect
        ;Gestion_listicongadget()
      EndIf
    EndIf
   
  Until Event = #PB_Event_CloseWindow
EndIf



Mesa.


Haut
 Profil  
 
 Sujet du message: Re: Question de propreté de code... et de fonctionnement
MessagePosté: Mer 07/Mar/2012 22:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 25/Aoû/2004 15:14
Messages: 376
Localisation: Grenoble
Pour le moment, les threads ne fonctionnent pas (je dois avoir une lib qui pose problème ou bien c'est le passage 64bit/i86 qui pose problème.
Le code est ici :
http://golfy.free.fr/Velbus/Tea.pb

Les procédures Velbus (include)
http://golfy.free.fr/Velbus/Velbus_Teo-Tea.pb

_________________
Purebasic 5.00 full sous Windows XP (x86) et Win7 (64 bits), parfois Linux. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/


Haut
 Profil  
 
 Sujet du message: Re: Question de propreté de code... et de fonctionnement
MessagePosté: Mer 07/Mar/2012 23:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 21/Mai/2005 17:50
Messages: 889
quelques conseils rapide (je n'ai pas le temps de me pencher sur le code maintenant ;(- ) :
- utilise toujours le type integer .i pour les adresses et les pointeurs (passage 64/32 bits immédiat
- teste avec le paramètre "threadsafe" dans les options du compilateur
- vérifié ton code pour voir si tu n'as pas des occasions dans lesquelles une même ressource mémoire (variable, liste chainée, Array, map) est modifiée par plusieurs thread en même temps -> error memory access (et le prog principal est aussi un thread ^^)

si c'est le cas, tu peux : soit modifier ton approche en rendant les objets uniques par thread, soit bloquer l'access des ressources concernées par des mutex et sémaphore etc.. (voir aide)

Pour passer des paramètres aux threads il y a aussi des précautions à prendre (voir post suivant)
Mais pour communiquer facilement, utilise des flags globaux (une variable déclarée en global qui va te permettre de communiquer facilement entre thread)

_________________
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))


Haut
 Profil  
 
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 5 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Google [Bot] et 2 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye