Como regla general he eludido muchas trampas de diseño clásicas cuando uso punteros aprovechando los parámetros de Const (sin tipo) en lugar de los tipos de código fijo. Esto me da la ventaja de la velocidad al ejecutar funciones gráficas avanzadas al tiempo que dejo los detalles técnicos al compilador. También ha hecho que sea fácil usar el mismo código en Delphi y Free Pascal con cambios mínimos. Sin embargo, últimamente he empezado a cuestionar esto debido a las declaraciones vagas de Embarcadero sobre la evolución de Delphi y su futuro modelo de seguridad.¿Los parámetros de constricción y el encasillado funcionarán como antes en Delphi 64bit?
Por ejemplo, concider el siguiente ejemplo:
Type TSomeDataProc = procedure (const aInput;var aOutput) of Object;
(* Convert 8-bit pixel to 16-bit pixel *)
Procedure TMyClass.ProcessSomeData08x565(Const aInput;var aOutput);
var r,g,b: Byte;
Begin
FPalette.ExportTriplets(Byte(aInput),r,g,b);
Word(aOutput):=(R SHR 3) SHL 11 or (G SHR 2) SHL 5 or (B SHR 3);
End;
(* Convert 16-bit pixel to 24-bit pixel *)
Procedure TMyClass.ProcessSomeData565x888(Const aInput;var aOutput);
Begin
With TRGBTriple(aOutput) do
Begin
rgbtRed:=(((word(aInput) and $F800) shr 11) shl 3);
rgbtGreen:= (((word(aInput) and $07E0) shr 5) shl 2);
rgbtBlue:= ((word(aInput) and $001f) shl 3);
end;
End;
ahora tenemos dos procedimientos con declaraciones idénticas, pero que manejan el pixeldata de manera muy diferente. Esto nos da la ventaja de usar una tabla de búsqueda para obtener el método correcto de "convertidor". Esto debe hacerse ya sea en el constructor o dondequiera que el mapa de bits de imagen se asigna, como esto:
Private
FLookup: Array[pf8bit..pf32bit,pf8bit..pf32bit] of TSomeDataProc;
Procedure TMyClass.Create;
Begin
Inherited;
FLookup[pf8bit,pf16bit]:=ProcessSomeData08x565;
FLookup[pf16bit,pf24Bit]:=ProcessSomeData565x888;
end;
Cada vez que necesitamos para convertir píxeles simplemente buscar el método correcto y lo usamos. La sintaxis sigue siendo la misma para todos los procedimientos, por lo que no debemos preocuparnos por "cómo" funciona cada procedimiento. En lo que respecta a nuestra clase, todos tienen el mismo aspecto.
Procedure TMyClass.ConvertTo(aFormat:TpixelFormat);
Begin
// Get function for the correct pixel converter
FConvertProc:=FLookup[CurrentFormat,aFormat];
//Use the pixel converter
FConvertProc(GetSourcePixelAddr(x,y),GetTargetPixelAddr(x,y));
end;
La pregunta es: ¿Se este tipo de encasillamiento (por ejemplo: Const a byte o cualquier tipo de registro definido) sobrevivir bajo 64 bits? Personalmente no puedo ver por qué no, pero Embarcadero ha sido un poco vago con respecto al nuevo modelo de "seguridad" y el uso de punteros, por lo que me resulta un poco difícil proteger mi código para el futuro.
No puedo ver cómo se escribe de esa manera en lugar de: 'ProcessSomeData (Const aInput : Byte; var aOutput: Word); ' –
No pasa un puntero a ese código de ejemplo, ¿verdad? Por curiosidad, ¿qué pasa con el sistema de tipo incorporado, qué velocidad de puntero? –
@Sertac Speed es lo mismo aquí. Existe una sutil diferencia entre un parámetro sin tipo var var y un parámetro const typeless y un puntero genérico: un parámetro const type no debe modificarse, mientras que un puntero siempre se puede modificar. Y el uso de una var sin letra puede evitar escribir algunos caracteres^en tu código: PWord (aOutput) ^: = 13 por ejemplo. El ensamblador generado será el mismo que word (aOutput): = 13. –