[a119] Associative or Pseudo- Arrays and Dereferencing Numbers Topic is solved

Discuss the future of the AutoHotkey language
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 16:08

@swagfag
now, u can only do obj:={keyN:"valueN"} to define a property with the literal name obj.keyN;
or obj:={%keyN%:"valueN"} to define a property with the value of the variable keyN
(before) {"keyN":"valueN"}: I was able to copy-paste JSON's syntax as is into AHK obj's {} initialization body. {(keyN):"valueN"} syntax seemed appropriate - (expr) that returns a property name.
(now) {keyN:"valueN"} could be used to access a value of keyN variable and use it as a property name. With previous {"keyN":"valueN"} syntax for immediate (literal) property names.
why is that u may ask? @lexikos probably has a grander vision for where the parser development is headed
R u being sarcastic here? :D
Well, I didn't ask questions after that update and simply used regex to change all my scripts at once and be done with it. :D yet I'm curious what caused that change?
swagfag
Posts: 4080
Joined: 11 Jan 2017, 17:59

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 17:17

was able to copy-paste JSON's syntax as is
cool, i guess. a convenient byproduct of the old syntax, but is straight up pasting json into the guts of data structures, it cant even properly map to, the use-case to base the language design on? id rather have/use a proper parser instead
{(keyN):"valueN"} syntax seemed appropriate - (expr) that returns a property name.
what caused that change?
probably to keep parity with %% being the-thing-that-evaluates-expressions/looks-up-variables
no, im not being sarcastic lol. personally, i find it makes total sense for it to be this way:
  • it mimics accessing properties - obj := {keyN: ...} unquoted; obj.keyN := ... unquoted
  • it mimics accessing properties dynamically - obj := {%keyN%: ...} percents; obj.%keyN% := ... percents
  • most of the times u arent gonna have to both instantiate an object and manually define dynamically named properties at the same time
  • for the rare times that u have to, u can
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 17:39

swagfag wrote:
30 Jul 2020, 17:17
  • it mimics accessing properties - obj := {keyN: ...} unquoted; obj.keyN := ... unquoted
  • it mimics accessing properties dynamically - obj := {%keyN%: ...} percents; obj.%keyN% := ... percents
Agree on that. I explained it to myself that time it mimics javascript's object initializer (especially new 2015 syntax).

Code: Select all

let object = {
  foo: 'bar',
  age: 42,
  baz: {myProp: 12}
}
id rather have/use a proper parser instead
Definitely. Just it is possible to express indirect (not immediate) key names w/o %var% notation using commonly used syntax like (), [], etc. If we wanna mimic javascript then "computed" property names could have the following syntax:

Code: Select all

let i = 0
let a = {
  [prop]:'value',
  ['foo' + ++i]: i,
  ['foo' + ++i]: i,
  ['foo' + ++i]: i
}
all %var% use cases could be replaced with [var] after all.
obj.%var% -> obj.[var], %fn%() -> [fn](), {%key%:'value'} -> {[key]:'value'}
That notation has an advantage for syntax parsing and highlighting due to opening and closing brackets.
Last edited by vvhitevvizard on 30 Jul 2020, 18:02, edited 1 time in total.
iseahound
Posts: 614
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 18:00

Just trying to keep this discussion on topic. Here's what I settled for: var%'5'%.

Code: Select all

   static isBitmapEqual(ByRef pBitmap1, ByRef pBitmap2, Format := 0x26200A) {
      ; Make sure both bitmaps are valid pointers.
      if !(pBitmap1 && pBitmap2)
         return false

      ; Check if pointers are identical.
      if (pBitmap1 == pBitmap2)
         return true

      ; The two bitmaps must be the same size.
      DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap1, "uint*", Width1:=0)
      DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap2, "uint*", Width2:=0)
      DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap1, "uint*", Height1:=0)
      DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap2, "uint*", Height2:=0)

      ; Match bitmap dimensions.
      if (Width1 != Width2 || Height1 != Height2)
         return false

      ; struct RECT - https://docs.microsoft.com/en-us/windows/win32/api/windef/ns-windef-rect
      Rect := BufferAlloc(16, 0)                     ; sizeof(Rect) = 16
         , NumPut(  "uint",   Width1, Rect,  8)      ; Width
         , NumPut(  "uint",  Height1, Rect, 12)      ; Height

      ; Do this twice.
      while ((i:=IsSet(i)?i:0)++ < 2) { ; for(int i = 0; i < 2; i++)

         ; Create a BitmapData structure.
         BitmapData%i% := BufferAlloc(16+2*A_PtrSize, 0)  ; sizeof(BitmapData) = 24, 32

         ; Transfer the pixels to a read-only buffer. Avoid using a different PixelFormat.
         DllCall("gdiplus\GdipBitmapLockBits"
                  ,    "ptr", pBitmap%i%
                  ,    "ptr", Rect
                  ,   "uint", 1            ; ImageLockMode.ReadOnly
                  ,    "int", Format       ; Format32bppArgb is fast.
                  ,    "ptr", BitmapData%i%)

         ; Get Stride (number of bytes per horizontal line).
         Stride%i% := NumGet(BitmapData%i%,  8, "int")

         ; If the Stride is negative, clone the image to make it top-down; redo the loop.
         if (Stride%i% < 0) {
            DllCall("gdiplus\GdipCloneImage", "ptr", pBitmap%i%, "ptr*", pBitmapClone:=0)
            DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap%i%) ; Permanently deletes.
            pBitmap%i% := pBitmapClone
            i-- ; "Let's go around again! Ha!" https://bit.ly/2AWWcM3
         }

         ; Get Scan0 (top-left pixel at 0,0).
         Scan0%i%  := NumGet(BitmapData%i%, 16, "ptr")
      }

      ; RtlCompareMemory preforms an unsafe comparison stopping at the first different byte.
      size := Stride%'1'% * Height1
      byte := DllCall("ntdll\RtlCompareMemory", "ptr", Scan0%'1'%, "ptr", Scan0%'2'%, "uptr", size, "uptr")

      ; Unlock Bitmaps. Since they were marked as read only there is no copy back.
      DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap1, "ptr", BitmapData%'1'%)
      DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap2, "ptr", BitmapData%'2'%)

      ; Compare stopped byte.
      return (byte == size) ? true : false
   }
So in the above example, pseudo-arrays not being used as arrays, but just as generic variables i.e. Name1, Name2 in a routine. Objects don't make sense here, as forming a collection of Stride Width or Height individually do not make sense. What would be the point of an array with stride1, stride2, stride3, disconnected from the bitmaps that own them? It's possible to replace this with objects, but as I imagine objects they contain the different properties of an image.

To keep it short the above code demonstrates the sweet spot for pseudoarray usage. A small number of variables, use of a routine, and a situation where the speed of retrieving a variable over array access is noticeable.
swagfag
Posts: 4080
Joined: 11 Jan 2017, 17:59

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 18:01

i guess its possible for it to get changed to

Code: Select all

prop := 'p'
a := {
	[prop]: 'value
}
a.[prop] := 'some other value'
but i think lexikos said(although i cant find the exact quote now) he wanted to differentiate [ ] as purely an indexing operator, and have another operator do the property accessing.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 18:11

swagfag wrote:
30 Jul 2020, 18:01
but i think lexikos said(although i cant find the exact quote now) he wanted to differentiate [ ] as purely an indexing operator, and have another operator do the property accessing.
I see. Well, that operator better have mirroring opening&closing brackets. :D
I, for one, prefer AHK to completely copy javascript notations including = for assignment. But I feel that's wrong time and place for holy warring.

iseahound, sorry for highjacking ur topic.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

30 Jul 2020, 18:35

iseahound wrote:
30 Jul 2020, 18:00
Objects don't make sense here, as forming a collection of Stride Width or Height individually do not make sense. What would be the point of an array with stride1, stride2, stride3, disconnected from the bitmaps that own them?
Well, u definitely have candidates for 3 arrays (one for bitmapdata pointers, another for pbitmap pointers, and the third for strides).
Also u could try map to gather all them in one collection but I suppose even pseudo arrays might have better performance than maps.

As for me, I would just use static vars for strides like a,b,c,d and 2 separate static arrays for pointers: pbitmap:=[0,0], bitmapdata:=[0,0]. If u organize it this way, u could have potential to transfer that code with minimal changes to other languages, should the need arise - I feel that pixels analyzer better be compiled as C/CPP code with streaming SIMD instructions eventually and moved to a library for performance sake. :D
Helgef
Posts: 4467
Joined: 17 Jul 2016, 01:02
Contact:

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 01:28

iseahound wrote:

Code: Select all

; Do this twice.
Just add

Code: Select all

Scan01 := 0, Scan02 := 0, BitmapData1 := 0, BitmapData2 := 0, Stride1 := 0, Stride2 := 0 ; ...
instead of Scan0%'1'% etc...

I agree that dynamic variable references (again, not pseudo-arrays) makes sense for your example. Using actual arrays would make perfect sense too though. Just do Scan0 := [0, 0], Scan0[1] etc.

Spoiler
iseahound
Posts: 614
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 05:24

Windows has the ability to store bitmaps bottom-up or top-down, with the vast majority of bitmaps being top-down. If a bitmap is bottom-up then it needs to be converted to a top down bitmap. I seem to remember that the CloneImage function does this conversion, as well as force the bitmap to 32bpp.

So yes, it does look like a bitmap is being cloned, and the original is being destroyed, but during the cloning process conversions are being made.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 06:25

Code: Select all

  while ((i:=IsSet(i)?i:0)++ < 2)
That feels redundant. ->

Code: Select all

i:=0  
  while(i++ < 2)
Helgef
Posts: 4467
Joined: 17 Jul 2016, 01:02
Contact:

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers  Topic is solved

31 Jul 2020, 06:31

@iseahound, I know nothing about that, but that wasn't the point. The point was that the caller might keep a handle to the bitmap which you destroy. Using that handle after calling your function is then not safe. Anyways, you need to use continue after the decrement (i--).

Cheers.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 06:46

Helgef wrote:
31 Jul 2020, 06:31
The point was that the caller might keep a handle to the bitmap which you destroy.
Adding to ur comment: removing ByRef for both bitmap handle arguments would make it safe as well.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 08:30

Helgef wrote:
31 Jul 2020, 07:31
N o
Why not? Could u clarify ur point?
Those r handles (essentially integers). I would keep byref for [in] parameters for potentially long strings (if performance is of most importance) and for actual pointers, passed by &var (old AHK syntax) and strptr(var) (new AHK syntax). And treat all the other [in] parameters as local shadow copies to keep the function as global-variables-agnostic as possible.
Helgef
Posts: 4467
Joined: 17 Jul 2016, 01:02
Contact:

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 10:49

Could u clarify ur point?
fegleh wrote:the caller might keep a handle to the bitmap which you destroy. Using that handle after calling your function is then not safe
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: [a119] Associative or Pseudo- Arrays and Dereferencing Numbers

31 Jul 2020, 11:09

thank u. Point well taken! One of the two bitmaps gets destroyed indeed.

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 6 guests