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.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #pragma once
  2. #include <stdint.h>
  3. #include <string>
  4. #include <vector>
  5. #include <memory>
  6. #include <type_traits>
  7. #include <SDL2/SDL.h>
  8. #include "Tile.h"
  9. #include "Item.h"
  10. #include "WorldGen.h"
  11. #include "Entity.h"
  12. #include "Collection.h"
  13. #include "Resource.h"
  14. #include "OS.h"
  15. #include "util.h"
  16. namespace Swan {
  17. class Mod {
  18. public:
  19. Mod(std::string name): name_(std::move(name)) {}
  20. virtual ~Mod() = default;
  21. void registerImage(const std::string &id);
  22. void registerTile(Tile::Builder tile);
  23. void registerItem(Item::Builder item);
  24. void registerWorldGen(const std::string &name, std::unique_ptr<WorldGen::Factory> gen);
  25. template<typename WG>
  26. void registerWorldGen(const std::string &name) {
  27. worldgens_.push_back(WorldGen::Factory{
  28. .name = name_ + "::" + name,
  29. .create = [](World &world) -> std::unique_ptr<WorldGen> {
  30. return std::make_unique<WG>(world);
  31. }
  32. });
  33. }
  34. template<typename Ent>
  35. void registerEntity(const std::string &name) {
  36. static_assert(
  37. std::is_move_constructible_v<Ent>,
  38. "Entities must be movable");
  39. entities_.push_back(EntityCollection::Factory{
  40. .name = name_ + "::" + name,
  41. .create = [](std::string name) -> std::unique_ptr<EntityCollection> {
  42. return std::make_unique<EntityCollectionImpl<Ent>>(std::move(name));
  43. }
  44. });
  45. }
  46. const std::string name_;
  47. std::vector<std::string> images_;
  48. std::vector<Tile::Builder> tiles_;
  49. std::vector<Item::Builder> items_;
  50. std::vector<WorldGen::Factory> worldgens_;
  51. std::vector<EntityCollection::Factory> entities_;
  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. Iter<std::unique_ptr<ImageResource>> buildImages(SDL_Renderer *renderer);
  64. Iter<std::unique_ptr<Tile>> buildTiles(const ResourceManager &resources);
  65. Iter<std::unique_ptr<Item>> buildItems(const ResourceManager &resources);
  66. Iter<WorldGen::Factory> getWorldGens();
  67. Iter<EntityCollection::Factory> getEntities();
  68. std::unique_ptr<Mod> mod_;
  69. std::string path_;
  70. OS::Dynlib dynlib_;
  71. };
  72. }