forked from Nigh/gdiChartLib
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindirectReference.ahk
133 lines (113 loc) · 4.02 KB
/
indirectReference.ahk
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
CLASS indirectReference
author: nnnik
description: A class that is able to create safe indirect references that allow access to an object without creating a reference.
This allows AutoHotkey to perform deletion of Object once all direct references are freed.
You can use this to avoid circular references.
usage: newIndirectReference := new indirectReference( object, modes := { __Set:0, __Get:0, __Delete:0 } )
newIndirectReference: The indirect reference towards the objects passed to the constructor
object: The object you want to refer to indirectly
modeOrModeStr: Controls how the indirectReference is connected to the object directly
e.g. with a __Call mode all method calls towards the indirectReference will end up calling the same method with the same parameters in the object
*/
class indirectReference
{
static relationStorage := {}
static performanceStorage := {}
static accessStorage := {}
static modeStorage := {}
static baseModes := { __Call:indirectReference.Call, __Set:indirectReference.Set, __Get:indirectReference.Get, __New:indirectReference.New, __Delete:indirectReference.Delete, _NewEnum:"" }
__New( obj, modeOrModeStr := "__Call" )
{
if !isObject( obj )
return
if isObject( modeOrModeStr )
{
str := ""
For modeName, val in modeOrModeStr
str .= modeName . "|"
modeOrModeStr := subStr( str, 1, -1 )
}
if !indirectReference.performanceStorage.hasKey( &obj )
{
indirectReference.performanceStorage[ &obj ] := []
indirectReference.accessStorage[ &obj ] := []
obj.base := { __Delete: indirectReference.DeleteObject, base: obj.base }
}
if ( !indirectReference.performanceStorage[ &obj ].hasKey( modeOrModeStr ) | deleteMode := inStr( modeOrModeStr, "__Delete" ) )
{
if !indirectReference.modeStorage.hasKey( modeOrModeStr )
{
newMode := {}
for each, mode in strSplit( modeOrModeStr, "|" )
{
newMode[ mode ] := indirectReference.baseModes[ mode ]
indirectReference.baseModes[ mode ]
}
indirectReference.modeStorage[ modeOrModeStr ] := newMode
}
newReference := { base: indirectReference.modeStorage[ modeOrModeStr ] }
indirectReference.accessStorage[ &obj ].Push( &newReference )
indirectReference.relationStorage[ &newReference ] := &obj
if !deleteMode
indirectReference.performanceStorage[ &obj, modeOrModeStr ] := newReference
else
return newReference
}
return indirectReference.performanceStorage[ &obj, modeOrModeStr ]
}
DeleteObject()
{
for each, reference in indirectReference.accessStorage[ &This ]
{
indirectReference.relationStorage.delete( reference )
Object( reference ).base := ""
}
indirectReference.accessStorage.Delete( &This )
indirectReference.performanceStorage.Delete( &This )
if ( isFunc( This.base.base.__Delete ) && This.base.base.__Delete.name != indirectReference.DeleteObject.name )
{
This.base := This.base.base
This.__Delete()
}
}
Call( functionName = "", parameters* )
{
if !( indirectReference.baseModes.hasKey( functionName ) && !This.base.hasKey( functionName ) )
return ( new directReference( This ) )[ functionName ]( parameters* )
}
Set( keyAndValue* )
{
Value := keyAndValue.Pop()
return ( new directReference( This ) )[ keyAndValue* ] := Value
}
Get( key* )
{
return ( new directReference( This ) )[ key* ]
}
New( parameters* )
{
newIndirectReference := This.base
This.base := ""
__class := new directReference( newIndirectReference )
return new __class( parameters* )
}
Delete()
{
return ( new directReference( This ) ).__Delete()
}
}
/*
CLASS directReference
description: creates direct References from indirect ones.
usage: object := new directReference( newIndirectReference )
newIndirectReference: A indirectReference created by calling new indirectReference( object )
object: The object that is refered to by the indirectReference
*/
class directReference
{
__New( reference )
{
return Object( indirectReference.relationStorage[ &reference ] )
}
}