Kent Eschenberg:
|How can a network built through DXLink be set to reexecute when a global
|variable changes?
|
|The variable is used in the macro named "main" (in a call to another macro)
|and the execution mode has been set to ExecuteOnChange. DX responds nicely
|when the objects are rotated via the mouse and when the window size is
|changed.
|
|As a temporary solution, setting "resetObject" to 1 in SuperviseState makes
|things work as I expected. However, it seems that this parameter should
|generally be 0 so that I can change the object.
Kent,
I assume you mean when the variable changes from the DXLink side. (?)
If so, attached is a comment I saved off back when I was writing a
dxui-like DXLink app that may help. Basically, use DXLInputNamed, or do a
DXLSend in addition to trigger a net execution.
I didn't trace through dxui at the time to see exactly how it handles this
as I wasn't as comfortable picking through the DX source then, but the
right solution is buried in there somewhere.
Randall
------------------------------------------------------------------------------
Relevent "empirically-derived" example code that seems to work. In Python
not C, but the guts for both are basically the same
...
# APIs to set DXLInput and DXLInputNamed values
# (see the DXLInput note at bottom of file for why DXLSend is here too)
def SetValue ( self, var, value ):
assert type(value) == types.StringType and value
DXLSetValue ( self.conn, var, value )
DXLSend ( self.conn, '%s = %s;' % (var,value) )
def SetInteger( self, var, value ):
DXLSetInteger( self.conn, var, value )
DXLSend ( self.conn, '%s = %s;' % (var,value) )
def SetScalar ( self, var, value ):
DXLSetScalar ( self.conn, var, value )
DXLSend ( self.conn, '%s = %s;' % (var,value) )
def SetString ( self, var, value ):
assert type(value) == types.StringType and value
DXLSetString ( self.conn, var, value )
DXLSend ( self.conn, '%s = "%s";' % (var,value) )
...
"""
-------------------------------------------------------------------------------
DX NOTES:
1) DXLINPUT
DXLInputNamed and DXLInput are NOT functionally equivalent in all
circumstances in a DX network (for commercial DX at least).
A difference comes up when you're in ExecuteOnChange mode. If you
DXLSetInteger a DXLInput symbol for a .net-created DXLInput module, the
network does NOT automatically re-execute in response to the change. If
you only use DXLSet*, you must force an execution in order for this
change to propogate (DXLExecute*Once), or simply wait for the next
execution to propagate it for it to take effect. Not good.
However, if you use a DXLInputNamed module instead, setting its symbol
to a value via DXLSetInteger 'will' automatically re-execute the network
like it's supposed to.
THE HACK-AROUND: If you use DXLSend to set a DXLInput to a value, then
it will actually work. So for every DXLSet* call, we both call the
appropriate DXLSet* call as well as invoke DXLSend to set the value of
the script variable with the same name. This covers both cases
(i.e. where the module is a DXLInput, and where it's a DXLInputNamed).
As to the robustness of this hack: Note that every DXLInput actually
materializes as a script variable of the same name in the DX network
anyway. So when the module is a DXLInput, no naming conflicts are
introduced by both DXLSending and DXLSeting the value. In fact, DX is
going to set this variable anyway so you might as well. However, if the
module is a 'DXLInputNamed', it doesn't materialize as a script
variable. So concievably there might be a conflict by setting a script
variable of the same name using DXLSend. The question is whether DX
allows both a DXLInput and a DXLInputNamed which both answer to the same
name. Probably not since DXLSet can set both; either way, it's perverse
to do this. So by default our DXLSet* wrapper calls do both DXLSet and
DXLSend for Set* wrapper calls.
NOTES:
1) For DXLInput, if you directly set the output script variable for the
'virtual' DXLInput module (e.g. main_DXLInput_57_out_1 below) via
DXLSetInteger, it still won't execute. However, different than
before, it 'won't' get picked up when you execute the net later
either.
2) DXLSetValue doesn't help you any over DXLSetInteger
Interesting related note: When you do a DXLSet*, the DX message you get
back across the wire explicitly says it's a SetDXLInputNamed event:
<DX Msg> INTERRUPT : begin /SetDXLInputNamed:0
<DX Msg> INTERRUPT : end /SetDXLInputNamed:0
Another interesting note (possibly related): In a .net file, notice that
a DXLInputNamed module gets an explicit module definition:
//
// node DXLInputNamed[3]: x = 4299, y = 424, inputs = 2, label = \
DXLInputNamed
// input[1]: defaulting = 0, visible = 1, type = 32, value = \
"InteractorMode"
// input[2]: defaulting = 0, visible = 1, type = 29, value = 0
// page group: Main
//
main_DXLInputNamed_3_out_1 =
DXLInputNamed(
main_DXLInputNamed_3_in_1,
main_DXLInputNamed_3_in_2
) [instance: 3, cache: 1];
//
// node Receiver[277]: x = 392, y = 98, inputs = 1, label = \
PickIsActive
// page group: IRR_MB
//
whereas DXLInput does not. It only gets a script variable placeholder to
transfer to the output name of a 'virtual' module:
//
// node DXLInput[57]: x = 4301, y = 394, inputs = 1, label = \
InteractorMode
// input[1]: defaulting = 0, visible = 1, type = 29, value = 0
// page group: Main
//
main_DXLInput_57_out_1 = InteractorMode;
//
-------------------------------------------------------------------------------
"""
--
Randall Hopper (mailto:[EMAIL PROTECTED])
Lockheed Martin Operation Support
EPA Scientific Visualization Center
US EPA N127-01; RTP, NC 27711