5 #include <boost/thread/mutex.hpp> 
    7 #include "flame/base.h" 
    8 #include "flame/util.h" 
   12 typedef boost::mutex info_mutex_t;
 
   13 info_mutex_t info_mutex;
 
   16 StateBase::~StateBase() {}
 
   39         Info.
name = 
"next_elem";
 
   41         Info.type = ArrayInfo::Sizet;
 
   47         Info.type = ArrayInfo::Double;
 
   55     :name(conf.get<
std::string>(
"name"))
 
   57     ,length(conf.get<double>(
"L",0.0))
 
   62 ElementVoid::~ElementVoid()
 
   74     p_conf = other->p_conf;
 
   76     *
const_cast<std::string*
>(&
name) = other->
name;
 
   86     std::string type(c.
get<std::string>(
"sim_type"));
 
   88     FLAME_LOG(INFO)<<
"Constructing Machine w/ sim_type='"<<type<<
'\'';
 
   90     info_mutex_t::scoped_lock G(info_mutex);
 
   92     p_state_infos_t::iterator it = p_state_infos.find(type);
 
   93     if(it==p_state_infos.end()) {
 
   94         std::ostringstream msg;
 
   95         msg<<
"Unsupport sim_type '"<<type<<
"'";
 
   96         throw key_error(msg.str());
 
  101     typedef Config::vector_t elements_t;
 
  102     elements_t Es(c.
get<elements_t>(
"elements"));
 
  105     p_lookup_t result_l, result_t;
 
  106     result.reserve(Es.size());
 
  109     for(elements_t::iterator it=Es.begin(), 
end=Es.end(); it!=
end; ++it)
 
  113         const std::string& etype(EC.
get<std::string>(
"type"));
 
  115         state_info::elements_t::iterator eit = p_info.elements.find(etype);
 
  116         if(eit==p_info.elements.end())
 
  117             throw key_error(etype);
 
  119         element_builder_t* builder = eit->second;
 
  123             E = builder->build(EC);
 
  124         }
catch(key_error& e){
 
  125             std::ostringstream strm;
 
  126             strm<<
"Error while initializing element "<<idx<<
" '"<<EC.
get<std::string>(
"name", 
"<invalid>")
 
  127                <<
"' : missing required parameter '"<<e.what()<<
"'";
 
  128             throw key_error(strm.str());
 
  130         }
catch(std::exception& e){
 
  131             std::ostringstream strm;
 
  132             strm<<
"Error while constructing element "<<idx<<
" '"<<EC.
get<std::string>(
"name", 
"<invalid>")
 
  133                <<
"' : "<<
typeid(e).name()<<
" : "<<e.what();
 
  134             throw std::runtime_error(strm.str());
 
  138             std::ostringstream strm;
 
  139             strm<<
"Element type inconsistent "<<etype<<
" "<<E->
type_name();
 
  140             throw std::logic_error(strm.str());
 
  143         *
const_cast<size_t*
>(&E->
index) = idx++; 
 
  146         result_l.insert(std::make_pair(LookupKey(E->
name, E->
index), E));
 
  147         result_t.insert(std::make_pair(LookupKey(etype, E->
index), E));
 
  152     p_elements.swap(result);
 
  153     p_lookup.swap(result_l);
 
  154     p_lookup_type.swap(result_t);
 
  155     FLAME_LOG(DEBUG)<<
"Complete constructing Machine w/ sim_type='"<<type<<
'\'';
 
  160     for(p_elements_t::iterator it=p_elements.begin(), 
end=p_elements.end(); it!=
end; ++it)
 
  169     const size_t nelem = p_elements.size();
 
  172     for(
size_t i=0; S->
next_elem<nelem && i<max; i++)
 
  179             E->p_observe->
view(E, S);
 
  181             (*p_trace) << 
"After ["<< n<< 
"] " << E->
name << 
" " << *S << 
"\n";
 
  188     return (*p_info.builder)(c);
 
  193     if(idx>=p_elements.size())
 
  194         throw std::invalid_argument(
"element index out of range");
 
  196     const std::string& etype(c.
get<std::string>(
"type"));
 
  198     state_info::elements_t::iterator eit = p_info.elements.find(etype);
 
  199     if(eit==p_info.elements.end())
 
  200         throw key_error(etype);
 
  202     element_builder_t *builder = eit->second;
 
  204     builder->rebuild(p_elements[idx], c);
 
  207 Machine::p_state_infos_t Machine::p_state_infos;
 
  209 void Machine::p_registerState(
const char *name, state_builder_t b)
 
  211     info_mutex_t::scoped_lock G(info_mutex);
 
  212     if(p_state_infos.find(name)!=p_state_infos.end()) {
 
  213         std::ostringstream strm;
 
  214         strm<<
"attempt to register already registered sim_type=\""<<name<<
"\"";
 
  215         throw std::logic_error(strm.str());
 
  220     p_state_infos[name] = I;
 
  223 void Machine::p_registerElement(
const std::string& sname, 
const char *ename, element_builder_t *b)
 
  225     info_mutex_t::scoped_lock G(info_mutex);
 
  226     p_state_infos_t::iterator it = p_state_infos.find(sname);
 
  227     if(it==p_state_infos.end()) {
 
  228         std::ostringstream strm;
 
  229         strm<<
"can't add element \""<<ename<<
"\" for unknown sim_type=\""<<sname<<
"\"";
 
  230         throw std::logic_error(strm.str());
 
  232     state_info& I = it->second;
 
  233     if(I.elements.find(ename)!=I.elements.end()) {
 
  234         std::ostringstream strm;
 
  235         strm<<
"element type \""<<ename<<
"\" has already been registered for " 
  236               "sim_type=\""<<sname<<
"\"";
 
  237         throw std::logic_error(strm.str());
 
  239     I.elements[ename] = b;
 
  244     info_mutex_t::scoped_lock G(info_mutex);
 
  246     for(p_state_infos_t::iterator it=p_state_infos.begin(), 
end=p_state_infos.end();
 
  249         state_info::elements_t::iterator it2, end2;
 
  250         for(it2=it->second.elements.begin(), end2=it->second.elements.end(); it2!=end2; ++it2)
 
  255     p_state_infos.clear();
 
  258 std::ostream& operator<<(std::ostream& strm, 
const Machine& m)
 
  260     strm<<
"sim_type: "<<m.p_info.name<<
"\n#Elements: "<<m.p_elements.size()<<
"\n";
 
  261     for(Machine::p_elements_t::const_iterator it=m.p_elements.begin(),
 
  262         end=m.p_elements.end(); it!=end; ++it)
 
  264         (*it)->show(strm, 0);
 
  270 struct Logcerr : 
public Machine::Logger
 
  272     virtual ~Logcerr() {}
 
  273     virtual void log(
const Machine::LogRecord &r)
 
  275         std::string msg(r.strm.str());
 
  276         std::cerr<<r.fname<<
':'<<r.lnum<<
" : "<<msg;
 
  277         if(msg.empty() || msg[msg.size()-1]!=
'\n')
 
  280     static Logcerr singleton;
 
  281     static void noopdtor(Logcerr*) {}
 
  283 Logcerr Logcerr::singleton;
 
  286 int Machine::log_detail = FLAME_WARN;
 
  287 boost::shared_ptr<Machine::Logger> Machine::p_logger(&Logcerr::singleton, Logcerr::noopdtor);
 
  289 void Machine::set_logger(
const boost::shared_ptr<Logger> &p)
 
  291     boost::shared_ptr<Logger> temp(p);
 
  293         temp.reset(&Logcerr::singleton, Logcerr::noopdtor);
 
  295         info_mutex_t::scoped_lock G(info_mutex);
 
  300 Machine::LogRecord::~LogRecord()
 
  302     boost::shared_ptr<Logger> logger;
 
  304         info_mutex_t::scoped_lock G(info_mutex);
 
StateBase(const Config &c)
 
ElementVoid(const Config &conf)
Construct this element using the provided Config. 
 
void propagate(StateBase *S, size_t start=0, size_t max=-1) const 
Pass the given bunch State through this Machine. 
 
Base class for all simulated elements. 
 
double length
Longitudual length of this element (added to StateBase::pos) 
 
virtual void view(const ElementVoid *elem, const StateBase *state)=0
Called from within Machine::propagate() 
 
Machine(const Config &c)
Construct a new Machine. 
 
The core simulate Machine engine. 
 
virtual const char * type_name() const =0
 
virtual void advance(StateBase &s)=0
Propogate the given State through this Element. 
 
The abstract base class for all simulation state objects. 
 
virtual void assign(const ElementVoid *other)=0
 
Associative configuration container. 
 
Used with StateBase::getArray() to describe a single parameter. 
 
virtual void assign(const StateBase &other)=0
 
static void registeryCleanup()
Discard all registered State and Element type information. 
 
double pos
absolute longitudinal position at end of Element 
 
const std::string name
Name of this element (unique in its Machine) 
 
iterator end()
Points just after the last element. 
 
void reconfigure(size_t idx, const Config &c)
Change the configuration of a single element. 
 
const size_t index
Index of this element (unique in its Machine) 
 
virtual bool getArray(unsigned index, ArrayInfo &Info)
Introspect named parameter of the derived class. 
 
detail::RT< T >::type get(const std::string &name) const 
 
virtual void show(std::ostream &, int level) const 
 
StateBase * allocState() const 
 
const char * name
The parameter name.