forked from Siv3D/OpenSiv3D
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
302 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
//----------------------------------------------- | ||
// | ||
// This file is part of the Siv3D Engine. | ||
// | ||
// Copyright (c) 2008-2023 Ryo Suzuki | ||
// Copyright (c) 2016-2023 OpenSiv3D Project | ||
// | ||
// Licensed under the MIT License. | ||
// | ||
//----------------------------------------------- | ||
|
||
# pragma once | ||
# include "IFrameRateLimit.hpp" | ||
|
||
namespace s3d | ||
{ | ||
class CFrameRateLimit final : public ISiv3DFrameRateLimit | ||
{ | ||
public: | ||
|
||
using clock_type = std::chrono::steady_clock; | ||
|
||
/// @brief フレームレート制限を実行します。 | ||
void update() override; | ||
|
||
/// @brief 目標フレームレートを設定します。 | ||
/// @param fps 目標フレームレート(FPS)。フレームレート制限を無効にする場合は none | ||
void setTargetFrameRate(const Optional<double>& fps) override; | ||
|
||
/// @brief 目標フレームレートを取得します。 | ||
/// @return 目標フレームレート(FPS)。フレームレート制限が無効の場合は none | ||
SIV3D_NODISCARD_CXX20 | ||
Optional<double> getTargetFrameRate() const override; | ||
|
||
private: | ||
|
||
class Limiter | ||
{ | ||
public: | ||
|
||
/// @brief コンストラクタ | ||
/// @param fps 目標フレームレート(FPS) | ||
/// @throw Error fps が無効な値の場合 | ||
SIV3D_NODISCARD_CXX20 | ||
explicit Limiter(double fps); | ||
|
||
/// @brief sleepを実行し、フレームを次に進めます。 | ||
void doSleep(); | ||
|
||
/// @brief 目標フレームレートを設定します。 | ||
/// @param targetFrameRate 目標フレームレート(FPS) | ||
/// @throw Error fps が無効な値の場合 | ||
void setTargetFrameRate(double fps); | ||
|
||
/// @brief 目標フレームレートを取得します。 | ||
/// @return 目標フレームレート(FPS) | ||
SIV3D_NODISCARD_CXX20 | ||
double getTargetFrameRate() const noexcept { return m_fps; } | ||
|
||
private: | ||
|
||
/// @brief 1秒間 | ||
static constexpr clock_type::duration OneSecond = std::chrono::seconds{ 1 }; | ||
|
||
/// @brief 目標フレームレート(FPS) | ||
double m_fps; | ||
|
||
/// @brief 1フレームあたりの時間 | ||
clock_type::duration m_oneFrameDuration; | ||
|
||
/// @brief 目標sleep時刻 | ||
clock_type::time_point m_sleepUntil; | ||
|
||
/// @brief フレームレートから1フレームあたりの時間の長さを計算します。 | ||
/// @param fps フレームレート(FPS) | ||
/// @return 1フレームあたりの時間の長さ | ||
/// @throw Error fps が無効な値の場合 | ||
SIV3D_NODISCARD_CXX20 | ||
static clock_type::duration FPSToOneFrameDuration(double fps); | ||
}; | ||
|
||
/// @brief フレームレート制限 | ||
/// @remark フレームレート制限が無効の場合は nullptr | ||
std::unique_ptr<Limiter> m_limiter; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//----------------------------------------------- | ||
// | ||
// This file is part of the Siv3D Engine. | ||
// | ||
// Copyright (c) 2008-2023 Ryo Suzuki | ||
// Copyright (c) 2016-2023 OpenSiv3D Project | ||
// | ||
// Licensed under the MIT License. | ||
// | ||
//----------------------------------------------- | ||
|
||
# include "CFrameRateLimit.hpp" | ||
|
||
namespace s3d | ||
{ | ||
ISiv3DFrameRateLimit* ISiv3DFrameRateLimit::Create() | ||
{ | ||
return new CFrameRateLimit; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//----------------------------------------------- | ||
// | ||
// This file is part of the Siv3D Engine. | ||
// | ||
// Copyright (c) 2008-2023 Ryo Suzuki | ||
// Copyright (c) 2016-2023 OpenSiv3D Project | ||
// | ||
// Licensed under the MIT License. | ||
// | ||
//----------------------------------------------- | ||
|
||
# pragma once | ||
# include <Siv3D/Common.hpp> | ||
# include <Siv3D/Optional.hpp> | ||
|
||
namespace s3d | ||
{ | ||
class SIV3D_NOVTABLE ISiv3DFrameRateLimit | ||
{ | ||
public: | ||
|
||
static ISiv3DFrameRateLimit* Create(); | ||
|
||
virtual ~ISiv3DFrameRateLimit() = default; | ||
|
||
virtual void update() = 0; | ||
|
||
virtual void setTargetFrameRate(const Optional<double>& fps) = 0; | ||
|
||
virtual Optional<double> getTargetFrameRate() const = 0; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//----------------------------------------------- | ||
// | ||
// This file is part of the Siv3D Engine. | ||
// | ||
// Copyright (c) 2008-2023 Ryo Suzuki | ||
// Copyright (c) 2016-2023 OpenSiv3D Project | ||
// | ||
// Licensed under the MIT License. | ||
// | ||
//----------------------------------------------- | ||
|
||
# include "CFrameRateLimit.hpp" | ||
# include "Siv3D/Graphics.hpp" | ||
# include "Siv3D/Error.hpp" | ||
# include "Siv3D/Duration.hpp" | ||
|
||
namespace s3d | ||
{ | ||
void CFrameRateLimit::update() | ||
{ | ||
if (Graphics::IsVSyncEnabled()) | ||
{ | ||
// VSync が有効の場合はフレームレート制限を無視 | ||
return; | ||
} | ||
|
||
if (not m_limiter) | ||
{ | ||
// フレームレート制限が無効の場合は何もしない | ||
return; | ||
} | ||
|
||
m_limiter->doSleep(); | ||
} | ||
|
||
void CFrameRateLimit::setTargetFrameRate(const Optional<double>& fps) | ||
{ | ||
if (not fps) | ||
{ | ||
// フレームレート制限を無効化 | ||
m_limiter.reset(); | ||
return; | ||
} | ||
|
||
if (m_limiter) | ||
{ | ||
// 既にフレームレート制限が有効の場合は目標フレームレートを設定 | ||
m_limiter->setTargetFrameRate(*fps); | ||
} | ||
else | ||
{ | ||
// フレームレート制限を有効化 | ||
m_limiter = std::make_unique<Limiter>(*fps); | ||
} | ||
} | ||
|
||
Optional<double> CFrameRateLimit::getTargetFrameRate() const | ||
{ | ||
if (m_limiter) | ||
{ | ||
return m_limiter->getTargetFrameRate(); | ||
} | ||
else | ||
{ | ||
return none; | ||
} | ||
} | ||
|
||
CFrameRateLimit::Limiter::Limiter(double fps) | ||
: m_fps(fps) | ||
, m_oneFrameDuration(FPSToOneFrameDuration(fps)) | ||
, m_sleepUntil(clock_type::now()) | ||
{ | ||
} | ||
|
||
void CFrameRateLimit::Limiter::doSleep() | ||
{ | ||
const auto now = clock_type::now(); | ||
const auto sleepUntil = Max(m_sleepUntil + m_oneFrameDuration, now); | ||
|
||
if (now < sleepUntil) | ||
{ | ||
std::this_thread::sleep_until(sleepUntil); | ||
} | ||
|
||
m_sleepUntil = sleepUntil; | ||
} | ||
|
||
void CFrameRateLimit::Limiter::setTargetFrameRate(double fps) | ||
{ | ||
m_fps = fps; | ||
m_oneFrameDuration = FPSToOneFrameDuration(fps); | ||
|
||
// setTargetFrameRate が毎フレーム呼び出された場合に sleep 時間に誤差が生じないよう, | ||
// m_sleepUntil はここでは更新しない | ||
} | ||
|
||
CFrameRateLimit::clock_type::duration CFrameRateLimit::Limiter::FPSToOneFrameDuration(double fps) | ||
{ | ||
if (fps <= 0.0) | ||
{ | ||
throw Error{ U"FrameRateLimit::Limiter::FPSToOneFrameDuration(): Invalid fps" }; | ||
} | ||
|
||
return DurationCast<clock_type::duration>(OneSecond / fps); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.