forked from electricessence/TypeScript.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLazy.ts
More file actions
109 lines (85 loc) · 1.92 KB
/
Copy pathLazy.ts
File metadata and controls
109 lines (85 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
///<reference path="IDisposable.ts"/>
/*
* @author electricessence / https://github.com/electricessence/
* Licensing: MIT https://github.com/electricessence/TypeScript.NET/blob/master/LICENSE
*/
// Ensure this is loaded before Lazy<T>.
import DisposableBase = System.DisposableBase;
module System {
export interface ILazy<T> extends IDisposable, IEquatable<ILazy<T>>
{
value:T;
isValueCreated:boolean;
}
export class Lazy<T> extends DisposableBase implements ILazy<T>
{
private _isValueCreated:boolean;
private _value:T;
constructor(private _closure:Func<T>)
{
super();
}
get isValueCreated():boolean
{
return this._isValueCreated;
}
// Adding a 'resettable' mechanism allows for simply resetting a lazy instead of re-instantiating a new one.
get canReset(): boolean
{
return !this.wasDisposed && !!(this._closure);
}
// Returns true if successfully reset.
reset(throwIfCannotReset?:boolean):boolean {
var _ = this;
if (throwIfCannotReset)
_.assertIsNotDisposed();
if (!_._closure)
{
if (throwIfCannotReset)
throw new Error("Cannot reset. This Lazy has already de-referenced its closure.");
return false;
} else
{
_._isValueCreated = false;
_._value = null;
return true;
}
}
get value():T
{
return this.getValue();
}
getValue(clearClosureReference?:boolean):T {
var _ = this;
_.assertIsNotDisposed();
try
{
if (!_._isValueCreated && _._closure)
{
var v = _._closure();
_._value = v;
_._isValueCreated = true;
return v;
}
}
finally
{
if(clearClosureReference)
_._closure = null;
}
return _._value;
}
protected _onDispose():void {
this._closure = null;
this._value = null;
}
equals(other: Lazy<T>): boolean
{
return this == other;
}
valueEquals(other: Lazy<T>): boolean
{
return this.equals(other) || this.value === other.value;
}
}
}