ICT290 / src / engine / stateManager.h
stateManager.h
Raw
#pragma once
#include <map>
#include <memory>
#include <stack>
#include "../glIncludes.h"
#include "audio.h"
#include "camera.h"
#include "light.h"
#include "resources.h"
#include "skybox.h"

typedef void (*fnPtr)();
typedef void (*fnPtrBool)(bool);
typedef void (*fnPtrEvent)(SDL_Event&);
typedef void (*fnPtrFloat)(float);

/**
 * @struct State
 * @brief Used to associate game logic to the main game loop, allowing for
 * multiple definitions of each function to be implemented.
 *
 * @author Chase Percy
 *
 */
struct State {
    fnPtr draw{nullptr};               /// Draw function
    fnPtrEvent handleEvents{nullptr};  /// Function to handle SDL events
    fnPtr destroy{nullptr};            /// Function to destroy a scenes assets
    fnPtrBool pause{nullptr};          /// Function to set pause flag
    fnPtrFloat update{nullptr};        /// Update function, receives delta time
    std::shared_ptr<State> newState{nullptr};  /// The new state to set
    bool stop{false};  /// Set true to stop and pop the state
    Camera_ camera{};  /// The primary camera for a state
    std::multimap<std::string, Object> objects;  /// The objects for the state
    Skybox skybox;                               /// The skybox for the state
    AudioManager audioManager;  /// The audio manager for the state
    Resources& resources;       /// The resources for the state
    Light lights[8];            /// The lights for the state

    /**
     * Constructor for state objects. All Function Pointers should be set
     * during construction.
     * @param draw_ the draw function pointer, void draw()
     * @param handleEvents_ the event handler function pointer, void
     * handleEvents(SDL_Event&)
     * @param destroy_ the destroy function pointer, void destroy()
     * @param pause_ the pause function pointer, void pause(bool)
     * @param update_ the update function pointer, void update()
     * @param shutdown_ the shutdown function pointer, bool shutdown()
     */
    State(fnPtr draw_,
          fnPtrEvent handleEvents_,
          fnPtr destroy_,
          fnPtrBool pause_,
          fnPtrFloat update_,
          Resources& resources_)
        : draw(draw_),
          handleEvents(handleEvents_),
          destroy(destroy_),
          pause(pause_),
          update(update_),
          resources(resources_) {
        for (short i = 0; i < 8; ++i) {
            lights[i] = Light{i, 0, 0, 0};
        }
    }
};

/**
 * @class StateManager
 * @brief Handles all the logic regarding states and calling appropriate
 * functions when they are swapped. Stores all states in a stack and performs
 * extra logic when returning the top struct to check the current status of the
 * state it's returning.
 *
 * @author Chase Percy
 *
 */
class StateManager {
   public:
    /**
     * Push a new state onto the stack
     */
    void push(const std::shared_ptr<State>& state);

    /**
     * Pop the top state off the stack
     */
    void pop();

    /**
     * Return the top state. If a state has initiated shutdown it is stopped and
     * popped from the top of the stack. If stack is empty nullptr is returned.
     */
    std::shared_ptr<State> top();

   private:
    std::stack<std::shared_ptr<State>> m_states;  /// State stack
};