source: trunk/gui/scripts/tool.tcl @ 11

Last change on this file since 11 was 11, checked in by mmc, 16 years ago

Major reorganization of the entire package. The config.xml file
is now irrelevant. All the action is in the tool.xml file. The
main program now organizes all input into 1) side-by-side pages,
2) input/result (wizard-style) pages, or 3) a series of wizard-
style pages. The <input> can have <phase> parts representing
the various pages.

Added a new ContourResult? widget based on Swaroop's vtk plotting
code.

Also, added easymesh and showmesh to the "tools" directory.
We need these for Eric Polizzi's code.

File size: 8.0 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: tool - represents an entire tool
3#
4#  This object represents an entire tool defined by Rappture.
5#  Each tool resides in an installation directory with other tool
6#  resources (libraries, examples, etc.).  Each tool is defined by
7#  its inputs and outputs, which are tied to various widgets in the
8#  GUI.  Each tool tracks the inputs, knows when they're changed,
9#  and knows how to run itself to produce new results.
10# ======================================================================
11#  AUTHOR:  Michael McLennan, Purdue University
12#  Copyright (c) 2004-2005
13#  Purdue Research Foundation, West Lafayette, IN
14# ======================================================================
15package require BLT
16
17itcl::class Rappture::Tool {
18    public variable analyzer ""
19
20    constructor {xmlobj installdir args} { # defined below }
21
22    public method installdir {} { return $_installdir }
23    public method xml {args}
24
25    public method load {xmlobj}
26    public method changed {path}
27    public method run {args}
28    public method abort {}
29
30    public method widgetfor {path {widget ""}}
31    public method sync {}
32
33    private variable _xmlobj ""      ;# XML overall <run> object
34    private variable _installdir ""  ;# installation directory for this tool
35    private variable _path2widget    ;# maps path => widget on this page
36
37    private common job               ;# array var used for blt::bgexec jobs
38}
39                                                                               
40# ----------------------------------------------------------------------
41# CONSTRUCTOR
42# ----------------------------------------------------------------------
43itcl::body Rappture::Tool::constructor {xmlobj installdir args} {
44    if {![Rappture::library isvalid $xmlobj]} {
45        error "bad value \"$xmlobj\": should be Rappture::Library"
46    }
47    set _xmlobj $xmlobj
48
49    if {![file exists $installdir]} {
50        error "directory \"$installdir\" doesn't exist"
51    }
52    set _installdir $installdir
53
54    eval configure $args
55}
56
57# ----------------------------------------------------------------------
58# USAGE: xml <subcommand> ?<arg> <arg> ...?
59# USAGE: xml object
60#
61# Used by clients to manipulate the underlying XML data for this
62# tool.  The <subcommand> can be any operation supported by a
63# Rappture::library object.  Clients can also request the XML object
64# directly by using the "object" subcommand.
65# ----------------------------------------------------------------------
66itcl::body Rappture::Tool::xml {args} {
67    if {"object" == $args} {
68        return $_xmlobj
69    }
70    return [eval $_xmlobj $args]
71}
72
73# ----------------------------------------------------------------------
74# USAGE: run ?<path1> <value1> <path2> <value2> ...?
75#
76# This method causes the tool to run.  All widgets are synchronized
77# to the current XML representation, and a "driver.xml" file is
78# created as the input for the run.  That file is fed to the tool
79# according to the <tool><command> string, and the job is executed.
80#
81# Returns a list of the form {status result}, where status is an
82# integer status code (0=success) and result is the output from the
83# simulator.  Successful output is something like {0 run1293921.xml},
84# where 0=success and run1293921.xml is the name of the file containing
85# results.
86# ----------------------------------------------------------------------
87itcl::body Rappture::Tool::run {args} {
88    global errorInfo
89
90    # sync all widgets to the XML tree
91    sync
92
93    # if there are any args, use them to override parameters
94    foreach {path val} $args {
95        $_xmlobj put $path.current $val
96    }
97
98    foreach item {control output error} { set job($item) "" }
99
100    # write out the driver.xml file for the tool
101    set file "driver[pid].xml"
102    set status [catch {
103        set fid [open $file w]
104        puts $fid "<?xml version=\"1.0\"?>"
105        puts $fid [$_xmlobj xml]
106        close $fid
107    } result]
108
109    # execute the tool using the path from the tool description
110    if {$status == 0} {
111        set cmd [$_xmlobj get tool.command]
112        regsub -all @tool $cmd $_installdir cmd
113        regsub -all @driver $cmd $file cmd
114
115        set status [catch {eval blt::bgexec \
116            ::Rappture::Tool::job(control) \
117            -output ::Rappture::Tool::job(output) \
118            -error ::Rappture::Tool::job(error) $cmd} result]
119    } else {
120        set job(error) "$result\n$errorInfo"
121    }
122    if {$status == 0} {
123        file delete -force -- $file
124    }
125
126    # see if the job was aborted
127    if {[regexp {^KILLED} $job(control)]} {
128        return [list 0 "ABORT"]
129    }
130
131    #
132    # If successful, return the output, which should include
133    # a reference to the run.xml file containing results.
134    #
135    if {$status == 0} {
136        set file [string trim $job(output)]
137        return [list $status $file]
138    } elseif {"" != $job(output) || "" != $job(error)} {
139        return [list $status [string trim "$job(output)\n$job(error)"]]
140    }
141    return [list $status $result]
142}
143
144# ----------------------------------------------------------------------
145# USAGE: abort
146#
147# Clients use this during a "run" to abort the current job.
148# Kills the job and forces the "run" method to return.
149# ----------------------------------------------------------------------
150itcl::body Rappture::Tool::abort {} {
151    set job(control) "abort"
152}
153
154# ----------------------------------------------------------------------
155# USAGE: widgetfor <path> ?<widget>?
156#
157# Used by descendents such as a Controls panel to register the
158# various controls associated with this page.  That way, this Tool
159# knows what widgets to look at when syncing itself to the underlying
160# XML data.
161# ----------------------------------------------------------------------
162itcl::body Rappture::Tool::widgetfor {path {widget ""}} {
163    # if this is a query operation, then look for the path
164    if {"" == $widget} {
165        if {[info exists _path2widget($path)]} {
166            return $_path2widget($path)
167        }
168        return ""
169    }
170
171    # otherwise, associate the path with the given widget
172    if {[info exists _path2widget($path)]} {
173        error "$path already associated with widget $_path2widget($path)"
174    }
175    set _path2widget($path) $widget
176}
177
178# ----------------------------------------------------------------------
179# USAGE: load <xmlobj>
180#
181# Loads the contents of a Rappture <xmlobj> into the controls
182# associated with this tool.
183# ----------------------------------------------------------------------
184itcl::body Rappture::Tool::load {newobj} {
185    if {![Rappture::library isvalid $newobj]} {
186        error "\"$newobj\" is not a Rappture::library"
187    }
188
189    foreach path [array names _path2widget] {
190        if {"" != [$newobj element -as type $path.current]} {
191            set val [$newobj get $path.current]
192            if {[string length $val] > 0} {
193                $_path2widget($path) value $val
194            } else {
195                set obj [$newobj element -as object $path.current]
196                $_path2widget($path) value $obj
197            }
198        }
199    }
200}
201
202# ----------------------------------------------------------------------
203# USAGE: changed <path>
204#
205# Invoked automatically by the various widgets associated with this
206# tool whenever their value changes.  If this tool has a -analyzer,
207# then it is notified that input has changed, so it can reset itself
208# for a new analysis.
209# ----------------------------------------------------------------------
210itcl::body Rappture::Tool::changed {path} {
211    if {"" != $analyzer} {
212        $analyzer reset
213    }
214}
215
216# ----------------------------------------------------------------------
217# USAGE: sync
218#
219# Used by descendents such as a Controls panel to register the
220# various controls associated with this page.  That way, this Tool
221# knows what widgets to look at when syncing itself to the underlying
222# XML data.
223# ----------------------------------------------------------------------
224itcl::body Rappture::Tool::sync {} {
225    foreach path [array names _path2widget] {
226        $_xmlobj put $path.current [$_path2widget($path) value]
227    }
228}
Note: See TracBrowser for help on using the repository browser.