mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-26 17:34:35 +02:00
Make the fps cap a per-view property
And have ui.fpsCap set only GameView's fps cap. This is the closest we'll be getting to the fps cap being true to its name (i.e. actually controlling frames per second, rather than ticks per second) with this iteration of the user interface. Also disable SRT if the sim is paused. Together, these changes fix some old problems such as non-sim user interfaces burning CPU for no reason when the fps cap is removed.
This commit is contained in:
@@ -8,7 +8,11 @@ struct FpsLimitExplicit
|
||||
{
|
||||
float value;
|
||||
};
|
||||
using FpsLimit = std::variant<FpsLimitNone, FpsLimitExplicit>;
|
||||
using SimFpsLimit = std::variant<FpsLimitNone, FpsLimitExplicit>;
|
||||
struct FpsLimitFollowDraw
|
||||
{
|
||||
};
|
||||
using FpsLimit = std::variant<FpsLimitNone, FpsLimitExplicit, FpsLimitFollowDraw>;
|
||||
|
||||
struct DrawLimitDisplay
|
||||
{
|
||||
|
@@ -477,6 +477,7 @@ void EngineProcess()
|
||||
EventProcess(event);
|
||||
}
|
||||
|
||||
std::optional<uint64_t> delay;
|
||||
{
|
||||
auto nowNs = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000);
|
||||
auto effectiveDrawLimit = engine.GetEffectiveDrawCap();
|
||||
@@ -485,10 +486,6 @@ void EngineProcess()
|
||||
engine.Tick();
|
||||
engine.Draw();
|
||||
drawSchedule.SetNow(nowNs);
|
||||
if (effectiveDrawLimit)
|
||||
{
|
||||
drawSchedule.Arm(float(*effectiveDrawLimit));
|
||||
}
|
||||
SDLSetScreen();
|
||||
blit(engine.g->Data());
|
||||
}
|
||||
@@ -496,14 +493,24 @@ void EngineProcess()
|
||||
{
|
||||
engine.SimTick();
|
||||
}
|
||||
}
|
||||
if (effectiveDrawLimit)
|
||||
{
|
||||
delay = drawSchedule.Arm(float(*effectiveDrawLimit)) / UINT64_C(1'000'000);
|
||||
}
|
||||
}
|
||||
auto fpsLimit = ui::Engine::Ref().GetFpsLimit();
|
||||
if (!std::holds_alternative<FpsLimitFollowDraw>(fpsLimit))
|
||||
{
|
||||
delay.reset();
|
||||
auto nowNs = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000);
|
||||
tickSchedule.SetNow(nowNs);
|
||||
if (auto *fpsLimitExplicit = std::get_if<FpsLimitExplicit>(&fpsLimit))
|
||||
{
|
||||
SDL_Delay(tickSchedule.Arm(fpsLimitExplicit->value) / UINT64_C(1'000'000));
|
||||
delay = tickSchedule.Arm(fpsLimitExplicit->value) / UINT64_C(1'000'000);
|
||||
}
|
||||
}
|
||||
if (delay.has_value())
|
||||
{
|
||||
SDL_Delay(std::max(*delay, UINT64_C(1)));
|
||||
}
|
||||
}
|
||||
|
@@ -970,6 +970,11 @@ void GameController::SetZoomPosition(ui::Point position)
|
||||
gameModel->SetZoomWindowPosition(zoomWindowPosition);
|
||||
}
|
||||
|
||||
bool GameController::GetPaused() const
|
||||
{
|
||||
return gameModel->GetPaused();
|
||||
}
|
||||
|
||||
void GameController::SetPaused(bool pauseState)
|
||||
{
|
||||
gameModel->SetPaused(pauseState);
|
||||
@@ -1730,7 +1735,7 @@ void GameController::AfterSimDraw()
|
||||
|
||||
bool GameController::ThreadedRenderingAllowed()
|
||||
{
|
||||
return gameModel->GetThreadedRendering() && !commandInterface->HaveSimGraphicsEventHandlers();
|
||||
return gameModel->GetThreadedRendering() && !GetPaused() && !commandInterface->HaveSimGraphicsEventHandlers();
|
||||
}
|
||||
|
||||
void GameController::SetToolIndex(ByteString identifier, std::optional<int> index)
|
||||
|
@@ -117,6 +117,7 @@ public:
|
||||
void CopyRegion(ui::Point point1, ui::Point point2);
|
||||
void CutRegion(ui::Point point1, ui::Point point2);
|
||||
void Update();
|
||||
bool GetPaused() const;
|
||||
void SetPaused(bool pauseState);
|
||||
void SetPaused();
|
||||
void SetDecoration(bool decorationState);
|
||||
|
@@ -1018,7 +1018,7 @@ void GameModel::SetPaused(bool pauseState)
|
||||
notifyPausedChanged();
|
||||
}
|
||||
|
||||
bool GameModel::GetPaused()
|
||||
bool GameModel::GetPaused() const
|
||||
{
|
||||
return sim->sys_pause?true:false;
|
||||
}
|
||||
|
@@ -237,7 +237,7 @@ public:
|
||||
void AddObserver(GameView * observer);
|
||||
|
||||
void SetPaused(bool pauseState);
|
||||
bool GetPaused();
|
||||
bool GetPaused() const;
|
||||
void SetDecoration(bool decorationState);
|
||||
bool GetDecoration();
|
||||
void SetAHeatEnable(bool aHeat);
|
||||
|
@@ -768,6 +768,7 @@ void GameView::NotifyUserChanged(GameModel * sender)
|
||||
void GameView::NotifyPausedChanged(GameModel * sender)
|
||||
{
|
||||
pauseButton->SetToggleState(sender->GetPaused());
|
||||
ApplySimFpsLimit();
|
||||
}
|
||||
|
||||
void GameView::NotifyToolTipChanged(GameModel * sender)
|
||||
@@ -2542,7 +2543,12 @@ void GameView::OnDraw()
|
||||
{
|
||||
//FPS and some version info
|
||||
StringBuilder fpsInfo;
|
||||
fpsInfo << Format::Precision(2) << "FPS: " << ui::Engine::Ref().GetFps();
|
||||
auto fps = 0.f;
|
||||
if (!c->GetPaused())
|
||||
{
|
||||
fps = ui::Engine::Ref().GetFps();
|
||||
}
|
||||
fpsInfo << Format::Precision(2) << "FPS: " << fps;
|
||||
|
||||
if (showDebug)
|
||||
{
|
||||
@@ -2563,14 +2569,13 @@ void GameView::OnDraw()
|
||||
{
|
||||
fpsInfo << "\nSimulation";
|
||||
fpsInfo << "\n FPS cap: ";
|
||||
auto fpsLimit = ui::Engine::Ref().GetFpsLimit();
|
||||
if (std::holds_alternative<FpsLimitNone>(fpsLimit))
|
||||
if (std::holds_alternative<FpsLimitNone>(simFpsLimit))
|
||||
{
|
||||
fpsInfo << "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
fpsInfo << std::get<FpsLimitExplicit>(fpsLimit).value;
|
||||
fpsInfo << std::get<FpsLimitExplicit>(simFpsLimit).value;
|
||||
}
|
||||
}
|
||||
if (c->GetDebugFlags() & DEBUG_RENHUD)
|
||||
@@ -2811,3 +2816,25 @@ void GameView::WaitForRendererThread()
|
||||
return !rendererThreadOwnsRenderer;
|
||||
});
|
||||
}
|
||||
|
||||
void GameView::ApplySimFpsLimit()
|
||||
{
|
||||
if (c->GetPaused())
|
||||
{
|
||||
SetFpsLimit(FpsLimitFollowDraw{});
|
||||
}
|
||||
else if (std::holds_alternative<FpsLimitNone>(simFpsLimit))
|
||||
{
|
||||
SetFpsLimit(FpsLimitNone{});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFpsLimit(std::get<FpsLimitExplicit>(simFpsLimit));
|
||||
}
|
||||
}
|
||||
|
||||
void GameView::SetSimFpsLimit(SimFpsLimit newSimFpsLimit)
|
||||
{
|
||||
simFpsLimit = newSimFpsLimit;
|
||||
ApplySimFpsLimit();
|
||||
}
|
||||
|
@@ -175,6 +175,9 @@ private:
|
||||
int foundParticles = 0;
|
||||
const RendererFrame *rendererFrame = nullptr;
|
||||
|
||||
SimFpsLimit simFpsLimit = FpsLimitExplicit{ 60.f };
|
||||
void ApplySimFpsLimit();
|
||||
|
||||
public:
|
||||
GameView();
|
||||
~GameView();
|
||||
@@ -278,4 +281,10 @@ public:
|
||||
|
||||
void RenderSimulation(const RenderableSimulation &sim, bool handleEvents);
|
||||
void AfterSimDraw(const RenderableSimulation &sim);
|
||||
|
||||
void SetSimFpsLimit(SimFpsLimit newSimFpsLimit);
|
||||
SimFpsLimit GetSimFpsLimit() const
|
||||
{
|
||||
return simFpsLimit;
|
||||
}
|
||||
};
|
||||
|
@@ -24,7 +24,6 @@ Engine::Engine():
|
||||
mousexp_(0),
|
||||
mouseyp_(0)
|
||||
{
|
||||
SetFpsLimit(FpsLimitExplicit{ 60.0f });
|
||||
}
|
||||
|
||||
Engine::~Engine()
|
||||
@@ -38,19 +37,9 @@ Engine::~Engine()
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::SetFpsLimit(FpsLimit newFpsLimit)
|
||||
void Engine::ApplyFpsLimit()
|
||||
{
|
||||
fpsLimit = newFpsLimit;
|
||||
::SetFpsLimit(fpsLimit);
|
||||
// Populate dt with whatever that makes any sort of sense.
|
||||
if (auto *explicitFpsLimit = std::get_if<FpsLimitExplicit>(&fpsLimit))
|
||||
{
|
||||
SetFps(explicitFpsLimit->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFps(1);
|
||||
}
|
||||
::SetFpsLimit(GetFpsLimit());
|
||||
}
|
||||
|
||||
void Engine::Begin()
|
||||
@@ -110,7 +99,7 @@ void Engine::ShowWindow(Window * window)
|
||||
state_->DoBlur();
|
||||
|
||||
state_ = window;
|
||||
|
||||
ApplyFpsLimit();
|
||||
}
|
||||
|
||||
void Engine::CloseWindowAndEverythingAbove(Window *window)
|
||||
@@ -153,11 +142,13 @@ int Engine::CloseWindow()
|
||||
mouseyp_ = mousey_;
|
||||
}
|
||||
ignoreEvents = true;
|
||||
ApplyFpsLimit();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state_ = nullptr;
|
||||
ApplyFpsLimit();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +170,7 @@ void Engine::Tick()
|
||||
{
|
||||
if(state_ != nullptr)
|
||||
{
|
||||
state_->DoTick(dt);
|
||||
state_->DoTick();
|
||||
state_->DoSimTick();
|
||||
}
|
||||
|
||||
@@ -241,19 +232,6 @@ void Engine::Draw()
|
||||
FrameIndex %= 7200;
|
||||
}
|
||||
|
||||
void Engine::SetFps(float fps)
|
||||
{
|
||||
this->fps = fps;
|
||||
if (std::holds_alternative<FpsLimitExplicit>(fpsLimit))
|
||||
{
|
||||
this->dt = 60/fps;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->dt = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::onKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
|
||||
{
|
||||
if (state_ && !ignoreEvents)
|
||||
@@ -396,3 +374,29 @@ std::optional<int> Engine::GetEffectiveDrawCap() const
|
||||
}
|
||||
return effectiveDrawCap;
|
||||
}
|
||||
|
||||
void Engine::SetFps(float newFps)
|
||||
{
|
||||
if (state_)
|
||||
{
|
||||
return state_->SetFps(newFps);
|
||||
}
|
||||
}
|
||||
|
||||
float Engine::GetFps() const
|
||||
{
|
||||
if (state_)
|
||||
{
|
||||
return state_->GetFps();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
FpsLimit Engine::GetFpsLimit() const
|
||||
{
|
||||
if (state_)
|
||||
{
|
||||
return state_->GetFpsLimit();
|
||||
}
|
||||
return FpsLimitNone{};
|
||||
}
|
||||
|
@@ -60,8 +60,8 @@ namespace ui
|
||||
void SimTick();
|
||||
void Draw();
|
||||
|
||||
void SetFps(float fps);
|
||||
inline float GetFps() { return fps; }
|
||||
void SetFps(float newFps);
|
||||
float GetFps() const;
|
||||
|
||||
inline int GetMouseButton() { return mouseb_; }
|
||||
inline int GetMouseX() { return mousex_; }
|
||||
@@ -75,11 +75,7 @@ namespace ui
|
||||
//inline State* GetState() { return state_; }
|
||||
inline Window* GetWindow() { return state_; }
|
||||
|
||||
void SetFpsLimit(FpsLimit newFpsLimit);
|
||||
FpsLimit GetFpsLimit() const
|
||||
{
|
||||
return fpsLimit;
|
||||
}
|
||||
FpsLimit GetFpsLimit() const;
|
||||
|
||||
DrawLimit drawingFrequencyLimit;
|
||||
Graphics * g;
|
||||
@@ -89,13 +85,11 @@ namespace ui
|
||||
|
||||
unsigned int FrameIndex;
|
||||
private:
|
||||
FpsLimit fpsLimit;
|
||||
|
||||
bool textInput = false;
|
||||
int lastTextEditingStart = INT_MAX;
|
||||
|
||||
float dt;
|
||||
float fps;
|
||||
void ApplyFpsLimit();
|
||||
std::deque<Window*> windows;
|
||||
std::stack<Point> mousePositions;
|
||||
//Window* statequeued_;
|
||||
|
@@ -26,6 +26,7 @@ Window::Window(Point _position, Point _size):
|
||||
destruct(false),
|
||||
stop(false)
|
||||
{
|
||||
SetFps(1);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
@@ -228,7 +229,7 @@ void Window::DoDraw()
|
||||
}
|
||||
}
|
||||
|
||||
void Window::DoTick(float dt)
|
||||
void Window::DoTick()
|
||||
{
|
||||
if (debugMode)
|
||||
return;
|
||||
@@ -610,3 +611,29 @@ void Window::Halt()
|
||||
halt = true;
|
||||
}
|
||||
|
||||
void Window::SetFps(float newFps)
|
||||
{
|
||||
fps = newFps;
|
||||
if (std::holds_alternative<FpsLimitExplicit>(fpsLimit))
|
||||
{
|
||||
dt = 60/fps;
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::SetFpsLimit(FpsLimit newFpsLimit)
|
||||
{
|
||||
fpsLimit = newFpsLimit;
|
||||
// Populate dt with whatever that makes any sort of sense.
|
||||
if (auto *explicitFpsLimit = std::get_if<FpsLimitExplicit>(&fpsLimit))
|
||||
{
|
||||
SetFps(explicitFpsLimit->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFps(1);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "common/String.h"
|
||||
#include "gui/interface/Point.h"
|
||||
#include "FpsLimit.h"
|
||||
#include <vector>
|
||||
|
||||
class Graphics;
|
||||
@@ -54,7 +55,7 @@ namespace ui
|
||||
|
||||
virtual void DoInitialized();
|
||||
virtual void DoExit();
|
||||
virtual void DoTick(float dt);
|
||||
virtual void DoTick();
|
||||
virtual void DoSimTick();
|
||||
virtual void DoDraw();
|
||||
virtual void DoFocus();
|
||||
@@ -85,6 +86,16 @@ namespace ui
|
||||
void MakeActiveWindow();
|
||||
void CloseActiveWindow();
|
||||
Graphics * GetGraphics();
|
||||
void SetFps(float newFps);
|
||||
float GetFps() const
|
||||
{
|
||||
return fps;
|
||||
}
|
||||
void SetFpsLimit(FpsLimit newFpsLimit);
|
||||
FpsLimit GetFpsLimit() const
|
||||
{
|
||||
return fpsLimit;
|
||||
}
|
||||
|
||||
protected:
|
||||
ui::Button * okayButton;
|
||||
@@ -122,5 +133,8 @@ namespace ui
|
||||
bool destruct;
|
||||
bool stop;
|
||||
|
||||
float dt;
|
||||
float fps;
|
||||
FpsLimit fpsLimit = FpsLimitFollowDraw{};
|
||||
};
|
||||
}
|
||||
|
@@ -197,10 +197,11 @@ static int debug(lua_State *L)
|
||||
|
||||
static int fpsCap(lua_State *L)
|
||||
{
|
||||
auto *lsi = GetLSI();
|
||||
int acount = lua_gettop(L);
|
||||
if (acount == 0)
|
||||
{
|
||||
auto fpsLimit = ui::Engine::Ref().GetFpsLimit();
|
||||
auto fpsLimit = lsi->window->GetSimFpsLimit();
|
||||
if (std::holds_alternative<FpsLimitNone>(fpsLimit))
|
||||
{
|
||||
lua_pushnumber(L, 2);
|
||||
@@ -218,10 +219,10 @@ static int fpsCap(lua_State *L)
|
||||
}
|
||||
if (fpscap == 2)
|
||||
{
|
||||
ui::Engine::Ref().SetFpsLimit(FpsLimitNone{});
|
||||
lsi->window->SetSimFpsLimit(FpsLimitNone{});
|
||||
return 0;
|
||||
}
|
||||
ui::Engine::Ref().SetFpsLimit(FpsLimitExplicit{ fpscap });
|
||||
lsi->window->SetSimFpsLimit(FpsLimitExplicit{ fpscap });
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -14,11 +14,7 @@ namespace http
|
||||
class Request;
|
||||
}
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Window;
|
||||
}
|
||||
|
||||
class GameView;
|
||||
class Graphics;
|
||||
class Renderer;
|
||||
class Simulation;
|
||||
@@ -82,7 +78,7 @@ public:
|
||||
|
||||
GameModel *gameModel;
|
||||
GameController *gameController;
|
||||
ui::Window *window;
|
||||
GameView *window;
|
||||
Simulation *sim;
|
||||
Graphics *g;
|
||||
|
||||
|
Reference in New Issue
Block a user