Tcl Library Source Code

Check-in [9e1225edc2]
Login

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: 9e1225edc2567540305196809fa79709754c8d50
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
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to modules/cron/cron.tcl.

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 get $processTable($task) coroutine]
      set command [dict get $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







|
|







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
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







|




|
|


|
|


|
|







|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
<
|




|
|

|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|



|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|
|
|
|
|
|
|
|
|
|
|








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|








|
|
|
|
|
|
|



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
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.6

namespace eval ::oo::meta {
  variable dirty_classes {}
  variable core_classes {::oo::class ::oo::object}
}

proc ::oo::meta::args_to_dict args {






|







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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
        set result [linsert $result 0 $item]
      }
    }
  }
  return $result
}

proc ::oo::meta::info {class submethod args} {
  set class [::oo::meta::normalize $class]
  switch $submethod {
    rebuild {
      if {$class ni $::oo::meta::dirty_classes} {
        lappend ::oo::meta::dirty_classes $class
      }
    }
    is {
      set info [metadata $class]
      return [string is [lindex $args 0] -strict [dict getnull $info {*}[lrange $args 1 end]]]
    }
    for -
    map {







|



<
|
<







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
113
114
115
116
117
118
119
120
121
122
      set result {}
      foreach {field value} [dict getnull $info {*}$args] {
        dict set result [string trimright $field :] $value
      }
      return $result
    }
    branchset {
      if {$class ni $::oo::meta::dirty_classes} {
        lappend ::oo::meta::dirty_classes $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]







<
|
<







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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    }
    append -
    incr -
    lappend -
    set -
    unset -
    update {
      if {$class ni $::oo::meta::dirty_classes} {
        lappend ::oo::meta::dirty_classes $class
      }
      ::dict $submethod ::oo::meta::local_property($class) {*}$args
    }
    merge {
      if {$class ni $::oo::meta::dirty_classes} {
        lappend ::oo::meta::dirty_classes $class
      }
      set ::oo::meta::local_property($class) [dict rmerge $::oo::meta::local_property($class) {*}$args]
    }
    dump {
      set info [metadata $class]
      return $info
    }
    default {







<
|
<



<
|
<







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
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.6 [list source [file join $dir oometa.tcl]]
package ifneeded oo::option 0.3 [list source [file join $dir oooption.tcl]]






|

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
6
7
8








9
10
11
12

13
14
15
16
17
18
19
20
21
::namespace eval ::tool::define {}





















###
# topic: fb8d74e9c08db81ee6f1275dad4d7d6f
###
proc ::tool::dynamic_methods_ensembles {thisclass metadata} {
  variable trace
  set ensembledict {}








  ###
  # Only go through the motions for classes that have a locally defined
  # ensemble method implementation
  ###

  foreach {ensemble einfo} [::oo::meta::info $thisclass getnull method_ensemble] {
    set einfo [dict getnull $metadata 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 {}}} {

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|


>
>
>
>
>
>
>
>




>

|







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
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.5.6








|

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
44
45
46
47
48
49
50
51
52

###
# topic: 2cfc44a49f067124fda228458f77f177
# title: Specify the constructor for a class
###
proc ::tool::define::constructor {arglist rawbody} {
  set body {
::tool::object_create [self]
my graft class [info object class [self]]
# Initialize public variables and options
my InitializePublic
  }
  append body $rawbody
  append body {
# Run "initialize"
my initialize







|
<







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
247
248
249
250
251
252
253
254
255



256






257
258
259
260
261
262
263
  }
  if { $dargs } {
    append result " ?option value?..."
  }
  return $result
}

proc ::tool::object_create objname {
  foreach varname {
    object_info
    object_signal
    object_subscribe
  } {
    variable $varname
    set ${varname}($objname) {}
  }



  set object_info($objname) [list class [info object class $objname]]






}


proc ::tool::object_rename {object newname} {
  foreach varname {
    object_info
    object_signal







|








>
>
>
|
>
>
>
>
>
>







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
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.5.6 [list source [file join $dir index.tcl]]











|
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]]