JohnOne Posted December 18, 2013 Share Posted December 18, 2013 (edited) Hey M23. Would you mind telling me in your words, what the OP is after? Because I still don't know EDIT: I've a sneaky feeling that whatever it is the OP wants, might better be achieved using beta, with its function in variable syntax. Edited December 18, 2013 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 18, 2013 Moderators Share Posted December 18, 2013 JohnOne,The basic problem as I understand it is how to update a Local variable from another function which is not being called directly by the original function in which the variable is located. Given that Local variables are not modifiable unless passed ByRef this would seem to be impossible. The short psuedo-code I posted at #14 shows the desired functionality.As we showed, you can do it by using structs - but the overhead is even worse than using a Global variable, which the OP does not want to do in view of the desired "cut-and-paste" modularity of the function. Personally I feel he is asking too much of AutoIt - but there are some excellent coders here who can work apparent miracles so there is always hope. Any clearer?M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted December 18, 2013 Share Posted December 18, 2013 Cheers. I'll let you know once I go through #14 again. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted December 18, 2013 Share Posted December 18, 2013 (edited) Still none the wiser, just cannot get which function this variable needs to be retained in. AFAIK this does the same as #17 Main() Func Main() Local $initialA = 3, $b = 0 Local $Retain_This_Value = $initialA test($initialA, True) test($b) ConsoleWrite("At the end, $a = " & $initialA & @LF) EndFunc ;==>_Main Func test(ByRef $pointerToResultVar, $fFlag = False) Static $staticPointerToResultVar If $fFlag Then $staticPointerToResultVar = $pointerToResultVar EndIf Local $oldA = $staticPointerToResultVar ConsoleWrite($oldA & @LF) EndFunc ;==>_test Edited December 18, 2013 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) @Lars This is basicly a good idea but, the example misses to show, that the 2. call comes from another fcn which itself cannot reach $a @JohnOne what is the ".. function in variable syntax." ? The difference to post #17 is, that fcn test can manipulate $a in the workspace of fcn main while in the example you cited this is not possible. $a is 3 there and stays 3. But the detour with the dll struct is ...well not very easy to use. The roleplay is: Caller1: "Hey Fcn test do something for me and store it in the variable i provide to you ( byRef )" Caller2: "Hey Fcn test do something else an store it the results in the variable you received from Caller1 to which I got no access Edited December 18, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted December 18, 2013 Share Posted December 18, 2013 Could you possibly comment your code from #17 a little more with what's going on? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) expandcollapse popupMain() Func Main() Local $initialA = 3, $b = 0 $a = DllStructCreate( "int var1" ) ; [ 1 ] $a is the variable that "test" should get access to DllStructSetData( $a , "var1", $initialA ) test( DllStructGetPtr($a) , True ) ; [ 2 ] now we give the pointer of $a to "test" so that it can access it test( $b ) ConsoleWrite("At the end, $a = " & DllStructGetData( $a , "var1" ) & @LF ) EndFunc Func test( $pointerToResultVar , $fFlag = False ) Static $staticPointerToResultVar If $fFlag Then $staticPointerToResultVar = $pointerToResultVar ; [ 3 ] here the access to $a is preserved for later calls EndIf Local $a $a = DllStructCreate( "int var1" , $staticPointerToResultVar ) $oldA = DllStructGetData( $a , "var1" ) ConsoleWrite( $oldA & @LF ) DllStructSetData( $a , "var1" , $oldA + 1 ) ; [ 4 ] and finally we can directly set $a without the need of "byRef" EndFunc ;==>test ...well I feel I have explained it now so many times I am a bit confused. Is the thread tite so bad chosen? "Static + ByRef" > if you try to maintain the access you get by "byRef" through a Static variable for the next call of the function (without this "byRef") then this is not possible? When assiging to a static variable you do not assign the access ( c++ pointer behavior ) but a copy of the variable. Thats bad for my purpose, and I asket for solutions. What is the confusing point? Edited December 18, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted December 18, 2013 Share Posted December 18, 2013 Nope, still not sure I'm getting it, I'm sorry if I'm frustrating you but rest assured I'm just as frustrated trying to figure it out. Is this correct. You want a function, anywhere in your script to be able to access and manipulate a variable, without having a global variable anywhere in your script? If so, what about and environment variable, that any good? EnvSet() EnvGet() AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) Sorry for sounding frustrated, I mean you spend your time for me! Thank you very much! The discussion is just a bit repetitive to the one I had with melba. I do not want global variables because: 1. they can cause conflicts ( so good so known ) 2. its not a single script problem, the function must be modular, > who ever calls it must get its individual results ( but without waiting for the fcn ) EnvSet() is just the same as a global variable but with some disadvantages ( slower and you have to refresh the enviroment, just not the purpose of EnvSet() ) Now dont get me wrong, I dont want to overstretch autoit. I just saw it has a pointer-behavior ( "byRef" ) build in which not every language has. But the pointer is lost when the fcn leaves ( as the whole workspace is by definition execpt for Static variables ). So I would need to give the access with "byRef" again on the second call. And here is the pity: The second call comes from another caller ( a timer event ) which does not have the access to the variable anymore.... So I had the choise: developing a costly workaround < or > asking the experts if static + byRef is possible and it ended up in a costly discussion ^^ which is ok as I ( and others ) can learn something best regards Blues Edited December 18, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 18, 2013 Moderators Share Posted December 18, 2013 (edited) Bluesmaster,No need to apologise for being frustrated - we quite understand. As I said to JohnOne earlier, I fear you are pushing well beyond the boundaries of a relatively simple language like AutoIt. Hence your difficulties in getting us simple folk to even understand the problem you wish to solve. I have kept an eye on the thread this afternoon and some of the very best AutoIt coders have looked in - the fact that they have not posted makes me think that there is no solution. Although now I have said that someone will no doubt produce one in the next post! However, after some more thought I will take issue with your dislike of Global variables. Why not use the API approach that so many of us use in our UDFs? Use a Global variable but hide it within an include like this:<snip> See better example belowHow does that look? Still modular - except it is an include file not a single function. M23 Edited December 19, 2013 by Melba23 Code removed Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted December 18, 2013 Share Posted December 18, 2013 Interesting thought M23. Working with that Idea, our beloved AutoIt3 allows Us to do this. #AutoIt3Wrapper_Run_AU3Check=n _Main() Func _Main() Local $initialA = 3, $b = 0 _Test($initialA) _Test($b) _Test($b) ConsoleWrite("> " & $initialA & @LF) EndFunc ;==>_Main Func _Test(ByRef $PassedArg) Static $Called = 0 If Not $Called Then Global $TheVar = $PassedArg $Called = 1 EndIf ConsoleWrite($TheVar & @LF) $TheVar += 1 $PassedArg = $TheVar + 1 EndFunc ;==>_test Or something similar. So although it's there, the caller does not have to create a global. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 19, 2013 Moderators Share Posted December 19, 2013 Hi,After a good night's sleep I have developed a better example of the concept:expandcollapse popup#include <Timers.au3> ; This is an include file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global $g_TheVariable Func _Set_Var($vVar) $g_TheVariable = $vVar EndFunc Func _Get_Var() Return $g_TheVariable EndFunc Func _Func_Include($vW, $vX, $vY, $vZ) If IsString($vW) Then $g_TheVariable = $vY Else $iSec = @SEC ConsoleWrite("Timer fired at " & $iSec & @CRLF) $g_TheVariable = $iSec _Set_Var($iSec) ConsoleWrite("+Setting Global to: " & $iSec & @CRLF) EndIf EndFunc ; End of include file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HotKeySet("{ESC}", "On_Exit") While 1 Func_1() Sleep(5000) WEnd Func Func_1($fKill = False) Static $hGUI = 0 ; Check for timer kill If $fKill Then _Timer_KillAllTimers($hGUI) Return EndIf If $hGUI Then ; What do we have in the Global? ConsoleWrite("!Reading from Global: " & _Get_Var() & @CRLF) Else ; Initiate the whole thing ConsoleWrite("Initiating" & @CRLF) ; Create GUI $hGUI = GUICreate("Just for the timer") ; Set timer _Timer_SetTimer($hGUI, 2000, "_Func_Include", -1) ; Set default value _Set_Var(9999) EndIf EndFunc Func On_Exit() ; Kill timer Func_1(True) ; Exit Exit EndFuncThat is more like Bluesmaster wanted originally. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 19, 2013 Author Share Posted December 19, 2013 (edited) @JohnOne This seems to be a brilliant solution. Unfortunately I discovered a weakness: If you add another _Test( $b )-Call then $initialA doesnt increase anymore. The example in this state is based on an illusion, where $initialA gets increased by 2 at once. The global variable is a copy and not an access token, similar to the static approach. I would really like to rescue that idea because its so fantastic simple. @M23 I need some time to understand that concept, I will write back later. Thank you. Blues Edited December 19, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted December 19, 2013 Share Posted December 19, 2013 @JohnOne This seems to be a brilliant solution. Unfortunately I discovered a weakness: If you add another _Test( $b )-Call then $initialA doesnt increase anymore. The example in this state is based on an illusion, where $initialA gets increased by 2 at once. The global variable is a copy and not an access token, similar to the static approach. I would really like to rescue that idea because its so fantastic simple. @M23 I need some time to understand that concept, I will write back later. Thank you. Blues That's weird that, and at first glance it seems to be a bug, only incrementing a few. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 19, 2013 Author Share Posted December 19, 2013 (edited) Ok, I think I understood. The function ensures, that the global variable is not declared elsewhere and causing conflicts. This is an interesting approach, that I could need in the future. However, the conflict-argument is not so important as it can be dam by using prefixes and so on. More important to me was the fact that global variables are simply against the nature of functions, especialy modular, reusable functions. Functions have input and output. Thats it. If one of the input is a access to a variable of the caller thats fine, but I have never seen a UDF telling me: "If you use this function you can get your results from the global variable <foo>" As you said, this is possibly a bit to much for a handy scripting language. If I reflect it properly, what I want is the function to be an object in the sense of object oriented programming. I call my function and expect it to store individual results just as an object. For me the best workaround seems to be this $TestCounter = 1 test( "TestCounter" ) ConsoleWrite( $TestCounter & @LF ) Func test( $nameOfGlobalResultVariable ) Execute( "global " & $nameOfGlobalResultVariable ) Assign( $nameOfGlobalResultVariable , 3 ) EndFunc Its not perfect but the best compromise between simplicity and proper interface. PS: why havnt you told me about "adlibregister" and let me perform the complicated timer-gui-message-construction? ^^ kind regards Edited December 19, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 19, 2013 Moderators Share Posted December 19, 2013 Bluesmaster, but I have never seen a UDF telling me: "If you use this function you can get your results from the global variableThen you have not looked at many UDFs - it is a very common method to keep things simple for the user. Look at my GUIListViewEx UDF for example - once you have initiated a listView and stored the integer return value all you need is to use that integer to do all sorts of things. You can access the current content, edit an item or header, set the ListView as active for data manipulation, etc. The UDF uses a fair few Global variables (including a fairly hefty array) but these are completely hidden from the user who only needs to use the public functions to get the UDF to work. Let me know if I can help you work out a way to get your required result using this concept. M23P.S. As to AdlibRegister I just assumed given the complexity of the example you posted there was a valid reason for you to use the timer construct. And there is a Help file for you to browse through and look for useful functions. Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted December 19, 2013 Share Posted December 19, 2013 The caller does not have to get the result from the global variable, they do not even have to know it's there if you use the return value. #AutoIt3Wrapper_Run_AU3Check=n _Main() Func _Main() Local $initialA = 3, $b = 0, $Val = 0 $Val = _Test($initialA) $Val = _Test($b) $Val = _Test($b) $Val = _Test($b) $Val = _Test($b) $Val = _Test($b) $Val = _Test($b) ConsoleWrite("> " & $Val & @LF) $first = 0 ; If you want first called value _Test($first, 1) ConsoleWrite("- " & $first & @LF) EndFunc ;==>_Main Func _Test(ByRef $PassedArg, $FirstCalled = 0) Static $Called = 0 If Not $Called Then Global $TheVar = $PassedArg $Called = $PassedArg EndIf If $FirstCalled Then $PassedArg = $Called Return EndIf ConsoleWrite($TheVar & @LF) $TheVar += 1 Return $TheVar EndFunc ;==>_test AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 19, 2013 Author Share Posted December 19, 2013 The caller does not have to get the result from the global variable But this was the intention of my request. The solution you provided is an identifier system. The caller gets it results by providing an aditional identifier ( in this case just a "1" ) This is ok if you got one caller. But if you got lets say 10 callers who all need their different results you need: - a more complex system. - the caller has in any way to maintain this identifier - the caller has to call the function again later on All this I wanted to avoid and it occurs, that is not possible. This is ok, I just wanted to know if this is real the case, because I am relativly new to autoIt. The best thing I learned is that autoIt has an active and motivated community which is the best argument to continue working with it Thank you Blues My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted December 19, 2013 Share Posted December 19, 2013 Yeah, it's a bit of a bastard really. You know that objects obey static too? I made an example of it a while back >here and >here It's not impossible that you might find a way it can help you. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 19, 2013 Author Share Posted December 19, 2013 I really miss structs in autoIt so this is definitly a snippet for my library. But at least it a contradiction to the basic target: simplicity So let us just accept its not possible. Sometimes one wins sometimes not. Thank you all for your kind help regards Blues My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
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