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 // DrivenNode.h -
15 //
16 // Definition for the DrivenNode class.
17 //
18 // There general support for data-driven nodes.  These
19 // are nodes that have inputs and make an executive module call and
20 // then expect a UImessage from that module concerning the state of the
21 // UI visuals for the Node (i.e. mininum, maximum, increment, label...).
22 // this->Node::netPrintNode() determines if the ModuleMessagingNode is
23 // data-driven with this->expectingModuleMessage() via this->isDataDriven()
24 // and arranges for this->execModuleMessageHandler() to be called when a
25 // message for this ModuleMessagingNode is found.
26 //
27 // All DrivenNodes (if they have NodeDefinitions that derived from
28 // DrivenDefinition) have AttributeParameters instead of Parameters for
29 // the inputs.  When arcs are changed or a message
30 // from the executive is received, the UI Visual is asked to updates its
31 // state through this->reflectStateChange() which is called by
32 // this->notifyVisualsOfStateChange() .  Calls to reflectStateChange()
33 // can be deferred through the use of [un]deferVisualNotification().  This
34 // can be useful during message reception.
35 //
36 // At this level isDataDriven() indicates that the node is data-driven if
37 // any non-private inputs are connected.
38 //
39 
40 
41 #ifndef _DrivenNode_h
42 #define _DrivenNode_h
43 
44 
45 #include "ModuleMessagingNode.h"
46 
47 
48 //
49 // Class name definition:
50 //
51 #define ClassDrivenNode	"DrivenNode"
52 
53 
54 //
55 // DrivenNode class definition:
56 //
57 class DrivenNode : public ModuleMessagingNode
58 {
59   private:
60     //
61     // Private member data:
62     //
63     int 	visualNotificationDeferrals;
64     boolean 	visualsNeedNotification;
65 
66     //
67     // Set the label used for the data driven node.  Generally
68     // only called by the message handler.
69     //
70     void setInteractorLabel(const char *label);
71 
72   protected:
73     //
74     // Protected member data:
75     //
76 
77     //
78     // This is set when the execModuleMessageHandler() starts accepting
79     // a long message.
80     //
81     boolean handlingLongMessage;
82 
83     //
84     // Called when a message is received from the executive after
85     // this->ExecModuleMessageHandler() is registered in
86     // this->Node::netPrintNode() to receive messages for this node.
87     // We parse all the common information and then the class specific.
88     // If any relevant info was found then we call this->reflectStateChange().
89     //
90     // If any input or output values are to be changed, don't send them
91     // because the module backing up the node will have just executed
92     // and if the UI is in 'execute on change' mode then there will be an
93     // extra execution.
94     //
95     virtual void execModuleMessageHandler(int id, const char *line);
96 
97     //
98     // Parse the node specific info from an executive message.
99     // Returns the number of attributes parsed.
100     //
101     virtual int  handleNodeMsgInfo(const char *line) = 0;
102 
103     //
104     // Update any UI visuals that may be based on the state of this
105     // node.   Among other times, this is called after receiving a message
106     // from the executive.
107     //
108     virtual void reflectStateChange(boolean unmanage) = 0;
109 
110     //
111     // Return TRUE/FALSE, indicating whether or not we expect to receive
112     // a message from the UI when our module executes in the executive.
113     // By default, a module only executes in the executive for data-driven
114     // nodes and so we don't expect messages unless the node
115     // is data-driven.
116     //
117     virtual boolean expectingModuleMessage();
118 
119     //
120     // Set the message id parameter for a data-driven node.
121     // We assume that the id parameter is always parameter the value
122     // returned by getMessageIdParamNumber().
123     // Returns TRUE/FALSE.  If FALSE, an error message is given.
124     //
125     boolean setMessageIdParameter(int id_index = 0);
126 
127     //
128     // Get the index of the parameter that has a message id token.
129     // Returns 0, if there is not message id parameter for the node.
130     //
getMessageIdParamNumber()131     virtual int getMessageIdParamNumber() { return 1; }
132 
133     //
134     // Notify anybody that needs to know that a parameter has changed its
135     // arcs or values.
136     //
137     virtual void ioParameterStatusChanged(boolean input, int index,
138 			NodeParameterStatusChange status);
139 
140     //
141     // Update any inputs that are being updated by the server (i.e. the
142     // module that is doing the data-driven operations).  These inputs
143     // are updated in a special way since we don't want to change the
144     // defaulting/set status of the parameter, we don't want it sent back
145     // to the server, and we don't want to mark it as dirty.
146     //
147     Type setInputAttributeFromServer(int index, const char *val,
148                                         Type t = DXType::UndefinedType);
149 
150     //
151     // Initialize/set the value of an attribute parameter.
152     // If forceSync is TRUE (default = FALSE), then force the primary
153     // parameters of the AttributeParameter to be updated regardless of
154     // whether or not the types match.
155     boolean setInputAttributeParameter(int index, const char *val,
156 						boolean forceSync = FALSE);
157     boolean initInputAttributeParameter(int index, const char *val);
158     const char *getInputAttributeParameterValue(int index);
159     //
160     // Determine if the give attribute/paramater is visually writeable (i.e.
161     // settable from something other than the CDB, like the SetAttrDialog).
162     // It may be ok to make this public, but erring on the side of caution
163     // for now.
164     //
165     virtual boolean isAttributeVisuallyWriteable(int input_index);
166 
167     //
168     //  Sync all the attribute values with the actual parameter values.
169     //
170     void syncAttributeParameters();
171 
172 
173   public:
174     //
175     // Constructor:
176     //
177     DrivenNode(NodeDefinition *nd, Network *net, int instnc);
178 
179     //
180     // Destructor:
181     //
~DrivenNode()182     ~DrivenNode(){}
183 
184     //
185     // Check all input parameters to see if any are connected.
186     // If connected, then we consider the ModuleMessagingNode to be data-driven
187     // (at this level of the the class hierarchy) and return TRUE,
188     // otherwise FALSE.
189     //
190     virtual boolean isDataDriven();
191 
192     //
193     // Notify all UI visuals that the attributes have changed.
194     // If 'unmanage' is TRUE, then it is recommended that the visual
195     // be unmanage making the changes.  This calls this->reflectStateChange()
196     // when undefered.
197     //
198     void notifyVisualsOfStateChange(boolean unmanage = FALSE);
199 
200     //
201     // in addition to superclass' work, change the node name parameter.
202     //
203     virtual int assignNewInstanceNumber();
204 
205     //
206     // Provide methods to delay notifyVisualsOfStateChange().
207     //
isVisualNotificationDeferred()208     boolean isVisualNotificationDeferred()
209 			{ return this->visualNotificationDeferrals != 0;}
deferVisualNotification()210     void deferVisualNotification()   {this->visualNotificationDeferrals++;}
211     void undeferVisualNotification(boolean unmanage = FALSE)
212                         {  ASSERT(this->visualNotificationDeferrals > 0);
213                            if ((--this->visualNotificationDeferrals == 0) &&
214                                this->visualsNeedNotification)
215                                 this->notifyVisualsOfStateChange(unmanage);
216 			}
217 
218     //
219     // Determine if this node is a node of the given class
220     //
221     virtual boolean isA(Symbol classname);
222 
hasJavaRepresentation()223     virtual boolean hasJavaRepresentation() { return TRUE; }
getJavaNodeName()224     virtual const char* getJavaNodeName() { return "DrivenNode"; }
225 
226     //
227     // Returns a pointer to the class name.
228     //
getClassName()229     const char* getClassName()
230     {
231 	return ClassDrivenNode;
232     }
233 };
234 
235 
236 #endif // _DrivenNode_h
237