object_factory.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SuperTux
  2. // Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
  3. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #ifndef HEADER_SUPERTUX_SUPERTUX_OBJECT_FACTORY_HPP
  18. #define HEADER_SUPERTUX_SUPERTUX_OBJECT_FACTORY_HPP
  19. #include <assert.h>
  20. #include <map>
  21. #include <memory>
  22. #include <functional>
  23. #include <vector>
  24. #include "math/fwd.hpp"
  25. #include "supertux/direction.hpp"
  26. class GameObject;
  27. class ReaderMapping;
  28. class ObjectFactory
  29. {
  30. private:
  31. struct FactoryFunctions {
  32. std::function<std::unique_ptr<GameObject> (const ReaderMapping&)> create = nullptr;
  33. std::function<std::string ()> get_display_name = nullptr;
  34. };
  35. typedef std::map<std::string, FactoryFunctions> Factories;
  36. Factories factories;
  37. std::vector<std::string> m_badguys_names;
  38. std::vector<uint8_t> m_badguys_params;
  39. std::vector<std::string> m_objects_names;
  40. std::vector<uint8_t> m_objects_params;
  41. protected:
  42. bool m_adding_badguys;
  43. public:
  44. enum RegisteredObjectParam
  45. {
  46. OBJ_PARAM_NONE = 0,
  47. OBJ_PARAM_PORTABLE = 0b10000000,
  48. OBJ_PARAM_WORLDMAP = 0b01000000,
  49. OBJ_PARAM_DISPENSABLE = 0b00100000
  50. };
  51. public:
  52. /** Will throw in case of creation failure, will never return nullptr */
  53. std::unique_ptr<GameObject> create(const std::string& name, const ReaderMapping& reader) const;
  54. std::string get_display_name(const std::string& name) const;
  55. bool has_params(const std::string& name, uint8_t params);
  56. std::vector<std::string>& get_registered_badguys() { return m_badguys_names; }
  57. std::vector<std::string> get_registered_badguys(uint8_t params);
  58. std::vector<std::string>& get_registered_objects() { return m_objects_names; }
  59. std::vector<std::string> get_registered_objects(uint8_t params);
  60. protected:
  61. ObjectFactory();
  62. void add_factory(const char* name, const FactoryFunctions functions, uint8_t obj_params = 0)
  63. {
  64. assert(factories.find(name) == factories.end());
  65. if (m_adding_badguys)
  66. {
  67. m_badguys_names.push_back(name);
  68. m_badguys_params.push_back(obj_params);
  69. }
  70. m_objects_names.push_back(name);
  71. m_objects_params.push_back(obj_params);
  72. factories[name] = std::move(functions);
  73. }
  74. private:
  75. template<class C>
  76. void add_factory(const char* class_name,
  77. const std::function<std::unique_ptr<GameObject> (const ReaderMapping&)>& create_func,
  78. uint8_t obj_params = 0)
  79. {
  80. add_factory(class_name, { std::move(create_func), C::display_name }, obj_params);
  81. }
  82. protected:
  83. template<class C>
  84. void add_factory(const char* class_name, uint8_t obj_params = 0)
  85. {
  86. add_factory<C>(class_name,
  87. [](const ReaderMapping& reader) {
  88. return std::make_unique<C>(reader);
  89. }, obj_params);
  90. }
  91. template<class C>
  92. void add_type_factory(const char* class_name, int type, uint8_t obj_params = 0)
  93. {
  94. add_factory<C>(class_name,
  95. [type](const ReaderMapping& reader) {
  96. return std::make_unique<C>(reader, type);
  97. }, obj_params);
  98. }
  99. };
  100. #endif
  101. /* EOF */