3D优化完成

This commit is contained in:
2026-08-28 21:11:39 +08:00
parent 93d3f93774
commit 647ad6a66c
36 changed files with 1974 additions and 1548 deletions
@@ -38,21 +38,6 @@ Nanoseconds fps_period(double fps) {
struct Frame_Scheduler::Timer::State {
enum struct Mode : std::uint8_t { stopped, once, periodic };
not_null<Frame_Scheduler::Private*> owner;
std::uint64_t id{};
Handler handler{};
std::atomic_bool alive{true};
Mode mode{Mode::stopped}; /* 仅 Scheduler thread 访问。 */
Nanoseconds period{}; /* 仅 Scheduler thread 访问。 */
Scheduler_Clock::time_point next_deadline{}; /* 真实 deadline,不按 tick 累积。 */
TimerEvent<std::function<void()>> event;
State(not_null<Frame_Scheduler::Private*> value_owner,
std::uint64_t value_id,
Handler value_handler);
};
struct Frame_Scheduler::Private {
enum struct Command_Type : std::uint8_t {
periodic,
once,
@@ -62,14 +47,48 @@ struct Frame_Scheduler::Private {
};
struct Command {
Command_Type type{};
std::shared_ptr<Timer::State> state{};
std::shared_ptr<State> state{};
Nanoseconds value{};
};
struct Command_Ingress {
moodycamel::BlockingConcurrentQueue<Command> commands{256};
std::atomic_bool accepting{true};
[[nodiscard]] bool enqueue(Command command) {
if (command.type != Command_Type::destroy &&
command.type != Command_Type::stop &&
!accepting.load(std::memory_order_acquire))
return false;
return commands.enqueue(std::move(command));
}
};
not_null<Frame_Scheduler::Private*> owner;
std::weak_ptr<Command_Ingress> ingress;
std::uint64_t id{};
Handler handler{};
std::atomic_bool alive{true};
Mode mode{Mode::stopped}; /* 仅 Scheduler thread 访问。 */
Nanoseconds period{}; /* 仅 Scheduler thread 访问。 */
Scheduler_Clock::time_point next_deadline{}; /* 真实 deadline,不按 tick 累积。 */
TimerEvent<std::function<void()>> event;
State(not_null<Frame_Scheduler::Private*> value_owner,
const std::shared_ptr<Command_Ingress>& value_ingress,
std::uint64_t value_id,
Handler value_handler);
};
struct Frame_Scheduler::Private {
using Command_Type = Timer::State::Command_Type;
using Command = Timer::State::Command;
using Command_Ingress = Timer::State::Command_Ingress;
std::shared_ptr<Command_Ingress> ingress{
std::make_shared<Command_Ingress>()};
TimerWheel wheel{};
Scheduler_Clock::time_point origin{Scheduler_Clock::now()};
Scheduler_Clock::time_point last_advance{origin};
moodycamel::BlockingConcurrentQueue<Command> commands{256};
std::atomic_uint64_t next_id{1};
std::atomic_bool stopping{};
std::jthread thread{};
@@ -77,19 +96,21 @@ struct Frame_Scheduler::Private {
Private() : thread([this](std::stop_token stop) { run(stop); }) {}
~Private() {
ingress->accepting.store(false, std::memory_order_release);
stopping.store(true, std::memory_order_release);
thread.request_stop();
enqueue({Command_Type::stop});
}
void enqueue(Command command) {
if (!commands.enqueue(std::move(command))) std::terminate();
if (!ingress->enqueue(std::move(command))) std::terminate();
}
std::shared_ptr<Timer::State> make_timer(Handler handler) {
if (!handler) throw std::invalid_argument("frame scheduler timer handler is empty");
const auto id = next_id.fetch_add(1, std::memory_order_relaxed);
auto state = std::make_shared<Timer::State>(this, id, std::move(handler));
auto state = std::make_shared<Timer::State>(
this, ingress, id, std::move(handler));
return state;
}
@@ -152,7 +173,7 @@ struct Frame_Scheduler::Private {
void process_commands(Scheduler_Clock::time_point now) {
Command command;
while (commands.try_dequeue(command)) {
while (ingress->commands.try_dequeue(command)) {
process_command(std::move(command), now);
now = Scheduler_Clock::now();
}
@@ -221,7 +242,7 @@ struct Frame_Scheduler::Private {
const auto deadline = last_advance +
Frame_Scheduler::tick_duration * static_cast<std::int64_t>(next);
Command command;
if (commands.wait_dequeue_timed(
if (ingress->commands.wait_dequeue_timed(
command, std::max(deadline - Scheduler_Clock::now(),
Scheduler_Clock::duration::zero())))
process_command(std::move(command), Scheduler_Clock::now());
@@ -234,9 +255,12 @@ struct Frame_Scheduler::Private {
};
Frame_Scheduler::Timer::State::State(
not_null<Frame_Scheduler::Private*> value_owner, std::uint64_t value_id,
not_null<Frame_Scheduler::Private*> value_owner,
const std::shared_ptr<Command_Ingress>& value_ingress,
std::uint64_t value_id,
Handler value_handler)
: owner(value_owner), id(value_id), handler(std::move(value_handler)),
: owner(value_owner), ingress(value_ingress), id(value_id),
handler(std::move(value_handler)),
event([this] {
owner->fire(*this);
}) {}
@@ -259,7 +283,10 @@ Frame_Scheduler::Timer::Timer(std::shared_ptr<State> state) noexcept
Frame_Scheduler::Timer::~Timer() noexcept {
if (!state_) return;
state_->alive.store(false, std::memory_order_release);
state_->owner->enqueue({Private::Command_Type::destroy, state_, {}});
const auto ingress = state_->ingress.lock();
if (ingress && !ingress->enqueue(
{Private::Command_Type::destroy, state_, {}}))
std::terminate();
}
Frame_Scheduler::Timer::Timer(Timer&& other) noexcept
@@ -279,19 +306,31 @@ void Frame_Scheduler::Timer::start_periodic(double fps) {
return;
}
state_->alive.store(true, std::memory_order_release);
state_->owner->enqueue({Private::Command_Type::periodic, state_, fps_period(fps)});
const auto ingress = state_->ingress.lock();
if (!ingress || !ingress->enqueue(
{Private::Command_Type::periodic, state_, fps_period(fps)})) {
state_->alive.store(false, std::memory_order_release);
throw std::runtime_error("frame scheduler is stopping");
}
}
void Frame_Scheduler::Timer::start_once(std::chrono::nanoseconds delay) {
if (!state_) throw std::logic_error("frame scheduler timer is empty");
state_->alive.store(true, std::memory_order_release);
state_->owner->enqueue({Private::Command_Type::once, state_, delay});
const auto ingress = state_->ingress.lock();
if (!ingress || !ingress->enqueue(
{Private::Command_Type::once, state_, delay})) {
state_->alive.store(false, std::memory_order_release);
throw std::runtime_error("frame scheduler is stopping");
}
}
void Frame_Scheduler::Timer::cancel() noexcept {
if (!state_ || !state_->owner) return;
if (!state_) return;
state_->alive.store(false, std::memory_order_release);
state_->owner->enqueue({Private::Command_Type::cancel, state_, {}});
const auto ingress = state_->ingress.lock();
if (ingress) static_cast<void>(ingress->enqueue(
{Private::Command_Type::cancel, state_, {}}));
}
bool Frame_Scheduler::Timer::valid() const noexcept {