0%


title: WebRTC中的MethodCall
date: 2020-07-18 08:30:03
tags: WebRTC
categories: WebRTC

1
2
3
4
...
MethodCall<PeerConnectionFactory, bool> call( pc_factory.get(), &PeerConnectionFactory::Initialize);
bool result = call.Marshal(RTC_FROM_HERE, pc_factory->signaling_thread());
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
template <typename R>
class ReturnType {
public:
template <typename C, typename M, typename... Args>
void Invoke(C* c, M m, Args&&... args) {
r_ = (c->*m)(std::forward<Args>(args)...);
}

R moved_result() { return std::move(r_); }

private:
R r_;
};

template <typename C, typename R, typename... Args >
class MethodCall : public rtc::Message, public rtc::MessageHandler {
public:
typedef R (C::*Method)(Args...);
MethodCall(C* c, Method m, Args&&... args) :
c_(c),
m_(m),
args_(std::forward_as_tuple(std::forward<Args>(args)...){}

R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
internal::SynchronousMethodCall(this).Invoke(posted_from, t);
return r_.moved_result();
}

private:
void OnMessage(rtc::Message*) { Invoke(std::index_sequence_for<Args...>()); }

template <size_t... ls>
void Invoke(std::index_sequence<ls...>) {
r_.Invoke(c_, m_, std::move(std::get<ls>(args_))...);
}

C* c_;
Method m_;
ReturnType<R> r_;
};


根据模板类型推导原则,当创建call对象时,可以推导出如下内容:C = PeerConnectionFactoryR = boolMethod= typedef bool (PeerConnectionFactory::*Method)()。所以最终的结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class ReturnType {
public:
typedef bool (PeerConnectionFactory::*Method)();
void Invoke(PeerConnectionFactory* c, Method m) {
r_ = (c->*m)();
}

R moved_result() { return std::move(r_); }

private:
bool r_;
};

class MethodCall : public rtc::Message, public rtc::MessageHandler {
public:
typedef bool (PeerConnectionFactory::*Method)();
MethodCall(PeerConnectionFactory* c, Method m,) :
c_(c),
m_(m){}

bool Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
internal::SynchronousMethodCall(this).Invoke(posted_from, t);
return r_.moved_result();
}

private:
void OnMessage(rtc::Message*) { Invoke(); }

template <size_t... ls>
void Invoke() {
r_.Invoke(c_, m_);
}

PeerConnectionFactory* c_;
Method m_;
ReturnType<bool> r_;
};

当调用internal::SynchronousMethodCall(this)时,会创建SynchronousMethodCall类对象,SynchronousMethodCall 类定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace internal {

class SynchronousMethodCall : public rtc::MessageData,
public rtc::MessageHandler {
public:
explicit SynchronousMethodCall(rtc::MessageHandler* proxy);
~SynchronousMethodCall() override;

void Invoke(const rtc::Location& posted_from, rtc::Thread* t);

private:
void OnMessage(rtc::Message*) override;

rtc::Event e_;
rtc::MessageHandler* proxy_;
};

} // namespace internal

当它调用invoke的时候,invoke的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void SynchronousMethodCall::Invoke(const rtc::Location& posted_from,
rtc::Thread* t) {
if (t->IsCurrent()) {
proxy_->OnMessage(nullptr);
} else {
t->Post(posted_from, this, 0);
e_.Wait(rtc::Event::kForever);
}
}

void SynchronousMethodCall::OnMessage(rtc::Message*) {
proxy_->OnMessage(nullptr);
e_.Set();
}