Repository: microsoft/terminal
File: src/cascadia/TerminalControl/ThrottledFunc.h (C/C++)

Code before:
    std::atomic_flag _isRunPending;
};

// Class Description:
// - Represents a function that takes arguments and whose invocation is
//   delayed by a specified duration and rate-limited such that if the code
//   tries to run the function while a call to the function is already
//   pending, then the previous call with the previous arguments will be
//   cancelled and the call will be made with the new arguments instead.
// - The function will be run on the the specified dispatcher.
template<bool leading, typename... Args>
class ThrottledFunc : public std::enable_shared_from_this<ThrottledFunc<leading, Args...>>
{
public:
    using Func = std::function<void(Args...)>;

    ThrottledFunc(winrt::Windows::UI::Core::CoreDispatcher dispatcher, winrt::Windows::Foundation::TimeSpan delay, Func func) :
        _dispatcher{ std::move(dispatcher) },
        _delay{ std::move(delay) },
        _func{ std::move(func) }
    {
    }

    // Method Description:
    // - Runs the function later with the specified arguments, except if `Run`
    //   is called again before with new arguments, in which case the new
    //   arguments will be used instead.
    // - For more information, read the class' documentation.
    // - This method is always thread-safe. It can be called multiple times on
    //   different threads.
    // Arguments:
    // - arg: the argument to pass to the function
    // Return Value:
    // - <none>
    template<typename... MakeArgs>
    void Run(MakeArgs&&... args)
    {
        if (!_storage.Emplace(std::forward<MakeArgs>(args)...))
        {
            _Fire();
        }
    }

    // Method Description:
    // - Modifies the pending arguments for the next function invocation, if
    //   there is one pending currently.
    // - Let's say that you just called the `Run` method with some arguments.
    //   After the delay specified in the constructor, the function specified
    //   in the constructor will be called with these arguments.
    // - By using this method, you can modify the arguments before the function
    //   is called.

Review comment (suggestion):
so, this is an interesting semantic change! It used to be guaranteed that the throttled function was called on the foreground queue; now that guarantee is only true for Trailing

Code after:
    std::atomic_flag _isRunPending;
};

// Class Description:
// - Represents a function that takes arguments and whose invocation is
//   delayed by a specified duration and rate-limited such that if the code
//   tries to run the function while a call to the function is already
//   pending, then the previous call with the previous arguments will be
//   cancelled and the call will be made with the new arguments instead.
// - The function will be run on the the specified dispatcher.
template<bool leading, typename... Args>
class ThrottledFunc : public std::enable_shared_from_this<ThrottledFunc<leading, Args...>>
{
public:
    using Func = std::function<void(Args...)>;

    ThrottledFunc(winrt::Windows::UI::Core::CoreDispatcher dispatcher, winrt::Windows::Foundation::TimeSpan delay, Func func) :
        _dispatcher{ std::move(dispatcher) },
        _delay{ std::move(delay) },
        _func{ std::move(func) }
    {
    }

    // Method Description:
    // - Runs the function later with the specified arguments, except if `Run`
    //   is called again before with new arguments, in which case the new
    //   arguments will be used instead.
    // - For more information, read the class' documentation.
    // - This method is always thread-safe. It can be called multiple times on
    //   different threads.
    // Arguments:
    // - args: the arguments to pass to the function
    // Return Value:
    // - <none>
    template<typename... MakeArgs>
    void Run(MakeArgs&&... args)
    {
        if (!_storage.Emplace(std::forward<MakeArgs>(args)...))
        {
            _Fire();
        }
    }

    // Method Description:
    // - Modifies the pending arguments for the next function invocation, if
    //   there is one pending currently.
    // - Let's say that you just called the `Run` method with some arguments.
    //   After the delay specified in the constructor, the function specified
    //   in the constructor will be called with these arguments.
    // - By using this method, you can modify the arguments before the function
    //   is called.