/** * The following method must have a specialization for type 'Message': * * bool SkShouldPostMessageToBus(const Message&, IDType msgBusUniqueID) * * We may want to consider providing a default template implementation, to avoid this requirement by * sending to all inboxes when the specialization for type 'Message' is not present.
*/ template <typename Message, typename IDType, bool AllowCopyableMessage = true> class SkMessageBus : SkNoncopyable { public: template <typename T> struct is_sk_sp : std::false_type {}; template <typename T> struct is_sk_sp<sk_sp<T>> : std::true_type {};
// We want to make sure the caller of Post() method will not keep a ref or copy of the message, // so the message type must be sk_sp or non copyable.
static_assert(AllowCopyableMessage || is_sk_sp<Message>::value ||
!std::is_copy_constructible<Message>::value, "The message type must be sk_sp or non copyable.");
// Post a message to be received by Inboxes for this Message type. Checks // SkShouldPostMessageToBus() for each inbox. Threadsafe. staticvoid Post(Message m);
class Inbox { public:
Inbox(IDType uniqueID);
~Inbox();
IDType uniqueID() const { return fUniqueID; }
// Overwrite out with all the messages we've received since the last call. Threadsafe. void poll(skia_private::TArray<Message>* out);
// This must go in a single .cpp file, not some .h, or we risk creating more than one global // SkMessageBus per type when using shared libraries. NOTE: at most one per file will compile. #define DECLARE_SKMESSAGEBUS_MESSAGE(Message, IDType, AllowCopyableMessage) \ template <> \
SkMessageBus<Message, IDType, AllowCopyableMessage>* \
SkMessageBus<Message, IDType, AllowCopyableMessage>::Get() { \ static SkOnce once; \ static SkMessageBus<Message, IDType, AllowCopyableMessage>* bus; \
once([] { bus = new SkMessageBus<Message, IDType, AllowCopyableMessage>(); }); \ return bus; \
}
// ----------------------- Implementation of SkMessageBus::Inbox -----------------------
template <typename Message, typename IDType, bool AllowCopyableMessage>
SkMessageBus<Message, IDType, AllowCopyableMessage>::Inbox::~Inbox() { // Remove ourselves from the corresponding message bus. auto* bus = SkMessageBus<Message, IDType, AllowCopyableMessage>::Get();
SkAutoMutexExclusive lock(bus->fInboxesMutex); // This is a cheaper fInboxes.remove(fInboxes.find(this)) when order doesn't matter. for (int i = 0; i < bus->fInboxes.size(); i++) { if (this == bus->fInboxes[i]) {
bus->fInboxes.removeShuffle(i); break;
}
}
}
template <typename Message, typename IDType, bool AllowCopyableMessage> /*static*/ void SkMessageBus<Message, IDType, AllowCopyableMessage>::Post(Message m) { auto* bus = SkMessageBus<Message, IDType, AllowCopyableMessage>::Get();
SkAutoMutexExclusive lock(bus->fInboxesMutex); for (int i = 0; i < bus->fInboxes.size(); i++) { if (SkShouldPostMessageToBus(m, bus->fInboxes[i]->fUniqueID)) { if constexpr (AllowCopyableMessage) {
bus->fInboxes[i]->receive(m);
} else { if constexpr (is_sk_sp<Message>::value) {
SkASSERT(m->unique());
}
bus->fInboxes[i]->receive(std::move(m)); break;
}
}
}
if constexpr (is_sk_sp<Message>::value && !AllowCopyableMessage) { // Make sure sk_sp has been sent to an inbox.
SkASSERT(!m); // NOLINT(bugprone-use-after-move)
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.