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

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