Internals.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**
  2. * @file artis/kernel/Internals.hpp
  3. * @author See the AUTHORS file
  4. */
  5. /*
  6. * Copyright (C) 2012-2017 ULCO http://www.univ-littoral.fr
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #ifndef __ARTIS_KERNEL_INTERNALS_HPP
  22. #define __ARTIS_KERNEL_INTERNALS_HPP
  23. #include <artis/context/State.hpp>
  24. #include <artis/kernel/Any.hpp>
  25. #include <artis/kernel/Macro.hpp>
  26. #include <vector>
  27. namespace artis { namespace kernel {
  28. template < typename T, typename U, typename V >
  29. class Internals
  30. {
  31. template < typename W >
  32. struct element
  33. {
  34. unsigned int index;
  35. const std::string name;
  36. W T::* var;
  37. element(unsigned int index, const std::string& name, W T::* var) :
  38. index(index), name(name), var(var)
  39. { }
  40. };
  41. public:
  42. Internals()
  43. { }
  44. virtual ~Internals()
  45. { }
  46. const Any& get(unsigned int index) const
  47. { return internals.at(index); }
  48. template < typename W >
  49. void I_(std::initializer_list < element < W > > list)
  50. {
  51. for (typename std::initializer_list <element < W > >::iterator it =
  52. list.begin(); it != list.end(); ++it) {
  53. if (internals.size() <= it->index) {
  54. internals.resize(it->index + 1);
  55. internal_names.resize(it->index + 1, std::string());
  56. }
  57. internals[it->index] = it->var;
  58. internal_names[it->index] = it->name;
  59. #ifdef WITH_TRACE
  60. utils::Trace < utils::DoubleTime >::trace()
  61. << utils::TraceElement < utils::DoubleTime >(
  62. dynamic_cast<T*>(this)->path(dynamic_cast<T*>(this)),
  63. utils::DoubleTime::null,
  64. utils::INTERNAL_DECL)
  65. << utils::KernelInfo(it->name, true);
  66. utils::Trace < utils::DoubleTime >::trace().flush();
  67. #endif
  68. }
  69. }
  70. template < typename W >
  71. void internal_(unsigned int index, const std::string& name, W T::* var)
  72. {
  73. if (internals.size() <= index) {
  74. internals.resize(index + 1, Any());
  75. internal_names.resize(index + 1, std::string());
  76. }
  77. internals[index] = Any(var);
  78. internal_names[index] = name;
  79. #ifdef WITH_TRACE
  80. utils::Trace < utils::DoubleTime >::trace()
  81. << utils::TraceElement < utils::DoubleTime >(
  82. dynamic_cast<T*>(this)->path(dynamic_cast<T*>(this)),
  83. utils::DoubleTime::null,
  84. utils::INTERNAL_DECL)
  85. << utils::KernelInfo(name, true);
  86. utils::Trace < utils::DoubleTime >::trace().flush();
  87. #endif
  88. }
  89. const std::string& name(unsigned int index) const
  90. { return internal_names.at(index); }
  91. virtual void restore(AbstractModel < U, V >* model,
  92. const context::State < U >& state)
  93. {
  94. unsigned int index = 0;
  95. for (typename std::vector < Any >::iterator it = internals.begin();
  96. it != internals.end(); ++it) {
  97. if (not it->is_null()) {
  98. it->restore < T >(static_cast < T* >(model),
  99. state.get_internal(index));
  100. }
  101. ++index;
  102. }
  103. }
  104. virtual void save(const AbstractModel < U, V >* model,
  105. context::State < U >& state) const
  106. {
  107. unsigned int index = 0;
  108. for (typename std::vector < Any >::const_iterator it =
  109. internals.begin(); it != internals.end(); ++it) {
  110. if (not it->is_null()) {
  111. state.add_internal(index,
  112. it->save < T >(
  113. static_cast < const T* >(model)));
  114. }
  115. ++index;
  116. }
  117. }
  118. unsigned int size() const
  119. { return internals.size(); }
  120. private:
  121. std::vector < std::string > internal_names;
  122. std::vector < Any > internals;
  123. };
  124. #define Internal(index, var) \
  125. internal_(index, std::string(ESCAPEQUOTE(index)), var)
  126. #define Internals(W,L) I_< W >(UNWRAP2 L)
  127. } } // namespace artis kernel
  128. #endif