58f5d7c72e
* Update _TerminalCursorPositionChanged to use ThrottledFunc. * Rename previous ThrottledFunc to ThrottledArgFunc because now ThrottledFunc is for functions that do not take an argument. * Update ThrottledFunc and ThrottledArgFunc to accept a CoreDispatcher on which the function should be called for convenience. * Don't use coroutines/winrt::fire_and_forget in ThrottledFunc/ThrottledArgFunc because they are too slow (see PR). _AdjustCursorPosition went from 17% of samples to 3% in performance testing.
55 lines
1.5 KiB
C++
55 lines
1.5 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "pch.h"
|
|
|
|
#include "ThrottledFunc.h"
|
|
|
|
using namespace winrt::Windows::Foundation;
|
|
using namespace winrt::Windows::UI::Core;
|
|
using namespace winrt::Windows::UI::Xaml;
|
|
|
|
ThrottledFunc<>::ThrottledFunc(ThrottledFunc::Func func, TimeSpan delay, CoreDispatcher dispatcher) :
|
|
_func{ func },
|
|
_delay{ delay },
|
|
_dispatcher{ dispatcher },
|
|
_isRunPending{}
|
|
{
|
|
}
|
|
|
|
// Method Description:
|
|
// - Runs the function later, except if `Run` is called again before
|
|
// with a new argument, in which case the request will be ignored.
|
|
// - For more information, read the class' documentation.
|
|
// - This method is always thread-safe. It can be called multiple times on
|
|
// different threads.
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - <none>
|
|
void ThrottledFunc<>::Run()
|
|
{
|
|
if (_isRunPending.test_and_set())
|
|
{
|
|
// already pending
|
|
return;
|
|
}
|
|
|
|
_dispatcher.RunAsync(CoreDispatcherPriority::Low, [weakThis = this->weak_from_this()]() {
|
|
if (auto self{ weakThis.lock() })
|
|
{
|
|
DispatcherTimer timer;
|
|
timer.Interval(self->_delay);
|
|
timer.Tick([=](auto&&...) {
|
|
if (auto self{ weakThis.lock() })
|
|
{
|
|
timer.Stop();
|
|
self->_isRunPending.clear();
|
|
self->_func();
|
|
}
|
|
});
|
|
timer.Start();
|
|
}
|
|
});
|
|
}
|