diff options
| author | Andrey Lihatskiy <andreylproductengine@lindenlab.com> | 2016-06-13 20:53:47 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <andreylproductengine@lindenlab.com> | 2016-06-13 20:53:47 +0300 | 
| commit | d1d39c1dd4bb3454f21a97083575853fd0ca237c (patch) | |
| tree | f094124d935030bc27d5c5ffd7aa8f5976ad6dfe /indra | |
| parent | 1adfaa081fd27d653619c84c520c16516c530ab1 (diff) | |
| parent | a3c4d1cd207358318ce5c91108f9bfcb14fecac6 (diff) | |
Merged in rider_linden/viewer-lynx (pull request #26)
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmessage/llassetstorage.h | 4 | ||||
| -rw-r--r-- | indra/newview/llcompilequeue.cpp | 908 | ||||
| -rw-r--r-- | indra/newview/llcompilequeue.h | 77 | 
3 files changed, 545 insertions, 444 deletions
| diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 4be677a4b0..0f23754096 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -181,6 +181,10 @@ protected:  // Map of known bad assets  typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t; +// *TODO: these typedefs are passed into the VFS via a legacy C function pointer +// future project would be to convert these to C++ callables (std::function<>) so that  +// we can use bind and remove the userData parameter. +//   typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,  										 LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 219bcf0eb0..c592a6c0c6 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -62,6 +62,58 @@  #include "llviewerassetupload.h"  #include "llcorehttputil.h" +namespace +{ + +    const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue"); +    const F32         TIMEOUT_INVENTORY_FETCH(5.0); + + +    class ObjectInventoryFetcher: public LLVOInventoryListener +    { +    public: +        typedef boost::shared_ptr<ObjectInventoryFetcher> ptr_t; + +        ObjectInventoryFetcher(LLEventPump &pump, LLViewerObject* object, void* user_data) : +            mPump(pump), +            LLVOInventoryListener() +        { +            registerVOInventoryListener(object, this); +        } + +        virtual void inventoryChanged(LLViewerObject* object, +            LLInventoryObject::object_list_t* inventory, +            S32 serial_num, +            void* user_data); + +        void fetchInventory()  +        { +            requestVOInventory(); +        } + +        const LLInventoryObject::object_list_t & getInventoryList() const { return mInventoryList; } + +    private: +        LLInventoryObject::object_list_t    mInventoryList; +        LLEventPump &                       mPump; +    }; + +    class HandleScriptUserData +    { +    public: +        HandleScriptUserData(const std::string &pumpname) : +            mPumpname(pumpname) +        { } + +        const std::string &getPumpName() const { return mPumpname; } + +    private: +        std::string mPumpname; +    }; + + +} +  // *NOTE$: A minor specialization of LLScriptAssetUpload, it does not require a buffer   // (and does not save a buffer to the vFS) and it finds the compile queue window and   // displays a compiling message. @@ -149,47 +201,6 @@ BOOL LLFloaterScriptQueue::postBuild()  	return TRUE;  } -// This is the callback method for the viewer object currently being -// worked on. -// NOT static, virtual! -void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object, -											 LLInventoryObject::object_list_t* inv, -											 S32, -											 void* q_id) -{ -	LL_INFOS() << "LLFloaterScriptQueue::inventoryChanged() for  object " -			<< viewer_object->getID() << LL_ENDL; - -	//Remove this listener from the object since its -	//listener callback is now being executed. -	 -	//We remove the listener here because the function -	//removeVOInventoryListener removes the listener from a ViewerObject -	//which it internally stores. -	 -	//If we call this further down in the function, calls to handleInventory -	//and nextObject may update the internally stored viewer object causing -	//the removal of the incorrect listener from an incorrect object. -	 -	//Fixes SL-6119:Recompile scripts fails to complete -	removeVOInventoryListener(); - -	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) -	{ -		handleInventory(viewer_object, inv); -	} -	else -	{ -		// something went wrong... -		// note that we're not working on this one, and move onto the -		// next object in the list. -		LL_WARNS() << "No inventory for " << mCurrentObjectID -				<< LL_ENDL; -		nextObject(); -	} -} - -  // static  void LLFloaterScriptQueue::onCloseBtn(void* user_data)  { @@ -199,7 +210,7 @@ void LLFloaterScriptQueue::onCloseBtn(void* user_data)  void LLFloaterScriptQueue::addObject(const LLUUID& id)  { -	mObjectIDs.push_back(id); +	mObjectIDs.insert(id);  }  BOOL LLFloaterScriptQueue::start() @@ -216,74 +227,24 @@ BOOL LLFloaterScriptQueue::start()  	return startQueue();  } -BOOL LLFloaterScriptQueue::isDone() const +void LLFloaterScriptQueue::addProcessingMessage(const std::string &message, const LLSD &args)  { -	return (mCurrentObjectID.isNull() && (mObjectIDs.size() == 0)); -} +    std::string buffer(LLTrans::getString(message, args)); -// go to the next object. If no objects left, it falls out silently -// and waits to be killed by the window being closed. -BOOL LLFloaterScriptQueue::nextObject() -{ -	U32 count; -	BOOL successful_start = FALSE; -	do -	{ -		count = mObjectIDs.size(); -		LL_INFOS() << "LLFloaterScriptQueue::nextObject() - " << count -				<< " objects left to process." << LL_ENDL; -		mCurrentObjectID.setNull(); -		if(count > 0) -		{ -			successful_start = popNext(); -		} -		LL_INFOS() << "LLFloaterScriptQueue::nextObject() " -				<< (successful_start ? "successful" : "unsuccessful") -				<< LL_ENDL;  -	} while((mObjectIDs.size() > 0) && !successful_start); -	if(isDone() && !mDone) -	{ -		mDone = true; -		getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM); -		getChildView("close")->setEnabled(TRUE); -	} -	return successful_start; +    getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);  } -// returns true if the queue has started, otherwise false.  This -// method pops the top object off of the queue. -BOOL LLFloaterScriptQueue::popNext() +void LLFloaterScriptQueue::addStringMessage(const std::string &message)  { -	// get the first element off of the container, and attempt to get -	// the inventory. -	BOOL rv = FALSE; -	S32 count = mObjectIDs.size(); -	if(mCurrentObjectID.isNull() && (count > 0)) -	{ -		mCurrentObjectID = mObjectIDs.at(0); -		LL_INFOS() << "LLFloaterScriptQueue::popNext() - mCurrentID: " -				<< mCurrentObjectID << LL_ENDL; -		mObjectIDs.erase(mObjectIDs.begin()); -		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); -		if(obj) -		{ -			LL_INFOS() << "LLFloaterScriptQueue::popNext() requesting inv for " -					<< mCurrentObjectID << LL_ENDL; -			LLUUID* id = new LLUUID(getKey().asUUID()); -			registerVOInventoryListener(obj,id); -			requestVOInventory(); -			rv = TRUE; -		} -	} -	return rv; +    getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM);  } -BOOL LLFloaterScriptQueue::startQueue() + +BOOL LLFloaterScriptQueue::isDone() const  { -	return nextObject(); +	return (mCurrentObjectID.isNull() && (mObjectIDs.size() == 0));  } -  ///----------------------------------------------------------------------------  /// Class LLFloaterCompileQueue  ///---------------------------------------------------------------------------- @@ -306,7 +267,7 @@ void LLFloaterCompileQueue::experienceIdsReceived( const LLSD& content )  	{  		mExperienceIds.insert(it->asUUID());  	} -	nextObject(); +//	nextObject();  }  BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const @@ -314,188 +275,282 @@ BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const  	return mExperienceIds.find(id) != mExperienceIds.end();  } +// //Attempt to record this asset ID.  If it can not be inserted into the set  +// //then it has already been processed so return false. +// bool LLFloaterCompileQueue::checkAssetId(const LLUUID &assetId) +// { +//     std::pair<uuid_list_t::iterator, bool> result = mAssetIds.insert(assetId); +//     return result.second; +// } -void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object, -											LLInventoryObject::object_list_t* inv) +void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD &expresult)  { -	// find all of the lsl, leaving off duplicates. We'll remove -	// all matching asset uuids on compilation success. +    LLEventPumps::instance().post(pumpName, expresult); +} -	typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map; -	uuid_item_map asset_item_map; +// *TODO: handleSCriptRetrieval is passed into the VFS via a legacy C function pointer +// future project would be to convert these to C++ callables (std::function<>) so that  +// we can use bind and remove the userData parameter. +//  +void LLFloaterCompileQueue::handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId,  +    LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus) +{ +    LLSD result(LLSD::emptyMap()); -	LLInventoryObject::object_list_t::const_iterator it = inv->begin(); -	LLInventoryObject::object_list_t::const_iterator end = inv->end(); -	for ( ; it != end; ++it) -	{ -		if((*it)->getType() == LLAssetType::AT_LSL_TEXT) -		{ -			LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); -			// Check permissions before allowing the user to retrieve data. -			if (item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID())  && -				item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) ) -			{ -				LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item); -				mCurrentScripts.push_back(script); -				asset_item_map.insert(std::make_pair(item->getAssetUUID(), item)); -			} -		} -	} +    result["asset_id"] = assetId; +    if (status) +    { +        result["error"] = status; +      +        if (status == LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE) +        { +            result["message"] = LLTrans::getString("CompileQueueProblemDownloading") + (":"); +            result["alert"] = LLTrans::getString("CompileQueueScriptNotFound"); +        } +        else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) +        { +            result["message"] = LLTrans::getString("CompileQueueInsufficientPermFor") + (":"); +            result["alert"] = LLTrans::getString("CompileQueueInsufficientPermDownload"); +        } +        else +        { +            result["message"] = LLTrans::getString("CompileQueueUnknownFailure"); +        } +    } -	if (asset_item_map.empty()) -	{ -		// There are no scripts in this object.  move on. -		nextObject(); -	} -	else -	{ -		// request all of the assets. -		uuid_item_map::iterator iter; -		for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++) -		{ -			LLInventoryItem *itemp = iter->second; -			LLScriptQueueData* datap = new LLScriptQueueData(getKey().asUUID(), -				viewer_object->getID(), itemp); - -            LLExperienceCache::instance().fetchAssociatedExperience(itemp->getParentUUID(), itemp->getUUID(), -                    boost::bind(&LLFloaterCompileQueue::requestAsset, datap, _1)); -		} -	} -} +    LLEventPumps::instance().post(((HandleScriptUserData *)userData)->getPumpName(), result); +} -void LLFloaterCompileQueue::requestAsset( LLScriptQueueData* datap, const LLSD& experience ) +/*static*/ +void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent)  { -	LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", datap->mQueueID); -	if(!queue) -	{ -		delete datap; -		return; -	} -	if(experience.has(LLExperienceCache::EXPERIENCE_ID)) -	{ -		datap->mExperienceId=experience[LLExperienceCache::EXPERIENCE_ID].asUUID(); -		if(!queue->hasExperience(datap->mExperienceId)) -		{ -			std::string buffer = LLTrans::getString("CompileNoExperiencePerm", LLSD::emptyMap() -				.with("SCRIPT", datap->mItem->getName()) -				.with("EXPERIENCE", experience[LLExperienceCache::NAME].asString())); -	 -			queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); -			queue->removeItemByItemID(datap->mItem->getUUID()); -			delete datap; -			return; -		} -	} -	//LL_INFOS() << "ITEM NAME 2: " << names.get(i) << LL_ENDL; -	gAssetStorage->getInvItemAsset(datap->mHost, -		gAgent.getID(), -		gAgent.getSessionID(), -		datap->mItem->getPermissions().getOwner(), -		datap->mTaskId, -		datap->mItem->getUUID(), -		datap->mItem->getAssetUUID(), -		datap->mItem->getType(), -		LLFloaterCompileQueue::scriptArrived, -		(void*)datap); +    LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent); +    if (!queue) +        return; + +    queue->experienceIdsReceived(result["experience_ids"]); + +    LLHandle<LLFloaterScriptQueue> hFloater(queue->getDerivedHandle<LLFloaterScriptQueue>()); + +    fnQueueAction_t fn = boost::bind(LLFloaterCompileQueue::processScript, +        queue->getDerivedHandle<LLFloaterCompileQueue>(), _1, _2, _3); + + +    LLCoros::instance().launch("ScriptQueueCompile", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, +        queue->mStartString, +        hFloater, +        queue->mObjectIDs, +        fn)); +  } -/*static*/ -void LLFloaterCompileQueue::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId) +bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater, +    const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { +    LLSD result; +    LLFloaterCompileQueue *that = hfloater.get(); +    bool monocompile = that->mMono; + +    if (!that) +        return false; -    LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(queueId)); -    if (queue) +    // Initial test to see if we can (or should) attempt to compile the script. +    LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory);      { -        // Bytecode save completed -        if (response["compiled"]) + +        if (!item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) || +            !item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()))          { -            std::string message = std::string("Compilation of \"") + scriptName + std::string("\" succeeded"); +            std::string buffer = "Skipping: " + item->getName() + "(Permissions)"; +            that->addStringMessage(buffer); +            return true; +        } -            queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM); -            LL_INFOS() << message << LL_ENDL; +//         if (!that->checkAssetId(item->getAssetUUID())) +//         { +//             std::string buffer = "Skipping: " + item->getName() + "(Repeat)"; +//             that->addStringMessage(buffer); +//             return true; +//         } +    } +    that = NULL; + +    // Attempt to retrieve the experience +    LLUUID experienceId; +    { +        LLExperienceCache::instance().fetchAssociatedExperience(inventory->getParentUUID(), inventory->getUUID(), +            boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1)); + +        result = llcoro::suspendUntilEventOnWithTimeout(pump, TIMEOUT_INVENTORY_FETCH,  +            LLSD().with("timeout", LLSD::Boolean(true))); + +        that = hfloater.get(); +        if (!that) +        { +            return false;          } -        else + +        if (result.has("timeout") && result["timeout"].asBoolean())          { -            LLSD compile_errors = response["errors"]; -            for (LLSD::array_const_iterator line = compile_errors.beginArray(); -                line < compile_errors.endArray(); line++) -            { -                std::string str = line->asString(); -                str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); +            std::string buffer = that->getString("Timeout") + ": " + inventory->getName(); +            that->addStringMessage(buffer); +            return true; +        } -                queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(str, ADD_BOTTOM); +        if (result.has(LLExperienceCache::EXPERIENCE_ID)) +        { +            experienceId = result[LLExperienceCache::EXPERIENCE_ID].asUUID(); +            if (!that->hasExperience(experienceId)) +            { +                that->addProcessingMessage("CompileNoExperiencePerm", LLSD() +                    .with("SCRIPT", inventory->getName()) +                    .with("EXPERIENCE", result[LLExperienceCache::NAME].asString())); +                return true;              } -            LL_INFOS() << response["errors"] << LL_ENDL;          }      } +    that = NULL; + +    { +        HandleScriptUserData    userData(pump.getName()); + + +        // request the asset +        gAssetStorage->getInvItemAsset(LLHost(), +            gAgent.getID(), +            gAgent.getSessionID(), +            item->getPermissions().getOwner(), +            object->getID(), +            item->getUUID(), +            item->getAssetUUID(), +            item->getType(), +            &LLFloaterCompileQueue::handleScriptRetrieval, +            &userData); + +        result = llcoro::suspendUntilEventOnWithTimeout(pump, TIMEOUT_INVENTORY_FETCH,  +            LLSD().with("timeout", LLSD::Boolean(true))); +    } + +    that = hfloater.get(); +    if (!that) +    { +        return false; +    } + +    if (result.has("timeout")) +    { +        if (result.has("timeout") && result["timeout"].asBoolean()) +        { +            std::string buffer = that->getString("Timeout") + ": " + inventory->getName(); +            that->addStringMessage(buffer); +            return true; +        } +    } + +    if (result.has("error")) +    { +        LL_WARNS("SCRIPTQ") << "Inventory fetch returned with error. Code: " << result["error"].asString() << LL_ENDL; +        std::string buffer = result["message"].asString() + " " + inventory->getName(); +        that->addStringMessage(buffer); + +        if (result.has("alert")) +        { +            LLSD args; +            args["MESSAGE"] = result["alert"].asString(); +            LLNotificationsUtil::add("SystemMessage", args); +        } +        return true; +    } + +    LLUUID assetId = result["asset_id"]; +    that = NULL; + + +    std::string url = object->getRegion()->getCapability("UpdateScriptTask"); + + +    { +        LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(object->getID(),  +            inventory->getUUID(),  +            assetId,  +            monocompile ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, +            true,  +            inventory->getName(),  +            LLUUID(),  +            experienceId,  +            boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _4))); + +        LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); +    } + +    result = llcoro::suspendUntilEventOnWithTimeout(pump, TIMEOUT_INVENTORY_FETCH, LLSD().with("timeout", LLSD::Boolean(true))); + +    that = hfloater.get(); +    if (!that) +    { +        return false; +    } + +    if (result.has("timeout")) +    { +        if (result.has("timeout") && result["timeout"].asBoolean()) +        { +            std::string buffer = that->getString("Timeout") + ": " + inventory->getName(); +            that->addStringMessage(buffer); +            return true; +        } +    } + +    // Bytecode save completed +    if (result["compiled"]) +    { +        std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" succeeded"); + +        that->addStringMessage(buffer); +        LL_INFOS() << buffer << LL_ENDL; +    } +    else +    { +        LLSD compile_errors = result["errors"]; +        std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" failed:"); +        that->addStringMessage(buffer); +        for (LLSD::array_const_iterator line = compile_errors.beginArray(); +            line < compile_errors.endArray(); line++) +        { +            std::string str = line->asString(); +            str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + +            that->addStringMessage(str); +        } +        LL_INFOS() << result["errors"] << LL_ENDL; +    } + +    return true;  } -// This is the callback for when each script arrives -// static -void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, -										  LLAssetType::EType type, -										  void* user_data, S32 status, LLExtStat ext_status) +bool LLFloaterCompileQueue::startQueue()  { -	LL_INFOS() << "LLFloaterCompileQueue::scriptArrived()" << LL_ENDL; -	LLScriptQueueData* data = (LLScriptQueueData*)user_data; -	if(!data) -	{ -		return; -	} -	LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID); -	 -	std::string buffer; -	if(queue && (0 == status)) -	{ -        LLViewerObject* object = gObjectList.findObject(data->mTaskId); -        if (object) +    LLViewerRegion* region = gAgent.getRegion(); +    if (region) +    { +        std::string lookup_url = region->getCapability("GetCreatorExperiences"); +        if (!lookup_url.empty())          { -            std::string url = object->getRegion()->getCapability("UpdateScriptTask"); -            std::string scriptName = data->mItem->getName(); - -            LLBufferedAssetUploadInfo::taskUploadFinish_f proc = boost::bind(&LLFloaterCompileQueue::finishLSLUpload, _1, _2, _3, _4,  -                scriptName, data->mQueueID); +            LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success = +                boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID()); -            LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(data->mTaskId, data->mItem->getUUID(), asset_id, -                (queue->mMono) ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, -                true, scriptName, data->mQueueID, data->mExperienceId, proc)); +            LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure = +                boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID()); -            LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); +            LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url, +                success, failure); +            return TRUE;          } -	} -	else -	{ -		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) -		{ -			LLSD args; -			args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound"); -			LLNotificationsUtil::add("SystemMessage", args); -			 -			buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mItem->getName(); -		} -		else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) -		{ -			LLSD args; -			args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload"); -			LLNotificationsUtil::add("SystemMessage", args); - -			buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mItem->getName(); -		} -		else -		{ -			buffer = LLTrans::getString("CompileQueueUnknownFailure") + (" ") + data->mItem->getName(); -		} - -		LL_WARNS() << "Problem downloading script asset." << LL_ENDL; -		if(queue) queue->removeItemByItemID(data->mItem->getUUID()); -	} -	if(queue && (buffer.size() > 0))  -	{ -		queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); -	} -	delete data; +    } + +    return true;  } @@ -514,40 +569,42 @@ LLFloaterResetQueue::~LLFloaterResetQueue()  {   } -void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, -										  LLInventoryObject::object_list_t* inv) +bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,  +    const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -	// find all of the lsl, leaving off duplicates. We'll remove -	// all matching asset uuids on compilation success. +    LLFloaterScriptQueue *that = hfloater.get(); +    if (that) +    { +        std::string buffer; +        buffer = that->getString("Resetting") + (": ") + inventory->getName(); +        that->addStringMessage(buffer); +    } +     +    LLMessageSystem* msg = gMessageSystem; +    msg->newMessageFast(_PREHASH_ScriptReset); +    msg->nextBlockFast(_PREHASH_AgentData); +    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +    msg->nextBlockFast(_PREHASH_Script); +    msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); +    msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); +    msg->sendReliable(object->getRegion()->getHost()); + +    return true; +} -	LLInventoryObject::object_list_t::const_iterator it = inv->begin(); -	LLInventoryObject::object_list_t::const_iterator end = inv->end(); -	for ( ; it != end; ++it) -	{ -		if((*it)->getType() == LLAssetType::AT_LSL_TEXT) -		{ -			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - -			if (object) -			{ -				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); -				std::string buffer; -				buffer = getString("Resetting") + (": ") + item->getName(); -				getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); -				LLMessageSystem* msg = gMessageSystem; -				msg->newMessageFast(_PREHASH_ScriptReset); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->nextBlockFast(_PREHASH_Script); -				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); -				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); -				msg->sendReliable(object->getRegion()->getHost()); -			} -		} -	} +bool LLFloaterResetQueue::startQueue() +{ +    fnQueueAction_t fn = boost::bind(LLFloaterResetQueue::resetObjectScripts, +        getDerivedHandle<LLFloaterScriptQueue>(), _1, _2, _3); -	nextObject();	 +    LLCoros::instance().launch("ScriptResetQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, +        mStartString, +        getDerivedHandle<LLFloaterScriptQueue>(), +        mObjectIDs, +        fn)); + +    return true;  }  ///---------------------------------------------------------------------------- @@ -565,44 +622,46 @@ LLFloaterRunQueue::~LLFloaterRunQueue()  {   } -void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, -										  LLInventoryObject::object_list_t* inv) +bool LLFloaterRunQueue::runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,  +    const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -	// find all of the lsl, leaving off duplicates. We'll remove -	// all matching asset uuids on compilation success. -	LLInventoryObject::object_list_t::const_iterator it = inv->begin(); -	LLInventoryObject::object_list_t::const_iterator end = inv->end(); -	for ( ; it != end; ++it) -	{ -		if((*it)->getType() == LLAssetType::AT_LSL_TEXT) -		{ -			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - -			if (object) -			{ -				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); -				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); -				std::string buffer; -				buffer = getString("Running") + (": ") + item->getName(); -				list->addSimpleElement(buffer, ADD_BOTTOM); - -				LLMessageSystem* msg = gMessageSystem; -				msg->newMessageFast(_PREHASH_SetScriptRunning); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->nextBlockFast(_PREHASH_Script); -				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); -				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); -				msg->addBOOLFast(_PREHASH_Running, TRUE); -				msg->sendReliable(object->getRegion()->getHost()); -			} -		} -	} +    LLFloaterScriptQueue *that = hfloater.get(); +    if (that) +    { +        std::string buffer; +        buffer = that->getString("Running") + (": ") + inventory->getName(); +        that->addStringMessage(buffer); +    } -	nextObject();	 +    LLMessageSystem* msg = gMessageSystem; +    msg->newMessageFast(_PREHASH_SetScriptRunning); +    msg->nextBlockFast(_PREHASH_AgentData); +    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +    msg->nextBlockFast(_PREHASH_Script); +    msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); +    msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); +    msg->addBOOLFast(_PREHASH_Running, TRUE); +    msg->sendReliable(object->getRegion()->getHost()); + +    return true;  } +bool LLFloaterRunQueue::startQueue() +{ +    LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>()); +    fnQueueAction_t fn = boost::bind(LLFloaterRunQueue::runObjectScripts, hFloater, _1, _2, _3); + +    LLCoros::instance().launch("ScriptRunQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, +        mStartString, +        hFloater, +        mObjectIDs, +        fn)); + +    return true; +} + +  ///----------------------------------------------------------------------------  /// Class LLFloaterNotRunQueue  ///---------------------------------------------------------------------------- @@ -618,96 +677,151 @@ LLFloaterNotRunQueue::~LLFloaterNotRunQueue()  {   } -void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id) +bool LLFloaterNotRunQueue::stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,  +    const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -	LL_INFOS() << "LLFloaterCompileQueue::removeItemByAssetID()" << LL_ENDL; -	for(S32 i = 0; i < mCurrentScripts.size(); ) -	{ -		if(asset_id == mCurrentScripts.at(i)->getUUID()) -		{ -			vector_replace_with_last(mCurrentScripts, mCurrentScripts.begin() + i); -		} -		else -		{ -			++i; -		} -	} -	if(mCurrentScripts.empty()) -	{ -		nextObject(); -	} +    LLFloaterScriptQueue *that = hfloater.get(); +    if (that) +    { +        std::string buffer; +        buffer = that->getString("NotRunning") + (": ") + inventory->getName(); +        that->addStringMessage(buffer); +    } + +    LLMessageSystem* msg = gMessageSystem; +    msg->newMessageFast(_PREHASH_SetScriptRunning); +    msg->nextBlockFast(_PREHASH_AgentData); +    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +    msg->nextBlockFast(_PREHASH_Script); +    msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); +    msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); +    msg->addBOOLFast(_PREHASH_Running, FALSE); +    msg->sendReliable(object->getRegion()->getHost()); + +    return true;  } -BOOL LLFloaterCompileQueue::startQueue() +bool LLFloaterNotRunQueue::startQueue()  { -	LLViewerRegion* region = gAgent.getRegion(); -	if (region) -	{ -		std::string lookup_url=region->getCapability("GetCreatorExperiences");  -		if(!lookup_url.empty()) -		{ -            LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success = -                boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID()); +    LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>()); -            LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure = -                boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID()); +    fnQueueAction_t fn = boost::bind(&LLFloaterNotRunQueue::stopObjectScripts, hFloater, _1, _2, _3); +    LLCoros::instance().launch("ScriptQueueNotRun", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, +        mStartString, +        hFloater, +        mObjectIDs, +        fn)); -            LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url, -                success, failure); -            return TRUE; -		} -	} -	return nextObject(); +    return true;  } -/*static*/ -void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent) +///---------------------------------------------------------------------------- +/// Local function definitions +///---------------------------------------------------------------------------- +void ObjectInventoryFetcher::inventoryChanged(LLViewerObject* object, +        LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data)  { -    LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent); -    if (!queue) -        return; +    mInventoryList.clear(); +    mInventoryList.assign(inventory->begin(), inventory->end()); + +    mPump.post(LLSD().with("changed", LLSD::Boolean(true))); -    queue->experienceIdsReceived(result["experience_ids"]);  } -void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, -										  LLInventoryObject::object_list_t* inv) +void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater, +    uuid_list_t objectList, fnQueueAction_t func)  { -	// find all of the lsl, leaving off duplicates. We'll remove -	// all matching asset uuids on compilation success. -	LLInventoryObject::object_list_t::const_iterator it = inv->begin(); -	LLInventoryObject::object_list_t::const_iterator end = inv->end(); -	for ( ; it != end; ++it) -	{ -		if((*it)->getType() == LLAssetType::AT_LSL_TEXT) -		{ -			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - -			if (object) -			{ -				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); -				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); -				std::string buffer; -				buffer = getString("NotRunning") + (": ") +item->getName(); -				list->addSimpleElement(buffer, ADD_BOTTOM); -	 -				LLMessageSystem* msg = gMessageSystem; -				msg->newMessageFast(_PREHASH_SetScriptRunning); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->nextBlockFast(_PREHASH_Script); -				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); -				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); -				msg->addBOOLFast(_PREHASH_Running, FALSE); -				msg->sendReliable(object->getRegion()->getHost()); -			} -		} -	} +    LLCoros::set_consuming(true); +    LLFloaterScriptQueue * floater(NULL); +    LLEventMailDrop        maildrop(QUEUE_EVENTPUMP_NAME, true); + +//     floater = hfloater.get(); +//     floater->addProcessingMessage("Starting", +//         LLSD() +//         .with("[START]", action) +//         .with("[COUNT]", LLSD::Integer(objectList.size()))); +//     floater = NULL; + +    for (uuid_list_t::iterator itObj(objectList.begin()); (itObj != objectList.end()); ++itObj) +    { +        bool firstForObject = true; +        LL_INFOS("SCRIPTQ") << "Next object in queue with ID=" << (*itObj).asString() << LL_ENDL; -	nextObject();	 -} +        LLPointer<LLViewerObject> obj = gObjectList.findObject(*itObj); +        LLInventoryObject::object_list_t inventory; +        if (obj) +        { +            ObjectInventoryFetcher::ptr_t fetcher(new ObjectInventoryFetcher(maildrop, obj, NULL)); -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- +            fetcher->fetchInventory(); + +            LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, TIMEOUT_INVENTORY_FETCH, +                LLSD().with("timeout", LLSD::Boolean(true))); + +            if (result.has("timeout") && result["timeout"].asBoolean()) +            { +                LL_WARNS("SCRIPTQ") << "Unable to retrieve inventory for object " << (*itObj).asString() << +                    ". Skipping to next object." << LL_ENDL; +                continue; +            } + +            inventory.assign(fetcher->getInventoryList().begin(), fetcher->getInventoryList().end()); +        } +        else +        { +            LL_WARNS("SCRIPTQ") << "Unable to retrieve object with ID of " << (*itObj) << +                ". Skipping to next." << LL_ENDL; +            continue; +        } + +        // TODO: Get the name of the object we are looking at here so that we can display it below. +        //std::string objName = (dynamic_cast<LLInventoryObject *>(obj.get()))->getName(); +        LL_DEBUGS("SCRIPTQ") << "Object has " << inventory.size() << " items." << LL_ENDL; + +        for (LLInventoryObject::object_list_t::iterator itInv = inventory.begin(); +            itInv != inventory.end(); ++itInv) +        { +            floater = hfloater.get(); +            if (!floater) +            { +                LL_WARNS("SCRIPTQ") << "Script Queue floater closed! Canceling remaining ops" << LL_ENDL; +                break; +            } + +            // note, we have a smart pointer to the obj above... but if we didn't we'd check that  +            // it still exists here. + +            if (((*itInv)->getType() == LLAssetType::AT_LSL_TEXT)) +            { +                LL_DEBUGS("SCRIPTQ") << "Inventory item " << (*itInv)->getUUID().asString() << "\"" << (*itInv)->getName() << "\"" << LL_ENDL; +                if (firstForObject) +                { +                    //floater->addStringMessage(objName + ":"); +                    firstForObject = false; +                } + +                if (!func(obj, (*itInv), maildrop)) +                { +                    continue; +                } +            } + +            llcoro::suspend(); +        } +        // Just test to be sure the floater is still present before calling the func +        if (!hfloater.get()) +        { +            LL_WARNS("SCRIPTQ") << "Script Queue floater dismissed." << LL_ENDL; +            break; +        } + +    } + +    floater = hfloater.get(); +    if (floater) +    { +        floater->addStringMessage("Done"); +        floater->getChildView("close")->setEnabled(TRUE); +    } +} diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h index 46bcb9746b..271ac5e05d 100644 --- a/indra/newview/llcompilequeue.h +++ b/indra/newview/llcompilequeue.h @@ -37,6 +37,8 @@  #include "llviewerinventory.h" +#include "llevents.h" +  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFloaterScriptQueue  // @@ -48,7 +50,7 @@  // scripts manipulated.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener +class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/  {  public:  	LLFloaterScriptQueue(const LLSD& key); @@ -64,29 +66,18 @@ public:  	// start() returns TRUE if the queue has started, otherwise FALSE.  	BOOL start(); -protected: -	// This is the callback method for the viewer object currently -	// being worked on. -	/*virtual*/ void inventoryChanged(LLViewerObject* obj, -								 LLInventoryObject::object_list_t* inv, -								 S32 serial_num, -								 void* queue); -	 -	// This is called by inventoryChanged -	virtual void handleInventory(LLViewerObject* viewer_obj, -								LLInventoryObject::object_list_t* inv) = 0; +    void addProcessingMessage(const std::string &message, const LLSD &args); +    void addStringMessage(const std::string &message); +    std::string getStartString() const { return mStartString; } + +protected:  	static void onCloseBtn(void* user_data);  	// returns true if this is done  	BOOL isDone() const; -	virtual BOOL startQueue(); - -	// go to the next object. If no objects left, it falls out -	// silently and waits to be killed by the deleteIfDone() callback. -	BOOL nextObject(); -	BOOL popNext(); +	virtual bool startQueue() = 0;  	void setStartString(const std::string& s) { mStartString = s; } @@ -96,12 +87,16 @@ protected:  	LLButton* mCloseBtn;  	// Object Queue -	std::vector<LLUUID> mObjectIDs; +    uuid_list_t     mObjectIDs;  	LLUUID mCurrentObjectID;  	bool mDone;  	std::string mStartString;  	bool mMono; + +    typedef boost::function<bool(const LLPointer<LLViewerObject> &, LLInventoryObject*, LLEventPump &)>   fnQueueAction_t; +    static void objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater, uuid_list_t objectList, fnQueueAction_t func); +  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -122,8 +117,6 @@ class LLFloaterCompileQueue : public LLFloaterScriptQueue  {  	friend class LLFloaterReg;  public: -	// remove any object in mScriptScripts with the matching uuid. -	void removeItemByItemID(const LLUUID& item_id);  	void experienceIdsReceived( const LLSD& content );  	BOOL hasExperience(const LLUUID& id)const; @@ -132,27 +125,17 @@ protected:  	LLFloaterCompileQueue(const LLSD& key);  	virtual ~LLFloaterCompileQueue(); -	// This is called by inventoryChanged -	virtual void handleInventory(LLViewerObject* viewer_obj, -								LLInventoryObject::object_list_t* inv); - -	static void requestAsset(struct LLScriptQueueData* datap, const LLSD& experience); +	virtual bool startQueue(); +    static bool processScript(LLHandle<LLFloaterCompileQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); -    static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId); - -	// This is the callback for when each script arrives -	static void scriptArrived(LLVFS *vfs, const LLUUID& asset_id, -								LLAssetType::EType type, -								void* user_data, S32 status, LLExtStat ext_status); - -	virtual BOOL startQueue(); -protected: -	LLViewerInventoryItem::item_array_t mCurrentScripts; +    //bool checkAssetId(const LLUUID &assetId); +    static void handleHTTPResponse(std::string pumpName, const LLSD &expresult); +    static void handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId, LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus);  private:      static void processExperienceIdResults(LLSD result, LLUUID parent); - +    //uuid_list_t mAssetIds;  // list of asset IDs processed.  	uuid_list_t mExperienceIds;  }; @@ -169,9 +152,9 @@ protected:  	LLFloaterResetQueue(const LLSD& key);  	virtual ~LLFloaterResetQueue(); -	// This is called by inventoryChanged -	virtual void handleInventory(LLViewerObject* viewer_obj, -								LLInventoryObject::object_list_t* inv); +    static bool resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + +    virtual bool startQueue();  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -186,10 +169,10 @@ class LLFloaterRunQueue : public LLFloaterScriptQueue  protected:  	LLFloaterRunQueue(const LLSD& key);  	virtual ~LLFloaterRunQueue(); -	 -	// This is called by inventoryChanged -	virtual void handleInventory(LLViewerObject* viewer_obj, -								LLInventoryObject::object_list_t* inv); + +    static bool runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + +    virtual bool startQueue();  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -205,9 +188,9 @@ protected:  	LLFloaterNotRunQueue(const LLSD& key);  	virtual ~LLFloaterNotRunQueue(); -	// This is called by inventoryChanged -	virtual void handleInventory(LLViewerObject* viewer_obj, -								LLInventoryObject::object_list_t* inv); +    static bool stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + +    virtual bool startQueue();  };  #endif // LL_LLCOMPILEQUEUE_H | 
