Clean up deferred views << Back



Raveen Sundram contributed a nice piece of code here to garbage collect deferred views here. I like the idea very much, however I would also like to add some more customizations and make some modifications to his approach.

CleanupDeferredViews.pkg
// Include this package inside of the ClientArea of you app
// Usage:
// Whenever you feel like it (for example, you app has been idle for an hour), call
// the procedure DestroyDeferredViews to clean up all the deferred view.
// 
// Inside each deferred view, you can decide to refuse to be cleaned up. To do so, 
// Set pbAllowDeferDestroyState to FALSE
// 
// When a deferred view is about to be cleaned up, you will receive a callback procedure call
// inside the deferred view
// 
// Procedure OnDeferDestroy Boolean ByRef bShouldDestroy
// 
// Augment OnDeferDestroy to do any cleanup. The parameter "bShouldDestroy" allows you one last
// chance to stop the destruction of the deferred view by doing
// 
// Move False to bShouldDestroy

Use VDFBase.pkg

Property Integer[] piDeferredViewMsgs

// This is called internally
Procedure AddDeferredView Integer iGetMsg Integer iSetMsg
	Integer[] iDeferredViewMsgs blanks
	Integer iCount
	Get piDeferredViewMsgs to iDeferredViewMsgs
	Move (SizeOfArray(iDeferredViewMsgs)) to iCount
	Get piDeferredViewMsgs to blanks
	Move iGetMsg to iDeferredViewMsgs[iCount]
	Move iSetMsg to iDeferredViewMsgs[iCount + 1]
	Set piDeferredViewMsgs to iDeferredViewMsgs
End_Procedure // AddDeferredView

Register_Function pbAllowDeferDestroyState Returns Boolean
Register_Procedure OnDeferDestroy Boolean ByRef bShouldDestroy

// This is the procedure you would call whenever you feel like it
Procedure DestroyDeferredViews
	Integer[] iDeferredViewMsgs
	Integer iCount iIndex iGetMsg iSetMsg
	Handle hView
	Boolean bCanDestroy
	Get piDeferredViewMsgs to iDeferredViewMsgs
	Move (SizeOfArray(iDeferredViewMsgs) / 2 - 1) to iCount
	For iIndex From 0 to iCount
		Move iDeferredViewMsgs[iIndex * 2] to iGetMsg
		Move iDeferredViewMsgs[iIndex * 2 + 1] to iSetMsg
		Get iGetMsg to hView
		If (hView And Active_State(hView) = 0) Begin
			Get pbAllowDeferDestroyState of hView to bCanDestroy
			If (bCanDestroy) Begin
				Send OnDeferDestroy of hView (&bCanDestroy)
				If (bCanDestroy) Begin
					Send Destroy of hView
					Set iSetMsg to 0
				End
			End
		End
	Loop
End_Procedure // DestroyDeferredViews

#COMMAND Deferred_View1 R "AS""FOR" "OBJECT""DFOBJECT"
	Property Integer !1_obj 0  //track Id of view object
	Send AddDeferredView Get_!1_Obj Set_!1_Obj

	// used to return the handle to the actual view creating it as needed
	Function !1_Handle Returns Handle
		Handle hoView
		Get !1_Obj to hoView    // Id of the view
		If (hoView=0) Begin    // if not created, create it
			Send Cursor_wait to (cursor_control(Self))
			Gosub Create_!1
			Get !1_Obj to hoView // this time it better be there!
			Send Cursor_ready to (cursor_control(Self))
		End
		Function_Return hoView
	End_Procedure // !1_Handle

	Procedure !1
		Handle hoView
		Get !1_Handle to hoView
		Send Activate_View to hoView
	End_Procedure // !1

	[Found ~Found] Begin
		Create_!1:
		Object !4 !5 !6 !7 !8  !9
			Property Boolean pbAllowDeferDestroyState True
			Procedure OnDeferDestroy Boolean ByRef bShouldDestroy
			End_Procedure // OnDeferDestroy
			Set !1_obj to Self
#ENDCOMMAND // Deferred_View1

#REPLACE Deferred_View Deferred_View1
Test.src
Use DfAllEnt.pkg

Object oMain is a Panel
    Set Size to 300 450
    Object oClientArea is a ClientArea
		Use CleanupDeferredViews.pkg
		
		DEFERRED_VIEW Activate_View1 FOR Object oView1 is a dbView
			Set Size to 100 200
			Set Label to "View1"
			Procedure OnDeferDestroy Boolean ByRef bShouldDestroy
				Showln "Getting destroyed :("
			End_Procedure
			Object oButton is a Button
				Procedure OnClick
					Delegate Send DestroyDeferredViews
				End_Procedure
			End_Object
		CD_End_Object
		
		DEFERRED_VIEW Activate_View2 FOR Object oView2 is a dbView
			Set Size to 100 200
			Set Label to "View2"
			Set pbAllowDeferDestroyState to False
			Object oButton is a Button
				Procedure OnClick
					Delegate Send DestroyDeferredViews
				End_Procedure
			End_Object
		CD_End_Object
		
		DEFERRED_VIEW Activate_View3 FOR Object oView3 is a dbView
			Set Size to 100 200
			Set Label to "View3"
			Procedure OnDeferDestroy Boolean ByRef bShouldDestroy
				Showln "Refuse to be destroyed >_<"
				Move False to bShouldDestroy
			End_Procedure
			Object oButton is a Button
				Procedure OnClick
					Delegate Send DestroyDeferredViews
				End_Procedure
			End_Object
		CD_End_Object
		
	End_Object
	On_Key Key_Ctrl+Key_1 Send Activate_View1 of oClientArea
	On_Key Key_Ctrl+Key_2 Send Activate_View2 of oClientArea
	On_Key Key_Ctrl+Key_3 Send Activate_View3 of oClientArea
End_Object

Start_UI





Free Web Hosting