// Low level interface void Cpp2Channel::sendMessage(SendCallback* callback, std::unique_ptr<folly::IOBuf>&& buf) { // Callback may be null. assert(buf); if (!transport_->good()) { VLOG(5) << "Channel is !good() in sendMessage"; TTransportException ex("Channel is !good()"); // Callback must be last thing in sendMessage, or use guard if (callback) { callback->messageSendError(make_exception_ptr(ex)); } return; } buf = frameMessage(std::move(buf)); if (protectionState_ == ProtectionState::VALID) { assert(saslEndpoint_); buf = saslEndpoint_->wrap(std::move(buf)); } if (!queueSends_) { // Send immediately. std::vector<SendCallback*> cbs; if (callback) { cbs.push_back(callback); } sendCallbacks_.push_back(std::move(cbs)); transport_->writeChain(this, std::move(buf)); } else { // Delay sends to optimize for fewer syscalls if (!sends_) { DCHECK(!isLoopCallbackScheduled()); // Buffer all the sends, and call writev once per event loop. sends_ = std::move(buf); getEventBase()->runInLoop(this); std::vector<SendCallback*> cbs; if (callback) { cbs.push_back(callback); } sendCallbacks_.push_back(std::move(cbs)); } else { DCHECK(isLoopCallbackScheduled()); sends_->prependChain(std::move(buf)); if (callback) { sendCallbacks_.back().push_back(callback); } } if (callback) { callback->sendQueued(); } } }
void CGameManager::update() { updateMovies(); frameMessage(getRoom()); _timers.update(g_vm->_events->getTicksCount()); _trueTalkManager.removeCompleted(); CScreenManager::_screenManagerPtr->_mouseCursor->update(); CViewItem *view = getView(); if (view) { // Expand the game manager's bounds to encompass all the view's items for (CTreeItem *item = view; item; item = item->scan(view)) { Rect r = item->getBounds(); if (!r.isEmpty()) _bounds.extend(r); } // Also include the PET control in the bounds if (_project) { CPetControl *pet = _project->getPetControl(); if (pet) _bounds.extend(pet->getBounds()); } // And the text cursor CScreenManager *screenManager = CScreenManager::_screenManagerPtr; CTextCursor *textCursor = screenManager->_textCursor; if (textCursor && textCursor->_active) _bounds.extend(textCursor->getCursorBounds()); // Set the surface bounds screenManager->setSurfaceBounds(SURFACE_BACKBUFFER, _bounds); // Handle redrawing the view if (!_bounds.isEmpty()) { _gameView->draw(_bounds); _bounds = Rect(); } _gameState.checkForViewChange(); } }