Initial commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
#include "global.h"
|
||||
|
||||
template <typename Mutex_Type = std::mutex>
|
||||
class Frequency_Limit_T {
|
||||
public:
|
||||
explicit Frequency_Limit_T(double times_per_second = 1.0)
|
||||
: interval(1.0 / times_per_second),
|
||||
last(std::chrono::steady_clock::now())
|
||||
{}
|
||||
|
||||
bool test() {
|
||||
using namespace std::chrono;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
auto now = steady_clock::now();
|
||||
double dt = duration_cast<microseconds>(now - last).count() * 1e-6;
|
||||
|
||||
if (dt >= interval) {
|
||||
last = now;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
double interval;
|
||||
std::chrono::steady_clock::time_point last;
|
||||
Mutex_Type mtx;
|
||||
};
|
||||
using Frequency_Limit_ST = Frequency_Limit_T<Psc::Empty_Lock>;
|
||||
using Frequency_Limit = Frequency_Limit_T<std::mutex>;
|
||||
|
||||
|
||||
|
||||
template <typename Mutex_Type = std::mutex>
|
||||
class Frequency_Limit_Multi_T {
|
||||
public:
|
||||
explicit Frequency_Limit_Multi_T(double default_times_per_second = 1.0)
|
||||
: default_interval_(1.0 / default_times_per_second) {}
|
||||
|
||||
// 单个类型的状态
|
||||
struct Type_Info {
|
||||
double interval{}; // 秒
|
||||
std::chrono::steady_clock::time_point last;
|
||||
};
|
||||
|
||||
// 设置某个类型的频率
|
||||
void set_rate(const std::string& type, double times_per_second) {
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
map_[type].interval = 1.0 / times_per_second;
|
||||
// 注意:不重置 last,避免突发放行
|
||||
}
|
||||
|
||||
// 测试是否允许执行
|
||||
bool test(const std::string& type) {
|
||||
using namespace std::chrono;
|
||||
|
||||
const auto now = steady_clock::now();
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
auto& info = map_[type];
|
||||
|
||||
// 第一次使用该 type
|
||||
if (info.interval == 0.0) {
|
||||
info.interval = default_interval_;
|
||||
info.last = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
const double dt =
|
||||
duration_cast<duration<double>>(now - info.last).count();
|
||||
|
||||
if (dt >= info.interval) {
|
||||
info.last = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
double default_interval_;
|
||||
std::map<std::string, Type_Info> map_;
|
||||
Mutex_Type mtx_;
|
||||
};
|
||||
|
||||
using Frequency_Limit_Multi_ST = Frequency_Limit_Multi_T<Psc::Empty_Lock>;
|
||||
using Frequency_Limit_Multi = Frequency_Limit_Multi_T<std::mutex>;
|
||||
Reference in New Issue
Block a user