1 /******************************************************************************
2 
3         copyright:      Copyright (c) 2009 Tango. All rights reserved
4 
5         license:        BSD style: $(LICENSE)
6 
7         version:        Jan 2010: Initial release
8 
9         authors:         wm4, kris
10 
11 ******************************************************************************/
12 
13 module tango.core.WeakRef;
14 
15 private import tango.core.Memory;
16 
17 /******************************************************************************
18 
19         A generic WeakReference.
20 
21 ******************************************************************************/
22 
23 alias WeakReference!(Object) WeakRef;
24 
25 /******************************************************************************
26 
27         Implements a Weak reference. The get() method returns null once 
28         the object pointed to has been collected.
29 
30 ******************************************************************************/
31 
32 class WeakReference (T : Object) 
33 {
34         public alias get opCall;        /// Alternative get() call.
35         private void* weakpointer;      // what the GC gives us back
36 
37         /**********************************************************************
38         
39                 Initializes a weak reference.
40         
41         **********************************************************************/
42 
43         this (T obj) 
44         {
45                 weakpointer = GC.weakPointerCreate (obj);
46         }
47 
48         /**********************************************************************
49         
50                 Clean up when we are no longer referenced.
51 
52         **********************************************************************/
53 
54         ~this () 
55         {
56                 clear;
57         }
58 
59         /**********************************************************************
60         
61                 Host a different object reference.
62 
63         **********************************************************************/
64 
65         final void set (T obj) 
66         {
67                 clear;
68                 weakpointer = GC.weakPointerCreate (obj);
69         }
70 
71         /**********************************************************************
72         
73                 Clear the weak reference - get() will always return null.
74         
75         **********************************************************************/
76 
77         final void clear () 
78         {
79                 GC.weakPointerDestroy (weakpointer);
80                 weakpointer = null;
81         }
82 
83         /**********************************************************************
84         
85                 Returns the weak reference - returns null if the object
86                 was deallocated in the meantime.
87 
88         **********************************************************************/
89 
90         final T get () 
91         {
92                 return cast(T) GC.weakPointerGet (weakpointer);
93         }
94 }
95 
96 
97 /******************************************************************************
98 
99         Note this requires -g (with dmd) in order for the GC.collect call
100         to operate as desired 
101 
102 ******************************************************************************/
103 
104 debug (WeakRef)
105 {
106         import tango.core.Memory;
107 
108         WeakRef make ()
109         {       
110                 return new WeakRef (new Object);
111         }
112 
113         void main()
114         {
115                 auto o = new Object;
116                 auto r = new WeakRef (o);
117                 assert (r() is o);
118                 delete o;
119                 assert (r() is null);
120 
121                 auto r1 = make;
122                 assert (r1.get);
123                 GC.collect;
124                 assert (r1() is null);
125         }
126 }