elementcontainer.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2002-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Thu Dec  5 16:43:54 2002
00010 // commit: $Id: elementcontainer.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/visx/elementcontainer.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_VISX_ELEMENTCONTAINER_CC_UTC20050626084017_DEFINED
00035 #define GROOVX_VISX_ELEMENTCONTAINER_CC_UTC20050626084017_DEFINED
00036 
00037 #include "visx/elementcontainer.h"
00038 
00039 #include "io/reader.h"
00040 #include "io/readutils.h"
00041 #include "io/writer.h"
00042 #include "io/writeutils.h"
00043 
00044 #include "nub/log.h"
00045 #include "nub/ref.h"
00046 
00047 #include "rutz/error.h"
00048 #include "rutz/iter.h"
00049 #include "rutz/rand.h"
00050 #include "rutz/sfmt.h"
00051 
00052 #include <algorithm>
00053 #include <vector>
00054 
00055 #include "rutz/debug.h"
00056 GVX_DBG_REGISTER
00057 #include "rutz/trace.h"
00058 
00059 using nub::ref;
00060 
00061 class ElementContainer::Impl
00062 {
00063 public:
00064   Impl() : elements(), randSeed(0), sequencePos(0) {}
00065 
00066   std::vector<ref<Element> > elements;
00067 
00068   int randSeed;                 // Random seed used to create element sequence
00069   unsigned int sequencePos;     // Index of the current element
00070                                 // Also functions as # of completed elements
00071 };
00072 
00074 //
00075 // ElementContainer member functions
00076 //
00078 
00079 ElementContainer::ElementContainer() :
00080   rep(new Impl)
00081 {
00082 GVX_TRACE("ElementContainer::ElementContainer");
00083 }
00084 
00085 ElementContainer::~ElementContainer() throw()
00086 {
00087 GVX_TRACE("ElementContainer::~ElementContainer");
00088   delete rep;
00089 }
00090 
00091 void ElementContainer::read_from(io::reader& reader)
00092 {
00093 GVX_TRACE("ElementContainer::read_from");
00094   clearElements();
00095 
00096   io::read_utils::read_object_seq<Element>
00097     (reader, "trialSeq", std::back_inserter(rep->elements));
00098 
00099   reader.read_value("randSeed", rep->randSeed);
00100   reader.read_value("curTrialSeqdx", rep->sequencePos);
00101   if (rep->sequencePos > rep->elements.size())
00102     {
00103       throw rutz::error("ElementContainer", SRC_POS);
00104     }
00105 }
00106 
00107 void ElementContainer::write_to(io::writer& writer) const
00108 {
00109 GVX_TRACE("ElementContainer::write_to");
00110   io::write_utils::write_object_seq(writer, "trialSeq",
00111                                     rep->elements.begin(),
00112                                     rep->elements.end());
00113 
00114   writer.write_value("randSeed", rep->randSeed);
00115   writer.write_value("curTrialSeqdx", rep->sequencePos);
00116 }
00117 
00119 //
00120 // ElementContainer's Element base interface
00121 //
00123 
00124 int ElementContainer::trialType() const
00125 {
00126 GVX_TRACE("ElementContainer::trialType");
00127   if (isComplete()) return -1;
00128 
00129   dbg_eval_nl(3, currentElement()->trialType());
00130 
00131   return currentElement()->trialType();
00132 }
00133 
00134 int ElementContainer::lastResponse() const
00135 {
00136 GVX_TRACE("ElementContainer::lastResponse");
00137   dbg_eval(9, rep->sequencePos);
00138   dbg_eval_nl(9, rep->elements.size());
00139 
00140   if (rep->sequencePos == 0 ||
00141       rep->elements.size() == 0) return -1;
00142 
00143   ref<Element> prev_element = rep->elements.at(rep->sequencePos-1);
00144 
00145   return prev_element->lastResponse();
00146 }
00147 
00148 rutz::fstring ElementContainer::vxInfo() const
00149 {
00150 GVX_TRACE("ElementContainer::vxInfo");
00151   if (isComplete()) return rutz::fstring("complete");
00152 
00153   return rutz::sfmt("current element %s, completed %u of %u",
00154                     currentElement()->unique_name().c_str(),
00155                     numCompleted(),
00156                     numElements());
00157 }
00158 
00159 void ElementContainer::vxHalt() const
00160 {
00161 GVX_TRACE("ElementContainer::vxHalt");
00162 
00163   if ( !isComplete() )
00164     currentElement()->vxHalt();
00165 }
00166 
00167 void ElementContainer::vxReturn(ChildStatus s)
00168 {
00169 GVX_TRACE("ExptDriver::vxReturn");
00170 
00171   GVX_PRECONDITION( !isComplete() );
00172 
00173   switch (s)
00174     {
00175     case Element::CHILD_OK:
00176       // Move on to the next element.
00177       ++rep->sequencePos;
00178       break;
00179 
00180     case Element::CHILD_REPEAT:
00181       {
00182         // Add a repeat of the current element to the sequence and reshuffle
00183         addElement(currentElement(), 1);
00184         std::random_shuffle
00185           (rep->elements.begin()+rep->sequencePos+1, rep->elements.end());
00186 
00187         // Move on to the next element.
00188         ++rep->sequencePos;
00189       }
00190       break;
00191 
00192     case Element::CHILD_ABORTED:
00193       {
00194         // Remember the element that we are about to abort so we can
00195         // store it at the end of the sequence.
00196         ref<Element> aborted_element = currentElement();
00197 
00198         // Erase the aborted element from the sequence. Subsequent elements
00199         // will slide up to fill in the gap.
00200         rep->elements.erase(rep->elements.begin()+rep->sequencePos);
00201 
00202         // Add the aborted element to the back of the sequence.
00203         rep->elements.push_back(aborted_element);
00204 
00205         // Don't need to increment sequencePos here since the new trial
00206         // has "slid into place" by the reshuffling we've just done.
00207       }
00208       break;
00209 
00210     default:
00211       GVX_ASSERT(false);
00212     }
00213 
00214   dbg_eval(3, numCompleted());
00215   dbg_eval(3, numElements());
00216   dbg_eval_nl(3, isComplete());
00217 
00218   // Now, after (possibly) adjusting our sequence counter, see if we have
00219   // still have additional elements to run...
00220   if ( isComplete() )
00221     {
00222       vxAllChildrenFinished();
00223     }
00224   else
00225     {
00226       nub::log( vxInfo() );
00227 
00228       currentElement()->vxRun(*this);
00229     }
00230 }
00231 
00232 void ElementContainer::vxUndo()
00233 {
00234 GVX_TRACE("ElementContainer::vxUndo");
00235   dbg_eval(3, rep->sequencePos);
00236 
00237   // FIXME how to know whether we should back up our own sequence, or
00238   // whether our child just backs up in its own sequence?
00239 
00240   // Check to make sure we've completed at least one element
00241   if (rep->sequencePos < 1) return;
00242 
00243   // Move the counter back to the previous element...
00244   --rep->sequencePos;
00245 
00246   GVX_ASSERT(rep->sequencePos < rep->elements.size());
00247 
00248   // ...and undo that element
00249   currentElement()->vxUndo();
00250 }
00251 
00252 void ElementContainer::vxReset()
00253 {
00254 GVX_TRACE("ElementContainer::vxReset");
00255   vxHalt();
00256 
00257   nub::log("ElementContainer::vxReset");
00258 
00259   for (unsigned int i = 0; i < rep->elements.size(); ++i)
00260     {
00261       nub::log(rutz::sfmt("resetting element %u", i));
00262       rep->elements[i]->vxReset();
00263     }
00264 
00265   rep->sequencePos = 0;
00266 }
00267 
00268 
00270 //
00271 // ElementContainer's container interface
00272 //
00274 
00275 void ElementContainer::addElement(ref<Element> element, unsigned int repeat)
00276 {
00277 GVX_TRACE("ElementContainer::addElement");
00278 
00279   for (unsigned int i = 0; i < repeat; ++i)
00280     {
00281       rep->elements.push_back(element);
00282     }
00283 }
00284 
00285 void ElementContainer::setRandSeed(int s)
00286 {
00287 GVX_TRACE("ElementContainer::setRandSeed");
00288   rep->randSeed = s;
00289 }
00290 
00291 int ElementContainer::getRandSeed() const
00292 {
00293 GVX_TRACE("ElementContainer::getRandSeed");
00294   return rep->randSeed;
00295 }
00296 
00297 void ElementContainer::shuffle(int seed)
00298 {
00299 GVX_TRACE("ElementContainer::shuffle");
00300 
00301   setRandSeed(seed);
00302 
00303   rutz::urand generator(rep->randSeed);
00304 
00305   std::random_shuffle(rep->elements.begin(),
00306                       rep->elements.end(),
00307                       generator);
00308 }
00309 
00310 void ElementContainer::clearElements()
00311 {
00312 GVX_TRACE("ElementContainer::clearElements");
00313   vxHalt();
00314 
00315   rep->elements.clear();
00316   rep->sequencePos = 0;
00317 }
00318 
00319 nub::soft_ref<Element> ElementContainer::currentElement() const
00320 {
00321 GVX_TRACE("ElementContainer::currentElement");
00322   if (rep->sequencePos >= rep->elements.size())
00323     return nub::soft_ref<Element>();
00324 
00325   return rep->elements.at(rep->sequencePos);
00326 }
00327 
00328 unsigned int ElementContainer::numElements() const
00329 {
00330 GVX_TRACE("ElementContainer::numElements");
00331   return rep->elements.size();
00332 }
00333 
00334 unsigned int ElementContainer::numCompleted() const
00335 {
00336 GVX_TRACE("ElementContainer::numCompleted");
00337   return rep->sequencePos;
00338 }
00339 
00340 rutz::fwd_iter<const nub::ref<Element> >
00341 ElementContainer::getElements() const
00342 {
00343 GVX_TRACE("ElementContainer::getElements");
00344 
00345   return rutz::fwd_iter<const nub::ref<Element> >
00346     (rep->elements.begin(), rep->elements.end());
00347 }
00348 
00349 bool ElementContainer::isComplete() const
00350 {
00351 GVX_TRACE("ElementContainer::isComplete");
00352 
00353   dbg_eval(9, rep->sequencePos);
00354   dbg_eval_nl(9, rep->elements.size());
00355 
00356   return (rep->sequencePos >= rep->elements.size());
00357 }
00358 
00359 static const char __attribute__((used)) vcid_groovx_visx_elementcontainer_cc_utc20050626084017[] = "$Id: elementcontainer.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00360 #endif // !GROOVX_VISX_ELEMENTCONTAINER_CC_UTC20050626084017_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:41 2008 by Doxygen version 1.5.5.