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
16 #include <stdio.h>
17 #ifdef ABS_IN_MATH_H
18 # define abs __Dont_define_abs
19 #endif
20 #include <math.h>
21 #ifdef ABS_IN_MATH_H
22 # undef abs
23 #endif
24
25 #include "lex.h"
26 #include "ScalarNode.h"
27 #include "ScalarInstance.h"
28 #include "ErrorDialogManager.h"
29 #include "Parameter.h"
30 #include "AttributeParameter.h"
31 #include "Network.h"
32 #include "ListIterator.h"
33 #include "WarningDialogManager.h"
34
35
36 //
37 // The following define the mapping of parameter indices to parameter
38 // functionality in the module that is used to 'data-drive' the
39 // ScalarNode class and Nodes derived from it.
40 // These MUST match the entries in the ui.mdf file for the interactors
41 // that expect to be implemented by the ScalarInteractor class.
42 //
43 #define ID_PARAM_NUM 1 // Id used for UI messages
44 #define DATA_PARAM_NUM 2 // The input object
45 #define CVAL_PARAM_NUM 3 // Current Value
46 #define REFRESH_PARAM_NUM 4 // Does the module refresh
47 #define MIN_PARAM_NUM 5 // The current minimum
48 #define MAX_PARAM_NUM 6 // The current maximum
49 #define INCR_PARAM_NUM 7 // The current increment
50 #define INCRMETHOD_PARAM_NUM 8 // Method used to interpret incr.
51 #define DECIMALS_PARAM_NUM 9 // The number of decimals to display
52 #define DFLTVAL_PARAM_NUM 10 // The default output indicator
53 #define LABEL_PARAM_NUM 11 // The label
54
55 // The total number of inputs as defined in the mdf file.
56 #define EXPECTED_SCALAR_INPUTS LABEL_PARAM_NUM
57
58
59 #define DEFAULT_VALUE 0.0
60 #define DEFAULT_INCR 1.0
61 #define DEFAULT_MAX 1.0e6
62 #define DEFAULT_MIN -1.0e6
63 #define DEFAULT_SCALAR_DECIMALS 5
64
65 #define DEFAULT_VALUE_STR " 0 "
66 #define DEFAULT_INCR_STR " 1 "
67 #define DEFAULT_MAX_STR " 100000 "
68 #define DEFAULT_MIN_STR " -100000 "
69 #define DEFAULT_SCALAR_DECIMALS_STR " 5 "
70
71 //
72 // Create the component
73 //
ScalarNode(NodeDefinition * nd,Network * net,int instance,boolean isVector,int dimensions)74 ScalarNode::ScalarNode(NodeDefinition *nd,
75 Network *net, int instance,
76 boolean isVector,
77 int dimensions) :
78 InteractorNode(nd, net, instance)
79 {
80 ASSERT(dimensions > 0);
81 this->isContinuousUpdate = FALSE;
82 this->vectorType = isVector;
83 this->numComponents = dimensions;
84 this->rangeCheckDeferrals = 0;
85 this->needsRangeCheck = FALSE;
86
87 if (!this->verifyInputCount())
88 return;
89
90 //
91 // The attribute is an absolute increment and the parameter value
92 // is a relative increment (between 0..1). They have the same types
93 // so turn off value synchronization in the increment parameter (which
94 // is where the increment value is stored).
95 //
96 AttributeParameter *ap = (AttributeParameter*)
97 this->getInputParameter(INCR_PARAM_NUM);
98 ASSERT(ap);
99 ap->setSyncOnTypeMatch(FALSE);
100 }
101
hasDynamicDimensionality(boolean ignoreDataDriven)102 boolean ScalarNode::hasDynamicDimensionality(boolean ignoreDataDriven)
103 {
104 return this->isVectorType() &&
105 (ignoreDataDriven || !this->isDataDriven());
106 }
107 //
108 // Change the dimensionality of a Vector interactor.
109 //
doDimensionalityChange(int new_dim)110 boolean ScalarNode::doDimensionalityChange(int new_dim)
111 {
112 ScalarInstance *si;
113 int old_dim = this->getComponentCount();
114
115 ASSERT(this->isVectorType());
116
117 if (new_dim == old_dim)
118 return TRUE;
119
120 this->numComponents = new_dim;
121 //
122 // Delete the interactors, so that they don't get updated when setting
123 // the output value. If we don't do this, we can get references to
124 // non-existent vector components.
125 //
126 ListIterator iterator(this->instanceList);
127 while ( (si = (ScalarInstance*)iterator.getNext()) )
128 si->uncreateInteractor();
129
130
131 //
132 // Adjust the and output values first.
133 //
134 this->adjustOutputDimensions(old_dim, new_dim);
135
136 //
137 // Adjust all the attribute values.
138 //
139 this->adjustAttributeDimensions(old_dim,new_dim);
140
141 //
142 // Now have all the instances adjust themselves
143 //
144 iterator.setList(this->instanceList);
145 while ( (si = (ScalarInstance*)iterator.getNext()) ) {
146 if (!si->handleNewDimensionality())
147 return FALSE;
148 }
149 return TRUE;
150
151 }
adjustOutputDimensions(int old_dim,int new_dim)152 boolean ScalarNode::adjustOutputDimensions(int old_dim, int new_dim)
153 {
154 const char *oldval = this->getOutputValueString(1);
155 char *newval = DXValue::AdjustVectorDimensions(oldval,
156 new_dim, DEFAULT_VALUE, this->isIntegerTypeComponent());
157 if (!newval)
158 return FALSE;
159
160 this->setOutputValue(1,newval,DXType::VectorType,TRUE);
161 delete newval;
162 return TRUE;
163 }
164
adjustAttributeDimensions(int old_dim,int new_dim)165 boolean ScalarNode::adjustAttributeDimensions(int old_dim, int new_dim)
166 {
167
168 boolean is_int = this->isIntegerTypeComponent();
169 const char *v;
170 char *newval;
171
172 //
173 // Adjust the min attribute
174 //
175 v = this->getInputAttributeParameterValue(MIN_PARAM_NUM);
176 newval = DXValue::AdjustVectorDimensions(v, new_dim, DEFAULT_MIN,is_int);
177 this->setMinimumAttribute(newval);
178 delete newval;
179
180 //
181 // Adjust the max attribute
182 //
183 v = this->getInputAttributeParameterValue(MAX_PARAM_NUM);
184 newval = DXValue::AdjustVectorDimensions(v, new_dim, DEFAULT_MAX, is_int);
185 this->setMaximumAttribute(newval);
186 delete newval;
187
188 //
189 // Adjust the delta attribute
190 //
191 v = this->getInputAttributeParameterValue(INCR_PARAM_NUM);
192 newval = DXValue::AdjustVectorDimensions(v, new_dim, DEFAULT_INCR, is_int);
193 this->setDeltaAttribute(newval);
194 delete newval;
195
196 //
197 // Adjust the decimals attribute
198 //
199 double decimals;
200 if (is_int)
201 decimals = 0;
202 else
203 decimals = DEFAULT_SCALAR_DECIMALS;
204 v = this->getInputAttributeParameterValue(DECIMALS_PARAM_NUM);
205 newval = DXValue::AdjustVectorDimensions(v, new_dim, decimals, TRUE);
206 this->setDecimalsAttribute(newval);
207 delete newval;
208
209 return TRUE;
210 }
211 //
212 // Set the interactor's default attributes.
213 //
setDefaultAttributes()214 boolean ScalarNode::setDefaultAttributes()
215 {
216 const char *id;
217 const char *min=NULL, *max=NULL, *incr=NULL, *decimals=NULL;
218 boolean r;
219
220 // FIXME: these strings should be build from DEFAULT_*_STR
221 switch (this->numComponents) {
222 case 1:
223 if (this->isVectorType()) {
224 min = "[ -1000000 ]";
225 max = "[ 1000000 ]";
226 incr = "[ 1 ]";
227 decimals = (this->isIntegerTypeComponent() ? "[0]" : "[5]");
228 } else {
229 min = "-1000000";
230 max = "1000000";
231 incr = "1";
232 decimals = (this->isIntegerTypeComponent() ? "0" : "5");
233 }
234 break;
235 case 2:
236 min = "[-1000000 -1000000]";
237 max = "[ 1000000 1000000]";
238 incr = "[ 1 1]";
239 decimals= "[ 5 5]";
240 break;
241 case 3:
242 min = "[-1000000 -1000000 -1000000]";
243 max = "[ 1000000 1000000 1000000]";
244 incr = "[ 1 1 1]";
245 decimals= "[ 5 5 5]";
246 break;
247 default:
248 ASSERT(0);
249 }
250
251 id = this->getModuleMessageIdString();
252
253 if ((this->setInputValue(ID_PARAM_NUM,id, DXType::UndefinedType,FALSE)
254 == DXType::UndefinedType)
255 ||
256 !this->initMinimumAttribute(min)
257 ||
258 !this->initMaximumAttribute(max)
259 ||
260 !this->initDeltaAttribute(incr)
261 ||
262 !this->initDecimalsAttribute(decimals)
263 ) {
264 r = FALSE;
265 } else
266 r = TRUE;
267
268 return r;
269 }
270
271 //
272 // Make sure the number of inputs is the number expected.
273 //
verifyInputCount()274 boolean ScalarNode::verifyInputCount()
275 {
276 if (this->getInputCount() != EXPECTED_SCALAR_INPUTS) {
277 ErrorMessage(
278 "Expected %d inputs for %s interactor, please check the mdf file.\n",
279 EXPECTED_SCALAR_INPUTS,
280 this->getNameString());
281 return FALSE;
282 }
283 return TRUE;
284 }
285 //
286 // Called after allocation is complete.
287 // The work done here is to assigned default values to the InteractorNode inputs
288 // so that we can use them later when setting the attributes for the
289 // Interactor.
290 //
initialize()291 boolean ScalarNode::initialize()
292 {
293
294 if (!this->verifyInputCount())
295 return FALSE;
296
297 // FIXME: these strings should be build from DEFAULT_*_STR
298 const char *value;
299 switch (this->numComponents) {
300 case 1: if (this->isVectorType())
301 value = "[ 0 ]";
302 else
303 value = "0";
304 break;
305 case 2: value = "[ 0 0 ]"; break;
306 case 3: value = "[ 0 0 0 ]"; break;
307 default: return FALSE;
308 }
309
310 if (!this->setDefaultAttributes()
311 ||
312 (this->setOutputValue(1,value, DXType::UndefinedType,FALSE) ==
313 DXType::UndefinedType)
314 ){
315 ErrorMessage(
316 "Error setting default attributes for %s interactor, check ui.mdf\n",
317 this->getNameString());
318 return FALSE;
319 }
320 //
321 // Make the shadows defaulting (even though we have a current output)
322 // so that the executive module can tell when it is executing a just
323 // placed module and one that is read in from a .net or .cfg file.
324 // When read in, the output will be set again which should make the
325 // corresponding shadowing input be non-defaulting.
326 //
327 this->setShadowingInputsDefaulting();
328
329 return TRUE;
330 }
331
332
333 // The messages we parse can contain one or more of the following...
334 //
335 // 'min=%g' 'max=%g' 'delta=%g' 'value=%g' 'decimals=%d'
336 //
337 // or one or more of the following...
338 //
339 // 'min=[%g %g %g]' 'max=[%g %g %g]' 'delta=[%g %g %g]' 'value=[%g %g %g]'
340 // 'decimals=[%g %g %g]'
341 //
342 // If any input or output values are to be changed, don't send them
343 // because the module backing up the interactor will have just executed
344 // and if the UI is in 'execute on change' mode then there will be an
345 // extra execution.
346 //
347 // Returns the number of attributes parsed.
348 //
handleInteractorMsgInfo(const char * line)349 int ScalarNode::handleInteractorMsgInfo(const char *line)
350 {
351 int values;
352 if (this->isVectorType())
353 values = this->handleVectorMsgInfo(line);
354 else
355 values = this->handleScalarMsgInfo(line);
356
357 //
358 // Handle the 'method="%s"' part of the message.
359 // We only need to look for the message if we don't already have it.
360 //
361 if (this->isInputConnected(INCRMETHOD_PARAM_NUM)) {
362 char *p, buf[128];
363 if ((p = strstr((char*)line,"method=")) &&
364 FindDelimitedString(p,'"','"', buf)) {
365 values++;
366 this->setInputAttributeFromServer(INCRMETHOD_PARAM_NUM,buf,
367 DXType::StringType);
368 }
369 }
370
371
372 //
373 // Make sure that the min or max sent back from the executive is
374 // consistent. If the user has not connected the data tab and has
375 // only one of min and max set then it is possible that the value sent
376 // back by the module conflicts with the other value stored in the ui.
377 //
378 if (!this->isInputDefaulting(DATA_PARAM_NUM)) {
379 boolean min_dflting = this->isInputDefaulting(MIN_PARAM_NUM);
380 boolean max_dflting = this->isInputDefaulting(MAX_PARAM_NUM);
381 if ((min_dflting && !max_dflting) || (!min_dflting && max_dflting)) {
382 int i, comps = this->getComponentCount();
383 boolean issue_warning = FALSE;
384 for (i=1 ; i<=comps ; i++) {
385 double minval = this->getComponentMinimum(i);
386 double maxval = this->getComponentMaximum(i);
387 if (minval > maxval) {
388 issue_warning = TRUE;
389 if (min_dflting)
390 this->setComponentMinimum(i,maxval);
391 else
392 this->setComponentMaximum(i,minval);
393 }
394 }
395 if (issue_warning) {
396 char *setattr, *set;
397 if (min_dflting) {
398 set = "maximum";
399 setattr = "minimum";
400 } else {
401 set = "minimum";
402 setattr = "maximum";
403 }
404 WarningMessage("%s value provided to %s conflicts "
405 "with %s value set with 'Set Attributes' dialog"
406 "...adjusting %s.",
407 set, this->getNameString(),
408 setattr,setattr);
409 }
410 }
411 }
412
413
414 return values;
415
416 }
417 // The messages we parse can contain one or more of the following...
418 //
419 // 'min=%g' 'max=%g' 'delta=%g' 'value=%g' 'decimals=%d'
420 //
421 // If any input or output values are to be changed, don't send them
422 // because the module backing up the interactor will have just executed
423 // and if the UI is in 'execute on change' mode then there will be an
424 // extra execution.
425 //
426 // Returns the number of attributes parsed.
427 //
handleScalarMsgInfo(const char * line)428 int ScalarNode::handleScalarMsgInfo(const char *line)
429 {
430 int index, values = 0;
431 char *p, *buf = NULL;
432
433 //
434 // Handle the 'min=%g' part of the message.
435 //
436 if ( (p = strstr((char*)line,"min=")) ) {
437 values++;
438 while (*p != '=') p++;
439 p++;
440 buf = DuplicateString(p);
441 index = 0;
442 if (IsScalar(buf, index)) {
443 buf[index] = '\0';
444 this->setInputAttributeFromServer(MIN_PARAM_NUM,buf,
445 DXType::UndefinedType);
446 }
447 delete buf;
448 }
449 //
450 // Handle the 'max=%g' part of the message.
451 //
452 if ( (p = strstr((char*)line,"max=")) ) {
453 values++;
454 while (*p != '=') p++;
455 p++;
456 buf = DuplicateString(p);
457 index = 0;
458 if (IsScalar(buf, index)) {
459 buf[index] = '\0';
460 this->setInputAttributeFromServer(MAX_PARAM_NUM,buf,
461 DXType::UndefinedType);
462 }
463 delete buf;
464 }
465 //
466 // Handle the 'delta=%g' part of the message.
467 // Since the attribute and parameter value have the same type, but
468 // different meanings we only set the attribute value as received from
469 // the exec.
470 //
471 if ( (p = strstr((char*)line,"delta=")) ) {
472 values++;
473 while (*p != '=') p++;
474 p++;
475 buf = DuplicateString(p);
476 index = 0;
477 if (IsScalar(buf, index)) {
478 buf[index] = '\0';
479 this->setInputAttributeFromServer(INCR_PARAM_NUM,buf,
480 DXType::UndefinedType);
481 }
482 delete buf;
483 }
484 //
485 // Handle the 'decimals=%d' part of the message.
486 //
487 if ( (p = strstr((char*)line,"decimals=")) ) {
488 values++;
489 while (*p != '=') p++;
490 p++;
491 buf = DuplicateString(p);
492 index = 0;
493 if (IsScalar(buf, index)) {
494 buf[index] = '\0';
495 this->setInputAttributeFromServer(DECIMALS_PARAM_NUM,buf,
496 DXType::UndefinedType);
497 }
498 delete buf;
499 }
500 //
501 // Handle the 'value=%g' part of the message.
502 //
503 if ( (p = strstr((char*)line,"value=")) ) {
504 values++;
505 while (*p != '=') p++;
506 p++;
507 buf = DuplicateString(p);
508 index = 0;
509 if (IsScalar(buf, index)) {
510 buf[index] = '\0';
511 this->setShadowedOutputSentFromServer(1,buf,
512 DXType::UndefinedType);
513 }
514 delete buf;
515 }
516 return values;
517
518 }
519
520 //
521 // Called when a message is received from the executive to parse class
522 // specific message information.
523 //
524 // The messages we handle can contain one or more of the following...
525 //
526 // 'dim=%d'
527 // 'min=[%g %g %g]' 'max=[%g %g %g]' 'delta=[%g %g %g]' 'value=[%g %g %g]'
528 // 'decimals=[%g %g %g]'
529 //
530 // If any input or output values are to be changed, don't send them
531 // because the module backing up the interactor will have just executed
532 // and if the UI is in 'execute on change' mode then there will be an
533 // extra execution.
534 //
535 // Returns the number of attributes parsed.
536 //
handleVectorMsgInfo(const char * line)537 int ScalarNode::handleVectorMsgInfo(const char *line)
538 {
539 char *p;
540 int values = 0;
541 char buf[256];
542
543 //
544 // Handle the 'dim=%d' part of the message.
545 // This message must be handled first, because changing the dimensionality
546 // resets all the interactor values which can be reset by subsequent
547 // assignments in the current message.
548 // We don't need to do a 'values++' since the info is handled locally
549 // with this->changeDimensionality().
550 //
551 if ( (p = strstr((char*)line,"dim=")) ) {
552 while (*p != '=') p++;
553 p++;
554 int dim = atoi(p);
555 if (this->isVectorType() && (this->getComponentCount() != dim))
556 this->changeDimensionality(dim);
557 }
558 //
559 // Handle the 'min=[%g...]' part of the message.
560 //
561 if ( (p = strstr((char*)line,"min=")) ) {
562 values++;
563 while (*p != '=') p++;
564 p++;
565 if (FindDelimitedString(p,'[',']', buf)) {
566 this->setInputAttributeFromServer(MIN_PARAM_NUM,buf,
567 DXType::UndefinedType);
568 }
569
570 }
571 //
572 // Handle the 'max=[%g...]' part of the message.
573 //
574 if ( (p = strstr((char*)line,"max=")) ) {
575 values++;
576 while (*p != '=') p++;
577 p++;
578 if (FindDelimitedString(p,'[',']', buf)) {
579 this->setInputAttributeFromServer(MAX_PARAM_NUM,buf,
580 DXType::UndefinedType);
581 }
582 }
583 //
584 // Handle the 'delta=[%g...]' part of the message.
585 // Since the attribute and parameter value have the same type, but
586 // different meanings we only set the attribute value as received from
587 // the exec.
588 //
589 if ( (p = strstr((char*)line,"delta=")) ) {
590 values++;
591 while (*p != '=') p++;
592 p++;
593 if (FindDelimitedString(p,'[',']', buf)) {
594 this->setInputAttributeFromServer(INCR_PARAM_NUM,buf,
595 DXType::UndefinedType);
596 }
597 }
598 //
599 // Handle the 'decimals=[%g...]' part of the message.
600 //
601 if ( (p = strstr((char*)line,"decimals=")) ) {
602 values++;
603 while (*p != '=') p++;
604 p++;
605 if (FindDelimitedString(p,'[',']', buf)) {
606 this->setInputAttributeFromServer(DECIMALS_PARAM_NUM,buf,
607 DXType::UndefinedType);
608 }
609 }
610 //
611 // Handle the 'value=[%g...]' part of the message.
612 //
613 if ( (p = strstr((char*)line,"value=")) ) {
614 values++;
615 while (*p != '=') p++;
616 p++;
617 if (FindDelimitedString(p,'[',']', buf)) {
618 this->setShadowedOutputSentFromServer(1,buf,
619 DXType::UndefinedType);
620 }
621 }
622 return values;
623 }
624
cfgParseComment(const char * comment,const char * filename,int lineno)625 boolean ScalarNode::cfgParseComment(const char *comment,
626 const char *filename, int lineno)
627 {
628 //
629 // Don't do range checking until after the value AND the component's
630 // min/max have been set (see cfgParseComponentComment()).
631 //
632 if (strncmp(" interactor",comment,11))
633 this->deferRangeChecking();
634
635 return this->cfgParseComponentComment(comment, filename,lineno) ||
636 this->cfgParseInstanceComment(comment, filename, lineno) ||
637 this->cfgParseLocalIncrementComment(comment, filename, lineno) ||
638 this->cfgParseLocalContinuousComment(comment, filename, lineno) ||
639 this->InteractorNode::cfgParseComment(comment, filename, lineno);
640 }
641
642 //
643 // Print the '// interactor...' comment to the file.
644 // We override the parent's method so that we can print num_components
645 // correctly.
646 //
cfgPrintInteractorComment(FILE * f)647 boolean ScalarNode::cfgPrintInteractorComment(FILE *f)
648 {
649 return fprintf(f,
650 "// interactor %s[%d]: num_components = %d, value = %s\n",
651 this->getNameString(),
652 this->getInstanceNumber(),
653 this->getComponentCount(),
654 this->getOutputValueString(1)) >= 0;
655 }
656
657 //
658 // Print auxiliary info for this interactor, which includes all global
659 // information about each component.
660 //
cfgPrintInteractorAuxInfo(FILE * f)661 boolean ScalarNode::cfgPrintInteractorAuxInfo(FILE *f)
662 {
663 int i, ncomp = this->getComponentCount();
664
665 for (i=1 ; i<=ncomp ; i++ ) {
666 if (fprintf(f,
667 "// component[%d]: minimum = %g, maximum = %g, "
668 "global increment = %g, decimal = %d, global continuous = %d\n",
669 i-1, // File uses 0 based indexing
670 this->getComponentMinimum(i),
671 this->getComponentMaximum(i),
672 this->getComponentDelta(i),
673 this->getComponentDecimals(i),
674 this->isContinuous()) < 0)
675 return FALSE;
676 }
677 return TRUE;
678 }
679
680 //
681 // Print auxiliary info for the interactor instance, which include all local
682 // information about each component.
683 //
cfgPrintInstanceAuxInfo(FILE * f,InteractorInstance * ii)684 boolean ScalarNode::cfgPrintInstanceAuxInfo(FILE *f,
685 InteractorInstance *ii)
686 {
687 int i, ncomp = this->getComponentCount();
688 ScalarInstance *si = (ScalarInstance *)ii;
689
690 if (fprintf(f,
691 "// local continuous: value = %d, mode = %s\n",
692 (si->getLocalContinuous() ? 1 : 0),
693 (si->usingGlobalContinuous() ? "global" : "local") ) < 0)
694 return FALSE;
695
696 for (i=1 ; i<=ncomp ; i++ ) {
697 if (fprintf(f,
698 "// local increment[%d]: value = %g, mode = %s\n",
699 i-1, // File uses 0 based indexing
700 si->getLocalDelta(i),
701 (si->isLocalDelta(i) ? "local" : "global") ) < 0)
702 return FALSE;
703 }
704 return TRUE;
705
706 }
707 //
708 // This is the same as for the super class except that when we get a new
709 // instance we build the list of local attributes (one LocalAttributes
710 // for each component).
711 //
cfgParseInstanceComment(const char * comment,const char * filename,int lineno)712 boolean ScalarNode::cfgParseInstanceComment(const char *comment,
713 const char *filename, int lineno)
714 {
715 if (!this->InteractorNode::cfgParseInstanceComment(comment,filename,lineno))
716 return FALSE;
717
718 #if 0
719 int i, instance, components;
720 //
721 // Get the instance added above.
722 //
723 instance = this->getInstanceCount(); // The just added instance #
724 ScalarInstance *si = (ScalarInstance*)this->getInstance(instance);
725
726 //
727 // Copy the global attributes to the local.
728 //
729 for (i=1 ; i<=this->getComponentCount() ; i++) {
730 double dval;
731 int ival = this->getComponentDecimals(i);
732 dval = this->getComponentMinimum(i);
733 si->setLocalMinimum(i, dval);
734 dval = this->getComponentMaximum(i);
735 si->setLocalMaximum(i, dval);
736 dval = this->getComponentDelta(i);
737 si->setLocalDelta(i, dval);
738 ival = this->getComponentDecimals(i);
739 si->setLocalDecimals(i, ival);
740 }
741 #endif
742
743 return TRUE;
744
745 }
cfgParseComponentComment(const char * comment,const char * filename,int lineno)746 boolean ScalarNode::cfgParseComponentComment(const char *comment,
747 const char *filename, int lineno)
748 {
749 int items_parsed;
750 double minimum;
751 double maximum;
752 double delta;
753 int decimal;
754 int component_num;
755 int continuous;
756
757 if (strncmp(comment," component",10))
758 return FALSE;
759
760 items_parsed = sscanf
761 (comment,
762 " component[%d]: minimum = %lf, maximum = %lf, global increment = %lf, decimal = %d, global continuous = %d",
763 &component_num,
764 &minimum,
765 &maximum,
766 &delta,
767 &decimal,
768 &continuous);
769
770 if (items_parsed != 5 && items_parsed != 6)
771 {
772 ErrorMessage("Bad 'component' comment (file %s, line %d)",
773 filename,lineno);
774 return FALSE;
775 }
776
777 component_num++; // 1 based indexing.
778
779 #if 0
780 Parameter *p = this->getOutputParameter(1);
781 Type t = p->getValueType();
782
783 //
784 // The following is done most for lists, which when the list is empty
785 // have "NULL" value. In this case we want to set the type to the
786 // default type.
787 //
788 if ((t == DXType::ObjectType) || EqualString("NULL",p->getValueString())) {
789 t = p->getDefaultType();
790 this->clearOutputValue(1);
791 p->setValue(NULL,t);
792 }
793 #endif
794
795 this->setComponentMinimum(component_num,minimum);
796 this->setComponentMaximum(component_num,maximum);
797 this->setComponentDelta(component_num,delta);
798 this->setComponentDecimals(component_num,decimal);
799
800 if ((items_parsed == 6) && continuous)
801 this->setContinuous();
802 else
803 this->clrContinuous();
804
805 //
806 // Enable range checking of the output value after the last component
807 // min/max has been set (see cfgParseComments() for matching
808 // deferComponentCount()).
809 //
810 if (component_num == this->getComponentCount())
811 this->undeferRangeChecking();
812
813 return TRUE;
814 }
815
816 //
817 // Get a an ScalarInstance instead of an InteractorInstance.
818 //
newInteractorInstance()819 InteractorInstance *ScalarNode::newInteractorInstance()
820 {
821 ScalarInstance *si = new ScalarInstance(this);
822
823 return (InteractorInstance*)si;
824 }
825 //
826 // G/Set the 'minimum' attribute for the given component
827 //
setAllComponentRanges(double * min,double * max)828 boolean ScalarNode::setAllComponentRanges(double *min, double *max)
829 {
830 this->deferRangeChecking();
831
832 int i, ncomps = this->getComponentCount();
833 for (i=1 ; i<=ncomps ; i++) {
834 if (min)
835 this->setComponentMinimum(i,min[i-1]);
836 if (max)
837 this->setComponentMaximum(i,max[i-1]);
838 }
839
840 this->undeferRangeChecking();
841 return TRUE;
842 }
initMinimumAttribute(const char * val)843 boolean ScalarNode::initMinimumAttribute(const char *val)
844 {
845 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
846 MIN_PARAM_NUM);
847 return p->initAttributeValue(val);
848 }
setMinimumAttribute(const char * val)849 boolean ScalarNode::setMinimumAttribute(const char *val)
850 {
851 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
852 MIN_PARAM_NUM);
853 return p->setAttributeValue(val);
854 }
setComponentMinimum(int component,double min)855 boolean ScalarNode::setComponentMinimum(int component, double min)
856 {
857 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
858 MIN_PARAM_NUM);
859
860 double oldmin = p->getAttributeComponentValue(component);
861
862 if (!p->setAttributeComponentValue(component, min))
863 return FALSE;
864
865 if (min > oldmin)
866 this->rangeCheckComponentValue(component,
867 min, this->getComponentMaximum(component));
868 return TRUE;
869
870 }
getComponentMinimum(int component)871 double ScalarNode::getComponentMinimum(int component)
872 {
873 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
874 MIN_PARAM_NUM);
875
876 if (p->getAttributeComponentCount() < component)
877 return DEFAULT_MIN;
878 else
879 return p->getAttributeComponentValue(component);
880 }
881 //
882 // G/Set the 'maximum' attribute for the given component
883 //
initMaximumAttribute(const char * val)884 boolean ScalarNode::initMaximumAttribute(const char *val)
885 {
886 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
887 MAX_PARAM_NUM);
888 return p->initAttributeValue(val);
889 }
setMaximumAttribute(const char * val)890 boolean ScalarNode::setMaximumAttribute(const char *val)
891 {
892 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
893 MAX_PARAM_NUM);
894 return p->setAttributeValue(val);
895 }
setComponentMaximum(int component,double max)896 boolean ScalarNode::setComponentMaximum(int component, double max)
897 {
898 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
899 MAX_PARAM_NUM);
900
901 double oldmax = p->getAttributeComponentValue(component);
902
903 if (!p->setAttributeComponentValue(component, max))
904 return FALSE;
905
906 if (max < oldmax)
907 this->rangeCheckComponentValue(component,
908 this->getComponentMinimum(component), max);
909 return TRUE;
910 }
getComponentMaximum(int component)911 double ScalarNode::getComponentMaximum(int component)
912 {
913 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
914 MAX_PARAM_NUM);
915 if (p->getAttributeComponentCount() < component)
916 return DEFAULT_MAX;
917 else
918 return p->getAttributeComponentValue(component);
919 }
920
921 //
922 // G/Set the 'delta' attribute for the given component
923 //
initDeltaAttribute(const char * val)924 boolean ScalarNode::initDeltaAttribute(const char *val)
925 {
926 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
927 INCR_PARAM_NUM);
928 return p->initAttributeValue(val);
929 }
setDeltaAttribute(const char * val)930 boolean ScalarNode::setDeltaAttribute(const char *val)
931 {
932 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
933 INCR_PARAM_NUM);
934 return p->setAttributeValue(val);
935 }
setComponentDelta(int component,double delta)936 boolean ScalarNode::setComponentDelta(int component, double delta)
937 {
938 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
939 INCR_PARAM_NUM);
940 return p->setAttributeComponentValue(component, delta);
941 }
getComponentDelta(int component)942 double ScalarNode::getComponentDelta(int component)
943 {
944 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
945 INCR_PARAM_NUM);
946 if (p->getAttributeComponentCount() < component)
947 return DEFAULT_INCR;
948 else
949 return p->getAttributeComponentValue(component);
950 }
951 //
952 // G/Set the 'decimal places' attribute for the given component
953 //
initDecimalsAttribute(const char * val)954 boolean ScalarNode::initDecimalsAttribute(const char *val)
955 {
956 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
957 DECIMALS_PARAM_NUM);
958 return p->initAttributeValue(val);
959 }
setDecimalsAttribute(const char * val)960 boolean ScalarNode::setDecimalsAttribute(const char *val)
961 {
962 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
963 DECIMALS_PARAM_NUM);
964 return p->setAttributeValue(val);
965 }
setComponentDecimals(int component,int decimals)966 boolean ScalarNode::setComponentDecimals(int component, int decimals)
967 {
968 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
969 DECIMALS_PARAM_NUM);
970 return p->setAttributeComponentValue(component, decimals);
971 }
getComponentDecimals(int component)972 int ScalarNode::getComponentDecimals(int component)
973 {
974 AttributeParameter *p = (AttributeParameter*) this->getInputParameter(
975 DECIMALS_PARAM_NUM);
976 if (p->getAttributeComponentCount() < component) {
977 if (this->isIntegerTypeComponent())
978 return 0;
979 else
980 return DEFAULT_SCALAR_DECIMALS;
981 } else
982 return (int) p->getAttributeComponentValue(component);
983 }
setComponentValue(int component,double value)984 boolean ScalarNode::setComponentValue(int component, double value)
985 {
986 Parameter *out = this->getOutputParameter(1);
987 if (!out->setComponentValue(component, value))
988 return FALSE;
989 const char *v = this->getOutputValueString(1);
990 // This forces update of the shadowing input.
991 return this->setOutputValue(1,v,DXType::UndefinedType,FALSE);
992 }
getComponentValue(int component)993 double ScalarNode::getComponentValue(int component)
994 {
995 Parameter *p = this->getOutputParameter(1);
996 ASSERT(p->getComponentCount() >= component);
997 return p->getComponentValue(component);
998 }
999
1000 //
1001 // Call doRangeCheckComponentValue() if range checking is not
1002 // deferred.
1003 //
rangeCheckComponentValue(int component,double min,double max)1004 void ScalarNode::rangeCheckComponentValue(int component, double min, double max)
1005 {
1006 if (!this->isRangeCheckingDeferred()) {
1007 this->needsRangeCheck = FALSE;
1008 this->doRangeCheckComponentValue(component, min,max);
1009 } else {
1010 this->needsRangeCheck = TRUE;
1011 }
1012 }
1013
1014 //
1015 // Do what ever is necessary when the given component of the output
1016 // value is out of range as indicated by the limits. Typically, this just
1017 // means resetting the current output value that is associated with the
1018 // node. ScalarListNodes however, have the current (non-output) value
1019 // associated with the interactor instance. Therefore, ScalarListNodes,
1020 // re-implement this to reset the component values of all their instances.
1021 // If 'component' is less than 0, then min/max are ignored and all
1022 // components are checked with the current min/max values.
1023 //
doRangeCheckComponentValue(int component,double min,double max)1024 void ScalarNode::doRangeCheckComponentValue(int component,
1025 double min, double max)
1026 {
1027 double val;
1028
1029 if (component < 0) {
1030 //
1031 // Check all components of current output value against current
1032 // component min/max values (ignore input min/max).
1033 //
1034 int i, ncomp = this->getComponentCount();
1035 double *mins = new double[ncomp];
1036 double *maxs = new double[ncomp];
1037 Type output_type = this->getOutputSetValueType(1);
1038 char *newval;
1039
1040 for (i=1 ; i<=ncomp ; i++) {
1041 mins[i-1] = this->getComponentMinimum(i);
1042 maxs[i-1] = this->getComponentMaximum(i);
1043 }
1044 if (DXValue::ClampVSIValue(this->getOutputValueString(1),
1045 output_type,
1046 mins,maxs,&newval)) {
1047 ASSERT(newval);
1048 this->setOutputValue(1,newval,output_type,TRUE);
1049 delete newval;
1050 }
1051 delete[] mins;
1052 delete[] maxs;
1053 } else {
1054 //
1055 // Just do a single component.
1056 // Instead of doing this we could just always do the above, but
1057 // this is much faster.
1058 // Eventually, this causes a setOutputValue() just as above.
1059 //
1060 val = this->getComponentValue(component);
1061 if (val < min) {
1062 this->setComponentValue(component,min);
1063 } else if (val > max) {
1064 this->setComponentValue(component,max);
1065 }
1066 }
1067
1068 }
1069 //
1070 // Determine if the given component is an integer type.
1071 // We ignore component and assume all components have the same type.
1072 //
isIntegerTypeComponent()1073 boolean ScalarNode::isIntegerTypeComponent()
1074 {
1075 // FIXME: is there a better way to do this.
1076 if (!strncmp("Integer",this->getNameString(),7))
1077 return TRUE;
1078 else
1079 return FALSE;
1080 }
1081
cfgParseLocalIncrementComment(const char * comment,const char * filename,int lineno)1082 boolean ScalarNode::cfgParseLocalIncrementComment(
1083 const char *comment, const char *filename, int lineno)
1084
1085 {
1086 int items_parsed;
1087 int component_num;
1088 double double_step;
1089 char mode[32];
1090
1091 ASSERT(comment);
1092
1093 if (strncmp(comment," local increment",16))
1094 return FALSE;
1095
1096 #if 0
1097 is_int = uiuEqualString(_interactor_name, "Integer");
1098 #endif
1099
1100 items_parsed =
1101 sscanf(comment,
1102 " local increment[%d]: value = %lf, mode = %s",
1103 &component_num, // Ignoring component number (always 0?)
1104 &double_step,
1105 mode);
1106
1107 component_num++; // 1 based indexing
1108 if (component_num < 1 || component_num > this->getComponentCount()) {
1109 ErrorMessage(
1110 "'local increment' comment references undefined component (file %s, line %d)",
1111 filename, lineno);
1112 return FALSE;
1113 }
1114
1115
1116 if (items_parsed != 3)
1117 {
1118 #if 1
1119 ErrorMessage("Bad 'local increment' comment (file %s, line %d)",
1120 filename, lineno);
1121 return FALSE;
1122 }
1123 #else
1124 uiuModelessErrorMessageDialog
1125 (_parse_widget,
1126 "#10001",
1127 "local increment",
1128 _parse_file,
1129 yylineno);
1130 _error_occurred = TRUE;
1131 return;
1132 }
1133
1134 if (_interactor_index < 0)
1135 {
1136 uiuModelessErrorMessageDialog
1137 (_parse_widget,
1138 "#10011", "local increment", "interactor", _parse_file, yylineno);
1139 _error_occurred = TRUE;
1140 return;
1141 }
1142
1143 interactor = _network->interactor + _interactor_index;
1144
1145 if (NOT interactor->in_use)
1146 {
1147 uiuModelessErrorMessageDialog
1148 (_parse_widget,
1149 "#10011",
1150 "local increment",
1151 "interactor",
1152 _parse_file,
1153 yylineno);
1154 _error_occurred = TRUE;
1155 return;
1156 }
1157 #endif
1158
1159 #if 1
1160 int instance = this->getInstanceCount();
1161 ScalarInstance *si = (ScalarInstance*)this->getInstance(instance);
1162 if (!si) {
1163 ErrorMessage("'local increment' comment out of order (file %s, line%d)",
1164 filename, lineno);
1165 return FALSE;
1166 }
1167 si->useLocalDelta(component_num, double_step);
1168 if (!EqualString(mode,"local"))
1169 si->clrLocalDelta(component_num);
1170
1171 #else
1172 if (is_int)
1173 {
1174 interactor->increment[component_num].integer =
1175 interactor->restore_increment[component_num].integer =
1176 int_step;
1177 }
1178 else
1179 {
1180 interactor->increment[component_num].real =
1181 interactor->restore_increment[component_num].real =
1182 double_step;
1183 }
1184
1185 interactor->local_increment[component_num] =
1186 interactor->restore_local_increment[component_num] =
1187 uiuEqualString(mode, "local");
1188 #endif
1189 return TRUE;
1190
1191 }
1192
cfgParseLocalContinuousComment(const char * comment,const char * filename,int lineno)1193 boolean ScalarNode::cfgParseLocalContinuousComment(
1194 const char *comment, const char *filename, int lineno)
1195 {
1196 int items_parsed;
1197 int continuous;
1198 char mode[32];
1199
1200 ASSERT(comment);
1201
1202 if (strncmp(comment," local continuous",17))
1203 return FALSE;
1204
1205 items_parsed =
1206 sscanf(comment,
1207 " local continuous: value = %d, mode = %s",
1208 &continuous,
1209 mode);
1210
1211 /*
1212 * Backwards compatibility...
1213 */
1214 if (items_parsed != 2)
1215 {
1216 items_parsed =
1217 sscanf(comment,
1218 " local continuous[0]: value = %d, mode = %s",
1219 &continuous,
1220 mode);
1221 }
1222
1223 if (items_parsed != 2)
1224 {
1225 #if 1
1226 ErrorMessage("Bad 'local continuous' comment (file %s, line %d)",
1227 filename, lineno);
1228 return FALSE;
1229 #else
1230 uiuModelessErrorMessageDialog
1231 (_parse_widget,
1232 "#10001",
1233 "local continuous",
1234 _parse_file,
1235 yylineno);
1236 _error_occurred = TRUE;
1237 return;
1238 #endif
1239 }
1240
1241 #if 0
1242 if (_interactor_index < 0)
1243 {
1244 uiuModelessErrorMessageDialog
1245 (_parse_widget,
1246 "#10011",
1247 "local continuous",
1248 "interactor",
1249 _parse_file,
1250 yylineno);
1251 _error_occurred = TRUE;
1252 return;
1253 }
1254
1255 interactor = _network->interactor + _interactor_index;
1256
1257 if (NOT interactor->in_use)
1258 {
1259 uiuModelessErrorMessageDialog
1260 (_parse_widget,
1261 "#10011",
1262 "local continuous",
1263 "interactor",
1264 _parse_file,
1265 yylineno);
1266 _error_occurred = TRUE;
1267 return;
1268 }
1269 #endif
1270
1271 #if 1
1272 int instance = this->getInstanceCount();
1273 ScalarInstance *si = (ScalarInstance*)this->getInstance(instance);
1274 if (!si) {
1275 ErrorMessage("'local continuous' comment out of order (file %s, line%d)",
1276 filename, lineno);
1277 return FALSE;
1278 }
1279 si->useLocalContinuous((continuous == 0 ? FALSE : TRUE));
1280 if (!EqualString(mode,"local"))
1281 si->useGlobalContinuous();
1282
1283 #else
1284 interactor->continuous =
1285 interactor->restore_continuous =
1286 continuous;
1287
1288 interactor->restore_local_continuous =
1289 interactor->local_continuous =
1290 uiuEqualString(mode, "local");
1291 #endif
1292
1293 return TRUE;
1294
1295 }
1296
1297 //
1298 // Determine if this node is of the given class.
1299 //
isA(Symbol classname)1300 boolean ScalarNode::isA(Symbol classname)
1301 {
1302 Symbol s = theSymbolManager->registerSymbol(ClassScalarNode);
1303 if (s == classname)
1304 return TRUE;
1305 else
1306 return this->InteractorNode::isA(classname);
1307 }
1308
isMinimumVisuallyWriteable()1309 boolean ScalarNode::isMinimumVisuallyWriteable()
1310 {
1311 return
1312 this->isInputDefaulting(DATA_PARAM_NUM) &&
1313 this->isAttributeVisuallyWriteable(MIN_PARAM_NUM);
1314 }
isMaximumVisuallyWriteable()1315 boolean ScalarNode::isMaximumVisuallyWriteable()
1316 {
1317 return
1318 this->isInputDefaulting(DATA_PARAM_NUM) &&
1319 this->isAttributeVisuallyWriteable(MAX_PARAM_NUM);
1320 }
isDecimalsVisuallyWriteable()1321 boolean ScalarNode::isDecimalsVisuallyWriteable()
1322 {
1323 return
1324 this->isInputDefaulting(DATA_PARAM_NUM) &&
1325 (this->isInputDefaulting(MIN_PARAM_NUM) ||
1326 this->isInputDefaulting(MAX_PARAM_NUM)) &&
1327 this->isAttributeVisuallyWriteable(DECIMALS_PARAM_NUM);
1328 }
isDeltaVisuallyWriteable()1329 boolean ScalarNode::isDeltaVisuallyWriteable()
1330 {
1331 const char *delta_method = this->getInputValueString(INCRMETHOD_PARAM_NUM);
1332
1333 //
1334 // Check to see of the tab-down value of the method input is set to
1335 // 'absolute'. We can only write this value when using absolute
1336 // increments. Actually, this test should be moved to the set attributes
1337 // code since it is the one that decides what kind of increments it
1338 // can support.
1339 //
1340 if (!this->isInputDefaulting(INCRMETHOD_PARAM_NUM) &&
1341 !this->isInputConnected(INCRMETHOD_PARAM_NUM) &&
1342 !EqualString(delta_method,"absolute"))
1343 return FALSE;
1344
1345 return
1346 this->isInputDefaulting(DATA_PARAM_NUM) &&
1347 (this->isInputDefaulting(MIN_PARAM_NUM) ||
1348 this->isInputDefaulting(MAX_PARAM_NUM)) &&
1349 this->isAttributeVisuallyWriteable(INCR_PARAM_NUM);
1350 }
1351 //
1352 // Catch the output comment to determine the number of components.
1353 // We need to do this when we have a 2d vector and no .cfg file to
1354 // tell us so. We then get numComponent==3, but all the parameter
1355 // values are 2d, which results in an ASSERTion failure.
1356 //
netParseComment(const char * comment,const char * file,int lineno)1357 boolean ScalarNode::netParseComment(const char* comment,
1358 const char *file, int lineno)
1359 {
1360 boolean r = this->InteractorNode::netParseComment(comment,file,lineno);
1361 if (r && EqualSubstring(comment," output[",8)) {
1362 Parameter *p = this->getOutputParameter(1);
1363 this->numComponents = p->getComponentCount();
1364 }
1365 return r;
1366 }
1367
1368
1369
1370 //
1371 // If we're parsing input #4 (which is now REFRESH and was at one point REMAP)
1372 // and the net version is older than 3.1.0 (which is compiled in by DXVersion.h),
1373 // then set the defaulting status = TRUE. Reason: the older ui was setting
1374 // the defaulting status of this unused param to FALSE. Now that we want to use
1375 // the param again, old nets believe the param is set.
1376 //
1377 // So, this chunk of code should go away if REFRESH goes away. It should also
1378 // go away sometime in the future (after no more old nets exist).
1379 //
1380 // In case it's not obvious, I'll tell you: this code was copy/pasted from
1381 // Node.C. Maybe it should be kept up to date with Node.C, but really its only
1382 // purpose is to deal with old nets, so if comments change this code won't really
1383 // affected.
1384 //
parseIOComment(boolean input,const char * comment,const char * filename,int lineno,boolean valueOnly)1385 boolean ScalarNode::parseIOComment(boolean input, const char* comment,
1386 const char* filename, int lineno, boolean valueOnly)
1387 {
1388 int defaulting = 0, items_parsed, ionum, tmp_type;
1389 int visible = TRUE;
1390 boolean parse_error = FALSE;
1391
1392 if(this->Node::parseIOComment(input, comment, filename, lineno, valueOnly) == FALSE)
1393 return FALSE;
1394
1395 //
1396 //
1397 // If the net version is less than 3.1.0 then set param 4 defaulting status
1398 // to true. The ui had mistakenly been setting it to false although the param
1399 // was not in use by the module. Now we want to use that param but existing
1400 // nets don't work unless param 4 (REFRESH) starts out defaulting.
1401 //
1402 // This code turns into NoOp starting with net version == 3.1.0
1403 //
1404 Network *net = this->getNetwork();
1405 if (net->getNetMajorVersion() > 3) return TRUE;
1406 if (net->getNetMinorVersion() >= 1) return TRUE;
1407
1408 ASSERT(comment);
1409
1410 if ((input) && (!parse_error)) {
1411
1412 if (valueOnly) {
1413 if (sscanf(comment, " input[%d]: defaulting = %d",
1414 &ionum, &defaulting) != 2)
1415 parse_error = TRUE;
1416 /*type = DXType::UndefinedType;*/
1417 } else {
1418 items_parsed = sscanf(comment,
1419 " input[%d]: defaulting = %d, visible = %d, type = %d",
1420 &ionum, &defaulting, &visible, &tmp_type);
1421 /*type = (Type) tmp_type;*/
1422 if (items_parsed != 4) {
1423 // Invisibility added 3/30/93
1424 items_parsed = sscanf(comment, " input[%d]: visible = %d",
1425 &ionum, &visible);
1426 if (items_parsed != 2) {
1427 // Backwards compatibility added 3/25/93
1428 items_parsed = sscanf(comment, " input[%d]: type = %d",
1429 &ionum, &tmp_type);
1430 /*type = (Type) tmp_type;*/
1431 if (items_parsed != 2) {
1432 items_parsed = sscanf(comment,
1433 " input[%d]: defaulting = %d, type = %d",
1434 &ionum, &defaulting, &tmp_type);
1435 /*type = (Type) tmp_type;*/
1436 if (items_parsed != 3)
1437 parse_error = TRUE;
1438 }
1439 }
1440 else
1441 {
1442 defaulting = 1;
1443 }
1444 }
1445 }
1446 }
1447
1448 if ((!parse_error) && (input) &&
1449 (ionum == REFRESH_PARAM_NUM) && (defaulting == FALSE)) {
1450 Parameter *par = this->getInputParameter(REFRESH_PARAM_NUM);
1451 par->setUnconnectedDefaultingStatus(TRUE);
1452 }
1453
1454
1455 return TRUE;
1456 }
1457
1458
printJavaValue(FILE * jf)1459 boolean ScalarNode::printJavaValue (FILE* jf)
1460 {
1461 const char* indent = " ";
1462 int comp_count = this->getComponentCount();
1463 const char* var_name = this->getJavaVariable();
1464 int i;
1465 for (i=1; i<=comp_count; i++) {
1466 if (this->isIntegerTypeComponent()) {
1467 int min = (int)this->getComponentMinimum(i);
1468 int max = (int)this->getComponentMaximum(i);
1469 int step = (int)this->getComponentDelta(i);
1470 int value = (int)this->getComponentValue(i);
1471 fprintf (jf, "%s%s.setValues(%d,%d,%d,%d,%d);\n",
1472 indent, var_name, i,min,max,step,value);
1473 } else {
1474 double min = this->getComponentMinimum(i);
1475 double max = this->getComponentMaximum(i);
1476 double step = this->getComponentDelta(i);
1477 double value = this->getComponentValue(i);
1478 int decimals = this->getComponentDecimals(i);
1479 fprintf (jf, "%s%s.setValues(%d,%g,%g,%g,%d,%g);\n",
1480 indent, var_name, i,min,max,step,decimals,value);
1481 }
1482 }
1483 return TRUE;
1484 }
1485
1486
1487