AutoHotkey Community

It is currently May 26th, 2012, 8:24 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 563 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 38  Next
Author Message
PostPosted: August 17th, 2009, 2:55 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Changes in V9:
1. Added builtin FindFunc()
2. updated addfile(), so when called with 2 as the 3rd parameter.
For ex. addfile("somefile.ahk", 1, 2)
simpleheap memory used by late included files upto this point is freed. Hotkeys, labels, and functions from the first call to addfile are retained.
If you want to create hotkeys in later include files that have already been defined, use a dynamic function call with the Hotkey command:
Hotkey, label, hotkey
2a: I ran a stress test loading 2 client scripts alternately 2000 times, and the total memory usage only increased by 200kb, compared to 2 megabytes with the older version.
2b: This allows me to experiment more seriously with an ahk webserver / app server that can run short independent scripts without launching a separate process.
For example, hosting AutoHotkey.dll in modpython for apache:
Code:
import os, time
from mod_python import apache
from ctypes import *

ahk = cdll.LoadLibrary("AutoHotkey.dll")
ahk.ahkdll(create_string_buffer("..\\htdocs\\test\\pyclient.ahk"), "", "")   

def handler(req):
    req.content_type = 'text/plain'
    req.write("Hello World2!")
    return apache.OK
FindFunc code:
Code:
EXPORT unsigned int ahkFindFunc(char *funcname)
{
return (unsigned int)g_script.FindFunc(funcname);
}

void BIF_FindFunc(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount) // Added in Nv8.
{
   // Set default return value in case of early return.
   aResultToken.symbol = SYM_INTEGER ;
   aResultToken.marker = "";
   // Get the first arg, which is the string used as the source of the extraction. Call it "findfunc" for clarity.
   char funcname_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
   char *funcname = TokenToString(*aParam[0], funcname_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
   int funcname_length = (int)EXPR_TOKEN_LENGTH(aParam[0], funcname);
   aResultToken.value_int64 = (__int64)ahkFindFunc(funcname);
   return;
}
updated addfile code:
Code:
EXPORT unsigned int addFile(char *fileName, bool aAllowDuplicateInclude, int aIgnoreLoadFailure)
{   // dynamically include a file into a script !!
   // labels, hotkeys, functions.   
   static int filesAdded = 0  ;
   
   Line *oldLastLine = g_script.mLastLine;
   
   if (aIgnoreLoadFailure > 1)  // if third param is > 1, reset all functions, labels, remove hotkeys
   {
      g_script.mFuncCount = 0;   
      g_script.mFirstLabel = NULL ;
      g_script.mLastLabel = NULL ;
      g_script.mLastFunc = NULL ;
       g_script.mFirstLine = NULL ;
      g_script.mLastLine = NULL ;
       g_script.mCurrLine = NULL ;

      if (filesAdded == 0)
         {
         SimpleHeap::sBlockCount = 0 ;
         SimpleHeap::sFirst = NULL;
         SimpleHeap::sLast  = NULL;
         SimpleHeap::sMostRecentlyAllocated = NULL;
         }
      if (filesAdded > 0)
         {
         // Naveen v9 free simpleheap memory for late include files
         SimpleHeap *next, *curr;
         for (curr = SimpleHeap::sFirst; curr != NULL;)
            {
            next = curr->mNextBlock;  // Save this member's value prior to deleting the object.
            curr->~SimpleHeap() ;
            curr = next;
            }
         SimpleHeap::sBlockCount = 0 ;
         SimpleHeap::sFirst = NULL;
         SimpleHeap::sLast  = NULL;
         SimpleHeap::sMostRecentlyAllocated = NULL;
/*  Naveen: the following is causing a memory leak in the exe version of clearing the simple heap v10
 g_script.mVar = NULL ;
 g_script.mVarCount = 0 ;
 g_script.mVarCountMax = 0 ;
 g_script.mLazyVar = NULL ;

 g_script.mLazyVarCount = 0 ;
*/
      }
   
   g_script.LoadIncludedFile(fileName, aAllowDuplicateInclude, (bool) aIgnoreLoadFailure);
   g_script.PreparseBlocks(g_script.mFirstLine); //
//   g_script.mFirstLine->ExecUntil(UNTIL_RETURN); // Might never return (e.g. infinite loop or ExitApp).
         filesAdded += 1;
   }
   else
   {
   g_script.LoadIncludedFile(fileName, aAllowDuplicateInclude, (bool) aIgnoreLoadFailure);
   g_script.PreparseBlocks(oldLastLine->mNextLine); //
   }
   return (unsigned int) oldLastLine->mNextLine;  //
}

testscripts: hostscript
Code:
start:
ahkdll := DllCall("LoadLibrary", "str", A_ScriptDir . "\AutoHotkey.dll")
sleep, 500
threadH := DllCall(A_ScriptDir . "\AutoHotkey.dll\ahkdll", "str", "cleanhostdll.ahk", "str"
, "", "str", "parameter1 parameter2", "Cdecl Int")
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", "clean.ahk", "uchar", 1
,"uchar" , 2, "Cdecl UInt")
msgbox hostcleanexe
gosub stress
return

stress:
loop, 2
{
loop, 1000
{
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", "clean.ahk", "uchar", 1
,"uchar" , 2, "Cdecl UInt")
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", "clean2.ahk", "uchar", 1
,"uchar" , 2, "Cdecl UInt")
}
msgbox 1000 
}
  return

F3::
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", "clean.ahk", "uchar", 1
,"uchar" , 2, "Cdecl UInt")
msgbox hostcleanexe clean
return

F4::
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", "clean2.ahk", "uchar", 1
,"uchar" , 2, "Cdecl UInt")
msgbox hostcleanexe clean2
return

!r::
Reload

!q::
ExitApp

client scripts:
Code:
#Persistent
return

file1:
x := "second"
x = test
x = another
return

fxclean()
{
msgbox clean
x = 3
}
2nd client script
Code:
#Persistent
return

file1:
x := "second"
x = test
x = another
return

fxclean2()
{
msgbox clean2
x = 3
}


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 17th, 2009, 6:02 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
tinku99 wrote:
...
2. updated addfile(), so when called with 2 as the 3rd parameter.
For ex. addfile("somefile.ahk", 1, 2)
simpleheap memory used by late included files upto this point is freed. Hotkeys, labels, and functions from the first call to addfile are retained.
If you want to create hotkeys in later include files that have already been defined, use a dynamic function call with the Hotkey command:
Hotkey, label, hotkey


Hi tinku99, that is great, thanks for update.
Btw. what happens to hotkeys + directives + OnMessage... from previous script? Are these also deactivated/disabled?

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 17th, 2009, 9:35 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
HotKeyIt wrote:
what happens to hotkeys + directives + OnMessage... from previous script? Are these also deactivated/disabled?
Directives will stay.
Hotkeys and OnMessage: Depends what they point to. If its to the first script loaded with ahkdll(), then they will work.
You can manually replace Hotkeys with the Hotkey command.
OnMessage can also be dynamically unhooked I believe.

If they point to code loaded with addfile(), hotkeys will fail, and OnMessage will crash the script, because it will try to call a function that doesn't exist anymore.

I will probably add the option to run an autoexecute section at the top of each include file loaded with addfile...


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 17th, 2009, 10:33 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
tinku99 wrote:
aResultToken.symbol = SYM_INTEGER ;
aResultToken.marker = "";
:shock:
marker is for SYM_STRING or SYM_OPERAND. Also, aResultToken.symbol is already set to SYM_INTEGER before the built-in function is called. Anyway, that function will never return early so there's no need to set any defaults.
Quote:
// A separate buf because aResultToken.buf is sometimes used to store the result.
It is sometimes used by the built-in function, but in this case you are not using it at all. If there's any risk that aResultToken.buf will be overwritten, you can copy the pointer to a local variable (the buffer itself exists in the stack of the caller). However, since there shouldn't be any need to support SYM_INTEGER / SYM_FLOAT inputs, you may as well use NULL in place of the buf. TokenToString would then return an empty string if the input is not a string (or var).
tinku99 wrote:
If they point to code loaded with addfile(), hotkeys will fail, and OnMessage will crash the script, because it will try to call a function that doesn't exist anymore.
It shouldn't be difficult to iterate through the functions and labels which are about to be deleted, and remove any associated hotkeys/message monitors (or to remove all hotkeys/message monitors). Hotkeys are kept in Hotkey::shk[], hotkey->mFirstVariant points to the first variant in the linked list, and each variant's mJumpToLabel points to... well, you know. g_MsgMonitor points to an array of MsgMonitorStruct; presumably each one's 'func' field contains a pointer to the function which will be called if message 'msg' is received.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 17th, 2009, 10:58 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Thanks for info, would be great if everything would get removed / deleted automatically, so new script will start off fresh.

Another question, would it be possible to addfile if thread (Autohotkey.dll) was terminated ( DllCall("TerminateThread",.. or DllCall("ExitThread",...) ) or if it hangs / crashed, so any loaded dll could be reused, that would be awsome.

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 17th, 2009, 2:15 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Hi tinku99,

Looks like I cannot understand how to use addfile, could you possibly give some more information about parameters and functionality?

I thought the old script will be replaced by the new one but it looks to be not the case.

So when I run following script using ahkdll:
Code:
lib:=DllCall("LoadLibrary","str",A_ScriptDir . "\AutoHotkey.dll")
thread_ := DllCall(A_ScriptDir . "\AutoHotkey.dll\ahkdll", "str", A_ScriptDir . "\test.ahk", "str", "", "str", parameters, "Cdecl Int")
MsgBox % thread_
DllCall(A_ScriptDir . "\AutoHotkey.dll\addFile", "str", A_ScriptDir . "\test1.ahk", "uchar", 1,"uchar" , 2, "Cdecl UInt")
MsgBox
Return

This script is loaded:
Code:
#Persistent
SetTimer, test
Return
test:
ToolTip % A_Now
Return

And addfile following:
Code:
#Persistent
SetTimer, test1
Return
test1:
ToolTip % A_TickCount
Return


Old script is still running.

Am I doing something wrong?

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 17th, 2009, 2:39 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
HotKeyIt wrote:
Old script is still running.

Am I doing something wrong?
The first script is special, it is not removed. If you load a 3rd script, the 2nd one will be replaced. Same with 4th, 5th etc... they will be removed. The first one will stay persistent.
If you don't need a first script, just load a dummy script with a single line: #Persistent.

But the first one is usefull because you can use it for utility functions and hotkeys, that will be common to all client scripts.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 17th, 2009, 3:02 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
HotKeyIt wrote:
Code:
#Persistent
SetTimer, test1
Return
test1:
ToolTip % A_TickCount
Return

By the way, if you try to replace this script without first stopping the timer, it will probably crash.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 17th, 2009, 6:41 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Hi tinku99,

I've got some questions regarding AutoHotkey.dll.

As far as I understand, loaded file will not be executed straight away, right?

So the only way to access an added file is to create a subroutine in host script that will check if a function or label exist (via IsFunc or IsLabel) and launch it afterwards.
Working example of host script (first loaded file):
Code:
#Persistent
Hotkey,1,test
Return
test:
   If IsLabel(label:="test")
      Gosub %label%
Return
or
Code:
#Persistent
Loop {
   If IsLabel(label:="test")
      Gosub %label%
}


I think it would be much better if the script would get executed straight away (at least optionally).

Also I do not think keeping host script running after addfile is necessary for AutoHotkey.dll, I think all code should be removed. It would be much better if we could have more control over the thread from the app that launched it, like killing and restarting it as well as launching a function or label.
For example something like:
Code:
DllCall("AutoHotkey.dll\ExecFunc","str","test",...)
DllCall("AutoHotkey.dll\ExecLabel","str","test",...)


What do you think?

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 18th, 2009, 1:11 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Lexikos wrote:
It shouldn't be difficult to iterate through the functions and labels which are about to be deleted, and remove any associated hotkeys/message monitors (or to remove all hotkeys/message monitors). Hotkeys are kept in Hotkey::shk[], hotkey->mFirstVariant points to the first variant in the linked list, and each variant's mJumpToLabel points to... well, you know. g_MsgMonitor points to an array of MsgMonitorStruct; presumably each one's 'func' field contains a pointer to the function which will be called if message 'msg' is received.
A simple matter of programming. :)

Removing and adding variants from the host application is on my todo list.
Basically I plan to export variations of the Hotkey command.

Will look in to msgmonitor and possibly exporting the OnMessage()function.
HotKeyIt wrote:
I think it would be much better if the script would get executed straight away (at least optionally).
Code:
DllCall("AutoHotkey.dll\ExecFunc","str","test",...)
DllCall("AutoHotkey.dll\ExecLabel","str","test",...)
Will add these features in the next release.
HotKeyIt wrote:
When the thread gets killed/terminated or you call "DllCall("ExitThread",..)", what is left there? ...
I have experimented with FreeLibrary, it all looks to work fine, the memory decreases but after LoadLibrary again (even another file) it gets same library pointer and this message RegClass appears....
As Lexikos pointed out a while back on this thread, terminating the thread or freeing the library without cleanup is problematic.
Also, freeing the library and reloading it is inefficient and unnecessary for any purpose that i can think of.
> if it hangs / crashed, any loaded dll could be reused, that would be awsome.
Real programmers get it right the first time. :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 18th, 2009, 9:32 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Hi tinku99,

So in next version, when addfile is called for Autohotkey.dll, it will replace the host script as well and new script will get executed?

tinku99 wrote:
As Lexikos pointed out a while back on this thread, terminating the thread or freeing the library without cleanup is problematic.
Also, freeing the library and reloading it is inefficient and unnecessary for any purpose that i can think of.
> if it hangs / crashed, any loaded dll could be reused, that would be awsome.
Real programmers get it right the first time. ;)


So I have to wait until "real programmers" get same request/requirement :?:

Some background why I need it especially:
When I launch "Loop, filepattern" (expecially on a network drive), it could take very long time to finish that operation and there is only one way to stop that loop, kill the thread/process.
There are some other commands that could get your script hang for some time and you would like to kill it.

Does AutoHotkey a cleanup on ExitApp? If so, then we only need to change ExitApp to ExitThread and it could work, right?

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: killing threads
PostPosted: August 18th, 2009, 4:20 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
HotKeyIt wrote:
Hi tinku99,
So in next version, when addfile is called for Autohotkey.dll, it will replace the host script as well and new script will get executed?
So I have to wait until "real programmers" get same request/requirement :?:
1. New script will be executed. Have not decided on clearing the first script. The first script can be blank anyway, so there is nothing to replace. (Its not really a host script, the host is outside the dll, my mistake in terminology earlier.
2. lol, nice comeback. sorry I had wasted some time on this when I first created the dll.
HotKeyIt wrote:
"[Loop, filepattern" and] some other commands could get your script hang for some time.
This could be a more general question for autohotkey. Consider creating a new discussion thread for this.
HotKeyIt wrote:
Does AutoHotkey a cleanup on ExitApp? If so, then we only need to change ExitApp to ExitThread and it could work, right?
Hmm, Maybe if we kill the ahkdll thread and clear the green threads also, we could reenter at MsgSleep(SLEEP_INTERVAL, WAIT_FOR_MESSAGES);
Will try it...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 18th, 2009, 5:56 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
tinku99 wrote:
Hmm, Maybe if we kill the ahkdll thread and clear the green threads also, we could reenter at MsgSleep(SLEEP_INTERVAL, WAIT_FOR_MESSAGES);
Will try it...


I'll keep my fingers crossed :D

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 19th, 2009, 4:58 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
ok, I enabled autoexecute for the top of the replacement scripts.
you can execute labels from outside now.
Functions don't take any parameters and don't return anything yet, so they are not much better than labels. Will work on it.
Code:
DllCall(A_ScriptDir . "\AutoHotkey.dll\ahkLabel", "str", "labelname", "Cdecl UInt")
DllCall(A_ScriptDir . "\AutoHotkey.dll\ahkFunction", "str", "funcname", "str", result, "Cdecl UInt")
download

killing the thread and trying to enter at msgsleep didn't simply work.
Killing the thread destroys the main gui. Its difficult to separate out which resources have to be reinitialized and which can be reused. Also, its complicated to pass on a mixture of global, static, and class variables through threads.
sorry. will try again after a while.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 19th, 2009, 7:10 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
That's great tinku99, thank you so much, I will try as soon as I can.

I am really curious about killing the thread. I hope it'll work.

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 563 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 38  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group