00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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;
00069 unsigned int sequencePos;
00070
00071 };
00072
00074
00075
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
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
00177 ++rep->sequencePos;
00178 break;
00179
00180 case Element::CHILD_REPEAT:
00181 {
00182
00183 addElement(currentElement(), 1);
00184 std::random_shuffle
00185 (rep->elements.begin()+rep->sequencePos+1, rep->elements.end());
00186
00187
00188 ++rep->sequencePos;
00189 }
00190 break;
00191
00192 case Element::CHILD_ABORTED:
00193 {
00194
00195
00196 ref<Element> aborted_element = currentElement();
00197
00198
00199
00200 rep->elements.erase(rep->elements.begin()+rep->sequencePos);
00201
00202
00203 rep->elements.push_back(aborted_element);
00204
00205
00206
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
00219
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
00238
00239
00240
00241 if (rep->sequencePos < 1) return;
00242
00243
00244 --rep->sequencePos;
00245
00246 GVX_ASSERT(rep->sequencePos < rep->elements.size());
00247
00248
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
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