BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) { LLMultiGesture* gesture = (*it).second; if (gesture) { const std::string& trigger = gesture->getTrigger(); if (in_len > (S32)trigger.length()) { // too short, bail out continue; } std::string trigger_trunc = trigger; LLStringUtil::truncate(trigger_trunc, in_len); if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) { *out_str = trigger; return TRUE; } } } return FALSE; }
void LLGestureMgr::update() { S32 i; for (i = 0; i < (S32)mPlaying.size(); ++i) { stepGesture(mPlaying[i]); } // Clear out gestures that are done, by moving all the // ones that are still playing to the front. std::vector<LLMultiGesture*>::iterator new_end; new_end = std::partition(mPlaying.begin(), mPlaying.end(), IsGesturePlaying()); // Something finished playing if (new_end != mPlaying.end()) { // Delete the completed gestures that want deletion std::vector<LLMultiGesture*>::iterator it; for (it = new_end; it != mPlaying.end(); ++it) { LLMultiGesture* gesture = *it; if (gesture->mDoneCallback) { gesture->mDoneCallback(gesture); // callback might have deleted gesture, can't // rely on this pointer any more gesture = NULL; } } // And take done gestures out of the playing list mPlaying.erase(new_end, mPlaying.end()); notifyObservers(); } }
// static void LLPreviewGesture::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status) { LLUUID* item_idp = (LLUUID*)user_data; LLPreview* preview = LLPreview::find(*item_idp); if (preview) { LLPreviewGesture* self = (LLPreviewGesture*)preview; if (0 == status) { LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); char* buffer = new char[size+1]; file.read((U8*)buffer, size); /*Flawfinder: ignore*/ buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); LLDataPackerAsciiBuffer dp(buffer, size+1); BOOL ok = gesture->deserialize(dp); if (ok) { // Everything has been successful. Load up the UI. self->loadUIFromGesture(gesture); self->mStepList->selectFirstItem(); self->mDirty = FALSE; self->refresh(); } else { llwarns << "Unable to load gesture" << llendl; } delete gesture; gesture = NULL; delete [] buffer; buffer = NULL; self->mAssetStatus = PREVIEW_ASSET_LOADED; } else { if( gViewerStats ) { gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); } if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { LLNotifyBox::showXml("GestureMissing"); } else { LLNotifyBox::showXml("UnableToLoadGesture"); } llwarns << "Problem loading gesture: " << status << llendl; self->mAssetStatus = PREVIEW_ASSET_ERROR; } } delete item_idp; item_idp = NULL; }
void LLPreviewGesture::saveIfNeeded() { if (!gAssetStorage) { llwarns << "Can't save gesture, no asset storage system." << llendl; return; } if (!mDirty) { return; } // Copy the UI into a gesture LLMultiGesture* gesture = createGesture(); // Serialize the gesture S32 max_size = gesture->getMaxSerialSize(); char* buffer = new char[max_size]; LLDataPackerAsciiBuffer dp(buffer, max_size); BOOL ok = gesture->serialize(dp); if (dp.getCurrentSize() > 1000) { gViewerWindow->alertXml("GestureSaveFailedTooManySteps"); delete gesture; gesture = NULL; } else if (!ok) { gViewerWindow->alertXml("GestureSaveFailedTryAgain"); delete gesture; gesture = NULL; } else { // Every save gets a new UUID. Yup. LLTransactionID tid; LLAssetID asset_id; tid.generate(); asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND); S32 size = dp.getCurrentSize(); file.setMaxSize(size); file.write((U8*)buffer, size); // Upload that asset to the database const LLInventoryItem* item = getItem(); if (item) { std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory"); std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory"); if (mObjectUUID.isNull() && !agent_url.empty()) { // Saving into agent inventory LLSD body; body["item_id"] = mItemUUID; LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); } else if (!mObjectUUID.isNull() && !task_url.empty()) { // Saving into task inventory LLSD body; body["task_id"] = mObjectUUID; body["item_id"] = mItemUUID; LLHTTPClient::post(task_url, body, new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); } else if (gAssetStorage) { LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE); } } // If this gesture is active, then we need to update the in-memory // active map with the new pointer. if (gGestureManager.isGestureActive(mItemUUID)) { // gesture manager now owns the pointer gGestureManager.replaceGesture(mItemUUID, gesture, asset_id); // replaceGesture may deactivate other gestures so let the // inventory know. gInventory.notifyObservers(); } else { // we're done with this gesture delete gesture; gesture = NULL; } mDirty = FALSE; refresh(); } delete [] buffer; buffer = NULL; }
// static void LLPreviewGesture::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) { LLUUID* item_idp = (LLUUID*)user_data; LLPreview* preview = LLPreview::find(*item_idp); if (preview) { LLPreviewGesture* self = (LLPreviewGesture*)preview; if (0 == status) { LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); std::vector<char> buffer(size+1); file.read((U8*)&buffer[0], size); buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); LLDataPackerAsciiBuffer dp(&buffer[0], size+1); BOOL ok = gesture->deserialize(dp); if (ok) { // Everything has been successful. Load up the UI. self->loadUIFromGesture(gesture); self->mStepList->selectFirstItem(); self->mDirty = FALSE; self->refresh(); self->refreshFromItem(self->getItem()); // to update description and title } else { llwarns << "Unable to load gesture" << llendl; } delete gesture; gesture = NULL; self->mAssetStatus = PREVIEW_ASSET_LOADED; } else { LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { LLDelayedGestureError::gestureMissing( *item_idp ); } else { LLDelayedGestureError::gestureFailedToLoad( *item_idp ); } llwarns << "Problem loading gesture: " << status << llendl; self->mAssetStatus = PREVIEW_ASSET_ERROR; } } delete item_idp; item_idp = NULL; }
void LLPreviewGesture::saveIfNeeded() { if (!gAssetStorage) { llwarns << "Can't save gesture, no asset storage system." << llendl; return; } if (!mDirty) { return; } // Copy the UI into a gesture LLMultiGesture* gesture = createGesture(); // Serialize the gesture S32 max_size = gesture->getMaxSerialSize(); char* buffer = new char[max_size]; LLDataPackerAsciiBuffer dp(buffer, max_size); BOOL ok = gesture->serialize(dp); // <edit> //if (dp.getCurrentSize() > 1000) if(0) // </edit> { LLNotificationsUtil::add("GestureSaveFailedTooManySteps"); delete gesture; gesture = NULL; } else if (!ok) { LLNotificationsUtil::add("GestureSaveFailedTryAgain"); delete gesture; gesture = NULL; } else { // Every save gets a new UUID. Yup. LLTransactionID tid; LLAssetID asset_id; tid.generate(); asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND); S32 size = dp.getCurrentSize(); file.setMaxSize(size); file.write((U8*)buffer, size); BOOL delayedUpload = FALSE; // Upload that asset to the database LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem(); if (item) { std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory"); std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory"); if (mObjectUUID.isNull() && !agent_url.empty()) { //need to disable the preview floater so item //isn't re-saved before new asset arrives //fake out refresh. item->setComplete(FALSE); refresh(); item->setComplete(TRUE); // Saving into agent inventory LLSD body; body["item_id"] = mItemUUID; LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); delayedUpload = TRUE; } else if (!mObjectUUID.isNull() && !task_url.empty()) { // Saving into task inventory LLSD body; body["task_id"] = mObjectUUID; body["item_id"] = mItemUUID; LLHTTPClient::post(task_url, body, new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); } else if (gAssetStorage) { LLLineEditor* descEditor = getChild<LLLineEditor>("desc"); LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE); } } // If this gesture is active, then we need to update the in-memory // active map with the new pointer. if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID)) { // gesture manager now owns the pointer LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, asset_id); // replaceGesture may deactivate other gestures so let the // inventory know. gInventory.notifyObservers(); } else { // we're done with this gesture delete gesture; gesture = NULL; } mDirty = FALSE; // refresh will be called when callback // if triggered when delayedUpload if(!delayedUpload) { refresh(); } } delete [] buffer; buffer = NULL; }
BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); #ifdef MATCH_COMMON_CHARS std::string rest_of_match = ""; std::string buf = ""; #endif item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) { LLMultiGesture* gesture = (*it).second; if (gesture) { const std::string& trigger = gesture->getTrigger(); #ifdef MATCH_COMMON_CHARS //return whole trigger, if received text equals to it if (!LLStringUtil::compareInsensitive(in_str, trigger)) { *out_str = trigger; return TRUE; } #else if (in_len > (S32)trigger.length()) continue; // too short, bail out #endif //return common chars, if more than one trigger matches the prefix std::string trigger_trunc = trigger; LLStringUtil::truncate(trigger_trunc, in_len); if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) { #ifndef MATCH_COMMON_CHARS *out_str = trigger; return TRUE; #else if (rest_of_match.compare("") == 0) { rest_of_match = trigger.substr(in_str.size()); } std::string cur_rest_of_match = trigger.substr(in_str.size()); buf = ""; U32 i=0; while (i<rest_of_match.length() && i<cur_rest_of_match.length()) { if (rest_of_match[i]==cur_rest_of_match[i]) { buf.push_back(rest_of_match[i]); } else { if (i==0) { rest_of_match = ""; } break; } i++; } if (rest_of_match.compare("") == 0) { return FALSE; } if (buf.compare("") != 0) { rest_of_match = buf; } #endif } } } #ifdef MATCH_COMMON_CHARS if (!rest_of_match.empty()) { *out_str = in_str + rest_of_match; return TRUE; } #endif return FALSE; }
// static void LLGestureMgr::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) { LLLoadInfo* info = (LLLoadInfo*)user_data; LLUUID item_id = info->mItemID; BOOL inform_server = info->mInformServer; BOOL deactivate_similar = info->mDeactivateSimilar; delete info; info = NULL; LLGestureMgr& self = LLGestureMgr::instance(); self.mLoadingCount--; if (0 == status) { LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); char* buffer = new char[size+1]; if (buffer == NULL) { LL_ERRS() << "Memory Allocation Failed" << LL_ENDL; return; } file.read((U8*)buffer, size); /* Flawfinder: ignore */ // ensure there's a trailing NULL so strlen will work. buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); LLDataPackerAsciiBuffer dp(buffer, size+1); BOOL ok = gesture->deserialize(dp); if (ok) { if (deactivate_similar) { self.deactivateSimilarGestures(gesture, item_id); // Display deactivation message if this was the last of the bunch. if (self.mLoadingCount == 0 && self.mDeactivateSimilarNames.length() > 0) { // we're done with this set of deactivations LLSD args; args["NAMES"] = self.mDeactivateSimilarNames; LLNotificationsUtil::add("DeactivatedGesturesTrigger", args); } } LLViewerInventoryItem* item = gInventory.getItem(item_id); if(item) { gesture->mName = item->getName(); } else { // Watch this item and set gesture name when item exists in inventory self.setFetchID(item_id); self.startFetch(); } self.mActive[item_id] = gesture; // Everything has been successful. Add to the active list. gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); if (inform_server) { // Inform the database of this change LLMessageSystem* msg = gMessageSystem; msg->newMessage("ActivateGestures"); msg->nextBlock("AgentData"); msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); msg->addU32("Flags", 0x0); msg->nextBlock("Data"); msg->addUUID("ItemID", item_id); msg->addUUID("AssetID", asset_uuid); msg->addU32("GestureFlags", 0x0); gAgent.sendReliableMessage(); } callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id); if(i_cb != self.mCallbackMap.end()) { i_cb->second(gesture); self.mCallbackMap.erase(i_cb); } self.notifyObservers(); } else { LL_WARNS() << "Unable to load gesture" << LL_ENDL; self.mActive.erase(item_id); delete gesture; gesture = NULL; } delete [] buffer; buffer = NULL; } else { LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { LLDelayedGestureError::gestureMissing( item_id ); } else { LLDelayedGestureError::gestureFailedToLoad( item_id ); } LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; LLGestureMgr::instance().mActive.erase(item_id); } }
// static void LLGestureManager::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) { LLLoadInfo* info = (LLLoadInfo*)user_data; LLUUID item_id = info->mItemID; BOOL inform_server = info->mInformServer; BOOL deactivate_similar = info->mDeactivateSimilar; delete info; info = NULL; gGestureManager.mLoadingCount--; if (0 == status) { LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); char* buffer = new char[size+1]; if (buffer == NULL) { llerrs << "Memory Allocation Failed" << llendl; return; } file.read((U8*)buffer, size); /* Flawfinder: ignore */ // ensure there's a trailing NULL so strlen will work. buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); LLDataPackerAsciiBuffer dp(buffer, size+1); BOOL ok = gesture->deserialize(dp); if (ok) { if (deactivate_similar) { gGestureManager.deactivateSimilarGestures(gesture, item_id); // Display deactivation message if this was the last of the bunch. if (gGestureManager.mLoadingCount == 0 && gGestureManager.mDeactivateSimilarNames.length() > 0) { // we're done with this set of deactivations LLStringUtil::format_map_t args; args["[NAMES]"] = gGestureManager.mDeactivateSimilarNames; LLNotifyBox::showXml("DeactivatedGesturesTrigger", args); } } // Everything has been successful. Add to the active list. gGestureManager.mActive[item_id] = gesture; gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); if (inform_server) { // Inform the database of this change LLMessageSystem* msg = gMessageSystem; msg->newMessage("ActivateGestures"); msg->nextBlock("AgentData"); msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); msg->addU32("Flags", 0x0); msg->nextBlock("Data"); msg->addUUID("ItemID", item_id); msg->addUUID("AssetID", asset_uuid); msg->addU32("GestureFlags", 0x0); gAgent.sendReliableMessage(); } gGestureManager.notifyObservers(); } else { llwarns << "Unable to load gesture" << llendl; gGestureManager.mActive.erase(item_id); delete gesture; gesture = NULL; } delete [] buffer; buffer = NULL; } else { LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { LLDelayedGestureError::gestureMissing( item_id ); } else { LLDelayedGestureError::gestureFailedToLoad( item_id ); } llwarns << "Problem loading gesture: " << status << llendl; gGestureManager.mActive.erase(item_id); } }