ModelFactory.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /**
  2. * @file artis/builder/ModelFactory.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_BUILDER_MODEL_FACTORY_HPP
  22. #define __ARTIS_BUILDER_MODEL_FACTORY_HPP
  23. #include <algorithm>
  24. #include <memory>
  25. #include <mutex>
  26. #include <typeinfo>
  27. #include <boost/core/demangle.hpp>
  28. namespace artis { namespace builder {
  29. template < typename M >
  30. class ObjectCreator
  31. {
  32. public:
  33. ObjectCreator()
  34. { }
  35. virtual ~ObjectCreator()
  36. { }
  37. virtual std::string get() const = 0;
  38. virtual M* operator()() const = 0;
  39. };
  40. template < typename M, typename I, typename O >
  41. class ModelFactory
  42. {
  43. typedef ModelFactory < M, I, O > type;
  44. public:
  45. virtual ~ModelFactory()
  46. { }
  47. bool add(const I& id, O* creator)
  48. {
  49. std::lock_guard < std::mutex > lock(_mutex);
  50. return creators.insert(typename Creators::value_type(
  51. creator->get(),
  52. std::make_pair(id, creator))).second;
  53. }
  54. M* create(const std::string& id)
  55. {
  56. std::lock_guard < std::mutex > lock(_mutex);
  57. typename Creators::const_iterator it = creators.find(id);
  58. if (it != creators.end()) {
  59. return (*it->second.second)();
  60. } else {
  61. return nullptr;
  62. }
  63. }
  64. static ModelFactory& factory()
  65. {
  66. std::call_once(_flag, [] ()
  67. { _instance.reset(new ModelFactory()); });
  68. return *_instance;
  69. }
  70. int make_id()
  71. {
  72. std::lock_guard < std::mutex > lock(_mutex);
  73. return ++id;
  74. }
  75. bool remove(const I& id)
  76. {
  77. std::lock_guard < std::mutex > lock(_mutex);
  78. typename Creators::const_iterator it = creators.find(id);
  79. if (it != creators.end()) {
  80. creators.erase(it);
  81. return true;
  82. } else {
  83. return false;
  84. }
  85. }
  86. private:
  87. ModelFactory()
  88. { id = -1; }
  89. typedef std::pair < I, O* > Creator;
  90. typedef std::map < std::string, Creator > Creators;
  91. static std::shared_ptr < type > _instance;
  92. static std::once_flag _flag;
  93. std::mutex _mutex;
  94. Creators creators;
  95. int id;
  96. };
  97. } }
  98. template < typename M, typename I, typename O >
  99. std::shared_ptr < artis::builder::ModelFactory < M, I, O > >
  100. artis::builder::ModelFactory < M, I, O >::_instance;
  101. template < typename M, typename I, typename O >
  102. std::once_flag artis::builder::ModelFactory < M, I, O >::_flag;
  103. #define DECLARE_MODEL(mdl, type, fct) \
  104. class creator_##mdl : public artis::builder::ObjectCreator < type > { \
  105. public: \
  106. creator_##mdl() \
  107. { \
  108. fct::factory().add(fct::factory().make_id(), this); \
  109. } \
  110. std::string get() const \
  111. { return boost::core::demangle(typeid(mdl).name()); } \
  112. type* operator()() const \
  113. { return new mdl(); } \
  114. static creator_##mdl an_##mdl; \
  115. }; \
  116. creator_##mdl an_##mdl;
  117. #endif