Michiel Posted December 9, 2014 Share Posted December 9, 2014 I'm trying to partition my program into libraries, but what I do need is for functions inside those libraries to log their output to one file or one specific control. But when I'm writing and testing au3 libraries to be included by the main program, SciTE doesn't know that the functions called, such as gLog() will be present in the main program. So what I'm asking is: is there an elegant way to call functions inside the main program from inside an included library? If I'm supposed to pass a reference to the library, then where should I be doing that? I can't do it immediately when I'm running #include "..." can I? Or, am I going about this the wrong way entirely? If so, how do I realize a centralized logging facility where I can have all units writing to one file or dialog of my choosing? Link to comment Share on other sites More sharing options...
Jfish Posted December 9, 2014 Share Posted December 9, 2014 I think some clarification would be helpful (maybe some code too). When you use #include you are including the entire "library" in your main program. It is similar to just having written a large program. If you use your includes at the top of your main program then all the functions and variables will be present as the main the program runs. You can also pass messages to a log file or a GUI (hidden or visible). I am not sure what you mean by "all units". Can you explain in a bit more detail? Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
Michiel Posted December 9, 2014 Author Share Posted December 9, 2014 Meanwhile, I've started setting it up with a 'log' unit, so maybe I've got it solved for now. Try to picture it like this: MAIN.au3 UNIT #1.au3 UNIT #2.au3 UNIT #3.au3 Like all developers, I want to split off a program into units. I want those units to be able to log warnings and other messages to one main window control. Currently I use an edit control for that. Above you see my 'main' script including 'units'. Now, of course, MAIN.au3 can call any function in any UNIT.au3. But can a UNIT call a function in MAIN.au3? Right now, after my first post in this thread, I've begun writing a log.au3 with '#include-once' and with an init function that sets a local unit-wide variable to an edit control, so for now, the bases seem covered. I was just wondering what else is possible, and if, for example, it is possible to call functions in MAIN from one of those UNIT scripts you see above. Link to comment Share on other sites More sharing options...
Jfish Posted December 9, 2014 Share Posted December 9, 2014 (edited) The includes can call other functions just like it was part of one big script. Example: ; main script #include<funcincludetest.au3> func _hello() MsgBox("","","hello") EndFunc Then this is the include: ;func include test file func _callHello() _hello() EndFunc _callHello() So the above included script is calling the function from the main script. Does that answer your question? Edited December 9, 2014 by Jfish Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 9, 2014 Moderators Share Posted December 9, 2014 Michiel,I would take a different approach.You want the various #include files to use a common logging process which will display using a control in the main script. Why not put all the logging functions into another #include file which will be included by all of the other UNIT #include files? (Of course you would need to use #include-once within the logging library to prevent multiple inclusions) That way all of the UNIT files can call the logging functions without problem. Inside the logging library you would have an Initiate function through which you identify the control used in the main script to display the log entries - if this control is not initialised then no logging happens, but there will be no errors either.Here is a short example:expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> ;###################################################### ; This is the included logging library #include-once #include <GuiEdit.au3> Global $iLog_Control = 0 ; This function initialises the logging process Func _Log_Init($iControl) If $iControl Then $iLog_Control = $iControl EndFunc Func _Log_Write($sText) If $iLog_Control Then ; Logging has been initiated _GUICtrlEdit_AppendText($iLog_Control, $sText & @CRLF) Else ; Or else show the problem MsgBox($MB_SYSTEMMODAL, "Error", "Logging not initiated") EndIf EndFunc ;####################################################### ;####################################################### ; This is one of the UNIT includes ; Include the logging library - of course here the code is already included above ; #include "Logging.au3" ; Start a logging process AdlibRegister("_UNIT_Logger", 2000) ; Comment this line to see what happens if the edit is not initialised <<<< Func _UNIT_Logger() _Log_Write("UNIT log @ " & @SEC) EndFunc ;####################################################### ; Now the main script ; Include the UNIT include - of course here the code is already included above ; #include "UNIT.au3" $hGUI = GUICreate("Test", 500, 500) $cEdit = GUICtrlCreateEdit("", 10, 10, 200, 400) GUISetState() ; Initialise the edit control for logging _Log_Init($cEdit) ; And watch the log fill....... While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEndPlease ask if you have any questions. 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...
Moderators JLogan3o13 Posted December 9, 2014 Moderators Share Posted December 9, 2014 To offer yet another opinion... Call me old school, but I think logging for a distributed application (as this sounds like it will be), especially one that has a number of modules to it, should take place in the Windows Event Viewer. You will only help anyone trying to troubleshoot your application down the road by using clear and concise Event Viewer reporting. "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! Link to comment Share on other sites More sharing options...
Michiel Posted December 9, 2014 Author Share Posted December 9, 2014 (edited) The includes can call other functions just like it was part of one big script. Example: ; main script #include<funcincludetest.au3> func _hello() MsgBox("","","hello") EndFunc Then this is the include:;func include test file func _callHello() _hello() EndFunc _callHello() So the above included script is calling the function from the main script. Does that answer your question? Yeah, I sort of had it like that, but unfortunately when I do Tools->SyntaxCheck Prod , SciTE gives me errors because _hello() isn't declared in the unit calling it. Of course, I can live with that and ignore it, but, as the script grows, so will the number of instances of this happening until it all eventually becomes impossible to error check the lot. So, if only I had a syntactically sound and accepted way of doing this that would be acceptable to my IDE's error checking mechanisms. <snip> Here is a short example: expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> ;###################################################### ; This is the included logging library #include-once #include <GuiEdit.au3> Global $iLog_Control = 0 ; This function initialises the logging process Func _Log_Init($iControl) If $iControl Then $iLog_Control = $iControl EndFunc Func _Log_Write($sText) If $iLog_Control Then ; Logging has been initiated _GUICtrlEdit_AppendText($iLog_Control, $sText & @CRLF) Else ; Or else show the problem MsgBox($MB_SYSTEMMODAL, "Error", "Logging not initiated") EndIf EndFunc ;####################################################### ;####################################################### ; This is one of the UNIT includes ; Include the logging library - of course here the code is already included above ; #include "Logging.au3" ; Start a logging process AdlibRegister("_UNIT_Logger", 2000) ; Comment this line to see what happens if the edit is not initialised <<<< Func _UNIT_Logger() _Log_Write("UNIT log @ " & @SEC) EndFunc ;####################################################### ; Now the main script ; Include the UNIT include - of course here the code is already included above ; #include "UNIT.au3" $hGUI = GUICreate("Test", 500, 500) $cEdit = GUICtrlCreateEdit("", 10, 10, 200, 400) GUISetState() ; Initialise the edit control for logging _Log_Init($cEdit) ; And watch the log fill....... While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Well, wouldn't you know it, that's exactly what I did down almost to the function names! (i.e. I made a logInit() , which writes a unit-local variable with the handle to the edit control!) Edited December 9, 2014 by Michiel Link to comment Share on other sites More sharing options...
jdelaney Posted December 9, 2014 Share Posted December 9, 2014 (edited) If you are calling a function within included scripts, then that function (logically) should be in that script file, or another included script...like a script that contains your logging functions. Your primary driving script should then include all the above. You should be able to execute any given 'included' script, and not get scite validation errors, or you are not doing everything you should be. Edited December 9, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
Michiel Posted December 9, 2014 Author Share Posted December 9, 2014 (edited) You should be able to execute any given 'included' script, and not get scite validation errors, or you are not doing everything you should be. Quoting someone else's code: The includes can call other functions just like it was part of one big script. Example: ; main script #include<funcincludetest.au3> func _hello() MsgBox("","","hello") EndFunc Then this is the include: ;func include test file func _callHello() _hello() EndFunc _callHello() So the above included script is calling the function from the main script. Does that answer your question? Tools->SyntaxCheck Prod, if run on the include, will then error on _hello() in the include, will it not? Or does it work for you? Edited December 9, 2014 by Michiel Link to comment Share on other sites More sharing options...
jdelaney Posted December 9, 2014 Share Posted December 9, 2014 Nope, that would blow up without the #include back to the main script. If an included script is calling a function, then it shouldn't be in the 'main' script...I think of 'main' scripts as something that drives exectuion of functions in other libraries. Personal preference...I don't want to have to include other 'main' scripts in new 'main' scripts. IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
Michiel Posted December 9, 2014 Author Share Posted December 9, 2014 Personal preference...I don't want to have to include other 'main' scripts in new 'main' scripts. Yeah, that makes a lot of sense to me too... Link to comment Share on other sites More sharing options...
Jfish Posted December 9, 2014 Share Posted December 9, 2014 Just to weigh back in here ... I agree with all the comments about the better approaches (from far more skilled coders than myself). I was merely demonstrating that you could call a function in the main script from an included script though it may not be best practices to do so. Now, of course, MAIN.au3 can call any function in any UNIT.au3. But can a UNIT call a function in MAIN.au3? Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
czardas Posted December 9, 2014 Share Posted December 9, 2014 (edited) It appears to work. Main.au3 ==> run this script. ; #include-once #include 'include2.au3' _2() Func _1() Msgbox(0, "", "Hello World") EndFunc ; include2.au3 Func _2() _1() EndFunc ; You must run Main.au3. This includes the second library which then calls the first library and bingo. It's a very disorganized mess and it's easy to write code which is unstable when your libraries are like that. As Melba showed earlier, you really ought to create a shared function library which you can call from either a main script or another library - providing you use #include-once where appropriate. BTW I didn't run the code using SciTE. I would expect an error if I had attempted that. Edited December 9, 2014 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Jfish Posted December 10, 2014 Share Posted December 10, 2014 (edited) I ran mine in Scite without an error. Mine was a bit different because I just had the included script call a function in the main script without first being called (that just sounds confusing typing it). +>07:36:56 AU3Check ended.rc:0 +>07:36:56 AutoIt3Wrapper Finished. >Exit code: 0 Time: 0.4385 Edited December 11, 2014 by Jfish Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
czardas Posted December 10, 2014 Share Posted December 10, 2014 (edited) It is slightly surprising that it works. I was thinking along the same lines as jdelaney. It changes my understanding of how the interpreter actually works. Even so, it's still very easy to mess up as in the following bad example. ; Main.au3 ==> WARNING <== Code is unstable. #include 'include2.au3' Global $sGlobalString = "Hello World" Func _1() Msgbox(0, "", $sGlobalString) EndFunc ; include2.au3 _1() Edited December 10, 2014 by czardas operator64 ArrayWorkshop 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