AutoXenon Posted December 15, 2021 Posted December 15, 2021 Hello, I'm more or less a layman to programming, only experience is with Autoit, and am completely unfamiliar with the general practices of Object-Oriented languages. As an exercise, I'm creating my first UDF that sort of emulates Objects via built-in Autoit functions. I know it's completely terrible with ill-advised abuses of the language, it's just purely for the purpose of exploration as well as trying to learn what coding an UDF that is usable by other people should entail. Please don't hesitate to point out spots where it's total heresy to unintended uses of functionalities, I have some guesses as to which ones are considered bad but it's nice to get some confirmation of _how_ and why it's bad, as an opportunity for learning an anti-example Here is what I have for the UDF so far, it's really simplistic and it's coded assuming that the user knows exactly what the functions expect, without any sort of error or exception handling: expandcollapse popupFunc _ObjBuild(ByRef Const $arr) Local $size = UBound($arr, 1)+1 Local $self[$size][3], $def = "PTR self;" For $i=1 to $size-1 ; $def = $def & "PTR " & $arr[$i-1][0] & ";" $def = $def & "PTR " & $arr[$i-1] & ";" Next $self[0][0] = DllStructCreate($def) $self[0][1] = "self" $self[0][2] = Null DllStructSetData($self[0][0], $self[0][1], Ptr(0)) For $i=1 to $size-1 $self[$i][0] = Null ; $arr[$i-1][1] $self[$i][1] = $arr[$i-1] ; $arr[$i-1][0] $self[$i][2] = Null ; $arr[$i-1][2] DllStructSetData($self[0][0], $self[$i][1], Ptr($i)) Next Return $self EndFunc Func _ObjClone(ByRef Const $arr) Local $size = UBound($arr, 1), $def = "" For $i=0 to $size-1 $def = $def & "PTR " & $arr[$i][1] & ";" Next Local $newarr[$size][3] $newarr[0][0] = DllStructCreate($def) $newarr[0][1] = $arr[0][1] $newarr[0][2] = $arr[0][2] DllStructSetData($newarr[0][0], $newarr[0][1], Ptr(0)) For $i=1 to $size-1 $newarr[$i][0]=$arr[$i][0] $newarr[$i][1]=$arr[$i][1] $newarr[$i][2]=$arr[$i][2] DllStructSetData($newarr[0][0], $newarr[$i][1], Ptr($i)) Next Return $newarr EndFunc Func _ObjSet(ByRef $arr, Const ByRef $key, Const ByRef $val, Const $type=Null) Local $index = DllStructGetData($arr[0][0], $key) If $index Then $arr[$index][0] = $val Else Local $size = UBound($arr, 1)+1, $def = "" ReDim $arr[$size][3] $arr[$size-1][0]=$val $arr[$size-1][1]=$key $arr[$size-1][2]=$type For $i=0 to $size-1 $def = $def & "PTR " & $arr[$i][1] & ";" Next $arr[0][0] = DllStructCreate($def) For $i=0 to $size-1 DllStructSetData($arr[0][0], $arr[$i][1], Ptr($i)) Next EndIf EndFunc Func _ObjGet(ByRef $self, Const ByRef $name, Const $args=Null) Local $index = DllStructGetData($self[0][0], $name) Local $func=$self[$index][0], $type=$self[$index][2] Local $exec="$func" Switch $type Case True $exec = $exec & "($self" If IsArray($args) Then For $i = 0 to UBound($args)-1 If $i=0 Then $exec = $exec & "," $exec = $exec & "$args[" & String($i) & "]" If $i<UBound($args)-1 Then $exec = $exec & "," Next EndIf $exec = $exec & ")" Case False $exec = $exec & "(" If IsArray($args) Then For $i = 0 to UBound($args)-1 $exec = $exec & "$args[" & String($i) & "]" If $i<UBound($args)-1 Then $exec = $exec & "," Next EndIf $exec = $exec & ")" EndSwitch Return Execute($exec) EndFunc Func _ObjArg($arg1=Null, $arg2=Null, $arg3=Null, $arg4=Null, $arg5=Null, $arg6=Null, $arg7=Null, $arg8=Null) Local $retArr[@NumParams] If @NumParams Then For $i=1 to @NumParams $retArr[$i-1] = Execute("$arg" & String($i)) Next EndIf return $retArr EndFunc Here is an example of how it might be used: expandcollapse popup#include "objUDF.au3" ExampleUDFUsage() Func ExampleUDFUsage() Local $class = ["time","position","velocity","acceleration"] Local $obj = _ObjBuild($class) Local $pos = [420,69,100] Local $vel = [320,270,0] Local $acc = [0,-200,0] _ObjSet($obj, "time", 0) _ObjSet($obj, "position", $pos) _ObjSet($obj, "velocity", $vel) _ObjSet($obj, "acceleration", $acc) _ObjSet($obj, "next_pos", Calc_Kinematics, True) _ObjSet($obj, "dist", DistanceFromPoint, True) _ObjSet($obj, "quit", ExitProgram, False) $time = _ObjGet($obj, "time") $pos = _ObjGet($obj, "position") $vel = _ObjGet($obj, "velocity") MsgBox(0, "Initial State t=" & $time, "Position: " & $pos[0] & ", " & $pos[1] & ", " & $pos[2] & @CRLF & "Velocity: " & $vel[0] & ", " & $vel[1] & ", " & $vel[2]) Local $nowtime, $lasttime=0, $epoch=TimerInit() Do $nowtime = TimerDiff($epoch) AdvancePhysicsState($obj, ($nowtime-$lasttime)*0.001) $lasttime = $nowtime $time = _ObjGet($obj, "time") $pos = _ObjGet($obj, "position") $vel = _ObjGet($obj, "velocity") Until 7=MsgBox(4, "State: t=" & $time, "Position: " & $pos[0] & ", " & $pos[1] & ", " & $pos[2] & @CRLF & "Velocity: " & $vel[0] & ", " & $vel[1] & ", " & $vel[2] & @CRLF & @CRLF & "Calculate next step?") $time = _ObjGet($obj, "time") $pos = _ObjGet($obj, "position") $vel = _ObjGet($obj, "velocity") MsgBox(0, "Final State t=" & $time, "Position: " & $pos[0] & ", " & $pos[1] & ", " & $pos[2] & @CRLF & "Velocity: " & $vel[0] & ", " & $vel[1] & ", " & $vel[2]) MsgBox(0, "Distance From Starting Point", _ObjGet($obj, "dist", _ObjArg(420,69,100))) _ObjGet($obj, "quit") EndFunc Func LoopPhysics(ByRef $obj) EndFunc Func AdvancePhysicsState(ByRef $obj, $dt) _ObjGet($obj, "next_pos", _ObjArg($dt)) EndFunc Func DistanceFromPoint(ByRef $self, $x, $y, $z) Local $pos = _ObjGet($self, "position") Local $dx = $pos[0]-$x Local $dy = $pos[1]-$y Local $dz = $pos[2]-$z Return Sqrt($dx*$dx + $dy*$dy + $dz*$dz) EndFunc Func Calc_Kinematics(ByRef $self, $dt) Local $time = _ObjGet($self, "time") Local $pos = _ObjGet($self, "position") Local $vel = _ObjGet($self, "velocity") Local $acc = _ObjGet($self, "acceleration") $time += $dt For $i=0 to Ubound($pos)-1 $pos[$i] += ( (0.5 * $acc[$i] * $dt * $dt) + ($vel[$i] * $dt) ) Next For $i=0 to Ubound($vel)-1 $vel[$i] += ($acc[$i]*$dt) Next _ObjSet($self, "time", $time) _ObjSet($self, "position", $pos) _ObjSet($self, "velocity", $vel) EndFunc Func ExitProgram() MsgBox(0,"Bye","See Ya.") Exit EndFunc
Moderators JLogan3o13 Posted December 17, 2021 Moderators Posted December 17, 2021 There is a section on the Wiki with some guidelines and Best Practices. Have you read it? UDF-spec - AutoIt Wiki (autoitscript.com) "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
junkew Posted January 3, 2022 Posted January 3, 2022 Nice to see some oo udf attempts Maybe you can get some ideas from this one https://github.com/genius257/AutoIt-projects/tree/master/AutoItObject Internal FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now