Every thread-count change on the Mining tab saved settings.json and, with a miner running, stopped and restarted it: xmrig re-inits its RandomX dataset and reconnects to the pool, seconds of lost hashing each time. A drag across the grid did this once per tile crossed (up to ~24), with a "Starting pool miner" toast each; every -/+ click or Enter did it again. The tab now hands each pick to the App, which puts the newest in settings at once and applies it when the input settles: on drag release, or 0.5 s after the last click, even if the Mining tab was left in the meantime. The header, RAM estimate and tile fill still follow the drag live. - Pool: the restart is decided on the mining-control thread, after every earlier start or stop has run. It never starts a miner the user stopped, is a no-op when xmrig already runs at that count, and is no longer silently skipped when the pick lands in another restart's stop window (which left xmrig on the old count). - Solo: one setgenerate per gesture. A pick made while one is in flight now waits for it instead of being dropped (another stale count). - Clicking the tile that is already selected does nothing; it used to save settings and restart the miner. - With idle thread scaling on, the grid no longer snaps back to the old count while a pick is on its way to the miner. A pool auto-balance restart keeps a count still queued. - Idle thread scaling changes the pool count through the same retarget. Its correction after a start compares with the count last requested, not the xmrig API's lagging report, so it comes about 1 s in instead of after the first API report (3-5 s). - A retarget whose pool config no longer validates shows the same error and stops the miner, as the old stop-then-start did. - While a benchmark runs a pick is saved, but the miner change is dropped: the benchmark owns the count until it ends. A crash within 0.5 s of a pick, or mid-drag, loses that pick; every clean exit saves it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.1 KiB
C++
64 lines
2.1 KiB
C++
// DragonX Wallet - ImGui Edition
|
|
// Copyright 2024-2026 The Hush Developers
|
|
// Released under the GPLv3
|
|
|
|
#pragma once
|
|
|
|
// Coalesces mining thread-count picks. The Mining tab reports every intermediate value of a gesture (a tile
|
|
// drag crosses up to ~24 tiles; the -/+ stepper is clicked repeatedly); only the LAST one should reach the
|
|
// settings file and the miner, once, when the input settles: on drag release, or kDebounceSec after the
|
|
// last click. Pure: time is passed in; nothing here touches settings, the miner or ImGui.
|
|
|
|
namespace dragonx {
|
|
namespace services {
|
|
|
|
class MiningThreadCommit {
|
|
public:
|
|
static constexpr double kDebounceSec = 0.5;
|
|
|
|
// The user picked `threads` at `now` (seconds, any monotonic clock). Latest wins.
|
|
void select(int threads, double now)
|
|
{
|
|
target_ = threads;
|
|
pending_ = true;
|
|
due_ = now + kDebounceSec;
|
|
}
|
|
|
|
// The drag that produced the pending pick ended: it is due now, not after the debounce.
|
|
void release(double now)
|
|
{
|
|
if (pending_ && due_ > now) due_ = now;
|
|
}
|
|
|
|
void cancel() { pending_ = false; }
|
|
bool pending() const { return pending_; }
|
|
|
|
// Once per frame. `held`: a drag is still in progress (nothing commits until it ends). Returns true
|
|
// exactly once per settled pick and sets `out` to it.
|
|
bool take(double now, bool held, int& out)
|
|
{
|
|
if (!pending_ || held || now < due_) return false;
|
|
pending_ = false;
|
|
out = target_;
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
int target_ = 0;
|
|
bool pending_ = false;
|
|
double due_ = 0.0;
|
|
};
|
|
|
|
// The pool thread count a wanted count is compared with: the newest start/retarget posted (it includes a
|
|
// restart still queued on the mining-control thread), else the count the running xmrig was started with,
|
|
// else what its HTTP API last reported (that lags a restart by seconds, so it is only a last resort).
|
|
inline int effectivePoolThreads(int queuedTarget, int requested, int apiActive)
|
|
{
|
|
if (queuedTarget > 0) return queuedTarget;
|
|
if (requested > 0) return requested;
|
|
return apiActive;
|
|
}
|
|
|
|
} // namespace services
|
|
} // namespace dragonx
|