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

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Calibri"; } @font-face{ font-family:"PingFang SC"; } p.MsoNormal{ mso-style-name:正文; mso-style-parent:""; margin:0pt; margin-bottom:.0001pt; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋体; mso-bidi-font-family:'Times New Roman'; font-size:10.5000pt; mso-font-kerning:1.0000pt; } span.10{ font-family:'Times New Roman'; } span.15{ font-family:'Times New Roman'; font-weight:bold; } span.msoIns{ mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single; color:blue; } span.msoDel{ mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:red; } @page{mso-page-border-surround-header:no; mso-page-border-surround-footer:no;}@page Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:595.3000pt 841.9000pt; layout-grid:15.6000pt; } div.Section0{page:Section0;}

这回我们重点介绍下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 byexecuteOnFocusChangedwhen 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线程。

 

posted @ 2018-03-06 14:19  zzzxzzz  阅读(296)  评论(0)    收藏  举报