AutoHotkey Community

It is currently May 27th, 2012, 4:14 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 563 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12 ... 38  Next
Author Message
 Post subject:
PostPosted: February 17th, 2010, 4:48 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Quote:
possibly I could do something using Meta-Function

Yes, on 2nd thought its better to keep it in an object.

Many more possibilites, plus, that way, once you don't need dll functions you can destroy them by destroying single object. It also makes good distinction:

Code:
win.Sleep(1000)
gdip.GetBitmap(...)


But also
Code:
someId3Funcs := Define() ;define all ID3 Tagging api's.
someMixingFunc := Define() ;lets say bass.dll

mp3 := LoadAudioFIle( "c... flac"),
mp3.base := MInherit(someId3Funcs, someMixingFunc); http://www.autohotkey.com/forum/viewtopic.php?t=54021
mp3.ChangeComment("meh")
mp3.AddReverb(...)

someMixingFunc := ""  ;don't need those any more... will call __Delete on object to free things.


I would also suggest alternative syntax for definition, the one letter syntax:
Code:
Define("dll\MsgBox", "i=issi", "cdecl")


First comes return value , = symbol, then list of parameters. Return value and = can be omitted.

That would make code more easier to change and code size will be smaller. Plus, it will make it compatible with some systems around that use such syntax (i.e. you can copy /paste already made definitions from other languages). Other than that, having single parameter that you can manage yourself is better then multiple parameters, at least now when code_gen lowlevel feature is not there (I doubt it ever will).

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 17th, 2010, 9:32 pm 
Offline

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

I've got the following idea using Meta-Function.
This is an example how it could be working in DynaCall internally, so in the end you can use MsgBox.(...) or dll.func(...).
DynaCall will save/manage the pointers internally under name of variables.
This should keep the speed up and be very easy to use, what do you think? (to test you'll need AHK_L46++)
Code:
"".base.__Call:="DynaCall"
"".base.__Set:="DynaCallSetGet" ;will be DynaCall as well so it is managed by AutoHotkey.exe
"".base.__Get:="DynaCallSetGet" ;will be DynaCall as well so it is managed by AutoHotkey.exe
dll = 27656192 ;Imagine DynaCall(dll . "\func"...) returned ptrFunc
dll.a:= 45656192 ;Imagine DynaCall(dll . "\func"...) returned ptrFunc
dll[var:= "funcdll"]:= 5679342
MsgBox % "End"
 . dll.funcdll(1,2,3,4,5)
 . dll.a(1,2,3,4,5)
 . dll.(1,2,3,4,5)





DynaCall(func,subfunc="",p1="",p2="",p3="",p4="",p5=""){ ; DynaCall for example only, will be managed internally
   if subfunc
   MsgBox % "DynaCall will launch:`nDynaCall(" func[subfunc] "," p1 "," p2 "," p3 "," p4 "," p5 ")"
   else
   MsgBox % "DynaCall will launch:`nDynaCall(" func "," p1 "," p2 "," p3 "," p4 "," p5 ")"
}
DynaCallSetGet(obj,key,value=""){ ;will be DynaCall as well so it is managed by BIF_DynaCall in AutoHotkey.exe
   static objects,keys,values
   If !values
      values:=Object()
   If value=
      return values[obj,key]
   else
      values[obj,key]:=value
}


I have to look into MInherit, sounds good :)

Defining parameters in one variable sounds good as well, will look into that.

Quote:
... at least now when code_gen lowlevel feature is not there (I doubt it ever will).

What do you mean, you can generate code using addScript and addFile in AutoHotkey_H.exe and dll?

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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 1:36 am 
Offline

Joined: February 6th, 2008, 12:26 am
Posts: 14
Location: the land of enchantment
i gave your dll a try and i must say i was disappointed ~ it took 500+ ms to launch a script. i can run a new instance of autohotkey in about 40ms! i ran your example scripts from ahkdll().

i suspect there is a 'built in' delay, and if so will this be a permanent feature?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 8:17 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
oldHacker wrote:
i gave your dll a try and i must say i was disappointed ~ it took 500+ ms to launch a script. i can run a new instance of autohotkey in about 40ms! i ran your example scripts from ahkdll().

i suspect there is a 'built in' delay, and if so will this be a permanent feature?


Have you used the latest version here?
Try that :)
Code:
dll:=AhkDllThread(A_ScriptDir . "\AutoHotkey.dll")
VarSetCapacity(var,1024)
pVar:=getVar(var)
Loop {
   DynaCall(dll.ahktextdll,"Alias(var," pVar "+0)`nvar++")
   ToolTip % var
   DynaCall(dll.ahkTerminate)
}

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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 8:33 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Quote:
This should keep the speed up and be very easy to use, what do you think?

I don't see a difference to what I proposed above. So, yes, its good :)

I would be able to create prototype for this in AHKL, similar to your code above. The only problem to it is that I can't generate DllCall with parameteres (requires code_gen).

Quote:
What do you mean, you can generate code using addScript and addFile in AutoHotkey_H.exe and dll?

Thanks. I didn't yet looked into those.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 10:03 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
HotKeyIt wrote:
DynaCall will save/manage the pointers internally under name of variables.
That sounds inefficient. Why not store it in an object, in the variable?
Quote:
I've got the following idea using Meta-Function.
I think you mean "global meta-function" or "default base". I consider this a gross misuse of the feature. It prevents other uses of the global meta-functions, has no benefits over using objects correctly, and is potentially unsafe.

Instead of DynaCall returning a pointer to an internal structure as an integer, you could return an object reference which is essentially the same thing but much safer. The "internal structure" (the object) then only needs one extra field: the compiler-generated hidden vtable pointer. Invoking the object via func[...](params) internally calls DynaCall using the information stored inside the object, func. Since func itself is the function being called, the name param [...] would be ignored; both func.() and obj.meth() would have the same effect where func=obj.meth, since it basically does func[obj]().

Here's an example (with obvious limitations which wouldn't be present for a built-in object):
Code:
_MsgBox := DynaFunc(1234)
; _MsgBox := DynaFunc(DynaCall(dll . "\MsgBox","Str","", "Str","","Cdecl UInt"))
x := _MsgBox.("a", "b")

ahkdll := Object()
ahkdll.MsgBox := _MsgBox
ahkdll.MsgBox("c", "d")

DynaFunc(dc) {
    static base
    return Object("_", dc, "base", base ? base : base := Object("__Call", "DynaFunc_Call"))
}
DynaFunc_Call(df, n, prm1="", prm2="") {
    MsgBox % "DynaCall(" df._ ", " prm1 ", " prm2 ")"
}
If you wanted to also allow func[prm1, prm2], you could use __Get. The only difference would be that __Get would not have param n.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 1:22 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
That sounds great, I was also a bit unsure about using global base, especially since it could not be used for something else anymore. Your suggestion seems to be a better solution, I will see how far I get :)

Btw. func[p1,p2] as well as func.sub[1,2] should 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:
PostPosted: February 18th, 2010, 2:25 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Lexikos wrote:
func=obj.meth

Ah, yes, this is the way to let the user set up the names he or she wants. Perfect for Dependency Injection too:

Code:
msg := win.MsgBox
msg.("meh")

;later the user is selecting other kind of messaging from configuration
msg := twitter.MsgBox
msg.("meh")


With system like this you can change behavior of code using simple assigments as long as functions have parameters that match (i.e. the same interface).

HotKeyIt wrote:
That sounds great, I was also a bit unsure about using global base, especially since it could not be used for something else anymore

Using MInherit or similar not exactly true. You can do this:

Code:
"".base := MInherit("".base, String, MyNextCoolThing.....)

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 18th, 2010, 10:46 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
HotKeyIt wrote:
Btw. func[p1,p2] as well as func.sub[1,2] should work, right?
It would "work", but what would you expect it to actually do? If you implement __Get, func[p1,p2] = func.(p1,p2) and func.sub[1,2] = func.("sub", 1, 2), unless func[p1] or func["sub"] actually exist. If func["sub"] itself contains a pseudo-function (implementing __Get for calling), it will be called. With a built-in object, this ambiguity would not necessarily occur. One way around it in script would be to store data internally in the object using unique object keys instead of strings/numbers.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 20th, 2010, 8:34 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
I think I've got it running, here is a test version, can you do some tests?

I still need to clean up and build in 1 parameter definition so will post code later :)

It seems to be only a little bit slower than using DynaCall directly :)

DynaCall wrote:
DynaCall will now return an object, object["_" function] will contain pointer
Code:
DllCall("LoadLibrary","str",dll)
ahk := DynaCall(dll . "\ahktextdll","Str","","Str","","Str","","CDecl UInt")

You can then call DynaCall dynamically using the object.
Following combinations work:
Code:
obj.(...)
obj.func(...)
obj[...]
obj.func[...]
return_value := obj.func.param
;for example
sleep:=DynaCall("Sleep","UInt",0)
start:=A_TickCount
MsgBox % (sleep.1325 . A_TickCount-start)+0

;simple example for AutoHotkey.dll
dll:=AhkDllThread("AutoHotkey.dll")
dll.ahktextdll("#Persistent`naVariable=Hello World!")
Sleep, 100
MsgBox % dll.ahkgetvar.aVariable


Here is adapted AhkDllThread()
Code:
AhkDllThread(dll=""){
   static
   static ResourceLoadLibrary:="ResourceLoadLibrary"
   static functions:="ahkdll|ahktextdll|ahkReady|ahkReload|ahkTerminate|addFile|addScript|ahkassign|ahkExecuteLine|ahkFindFunc|ahkFindLabel|ahkgetvar|ahkLabel|ahkPause|ahkExecuteLine"
   If !(dll){
      Loop % i
      {
         idx:=A_Index
         Loop,Parse,functions,|
            DynaCall(dll%idx% . "" . A_LoopField)
         MemoryFreeLibrary(dllmodule%A_Index%)
         obj%A_Index%=
         dll%A_Index%=
         dllmodule%A_Index%=
      }
      i=0
      return
   }
   i++
   dllmodule%i%:=A_IsCompiled ? %ResourceLoadLibrary%(dll) : MemoryLoadLibrary(dll)
   object := Object()
   Loop,Parse,functions,|
      object[A_LoopField]:=MemoryGetProcAddress(dllmodule%i%,A_LoopField)
   object.ahkdll:=DynaCall(object.ahkdll,"Str","","Str","","Str","","CDecl UInt")
   object.ahktextdll:=DynaCall(object.ahktextdll,"Str","","Str","","Str","","CDecl UInt")
   object.ahkReady:=DynaCall(object.ahkReady,"Cdecl Int")
   object.ahkReload:=DynaCall(object.ahkReload,"Cdecl Int")
   object.ahkTerminate:=DynaCall(object.ahkTerminate,"Int",0,"Cdecl Int")
   object.addFile:=DynaCall(object.addFile,"Str","","uchar",0,"uchar",0,"CDecl UInt")
   object.addScript:=DynaCall(object.addScript,"Str","","Int",0,"Int",0,"CDecl UInt")
   object.ahkassign:=DynaCall(object.ahkassign,"Str","","Str","","Cdecl Int")
   object.ahkExecuteLine:=DynaCall(object.ahkExecuteLine,"UInt",0,"UInt",0,"UInt",0,"CDecl UInt")
   object.ahkFindFunc:=DynaCall(object.ahkFindFunc,"Str","","CDecl UInt")
   object.ahkFunction:=DynaCall(object.ahkFunction,"Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
   object.ahkPostFunction:=DynaCall(object.ahkPostFunction,"Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
   object.ahkgetvar:=DynaCall(object.ahkgetvar,"Str","","UInt",0,"CDecl Str")
   object.ahkLabel:=DynaCall(object.ahkLabel,"Str","","CDecl UInt")
   object.ahkPause:=DynaCall(object.ahkPause,"Str","")
   obj%i%:=object
   dll%i%:=dll
   return obj%i%
}

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


Last edited by HotKeyIt on February 23rd, 2010, 2:02 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 20th, 2010, 9:57 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Thx for update. Ill test it as soon as I find time (it make take a while, I am very busy to the end of the month).

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 23rd, 2010, 10:07 am 
i just tried ahktextdll, it's very nice. thanx for your hard work :)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 23rd, 2010, 11:45 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Updated test version (including exe, dlls and bin)
It is possible now to define multiple DynaCall parameters in one parameter.
It is now so easy to use multithreading, please try it if you haven't before :D
Enjoy scripting ;)
Code:
dll:="AutoHotkey.dll"
DllCall("LoadLibrary","Str",dll)
ahk:=Object( "run",DynaCall(dll . "\ahktextdll","ui=sss")
            ,"get",DynaCall(dll . "\ahkgetvar","s=sui")
            ,"set",DynaCall(dll . "\ahkassign","ss") )
ahk.run("MsgBox thread")
ahk.set["a","test"] ;same as ahk.set("a","test")
MsgBox % ahk.get.a

Multiple parameters in one string wrote:
Int = i
Str = s
Short = h
Char = c
Float = f
Double = d
Ptr = t
Int64 = 6

U prefix and * or p is supported as well, for example
ui*=ui*s

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


Last edited by HotKeyIt on February 24th, 2010, 8:36 am, edited 5 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2010, 1:21 am 
Offline
User avatar

Joined: April 4th, 2009, 8:19 pm
Posts: 1143
Location: Croatia
Hi,
I'm totally new to multithreading using AutoHotkey.dll, and I need some explanations.

When I want multithreading, I simply create accessory, hidden, ghost script(s) (no tray icon, no visable windows),
run them by main script, and than accessory script(s) execute when main script sends them a message --> OnMessage(). This method works perfectly.

Can somebody please explain me why should I use AutoHotkey.dll for multithreading instead of SendMessage + OnMessage() combination ? What's the benefit?
Why should I be motivated to learn how to use AutoHotkey.dll and abandon method that I'm currently using?

Thanks in advance.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2010, 8:31 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
HotKeyIt wrote:
1. Whenever you use multi-processing, you have several processes running that are shown in Task Manager which does not look professional in my view. A dll is loaded dynamically into your process and does not create a separate process but thread.
2. Using OnMessage you have no direct access/control over your script, where in Autohotkey.dll you have full control over your thread/script.
3. It is much faster and more naturally using DllCall rather than SendMessage for multi-threading.
4. Accessing a variable from several processes simultaneously is not possible but using Alias() in AutoHotkey.dll and corresponding exe.


AutoHotkey.dll wrote:
AutoHotkey.dll and corresponding AutoHotkey.exe give you high control over your thread(s).
Using exported functions you can
- launch a function in thread (++ pass up to 10 parameters)
- launch a label
- pause the thread
- terminate the thread
- reload the thread
- run a thread from variable without using pipes
- dynamically add code
- set and get variables.


I am implementing threads in AutoHotFile where it currently uses 5 additional threads (no release yet).

Quote:
One thread runs the database using objects.
Another thread is watching for new/moved/deleted files and amends the database.
Another thread is running ToolTip()
Another thread is serving dynamic hotstrings and hotkeys.
Another thread searches for files when typing.
Main thread (AutoHotkey.exe) is catching users input and searches for data in database.


Current release version of AutoHotFile also uses IPC (inter processing communication), but it is far not as good as real multi-threading.

Hope this answers your question :)

_________________
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 ... 6, 7, 8, 9, 10, 11, 12 ... 38  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


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