Class > __New() -- DefineProp() weirdness with Buffer() Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
TheArkive
Posts: 1030
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Class > __New() -- DefineProp() weirdness with Buffer()

04 Nov 2022, 11:04

This is a simplified template that I use to map out a struct into an obj that is usable obj in AHK:

Code: Select all

t := TestClass()

msgbox "size: " t.size "`n"
     . "ptr: " t.ptr " / " t.buf.ptr " (equal: " (t.ptr = t.buf.ptr) ")"

class TestClass {
    __New(ptr:=0) {
        Static size := 8
        f := {size:{t:"UInt", o:0}, field2:{t:"UInt", o:4}} ; field data (type and offset)
        
        ; ============================================================================
        ; 1) size IS NOT initialized, ptr MISMATCH = doesn't work
        ; ============================================================================
        this.DefineProp("buf", {Get:(o) => (ptr ? {ptr:ptr,size:size} : Buffer(size,0))})
        this.DefineProp("ptr", {Get:(o) => this.buf.ptr})
        
        ; ============================================================================
        ; 2) size IS initialized, ptr MISMATCH = works / unsafe
        ; ============================================================================
        ; this.DefineProp("buf", {Get:(o) => (ptr ? {ptr:ptr,size:size} : Buffer(8,0))})
        ; this.DefineProp("ptr", {Value:this.buf.ptr})
        
        ; ============================================================================
        ; 3) size IS initialized, ptr MATCH = works / safe
        ; ============================================================================
        ; this.DefineProp("buf", {Value: (ptr ? {ptr:ptr,size:size} : Buffer(8,0))})
        ; this.DefineProp("ptr", {Get:(o) => this.buf.ptr})
        
        ; ============================================================================
        ; 4) size IS initialized, ptr MATCH = works / safe
        ; ============================================================================
        ; this.DefineProp("buf", {Value: (ptr ? {ptr:ptr,size:size} : Buffer(8,0))})
        ; this.DefineProp("ptr", {Value:this.buf.ptr})
        ; ============================================================================
        
        this.DefineProp("f"  , {Get:(o) => f}) ; to access field data (type and offset)
        
        this.size := size ; init the size property
    }
    __Get(name,p) => NumGet(this.ptr, this.f.%name%.o, this.f.%name%.t)
    __Set(name,p,value) => NumPut(this.f.%name%.t, value, this.ptr, this.f.%name%.o)
}

I usually map the buffer to the buf property, and the ptr of the buf separately to the ptr property. The strangeness comes with using {Get:...} or {Value:...} as the descriptor.

I usually try to use {Get:...} in order to ensure a property is read only, as a built-in means to make sure the user can't use the object other than intended. But it seems that when using a buffer I must use {Value:...}, otherwise the reported ptr of the buffer is actually wrong when I map the ptr property.

I hope this isn't too obscure. I tried to map it out as clearly as possible.

So I know what I need to do to "make it work". Basically options #3 and #4 above work fine. And the key is to ensure that the buf property is mapped with {Value:...} instead of {Get:...}.

But I'm wondering if this might be a bug? Or did I miss something in the docs that explains the mismatched ptr when using options #1 and #2?

Thanks for any explanation on this matter. I've been chasing this issue for a while and have finally narrowed it down to a smaller case that is easy to replicate.
Last edited by TheArkive on 04 Nov 2022, 11:49, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Class > __New() -- DefineProp() weirdness with Buffer()  Topic is solved

04 Nov 2022, 11:22

a()=>b() will call b every time you call a, and only then.

Cheers.
User avatar
TheArkive
Posts: 1030
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Class > __New() -- DefineProp() weirdness with Buffer()

04 Nov 2022, 11:26

Thanks @Helgef.

So if I'm not mistaken, it's actually calling a new buffer every time in option #1 and #2 then?

That would explain a lot :facepalm:
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Class > __New() -- DefineProp() weirdness with Buffer()

04 Nov 2022, 11:31

That is correct.

Also note that this.DefineProp("ptr", {Get:(o) => this.buf.ptr}) creates a circular reference, better to use o.buf.ptr.

Cheers
User avatar
TheArkive
Posts: 1030
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Class > __New() -- DefineProp() weirdness with Buffer()

04 Nov 2022, 11:35

Ah, I see. That too would make more sense :facepalm:

But if it is circular, shouldn't the script crash or halt? I never get a crash/halt when calling it.
User avatar
TheArkive
Posts: 1030
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Class > __New() -- DefineProp() weirdness with Buffer()

04 Nov 2022, 11:46

Ah, and thus a memory leak was born.

Thanks again @Helgef :D :thumbup:

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Descolada, robinson, teadrinker and 38 guests