CD_Popup_Object in depth
<< Back
As we have talked about how to identify all the non-deferred objects in the past,
one couldn't help but wonder how it all works. I remember when I first started programming in VDF 7 (2001), you just had
to change the property "Defer" in the property panel in the IDE (it was not called "Studio"), and boom, your view/modal panel
had just become "Deferred". Let's look at some code.
// Non-deferred Version
Object oPanel is a ModalPanel
Property Integer piValue 0
End_Object
// Deferred Version
CD_Popup_Object oPanel is a ModalPanel
Property Integer piValue 0
CD_End_Object
From the implementation point of view, it's pretty simple. However, in the Dfdafmac.pkg, it reveals something pretty interesting.
#COMMAND Cd_Popup_Object R
#PUSH !g
Register_Object !1_cd
Object !1 is a CD_Client
Function Popup_Handle Returns Handle
Handle hoID
Get Created_Object_Id to hoId
If (hoId=0) Begin
#SET G$ !a
Gosub !1_Sub!g
Move (!1_cd(Self)) to hoId
Set Created_Object_id to hoID
End
Function_Return hoID
End_Function
End_Object
[Found ~Found] Begin
!1_Sub!g:
#POP R$
#POP G$
#PUSH !r
Object !1_cd !2 !3 !4 !5 !6 !7 !8 !9
#ENDCOMMAND
#COMMAND CD_END_OBJECT .
End_Object
Gosub_Return
End
#ENDCOMMAND
Class CD_Client is a Container
Procedure Construct_Object
Forward Send Construct_Object
Property Integer Created_object_id 0
Set focus_mode to nonfocusable
End_Procedure // Construct_Object
Procedure Popup
Send Popup_Modal
End_Procedure // Popup
Procedure Popup_Modal Returns Integer
Integer iRet
Handle hoId
Boolean bDestroy
Get Popup_Handle to hoId
If hoId Begin
Get msg_Popup_Modal of hoId to iRet
Get Destroy_Object_State of hoId to bDestroy
If bDestroy Begin
Send Destroy of hoId
Set Created_Object_Id to 0
End
Procedure_Return iRet
End
End_Procedure
End_Class
When you defer a modal panel, VDF does a few things for you (based on the above example)
- It creates a dummy CD_Client object named "oPanel"
- Your actual modal panel is now named "oPanel_CD"
- The entire code for the "oPanel" (technically "oPanel_CD") is now inside a gigantic block of "IF" (Look for the line 22), which
will always be false becasue the expression [Found ~Found]. Which means the "IF" block (all the code for the modal panel) will be
skipped over.
- If you evaluate the Name of the actual modal panel, it has now become "oPanel.oPanel_CD" instead of just "oPanel". That means the dummy
CD_Popup_Object (oPanel) is now the parent object of the actual modal panel (oPanel_CD)
- When you make a Popup call to oPanel, the dummy CD_Client object will jump the code straight inside the "IF" block (line 13 and 23),
this is the time where the actual code for the modal panel gets executed.
Basically put, VDF uses of "GoSub" to skip over some of code execution until you need it. If you look at the implementation of CD_End_Object,
it's almost comical that they are just simple "End_Object" and "Gosub_Return" statements. Imagine if you have thousands of modal panels
in your program (selection lists included), deferring the modal panels will definitely decrease the startup time of your program. Therefore
it is highly recommended that you defer all your modal panels. Pay attention to item #4 - it has burned me in the past. The actual modal panel is
now the child of a Container, which usually isn't a big deal. We will cover that more in the future article.