xref: /third_party/skia/tests/MessageBusTest.cpp (revision cb93a386)
1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/gpu/GrDirectContext.h"
9#include "src/core/SkMessageBus.h"
10#include "tests/Test.h"
11
12namespace {
13
14struct TestMessage {
15    TestMessage(int i, float f) : x(i), y(f) {}
16
17    int x;
18    float y;
19};
20
21static inline bool SkShouldPostMessageToBus(const TestMessage&, uint32_t) {
22    return true;
23}
24
25}  // namespace
26
27DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage, uint32_t, true)
28
29DEF_TEST(MessageBus, r) {
30    using TestMessageBus = SkMessageBus<TestMessage, uint32_t>;
31    // Register two inboxes to receive all TestMessages.
32    TestMessageBus::Inbox inbox1(0), inbox2(0);
33
34    // Send two messages.
35    const TestMessage m1 = { 5, 4.2f };
36    const TestMessage m2 = { 6, 4.3f };
37    TestMessageBus::Post(std::move(m1));
38    TestMessageBus::Post(std::move(m2));
39
40    // Make sure we got two.
41    SkTArray<TestMessage> messages;
42    inbox1.poll(&messages);
43    REPORTER_ASSERT(r, 2 == messages.count());
44    REPORTER_ASSERT(r, 5 == messages[0].x);
45    REPORTER_ASSERT(r, 6 == messages[1].x);
46
47    // Send another; check we get just that one.
48    const TestMessage m3 = { 1, 0.3f };
49    TestMessageBus::Post(m3);
50    inbox1.poll(&messages);
51    REPORTER_ASSERT(r, 1 == messages.count());
52    REPORTER_ASSERT(r, 1 == messages[0].x);
53
54    // Nothing was sent since the last read.
55    inbox1.poll(&messages);
56    REPORTER_ASSERT(r, 0 == messages.count());
57
58    // Over all this time, inbox2 should have piled up 3 messages.
59    inbox2.poll(&messages);
60    REPORTER_ASSERT(r, 3 == messages.count());
61    REPORTER_ASSERT(r, 5 == messages[0].x);
62    REPORTER_ASSERT(r, 6 == messages[1].x);
63    REPORTER_ASSERT(r, 1 == messages[2].x);
64}
65
66namespace {
67
68struct TestMessageRefCnt : public SkRefCnt {
69    TestMessageRefCnt(int i, float f) : x(i), y(f) {}
70
71    int x;
72    float y;
73};
74
75static inline bool SkShouldPostMessageToBus(const sk_sp<TestMessageRefCnt>&, uint32_t) {
76    return true;
77}
78
79}  // namespace
80
81DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<TestMessageRefCnt>, uint32_t, false)
82
83DEF_TEST(MessageBusSp, r) {
84    // Register two inboxes to receive all TestMessages.
85    using TestMessageBus = SkMessageBus<sk_sp<TestMessageRefCnt>, uint32_t, false>;
86    TestMessageBus::Inbox inbox1(0);
87
88    // Send two messages.
89    auto m1 = sk_make_sp<TestMessageRefCnt>(5, 4.2f);
90    auto m2 = sk_make_sp<TestMessageRefCnt>(6, 4.3f);
91    TestMessageBus::Post(std::move(m1));
92    TestMessageBus::Post(std::move(m2));
93
94    // Make sure we got two.
95    SkTArray<sk_sp<TestMessageRefCnt>> messages;
96    inbox1.poll(&messages);
97    REPORTER_ASSERT(r, 2 == messages.count());
98    REPORTER_ASSERT(r, messages[0]->unique());
99    REPORTER_ASSERT(r, messages[1]->unique());
100    REPORTER_ASSERT(r, 5 == messages[0]->x);
101    REPORTER_ASSERT(r, 6 == messages[1]->x);
102
103    // Send another; check we get just that one.
104    auto m3 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
105    TestMessageBus::Post(std::move(m3));
106    inbox1.poll(&messages);
107    REPORTER_ASSERT(r, 1 == messages.count());
108    REPORTER_ASSERT(r, messages[0]->unique());
109    REPORTER_ASSERT(r, 1 == messages[0]->x);
110
111    // Send another without std::move(), it should trigger SkASSERT().
112    // auto m4 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
113    // TestMessageBus::Post(m4);
114
115    // Nothing was sent since the last read.
116    inbox1.poll(&messages);
117    REPORTER_ASSERT(r, 0 == messages.count());
118}
119
120namespace {
121
122struct AddressedMessage {
123    GrDirectContext::DirectContextID fInboxID;
124};
125
126static inline bool SkShouldPostMessageToBus(const AddressedMessage& msg,
127                                            GrDirectContext::DirectContextID msgBusUniqueID) {
128    SkASSERT(msgBusUniqueID.isValid());
129    if (!msg.fInboxID.isValid()) {
130        return true;
131    }
132    return msgBusUniqueID == msg.fInboxID;
133}
134
135}  // namespace
136
137DECLARE_SKMESSAGEBUS_MESSAGE(AddressedMessage, GrDirectContext::DirectContextID, true)
138
139DEF_TEST(MessageBus_SkShouldPostMessageToBus, r) {
140    using ID = GrDirectContext::DirectContextID;
141    using AddressedMessageBus = SkMessageBus<AddressedMessage, ID>;
142
143    ID idInvalid;
144    ID id1 = ID::Next(),
145       id2 = ID::Next(),
146       id3 = ID::Next();
147
148    AddressedMessageBus::Inbox inbox1(id1), inbox2(id2);
149
150    AddressedMessageBus::Post({idInvalid});  // Should go to both
151    AddressedMessageBus::Post({id1});        // Should go to inbox1
152    AddressedMessageBus::Post({id2});        // Should go to inbox2
153    AddressedMessageBus::Post({id3});        // Should go nowhere
154
155    SkTArray<AddressedMessage> messages;
156    inbox1.poll(&messages);
157    REPORTER_ASSERT(r, messages.count() == 2);
158    if (messages.count() == 2) {
159        REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
160        REPORTER_ASSERT(r, messages[1].fInboxID == id1);
161    }
162    inbox2.poll(&messages);
163    REPORTER_ASSERT(r, messages.count() == 2);
164    if (messages.count() == 2) {
165        REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
166        REPORTER_ASSERT(r, messages[1].fInboxID == id2);
167    }
168}
169
170// Multithreaded tests tbd.
171