Model.hpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /**
  2. * @file Model.hpp
  3. * @author The ARTIS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * ARTIS - the multimodeling and simulation environment
  8. * This file is a part of the ARTIS environment
  9. *
  10. * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #ifndef COMMON_MODEL
  26. #define COMMON_MODEL
  27. #include <artis-star/common/Bag.hpp>
  28. #include <artis-star/common/ExternalEvent.hpp>
  29. #include <artis-star/common/InternalEvent.hpp>
  30. #include <artis-star/common/Scheduler.hpp>
  31. #include <artis-star/common/Value.hpp>
  32. #include <algorithm>
  33. #include <cassert>
  34. #include <map>
  35. #include <sstream>
  36. namespace artis {
  37. namespace common {
  38. template<class Time>
  39. class ExternalEvent;
  40. template<class Time>
  41. class InternalEvent;
  42. template<class Time>
  43. class Bag;
  44. struct Port {
  45. unsigned int index;
  46. std::string name;
  47. };
  48. typedef std::vector<unsigned int> Ports;
  49. typedef std::map<unsigned int, std::string> PortMap;
  50. template<class Time>
  51. class Model {
  52. public:
  53. Model(const std::string& name)
  54. :
  55. _tl(0), _tn(0), _parent(0), _name(name), _inputs(0) { }
  56. virtual ~Model()
  57. {
  58. if (_inputs) {
  59. delete _inputs;
  60. }
  61. }
  62. // structure
  63. void add_in_port(const Port& port)
  64. {
  65. assert(not exist_in_port(port.index));
  66. _in_ports.push_back(port.index);
  67. _in_port_map[port.index] = port.name;
  68. }
  69. void add_out_port(const Port& port)
  70. {
  71. assert(not exist_out_port(port.index));
  72. _out_ports.push_back(port.index);
  73. _out_port_map[port.index] = port.name;
  74. }
  75. void delete_in_port(const Port& port)
  76. {
  77. assert(not exist_in_port(port.index));
  78. _in_ports.erase(std::find(_in_ports.begin(), _in_ports.end(),
  79. port.index));
  80. _in_port_map.erase(port.index);
  81. }
  82. void delete_out_port(const Port& port)
  83. {
  84. assert(not exist_out_port(port.index));
  85. _out_ports.erase(std::find(_out_ports.begin(), _out_ports.end(),
  86. port.index));
  87. _out_port_map.erase(port.index);
  88. }
  89. bool exist_in_port(unsigned int port_index) const
  90. {
  91. return _in_port_map.find(port_index) != _in_port_map.end();
  92. }
  93. bool exist_out_port(unsigned int port_index) const
  94. {
  95. return _out_port_map.find(port_index) != _out_port_map.end();
  96. }
  97. std::string get_in_port_name(unsigned int port_index) const
  98. {
  99. assert(exist_in_port(port_index));
  100. return _in_port_map.find(port_index)->second;
  101. }
  102. size_t get_in_port_number() const { return _in_port_map.size(); }
  103. std::string get_out_port_name(unsigned int port_index) const
  104. {
  105. assert(exist_out_port(port_index));
  106. return _out_port_map.find(port_index)->second;
  107. }
  108. size_t get_out_port_number() const { return _out_port_map.size(); }
  109. const std::string& get_name() const { return _name; }
  110. Model<Time>* get_parent() const { return _parent; }
  111. // TODO: to remove
  112. virtual int get_receiver_number(typename Time::type t)
  113. {
  114. (void) t;
  115. return 0;
  116. }
  117. virtual const Model<Time>* get_submodel(unsigned int index) const
  118. {
  119. (void) index;
  120. assert(false);
  121. return nullptr;
  122. }
  123. virtual const Model<Time>* get_submodel(unsigned int index,
  124. unsigned int rank) const
  125. {
  126. (void) index;
  127. (void) rank;
  128. assert(false);
  129. return nullptr;
  130. }
  131. virtual unsigned int get_submodel_number(unsigned int index) const
  132. {
  133. (void) index;
  134. assert(false);
  135. return 0;
  136. }
  137. virtual bool is_atomic() const = 0;
  138. virtual bool is_remote() const { return false; }
  139. virtual std::string observable_name(unsigned int observable_index) const
  140. {
  141. (void) observable_index;
  142. assert(false);
  143. return std::string();
  144. }
  145. std::string path() const
  146. {
  147. return (_parent != nullptr ? _parent->path() : "") + ":" + get_name();
  148. }
  149. void set_parent(Model<Time>* parent) { _parent = parent; }
  150. virtual std::string to_string(int /* level */) const = 0;
  151. // event
  152. void add_event(const common::ExternalEvent<Time>& message)
  153. {
  154. if (_inputs == 0) {
  155. _inputs = new Bag<Time>;
  156. }
  157. _inputs->push_back(message);
  158. }
  159. void clear_bag()
  160. {
  161. if (_inputs) {
  162. delete _inputs;
  163. _inputs = 0;
  164. }
  165. }
  166. unsigned int event_number() const
  167. {
  168. return _inputs ? _inputs->size() : 0;
  169. }
  170. const common::Bag<Time>& get_bag()
  171. {
  172. if (_inputs == 0) {
  173. _inputs = new Bag<Time>;
  174. }
  175. return *_inputs;
  176. }
  177. // time
  178. typename Time::type get_tl() const { return _tl; }
  179. typename Time::type get_tn() const { return _tn; }
  180. // devs methods
  181. virtual common::Value observe(const typename Time::type& t,
  182. unsigned int index) const = 0;
  183. virtual void output(const typename Time::type& t) = 0;
  184. virtual void post_event(const typename Time::type& t,
  185. const common::ExternalEvent<Time>& event) = 0;
  186. virtual typename Time::type start(const typename Time::type& t) = 0;
  187. virtual typename Time::type transition(const typename Time::type& t) = 0;
  188. // scheduler
  189. void handle(SchedulerHandle handle) { _handle.handle(handle); }
  190. const SchedulerHandle& handle() const { return _handle.handle(); }
  191. protected:
  192. typename Time::type _tl;
  193. typename Time::type _tn;
  194. private :
  195. Model<Time>* _parent;
  196. std::string _name;
  197. Ports _in_ports;
  198. PortMap _in_port_map;
  199. Ports _out_ports;
  200. PortMap _out_port_map;
  201. Bag<Time>* _inputs;
  202. SchedulerHandle _handle;
  203. };
  204. template<class Time>
  205. class ModelMap : public std::map<unsigned int, Model<Time>*> {
  206. public:
  207. ModelMap() { }
  208. virtual ~ModelMap() { }
  209. std::string to_string() const
  210. {
  211. std::ostringstream ss;
  212. ss << "{ ";
  213. for (typename ModelMap<Time>::const_iterator it =
  214. ModelMap<Time>::begin();
  215. it != ModelMap<Time>::end(); ++it) {
  216. ss << it->second->get_name() << " ";
  217. }
  218. ss << "}";
  219. return ss.str();
  220. }
  221. };
  222. template<class Time>
  223. class Models : public std::vector<Model<Time>*> {
  224. public:
  225. Models() { }
  226. virtual ~Models() { }
  227. std::string to_string() const
  228. {
  229. std::ostringstream ss;
  230. ss << "{ ";
  231. for (typename Models<Time>::const_iterator it =
  232. Models<Time>::begin();
  233. it != Models<Time>::end(); ++it) {
  234. ss << (*it)->get_name() << " ";
  235. }
  236. ss << "}";
  237. return ss.str();
  238. }
  239. };
  240. template<class Time>
  241. class ModelsMap : public std::map<unsigned int, Models<Time> > {
  242. public:
  243. ModelsMap() { }
  244. virtual ~ModelsMap() { }
  245. std::string to_string() const
  246. {
  247. std::ostringstream ss;
  248. ss << "{ ";
  249. for (typename ModelsMap<Time>::const_iterator it =
  250. ModelsMap<Time>::begin();
  251. it != ModelsMap<Time>::end(); ++it) {
  252. ss << it->second.to_string() << " ";
  253. }
  254. ss << "}";
  255. return ss.str();
  256. }
  257. };
  258. }
  259. } // namespace artis common
  260. #endif