Tcl Library Source Code

Check-in [76c9fac30f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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
Timelines: family | ancestors | descendants | both | odie
Files: files | file ages | folders
SHA1: 76c9fac30f619e3a3b2c46a112ed51cec24f023f
User & Date: tne 2016-10-17 16:33:04
Context
2016-10-17
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
14:13
Fixed indentation in the source code. No functional changes check-in: dee02101fb user: tne tags: odie
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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