/** * @file HeapScheduler.hpp * @author The ARTIS Development Team * See the AUTHORS or Authors.txt file */ /* * ARTIS - the multimodeling and simulation environment * This file is a part of the ARTIS environment * * Copyright (C) 2013-2018 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 COMMON_SCHEDULER_HEAP_SCHEDULER_HPP #define COMMON_SCHEDULER_HEAP_SCHEDULER_HPP 1 #include #include #include namespace artis { namespace common { template < class Time > class Model; template < class Time > class Models; namespace scheduler { template < class Time, class T > class HeapScheduler : public boost::heap::fibonacci_heap < InternalEvent < Time >, boost::heap::compare < EventCompare < InternalEvent < Time > > > > { public: typedef HeapScheduler < Time, T > type; typedef Model < Time > model_type; typedef Models < Time > models_type; typedef InternalEvent < Time > internal_event_type; HeapScheduler() { } virtual ~HeapScheduler() { } model_type* get_current_model() { return type::top().get_model(); } models_type get_current_models(typename Time::type time) const { models_type models; typename models_type::iterator it; for (typename type::ordered_iterator it = type::ordered_begin(); it != type::ordered_end() and it->get_time() == time; ++it) { std::string str = it->get_model()->get_name(); auto it2 = find_if(models.begin(), models.end(), [&str](const model_type* obj) { return obj->get_name() == str; }); if (it2 == models.end()) { models.push_back(it->get_model()); } } return models; } typename Time::type get_current_time() const { return type::top().get_time(); } void init(typename Time::type time, model_type* model) { model->handle(T(type::push(internal_event_type(time, model)))); } void put(typename Time::type time, const model_type* model) { typename Time::type previous_time = (*model->handle()._handle).get_time(); if (previous_time != time) { (*model->handle()._handle).set_time(time); if (previous_time < time) { type::decrease(model->handle()._handle); } else if (previous_time > time) { type::increase(model->handle()._handle); } } } std::string to_string() const { std::stringstream ss; ss << "Scheduler = { "; for (typename type::ordered_iterator it = type::ordered_begin(); it != type::ordered_end(); ++it) { ss << "(" << it->get_time() << " -> " << it->get_model()->get_name() << ") "; } ss << "} [" << type::size() << "]"; return ss.str(); } }; } } } // namespace artis common scheduler #endif