Sự kiện tức thời và sự kiện hẹn trước (Commit-Time)
Với AcDbObjectReactor, sự kiện thông báo có thể diễn ra tức thời hoặc được trì hoãn đến thời điểm hẹn trước. Thời gian hẹn trước là thời gian đối tượng được đóng nếu bạn đang hoạt động trên mỗi đối đượng cơ sở, hoặc kết thúc giao dịch ngoài cùng khi bạn thực hiện kiểu giao dịch (transaction). Sự kiện sau sẽ gửi thông báo ngay lập tức:
cancelled()
Thông báo được gửi đến AcDbObject khi gọi tới AcDbObject::cancelled().
openedForModify()
Thông báo được gửi tới lần đầu tiên hàm chỉnh sửa đối tượng được gọi tới, trước khi trạng thái đối tượng bị thay đổi.
copied()
Thông báo khi đối tượng được copy.
goodbye()
Các thông báo tức thời được thực hiện cùng lúc với sự kiện tương ứng. Ví dụ, khi hàm assertWriteEnabled() được gọi lần đầu tiên trên đối tượng, thông báo openedForModify() ngay lập tức được gửi đi đến tất cả các reactor trên đối tượng đó.
Các sự kiện sau đây chỉ được gửi theo thời gian hẹn trước:
- modified()
- subObjModified()
- erased()
- modifyUndone()
- modifiedXData()
- unappended()
- reappended()
- graphicsModified()
Thông báo modified() của AcDbObjectReactor là một ví dụ của thông báo hẹn trước commit-time. Giả sử một đối tượng được mở và hàm chỉnh sửa được gọi đến. Hàm chỉnh sửa lại gọi hàm assertWriteEnabled() và tất cả các reactor sẽ nhận được phản ứng openedForModify(). Các hàm chỉnh sửa tiếp theo trên đối tượng sẽ không tạo ra bất kì thông báo nào khác. Khi đối tượng được đóng, thông báo modified() sẽ được gửi đi. Tuy nhiên, nếu trình mở chọn phương thức cancel() thay cho close() thì thông báo cancelled() sẽ được gửi thay thế.
Khi nhận được thông thông báo trì hoãn (deferred notification) như modified() trong thời gian hẹn trước (commit time), một trong số tham số là con trỏ tới đối tượng. Lúc này, đối tượng đang ở trạng thái chỉ đọc (read-only). Bạn không thể chỉnh sửa cho đến khi kết thúc quá trình hẹn trước được.
Cố gắng thay đổi đối tượng trước khi thời gian hẹn trước kết thúc sẽ khiến cho AutoCAD hủy bỏ với thông điệp lỗi eWasNotOpenForWrite hoặc eInProcessOfCommitting.
Bạn có thể sử dụng hàm sau để kiểm tra quá trình hẹn trước đã kết thúc hay chưa trước khi mở đối tượng để ghi:
AcDbObjectReactor::objectClosed(const AcDbObjectId objId);
AcTransactionReactor::transactionEnded(
int& numTransactions,
AcDbTransactionManager* transactionManagerPtr);
Thông báo objectClosed() được gửi khi đối tượng thực sự đóng lại và con trỏ không còn hợp lệ nữa. Bạn có thể mở lại đối tượng bằng ID đã đưa vào trong tham số và thao tác trên nó. Đừng nên tạo ra các vòng lặp thông báo vô hạn vào lúc này.
Trong thông báo transactionEnded(), bạn có thể sử dụng hàm numActiveTransactions() để hỏi trình quản lý giao dịch (transaction manager) xem có bao nhiêu giao dịch đang diễn ra. Nếu không còn giao dịch hiện thời, nghĩa là giao dịch đã kết thúc và tất cả các đối tượng trong giao dịch đã hoàn hành thời gian hẹn trước.
Đôi khi bạn có thể cần biết khi nào giao dịch ngoài cùng kết thúc và quá trình hẹn trước bắt đầu. Muốn vậy, hãy sử dụng thông báo sau đây:
AcTransactionReactor::endCalledOnOutermostTransaction(
int& numTransactions,
AcDbTransactionManager* transactionManagerPtr);
Khi vòng giao dịch ngoài cùng kết thúc, quá trình hẹn trước bắt đầu và phương thức close() được gọi tới trên các đối tượng. Bạn phải nhận thông báo objectClosed() như là một phần của quá trình đóng. Tuy nhiên, tốt hơn hết là không hành động ngay lập tức. Thay vào đó, hãy đợi đến lúc toàn bộ giao dịch kết thúc trước ki tiến hành bất cứ quá trình nào trên các đối tượng này.
No comments:
Post a Comment