Page 1 sur 1

Bar progressive

Publié : lun. 19/sept./2005 15:39
par Thyphoon
Bonjour

je charge parfois dans mon programme de tres gros fichier txt qui son long a chargé et a traité. Je voulais donc afficher une barre progressive graphique pour voir l'avancement seulment rien que d'afficher cette barre ralentie enormement le traitement
en gros mon code ressemble a ça

Code : Tout sélectionner

If InitSprite() = 0 Or InitPalette() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 or later", 0)
End

If OpenScreen(800, 600, 32, "Test")

  repeat
    clearscreen(0,0,0)
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Tab) 
      If ReadFile(0, "gamelist.txt")
        While Eof(0) = 0
          chaine$ = ReadString()
          ;traitement dû fichier
          ;bar de progression
          StartDrawing(ScreenOutput())
           FrontColor(100,100,100)
           Box(200,200,400,200); la fenêtre
           FrontColor(255,0,0)
           Box(200,300,Int(400*Loc()/Lof()),20); bar de progression
         stopDrawing()
      FlipBuffer()         
    Wend
      endif
    endif
   ;Bon j'affiche plein de truc a l'ecran etc...
    FlipBuffer()
  Until KeyboardPushed(#PB_Key_Escape)
endif
quelqu'un a une idée ?
j'ai essayé de simplifié au maximum mon code
Merci

Publié : lun. 19/sept./2005 15:59
par Progi1984
utilise deux threads

Publié : lun. 19/sept./2005 16:19
par Droopy
Teste les fonctions Bargraph de la Droopy Lib, ça devrait le faire

Publié : lun. 19/sept./2005 16:23
par nico
Avec Readdata, la lecture irait plus vite mais si tu veux pouvoir savoir où en est la lecture, il faudrait passer par les API.

Publié : lun. 19/sept./2005 16:27
par fweil
Dans tous les cas, il faut surtout penser à temporiser le dessin par rapport aux autres opérations.

L'utilisation d'un thread peut le permettre, ou simplement un test dans la boucle principale.

En plus dans ton exemple, tu utilises le mode screen.

Il y a plusieurs niveaux de problèmes. En particulier le FlipBuffers() va en principe bloquer le fonctionnement à 60 itérations par seconde (valeur par défaut).

Le mode screen est-il vraiment nécessaire à ton appli ?

Si tel est le cas et que tu bloques je te ferai un exemple de mode screen pouvant répondre à ce genre de situation ...

Publié : lun. 19/sept./2005 20:45
par Thyphoon
Merci a tous pour vos idées et bon conseil ! Je pense ête sur le bon chemin avec les thread et ça marche pas trop mal. Encore des petits réglages et ça devrait être bon. Je suis obligé de passé par le mode screen car mon application est prévu pour ête mis dans une borne donc pas de souris ... :o) et interface maxi simplifié !
fweil je suis pas contre ton exemple de code (si tu as le temps bien entendu)
Merci à tous

Publié : lun. 19/sept./2005 21:19
par fweil
Thyphoon,

Voici un exemple de barre de progression :

Code : Tout sélectionner

Procedure ProgressBar(x.l, y.l, width.l, height.l, percentage.f)
  DrawingMode(0)
  Box(x, y, width, height, #White)
  Box(x, y, width * percentage / 100, height, #Blue)
  DrawingMode(1)
  BackColor(0, 0, 0)
  FrontColor(255, 255, 255)
  Text.s = "Loading files ..."
  Locate((x + width - TextLength(Text)) / 2, y + height + 2)
  DrawText(Text)
EndProcedure

  ScreenWidth = GetSystemMetrics_(#SM_CXSCREEN)
  ScreenHeight = GetSystemMetrics_(#SM_CYSCREEN)
  ScreenDepth = 0
  If InitSprite() And InitMouse() And InitKeyboard()
      If ExamineScreenModes()
          While NextScreenMode()
            If ScreenModeWidth() = ScreenWidth And ScreenModeHeight() = ScreenHeight
                If ScreenModeDepth() > ScreenDepth
                    ScreenDepth = ScreenModeDepth()
                EndIf
            EndIf
          Wend
      EndIf
      If OpenScreen(ScreenWidth, ScreenHeight, ScreenDepth, "")
          Lof = 500
          Quit = #False
          Repeat
            FlipBuffers(0)
            ClearScreen(0, 0, 0)
            ;
            ; On simule un processus qui tourne d'autre part
            ;
            If Loc < Lof
                Loc + 1
                ElapsedMilliseconds = ElapsedMilliseconds()
                If ElapsedMilliseconds - OldElapsedMilliseconds => 100
                    StartDrawing(ScreenOutput())
                      ProgressBar(10, 10, 200, 20, 100 * Loc / Lof)
                    StopDrawing()
                EndIf
            EndIf
            ;
            ExamineKeyboard()
            If KeyboardPushed(#PB_Key_Escape) : Quit = #True : EndIf
            Delay(1)
          Until Quit
          CloseScreen()
      EndIf
  EndIf
End
Le principe ici est de faire appel à une procédure de dessin sans prendre le risque de de saturer le processeur.

On doit donc gérer le temps alloué au dessin.

La boucle de raffraichissement des buffers est poussée au maximum par FlipBuffers(0), mais limitée tout de même avec un Delay(1), pour éviter de saturer également (le délai peut être augmenté sur les CPU plus lentes).

Attention à bien régler les différents élements de gestion du temps, en fonction de la plate-forme de production utilisée, car les temps de réponse peuvent varier de manière significative.

Si le dessin se limite à des objets aussi simples que cette barre de progression, la charge de calcul et de transfert mémoire est faible, mais si il faut raffraichir de nombreux objets dans le dessin, on peut tomber sous les performances de la vidéo et du processeur.

Cette manière de procéder permet de gérer simplement les choses sans passer par un thred ou un callback.

Ce n'est pas la plus jolie manière de programmer, mais c'est très efficace et le code reste facile à maintenir.

Disons que pour un interface utilisateur bien structuré celà peut donner toutes satisfactions.

Publié : mar. 20/sept./2005 6:41
par Thyphoon
Merci beaucoup ! :o)
C'est un peu prêt ce que j'ai fait..sauf que moi c'était moin propre :o)
Et puis j'ai compliqué un peu la chose car l'analyse du fichier est fait via une DLL ...Mais là ça marche :o)