-
Notifications
You must be signed in to change notification settings - Fork 6
/
struct.ahk
51 lines (49 loc) · 1.74 KB
/
struct.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
class ValueType extends RtAny {
static Call() {
proto := this.Prototype
b := Buffer(proto.Size, 0)
return {ptr: b.ptr, _buf_: b, base: proto}
}
; static FromPtr(ptr) {
; return {ptr: ptr, base: this.Prototype}
; }
static FromOffset(buf, offset) {
return {ptr: buf.ptr + offset, _outer_: buf, base: this.Prototype}
}
CopyToPtr(ptr) {
DllCall('msvcrt\memcpy', 'ptr', ptr, 'ptr', this, 'ptr', this.Size, 'cdecl')
}
}
class EnumValue extends RtAny {
static Call(n) {
if e := this.__item.get(n, 0)
return e
return {n: n, base: this.prototype}
}
static Parse(v) { ; TODO: parse space-delimited strings for flag enums
if v is this
return v.n
if v is Integer
return v ; this[v].n would only permit explicitly defined values, but Parse is currently used for all enum args, so this isn't suitable for flag enums.
if v is String
return this.%v%.n
throw TypeError(Format('Value of type "{}" cannot be converted to {}.', type(v), this.prototype.__class), -1)
}
s => String(this.n) ; TODO: produce space-delimited strings for flag enums
ToString() => this.s
}
_rt_CreateEnumWrapper(t) {
w := _rt_CreateClass(t.Name, EnumValue)
t.DefineProp 'Class', {value: w}
def(n, v) => w.DefineProp(n, {value: v})
def '__item', items := Map()
for f in t.Fields() {
switch f.flags {
case 0x601: ; Private | SpecialName | RTSpecialName
def '__basicType', f.type
case 0x8056: ; public | static | literal | hasdefault
def f.name, items[f.value] := {n: f.value, s: f.name, base: w.prototype}
}
}
return w
}