| 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 |
author: 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 |
} |
|---|