Writing Modules

advertisement
Overview
Writing Modules
• Before You Start
• Structure of a Module
• Ports and Datatypes
• Component Wizard
• GUI’s
• Dynamic Compilation
NCRR
Before You Start
Design Your Function
•
•
•
•
Writing Modules
A Module is a Function
Inputs and Outputs
User Input (GUI Variables)
Dataflow
Coding Standard
• Standards
• Advice
• SCIRun/doc/Developer/Guide/coding_standard.html
NCRR
Module Structure
Writing Modules
Support Files
•
•
•
•
•
•
.cc file
sub.mk
.xml file
.tcl file
sub.mk
.h file (optional)
NCRR
Ports and Datatypes
Ports
•
•
•
•
•
Writing Modules
LockingHandles
Generation number
Memory Management
Sending Data
Cache Results
Datatypes
• Fields, Matrix, SceneGraph
• Detach (Dataflow)
• Properties
NCRR
Component Wizard
Adding a Module
Writing Modules
NCRR
Component Wizard
Writing Modules
NCRR
Component Wizard
Edit a Port
Writing Modules
• Name
• Namespace
NCRR
Component Wizard
• Package
• Category
• Path
Writing Modules
NCRR
Component Wizard
• New Package?
• New Category?
• Reconfiguring.
Writing Modules
NCRR
Component Wizard
After Compiling
Writing Modules
NCRR
Component Wizard
Your Skeleton GUI
Writing Modules
NCRR
GUI’s
Writing Modules
TCL
• itcl
• blt
• Use Simple GUI as a Pattern
• GuiVars
NCRR
GUI’s
itcl_class SCIRun_Fields_SelectField {
inherit Module
constructor {config} {
set name SelectField
Writing Modules
global $this-stampvalue
global $this-runmode
}
set_defaults
method set_defaults {} {
set $this-stampvalue 100
set $this-runmode 0
# 0 nothing 1 accumulate 2 replace
}
method replace {} {
set $this-runmode 2
$this-c needexecute
}
method accumulate {} {
set $this-runmode 1
$this-c needexecute
}
NCRR
GUI’s
method ui {} {
set w .ui[modname]
if {[winfo exists $w]} {
raise $w
return
}
toplevel $w
Writing Modules
frame $w.row1
frame $w.row3
frame $w.row4
pack $w.row1 $w.row3 $w.row4 -side top -e y -f both -padx 5 -pady 5
label $w.row1.value_label -text "Selection Value"
entry $w.row1.value -textvariable $this-stampvalue
pack $w.row1.value_label $w.row1.value -side left
button $w.row3.execute -text "Replace" -command "$this replace"
pack $w.row3.execute -side top -e n -f both
button $w.row4.execute -text "Accumulate" -command "$this accumulate"
pack $w.row4.execute -side top -e n -f both
}
NCRR
GUI’s
Writing Modules
GuiVars
• Values to from C side
- Initialize

C++ side constructor synchs with tcl name

tcl side sets the initial value
- my_var.reset()
- my_var.get()
• tcl_command(...)
- $this-c “needexecute”
NCRR
Dynamic Compilation
Writing Modules
Motivation
• SCIRun::Field
• Code Explosion
• Extensibility
• Maintenance
NCRR
Dynamic Compilation
Writing Modules
Field Types (4)
TetVol, LatticeVol, ContourField, TriSurf
Supported Data Types (9)
double, int, char, unsigned char, short,
unsigned short, bool, Vector, and Tensor
An Algorithm Parameterized on One Field Type
• Requires 36 Field instantiations
• And 36 Algorithm Instantiations
Parameterized On Two Fields
• 362 = 1296 Versions of the Algorithm
Parameterized On Three Fields
• 363 = 46656 Versions of the Algorithm
Actual implementation supports more Field and Data types
Very few of these combinations are needed by any one person or
application
NCRR
Algorithm Structure
Writing Modules
Algorithm Base Class
• Inherits from common base class
• Defines the pure virtual interface needed by a module
• Provides a static CompileInfo
Templated Algorithm
• Implements the pure virtual interface in the base class
• Potentially specialized for specific field type
template<class Field> RenderField : public RenderFieldBase
RenderFieldBase
RenderField<TetVol<double> >
virtual void render(FieldBase&)=0;
RenderField<LatticeVol<double> >
RenderField<TetVol<Vector> >
RenderField<LatticeVol<Vector> >
etc...
NCRR
TypeDescription
TypeDescription object augments RTTI
Holds:
Writing Modules
• Strings that describe object’s exact type
• Namespace string
• Path to the .h file that declares the object
Has a recursive structure
Example: foo<bar,
foobar<int> >;
foo
bar
foobar
int
NCRR
CompileInfo
Writing Modules
Similar info as a TypeDescription
Algorithm is not instantiated, so cannot yet be
queried
Start with a CompileInfo from Algorithm base class
Augmented with information from all pertinent
TypeDescription objects for the specific types
involved
Passed to DynamicLoader, which creates the
proper type
NCRR
DynamicLoader
Returns Requested Algorithm
•
•
•
•
Writing Modules
Writes C++ instantiation code
Compile shared library, using SCIRun makefiles
Load shared library (dlopen)
Return Instance of Algorithm (Cached for next use)
Synchronization code such that
• Only 1 thread can compile at a time per algorithm
• Multiple algorithms can compile and load at the same time
NCRR
Calling Module
void ShowField::execute()
{
// Get a Field from input field port.
field = (FieldIPort *)get_iport("Field");
field->get(field_handle);
Writing Modules
// Get the input field's type info.
const TypeDescription *td = field_handle->get_type_description();
// Get the Algorithm.
CompileInfo *ci = RenderFieldBase::get_compile_info(td);
if (! DynamicLoader::scirun_loader().get(*ci, rend_algo)) {
error("Could not compile algorithm for ShowField -");
return;
}
RenderFieldBase *rf = dynamic_cast<RenderFieldBase*>(rend_algo);
// Let the templated algorithm render this field.
rf->render(field_handle, /* any other parameters from gui */);
}
// Send results downstream...
No template instantiations for the exact algorithm type
NCRR
Example
Writing Modules
//! ConvertTetBase supports the dynamically loadable algorithm concept.
//! when dynamically loaded the user will dynamically cast to a
//! ConvertTetBase from the DynamicAlgoBase they will have a pointer to.
class ConvertTetBase : public DynamicAlgoBase
{
public:
virtual FieldHandle convert_quadratic(FieldHandle in) = 0;
virtual ~ConvertTetBase();
static const string& get_h_file_path();
static string dyn_file_name(const TypeDescription *td) {
// add no extension.
return template_class_name() + "." + td->get_filename() + ".";
}
static const string base_class_name() {
static string name("ConvertTetBase");
return name;
}
static const string template_class_name() {
static string name("ConvertTet");
return name;
}
//! support the dynamically compiled algorithm concept
static CompileInfo *get_compile_info(const TypeDescription *td);
};
NCRR
Example
Writing Modules
template <class Fld>
class ConvertTet : public ConvertTetBase
{
public:
//! virtual interface.
virtual FieldHandle convert_quadratic(FieldHandle in);
};
template <class Fld>
FieldHandle
ConvertTet<Fld>::convert_quadratic(FieldHandle ifh)
{
Fld *fld = dynamic_cast<Fld*>(ifh.get_rep());
ASSERT(fld != 0);
typedef typename Fld::value_type val_t;
FieldHandle fh(QuadraticTetVolField<val_t>::create_from(*fld));
return fh;
}
NCRR
Summary
Writing Modules
Concepts
• Ports and Datatypes
• Modules (Component Wizard)
• Templated Algorithms
• Dynamic Loading
NCRR
Download