A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Mod.h 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <stdint.h>
  3. #include <string>
  4. #include <vector>
  5. #include <memory>
  6. #include <type_traits>
  7. #include <SDL.h>
  8. #include "Tile.h"
  9. #include "Item.h"
  10. #include "WorldGen.h"
  11. #include "Entity.h"
  12. #include "Collection.h"
  13. #include "OS.h"
  14. #include "util.h"
  15. namespace Swan {
  16. class ModWrapper;
  17. class Mod {
  18. public:
  19. Mod(std::string name): name_(std::move(name)) {}
  20. virtual ~Mod() = default;
  21. void registerTile(Tile::Builder tile) { tiles_.push_back(tile); }
  22. void registerItem(Item::Builder item) { items_.push_back(item); }
  23. void registerSprite(std::string sprite) { sprites_.push_back(sprite); }
  24. template<typename WG>
  25. void registerWorldGen(std::string name) {
  26. worldGens_.push_back(WorldGen::Factory{
  27. .name = name,
  28. .create = [](World &world) -> std::unique_ptr<WorldGen> {
  29. return std::make_unique<WG>(world);
  30. }
  31. });
  32. }
  33. template<typename Ent>
  34. void registerEntity(const std::string &name) {
  35. static_assert(
  36. std::is_move_constructible_v<Ent>,
  37. "Entities must be movable");
  38. entities_.push_back(EntityCollection::Factory{
  39. .name = name,
  40. .create = [](std::string name) -> std::unique_ptr<EntityCollection> {
  41. return std::make_unique<EntityCollectionImpl<Ent>>(std::move(name));
  42. }
  43. });
  44. }
  45. private:
  46. const std::string name_;
  47. std::vector<Tile::Builder> tiles_;
  48. std::vector<Item::Builder> items_;
  49. std::vector<std::string> sprites_;
  50. std::vector<WorldGen::Factory> worldGens_;
  51. std::vector<EntityCollection::Factory> entities_;
  52. friend ModWrapper;
  53. };
  54. class ModWrapper {
  55. public:
  56. ModWrapper(std::unique_ptr<Mod> mod, std::string path, OS::Dynlib lib):
  57. mod_(std::move(mod)), path_(std::move(path)), dynlib_(std::move(lib)) {}
  58. ModWrapper(ModWrapper &&other) noexcept = default;
  59. ~ModWrapper() {
  60. // Mod::~Mod will destroy stuff allocated by the dynlib,
  61. // so we must run its destructor before deleting the dynlib
  62. mod_.reset();
  63. }
  64. const std::string &name() { return mod_->name_; }
  65. const std::vector<Tile::Builder> &tiles() { return mod_->tiles_; }
  66. const std::vector<Item::Builder> &items() { return mod_->items_; }
  67. const std::vector<std::string> &sprites() { return mod_->sprites_; }
  68. const std::vector<WorldGen::Factory> &worldGens() { return mod_->worldGens_; }
  69. const std::vector<EntityCollection::Factory> &entities() { return mod_->entities_; }
  70. std::unique_ptr<Mod> mod_;
  71. std::string path_;
  72. OS::Dynlib dynlib_;
  73. };
  74. }