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 

options.ahkl - an options object for AutoHotkey_L v.1a

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
ahklerner



Joined: 26 Jun 2006
Posts: 1317
Location: USA

PostPosted: Wed Sep 30, 2009 9:32 am    Post subject: options.ahkl - an options object for AutoHotkey_L v.1a Reply with quote

requires newest update of autohotkey_l
still probably has bugs
version .1 alpha
i know there is lots of room for improvement, and im working on it.
Very Happy

Test Script:
Code:
o := Options("","wp+100 h200 xp-20 yp+250 xs+200 ys-30 xm+10 ym-3 vMyProgress")          ; create options object
o.wp := "+400"
o.LastFound := "True"    ; Setting an Option to "True" (the string)  outputs +Option
o.ToolWindow := "True"
o.Caption := "False"    ; Setting Option to "False" (the string)  outputs -Option
;o.Color := "Blue"
MsgBox % "current options:`n" .  o.ToParam()

Esc::ExitApp



Code:
; options.ahkl
; requires AutoHotkey_L
; by ahklerner
;version .1 alpha
; This object  handles a gui's or control's "Options"
; intended use is by control and gui object... but can be modified to suit other purposes
;

Options_Opt(ByRef sOpts,sName,sVal="¬"){
   if (sVal = "¬"){ ; get the option
      if RegExMatch(sOpts, sName . "=(\+?-?[a-zA-Z0-9\s]*)¬",Match)
         return Match1
      else
         return ""
   }
   if RegExMatch(sOpts, sName . "=(\+?-?[a-zA-Z0-9\s]*)¬",Match)
      sOpts := RegExReplace(sOpts,sName . "=(\+?-?[a-zA-Z0-9\s]*)¬",sName . "=" . sVal . "¬")
   else if (sOpts = "¬")
      sOpts := sName . "=" . sVal . "¬"
   else
      sOpts .= sName . "=" . sVal . "¬"
   return sOpts
}


Options_GetVal(obj, name){
   if name = Parent
      return obj.Parent
   sOpts := obj.ToStr
   return Options_Opt(sOpts,name)
}

Options_SetVal(obj, name, val){
;MsgBox % "options:SetVal`nname:" . name . "`nval:" . val
   if name = Parent
      return obj.Parent := val

   if name = ToStr
      return obj.ToStr := val
   sOpts := obj.ToStr
   ret := Options_Opt(sOpts,name,val)
   obj.ToStr := sOpts
   return ret
}

Options_Import(obj,prm0){
   options := obj
   Loop, Parse, prm0, %A_Space%
      {
         if RegExMatch(A_LoopField,"wp(-[a-zA-Z0-9\s]*)",Match)
            out .= "wp=" . Match1 . "¬"
            , options.wp := Match1
         else if RegExMatch(A_LoopField,"hp(-[a-zA-Z0-9\s]*)",Match)
            out .= "hp=" . Match1 . "¬"
            , options.hp := Match1
         else if RegExMatch(A_LoopField,"wp(\+[a-zA-Z0-9\s]*)",Match)
            out .= "wp=" . Match1 . "¬"
            , options.wp := Match1
         else if RegExMatch(A_LoopField,"hp(\+[a-zA-Z0-9\s]*)",Match)
            out .= "hp=" . Match1 . "¬"
            , options.hp := Match1

         else if RegExMatch(A_LoopField,"xp(-[a-zA-Z0-9\s]*)",Match)
            out .= "xp=" . Match1 . "¬"
            , options.xp := Match1
         else if RegExMatch(A_LoopField,"yp(-[a-zA-Z0-9\s]*)",Match)
            out .= "yp=" . Match1 . "¬"
            , options.yp := Match1
         else if RegExMatch(A_LoopField,"xp(\+[a-zA-Z0-9\s]*)",Match)
            out .= "xp=" . Match1 . "¬"
            , options.xp := Match1
         else if RegExMatch(A_LoopField,"yp(\+[a-zA-Z0-9\s]*)",Match)
            out .= "yp=" . Match1 . "¬"
            , options.yp := Match1

         else if RegExMatch(A_LoopField,"xm(-[a-zA-Z0-9\s]*)",Match)
            out .= "xm=" . Match1 . "¬"
            , options.xm := Match1
         else if RegExMatch(A_LoopField,"xm(\+[a-zA-Z0-9\s]*)",Match)
            out .= "xm=" . Match1 . "¬"
            , options.xm := Match1

         else if RegExMatch(A_LoopField,"ym(-[a-zA-Z0-9\s]*)",Match)
            out .= "ym=" . Match1 . "¬"
            , options.ym := Match1
         else if RegExMatch(A_LoopField,"ym(\+[a-zA-Z0-9\s]*)",Match)
            out .= "ym=" . Match1 . "¬"
            , options.ym := Match1


         else if RegExMatch(A_LoopField,"xs(-[a-zA-Z0-9\s]*)",Match)
            out .= "xs=" . Match1 . "¬"
            , options.xs := Match1
         else if RegExMatch(A_LoopField,"xs(\+[a-zA-Z0-9\s]*)",Match)
            out .= "xs=" . Match1 . "¬"
            , options.xs := Match1

         else if RegExMatch(A_LoopField,"ys(-[a-zA-Z0-9\s]*)",Match)
            out .= "ys=" . Match1 . "¬"
            , options.ys := Match1
         else if RegExMatch(A_LoopField,"ys(\+[a-zA-Z0-9\s]*)",Match)
            out .= "ys=" . Match1 . "¬"
            , options.ys := Match1


         else if RegExMatch(A_LoopField,"ym",Match)
            out .= "ym=True¬"
            , options.ym := "True"
         else if RegExMatch(A_LoopField,"xm",Match)
            out .= "xm=True¬"
            , options.xm := "True"
         else if RegExMatch(A_LoopField,"xs",Match)
            out .= "xs=True¬"
            , options.xs := "True"
         else if RegExMatch(A_LoopField,"ys",Match)
            out .= "ys=True¬"
            , options.ys := "True"

         else if RegExMatch(A_LoopField,"v([a-zA-Z0-9\s]*)",Match){
            Match1 = %Match1%
            ;MsgBox Var Imported
            out .= "v" . "=" . Match1 . "¬"
            options.Parent.v := Match1
            obj.Parent[Match1] := options.Parent
         }
         
         else if RegExMatch(A_LoopField,"g([a-zA-Z0-9\s]*)",Match)
            out .= "g" . "=" . Match1 . "¬"
            , options.g := Match1
         else if RegExMatch(A_LoopField,"w([a-zA-Z0-9\s]*)",Match)
            out .= "w" . "=" . Match1 . "¬"
            , options.w := Match1
         else if RegExMatch(A_LoopField,"h([a-zA-Z0-9\s]*)",Match)
            out .= "h" . "=" . Match1 . "¬"
            , options.h := Match1
         else if RegExMatch(A_LoopField,"x([a-zA-Z0-9\s]*)",Match)
            out .= "x" . "=" . Match1 . "¬"
            , options.x := Match1
         else if RegExMatch(A_LoopField,"y([a-zA-Z0-9\s]*)",Match)
            out .= "y" . "=" . Match1 . "¬"
            , options.y := Match1
         else if RegExMatch(A_LoopField,"\+([a-zA-Z0-9\s]*)",Match)
            out .= Match1 . "=True¬"
            , options[Match1] := "True"
         else if RegExMatch(A_LoopField,"\-([a-zA-Z0-9\s]*)",Match)
            out .= Match1 . "=False¬"
            , options[Match1] := "False"
      }

}

Options_ToParam(obj){
   StringOpt := obj.ToStr
   Loop, Parse, StringOpt, ¬
   {
      RegExMatch(A_LoopField,"([a-zA-Z0-9\s]*)=",name)
      OptName = %name1%
      RegExMatch(A_LoopField,"=(\+?-?[a-zA-Z0-9\s]*)",val)
      OptVal = %val1%
      if OptVal = False
         RetVal .= "-" . OptName . " "
      else if OptVal = True
         RetVal .= "+" . OptName . " "
      else
         RetVal .= OptName . OptVal . " "
   }
   return RetVal
}

Options_SetParent(obj,parentObj){
}

Options(parent="",param="¬"){
   static COBase
   If !COBase
      COBase := Object(      "__Get"      , "Options_GetVal"  ;    default getter
                     ,   "__Set"      , "Options_SetVal"  ;    default setter
                     ,   "ToParam"   , "Options_ToParam" ;    .ToParam()
                     ,   "Import"   , "Options_Import") ;    .Import(sOptions)
;                     ,   "SetParent"   , "Options_SetParent") ;    .SetParent(parentObj)

   obj := Object("ToStr", " ", "Parent"," ","base", COBase)
   if (param != "¬"){
      obj.Import(param)
   }
   return obj
}



_________________

ʞɔпɟ əɥʇ ʇɐɥʍ


Last edited by ahklerner on Wed Sep 30, 2009 9:11 pm; edited 1 time in total
Back to top
View user's profile Send private message
ahklerner



Joined: 26 Jun 2006
Posts: 1317
Location: USA

PostPosted: Wed Sep 30, 2009 11:12 am    Post subject: Reply with quote

updated
_________________

ʞɔпɟ əɥʇ ʇɐɥʍ
Back to top
View user's profile Send private message
ahklerner



Joined: 26 Jun 2006
Posts: 1317
Location: USA

PostPosted: Wed Sep 30, 2009 9:12 pm    Post subject: Reply with quote

updated.......i think it handles all control options now.
_________________

ʞɔпɟ əɥʇ ʇɐɥʍ
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4726
Location: Australia

PostPosted: Sat Nov 28, 2009 5:01 am    Post subject: Reply with quote

Some comments:
  • I just noticed your big RegEx if..else if ladder, and it made me cringe.
  • The lack of ^anchor causes false positives such as the "w" in "+ToolWindow".
  • Most or all options are not case-sensitive, but your regexes are.
  • Your regexes include \s, for no apparent reason. It will not match any spaces (since the outer parsing loop excludes them), tabs should be equivalent to spaces and other whitespace characters probably aren't valid.
  • Options such as "xs +ys -xm" (whether this example is valid or not) come out as "+xs +ys +ym".
  • "\+?-?" is used in a few regexes; it should probably be "[+-]?" (i.e. allow either one or neither, but not both.)
  • "[a-zA-Z0-9\s]" is used even with options that allow only numbers or allow additional characters. (For instance, v_#var or g(practically-anything).) Although this isn't much of a problem, I would suggest using \w as it is easier on the eyes. It excludes some less common valid characters (for v and g), but includes one of the most common symbols: _.

Anyway, here's my take on the parsing loop in Options_Import:
Code:
Options_Import(obj,prm0){
   options := obj
   Loop, Parse, prm0, %A_Space%%A_Tab%
      {
         if RegExMatch(A_LoopField,"i)^([xy][mps]?|[wh]p?)(\+?-?\d\w*)$",Match)
            options[Match1] := Match2
 
         else if RegExMatch(A_LoopField,"i)^v(\w+)$",Match)
            options.Parent.v := Match1
            , obj.Parent[Match1] := options.Parent
 
         else if RegExMatch(A_LoopField,"^\+?(\w+)$",Match)
            options[Match1] := "True"
         else if RegExMatch(A_LoopField,"^\-(\w+)$",Match)
            options[Match1] := "False"
      }
}
It should perform better in addition to being much more maintainable and readable. It also allows a few options/values that didn't work before, but still doesn't handle all valid cases. Note the \d\w* part of the first regex: I think it should include all but the rarest valid options and exclude some false positives (like "wrap" and "hidden"). You could write a more complex regex to ensure it really is a number, but I suppose it wouldn't be worth it.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
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