IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Tronçon de programme perturbé [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut Tronçon de programme perturbé
    Bonjour à toutes et à tous,

    Dans mon programme GPS, au fur et à mesure que je me déplace (via les données du GPS ou avec la souris sur l'écran), je dois rafraichir ma carte avec de nouvelles tuiles.

    Pour ce faire, lorsque que j'arrive à un certain pourcentage du bord de la dernière tuile, je déclenche le chargement et placement de nouvelles tuiles.

    Probléme : de temps à autre, lors de ce changement, les tuiles que j'obtiens ne sont pas les bonnes, comme si un évènement s'était produit au cours de ce changement.

    Ci-après un morceau de ce que je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
      3: begin  // Diminution de la latitude
           for j:= 1 to 4 do
             BmpCarte.CanvasBGRA.CopyRect(Rect(0, DimTuile*(j-1), DimTuile*5, DimTuile*j), BmpCarte, Rect(0, DimTuile*j, DimTuile*5, DimTuile*(j+1)));
           for i:= 0 to 4 do
             with Tuile do
             begin     {Chargement d'un panel de 4 cartes de 256 x 256 pixels²}
               NomCarte:= Fch_Tuile(OSMLat+2, OSMLon+i-2, Tuile);
               if NomCarte = '' then
                 BmpCarte.CanvasBGRA.CopyRect(Rect(DimTuile*i, DimTuile*4, DimTuile*(i+1), DimTuile*5), BmpVide, Rect(0, 0, DimTuile, DimTuile))
               else
               begin
                 NomTuile:= 'Cartes'+SepRep+NomCarte+IntToStr(Zoom)+SepRep+IntToStr(OSMLon+i-2)+SepRep+IntToStr(OSMLat+2)+'.jpg';
                 if FileExists(NomTuile) then
                 begin
                   BmpTuile.LoadFromFile(NomTuile);
                   BmpCarte.CanvasBGRA.CopyRect(Rect(DimTuile*i, DimTuile*4, DimTuile*(i+1), DimTuile*5), BmpTuile, Rect(0, 0, DimTuile, DimTuile));
                 end;
               end;
             end;
           Decal.Y:= Decal.Y-256;
           Depl.Y:= Depl.Y-256;
         end;
    J'ai essayé d'y remédier avec des sections critiques (peut-être mal employées) mais cela n'a rien amélioré.

    Ce qu'il me faudrait (je pense), c'est un drapeau, une procédure, ... qui ferait en sorte que le tronçon de code que j'exécute ne soit pas perturbé, coupé par un évènement quelconque.

    Si vous avez des idées ...

    Cordialement.

    Pierre

  2. #2
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par ChPr Voir le message
    Bonjour à toutes et à tous,

    Dans mon programme GPS, au fur et à mesure que je me déplace (via les données du GPS ou avec la souris sur l'écran), je dois rafraichir ma carte avec de nouvelles tuiles.

    Pour ce faire, lorsque que j'arrive à un certain pourcentage du bord de la dernière tuile, je déclenche le chargement et placement de nouvelles tuiles.

    Probléme : de temps à autre, lors de ce changement, les tuiles que j'obtiens ne sont pas les bonnes, comme si un évènement s'était produit au cours de ce changement.

    Ci-après un morceau de ce que je fais :

    ...

    J'ai essayé d'y remédier avec des sections critiques (peut-être mal employées) mais cela n'a rien amélioré.

    Ce qu'il me faudrait (je pense), c'est un drapeau, une procédure, ... qui ferait en sorte que le tronçon de code que j'exécute ne soit pas perturbé, coupé par un évènement quelconque.

    Si vous avez des idées ...

    Cordialement.

    Pierre
    Salut, les sections critique c'est pour les thread donc le mieux serait de créer un Thread que tu lancerai au moment adéquate et qui se chargerai de charger tes tuiles en tâche de fond. Suffirait juste d'un "drapeau" pour savoir quand le processus est terminé afin de bloquer temporairement le déplacement jusqu'à une certaine limite

    A = Ancienne tuile
    N = Nouvelle Tuile (noire jusqu'à la fin du chargement)
    P = Position GPS / tuile en cours

    AANNN...
    APNNN...
    AANNN...

    A+
    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  3. #3
    Membre chevronné Avatar de der§en
    Homme Profil pro
    Bretagne
    Inscrit en
    Septembre 2005
    Messages
    1 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bretagne
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 072
    Par défaut
    J'ai exploité pour un besoin totalement personnel, un système a base de pool de Threads (sous le framework firemonkey de Delphi) qui fonctionne très bien pour afficher des fractales dans un système de tuiles (avec des niveaux de zooms):

    https://parnassus.co/a-firemonkey-cl...brot-data-set/

    Les sources son proposé, et je pense que l'on devrais pouvoir les adapter a Lazarus...

  4. #4
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 644
    Par défaut Déplacements déplacés
    Bonjour,

    La portion de code est un peu succincte mais je me demande si nous n'avons pas ici un problème de cascade. Le code est activé par un déplacement (hypothèse) et il provoque lui même un déplacement (à la fin de l'extrait). Normalement le déplacement induit a pour but de recentrer très approximativement le curseur. Mais le pas de déplacement est fixe (dimension d'une dalle), alors que se passe t'il si ce pas s'avère insuffisant ?

    Ce n'est qu'une piste mais ce genre de problème est fréquent avec les chaînes d'événements.

    Bonne chance.

  5. #5
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    J'ai placé des points de log à chaque changement de tuile et apparemment, tout se passe bien.

    J'ai observé que si je me déplace doucement, il n'y a pas de problème.

    Les problèmes semblent arriver lorsque je demande brusquement un grand déplacement.

    Il faut que j'arrive à quantifier cela en rapport à la dimension des tuiles.

    Il me semble que si j'arrivais à scinder un brusque (ou grand) déplacement de la souris en plusieurs petits pas, cela résoudrait (peut-être) le problème.

    Il faut donc que je réalise une procédure qui fasse ce découpage ...

    Cordialement.

    Pierre

  6. #6
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 644
    Par défaut Elargir
    Bonjour,

    Il est possible de voir un peu plus largement le code ? Est-ce une fonction/procédure ou un gestionnaire d'événement ? Quand il modifie la position en fin de traitement, y a t'il une vérification que le mouvement généré est suffisant pour ramener le curseur dans la zone affichée ? Que se passe-t'il si ce n'est pas le cas ?

    Salutations

  7. #7
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Citation Envoyé par Guesset Voir le message
    ... Il est possible de voir un peu plus largement le code ? ...
    Ce n'est pas que je ne veuille pas, mais le code est très long et met en jeu plusieurs unités qui, sans avoir une vue totale de l'application, reste assez incompréhensibles à moins de les décrire sur des dizaines de pages ...

    La partie que je vous ai montrée concerne le choix et le chargement des tuiles. La procédure qui est présentée ci-après est celle qui met en œuvre les déplacements.

    Cette procédure était avant dans l'évènement "OnMouseMove" Elle est maintenant déclenchée par l'évènement "OnIdle". Pourquoi ?

    Je me suis aperçu que, si on déplaçait rapidement la souris d'un point à un autre et que l'on ne bouge plus de ce dernier point, du fait de la longueur du traitement à effectuer, l'évènement "OnMouseMove" se déclenchait rapidement, pratiquement dès le début du mouvement, mais n'était plus redéclenché pour le reste de la trajectoire. De ce fait, la procédure "MonAffichageMouseMove" n'était pas mise à jour du point final ... que je ne pouvais donc atteindre.

    L'évènement OnIdle se déclenchant dès qu'il n'y a plus rien à faire, la dernière position de mon curseur est mise à jour dès ce moment ... et je peux donc l'atteindre.

    Néanmoins, ceci n'est que du détail de cuisine interne.

    Je me suis aperçu que si je scindais le parcours en petit tronçons, la fréquence de mauvais placement de tuiles était grandement diminuée (sans pour autant devenir nulle ). Dans la procédure qui suit, est présenté ce découpage.

    Toutefois, je n'ai pas réussi à mettre en évidence la cause du problème.

    NOTA : le problème est le même que je sois sur mon PC avec Windows XP ou sur mon Raspberry Pi 3B+ sous Raspbian "Stretch".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    procedure TAffCarte.Loisir(Sender: TObject; var Done: Boolean);
    {Cette procédure est déclenchée par l'évènement "OnIdle"}
    {Il semble que sur l'écran tactile 7" de mon Raspberry, les premières données de
     "OnMove" obtenues par toucher de l'écran ne soient pas correctes. Un petit
     compteur permet de ne pas les prendre en compte.}
    var
      Da, Xa, Ya: Extended;
    begin
      GetCursorPos(PosS);
      PosS:= ScreenToClient(PosS); // Position courante du curseur
      if SourisDown then
      begin
        Xa:= PosS.X*cosCap+PosS.Y*sinCap;
        Ya:= PosS.Y*cosCap-PosS.X*sinCap;
    {}   Write(Flog,IntToStr(XXX)+'   Xa  '+IntToStr(PosS.X)+'   Ya  '+IntToStr(PosS.Y));
     
        Depl.X:= (CurPos0.X-Xa)/kZoom; // Depl = déplacement de la souris en pixels
        Depl.Y:= (CurPos0.Y-Ya)/kZoom;
    {}    Write(Flog, '  Depl.X  '+IntToStr(Round(Depl.X))+'  Depl.Y  '+IntToStr(Round(Depl.Y)));
     
        Da:= Sqrt(Depl.X*Depl.X+Depl.Y*Depl.Y); // Taille du déplacement à effectuer
    {}    Write(FLog, '  Da  '+IntToStr(Round(Da)) );
        if Da > DeplMax then  // Si le déplcement est trp grand ...
        begin  // ... on le scinde en plusieurs tronçons consécutifs
          Depl.X:= Depl.X*DeplMax/Da;
          Depl.Y:= Depl.Y*DeplMax/Da;
        end;
    {}    Write(Flog, '  Depl.X  '+IntToStr(Round(Depl.X))+'  Depl.Y  '+IntToStr(Round(Depl.Y)));
        if CmptDepl > 1 then
        begin
          TotDepl.X:= TotDepl.X+Depl.X;
          TotDepl.Y:= TotDepl.Y+Depl.Y;
    {}      Write(Flog, '  TotDepl.X  '+IntToStr(Round(TotDepl.X))+'  TotDepl.Y  '+IntToStr(Round(TotDepl.Y)));
          if Da > DeplMax then  // Si déplacement tronçonné, mise à jour partielle de la position du curseur
          begin
            CurPos0.X:= CurPos0.X-Depl.X*kZoom;
            CurPos0.Y:= CurPos0.Y-Depl.Y*kZoom;
          end
          else
          begin  // sinon la position du curseur est amenée directement à la valeur finale.
            CurPos0.X:= Xa;
            CurPos0.Y:= Ya;
          end;
    {}      Write(Flog, '  CurPos0.X  '+IntToStr(Round(CurPos0.X))+'  CurPos0.Y  '+IntToStr(Round(CurPos0.Y)));
          Longitude:= LonTuileG+(DemiTuile+TotDepl.X)*(LonTuileD-LonTuileG)/DimTuile;
          if Longitude > 180 then
            Longitude:= Longitude-360
          else if Longitude < -180 then
            Longitude:= Longitude+360;
          Latitude:= LatTuileB+(DemiTuile-TotDepl.Y)*(LatTuileH-LatTuileB)/DimTuile;
          if MajAff then
          begin
            MaJ_Carte(PointF(TotDepl.X, TotDepl.Y)); // Choix et chargement des nouvelles tuiles à afficher
            clInfPos:= VGABlue;
            TxtGPS:= Choix_Aff_Coord(Latitude, Longitude, TypeCoord);
            ZoneAff.DoOnPaint; // Rafraichement de l'écran
    {}        Inc(XXX);
          end;
        end;
    {}    WriteLn(FLog);
        Inc(CmptDepl);
      end;
      Done:= True;
    end;
    Cordialement.

    Pierre.

  8. #8
    Membre Expert

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Billets dans le blog
    9
    Par défaut Tronçon de programme perturbé
    Bonjour,

    Citation Envoyé par ChPr Voir le message
    ... Dans mon programme GPS, au fur et à mesure que je me déplace (via les données du GPS ou avec la souris sur l'écran), je dois rafraichir ma carte avec de nouvelles tuiles.

    Pour ce faire, lorsque que j'arrive à un certain pourcentage du bord de la dernière tuile, je déclenche le chargement et placement de nouvelles tuiles.

    Probléme : de temps à autre, lors de ce changement, les tuiles que j'obtiens ne sont pas les bonnes, comme si un évènement s'était produit au cours de ce changement ...
    Les tuiles sont-elles prédéfinies, et de quelle manière ? Parce que si le quadrillage évoqué n'introduit pas de difficultés tant qu'on reste aux latitudes modérées, il n'en va pas de même lorsque l'on se rapproche des pôles: une partition du géoïde établie sur des angles conduit en effet à des zones de plus en plus étroites.
    Ce qui est en cause, c'est le pavage de la sphère.

  9. #9
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    ... Les tuiles sont-elles prédéfinies, et de quelle manière ? ...
    Oui, elles le sont. Elles sont au format OSM et donc, quelle que soient la latitude et la longitude, ce sont des bitmaps de 256 x 256 pixels².

    Cordialement.

    Pierre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 08/05/2010, 12h44
  2. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  3. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  4. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo