Giới thiệu
Đây là 1 vấn đề đã được nhắc đến trong các bài viết trước, khi hiện thực CAnimation
. Đó là vấn đề phải ép kiểu để gọi đến phương thức đặc trưng của CAnimation
: draw
. Bài viết này sẽ hiện thực 1 lớp quản lý các Component này, nhằm mục đích gom nhóm và gọi phương thức đặc thù draw
bằng tất cả các CAnimation
đã từng được tạo và còn đang tồn tại.
Tải project mẫu
Đây là project ví dụ dùng trong bài viết: CBP-10-2019.zip.
Project này có thể mở bằng Visual Studio 2019, project này chứa các file mã C++ của CBP, project có thể không tương thích với nhiều môi trường Visual Studio khác nhau nhưng có thể dành để tham khảo.
Tổng quan tư tưởng
Đó sẽ là 1 lớp lưu trữ tất cả các component CAnimation
được tạo ra trong suốt thời gian chương trình hoạt động, có 1 phương thức đặc trưng của lớp, dùng để gọi tất cả các phương thức draw
bằng những Component đã được tạo.
Những vấn đề khác như không vẽ đối tượng trong màn hình sẽ không đề cập tới, vì nó phụ thuộc vào cách hiện thực của chỉnh độc giả. 1 số sẽ dựa vào command HIDE
và SHOW
sẵn có, 1 số khác lại xét khung hình khi vẽ, số khác nữa dựa vào các thuật toán phân hoạch không gian, ... dù gì thì cũng mang đến cùng 1 kết quả nên sẽ không bàn đến ở đây.
Phân tích
Như đã trình bày, lớp quản lý này cần thực hiện các chức năng:
- Lưu trữ 1 mối liên kết dẫn đến từng
CAnimation
đã tạo. - Có phương thức để gọi tất cả phương thức
draw
của từng Component đã lưu trữ. - Gỡ bỏ liên kết đến những
CAnimation
đã bị thu hồi khỏi danh sách.
Lưu ý: lớp quản lý có thể liên kết với Component, tuy nhiên lớp quản lý phải đảm bảo không can dự vào hoạt động bình thường của Component để tránh những xung đột có thể xảy ra (và phần lớn đều rất rắc rối).
Toàn bộ chương trình chỉ tồn tại 1 lớp quản lý cho CAnimation
, nên cần ứng dụng Singleton Pattern để tăng tính linh hoạt của lớp quản lý, tương tự như đã làm với Factory.
Hiện thực
Khai báo của lớp quản lý:
class CAnimation; class ManagerCAnimation { public: // To call the draw method from all created CAnimation. // @param hdc: Handle for Device Context using in this draw. void callDraw(HDC hdc); // To add a new-created CAnimation into managing list. // @param component: Pointer to the pushed component. void addComponent(CAnimation* component); // To remove the passed component from managing list, treated as destroyed. // @param component: Pointer to the released component. void removeComponent(CAnimation* component); // Singleton Pattern methods static ManagerCAnimation* getInstance(); static void init(); static void release(); // ======================== private: ManagerCAnimation(); ~ManagerCAnimation(); private: std::vector<CAnimation*> m_componentList; static ManagerCAnimation* m_instance; };
Với 3 phương thức calldraw
, addComponent
, removeComponent
và 1 thuộc tính m_componentList
đặc trưng, lớp quản lý có các chức năng:
- Thêm
CAnimation
vừa được tạo mới vào danh sách quản lý:addComponent
được gọi tại constructor củaCAnimation
. - Gỡ bỏ
CAnimation
vừa bị hủy khỏi danh sách quản lýremoveComponent
được gọi tại destructor củaCAnimation
. - Gọi phương thức
draw
của tất cả cácCAnimation
đang tồn tạicallDraw
được gọi tại hàmdraw
của file main.cpp.
Các phương thức này đều được định nghĩa hết sức đơn giản, có thể tham khảo trong project ví dụ đính kèm.
Cài đặt và thử nghiệm
Để thử nghiệm, có 1 số thay đổi như sau trong mã nguồn project:
void draw(HDC hdc) { ManagerCAnimation::getInstance()->callDraw(hdc); }
void init(HINSTANCE instance, HWND handler) { ... ManagerCAnimation::init(); ... }
void release() { ... ManagerCAnimation::release(); ... }
CAnimation::CAnimation() { ... ManagerCAnimation::getInstance()->addComponent(this); } CAnimation::~CAnimation() { ... ManagerCAnimation::getInstance()->removeComponent(this); }
Và thế là project đã hoạt động mà không cần tìm kiếm, không ép kiểu, các Entity được vẽ lên màn hình giao diện không chút trở ngại.
Lời kết
CBP-10 đã kết thúc chuỗi bài viết về Component Base Programming nhằm hướng dẫn độc giả hiện thực hệ thống này.
- Entity đã được hiện thực.
- Component đã được hiện thực.
- Hàng đợi chỉ lệnh, Factory, phản ứng của Entity, ... đã được hiện thực.
Bài chung series
- CBP-0: Giới Thiệu về Component Base Development
- CBP-1: Tổng Quan về Project Ví Dụ
- CBP-2: Khai Báo Component Cơ Sở và Entity Cơ Bản
- CBP-3: Khai Báo Component Cơ Bản, Tích Hợp Component vào Entity
- CBP-4: Giao Tiếp với Entity – Hệ Thống Chỉ Lệnh
- CBP-5: Truyền và Lấy Thông Số từ Component
- CBP-6: Hàng Đợi Chỉ Lệnh
- CBP-7: Cài Đặt Phản Ứng cho Entity
- CBP-8: Component Điều Khiển và AI – Component Ra Lệnh
- CBP-9: Bộ Khởi Tạo Entity – Factory và Hệ Thống ID
- CBP-10: Hệ Thống Quản Lý Tập Trung Các Component Đặc Thù