Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
third_party
skia
src
core
SkMessageBus.h
Go to the documentation of this file.
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
#ifndef SkMessageBus_DEFINED
9
#define SkMessageBus_DEFINED
10
11
#include <type_traits>
12
13
#include "
include/core/SkRefCnt.h
"
14
#include "
include/core/SkTypes.h
"
15
#include "
include/private/base/SkMutex.h
"
16
#include "
include/private/base/SkNoncopyable.h
"
17
#include "
include/private/base/SkOnce.h
"
18
#include "
include/private/base/SkTArray.h
"
19
#include "
include/private/base/SkTDArray.h
"
20
21
/**
22
* The following method must have a specialization for type 'Message':
23
*
24
* bool SkShouldPostMessageToBus(const Message&, IDType msgBusUniqueID)
25
*
26
* We may want to consider providing a default template implementation, to avoid this requirement by
27
* sending to all inboxes when the specialization for type 'Message' is not present.
28
*/
29
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage = true>
30
class
SkMessageBus
:
SkNoncopyable
{
31
public
:
32
template
<
typename
T>
struct
is_sk_sp
: std::false_type {};
33
template
<
typename
T>
struct
is_sk_sp
<
sk_sp
<
T
>> : std::true_type {};
34
35
// We want to make sure the caller of Post() method will not keep a ref or copy of the message,
36
// so the message type must be sk_sp or non copyable.
37
static_assert
(AllowCopyableMessage ||
is_sk_sp<Message>::value
||
38
!std::is_copy_constructible<Message>::value,
39
"The message type must be sk_sp or non copyable."
);
40
41
// Post a message to be received by Inboxes for this Message type. Checks
42
// SkShouldPostMessageToBus() for each inbox. Threadsafe.
43
static
void
Post
(
Message
m);
44
45
class
Inbox
{
46
public
:
47
Inbox(IDType
uniqueID
);
48
~Inbox
();
49
50
IDType
uniqueID
()
const
{
return
fUniqueID; }
51
52
// Overwrite out with all the messages we've received since the last call. Threadsafe.
53
void
poll
(
skia_private::TArray<Message>
* out);
54
55
private
:
56
skia_private::TArray<Message>
fMessages;
57
SkMutex fMessagesMutex;
58
const
IDType fUniqueID;
59
60
friend
class
SkMessageBus
;
61
void
receive(
Message
m);
// SkMessageBus is a friend only to call this.
62
};
63
64
private
:
65
SkMessageBus
();
66
static
SkMessageBus
* Get();
67
68
SkTDArray<Inbox*>
fInboxes;
69
SkMutex fInboxesMutex;
70
};
71
72
// This must go in a single .cpp file, not some .h, or we risk creating more than one global
73
// SkMessageBus per type when using shared libraries. NOTE: at most one per file will compile.
74
#define DECLARE_SKMESSAGEBUS_MESSAGE(Message, IDType, AllowCopyableMessage) \
75
template <> \
76
SkMessageBus<Message, IDType, AllowCopyableMessage>* \
77
SkMessageBus<Message, IDType, AllowCopyableMessage>::Get() { \
78
static SkOnce once; \
79
static SkMessageBus<Message, IDType, AllowCopyableMessage>* bus; \
80
once([] { bus = new SkMessageBus<Message, IDType, AllowCopyableMessage>(); }); \
81
return bus; \
82
}
83
84
// ----------------------- Implementation of SkMessageBus::Inbox -----------------------
85
86
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
87
SkMessageBus<Message, IDType, AllowCopyableMessage>::Inbox::Inbox
(IDType uniqueID)
88
: fUniqueID(uniqueID) {
89
// Register ourselves with the corresponding message bus.
90
auto
* bus =
SkMessageBus<Message, IDType, AllowCopyableMessage>::Get
();
91
SkAutoMutexExclusive
lock(bus->fInboxesMutex);
92
bus->fInboxes.push_back(
this
);
93
}
94
95
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
96
SkMessageBus<Message, IDType, AllowCopyableMessage>::Inbox::~Inbox
() {
97
// Remove ourselves from the corresponding message bus.
98
auto
* bus =
SkMessageBus<Message, IDType, AllowCopyableMessage>::Get
();
99
SkAutoMutexExclusive
lock(bus->fInboxesMutex);
100
// This is a cheaper fInboxes.remove(fInboxes.find(this)) when order doesn't matter.
101
for
(
int
i = 0; i < bus->fInboxes.size(); i++) {
102
if
(
this
== bus->fInboxes[i]) {
103
bus->fInboxes.removeShuffle(i);
104
break
;
105
}
106
}
107
}
108
109
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
110
void
SkMessageBus<Message, IDType, AllowCopyableMessage>::Inbox::receive
(
Message
m) {
111
SkAutoMutexExclusive
lock(fMessagesMutex);
112
fMessages.push_back(std::move(m));
113
}
114
115
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
116
void
SkMessageBus<Message, IDType, AllowCopyableMessage>::Inbox::poll
(
117
skia_private::TArray<Message>
* messages) {
118
SkASSERT
(messages);
119
messages->
clear
();
120
SkAutoMutexExclusive
lock(fMessagesMutex);
121
fMessages.swap(*messages);
122
}
123
124
// ----------------------- Implementation of SkMessageBus -----------------------
125
126
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
127
SkMessageBus<Message, IDType, AllowCopyableMessage>::SkMessageBus
() =
default
;
128
129
template
<
typename
Message,
typename
IDType,
bool
AllowCopyableMessage>
130
/*static*/
void
SkMessageBus<Message, IDType, AllowCopyableMessage>::Post
(
Message
m) {
131
auto
* bus =
SkMessageBus<Message, IDType, AllowCopyableMessage>::Get
();
132
SkAutoMutexExclusive
lock(bus->fInboxesMutex);
133
for
(
int
i = 0; i < bus->fInboxes.size(); i++) {
134
if
(
SkShouldPostMessageToBus
(m, bus->fInboxes[i]->fUniqueID)) {
135
if
constexpr
(AllowCopyableMessage) {
136
bus->fInboxes[i]->receive(m);
137
}
else
{
138
if
constexpr
(
is_sk_sp<Message>::value
) {
139
SkASSERT
(m->unique());
140
}
141
bus->fInboxes[i]->receive(std::move(m));
142
break
;
143
}
144
}
145
}
146
147
if
constexpr
(
is_sk_sp<Message>::value
&& !AllowCopyableMessage) {
148
// Make sure sk_sp has been sent to an inbox.
149
SkASSERT
(!m);
// NOLINT(bugprone-use-after-move)
150
}
151
}
152
153
#endif
// SkMessageBus_DEFINED
SkASSERT
#define SkASSERT(cond)
Definition
SkAssert.h:116
SkMutex.h
SkNoncopyable.h
SkOnce.h
SkRefCnt.h
SkShouldPostMessageToBus
static bool SkShouldPostMessageToBus(const SkResourceCache::PurgeSharedIDMessage &, uint32_t)
Definition
SkResourceCache.cpp:37
SkTArray.h
SkTDArray.h
SkTypes.h
SkAutoMutexExclusive
Definition
SkMutex.h:49
SkMessageBus::Inbox
Definition
SkMessageBus.h:45
SkMessageBus::Inbox::poll
void poll(skia_private::TArray< Message > *out)
Definition
SkMessageBus.h:116
SkMessageBus::Inbox::~Inbox
~Inbox()
Definition
SkMessageBus.h:96
SkMessageBus::Inbox::uniqueID
IDType uniqueID() const
Definition
SkMessageBus.h:50
SkMessageBus::Inbox::Inbox
Inbox(IDType uniqueID)
Definition
SkMessageBus.h:87
SkMessageBus
Definition
SkMessageBus.h:30
SkMessageBus::Post
static void Post(Message m)
Definition
SkMessageBus.h:130
SkNoncopyable
Definition
SkNoncopyable.h:18
SkTDArray
Definition
SkTDArray.h:105
sk_sp
Definition
SkRefCnt.h:220
skia_private::TArray
Definition
SkTArray.h:40
skia_private::TArray::clear
void clear()
Definition
SkTArray.h:420
T
#define T
Definition
precompiler.cc:65
Message
Definition
SurfaceThread.h:28
SkMessageBus::is_sk_sp
Definition
SkMessageBus.h:32
Generated on Fri Apr 26 2024 06:16:44 for Flutter Engine by
1.9.8