Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Cron: Added error handling OOdialect: Fixed tabs and indentation (no code change) oometa: Added a mechanism for frameworks to intercept and detect when the metadata for a class has changed tool: Delays ensemble creation until object creation. Utilizes the new metadata modified method from oometa to invalidate the method ensembles for classed and their decendents. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9e1225edc2567540305196809fa79709 |
User & Date: | tne 2016-10-17 16:36:24 |
Context
2016-10-17
| ||
16:44 | Cron: Added error handling OOdialect: Fixed tabs and indentation (no code change) oometa: Added a mechanism for frameworks to intercept and detect when the metadata for a class has changed tool: Delays ensemble creation until object creation. Utilizes the new metadata modified method from oometa to invalidate the method ensembles for classed and their decendents. check-in: 182b1361cf user: hypnotoad tags: trunk | |
16:38 | Pulling changes from trunk check-in: bf145ead28 user: tne tags: odie | |
16:36 | Cron: Added error handling OOdialect: Fixed tabs and indentation (no code change) oometa: Added a mechanism for frameworks to intercept and detect when the metadata for a class has changed tool: Delays ensemble creation until object creation. Utilizes the new metadata modified method from oometa to invalidate the method ensembles for classed and their decendents. check-in: 9e1225edc2 user: tne tags: trunk | |
16:33 | Bumped oometa to version 0.7 Added a new hook to notify dialects that a class' metadata has changed Bumped tool to version 0.6 Added a procedure to intercept calls from oometa's new "rebuild" command, and signal that a class needs to rebuild it's ensemble methods. Added a new family of procedures to be executed when a new tool object is instantiated. On object startup, every object checks to see if they have a valid method ensemble. If not, it triggers a rebuild. This replaces the prior scheme where ensembles were built on response to tool::define check-in: 76c9fac30f user: tne tags: odie | |
2016-09-29
| ||
19:32 | Pulling changes from odie 1) Fixed the handling of the myaddr argument in the httpd example 2) Added the concept of compositing the metadata from multiple classes on a per-object basis to oometa 3) Bumped oometa to 0.6 4) Fixed a bug in tool that was causing the UUID seed to always initialize to empty string 5) Added a workaround for occasionally inconsitent cpu activity results from TWAPI in nettool::platform 6) Changed line breaks in the httpd.tcl example check-in: 8b2744c208 user: hypnotoad tags: trunk | |
Changes
Changes to modules/cron/cron.tcl.
︙ | ︙ | |||
359 360 361 362 363 364 365 | } continue } if {$::cron::trace > 2} { puts [list RUNNING $task [task info $task]] } dict set processTable($task) running 1 | | | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | } continue } if {$::cron::trace > 2} { puts [list RUNNING $task [task info $task]] } dict set processTable($task) running 1 set coro [dict getnull $processTable($task) coroutine] set command [dict getnull $processTable($task) command] if {$command eq {} && $coro eq {}} { # Task has nothing to do. Slot it for destruction lappend cancellist $task } elseif {$coro ne {}} { if {[info command $coro] eq {}} { set object [dict get $processTable($task) object] # Trigger coroutine again if a command was given |
︙ | ︙ | |||
429 430 431 432 433 434 435 436 437 438 439 440 441 442 | } dict set processTable($task) running 0 } foreach {task} $cancellist { unset -nocomplain processTable($task) } foreach {process} [lsort -dictionary [array names processTable]] { dict with processTable($process) { if {$scheduled==0 && $frequency==0} { if {$next_idle_event < $nextevent} { set nexttask $task set nextevent $next_idle_event } } elseif {$scheduled < $nextevent} { | > > | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | } dict set processTable($task) running 0 } foreach {task} $cancellist { unset -nocomplain processTable($task) } foreach {process} [lsort -dictionary [array names processTable]] { set scheduled 0 set frequency 0 dict with processTable($process) { if {$scheduled==0 && $frequency==0} { if {$next_idle_event < $nextevent} { set nexttask $task set nextevent $next_idle_event } } elseif {$scheduled < $nextevent} { |
︙ | ︙ |
Changes to modules/oodialect/oodialect.tcl.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # Meta author Donald K. Fellows # Meta license BSD # @@ Meta End package require TclOO namespace eval ::oo::dialect { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | # Meta author Donald K. Fellows # Meta license BSD # @@ Meta End package require TclOO namespace eval ::oo::dialect { namespace export create } # A stack of class names proc ::oo::dialect::Push {class} { ::variable class_stack lappend class_stack $class } proc ::oo::dialect::Peek {} { ::variable class_stack return [lindex $class_stack end] } proc ::oo::dialect::Pop {} { ::variable class_stack set class_stack [lrange $class_stack 0 end-1] } ### # This proc will generate a namespace, a "mother of all classes", and a # rudimentary set of policies for this dialect. ### proc ::oo::dialect::create {name {parent ""}} { set NSPACE [NSNormalize [uplevel 1 {namespace current}] $name] ::namespace eval $NSPACE {::namespace eval define {}} ### # Build the "define" namespace ### if {$parent eq ""} { ### # With no "parent" language, begin with all of the keywords in # oo::define ### foreach command [info commands ::oo::define::*] { set procname [namespace tail $command] interp alias {} ${NSPACE}::define::$procname {} \ ::oo::dialect::DefineThunk $procname } # Create an empty dynamic_methods proc proc ${NSPACE}::dynamic_methods {class} {} namespace eval $NSPACE { ::namespace export dynamic_methods ::namespace eval define {::namespace export *} } set ANCESTORS {} } else { ### # If we have a parent language, that language already has the # [oo::define] keywords as well as additional keywords and behaviors. # We should begin with that ### set pnspace [NSNormalize [uplevel 1 {namespace current}] $parent] apply [list parent { ::namespace export dynamic_methods ::namespace import -force ${parent}::dynamic_methods } $NSPACE] $pnspace apply [list parent { ::namespace import -force ${parent}::define::* ::namespace export * } ${NSPACE}::define] $pnspace set ANCESTORS [list ${pnspace}::object] } ### # Build our dialect template functions ### proc ${NSPACE}::define {oclass args} [string map [list %NSPACE% $NSPACE] { ### # To facilitate library reloading, allow # a dialect to create a class from DEFINE ### set class [::oo::dialect::NSNormalize [uplevel 1 {namespace current}] $oclass] if {[info commands $class] eq {}} { %NSPACE%::class create $class {*}${args} } else { ::oo::dialect::Define %NSPACE% $class {*}${args} } }] interp alias {} ${NSPACE}::define::current_class {} \ ::oo::dialect::Peek interp alias {} ${NSPACE}::define::aliases {} \ ::oo::dialect::Aliases $NSPACE interp alias {} ${NSPACE}::define::superclass {} \ ::oo::dialect::SuperClass $NSPACE if {[info command ${NSPACE}::class] ne {}} { ::rename ${NSPACE}::class {} } ### # Build the metaclass for our language ### ::oo::class create ${NSPACE}::class { superclass ::oo::dialect::MotherOfAllMetaClasses } # Wire up the create method to add in the extra argument we need; the # MotherOfAllMetaClasses will know what to do with it. ::oo::objdefine ${NSPACE}::class \ method create {name {definitionScript ""}} \ "next \$name [list ${NSPACE}::define] \$definitionScript" ### # Build the mother of all classes. Note that $ANCESTORS is already # guaranteed to be a list in canonical form. ### uplevel #0 [string map [list %NSPACE% [list $NSPACE] %name% [list $name] %ANCESTORS% $ANCESTORS] { %NSPACE%::class create %NSPACE%::object { superclass %ANCESTORS% # Put MOACish stuff in here } }] if {[info exists ::oo::meta::core_classes]} { if { "${NSPACE}::class" ni $::oo::meta::core_classes } { lappend ::oo::meta::core_classes "${NSPACE}::class" } if { "${NSPACE}::object" ni $::oo::meta::core_classes } { lappend ::oo::meta::core_classes "${NSPACE}::object" } } } # Support commands; not intended to be called directly. proc ::oo::dialect::NSNormalize {namespace qualname} { if {![string match ::* $qualname]} { set qualname ${namespace}::$qualname } regsub -all {::+} $qualname "::" } proc ::oo::dialect::DefineThunk {target args} { tailcall ::oo::define [Peek] $target {*}$args } proc ::oo::dialect::Canonical {namespace NSpace class} { namespace upvar $namespace cname cname if {[string match ::* $class]} { return $class } if {[info exists cname($class)]} { return $cname($class) } if {[info exists ::oo::dialect::cname($class)]} { return $::oo::dialect::cname($class) } foreach item [list "${NSpace}::$class" "::$class"] { if {[info command $item] ne {}} { return $item } } return ${NSpace}::$class } ### # Implementation of the languages' define command ### proc ::oo::dialect::Define {namespace class args} { Push $class try { if {[llength $args]==1} { namespace eval ${namespace}::define [lindex $args 0] } else { ${namespace}::define::[lindex $args 0] {*}[lrange $args 1 end] } ${namespace}::dynamic_methods $class } finally { Pop } } ### # Implementation of how we specify the other names that this class will answer # to ### proc ::oo::dialect::Aliases {namespace args} { set class [Peek] namespace upvar $namespace cname cname set NSpace [join [lrange [split $class ::] 1 end-2] ::] set cname($class) $class foreach name $args { set alias $name #set alias [NSNormalize $NSpace $name] # Add a local metaclass reference set cname($alias) $class if {![info exists ::oo::dialect::cname($alias)]} { ## # Add a global reference, first come, first served ## set ::oo::dialect::cname($alias) $class } } } ### # Implementation of a superclass keyword which will enforce the inheritance of # our language's mother of all classes ### proc ::oo::dialect::SuperClass {namespace args} { set class [Peek] namespace upvar $namespace class_info class_info dict set class_info($class) superclass 1 set ::oo::dialect::cname($class) $class set NSpace [join [lrange [split $class ::] 1 end-2] ::] set unique {} foreach item $args { set Item [Canonical $namespace $NSpace $item] dict set unique $Item $item } set root ${namespace}::object if {$class ne $root} { dict set unique $root $root } tailcall ::oo::define $class superclass {*}[dict keys $unique] } ### # Implementation of the common portions of the the metaclass for our # languages. ### ::oo::class create ::oo::dialect::MotherOfAllMetaClasses { superclass ::oo::class constructor {define definitionScript} { $define [self] { superclass } $define [self] $definitionScript } } package provide oo::dialect 0.3.1 |
Changes to modules/oometa/oometa.tcl.
1 2 3 4 5 6 | ### # Author: Sean Woods, [email protected] ## # TclOO routines to implement property tracking by class and object ### package require dicttool | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ### # Author: Sean Woods, [email protected] ## # TclOO routines to implement property tracking by class and object ### package require dicttool package provide oo::meta 0.7 namespace eval ::oo::meta { variable dirty_classes {} variable core_classes {::oo::class ::oo::object} } proc ::oo::meta::args_to_dict args { |
︙ | ︙ | |||
75 76 77 78 79 80 81 | set result [linsert $result 0 $item] } } } return $result } | | < | < | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | set result [linsert $result 0 $item] } } } return $result } proc oo::meta::info {class submethod args} { set class [::oo::meta::normalize $class] switch $submethod { rebuild { ::oo::meta::rebuild $class } is { set info [metadata $class] return [string is [lindex $args 0] -strict [dict getnull $info {*}[lrange $args 1 end]]] } for - map { |
︙ | ︙ | |||
106 107 108 109 110 111 112 | set result {} foreach {field value} [dict getnull $info {*}$args] { dict set result [string trimright $field :] $value } return $result } branchset { | < | < | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | set result {} foreach {field value} [dict getnull $info {*}$args] { dict set result [string trimright $field :] $value } return $result } branchset { ::oo::meta::rebuild $class foreach {field value} [lindex $args end] { ::dict set ::oo::meta::local_property($class) {*}[lrange $args 0 end-1] [string trimright $field :]: $value } } leaf_add { set result [dict getnull $::oo::meta::local_property($class) {*}[lindex $args 0]] ladd result {*}[lrange $args 1 end] |
︙ | ︙ | |||
132 133 134 135 136 137 138 | } append - incr - lappend - set - unset - update { | < | < < | < | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | } append - incr - lappend - set - unset - update { ::oo::meta::rebuild $class ::dict $submethod ::oo::meta::local_property($class) {*}$args } merge { ::oo::meta::rebuild $class set ::oo::meta::local_property($class) [dict rmerge $::oo::meta::local_property($class) {*}$args] } dump { set info [metadata $class] return $info } default { |
︙ | ︙ | |||
228 229 230 231 232 233 234 235 236 237 238 239 240 241 | if {[::info exists local_property($class)]} { lappend metadata $local_property($class) } set metadata [dict rmerge {*}$metadata] set cached_property($class) $metadata return $metadata } proc ::oo::meta::search args { variable local_property set path [lrange $args 0 end-1] set value [lindex $args end] | > > > > > > > > | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | if {[::info exists local_property($class)]} { lappend metadata $local_property($class) } set metadata [dict rmerge {*}$metadata] set cached_property($class) $metadata return $metadata } proc ::oo::meta::rebuild args { foreach class $args { if {$class ni $::oo::meta::dirty_classes} { lappend ::oo::meta::dirty_classes $class } } } proc ::oo::meta::search args { variable local_property set path [lrange $args 0 end-1] set value [lindex $args end] |
︙ | ︙ |
Changes to modules/oometa/pkgIndex.tcl.
1 2 3 4 5 6 | #checker -scope global exclude warnUndefinedVar # var in question is 'dir'. if {![package vsatisfies [package provide Tcl] 8.5]} { # PRAGMA: returnok return } | | | 1 2 3 4 5 6 7 8 | #checker -scope global exclude warnUndefinedVar # var in question is 'dir'. if {![package vsatisfies [package provide Tcl] 8.5]} { # PRAGMA: returnok return } package ifneeded oo::meta 0.7 [list source [file join $dir oometa.tcl]] package ifneeded oo::option 0.3 [list source [file join $dir oooption.tcl]] |
Changes to modules/tool/ensemble.tcl.
1 2 3 4 5 | ::namespace eval ::tool::define {} ### # topic: fb8d74e9c08db81ee6f1275dad4d7d6f ### | > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | ::namespace eval ::tool::define {} if {![info exists ::tool::dirty_classes]} { set ::tool::dirty_classes {} } ### # Monkey patch oometa's rebuild function to # include a notifier to tool ### proc ::oo::meta::rebuild args { foreach class $args { if {$class ni $::oo::meta::dirty_classes} { lappend ::oo::meta::dirty_classes $class } if {$class ni $::tool::dirty_classes} { lappend ::tool::dirty_classes $class } } } ### # topic: fb8d74e9c08db81ee6f1275dad4d7d6f ### proc ::tool::dynamic_object_ensembles {thisobject thisclass} { variable trace set ensembledict {} foreach dclass $::tool::dirty_classes { foreach {cclass cancestors} [array get ::oo::meta::cached_hierarchy] { if {$dclass in $cancestors} { unset -nocomplain ::tool::obj_ensemble_cache($cclass) } } } set ::tool::dirty_classes {} ### # Only go through the motions for classes that have a locally defined # ensemble method implementation ### if {[info exists ::tool::obj_ensemble_cache($thisclass)]} return foreach {ensemble einfo} [::oo::meta::info $thisclass getnull method_ensemble] { #set einfo [dict getnull $einfo method_ensemble $ensemble] set eswitch {} set default standard if {[dict exists $einfo default:]} { set emethodinfo [dict get $einfo default:] set arglist [lindex $emethodinfo 0] set realbody [lindex $emethodinfo 1] if {$arglist in {args {}}} { |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 | append body \n [list set methodlist $methodlist] append body \n "set code \[catch {switch -- \$method [list $eswitch]} result opts\]" append body \n {return -options $opts $result} oo::define $thisclass method $ensemble {{method default} args} $body # Define a property for this ensemble for introspection ::oo::meta::info $thisclass set ensemble_methods $ensemble: [lsort -dictionary [dict keys $einfo]] } } ### # topic: ec9ca249b75e2667ad5bcb2f7cd8c568 # title: Define an ensemble method for this agent ### ::proc ::tool::define::method {rawmethod args} { | > > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | append body \n [list set methodlist $methodlist] append body \n "set code \[catch {switch -- \$method [list $eswitch]} result opts\]" append body \n {return -options $opts $result} oo::define $thisclass method $ensemble {{method default} args} $body # Define a property for this ensemble for introspection ::oo::meta::info $thisclass set ensemble_methods $ensemble: [lsort -dictionary [dict keys $einfo]] } set ::tool::obj_ensemble_cache($thisclass) 1 } ### # topic: ec9ca249b75e2667ad5bcb2f7cd8c568 # title: Define an ensemble method for this agent ### ::proc ::tool::define::method {rawmethod args} { |
︙ | ︙ |
Changes to modules/tool/index.tcl.
︙ | ︙ | |||
52 53 54 55 56 57 58 | set ::tool::tool_root [file dirname $cwd] ::tool::pathload $cwd { uuid.tcl ensemble.tcl metaclass.tcl event.tcl } $idxfile | | | 52 53 54 55 56 57 58 59 60 | set ::tool::tool_root [file dirname $cwd] ::tool::pathload $cwd { uuid.tcl ensemble.tcl metaclass.tcl event.tcl } $idxfile package provide tool 0.6 |
Changes to modules/tool/metaclass.tcl.
︙ | ︙ | |||
37 38 39 40 41 42 43 | ### # topic: 2cfc44a49f067124fda228458f77f177 # title: Specify the constructor for a class ### proc ::tool::define::constructor {arglist rawbody} { set body { | | < | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ### # topic: 2cfc44a49f067124fda228458f77f177 # title: Specify the constructor for a class ### proc ::tool::define::constructor {arglist rawbody} { set body { ::tool::object_create [self] [info object class [self]] # Initialize public variables and options my InitializePublic } append body $rawbody append body { # Run "initialize" my initialize |
︙ | ︙ | |||
240 241 242 243 244 245 246 | } if { $dargs } { append result " ?option value?..." } return $result } | | > > > | > > > > > > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | } if { $dargs } { append result " ?option value?..." } return $result } proc ::tool::object_create {objname {class {}}} { foreach varname { object_info object_signal object_subscribe } { variable $varname set ${varname}($objname) {} } if {$class eq {}} { set class [info object class $objname] } set object_info($objname) [list class $class] if {$class ne {}} { $objname graft class $class foreach command [info commands [namespace current]::dynamic_object_*] { $command $objname $class } } } proc ::tool::object_rename {object newname} { foreach varname { object_info object_signal |
︙ | ︙ |
Changes to modules/tool/pkgIndex.tcl.
1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. if {![package vsatisfies [package provide Tcl] 8.6]} {return} | | | 1 2 3 4 5 6 7 8 9 10 11 12 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. if {![package vsatisfies [package provide Tcl] 8.6]} {return} package ifneeded tool 0.6 [list source [file join $dir index.tcl]] |