Panda3D
|
00001 // Filename: dataNode.cxx 00002 // Created by: drose (11Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "dataNode.h" 00016 #include "dataNodeTransmit.h" 00017 #include "config_dgraph.h" 00018 #include "dcast.h" 00019 00020 TypeHandle DataNode::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: DataNode::make_copy 00024 // Access: Public, Virtual 00025 // Description: Returns a newly-allocated Node that is a shallow copy 00026 // of this one. It will be a different Node pointer, 00027 // but its internal data may or may not be shared with 00028 // that of the original Node. 00029 //////////////////////////////////////////////////////////////////// 00030 PandaNode *DataNode:: 00031 make_copy() const { 00032 return new DataNode(*this); 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: DataNode::transmit_data 00037 // Access: Public 00038 // Description: Collects the data from all of the parent nodes and 00039 // puts it into one DataNodeTransmit object, for 00040 // processing; calls do_transmit_data() to read all the 00041 // inputs and put the result into the indicated output. 00042 //////////////////////////////////////////////////////////////////// 00043 void DataNode:: 00044 transmit_data(DataGraphTraverser *trav, 00045 const DataNodeTransmit inputs[], 00046 DataNodeTransmit &output) { 00047 DataNodeTransmit new_input; 00048 new_input.reserve(get_num_inputs()); 00049 00050 DataConnections::const_iterator ci; 00051 for (ci = _data_connections.begin(); ci != _data_connections.end(); ++ci) { 00052 const DataConnection &connect = (*ci); 00053 const EventParameter &data = 00054 inputs[connect._parent_index].get_data(connect._output_index); 00055 new_input.set_data(connect._input_index, data); 00056 } 00057 00058 #ifndef NDEBUG 00059 if (dgraph_cat.is_spam()) { 00060 bool any_data = false; 00061 Wires::const_iterator wi; 00062 for (wi = _input_wires.begin(); wi != _input_wires.end(); ++wi) { 00063 const string &name = (*wi).first; 00064 const WireDef &def = (*wi).second; 00065 if (new_input.has_data(def._index)) { 00066 if (!any_data) { 00067 dgraph_cat.spam() 00068 << *this << " receives:\n"; 00069 any_data = true; 00070 } 00071 dgraph_cat.spam(false) 00072 << " " << name << " = " << new_input.get_data(def._index) 00073 << "\n"; 00074 } 00075 } 00076 } 00077 #endif // NDEBUG 00078 00079 do_transmit_data(trav, new_input, output); 00080 00081 #ifndef NDEBUG 00082 if (dgraph_cat.is_spam()) { 00083 bool any_data = false; 00084 Wires::const_iterator wi; 00085 for (wi = _output_wires.begin(); wi != _output_wires.end(); ++wi) { 00086 const string &name = (*wi).first; 00087 const WireDef &def = (*wi).second; 00088 if (output.has_data(def._index)) { 00089 if (!any_data) { 00090 dgraph_cat.spam() 00091 << *this << " transmits:\n"; 00092 any_data = true; 00093 } 00094 dgraph_cat.spam(false) 00095 << " " << name << " = " << output.get_data(def._index) 00096 << "\n"; 00097 } 00098 } 00099 } 00100 #endif // NDEBUG 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: DataNode::write_inputs 00105 // Access: Published 00106 // Description: Writes to the indicated ostream a list of all the 00107 // inputs this DataNode might expect to receive. 00108 //////////////////////////////////////////////////////////////////// 00109 void DataNode:: 00110 write_inputs(ostream &out) const { 00111 Wires::const_iterator wi; 00112 for (wi = _input_wires.begin(); wi != _input_wires.end(); ++wi) { 00113 const string &name = (*wi).first; 00114 const WireDef &def = (*wi).second; 00115 out << name << " " << def._data_type << "\n"; 00116 } 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: DataNode::write_outputs 00121 // Access: Published 00122 // Description: Writes to the indicated ostream a list of all the 00123 // outputs this DataNode might generate. 00124 //////////////////////////////////////////////////////////////////// 00125 void DataNode:: 00126 write_outputs(ostream &out) const { 00127 Wires::const_iterator wi; 00128 for (wi = _output_wires.begin(); wi != _output_wires.end(); ++wi) { 00129 const string &name = (*wi).first; 00130 const WireDef &def = (*wi).second; 00131 out << name << " " << def._data_type << "\n"; 00132 } 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: DataNode::write_connections 00137 // Access: Published 00138 // Description: Writes to the indicated ostream a list of all the 00139 // connections currently showing between this DataNode 00140 // and its parent(s). 00141 //////////////////////////////////////////////////////////////////// 00142 void DataNode:: 00143 write_connections(ostream &out) const { 00144 DataConnections::const_iterator ci; 00145 for (ci = _data_connections.begin(); ci != _data_connections.end(); ++ci) { 00146 const DataConnection &connect = (*ci); 00147 nassertv(connect._parent_index >= 0 && connect._parent_index < get_num_parents()); 00148 00149 // Now we have to search exhaustively for the input with the 00150 // matching index number. 00151 Wires::const_iterator wi; 00152 bool found = false; 00153 for (wi = _input_wires.begin(); wi != _input_wires.end() && !found; ++wi) { 00154 const string &name = (*wi).first; 00155 const WireDef &def = (*wi).second; 00156 if (def._index == connect._input_index) { 00157 out << name << " " << def._data_type << " from " 00158 << *get_parent(connect._parent_index) << "\n"; 00159 found = true; 00160 } 00161 } 00162 nassertv(found); 00163 } 00164 } 00165 00166 //////////////////////////////////////////////////////////////////// 00167 // Function: DataNode::define_input 00168 // Access: Protected 00169 // Description: Adds a new input wire with the given name and the 00170 // indicated data type. The data type should be the 00171 // TypeHandle for some type that derives from 00172 // TypedReferenceCount, e.g. EventStoreInt, 00173 // EventStoreDouble, or some fancier data type like 00174 // Texture. 00175 // 00176 // If there is already an input wire defined with the 00177 // indicated name, its type is changed. 00178 // 00179 // The return value is the index into the "input" 00180 // parameter to do_transmit_data() that can be used to 00181 // access the input data. 00182 //////////////////////////////////////////////////////////////////// 00183 int DataNode:: 00184 define_input(const string &name, TypeHandle data_type) { 00185 // We shouldn't already be connected. 00186 nassertr(_data_connections.empty(), 0); 00187 00188 Wires::iterator wi; 00189 wi = _input_wires.find(name); 00190 if (wi != _input_wires.end()) { 00191 // This wire already existed; modify it and return the original 00192 // index. 00193 WireDef &def = (*wi).second; 00194 def._data_type = data_type; 00195 return def._index; 00196 } 00197 00198 // This wire did not already exist; add it. 00199 WireDef &def = _input_wires[name]; 00200 def._data_type = data_type; 00201 def._index = _input_wires.size() - 1; 00202 return def._index; 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: DataNode::define_output 00207 // Access: Protected 00208 // Description: Adds a new output wire with the given name and the 00209 // indicated data type. The data type should be the 00210 // TypeHandle for some type that derives from 00211 // TypedReferenceCount, e.g. EventStoreInt, 00212 // EventStoreDouble, or some fancier data type like 00213 // Texture. 00214 // 00215 // If there is already an output wire defined with the 00216 // indicated name, its type is changed. 00217 // 00218 // The return value is the index into the "output" 00219 // parameter to do_transmit_data() where the output data 00220 // should be stored. 00221 //////////////////////////////////////////////////////////////////// 00222 int DataNode:: 00223 define_output(const string &name, TypeHandle data_type) { 00224 // We shouldn't already be connected. 00225 nassertr(_data_connections.empty(), 0); 00226 00227 Wires::iterator wi; 00228 wi = _output_wires.find(name); 00229 if (wi != _output_wires.end()) { 00230 // This wire already existed; modify it and return the original 00231 // index. 00232 WireDef &def = (*wi).second; 00233 def._data_type = data_type; 00234 return def._index; 00235 } 00236 00237 // This wire did not already exist; add it. 00238 WireDef &def = _output_wires[name]; 00239 def._data_type = data_type; 00240 def._index = _output_wires.size() - 1; 00241 return def._index; 00242 } 00243 00244 //////////////////////////////////////////////////////////////////// 00245 // Function: DataNode::parents_changed 00246 // Access: Protected, Virtual 00247 // Description: Called after a scene graph update that either adds or 00248 // remove parents from this node, this just provides a 00249 // hook for derived PandaNode objects that need to 00250 // update themselves based on the set of parents the 00251 // node has. 00252 //////////////////////////////////////////////////////////////////// 00253 void DataNode:: 00254 parents_changed() { 00255 PandaNode::parents_changed(); 00256 reconnect(); 00257 } 00258 00259 //////////////////////////////////////////////////////////////////// 00260 // Function: DataNode::do_transmit_data 00261 // Access: Protected, Virtual 00262 // Description: The virtual implementation of transmit_data(). This 00263 // function receives an array of input parameters and 00264 // should generate an array of output parameters. The 00265 // input parameters may be accessed with the index 00266 // numbers returned by the define_input() calls that 00267 // were made earlier (presumably in the constructor); 00268 // likewise, the output parameters should be set with 00269 // the index numbers returned by the define_output() 00270 // calls. 00271 //////////////////////////////////////////////////////////////////// 00272 void DataNode:: 00273 do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &, 00274 DataNodeTransmit &) { 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: DataNode::reconnect 00279 // Access: Private 00280 // Description: Establishes the input(s) that this DataNode has in 00281 // common with its parents' output(s). Builds up the 00282 // _data_connections list correspondingly. 00283 //////////////////////////////////////////////////////////////////// 00284 void DataNode:: 00285 reconnect() { 00286 int num_parents = get_num_parents(); 00287 _data_connections.clear(); 00288 // Look for each input among one of the parents. 00289 int num_datanode_parents = 0; 00290 00291 Wires::const_iterator wi; 00292 for (wi = _input_wires.begin(); wi != _input_wires.end(); ++wi) { 00293 const string &name = (*wi).first; 00294 const WireDef &input_def = (*wi).second; 00295 00296 int num_found = 0; 00297 for (int i = 0; i < num_parents; i++) { 00298 PandaNode *parent_node = get_parent(i); 00299 if (parent_node->is_of_type(DataNode::get_class_type())) { 00300 DataNode *data_node = DCAST(DataNode, parent_node); 00301 num_datanode_parents++; 00302 Wires::const_iterator pi; 00303 pi = data_node->_output_wires.find(name); 00304 if (pi != data_node->_output_wires.end()) { 00305 const WireDef &output_def = (*pi).second; 00306 num_found++; 00307 if (output_def._data_type != input_def._data_type) { 00308 dgraph_cat.warning() 00309 << "Ignoring mismatched type for connection " << name 00310 << " between " << *data_node << " and " << *this << "\n"; 00311 } else if (num_found == 1) { 00312 DataConnection dc; 00313 dc._parent_index = i; 00314 dc._output_index = output_def._index; 00315 dc._input_index = input_def._index; 00316 _data_connections.push_back(dc); 00317 } 00318 } 00319 } 00320 } 00321 00322 if (num_found > 1) { 00323 dgraph_cat.warning() 00324 << "Multiple connections found for " << name << " into " << *this 00325 << "\n"; 00326 } 00327 } 00328 00329 if (_data_connections.empty() && get_num_inputs() != 0 && 00330 num_datanode_parents != 0) { 00331 dgraph_cat.warning() 00332 << "No data connected to " << *this << "\n"; 00333 } 00334 } 00335 00336 //////////////////////////////////////////////////////////////////// 00337 // Function: DataNode::write_datagram 00338 // Access: Public, Virtual 00339 // Description: Writes the contents of this object to the datagram 00340 // for shipping out to a Bam file. 00341 //////////////////////////////////////////////////////////////////// 00342 void DataNode:: 00343 write_datagram(BamWriter *manager, Datagram &dg) { 00344 PandaNode::write_datagram(manager, dg); 00345 } 00346 00347 //////////////////////////////////////////////////////////////////// 00348 // Function: DataNode::fillin 00349 // Access: Protected 00350 // Description: This internal function is called by make_from_bam to 00351 // read in all of the relevant data from the BamFile for 00352 // the new Lens. 00353 //////////////////////////////////////////////////////////////////// 00354 void DataNode:: 00355 fillin(DatagramIterator &scan, BamReader *manager) { 00356 PandaNode::fillin(scan, manager); 00357 }