1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12
13
14
15 #include <string.h>
16
17 #include "DXApplication.h"
18 #include "DrivenNode.h"
19 #include "Parameter.h"
20 #include "AttributeParameter.h"
21 #include "ErrorDialogManager.h"
22
23 // for java stuff
24 #include "Ark.h"
25 #include "ListIterator.h"
26
27 //
28 // Constructor
29 //
DrivenNode(NodeDefinition * nd,Network * net,int instance)30 DrivenNode::DrivenNode(NodeDefinition *nd,
31 Network *net, int instance) :
32 ModuleMessagingNode(nd, net, instance)
33 {
34 this->visualNotificationDeferrals = 0;
35 this->visualsNeedNotification = FALSE;
36 this->handlingLongMessage = FALSE;
37 }
38
39 //
40 // Update any inputs that are being updated by the server (i.e. the
41 // module that is doing the data-driven operations). These inputs
42 // are updated in a special way since we don't want to change the
43 // defaulting/set status of the parameter, we don't want it sent back
44 // to the server, and we don't want to mark it as dirty.
45 //
setInputAttributeFromServer(int index,const char * val,Type t)46 Type DrivenNode::setInputAttributeFromServer(int index,
47 const char *val, Type t)
48 {
49
50 Parameter *p = this->getInputParameter(index);
51 ASSERT(p->isA(ClassAttributeParameter));
52 boolean was_dirty = p->isDirty();
53 #if 11
54 boolean r = this->setInputAttributeParameter(index,val);
55 #else // We now do this to fix GRESH883, with the thinking being that when
56 // we get a value from the server, the real parameter (not just the
57 // attribute parameter) should be updated, regardless of whether or
58 // not it type matches with the attribute.
59 // Also, see AttributeParamter::setAttributeValue().
60 boolean r = this->setInputAttributeParameter(index,val, TRUE);
61 #endif
62 if (!was_dirty)
63 this->clearInputDirty(index);
64 ASSERT(r);
65 if (t == DXType::UndefinedType) {
66 AttributeParameter *ap = (AttributeParameter*)p;
67 t = ap->getAttributeValueType();
68 }
69 return t;
70 }
71
72 //
73 // Check all input parameters to see if any are connected.
74 // If connected, then we consider the ModuleMessagingNode to be data-driven
75 // (at this level of the the class hierarchy) and return TRUE,
76 // otherwise FALSE.
77 //
isDataDriven()78 boolean DrivenNode::isDataDriven()
79 {
80 int i, icnt = this->getInputCount();
81 boolean driven = FALSE;
82
83 for (i=1 ; !driven && i<=icnt ; i++) {
84 if (this->isInputViewable(i))
85 #if 0 // 8/9/93
86 driven = this->isInputConnected(i) || !this->isInputDefaulting(i);
87 #else
88 driven = !this->isInputDefaulting(i);
89 #endif
90 }
91
92 return driven;
93 }
94 //
95 // Notify anybody that needs to know that a parameter has changed.
96 // At the level we notify all instances that the label has changed.
97 //
ioParameterStatusChanged(boolean input,int index,NodeParameterStatusChange status)98 void DrivenNode::ioParameterStatusChanged(boolean input, int index,
99 NodeParameterStatusChange status)
100 {
101 if ((input) && (status & Node::ParameterArkChanged)) {
102 //
103 // If we become un data driven, then we must make sure the
104 // outputs get sent on the next execution.
105 //
106 boolean driven = this->isDataDriven();
107 if (driven) {
108 int i, ocnt = this->getOutputCount();
109 for (i=1 ; i<=ocnt ; i++)
110 this->setOutputDirty(i);
111 // Don't need to send them because the network will get marked
112 // dirty as a result of an arc change.
113 }
114 }
115
116 this->ModuleMessagingNode::ioParameterStatusChanged(input,index, status);
117
118 //
119 // Update the UI visuals for this node when ever any of our viewable
120 // input arcs or values change, which may lead to a sensitivity change
121 // on one of the UI visuals for this node.
122 //
123 if (input && ((status & Node::ParameterVisibilityChanged) == 0) &&
124 this->isInputViewable(index))
125 this->notifyVisualsOfStateChange();
126 }
127 //
128 // Set the message id parameter for a data-driven node.
129 // We assume that the id parameter is always parameter found in
130 // the parameter indexed by this->getMessageIdParamNumber().
131 // Returns TRUE/FALSE. If FALSE, an error message is given.
132 //
setMessageIdParameter(int id_index)133 boolean DrivenNode::setMessageIdParameter(int id_index)
134 {
135 const char *id = this->getModuleMessageIdString();
136
137 if (id_index == 0) {
138 id_index = this->getMessageIdParamNumber();
139 if (id_index == 0)
140 return TRUE;
141 }
142
143 if (this->setInputValue(id_index, id, DXType::StringType, FALSE) ==
144 DXType::UndefinedType) {
145 ErrorMessage(
146 "Error setting message id string for node %s, check ui.mdf\n",
147 this->getNameString());
148 return FALSE;
149 }
150 return TRUE;
151 }
152 #if 0
153 //
154 // Called at the end of a long message.
155 // This can be overridden by those derived classes that expect long messages.
156 // At this level, this method is a no-op.
157 //
158 void DrivenNode::completeLongMessage()
159 {
160 }
161 #endif
162 //
163 //
164 // Called when a message is received from the executive after
165 // this->ExecModuleMessageHandler() is registered in
166 // this->Node::netPrintNode() to receive messages for this node.
167 // We parse all the common information and then the class specific.
168 // If any relevant info was found then we call this->reflectStateChange().
169 //
execModuleMessageHandler(int id,const char * line)170 void DrivenNode::execModuleMessageHandler(int id, const char *line)
171 {
172 const char *p;
173 int values;
174 boolean do_notify;
175
176 #ifdef DEBUG
177 printf("%s: receiving message #%d...\n", this->getNameString(), id);
178 printf("%s\n",line);
179 #endif
180
181 this->deferVisualNotification();
182
183 //
184 // Parse the attributes specific to the derived class
185 //
186 p = strchr(line,':'); // Skip over '%d:'
187 ASSERT(p);
188 p = strchr(p+1,':'); // Skip over 'Node-name_%d:'
189 ASSERT(p);
190 if (!this->handlingLongMessage && EqualString(p,": begin")) {
191 //
192 // Begin handling a long message.
193 //
194 this->handlingLongMessage = TRUE;
195 //
196 // Don't notify visuals during a long message.
197 //
198 do_notify = FALSE;
199 } else if (EqualString(p,": end")) {
200 //
201 // End of long message encountered.
202 //
203 this->handlingLongMessage = FALSE;
204 //
205 // Always notify visuals after a long message.
206 //
207 do_notify = TRUE;
208 } else {
209 //
210 // Handle both long and short messages.
211 // Only do notification on short messages.
212 //
213 values = this->handleNodeMsgInfo(line);
214 do_notify = (!this->handlingLongMessage && values > 0);
215 }
216
217 //
218 // Notify the visuals if requested.
219 //
220 if (do_notify)
221 this->notifyVisualsOfStateChange();
222
223 this->undeferVisualNotification(TRUE);
224 }
225 //
226 // Return TRUE/FALSE, indicating whether or not we expect to receive
227 // a message from the UI when our module executes in the executive.
228 // By default, a module only executes in the executive for data-driven
229 // nodes and so we don't expect messages unless the node
230 // is data-driven.
231 //
expectingModuleMessage()232 boolean DrivenNode::expectingModuleMessage()
233 {
234 return this->isDataDriven();
235 }
236
237 //
238 // Notify all UI visuals that the attributes have changed.
239 // This calls this->reflectStateChange() if notification is not
240 // deferred.
241 //
notifyVisualsOfStateChange(boolean unmanage)242 void DrivenNode::notifyVisualsOfStateChange(boolean unmanage)
243 {
244 if (!this->isVisualNotificationDeferred()) {
245 this->visualsNeedNotification = FALSE;
246 this->reflectStateChange(unmanage);
247 } else {
248 this->visualsNeedNotification = TRUE;
249 }
250 }
251 //
252 // Determine if the give attribute/paramater is visually writeable (i.e.
253 // settable from something other than the CDB, like the SetAttrDialog).
254 //
isAttributeVisuallyWriteable(int input_index)255 boolean DrivenNode::isAttributeVisuallyWriteable(int input_index)
256 {
257 if (!this->isDataDriven())
258 return TRUE;
259
260 Parameter *p = this->getInputParameter(input_index);
261 ASSERT(p->isA(ClassAttributeParameter));
262 AttributeParameter *ap = (AttributeParameter*)p;
263 return ap->isAttributeVisuallyWriteable();
264 }
265 //
266 // Initialize the value of an attribute parameter.
267 //
initInputAttributeParameter(int index,const char * val)268 boolean DrivenNode::initInputAttributeParameter(int index, const char *val)
269 {
270 AttributeParameter *p = (AttributeParameter*)
271 this->getInputParameter(index);
272 return p->initAttributeValue(val);
273 }
274 //
275 // Set the value of an attribute parameter.
276 // If forceSync is TRUE (default = FALSE), then force the primary
277 // parameters of the AttributeParameter to be updated regardless of
278 // whether or not the types match.
279 //
setInputAttributeParameter(int index,const char * val,boolean forceSync)280 boolean DrivenNode::setInputAttributeParameter(int index,
281 const char *val, boolean forceSync)
282 {
283 AttributeParameter *p = (AttributeParameter*)
284 this->getInputParameter(index);
285 return p->setAttributeValue(val,forceSync);
286 }
287 //
288 // Get the value of an attribute parameter.
289 //
getInputAttributeParameterValue(int index)290 const char *DrivenNode::getInputAttributeParameterValue(int index)
291 {
292 AttributeParameter *p = (AttributeParameter*)
293 this->getInputParameter(index);
294 return p->getAttributeValueString();
295 }
296 //
297 // Determine if this node is of the given class.
298 //
isA(Symbol classname)299 boolean DrivenNode::isA(Symbol classname)
300 {
301 Symbol s = theSymbolManager->registerSymbol(ClassDrivenNode);
302 if (s == classname)
303 return TRUE;
304 else
305 return this->ModuleMessagingNode::isA(classname);
306 }
307 //
308 // Sync all the attribute values with the actual parameter values.
309 //
syncAttributeParameters()310 void DrivenNode::syncAttributeParameters()
311 {
312 int i, cnt = this->getInputCount();
313
314
315 for (i=1 ; i<=cnt ; i++) {
316 Parameter *p = this->getInputParameter(i);
317 ASSERT(p);
318 if (p->isA(ClassAttributeParameter)) {
319 AttributeParameter *ap = (AttributeParameter*)p;
320 ap->syncAttributeValue();
321 }
322 }
323 }
324
assignNewInstanceNumber()325 int DrivenNode::assignNewInstanceNumber()
326 {
327 int t = this->ModuleMessagingNode::assignNewInstanceNumber();
328 int index = this->getMessageIdParamNumber();
329 if (index > 0)
330 this->setMessageIdParameter(index);
331 return t;
332 }
333
334
335
336
337