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

Conversions de mesures


précédentsommairesuivant

III. Fonction Convert

C'est la fonction globale Convert qui réalise la conversion. La valeur à convertir est de type double et le résultat fourni est également de type double.

On peut faire appel à la fonction Convert dès lors que les familles et unités de mesure sont recensées.

Nous allons reprendre le premier exemple pour comprendre le fonctionnement. Rappelons que la fonction Convert est définie deux fois avec des paramètres différents (directive overload) :

Image non disponible
Figure 8

III-A. Première définition de Convert (conversion simple)

La ligne de code suivante :

 
Sélectionnez
miles := Convert(metres, duMeters, duMiles);

appelle la première définition de Convert, soit une conversion simple. Voyons le détail du code exécuté :

 
Sélectionnez
function Convert(const AValue: Double; const AFrom, ATo: TConvType): Double;
var
  LFromTypeInfo, LToTypeInfo: TConvTypeInfo;
begin
  if not GetConvInfo(AFrom, ATo, LFromTypeInfo, LToTypeInfo) then
    RaiseConversionError(SConvIncompatibleTypes2,
      [ConvTypeToDescription(AFrom),
       ConvTypeToDescription(ATo)]);
  Result := LToTypeInfo.FromCommon(LFromTypeInfo.ToCommon(AValue));
end;

On commence par un appel à GetConvInfo. On passe en paramètre le type de l'unité de mesure source (AFrom) et destination (ATo) et on obtiendra en retour les objets TConvInfo (fig. 9) respectifs (dans LFromTypeInfo et LToTypeInfo). Cela va permettre, à partir des références (nombres entiers) des unités recensées de retrouver les objets de type TConvInfo respectifs, car ce sont eux qui implémentent la conversion.

Image non disponible
Figure 9

Si GetConvInfo a réussi, alors le calcul de la conversion réside dans l'appel des méthodes FromCommon et ToCommon des objets TConvTypeInfo précédemment retrouvés.

Ce sont les méthodes de TConvTypeFactor (descendant de TConvInfo) qui sont appelées, car les types d'unités de mesure metres et miles ont été recensés avec un facteur multiplicateur (fig. 10).

Image non disponible
Figure 10

FFromTypeInfo.ToCommon(AValue) est calculé en premier, voici l'implémentation VCL :

 
Sélectionnez
function TConvTypeFactor.ToCommon(const AValue: Double): Double;
begin
  Result := AValue * FFactor;
end;

Et le résultat est ensuite passé à LToTypeInfo.FromCommon(le résultat de 3.) :

 
Sélectionnez
function TConvTypeFactor.FromCommon(const AValue: Double): Double;
begin
  Result := AValue / FFactor;
end;

Le double appel :

 
Sélectionnez
Result := LToTypeInfo.FromCommon(LFromTypeInfo.ToCommon(AValue));

correspond dans notre exemple au calcul :

 
Sélectionnez
Resultat := AValue * Facteur mètres / Facteur miles;

La VCL convertit la mesure initiale vers l'unité de mesure commune pour ensuite la convertir vers l'unité de mesure finale ce qui est logique puisque toutes les unités de mesure possèdent un facteur de conversion lié à l'unité de mesure commune.

Lors du recensement, la VCL prend connaissance du facteur de conversion entre toutes les unités de mesure recensées et l'unité de mesure commune de la même famille. FFactor est un attribut privé (accédé par la propriété Factor) qui mémorise le facteur de conversion de l'unité de mesure respective par rapport à l'unité de mesure commune (unité dont le facteur = 1).

Image non disponible
Figure 11

La fig. 11 explique comment fonctionne la VCL pour convertir une mesure vers une autre en spécifiant qu'elle passe par une étape intermédiaire : la conversion vers l'unité de mesure commune.

III-B. Deuxième définition de Convert (conversion procédurale)

Le fonctionnement dans le cadre d'une conversion procédurale est quasi identique. Voyons avec un exemple de conversion performance --> points de l'épreuve de perche du décathlon (que l'on retrouvera en détail plus loin).

duPerfPerche et duPointDecation sont des pointeurs de fonctions de type TConversionProc dont la déclaration est la suivante :

 
Sélectionnez
TConversionProc = function(const AValue: Double): Double;

L'exécution de la conversion s'effectuera comme suit :

 
Sélectionnez
points := Convert(perf, duPerfPerche, duPointDecathlon);

La fonction Convert est appelée comme précédemment, une différence subsiste au moment de

 
Sélectionnez
Result := LToTypeInfo.FromCommon(LFromTypeInfo.ToCommon(AValue));

Le type duPerfPerche a été recensé en créant un objet non plus de type TConvTypeFactor, mais de type TConvTypeProcs (voir fig. 12). La différence est que les fonctions ToCommon et FromCommon ne sont pas implémentées dans cette classe, mais déléguées à des fonctions fournies par le développeur (stockées dans les propriétés privées FToCommonProc et FFromCommonProc au moment du recensement) :

 
Sélectionnez
decaPerche := RegisterConversionType(cbDecathlon, 'Perf Perche', PerfPercheToPoints, PointsToPerfPerche);

Ici, FToCommonProc référence la fonction PerfPercheToPoints et FFromCommonProc référence la fonction PointsToPerfPerche.

On retrouve la redirection d'appel à ces fonctions dans l'implémentation de ToCommon et de FromCommon :

 
Sélectionnez
function TConvTypeProcs.ToCommon(const AValue: Double): Double;
begin
  Result := FToCommonProc(AValue);
end;
 
function TConvTypeProcs.FromCommon(const AValue: Double): Double;
begin
  Result := FFromCommonProc(AValue);
end;

Diagramme de classes :

Image non disponible
Figure 12

Nous avons maintenant suffisamment de connaissances pour créer un système de conversions personnalisées.


précédentsommairesuivant

Copyright © 2002 Sylvain James. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.