Alexa SDK庖丁解牛-第二回:run函数解析

这回我们重点介绍下main中的void UserInputManager::run()
{
void InteractionManager::tap()
}
在此我们首先看下tap事件处理:
std::future<bool> AudioInputProcessor::recognize()
======》
bool AudioInputProcessor::executeRecognize()与 Creating the Context Manager、DialogUXStateAggregator 如何交互呢??
1)首先bool AudioInputProcessor::executeRecognize()捕获到事件;
2)状态更新到DialogUXStateAggregator;
bool AudioInputProcessor:: executeRecognize() //按键触发、唤醒词触发
{
/*
=>observer->onStateChanged(m_state);
=>DialogUXStateAggregator::onStateChanged(AudioInputProcessorObserverInterface::State state)
*/
setState(ObserverInterface::State::RECOGNIZING);

/* 此处会给 Context Manager队列塞数据*/
m_contextManager->getContext(shared_from_this());

}
3) setState(ObserverInterface::State::RECOGNIZING);
当audioinput状态为AudioInputProcessorObserverInterface::State::RECOGNIZING,轮询设置状态更新,触发对话管理器事件更新:
void DialogUXStateAggregator::onStateChanged(AudioInputProcessorObserverInterface::State state) {
//由于audioinput状态更新为RECOGNIZING,则对话进入LISTENING
case AudioInputProcessorObserverInterface::State::RECOGNIZING:
 onActivityStarted();
 setState(DialogUXStateObserverInterface::DialogUXState::LISTENING);
 return;
}
4) m_contextManager->getContext(shared_from_this());
Context Manager线程的主循环解阻塞,看文章最后面的说明:
void ContextManager::updateStatesLoop() {
 while (true) {
m_contextLoopNotifier.wait(); //条件变量阻塞等待
..........................................................
sendContextToRequesters();
 }
}

sendContextAndClearQueue()=> onContextAvailable();
void AudioInputProcessor:: onContextAvailable(const std::string& jsonContext) {
m_executor.submit([this, jsonContext]() { executeOnContextAvailable(jsonContext); });
}
再次获取channel,dialogRequestId,发送request
m_directiveSequencer-> setDialogRequestId(dialogRequestId);
=>setDialogRequestIdLocked()
=>scrubDialogRequestIdLocked()
=>m_wakeProcessingLoop.notify_one();
auto msgIdAndJsonEvent = buildJsonEventString("Recognize", dialogRequestId, m_payload, jsonContext);
// Assemble the MessageRequest. It will be sent by executeOnFocusChangedwhen we acquire the channel.
m_request->addObserver(shared_from_this());

bool HTTP2Stream::setCommonOptions(const std::string& url, const std::string& authToken)
{
(!m_transfer.setWriteCallback(&HTTP2Stream::writeCallback, this));
(!m_transfer.setHeaderCallback(&HTTP2Stream::headerCallback, this));
setopt(CURLOPT_TCP_KEEPALIVE, "CURLOPT_TCP_KEEPALIVE", 1);
}
writeCallback分析:即收到http消息
size_t HTTP2Stream:: writeCallback(char* data, size_t size, size_t nmemb, void* user)
=>
MimeParser::DataParsedStatus MimeParser:: feed(char* data, size_t length)
=>
m_multipartReader. feed(data, length);
=>
size_t feed(const char *buffer, size_t len) {
return parser. feed(buffer, len);
}
=>
size_t feed(const char *buffer, size_t len)
{
callback(onPartEnd);
callback(onPartBegin);
callback(onHeaderEnd);
callback(onPartBegin);
}
=>
void MimeParser:: partEndCallback(void* userData)
=>
 void MessageRouter:: consumeMessage(const std::string& contextId, const std::string& message)
=>
 void MessageRouter:: notifyObserverOnReceive(const std::string& contextId, const std::string& message)
=>
 void MessageInterpreter:: receive(const std::string& contextId, const std::string& message);
=>
 m_directiveSequencer->onDirective(avsDirective);
 {
 auto handled = m_directiveRouter-> preHandleDirective();
 ============================
 m_receivingQueue. push_back(directive);
 m_wakeReceivingLoop. notify_one();
 }

bool DirectiveRouter::preHandleDirective()
{
handlerAndPolicy.handler->preHandleDirective(directive, std::move(result));
}
=》
void CapabilityAgent::preHandleDirective()
{
}
=>
bool DirectiveRouter::handleDirective()
=》
void AudioInputProcessor::handleDirective(std::shared_ptr<DirectiveInfo> info)
{
handleStopCaptureDirective(info);
}
=》
executeStopCapture(stopImmediately, info);
=》
setState(ObserverInterface::State::BUSY);
=》
observer->onStateChanged(m_state);

另一个分支:
void SpeechSynthesizer::handleDirective()
=>
void SpeechSynthesizer::executeHandle(std::shared_ptr<DirectiveInfo> info)
=>
void SpeechSynthesizer::addToDirectiveQueue(std::shared_ptr<SpeakDirectiveInfo> speakInfo)
=>
m_speakInfoQueue.push_back(speakInfo);
executeHandleAfterValidation(speakInfo);
=>
bool FocusManager::acquireChannel()
=》
void FocusManager::acquireChannelHelper()
=>
channelToAcquire->setFocus(FocusState::FOREGROUND);
=>
m_observer->onFocusChanged(m_focusState);
=>
void SpeechSynthesizer::onFocusChanged(FocusState newFocus)
=>
 1)void SpeechSynthesizer:: setCurrentStateLocked()
 2)executeStateChange();


1)其中void SpeechSynthesizer:: setCurrentStateLocked()分析如下:
 observer->onStateChanged(m_currentState);
=》
 void AudioInputProcessor::onFocusChanged(avsCommon::avs::FocusState newFocus)
=>
 void AudioInputProcessor:: executeOnFocusChanged(avsCommon::avs::FocusState newFocus)
=>
 void AudioInputProcessor::executeResetState()
=>
 void AudioInputProcessor::setState(ObserverInterface::State state)
=>
2)其中executeStateChange()分析如下:
=》
startPlaying()
{
  m_speechPlayer-> setSource(std::move(m_currentInfo->attachmentReader);//这里做了很多设置
 m_speechPlayer-> play(m_mediaSourceId);
}
=》
 bool MediaPlayer:: play(MediaPlayer::SourceId id);
=》
 void MediaPlayer:: handlePlay(SourceId id, std::promise<bool>* promise)
 {
  m_busWatchId = gst_bus_add_watch(bus, &MediaPlayer::onBusMessage, this);
 }
=》
 (mediaPlayer)->handleBusMessage(message);
=》
 gboolean MediaPlayer::handleBusMessage(GstMessage* message);
在此重点看GST_MESSAGE_STATE_CHANGED分支就可以。
void MediaPlayer::sendPlaybackStarted()


当这里我们需要回过头看看在main初始化中
Creating the Directive Sequencer:负责把AVS指令序列化管理,根据namespace推到对应的组件模块
m_directiveSequencer = adsl::DirectiveSequencer::create(exceptionSender);
{
return std::unique_ptr<DirectiveSequencerInterface>(new DirectiveSequencer(exceptionSender));
}
构造函数创建了线程:
DirectiveSequencer::DirectiveSequencer()
{
m_receivingThread = std::thread(&DirectiveSequencer:: receivingLoop, this);
}
void DirectiveSequencer:: receivingLoop() {
auto wake = [this]() { return !m_receivingQueue.empty() || m_isShuttingDown; };

std::unique_lock<std::mutex> lock(m_mutex);
while (true) {
 m_wakeReceivingLoop.wait(lock, wake);
 if (m_isShuttingDown) {
   break;
 }
 receiveDirectiveLocked(lock);
}

void DirectiveSequencer::receiveDirectiveLocked(std::unique_lock<std::mutex>& lock) {
==================================
auto directive = m_receivingQueue.front();
m_receivingQueue.pop_front();
==================================
handled = m_directiveRouter.handleDirectiveImmediately(directive);
或者
handled = m_directiveRouter.handleDirectiveWithPolicyHandleImmediately(directive);

}
其实在SDK的初试中创建了很多线程,他们都在block等待状态更新,这里比较重要的是 HTTP2Stream线程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值