Panda3D

dataNode.cxx

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 }
 All Classes Functions Variables Enumerations