Thiết Kế Một IDL Cho Bgfx - nói dối e blog

Thiết Kế Một IDL Cho Bgfx

Vào tháng trước, tôi đã dành hơn một tuần đóng góp cho dự án bgfx. Sự việc bắt đầu khi tác giả của bgfx tạo một issue trên dự án sproto của tôi (sau này được chuyển sang dự án bgfxidl). Anh ấy muốn thiết kế một Ngôn ngữ Mô tả Giao diện (Interface Description Language - IDL) cho các API của bgfx nhằm tự động hóa việc duy trì các tệp giao diện đa ngôn ngữ, đồng thời mở ra khả năng sinh mã tự động hiệu quả.

Trong quá trình nghiên cứu, tôi nhớ lại kinh nghiệm năm 2006 khi từng sử dụng IDL của COM để xây dựng hệ thống tương tự. Tôi nhận thấy đây là bài toán cổ điển về tương tác đa nền tảng. Với kinh nghiệm đó, tôi đề xuất sử dụng Lua - một ngôn ngữ cực kỳ phù hợp để xây dựng DSL/IDL nhờ cú pháp linh hoạt và khả năng xử lý meta-programming mạnh mẽ. Đặc biệt, công cụ xây dựng Genie đang dùng cho bgfx cũng được viết bằng Lua, tạo nên sự nhất quán trong chuỗi công cụ phát triển.

Yêu cầu ban đầu chỉ đơn giản là sinh các tệp .h API C99. Với đặc tính của Lua cho phép bỏ qua dấu ngoặc khi gọi hàm với tham số duy nhất là chuỗi hoặc bảng, tôi nhanh chóng đề xuất cú pháp trực quan như sau:

1
2
3
func.createShader
  "ShaderHandle"
  .mem "const Memory*"

Đoạn mã trên định nghĩa hàm createShader trả về ShaderHandle với tham số mem kiểu const Memory*. Trong một buổi chiều cuối tuần sau khi dỗ con ngủ trưa, tôi đã hoàn thành phiên bản đầu tiên.

Sự thành công ban đầu khiến yêu cầu ngày càng gia tăng. Trong hơn một tuần tiếp theo, chúng tôi bổ sung hàng loạt tính năng: định nghĩa Enum, Struct, phương thức lớp, giá trị mặc định tham số hàm… Khả năng của IDL nhanh chóng vượt xa mục tiêu ban đầu khi không chỉ sinh mã C/C++ mà còn tự động tạo các hàm binding C. Đặc biệt, việc xử lý các kiểu dữ liệu đặc biệt như handle trong bgfx đòi hỏi giải pháp chuyển đổi phức tạp.

Thách thức lớn thứ hai là hệ thống chú thích mã. Chúng tôi muốn duy trì tài liệu giao diện trong IDL và sinh ra các chú thích Doxygen chất lượng cao. Cú pháp hiện tại của Lua không đủ đáp ứng, nên sau nhiều lần cải tiến, chúng tôi quyết định sử dụng chuỗi dài kiểu Lua trong ngoặc vuông để viết tài liệu. Đồng thời phát triển module tiền xử lý chuyển đổi các chú thích đơn dòng bắt đầu bằng “—” thành chuỗi tài liệu. Giải pháp này cho phép hai dạng chú thích song hành: nếu không dùng module, chú thích sẽ bị bỏ qua; nếu dùng, tài liệu sẽ được tích hợp vào cấu trúc IDL.

Kết quả hiện tại là một hệ thống IDL phong phú với hơn 1000 dòng mã. Dự án được cấp phép MIT giống bgfx và dù được thiết kế riêng cho bgfx, các module lõi có thể tái sử dụng cho nhiều dự án lớn khác cần IDL tùy chỉnh.

Hiện tại, toàn bộ giao diện bgfx đã được sinh mã tự động. Đặc biệt, tác giả bgfx đã trực tiếp yêu cầu tôi gửi PR để hợp nhất các thay đổi, đảm bảo công việc này được ghi nhận chính thức trong kho mã nguồn chính.

Trong tương lai gần, bgfx sẽ sử dụng hệ thống sinh mã để tạo lớp bọc dynamic library với giao diện tải API tập trung, kèm theo tính năng ghi log chi tiết các lời gọi API. Các binding Python cũng sẽ chuyển từ bảo trì thủ công sang sinh mã tự động dựa trên IDL.

Tác giả bgfx đã viết một bài blog chi tiết về quá trình phát triển này, bạn có thể

0%