Tôi đang viết một công cụ nhỏ để thực hiện một số thao tác của các tệp SWF, sử dụng Delphi XE2. Cho đến nay, tôi chỉ đơn giản theo dõi the SWF specification và bây giờ tôi đã gặp phải một vấn đề nhỏ trong việc triển khai cấu trúc dữ liệu để biểu diễn các hình dạng.Nhiều phần biến thể trong một bản ghi
Hình dạng SWF chứa một số bản ghi hình dạng. Bản ghi hình dạng có thể là bản ghi cạnh hoặc bản ghi không cạnh và mỗi loại trong hai loại này có hai loại phụ bổ sung.
Cụ thể, trên trang 135 của đặc tả, hai loại bản ghi không cạnh được mô tả; EndShapeRecord
và StyleChangeRecord
. Trong tệp SWF, cách phân biệt giữa các tệp này là kiểm tra xem tất cả năm bit cờ (sau TypeFlag) là 0 hay không; nếu có, đó là số EndShapeRecord
, nếu không thì là StyleChangeRecord
.
Để giúp tôi xử lý các bản ghi hình dạng sau này, tôi muốn hợp nhất các bản ghi cạnh và không cạnh thành một loại bản ghi duy nhất, sử dụng một bản ghi biến thể. Phân biệt giữa các loại hồ sơ khác nhau là đủ dễ dàng; một bản ghi biến thể lồng nhau cho phép tôi dễ dàng để các hồ sơ cạnh này ngoài, và cho các hồ sơ không cạnh, tôi có thể tuyên bố 5 lá cờ từ StyleChangeRecord
và viết một chức năng IsEndRecord
.
Tuy nhiên, để làm cho mã nguồn của tôi phản ánh đặc điểm kỹ càng nhất có thể, tôi muốn tiến thêm một bước nữa. Sự hiện diện của các trường khác trong một StyleChangeRecord
được xác định dựa trên giá trị của 5 cờ này, vì vậy tôi muốn có thể khai báo 5 bản ghi biến thể, một bản ghi cho mỗi cờ, có chứa các trường được thêm bởi mỗi cờ. (Tôi nhận thấy điều này sẽ không ảnh hưởng đến việc sử dụng bộ nhớ theo bất kỳ cách nào, nhưng đó không phải là vấn đề.)
Thật không may, Delphi dường như không cho phép nhiều hơn một phần biến thể cho mỗi cấp độ và cố gắng xác định 5 các phần biến thể cùng cấp chỉ ném một tấn lỗi cú pháp.
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;
Về hơi đơn giản, mục tiêu là để có thể xây dựng một kỷ lục như vậy:
TNonEdgeRecord = record
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of
True: (LineStyle: UInt16);
end;
... mà không cần tháo phần biến thể của các hồ sơ, và không làm tổ họ (kể từ lồng nhau sẽ ngụ ý một quan hệ không chính xác từ một quan điểm cú pháp).
Có cách nào khác để tôi có thể khai báo nhiều phần biến thể (không lồng nhau) trong một bản ghi hay tôi chỉ cần quay lại không sử dụng các bản ghi biến thể cho phần bên trong?
tôi không hoàn toàn hiểu những gì bạn đang cố gắng để đạt được nhưng có vẻ như bạn muốn cuộn xử lý bản ghi biến thể của riêng bạn. Điều này là dễ dàng, đủ để làm bằng cách sử dụng tài sản ghi lại. –
@DavidHeffernan: Không, điều đó không hoàn toàn. Tôi muốn làm cho * định nghĩa kiểu * cho thấy các trường nào có mặt, được gán cho giá trị của một cờ hoặc biến nào đó - đó là cơ bản những gì một bản ghi biến thể làm, và điều đó đơn giản là đủ.Vấn đề đối với tôi là nhận được * nhiều * của những người trong một bản ghi * duy nhất *; điều tốt nhất tôi có thể làm là lồng ghép chúng, nhưng điều đó sẽ là ngớ ngẩn, vì những lá cờ này độc lập với nhau. Tôi sẽ cố gắng viết lại câu hỏi một chút để hy vọng làm cho nó rõ ràng hơn. –
Cú pháp không hỗ trợ nhiều cờ độc lập. Làm tổ là một lựa chọn. Hồ sơ với các phương pháp/tài sản là khác mà tôi có thể nghĩ đến. –