Joined: December 26th, 2005, 4:40 pm Posts: 8776
|
Quote: FA() - A Tiny 2L Function to maintain a single dimension UINT array
Code: FA(E=0,V="",S="") { ; www.autohotkey.com/forum/viewtopic.php?p=242750#242750 Static C,P Return ((E+0)>=0&&V="")?(NumGet(P+0,E*4)):(E&&(V+0)>=0)?(NumPut(V,P+0,E*4)-4):(S="+"&&V >0)?((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V):(S="-"&&V>0)?((O:=NumPut((V:=NumGet(E*4 +P)-V),E*4+P))-O+V):(E>0&&V="Init")?(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P):(E ="Rel"&&P)?((P:=0)+VarSetCapacity(C,0)+1):(E="Ptr"&&P) ? P : "" }
; The above ternary version was derived from following code
/*
FA( E=0,V="",S="" ) { Static C,P
If ((E+0)>=0&&V="") ; NumGet Return (NumGet(P+0,E*4))
If (E&&(V+0)>=0) ; NumPut Return (NumPut(V,P+0,E*4)-4)
If (S="+"&&V>0) ; NumAdd Return ((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V)
If (S="-"&&V>0) ; NumSub Return ((O:=NumPut((V:=NumGet(E*4+P)-V),E*4+P))-O+V)
If (E>0&&V="Init") ; Init Var Return,(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P)
If (E="Rel"&&P) ; Release Var Return ((P:=0)+VarSetCapacity(C,0)+1)
If (E="Ptr"&&P) ; Obtain Pointer Return P } */
The primary objective of this function is to provide a mechanism to share Integers between functions, thereby avoiding a clutter of Global variables. In short, FA() is a function that acts as an single dimension array
The parameters are cumbersome to document, and so, I provide here example calls, instead.
Basic:
Code: FA(10,"Init") ; Initialise capacity for 10 UINT elements ; Returns the Static Variable's size
FA(6,25000) ; Put 25000 in element 6 ; Returns the pointer to the UINT
FA(4,0) ; Nullify element 4 ; same as above
FA(7) ; Return the value stored in element 7
Extended: Support for counters.
Code: FA(6,1230,"+") ; Increment the value stored in element 6 by 1230 ; Returns the new value
FA(6,1230,"-") ; Decrement the value stored in element 6 by 1230 ; Returns the new value
For any further manipulation, the pointer to the array can be retrieved..
Code: FA("Ptr")
..and to release/reset the array
Code: FA("Rel")
My Requirement: With forth-coming release: 1.0.48, using ProcAddress directly in DllCall() would increase the performance significantly. I needed a mechanism to initialise the and share the ProcAddresses between many functions of the same wrapper - without creating global variables, and hence I wrote FA()
The following is a dumb, but working example of my intended use.
Code: MsgBox, % FormatBytes( GetFileSize( A_AhkPath ) ) MsgBox, % FormatBytes( GetFileSize( A_ScriptFullPath ) )
GetFileSize( File ) { ; 4GB Limit Static Init,FOpen,FSeek,FClose If !Init Init:=InitAPI(), FOpen:=FA(1),FSeek:=FA(3),FClose:=FA(4) If ( H := DllCall(FOpen,Str,File,Int,0x0) ) < 1 Return H FilePointer := DllCall(FSeek,Int,H,Int,0,Int,2), DllCall(FClose,UInt,H) Return FilePointer }
FormatBytes( Bytes ) { Static FormatBytes If !FormatBytes FormatBytes:=FA(11), VarSetCapacity(Formatted,16) DllCall(FormatBytes, Int64,Bytes, Str,Formatted, UInt,16 ) Return Formatted }
InitAPI() { Static Funx IfNotEqual,Funx,,Return,Funx FA( 20, "Init" ) ; Initialise 20 UINT elements
Kernel32 := DllCall( "GetModuleHandle", Str,"Kernel32.dll" ) FA( 1, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lopen" ) ) FA( 2, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lread" ) ) FA( 3, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_llseek" ) ) FA( 4, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lclose" ) ) FA( 5, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lcreat" ) ) FA( 6, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lwrite" ) ) FA( 7, DllCall( "GetProcAddress", UInt,Kernel32, Str,"RtlMoveMemory" ) )
ShlwAPI := DllCall( "LoadLibrary", Str,"Shlwapi.dll" ) FA( 11, DllCall( "GetProcAddress", UInt,ShlwAPI, Str,"StrFormatByteSize64A" ) ) ; unused elements are for future use Return (Funx:=1) }
FA(E=0,V="",S="") { ; www.autohotkey.com/forum/viewtopic.php?p=242750#242750 Static C,P Return ((E+0)>=0&&V="")?(NumGet(P+0,E*4)):(E&&(V+0)>=0)?(NumPut(V,P+0,E*4)-4):(S="+"&&V >0)?((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V):(S="-"&&V>0)?((O:=NumPut((V:=NumGet(E*4 +P)-V),E*4+P))-O+V):(E>0&&V="Init")?(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P):(E ="Rel"&&P)?((P:=0)+VarSetCapacity(C,0)+1):(E="Ptr"&&P) ? P : "" }
Last edited by SKAN on July 12th, 2009, 7:13 am, edited 2 times in total.
|
|