 |
AutoHotkey Community Let's help each other out
|
AutoHotkey_L: Arrays, Debugger, x64, COM, #If expression ...
Goto page Previous 1, 2, 3 ... 22, 23, 24 ... 68, 69, 70 Next
|
| View previous topic :: View next topic |
| Author |
Message |
IsNull
Joined: 10 May 2007 Posts: 593 Location: .switzerland
|
Posted: Fri Jan 29, 2010 7:41 pm Post subject: |
|
|
I wonder how to handle "collection" objects. There are some array like behaviors I know:
| Code: |
obj[1] := "blub"
obj[2] := "more blub"
Loop, 2
{
msgbox % obj[a_index]
}
|
The problem of this design is, if index 1 getting deleted, index 2 stays. For real collection handling, the object should reorganize itself and place the items to new index.
If you think, this should be handled by the script itself- I have to say that this would be a performance mess. (stepping through each item, every time a item getting deleted)
This point to another thing:
VB Style
| Code: |
For each ITEM in COLLECTION
;ITEM will be a reference to the current object
Next
|
Also some basic functions/properties from the collection object:
| Code: |
Col := Object(COLLECTION) ; maybe define a collection specally…
Col.Add(item)
Col.remove(item)
Col.count
;…
|
Are there any plans for Collection-Objects or improvements for the array-like behavior?
btw, I tried a bit, to create a fast as possible collection base object, wich works with a List wich contains free spaces (to try to fill them before creating new index)
| Code: |
;******** Class Collection ********
;----------------------------------
/*
Important: _freelist property lists all id's where are
free, and is
internally used to hold the overview of curently used objects.
*/
;__________________________________
ocol := Object()
ocol.cnt := 0 ; real object cnt
ocol.pointer := 0 ; curent index (not Object cnt!)
ocol._freelist := "" ; free index places
;functions
ocol._cadd := "ocoll_add"
ocol._crem := "ocoll_rem"
ocol._cGetID := "ocoll_collgetid"
/**************************************************
ocoll_add(_col,obj_to_add)
Adds a item to the collection.
***************************************************
*/
ocoll_add(_col,obj_to_add){
i := 0
newlist := ""
;do we have free slots?
;------------------------------------------
list := _col._freelist
Loop, parse, list, `,
{
If(a_loopfield != ""){
If(!i){
i := a_loopfield
}else{
newlist .= a_loopfield ","
}
}
}
_col._freelist := newlist
;------------------------------------------
If(!i){ ;if no free slot avaiable, create new
_col.pointer := _col.pointer + 1
i := _col.pointer
}
_col[i] := obj_to_add
_col.cnt := _col.cnt + 1
obj_to_add._colid := i ;save the object id.
return
} ;**************************************************
/**************************************************
ocoll_rem(_col,obj_to_rem)
Removes a item from the collection.
***************************************************
*/
ocoll_rem(_col,obj_to_rem){
i := obj_to_rem._colid
If(!i)
return, 0
_col._Remove(i)
_col.cnt := ocol.cnt - 1 ; actualize counter
_col._freelist := _col._freelist i ","
} ;**************************************************
oColEACH(_col){
return, _col.pointer
}
|
_________________ http://securityvision.ch
AHK 2D GAME ENGINE |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
|
| Back to top |
|
 |
jethrow
Joined: 24 May 2009 Posts: 1907 Location: Iowa, USA
|
Posted: Fri Jan 29, 2010 10:05 pm Post subject: |
|
|
| IsNull wrote: | | The problem of this design is, if index 1 getting deleted, index 2 stays. For real collection handling, the object should reorganize itself and place the items to new index. | Perhaps I'm misinterpereting what you're saying, but have to looked into the built-in methods? Specifically Object._Insert(key, value) & Object._Remove(min_key [, max_key])? _________________
- in case I forgot to smile
Basic Webpage Controls
COM Object Reference |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sat Jan 30, 2010 3:16 am Post subject: |
|
|
ocoll_rem already uses _Remove(i), but appears to assumes it "frees" the "slot" at index i. It doesn't.
| Quote: | If both keys are integers, any integer keys greater than max_key are decremented by (max_key - min_key + 1).
Source: AutoHotkey_L - Objects | I probably should've mentioned that max_key = min_key if unspecified. Example:
| Code: | obj := Object()
obj[1] := "blub"
obj[2] := "more blub"
s := list_stuff(obj)
. "`n`nRemoved " obj._Remove(1) " item(s)`n"
. list_stuff(obj)
; If obj is empty, _MaxIndex() will be blank. To get around this...
; obj[0] := ""
obj._Insert(obj._MaxIndex() + 1, "bar")
s .= "`n`nInserted bar`n" list_stuff(obj)
obj._Insert(2, "foo")
s .= "`n`nInserted foo`n" list_stuff(obj)
MsgBox %s%
list_stuff(obj){
Loop % obj._MaxIndex() ; Assumes _MinIndex()=1
s .= A_Index ": " obj[A_Index] "`n"
return SubStr(s,1,-1)
} |
|
|
| Back to top |
|
 |
fincs
Joined: 05 May 2007 Posts: 1163 Location: Seville, Spain
|
Posted: Sat Jan 30, 2010 10:29 am Post subject: |
|
|
Script::Init() fails to load AutoHotkey.ahk on the Unicode version because GetFullPathNameW's input and output buffers are the same.
This doesn't happen in the ANSI version because strings are converted to/from Unicode.
Fix:
| Code: | ResultType Script::Init(global_struct &g, LPTSTR aScriptFilename, bool aIsRestart)
(snip)
{
mIsRestart = aIsRestart;
TCHAR buf[2048]; // Just to make sure we have plenty of room to do things with.
TCHAR buf2[MAX_PATH];
(snip)
aScriptFilename = _T("AutoHotkey.ini");
if (GetFileAttributes(aScriptFilename) == 0xFFFFFFFF) // File doesn't exist, so fall back to new method.
{
aScriptFilename = buf2; // it formerly pointed to buf
(snip) |
I fixed this a few months ago in AutoHotkeyU but apparently the fix got missed in the AutoHotkey_L merge.
PD: AutoHotkeyL_Source.zip doesn't include KuString.h, TextIO.h and TextIO.cpp so I had to re-download the source from github  _________________ fincs
Get SciTE4AutoHotkey v3.0.00 (Release Candidate)
[My project list] |
|
| Back to top |
|
 |
IsNull
Joined: 10 May 2007 Posts: 593 Location: .switzerland
|
Posted: Sat Jan 30, 2010 11:13 am Post subject: |
|
|
ok that works (not really...):
| Code: |
;############ CLASS COLLECTION ###############
collection := Object()
collection.add := "collection_add"
collection.remove := "collection_remove"
collection.removei := "collection_removeindex"
collection.count := 0 ;"collection_count"
collection_count(_col){
return, _col._MaxIndex()
}
collection_removeindex(_col,i){
_col._Remove(i)
}
collection_remove(_col,byref item){
_col.Count := _col.Count - _col._Remove(item.__index)
item.__index := ""
}
collection_add(_col,item){
i := _col._MaxIndex() = "" ? 1 : _col._MaxIndex() + 1
_col._Insert(i, item)
_col.Count := _col.Count + 1
item.__index := i
}
;#############################################
;-------------testing--------------------------------------------
item := Object()
item.name := "max"
item2 := Object()
item2.name := "peter"
item3 := Object()
item3.name := "berta"
Col := Object("base",collection)
col.add(item)
col.add(item2)
col.add(item3)
msgbox % list_stuff(col)
col.remove(item2)
col.remove(item2) ;nothing happens, ok.
msgbox % list_stuff(col)
col.add(item2)
msgbox % list_stuff(col)
exitapp
list_stuff(obj){
Loop % obj.count ; Assumes _MinIndex()=1
s .= A_Index ": " obj[A_Index,"name"] "`n"
return SubStr(s,1,-1)
}
| but has minor limitations:
1. The added item has to be a object.
2. A item can only stored once in a collection. (because the collection holds only a reference to the original object.)
3. A item can only be member of one collection at all.
4. If the collection moves the indexes, the item can't be deleted (__index won't be updated... so we loosing control :/ )
| Quote: | | @ IsNull, have you tried WideObject | hotkeyit, now I will have a look on it, thanks. _________________ http://securityvision.ch
AHK 2D GAME ENGINE |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sat Jan 30, 2010 1:27 pm Post subject: |
|
|
| fincs wrote: | Script::Init() fails to load AutoHotkey.ahk on the Unicode version because GetFullPathNameW's input and output buffers are the same.
This doesn't happen in the ANSI version because strings are converted to/from Unicode. | Thanks. Actually, I figured that out last night and committed a fix to github.
| Quote: | | PD: AutoHotkeyL_Source.zip doesn't include KuString.h, TextIO.h and TextIO.cpp | Thanks for bringing that to my attention. My "release" script (which has saved me a lot of time) uses a "whitelist" to create the source zip, and I had unfortunately neglected to update it. Since it isn't really necessary anymore, I've removed AutoHotkey_L_Source.zip and put more emphasis on the github link.
AutoHotkey_L.zip and AutoHotkey_L_SC.zip now contain Unicode builds, mostly by accident. Rather than changing them back, I'll re-upload an ANSI build once I've sorted out customizing builds via command-line.
| IsNull wrote: | 1. The added item has to be a object.
2. A item can only stored once in a collection. (because the collection holds only a reference to the original object.)
3. A item can only be member of one collection at all.
4. If the collection moves the indexes, the item can't be deleted (__index won't be updated... so we loosing control :/ )
| As far as I can tell, all four of these limitations are because you store the item's index in the item itself. Why do it? If you really need to remove by value, you can first determine the index, then use that to remove the item. For example, see the end of this post.
| Quote: | | collection_remove(_col,byref item){ | Note that ByRef is only necessary to pass a variable reference; i.e. if you need to assign a new value to the variable. Since you are only accessing properties of an object, I would recommend removing "byref" so that variables aren't required. For instance, the following won't work with ByRef since apples[i] isn't a variable:
| Code: | | oranges.remove(apples[i]) |
| Quote: | i := _col._MaxIndex() = "" ? 1 : _col._MaxIndex() + 1
_col._Insert(i, item)
_col.Count := _col.Count + 1 | Why use both _MaxIndex() and a manually-maintained count? If valid indices are [1..Count], Count is equivalent to _MaxIndex(). If you want col.Count without () to automatically call collection_count, use MetaProps:
| Code: | collection.__Get := MetaProps()
collection.__Get["count"] := "collection_count" |
You might be interested in temp01's Array lib. Example:
| Code: | apples := Array("red", "orange", "green")
apples.Delete(apples.indexOf("orange"))
msgbox % apples[1] "," apples[2] "," apples[3] ; red,green,
| Delete() is equivalent to _Remove() in this case; Delete accepts up to 6 indices to remove, whereas _Remove accepts either a single index or the first and last of a range. |
|
| Back to top |
|
 |
linpinger
Joined: 20 Oct 2007 Posts: 14 Location: china,hubei
|
Posted: Mon Feb 01, 2010 8:11 am Post subject: |
|
|
Is this a bug ?
Test code:
| Code: |
string := "君子以自强不息"
b := "自"
msgbox, % instr(string, b)
|
In Revision 40:
output is : 10
In Revision 43:
output is : 0 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Feb 01, 2010 11:11 am Post subject: |
|
|
I am unable to test with those characters in any ANSI build, as they do not exist in my system code page. Please note that L41 and earlier (including standard AutoHotkey) were available only in ANSI flavour, and supported only files in the system code page (not any form of Unicode). L42 and later can be built for Unicode, but prior to my previous post, the available executables were ANSI based.
Try downloading AutoHotkey_L.zip again from here, as it is currently a Unicode build. I have tested on this build with your script saved as UTF-16, and it returns 4 as expected.
That's a bit odd. What does it show on standard AutoHotkey v1.0.48.05? Also, what encoding are you using for the file? Are those 8-bit characters? (If not, it is unlikely that any ANSI build will give you the desired result.) |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2462
|
Posted: Mon Feb 01, 2010 11:28 am Post subject: |
|
|
Looks like he encoded the string in UTF-8. All those double-byte characters consume 3-bytes in UTF-8.
| Code: | | ANSI: 7, UTF-8: 10, UTF-16: 4 |
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4511 Location: Belgrade
|
Posted: Mon Feb 01, 2010 1:48 pm Post subject: |
|
|
UTF-8 + BOM return 4.
UTF-8 returns 10. _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Feb 01, 2010 2:46 pm Post subject: |
|
|
Thanks Sean, that put me in the right direction.
It seems that InStr incorrectly fails to find the string (returns 0) when:
- L43 (or presumably L42) ANSI build is used;
- 'Needle' contains any character whose unsigned value is >= 0x80; and
- InStr is used in case-insensitive mode without StringCaseSense Locale.
L42 introduced this issue along with ctoupper/ctolower from AutoHotkeyU. It has been fixed for future ANSI builds; see this commit for more info. In the mean-time, I suggest any users affected by this issue download the Unicode build, as it's likely to give better results (particularly when UTF-8 or -16 is used).
| majkinetor wrote: | | UTF-8 + BOM return 4. | That is one example of "better results" given by the Unicode build. On the ANSI build with my current language settings, all of the characters in "君子以自强不息" are replaced with "?", so InStr returns 1.
At the time of this post, UTF-8 saved without BOM is interpreted by all builds of AutoHotkey_L as the system code page. Do not expect such files to work correctly. |
|
| Back to top |
|
 |
linpinger
Joined: 20 Oct 2007 Posts: 14 Location: china,hubei
|
Posted: Tue Feb 02, 2010 3:00 am Post subject: |
|
|
At First ,Thanks Lexikos and Others
| Lexikos wrote: | | What does it show on standard AutoHotkey v1.0.48.05? Also, what encoding are you using for the file? Are those 8-bit characters? (If not, it is unlikely that any ANSI build will give you the desired result.) |
My default codepage is ANSI, File Encoding is cp936 or gb2312 or GBK
They are the same, they are 8-bit characters, and two characters is a chinese word, english is still one character
In standard AutoHotkey v1.0.48.05, Result is 7
In Revision 40, Result is 7 ( yesterday's script's encoding is UTF-8 )
Now In Your New Revision 43, Result is 4
Instr() works now, but it treat a chinese word to be one character, it may effect some other scripts |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4511 Location: Belgrade
|
Posted: Tue Feb 02, 2010 1:17 pm Post subject: |
|
|
Hello
Are there any plans to add "operational" metafunctions like add, sub, pow, mul, concat, len, eq, lt, gt and so on.
One additional object information that would be great to have is "default property" (VB has it for instance)
| Code: | Base := Object("__Mul", "Mul", "__Default", "Show", "y", 0, "x", 0)
c1 := Object("x", 2, "y", 5, "base", Base)
c2 := Object("x", 5, "y", 3, "base", Base)
d := c1 * c2
msgbox % d
Mul(l, r) {
return Object("x", L.x*R.x - L.y*R.y, "y", L.y*R.x + L.x*R.y, "base", this.base)
}
Show(this) {
return this.x " + " this.y "i"
}
|
I also wonder is it achievable to define default function call. It could come handy in various situations:
| Code: | MyClass := Object("__DefaultFunc", "New", ....)
x := MyClass(p1, ... pn)
y := MyClass()
New(this, p1="", ... pn="") {
return Object("base", this.base)
}
;--------------------------
msgbox := DllImport("MessageBoxA", "uint", 0 .....) ;creates an object msgbox
msgbox(0, "Title", "Prompt"...) ;same as msgbox.invoke(...)
|
_________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4511 Location: Belgrade
|
Posted: Tue Feb 02, 2010 2:05 pm Post subject: |
|
|
BTW, in bellow code (slightly modified version from your code on one of the previous pages) accessing any field of Obj will crash AHKL:
| Code: | TThumb := Object()
TThumb.__Get := TThumb.__Set := Object("base", Object("__Call","MetaProps"), "label", "TThumb")
TThumb.__Set.Width := "Thumb_Width"
thumb := Object("base", TThumb, "label", "thumb")
thumb.Width := 1 ; set to 1
MsgBox % thumb.Width
thumb.Width := 1.9 ; set to 2
MsgBox % thumb.Width
thumb.Width := "foo" ; fail, leave as is
MsgBox % thumb.Width
return
Thumb_Width(this, value) {
static _width
if (value == "#gEt#")
return _width
if value is not number
return ""
value := Round(value)
return _width := value
}
MetaProps(this, obj, name, param="#gEt#") {
;msgbox obj.label <-------------- crash
if IsFunc(prop := this[name])
return %prop%(obj, param)
} |
_________________
 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|