C

事件队列类

template <typename EventType_, Qul::EventQueueOverrunPolicy overrunPolicy, size_t queueSize> class Qul::EventQueue

提供了一种方便的方式在不同应用程序部分之间发送和接收事件。 更多...

头文件 #include <qul/eventqueue.h>
Qt Quick Ultralite 1.0

公共类型

公共函数

事件队列()
~事件队列()
voidclearOverrun()
boolisOverrun() const
virtual voidonEvent(const Qul::EventQueue::EventType &event) = 0
virtual voidonEventDiscarded(const Qul::EventQueue::EventType &event)
virtual voidonQueueOverrun()
voidpostEvent(const Qul::EventQueue::EventType &event)
voidpostEventFromInterrupt(const Qul::EventQueue::EventType &event)

详细描述

这是一个模板类,需要事件的类型、EventQueueOverrunPolicy 和队列的最大 size。默认值是 EventQueueOverrunPolicy_Discard 和队列大小为 5。有关详细信息,请参阅 调整队列大小

通常,可以使用 postEvent 函数将事件发布到队列(在没有中断上下文的情况下),或从中断处理程序使用 postEventFromInterrupt 函数。覆盖 onEvent 来处理事件,通常在下一帧期间。

DoubleQueue 是裸金属平台上的默认队列后端。只要有一个写入器,它就是中断安全的,因为写入和读取都是指向不同的列表。可以在队列有单个写入器的情况下从中断调用 postEventFromInterrupt()。如果有多个写入器,必须确保 postEvent() 或 postEventFromInterrupt() 不会被同一队列的另一个 postEvent() 或 postEventFromInterrupt() 中断。process() 可以被 postEvent() 或 postEventFromInterrupt() 中断。

对于基于实时操作系统(RTOS)的平台,队列后端实现依托于RTOS特定的队列,这使得在多线程环境下 Qul::EventQueue 具有线程安全性。

Qt Quick Ultralite 提供的默认后端使用 memcpy() 或等价操作来复制数据到队列。这意味着在 EventQueue 中使用的数据类型必须是/包含原始数据(POD),或者 纯旧数据。如果不能这样做,则必须使用指针。然而,Qt Quick Ultralite 提供的后端在事件是指针时不会管理内存。您可以选择使用 EventQueueOverrunPolicy_DiscardonEventDiscarded,或者提供自定义后端来处理被覆盖的事件的内存。有关更多信息,请参阅 实现自定义队列

当队列接收到的的事件超过其容量时,将根据 EventQueueOverrunPolicy 进行处理。此外,只要状态未被调用 clearOverrun 重置,就会在处理任何事件之前调用 onQueueOverrun

如果使用了 EventQueueOverrunPolicy_Discard 并且需要处理被丢弃的事件,则可以重写 onEventDiscarded 函数。

示例

从 EventQueue 派生,以创建特定事件类型的队列,并覆盖 onEvent

#include <qul/eventqueue.h>

typedef int IntegerEvent;

class IntegerEventQueue : public Qul::EventQueue<IntegerEvent> {
    void onEvent(const IntegerEvent &event) override {
        // do some stuff with your event here
    }
};

接下来,创建队列的实例。通常,公开数据或信号到 QML 的队列除了从 EventQueue 继承外,还从 Singleton 继承,这使得此步骤变得不必要。

IntegerEventQueue integerEventQueue;

现在,可以在中断上下文之外发布事件

integerEventQueue.postEvent(42);

或者从中断处理程序中

integerEventQueue.postEventFromInterrupt(42);

调整队列大小

默认情况下,队列的大小设置为 5。大小决定在随后的分派操作之间可以存储多少事件。分派尽可能快速进行,通常在下一次应用程序帧中。使用 EventQueueOverrunPolicy 来控制队列满时队列的行为。

// A queue where only the most recent event is interesting
Qul::EventQueue<IntegerEvent, Qul::EventQueueOverrunPolicy_OverwriteOldest, 1>

// A queue that can store many events
Qul::EventQueue<IntegerEvent, Qul::EventQueueOverrunPolicy_Discard, 1000>

通过覆盖 onQueueOverrun 方法来接收越界通知。

class AudioQueue : public Qul::EventQueue<float, Qul::EventQueueOverrunPolicy_Discard, 1000>
{
    void onQueueOverrun() override {
        // Avoid the problem by reducing the frequency of event generation.
        setSampleRate(8000);
        clearOverrun();
    }
};

事件顺序

每个队列中事件的顺序被保留,但不同队列之间没有保证顺序。

当事件顺序很重要时,如输入事件,这可能会成为问题

keyboardInput.postEvent(KeyEvents(...));
touchInput.postEvent(TouchEvent(...));
// Unknown whether the KeyEvent or TouchEvent is processed first!

在这些情况下,可以使用单队列,而不是单独的队列,使用联合或 std::variant 事件类型。

另请参阅 将数据从中断处理程序转移到 QML

成员类型文档

EventQueue::EventType

本事件循环使用的事件类型。

成员函数文档

EventQueue::EventQueue()

构造队列并注册到应用程序以处理事件。

EventQueue::~EventQueue()

销毁队列并注销它。

[自 Qt Quick Ultralite 2.3] void EventQueue::clearOverrun()

清除实现的越界标志。

这个函数是在 Qt Quick Ultralite 2.3 中引入的。

另请参阅 Qul::Platform::MessageQueueInterface::clearOverrun() 和 isOverrun()。

[自 Qt Quick Ultralite 2.3] bool EventQueue::isOverrun() const

如果实现的队列被丢弃或覆盖的事件超载,则返回 true

这个函数是在 Qt Quick Ultralite 2.3 中引入的。

另请参阅 Qul::Platform::MessageQueueInterface::isOverrun() 和 clearOverrun

[纯虚函数] void EventQueue::onEvent(const Qul::EventQueue::EventType &event)

派生类必须重写此方法来处理 事件

每个队列中事件按照从旧到新的顺序处理。

[虚函数] void EventQueue::onEventDiscarded(const Qul::EventQueue::EventType &event)

派生类可以重写此方法来处理丢弃的 事件。如果 EventType_ 参数是一个指针,需要适当的销毁例程,这非常有用。

此函数仅在 Qul::EventQueueOverrunPolicy_Discard 被使用时调用。

[虚函数] void EventQueue::onQueueOverrun()

派生类可以重写此方法来处理队列超载。

如果向此队列发送的事件多于分配的存储空间,则调用此函数。它不是在 postEventpostEventFromInterrupt 调用期间立即调用,而是在下一次 onEvent 调用之前直接调用。

void EventQueue::postEvent(const Qul::EventQueue::EventType &event)

事件 的副本追加到队列中,以便在下一次调度操作(通常是下一次帧)期间进行处理。

如果队列已满,EventQueueOverrunPolicy 确定是丢弃事件还是覆盖旧事件。在这两种情况下,都会安排调用 onQueueOverrun

注意:在中断上下文中,请使用 postEventFromInterrupt 替代。

void EventQueue::postEventFromInterrupt(const Qul::EventQueue::EventType &event)

事件 的副本追加到队列中,以便在下一次调度操作(通常是下一次帧)期间进行处理。

如果队列已满,EventQueueOverrunPolicy 确定是丢弃事件还是覆盖旧事件。在这两种情况下,都会安排调用 onQueueOverrun

当从中断上下文写入事件时应使用此函数。

在特定的 Qt 许可证下提供。
了解更多信息。