diff --git a/example/main.c b/example/main.c index ee817bb..57d9c94 100644 --- a/example/main.c +++ b/example/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2024/01/18 09:58:15 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 15:23:35 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -133,6 +133,8 @@ int main(void) mlx.mlx = mlx_init(); mlx.win = mlx_new_window(mlx.mlx, 400, 400, "My window"); + mlx_set_fps_goal(mlx.mlx, 60); + mlx_on_event(mlx.mlx, mlx.win, MLX_KEYDOWN, key_hook, &mlx); mlx_on_event(mlx.mlx, mlx.win, MLX_WINDOW_EVENT, window_hook, &mlx); diff --git a/includes/mlx.h b/includes/mlx.h index 809058a..14e4a0e 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2024/01/18 09:55:36 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 14:36:12 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -360,6 +360,17 @@ MLX_API int mlx_destroy_display(void* mlx); */ MLX_API int mlx_get_screens_size(void* mlx, void* win, int* w, int* h); + +/** + * @brief Caps the FPS + * + * @param mlx Internal MLX application + * @param fps The FPS cap + * + * @return (int) Always return 0 + */ +MLX_API int mlx_set_fps_goal(void* mlx, int fps); + #ifdef __cplusplus } #endif diff --git a/src/core/application.cpp b/src/core/application.cpp index cd33ee8..b8a02f7 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2024/01/18 09:44:26 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 15:19:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,8 +24,9 @@ namespace mlx::core { static bool __drop_sdl_responsability = false; - Application::Application() : _in(std::make_unique()) + Application::Application() : _fps(), _in(std::make_unique()) { + _fps.init(); __drop_sdl_responsability = SDL_WasInit(SDL_INIT_VIDEO); if(__drop_sdl_responsability) // is case the mlx is running in a sandbox like MacroUnitTester where SDL is already init return; @@ -38,6 +39,8 @@ namespace mlx::core { while(_in->is_running()) { + if(!_fps.update()) + continue; _in->update(); if(_loop_hook) diff --git a/src/core/application.h b/src/core/application.h index fee2c33..a4bb649 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ -/* Updated: 2024/01/18 09:56:04 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 14:59:47 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,6 +26,7 @@ #include #include #include +#include namespace mlx::core { @@ -41,6 +42,8 @@ namespace mlx::core inline void getScreenSize(void* win, int* w, int* h) noexcept; + inline void setFPSCap(uint32_t fps) noexcept; + inline void* newGraphicsSuport(std::size_t w, std::size_t h, const char* title); inline void clearGraphicsSupport(void* win); inline void destroyGraphicsSupport(void* win); @@ -65,6 +68,7 @@ namespace mlx::core ~Application(); private: + FpsManager _fps; std::list _textures; std::vector> _graphics; std::function _loop_hook; diff --git a/src/core/application.inl b/src/core/application.inl index 9b27349..dbc2f5c 100644 --- a/src/core/application.inl +++ b/src/core/application.inl @@ -64,6 +64,11 @@ namespace mlx::core *h = DM.h; } + void Application::setFPSCap(uint32_t fps) noexcept + { + _fps.setMaxFPS(fps); + } + void* Application::newGraphicsSuport(std::size_t w, std::size_t h, const char* title) { MLX_PROFILE_FUNCTION(); diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index 5e7b962..e714b6b 100644 --- a/src/core/bridge.cpp +++ b/src/core/bridge.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2024/01/18 09:55:53 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 15:02:06 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -277,4 +277,21 @@ extern "C" static_cast(mlx)->getScreenSize(win, w, h); return 0; } + + int mlx_set_fps_goal(void* mlx, int fps) + { + MLX_CHECK_APPLICATION_POINTER(mlx); + if(fps < 0) + { + mlx::core::error::report(e_kind::error, "You cannot set a negative FPS cap (nice try)"); + fps = -fps; + } + if(fps == 0) + { + mlx::core::error::report(e_kind::error, "You cannot set a FPS cap to 0 (nice try)"); + return 0; + } + static_cast(mlx)->setFPSCap(static_cast(fps)); + return 0; + } } diff --git a/src/core/fps.cpp b/src/core/fps.cpp new file mode 100644 index 0000000..db76414 --- /dev/null +++ b/src/core/fps.cpp @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fps.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/18 14:56:17 by maldavid #+# #+# */ +/* Updated: 2024/01/18 15:20:03 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +namespace mlx +{ + void FpsManager::init() + { + _timer = SDL_GetTicks64(); + _fps_before = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); + _fps_now = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); + } + + bool FpsManager::update() + { + using namespace std::chrono_literals; + _fps_now = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); + + if(SDL_GetTicks64() - _timer > 1000) + _timer += 1000; + + _fps_elapsed_time = _fps_now - _fps_before; + if(_fps_elapsed_time >= _ns) + { + _fps_before += _ns; + return true; + } + std::this_thread::sleep_for(std::chrono::duration(_ns)); + return false; + } +} diff --git a/src/core/fps.h b/src/core/fps.h new file mode 100644 index 0000000..80f25db --- /dev/null +++ b/src/core/fps.h @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fps.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/18 14:53:30 by maldavid #+# #+# */ +/* Updated: 2024/01/18 15:16:06 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_FPS__ +#define __MLX_FPS__ + +#include + +namespace mlx +{ + class FpsManager + { + public: + FpsManager() = default; + + void init(); + bool update(); + inline void setMaxFPS(uint32_t fps) noexcept { _max_fps = fps; _ns = 1000000000.0 / fps; } + + ~FpsManager() = default; + + private: + double _ns = 1000000000.0 / 1'337'000.0; + uint64_t _timer = 0; + uint64_t _fps_before = 0; + uint64_t _fps_now = 0; + uint32_t _max_fps = 1'337'000; + uint32_t _fps_elapsed_time = 0; + }; +} + +#endif