Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Class pattern: weak references for owned resources
Message
De
23/11/2003 12:03:54
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Titre:
Class pattern: weak references for owned resources
Divers
Thread ID:
00852756
Message ID:
00852756
Vues:
40
We all know the problem that object cannot refer to each other without creating the dreaded circular references that prevent automatic destruction, unless the objects in question are in a parent/child relationship and the references are the builtin ones (.Parent on one end, .Controls[] on the other).

Sometimes an object needs to hand out other objects representing resources owned by it in some fashion but needs to keep references to everything it hands out to allow forceful removal. .AddObject does most of the job but not all - the objects handed out are not cleaned up up automatically because they are still referenced by the owning container.

Enter the 'handle' class. The resource will be wrapped in a normal class which contains a property reference to a handle object which is actually a child of the container, created via .AddObject with a pseudo-random name. It is the job of the handle object to manage the resource in collusion with the container (which it can access via its .Parent property) and to relay news of the resource object's destruction to the container to allow cleanup of the resource.

The resource objects themselves follow normal lifetime rules and they will be cleaned up normally, because the resource owner does not reference them. These objects will even survive destruction of the resource container; all that happens is that the handle property turns .null.

The handle object could forward certain requests to the container and it could also store some information (like operating system handles). But in the simplest case it needs to do nothing else because even as it is it can prevent the resource object from doing certain things that it should not do when the resource owner/container has gone away.

Note: the resource owner/container will not get destroyed automatically until all references to it are released and all resource objects that it handed out have gone away. For some purposes this is just fine as it is, but it can also forcefully destroy all outstanding handles if it so chooses.
* CResourceDispenser.prg

return createobject([CResourceDispenser])

*******************************************************************************

#define CHandle_  CResourceDispenser_Handle_6KV5YtzcwCEd1oN8cUhxo_

* public
define class CResourceDispenser as custom

   function CreateResource
      this.AddObject("handle" + sys(2015), [CHandle_])
      return createobject([CResource], this.Controls[this.ControlCount])
   
   procedure FreeResourceByHandle (oHandle)
      this.RemoveObject(m.oHandle.Name)

   procedure FreeAllResources
      * destroy in reverse order of construction (LIFO)
      do while this.ControlCount > 0
         this.RemoveObject(this.Controls[this.ControlCount].Name)
      enddo
      
enddefine

* semi-private
define class CHandle_ as custom

   procedure Suicide
      this.Parent.FreeResourceByHandle(this)

enddefine

* public
define class CResource as relation

*- protected o_Handle
   o_Handle = .null.
   
   function Init (oHandle)
      if isnull(m.oHandle)
         return .f.
      endif
      this.o_Handle = m.oHandle
   
   procedure Destroy
      if not isnull(this.o_Handle)
         this.o_Handle.Suicide
      endif
      
   procedure o_Handle_ASSIGN (uNewValue)
      if isnull(m.uNewValue) and not isnull(this.o_Handle)
         this.Event_HandleDestroyed
      endif
      this.o_Handle = m.uNewValue

   procedure Event_HandleDestroyed

enddefine
Répondre
Fil
Voir

Click here to load this message in the networking platform