Execution d'une fonction identique de plusieurs fiche

Résolu
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 - 30 juil. 2013 à 17:47
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 6 août 2013 à 23:01
Bonjour,

J'ai construit une application MDI qui permet d'analyser un réseau CAN.
A partir d'une fiche de configuration, on peut ajouter des fiches "traces", "graphique",etc...

Toutes ces fiches ont un point commun : une procedure appelé Work exemple :

TFDataView = class(TForm)
    SG_DataView: TStringGrid;
    ...
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    ...
  private
    { Déclarations privées }
    ...
  public
    { Déclarations publiques }
    Setup : TStringList;
    Procedure ReadSetup(var ListSetup : TStringList);
    Procedure WriteSetup(var ListSetup : TStringList);
    Procedure Start;
    Procedure Stop;
    Procedure Work(var Buffer : Array of byte;var Count : integer);
  end;


J'aimerais lors de la création de la fiche récupérer un Handle, une adresse de ma fiche créé afin de pouvoir rapidement executer la fonction work.

Actuellement, j'utilise l'acces par nom est c'est trop long (en temps de traitement). j'utilise par exemple :

TFDataView(Application.FindComponent(name)).Work(Buffer,Count);

avec name contenant le nom de la fiche TDataview pour executer cette fonction work

Pour acceder à la fonction Work du TDataView.

Ca fonctionne mais comme cette fonction est appelé plusieurs fois par seconde ( toutes les 10ms environ), lorsqu'il y a une évolution de mes données contenu dans le buffer, mon programme met 2s avant d'afficher le résultat.

Mon objectif est d'optimiser le code.

Le top : au moment de la création de la nouvelle fiche, récupérer l'adresse de la fonction work de l'objet. et pour l'execution, appeler cette fonction par son adresse mémorisée dans un tableau.

Je pense que le temps perdu vient du FindComponent(name).
Si je pouvais m'en passer, je gagnerais un temps précieux.

Merci à vous tous

6 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
30 juil. 2013 à 18:43
Salut,

pourquoi pas directement avec le nom de la fiche ?

var
  MaFiche: TFDataView;
  ...

  MaFiche := TFDataView.Create(Self);
  MaFiche.Work(Buffer, Count);

1
jderf Messages postés 189 Date d'inscription mercredi 29 décembre 2004 Statut Membre Dernière intervention 2 octobre 2014 1
Modifié par jderf le 31/07/2013 à 12:12
Bonjour,

Pourquoi ne pas utiliser les TObjectList ou TcomponentList plutôt que des tableaux ?

Jean
1
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
30 juil. 2013 à 21:24
Merci pour ton aide Cirec.
En fait, je ne peux pas car je conserve les noms des objets que je créé dynamiquement dans un tableau de chaine. Pendant l'execution,le programme recoit un tableau de valeur venant de l'interface (le buffer) et ensuite, je prend mon tableau de chaine et j'execute une à une les fonction work de mes fiches ( dans l'ordre que l'utilisateur a choisi).

Donc à l'instant où je recoit des données, je connais uniquement les noms car les object que je créé sont des fiches qui sont toutes différentes (un TDataView permet de voir des valeurs particulières, un TPlot permet de tracer des courbes à partir des données recu).

Je ne sais pas s'il est possible de créer des tableaux pouvant contenir des fiches différentes. Ca me permettrais de faire par exemple :
var  F : TDataView;
begin
  F : TDataView.Create(Self);
  Tableau[i] := F;
end;

et lorsque je veux l'executer :
Tableau[i].work(buffer,nbbuffer);


Sinon, je suis en train de regarder s'il est possible de donner l'ordre à ma fiche par un SendMessage(....) d'executer work.
car il est possible de récupérer le Handle de la fiche au moment de la création.
Mais là, je ne sais pas non plus comment ca marche exactement.

Oniria

Mon site web :
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
31 juil. 2013 à 10:20
Salut Oniria,

c' est asssez simple.
Tu crées une variable de type TFDataView que tu affectes qu' une seule fois:
var
aDataView : TFDataView;

aDataView := TFDataView(Application.FindComponent(name));

Tu n' as plus qu' à appeler au bon endroit :
aDataView.Work();

a+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
31 juil. 2013 à 13:31
Mauricio, je ne peux pas faire ce que tu me dis car mes fiches sont créées dynamiquement. Je n'ai pas une seule fiche de chaque, mais l'utilisateur peut ajouter 2 fiche de "PLOT", 3 fiche "Dataview" etc...
Il faut donc que je passe par un tableau quelconque.

Jderf : je ne connaissais pas ces composants ... Merci de l'info, je vais regarder comment ils fonctionnent.

En tout cas, merci beaucoup de votre aide si précieuse.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
Modifié par f0xi le 5/08/2013 à 13:23
Je confirme l'utilisation du TObjectList voir même d'une TList surchargée pour le type TFDataView.

si tu possède Delphi à partir de D2009, tu peux faire cela en quelque lignes :

Unit (*...*);

interface 

uses (*...*), Generics.Collections;

Type
  TFDataView = class
    (*...*)
  end;

  TFDataViewList = TList<TFDataView>;

(*...*)

var
  FDataViewList = TFDataViewList;

implementation

(*...*)

initialization 
  FDataViewList := TFDataViewList.Create;
finalization
  FDataViewList.Free;
end.

que tu pourras utiliser comme cela :

ajout d'un FDataView :

FDV := TFDataView.Create((*...*));
FDV.Index := FDataViewList.Add( FDV );


suppression d'un FDataView :

FDataViewList.Delete(FDV.index);
FDV.Free;


Execution d'une méthode ou autre :

for index := 0 to FDataViewList.Count-1 do
  FDataViewList.Items[ index ].Invalidate;
0
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
6 août 2013 à 09:18
Bonjour,
Merci f0xi, je ne savais pas qu'on pouvait surcharger une liste comme ca.
Pour résoudre mon probléme, j'ai opté pour un tableau de TComponent qui me permet de supprimer tous les appels à Application.Fincomponent(..).
Je suis en train de tester (plutot debugger car le programme est très gros et pour l'instant, je supprime les bugs)mais je pense que je vais gagner pas mal de temps lorsque ce programme de m.... va fonctionner.
C'est facile de coder quelque chose mais optimiser, c'est bien plus dur. d'ailleur, je me demande s'il ne faudrait pas que j'utilise des threads pour améliorer la fluidité car ce n'est pas encore le top.

En tout cas, merci à tous car j'ai appris plein de choses.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
6 août 2013 à 23:01
Les thread ne sont pas necessaires, debug, optimises, concentre toi la dessus. les threads peuvent vite t'amener des problèmes que tu ne voulais pas.

N'hesite pas a user de progressbar pour montrer l'avancement des process et de prevenir l'utilisateur que tel ou tel action peu prendre du temps.

Un array of TComponent peut être sympa, mais reste peu souple, utilise plutot un TList de base il suffit de transtyper l'items pour y mettre n'importe quoi.
Les liste generiques sont très rapide, performance identique a des TList normales ou TObjectList, mais pas besoin de transtyper ou de s'en inquieter. C'est l'idéal pour maintenir une liste de fenetre qui vont etre créées, ouvertes, fermées, détruites, peu de risque de memory leak contrairement à un array fixe.
0
Rejoignez-nous