damaris-backends/core/states.cpp
2014-06-26 11:10:51 +00:00

112 lines
3.1 KiB
C++

/* **************************************************************************
Author: Achim Gaedke
Created: June 2004
****************************************************************************/
#include "states.h"
#include "xml_states.h"
state* state_parallel::copy_flat(size_t enroll) const {
return copy_new();
}
state* state_sequent::copy_flat(size_t max_enroll_loop) const {
state_sequent* flat=new state_sequent;
flat->repeat=repeat;
if (flat->repeat==0)
return flat;
// start copying everything...
for (const_iterator i=begin(); i!=end(); ++i) {
const state* this_state=dynamic_cast<const state*>(*i);
// make the state flat, if sequence is no loop
if (this_state!=NULL) {
state* new_flat=this_state->copy_flat(max_enroll_loop);
state_sequent* ss=dynamic_cast<state_sequent*>(new_flat);
// handle the sequence
if (ss!=NULL) {
// skip this part
if (ss->repeat==0) {
delete ss;
continue;
}
// do not use extra sequent section
if (ss->repeat==1) {
while (!ss->empty()) {
flat->push_back(ss->front());
ss->pop_front();
}
delete ss;
continue;
}
flat->push_back(new_flat);
continue;
}
state_parallel* sp=dynamic_cast<state_parallel*>(new_flat);
if (sp!=NULL) {
flat->push_back(new_flat);
continue;
}
// if this is a state, check length...
if (new_flat->length==0.0)
delete new_flat;
else
flat->push_back(new_flat);
continue;
}
// simply append other things
flat->push_back((**i).copy_new());
} // for
// now enrol own loop
if (repeat>1 && repeat<=max_enroll_loop) {
flat->repeat=1;
std::list<state_atom*> orig_list(*flat);
for (size_t loop=1;loop<repeat;++loop)
flat->insert(flat->end(),orig_list.begin(),orig_list.end());
}
return flat;
}
state* state_iterator::get_state() {
if (subsequence_stack.empty()) return NULL; // at the end of traversal
// find a state or a subsequence in actual subsequence
state* next_one=NULL;
for (state_sequent::const_iterator i=subsequence_stack.back().subsequence_pos;
i!=subsequence_stack.back().subsequence->end();
++i) {
next_one=dynamic_cast<state*>(*i);
if (next_one!=NULL) break;
}
// this subsequence is finished, so go on with the upper one
if (next_one==NULL) {
double substate_time=subsequence_stack.back().elapsed_time*subsequence_stack.back().subsequence->repeat;
subsequence_stack.pop_back();
if (subsequence_stack.empty()) {
total_time=substate_time;
return NULL;
}
subsequence_stack.back().elapsed_time+=substate_time;
++subsequence_stack.back().subsequence_pos;
return get_state();
}
// find out, if this is a subsequence
state_sequent* next_sequent=dynamic_cast<state_sequent*>(next_one);
if (next_sequent!=NULL) {
if (next_sequent->repeat!=0) {
subsequence_iterator next_level={next_sequent,next_sequent->begin(),0};
subsequence_stack.push_back(next_level);
}
else {
++(subsequence_stack.back().subsequence_pos);
}
return get_state();
}
// this is a state
return next_one;
}