estoy escribiendo una pequeña herramienta para hacer un poco de manipulación de archivos SWF, usando Delphi XE2. Hasta ahora, simplemente estoy siguiendo the SWF specification, y ahora me he topado con un pequeño problema al implementar una estructura de datos para representar formas.partes variantes múltiples en un registro
Las formas SWF contienen un número de registros de forma. Los registros de forma pueden ser registros de borde o no frontales, y cada uno de esos dos tipos tiene dos subtipos adicionales.
Específicamente, en la página 135 de la especificación, se describen los dos tipos de registros que no son de borde; EndShapeRecord
y StyleChangeRecord
. En el archivo SWF, la forma de diferenciarlos es comprobar si los cinco bits de marca (después de TypeFlag) son 0; si lo son, es EndShapeRecord
; de lo contrario, es StyleChangeRecord
.
Para ayudarme a procesar los registros de forma más adelante, me gustaría unificar los registros de bordes y no bordes en un solo tipo de registro, usando un registro de variantes. Distinguir entre los diferentes tipos de registros es bastante fácil; un registro variante anidada me permite fácilmente a este los registros de bordes separados, y para los registros no borde, que puede declarar las 5 banderas del StyleChangeRecord
y escribir una función IsEndRecord
.
Sin embargo, con el fin de hacer que mi código fuente refleje la especificación lo más fielmente posible, me gustaría dar un paso más. La presencia de los otros campos en un StyleChangeRecord
se basan en los valores de estos 5 banderas, por lo que le gustaría ser capaz de declarar 5 registros variante, uno por bandera, que contienen los campos añadidos por cada bandera. (Me doy cuenta de que esto no afectará el uso de la memoria de ninguna manera, pero ese no es el punto.)
Desafortunadamente, Delphi no parece permitir más de una variante por "nivel" e intenta definirlas 5 las partes variantes en el mismo nivel solo arrojan una tonelada de errores de sintaxis.
TShapeRecord = record
case EdgeRecord: Boolean of
False: (
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of // << Errors start here
True: (LineStyle: UInt16);
//Additional flags
);
//Fields for edge records
end;
En términos un poco más sencillo, el objetivo es ser capaz de formular un registro de este modo:
TNonEdgeRecord = record
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of
True: (LineStyle: UInt16);
end;
... sin necesidad de retirar las partes variantes del registro, y sin anidarlas (ya anidar implicaría una relación incorrecta desde un punto de vista sintáctico).
¿Hay alguna otra manera en que pueda declarar varias partes variantes (no anidadas) en un registro, o debería simplemente volver a no usar registros de variantes para la parte interna?
No entiendo completamente lo que usted está tratando de lograr pero suena como desea desplegar su propio manejo de registro de variante. Esto es bastante fácil de hacer usando propiedades de registro. –
@DavidHeffernan: No, eso no es todo. Quiero hacer que la * definición de tipo * muestre qué campos están presentes, dado el valor de una determinada marca o variable; eso es básicamente lo que hace una variante de registro, y eso es bastante simple.El problema para mí es obtener * múltiples * de ésos en un * single * registro; lo mejor que he podido hacer es anidarlos, pero sería una tontería, ya que estas banderas son independientes entre sí. Trataré de volver a escribir la pregunta un poco para poder aclararla. –
La sintaxis no es compatible con múltiples indicadores independientes. Anidar es una opción. Registros con métodos/propiedades es el otro que se me ocurre. –