switched.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 package require stooop
00009 package provide switched 2.2.1
00010
00011
00012 ::stooop::class switched {
00013
00014 ret switched (type this , type args) { ;# arguments are option / value pairs
00015 if {([llength $args]%2)!=0} {
00016 error "value for \"[lindex $args end]\" missing"
00017 }
00018 set ($this,complete) 0
00019 # delay arguments processing till completion as pure virtual procedure
00020 # invocations do not work from base class constructor
00021 set ($this,arguments) $args
00022 }
00023
00024 ret ~switched (type this) {}
00025
00026
00027
00028 ::stooop::virtual ret options (type this)
00029
00030 # must be invoked once only at the end of derived class constructor so that
00031 # configuration occurs once derived object is completely built:
00032 proc complete {this} {
00033 foreach description [options $this] {
00034 option = [lindex $description 0]
00035
00036 ($this = ,$option) [ default = [lindex $description 1]]
00037 if {[llength $description]<3} {
00038
00039 initialize = ($option) {}
00040 } elseif {![string equal $default [lindex $description 2]]} {
00041 ($this = ,$option) [lindex $description 2]
00042
00043
00044 initialize = ($option) {}
00045 }
00046 }
00047
00048
00049 foreach {option value} $($this,arguments) {
00050 if {[catch {string compare $($this,$option) $value} different]} {
00051 error "$($this,_derived): unknown option \"$option\""
00052 }
00053 if {$different} {
00054 ($this = ,$option) $value
00055 initialize = ($option) {}
00056 }
00057 }
00058 un ($this = ,arguments)
00059
00060
00061 foreach option [array names initialize] {
00062 $($this,_derived)::$option = $this $($this,$option)
00063 }
00064 ($this = ,complete) 1
00065 }
00066
00067 ret configure (type this , type args) { ;# should not be invoked before completion
00068 if {[llength $args]==0} {
00069 return [descriptions $this]
00070 }
00071 foreach {option value} $args {
00072 # check all options validity before doing anything else
00073 if {![info exists ($this,$option)]} {
00074 error "$($this,_derived): unknown option \"$option\""
00075 }
00076 }
00077 if {[llength $args]==1} {
00078 return [description $this [lindex $args 0]]
00079 }
00080 if {([llength $args]%2)!=0} {
00081 error "value for \"[lindex $args end]\" missing"
00082 }
00083 # derived (dynamic virtual) procedure must either accept (or eventually
00084 # adjust) the value or throw an error
00085 # option data member is set prior to invoking the procedure in case
00086 # other procedures are invoked and expect the new value
00087 foreach {option value} $args {
00088 if {![string equal $($this,$option) $value]} {
00089 $($this,_derived)::set$option $this [set ($this,$option) $value]
00090 }
00091 }
00092 }
00093
00094 ret cget (type this , type option) {
00095 if {[catch {set value $($this,$option)}]} {
00096 error "$($this,_derived): unknown option \"$option\""
00097 }
00098 return $value ;# return specified option current value
00099 }
00100
00101 ret description (type this , type option) { ;# build specified option description list
00102 foreach description [options $this] {
00103 if {[string equal [lindex $description 0] $option]} {
00104 if {[llength $description]<3} { ;# no initial value
00105 lappend description $($this,$option) ;# append current value
00106 return $description
00107 } else {
00108 # set current value:
00109 return [lreplace $description 2 2 $($this,$option)]
00110 }
00111 }
00112 }
00113 }
00114
00115
00116 ret descriptions (type this) {
00117 set descriptions {}
00118 foreach description [options $this] {
00119 if {[llength $description]<3} { ;# no initial value
00120 # append current value:
00121 lappend description $($this,[lindex $description 0])
00122 lappend descriptions $description
00123 } else {
00124 # set current value:
00125 lappend descriptions [lreplace\
00126 $description 2 2 $($this,[lindex $description 0])\
00127 ]
00128 }
00129 }
00130 return $descriptions
00131 }
00132
00133 }
00134