Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/engine/core/include/engine.hpp

369 lines
12 KiB
C++
Raw Normal View History

2020-08-11 12:07:21 -04:00
#pragma once
2020-09-21 09:37:52 -04:00
#include <nlohmann/json_fwd.hpp>
2020-08-11 12:07:21 -04:00
#include "object.hpp"
2020-09-21 09:37:52 -04:00
#include "cutscene.hpp"
2020-08-11 12:07:21 -04:00
#include "common.hpp"
2020-09-20 23:31:03 -04:00
#include "asset_types.hpp"
2020-09-21 09:37:52 -04:00
#include "platform.hpp"
#include "path.hpp"
2020-08-11 12:07:21 -04:00
class GFX;
2020-09-21 09:37:52 -04:00
class Scene;
class RenderTarget;
2020-09-21 09:37:52 -04:00
class Physics;
2020-08-11 12:07:21 -04:00
struct Timer;
namespace prism {
class app;
2021-04-20 10:37:56 -04:00
class imgui_backend;
class input_system;
class renderer;
struct AnimationTarget {
float current_time = 0.0f;
float animation_speed_modifier = 1.0f;
bool looping = false;
Object target = NullObject;
Animation animation;
};
/// The glue between app and systems such as the Renderer.
2021-04-19 12:23:18 -04:00
class engine {
public:
/**
Constructs an Engine with command line arguments. Can be accessed later from command_line_arguments.
@param argc Numer of arguments. Can be null.
@param argv Array of strings containing arguments. Can be null.
*/
2021-04-19 12:23:18 -04:00
engine(int argc, char* argv[]);
2021-04-19 12:23:18 -04:00
engine(const engine& other) = delete;
engine(engine&& other) = delete;
2021-04-19 12:23:18 -04:00
~engine();
/// Command line arguments, can be empty.
std::vector<std::string_view> command_line_arguments;
2021-04-19 12:35:52 -04:00
/** Sets the p_app object.
@param p_app The p_app object to set. Must not be null.
*/
2021-04-19 12:35:52 -04:00
void set_app(app* p_app);
/** Gets the current app object
@return The current app object. Can be null.
*/
[[nodiscard]] app* get_app() const;
/** Call to begin the next frame.
@param delta_time Delta time in seconds.
*/
void begin_frame(float delta_time);
/** Call to start updating the current frame.
@param delta_time Delta time in seconds.
*/
void update(float delta_time);
/** Call to begin rendering for a window.
@param index The index of the window to begin rendering for.
*/
void render(platform::window_ptr index);
void end_frame();
/// Pause updating.
void pause();
/// Resume updating.
void unpause();
/** Query the current pause state.
@return Whether or not the engine is currently paused.
*/
[[nodiscard]] bool is_paused() const;
/// Request to begin quitting immediately. This is not forced, and can be canceled by the user, platform, or app.
void quit();
/// Call right before the platform is about to quit the application, and requests the app or other systems to save work.
void prepare_quit();
/// Query whether or not the engine is in the process of quitting.
[[nodiscard]] bool is_quitting() const;
/** Set the GFX api to use.
2021-04-19 12:35:52 -04:00
@param p_gfx The GFX object to use. Must not be null.
*/
2021-04-19 12:35:52 -04:00
void set_gfx(GFX* p_gfx);
/** Get the current GFX api.
@return The current GFX api. Can be null.
*/
GFX* get_gfx();
/** Get the input system.
@return Instance of the input system. Will not be null.
*/
input_system* get_input();
/** Get the renderer for a window.
@param index Index of the window. Default is 0.
@return Instance of the renderer. Will not be null.
*/
renderer* get_renderer();
/** Get the physics system.
@return Instance of the physics system. Will not be null.
*/
Physics* get_physics();
/// Creates an empty scene with no path. This will change the current scene.
void create_empty_scene();
/** Load a scene from disk. This will change the current scene if successful.
@param path The scene file path.
@return Returns a instance of the scene is successful, and nullptr on failure.
*/
2021-05-12 09:05:56 -04:00
Scene* load_scene(const prism::path& path);
/** Save the current scene to disk.
@param path The absolute file path.
*/
void save_scene(std::string_view path);
/** Load a prefab from disk.
@param scene The scene to add the prefab to.
@param path The prefab file path.
@param override_name If not empty, the root object's new name. Defaulted to a empty string.
*/
2021-05-12 09:05:56 -04:00
Object add_prefab(Scene& scene, const prism::path& path, std::string_view override_name = "");
/** Save a tree of objects as a prefab to disk.
@param root The parent object to save as a prefab.
@param path The absolue file path.
*/
void save_prefab(Object root, std::string_view path);
/** Deserializes a animation channel from JSON.
@param j The animation channel json to deserialize.
@return An animation channel.
*/
AnimationChannel load_animation(nlohmann::json j);
/** Load an animation from disk.
@param path The animation file path.
@return An animation.
*/
2021-05-12 09:05:56 -04:00
Animation load_animation(const prism::path& path);
/** Load a cutscene from disk. This changes the current cutscene.
@param path The cutscene file path.
*/
2021-05-12 09:05:56 -04:00
void load_cutscene(const prism::path& path);
/** Saves the current cutscene to disk.
@param path The absolute file path.
*/
void save_cutscene(std::string_view path);
/** Adds the window for engine management.
@param native_handle The platform's native handle to it's window equivalent.
@param identifier The identifier of the new window.
@param extent The extent of the window.
*/
void add_window(void* native_handle, platform::window_ptr window, prism::Extent extent);
/** Removes the window from engine management. Should be called before the window is actually closed.
@param identifier The identifier of the window to remove.
*/
void remove_window(platform::window_ptr identifier);
platform::window_ptr get_main_window() {
return windows[0]->identifier;
}
/** Called when the window has changed size.
@param identifier The window that has been resized.
@param extent The new extent of the window.
*/
void resize(platform::window_ptr identifier, prism::Extent extent);
/** Called when the window has moved.
*
*/
void move(platform::window_ptr identifier);
/** Called when a key has been pressed.
@param keyCode A platform-specific key code.
@note Use platform::get_keycode to get a InputButton equivalent if needed.
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
*/
void process_key_down(unsigned int keyCode);
/** Called when a key has been released.
@param keyCode A platform-specific key code.
@note Use platform::get_keycode to get a InputButton equivalent if needed.
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
*/
void process_key_up(unsigned int keyCode);
/** Called when a mouse button has been clicked..
@param button The mouse button.
@param offset The mouse position relative to the window where the click occured.
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
*/
void process_mouse_down(int button, prism::Offset offset);
/**
* Called when text has been inputted. This is only emitted when text input is enabled thru input system
* @param string
*/
2021-10-14 08:51:58 -04:00
void process_text_input(std::string_view string);
/** Adds a timer to the list of timers.
@param timer The timer to add.
@note The timer instance is passed by reference. Use this to keep track of your timers without having to query it's state back.
*/
void add_timer(Timer& timer);
/** Gets the current scene.
@return The current scene if set, or nullptr if there isn't one.
*/
Scene* get_scene();
/** Get a scene by path. This does not change the current scene.
@param name The path to the scene file.
@return Returns a scene if it was previously loaded and found, or nullptr on failure.
*/
Scene* get_scene(std::string_view name);
/** Set the current scene.
@param scene The scene to set. Can be null.
*/
void set_current_scene(Scene* scene);
/** Get the current scene's path.
@return If a scene is loaded, the path to the scene. Can be an empty string if there is no scene loaded, or if it's an empty scene.
*/
[[nodiscard]] std::string_view get_scene_path() const;
/** Updates the Transform hierarchy for a scene.
@param scene The scene to update.
*/
void update_scene(Scene& scene);
2021-10-11 13:39:15 -04:00
imgui_backend& get_imgui() {
return *imgui;
}
/// The current cutscene.
std::unique_ptr<Cutscene> cutscene;
/// The current time in seconds for cutscene playback.
float current_cutscene_time = 0.0f;
/// The cutscene playback state.
bool play_cutscene = false;
/** Start playback of an animation.
@param animation The animation to play.
@param object The animation's target.
@param looping Whether or not the animation should loop or be discarded when finished. Default is false.
*/
void play_animation(Animation animation, Object target, bool looping = false);
/** Sets the animation speed of an object.
@param target The object you want to change the animation speed of.
@param modifier The speed to play the object's animations at. A modifier of 2.0 would be 2x the speed, and 0.5 would be 1/2x the speed.
*/
void set_animation_speed_modifier(Object target, float modifier);
/** Stops all animation for an object.
@param target The object you want the animations to stop for.
*/
void stop_animation(Object target);
/// If there is a render context available. If this is false, avoid doing any GFX or Renderer work as it could crash or cause undefined behavior.
bool render_ready = false;
/// If physics should upate. This is a control indepentent of the pause state.
bool update_physics = true;
2020-08-11 12:07:21 -04:00
// we enable the debug menu by default on tvOS and iOS since there's no easily accessible keybind
#if defined(PLATFORM_TVOS) || defined(PLATFORM_IOS)
bool debug_enabled = true;
2020-08-11 12:07:21 -04:00
#else
bool debug_enabled = false;
2020-08-11 12:07:21 -04:00
#endif
bool console_enabled = true;
private:
void setup_scene(Scene& scene);
void on_remove(Object object);
bool paused = false;
2020-08-11 12:07:21 -04:00
Scene* current_scene = nullptr;
std::vector<std::unique_ptr<Scene>> scenes;
std::map<std::string, Scene*> path_to_scene;
struct Window {
platform::window_ptr identifier = nullptr;
prism::Extent extent;
bool quit_requested = false;
RenderTarget* render_target = nullptr;
};
std::vector<Window*> windows;
Window* get_window(const platform::window_ptr identifier) {
for(auto& window : windows) {
if(window->identifier == identifier)
return window;
}
return nullptr;
2020-08-11 12:07:21 -04:00
}
void calculate_bone(Mesh& mesh, const Mesh::Part& part, Bone& bone, const Bone* parent_bone = nullptr);
void calculate_object(Scene& scene, Object object, Object parent_object = NullObject);
2020-08-11 12:07:21 -04:00
2021-04-19 12:35:52 -04:00
Shot* get_shot(float time) const;
void update_animation(const Animation& anim, float time);
void update_cutscene(float time);
2020-08-11 12:07:21 -04:00
void update_animation_channel(Scene& scene, const AnimationChannel& channel, float time);
2020-08-11 12:07:21 -04:00
app* current_app = nullptr;
GFX* gfx = nullptr;
2020-08-11 12:07:21 -04:00
std::unique_ptr<input_system> input;
std::unique_ptr<Physics> physics;
std::unique_ptr<renderer> current_renderer;
2020-08-11 12:07:21 -04:00
std::vector<Timer*> timers, timers_to_remove;
2020-08-11 12:07:21 -04:00
std::map<std::string, std::string> strings;
2020-08-11 12:07:21 -04:00
std::vector<AnimationTarget> animation_targets;
2020-08-11 12:07:21 -04:00
2021-04-20 10:37:56 -04:00
std::unique_ptr<imgui_backend> imgui;
2020-08-11 12:07:21 -04:00
const InputButton debug_button = InputButton::Q;
};
2020-08-11 12:07:21 -04:00
inline bool operator==(const AnimationTarget& a1, const AnimationTarget& a2) {
return a1.current_time == a2.current_time;
}
2020-08-11 12:07:21 -04:00
}
2021-04-19 12:23:18 -04:00
inline prism::engine* engine = nullptr;