Program Listing for File Demeter.hpp

Return to documentation for file (gui/Demeter/Demeter.hpp)

#pragma once

#include <algorithm>
#include <array>
#include <memory>
#include <optional>
#include <unordered_map>
#include <vector>

#include "Renderer/Object3D.hpp"

#include "Entity.hpp"

namespace Dem {

  struct Demeter {
  private:
    std::unique_ptr<SDL2> sdl2;

    struct Time {
    private:
      Uint64 last;
      Uint64 current;
      double delta = 0;

    public:
      Time() = default;

      Time(const SDL2 &sdl2Instance)
        : last(sdl2Instance.GetTicks64()), current(last)
      {
      }

      void Update(const SDL2 &sdl2Instance);

      [[nodiscard]] Uint64 GetLast() const
      {
        return last;
      }

      [[nodiscard]] Uint64 GetCurrent() const
      {
        return current;
      }

      [[nodiscard]] double GetDelta() const
      {
        return delta;
      }
    } time;

    struct InputState {
      std::array<bool, SDL_NUM_SCANCODES> keys;
      int mouseX, mouseY;
      int mouseDeltaX, mouseDeltaY;
      std::array<bool, 5> mouseButtons;
    } input = {};

    std::vector<std::shared_ptr<IEntity>> entityPool;
    std::vector<std::shared_ptr<Texture>> texturePool;
    std::unordered_map<std::string, size_t> textureMap;
    std::vector<std::shared_ptr<Object3D>> objectPool;
    std::unordered_map<std::string, size_t> objectMap;
    std::unique_ptr<ShaderProgram> shader = std::make_unique<ShaderProgram>();
    bool isRunning;
    bool glDebug;
    bool isImGUIWindowCreated;

    static void DebugCallback(
      GLenum source,
      GLenum type,
      GLuint id,
      GLenum severity,
      GLsizei length,
      const GLchar *message,
      const void *userParam);

    void Update();

    void Draw();

    void HandleEvent();

  public:
    Camera camera;  // NOLINT

    Demeter() = default;
    ~Demeter() = default;

    [[nodiscard]] bool
    Init(std::unique_ptr<SDL2> renderer, bool activateDebug = false);

    [[nodiscard]] const InputState &GetInput() const
    {
      return input;
    }

    [[nodiscard]] const Time &GetTime() const
    {
      return time;
    }

    [[nodiscard]] const std::unique_ptr<ShaderProgram> &GetShader() const
    {
      return shader;
    }

    std::shared_ptr<IEntity> AddEntity(std::shared_ptr<IEntity> entity)
    {
      entityPool.push_back(std::move(entity));
      return entityPool.back();
    }

    std::shared_ptr<IEntity> GetEntity(size_t index) const
    {
      return entityPool.at(index);
    }

    void DeleteEntity(const std::shared_ptr<IEntity> &entity)
    {
      std::ranges::remove(entityPool, entity);
    }

    [[nodiscard]] std::shared_ptr<Texture> AddTexture(const std::string &path);

    void DeleteTexture(const std::string &path)
    {
      size_t index = textureMap[path];
      textureMap.erase(path);
      texturePool.erase(texturePool.begin() + index);
    }

    [[nodiscard]] std::optional<std::shared_ptr<Object3D>>
    AddObject3D(const std::string &path);

    void DeleteObject3D(const std::string &path)
    {
      size_t index = objectMap[path];
      objectMap.erase(path);
      objectPool.erase(objectPool.begin() + index);
    }

    void SetIsImGuiWindowCreated(bool isCreated)
    {
      isImGUIWindowCreated = isCreated;
    }

    void Run();
  };

}  // namespace Dem