AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AutoHotkey_L: Arrays, Debugger, x64, COM, #If expression ...
Goto page Previous  1, 2, 3 ... 22, 23, 24 ... 68, 69, 70  Next
 
This topic is locked: you cannot edit posts or make replies.    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
IsNull



Joined: 10 May 2007
Posts: 593
Location: .switzerland

PostPosted: Fri Jan 29, 2010 7:41 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Fri Jan 29, 2010 8:18 pm    Post subject: Reply with quote

@ IsNull, have you tried WideObject
_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
jethrow



Joined: 24 May 2009
Posts: 1907
Location: Iowa, USA

PostPosted: Fri Jan 29, 2010 10:05 pm    Post subject: Reply with quote

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])?
_________________
Very Happy - in case I forgot to smile
Basic Webpage Controls
COM Object Reference
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Sat Jan 30, 2010 3:16 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
fincs



Joined: 05 May 2007
Posts: 1163
Location: Seville, Spain

PostPosted: Sat Jan 30, 2010 10:29 am    Post subject: Reply with quote

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 Evil or Very Mad
_________________
fincs
Get SciTE4AutoHotkey v3.0.00 (Release Candidate)
[My project list]
Back to top
View user's profile Send private message
IsNull



Joined: 10 May 2007
Posts: 593
Location: .switzerland

PostPosted: Sat Jan 30, 2010 11:13 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Sat Jan 30, 2010 1:27 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
linpinger



Joined: 20 Oct 2007
Posts: 14
Location: china,hubei

PostPosted: Mon Feb 01, 2010 8:11 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Mon Feb 01, 2010 11:11 am    Post subject: Reply with quote

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.
Quote:
output is : 10
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
View user's profile Send private message Visit poster's website
Sean



Joined: 12 Feb 2007
Posts: 2462

PostPosted: Mon Feb 01, 2010 11:28 am    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Mon Feb 01, 2010 1:48 pm    Post subject: Reply with quote

UTF-8 + BOM return 4.
UTF-8 returns 10.
_________________
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Mon Feb 01, 2010 2:46 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
linpinger



Joined: 20 Oct 2007
Posts: 14
Location: china,hubei

PostPosted: Tue Feb 02, 2010 3:00 am    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Tue Feb 02, 2010 1:17 pm    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Tue Feb 02, 2010 2:05 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
This topic is locked: you cannot edit posts or make replies.    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 22, 23, 24 ... 68, 69, 70  Next
Page 23 of 70

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group