/** * @file artis/observer/View.hpp * @author See the AUTHORS file */ /* * Copyright (C) 2012-2017 ULCO http://www.univ-littoral.fr * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ARTIS_OBSERVER_VIEW_HPP #define ARTIS_OBSERVER_VIEW_HPP #include #include #include namespace artis { namespace observer { template < typename U, typename V > class View { typedef std::vector < unsigned int > Selector; public: typedef std::vector < std::pair < double, std::string > > Value; typedef std::map < std::string, Value > Values; View() : _model(0) { } virtual ~View() { } void attachModel(const artis::kernel::AbstractModel < U, V >* m) { _model = m; } double begin() const { double t = utils::DoubleTime::infinity; for (Values::const_iterator it = _values.begin(); it!= _values.end(); ++it) { if (t > it->second.begin()->first) { t = it->second.begin()->first; } } return t; } View* clone() const { View* v = new View(); v->_selectors = _selectors; for (Values::const_iterator it = _values.begin(); it!= _values.end(); ++it) { v->_values[it->first] = Value(); Value::const_iterator itp = it->second.begin(); while (itp != it->second.end()) { v->_values[it->first].push_back(*itp); ++itp; } } v->_model = 0; return v; } double end() const { double t = 0; for (Values::const_iterator it = _values.begin(); it!= _values.end(); ++it) { if (t < it->second.back().first) { t = it->second.back().first; } } return t; } double get(double t, const std::string& name) const { Values::const_iterator it = _values.find(name); if (it != _values.end()) { Value::const_iterator itp = it->second.begin(); while (itp != it->second.end() and itp->first < t) { ++itp; } if (itp != it->second.end()) { // TODO: to improve return boost::lexical_cast < double >(itp->second); } else { return 0; } } return 0; } const Value& get(const std::string& name) const { Values::const_iterator it = _values.find(name); if (it != _values.end()) { return it->second; } else { assert(false); } } virtual void observe(double time) { for (typename Selectors::const_iterator it = _selectors.begin(); it != _selectors.end(); ++it) { const kernel::Node < utils::DoubleTime >* model = _model; if (it->second.second.size() > 1) { size_t i = 0; while (i < it->second.second.size() - 1 and model) { model = model->get_submodel(it->second.second[i]); ++i; } } if (model) { _values[it->first].push_back( std::make_pair(time, model->get(it->second.first, time, it->second.second.back()))); } } } void selector(const std::string& name, kernel::ValueTypeID value_type, const Selector& chain) { _selectors[name] = std::make_pair(value_type, chain); _values[name] = Value(); } const Values& values() const { return _values;} private: typedef std::map < std::string, std::pair < kernel::ValueTypeID, Selector > > Selectors; Selectors _selectors; Values _values; const artis::kernel::AbstractModel < U, V >* _model; }; } } #endif