PageRenderTime 327ms CodeModel.GetById 51ms app.highlight 213ms RepoModel.GetById 54ms app.codeStats 1ms

/indra/newview/llcompilequeue.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 769 lines | 566 code | 96 blank | 107 comment | 76 complexity | d2b0d413754dde3001a8d7ed792b1748 MD5 | raw file
  1/** 
  2 * @file llcompilequeue.cpp
  3 * @brief LLCompileQueueData class implementation
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27/**
 28 *
 29 * Implementation of the script queue which keeps an array of object
 30 * UUIDs and manipulates all of the scripts on each of them. 
 31 *
 32 */
 33
 34
 35#include "llviewerprecompiledheaders.h"
 36
 37#include "llcompilequeue.h"
 38
 39#include "llagent.h"
 40#include "llassetuploadqueue.h"
 41#include "llassetuploadresponders.h"
 42#include "llchat.h"
 43#include "llfloaterreg.h"
 44#include "llviewerwindow.h"
 45#include "llviewerobject.h"
 46#include "llviewerobjectlist.h"
 47#include "llviewerregion.h"
 48#include "lscript_rt_interface.h"
 49#include "llviewercontrol.h"
 50#include "llviewerobject.h"
 51#include "llviewerregion.h"
 52#include "llresmgr.h"
 53
 54#include "llbutton.h"
 55#include "lldir.h"
 56#include "llnotificationsutil.h"
 57#include "llviewerstats.h"
 58#include "llvfile.h"
 59#include "lluictrlfactory.h"
 60#include "lltrans.h"
 61
 62#include "llselectmgr.h"
 63
 64// *TODO: This should be separated into the script queue, and the floater views of that queue.
 65// There should only be one floater class that can view any queue type
 66
 67///----------------------------------------------------------------------------
 68/// Local function declarations, constants, enums, and typedefs
 69///----------------------------------------------------------------------------
 70
 71struct LLScriptQueueData
 72{
 73	LLUUID mQueueID;
 74	std::string mScriptName;
 75	LLUUID mTaskId;
 76	LLUUID mItemId;
 77	LLScriptQueueData(const LLUUID& q_id, const std::string& name, const LLUUID& task_id, const LLUUID& item_id) :
 78		mQueueID(q_id), mScriptName(name), mTaskId(task_id), mItemId(item_id) {}
 79
 80};
 81
 82///----------------------------------------------------------------------------
 83/// Class LLFloaterScriptQueue
 84///----------------------------------------------------------------------------
 85
 86// Default constructor
 87LLFloaterScriptQueue::LLFloaterScriptQueue(const LLSD& key) :
 88	LLFloater(key),
 89	mDone(false),
 90	mMono(false)
 91{
 92}
 93
 94// Destroys the object
 95LLFloaterScriptQueue::~LLFloaterScriptQueue()
 96{
 97}
 98
 99BOOL LLFloaterScriptQueue::postBuild()
100{
101	childSetAction("close",onCloseBtn,this);
102	getChildView("close")->setEnabled(FALSE);
103	return TRUE;
104}
105
106// This is the callback method for the viewer object currently being
107// worked on.
108// NOT static, virtual!
109void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object,
110											 LLInventoryObject::object_list_t* inv,
111											 S32,
112											 void* q_id)
113{
114	llinfos << "LLFloaterScriptQueue::inventoryChanged() for  object "
115			<< viewer_object->getID() << llendl;
116
117	//Remove this listener from the object since its
118	//listener callback is now being executed.
119	
120	//We remove the listener here because the function
121	//removeVOInventoryListener removes the listener from a ViewerObject
122	//which it internally stores.
123	
124	//If we call this further down in the function, calls to handleInventory
125	//and nextObject may update the interally stored viewer object causing
126	//the removal of the incorrect listener from an incorrect object.
127	
128	//Fixes SL-6119:Recompile scripts fails to complete
129	removeVOInventoryListener();
130
131	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
132	{
133		handleInventory(viewer_object, inv);
134	}
135	else
136	{
137		// something went wrong...
138		// note that we're not working on this one, and move onto the
139		// next object in the list.
140		llwarns << "No inventory for " << mCurrentObjectID
141				<< llendl;
142		nextObject();
143	}
144}
145
146
147// static
148void LLFloaterScriptQueue::onCloseBtn(void* user_data)
149{
150	LLFloaterScriptQueue* self = (LLFloaterScriptQueue*)user_data;
151	self->closeFloater();
152}
153
154void LLFloaterScriptQueue::addObject(const LLUUID& id)
155{
156	mObjectIDs.put(id);
157}
158
159BOOL LLFloaterScriptQueue::start()
160{
161	//llinfos << "LLFloaterCompileQueue::start()" << llendl;
162	std::string buffer;
163
164	LLSelectMgr *mgr = LLSelectMgr::getInstance();
165	LLObjectSelectionHandle selectHandle = mgr->getSelection();
166	U32 n_objects = 0;
167	if (gSavedSettings.getBOOL("EditLinkedParts"))
168	{
169		n_objects = selectHandle->getObjectCount();
170	}
171	else
172	{
173		n_objects = selectHandle->getRootObjectCount();
174	}
175
176	LLStringUtil::format_map_t args;
177	args["[START]"] = mStartString;
178	args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
179	buffer = getString ("Starting", args);
180	
181	getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
182
183	return nextObject();
184}
185
186BOOL LLFloaterScriptQueue::isDone() const
187{
188	return (mCurrentObjectID.isNull() && (mObjectIDs.count() == 0));
189}
190
191// go to the next object. If no objects left, it falls out silently
192// and waits to be killed by the window being closed.
193BOOL LLFloaterScriptQueue::nextObject()
194{
195	S32 count;
196	BOOL successful_start = FALSE;
197	do
198	{
199		count = mObjectIDs.count();
200		llinfos << "LLFloaterScriptQueue::nextObject() - " << count
201				<< " objects left to process." << llendl;
202		mCurrentObjectID.setNull();
203		if(count > 0)
204		{
205			successful_start = popNext();
206		}
207		llinfos << "LLFloaterScriptQueue::nextObject() "
208				<< (successful_start ? "successful" : "unsuccessful")
209				<< llendl; 
210	} while((mObjectIDs.count() > 0) && !successful_start);
211	if(isDone() && !mDone)
212	{
213		mDone = true;
214		getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("Done"));
215		getChildView("close")->setEnabled(TRUE);
216	}
217	return successful_start;
218}
219
220// returns true if the queue has started, otherwise false.  This
221// method pops the top object off of the queue.
222BOOL LLFloaterScriptQueue::popNext()
223{
224	// get the first element off of the container, and attempt to get
225	// the inventory.
226	BOOL rv = FALSE;
227	S32 count = mObjectIDs.count();
228	if(mCurrentObjectID.isNull() && (count > 0))
229	{
230		mCurrentObjectID = mObjectIDs.get(0);
231		llinfos << "LLFloaterScriptQueue::popNext() - mCurrentID: "
232				<< mCurrentObjectID << llendl;
233		mObjectIDs.remove(0);
234		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
235		if(obj)
236		{
237			llinfos << "LLFloaterScriptQueue::popNext() requesting inv for "
238					<< mCurrentObjectID << llendl;
239			LLUUID* id = new LLUUID(getKey().asUUID());
240			registerVOInventoryListener(obj,id);
241			requestVOInventory();
242			rv = TRUE;
243		}
244	}
245	return rv;
246}
247
248
249///----------------------------------------------------------------------------
250/// Class LLFloaterCompileQueue
251///----------------------------------------------------------------------------
252
253class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier
254{
255public:
256	
257	LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) :
258		mQueueId(queue_id)
259	{
260	}
261		
262	virtual LLAssetUploadQueue* get() const 
263	{
264		LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(mQueueId));
265		if(NULL == queue)
266		{
267			return NULL;
268		}
269		return queue->getUploadQueue();
270	}
271
272	virtual void log(std::string message) const
273	{
274		LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(mQueueId));
275		if(NULL == queue)
276		{
277			return;
278		}
279
280		queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(message);
281	}
282		
283private:
284	LLUUID mQueueId;
285};
286
287LLFloaterCompileQueue::LLFloaterCompileQueue(const LLSD& key)
288  : LLFloaterScriptQueue(key)
289{
290	setTitle(LLTrans::getString("CompileQueueTitle"));
291	setStartString(LLTrans::getString("CompileQueueStart"));
292														 															 
293	mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(key.asUUID()));
294}
295
296LLFloaterCompileQueue::~LLFloaterCompileQueue()
297{ 
298}
299
300void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
301											LLInventoryObject::object_list_t* inv)
302{
303	// find all of the lsl, leaving off duplicates. We'll remove
304	// all matching asset uuids on compilation success.
305
306	typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map;
307	uuid_item_map asset_item_map;
308
309	LLInventoryObject::object_list_t::const_iterator it = inv->begin();
310	LLInventoryObject::object_list_t::const_iterator end = inv->end();
311	for ( ; it != end; ++it)
312	{
313		if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
314		{
315			LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
316			// Check permissions before allowing the user to retrieve data.
317			if (item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID())  &&
318				item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) )
319			{
320				LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item);
321				mCurrentScripts.put(script);
322				asset_item_map.insert(std::make_pair(item->getAssetUUID(), item));
323			}
324		}
325	}
326
327	if (asset_item_map.empty())
328	{
329		// There are no scripts in this object.  move on.
330		nextObject();
331	}
332	else
333	{
334		// request all of the assets.
335		uuid_item_map::iterator iter;
336		for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++)
337		{
338			LLInventoryItem *itemp = iter->second;
339			LLScriptQueueData* datap = new LLScriptQueueData(getKey().asUUID(),
340												 itemp->getName(),
341												 viewer_object->getID(),
342												 itemp->getUUID());
343
344			//llinfos << "ITEM NAME 2: " << names.get(i) << llendl;
345			gAssetStorage->getInvItemAsset(viewer_object->getRegion()->getHost(),
346				gAgent.getID(),
347				gAgent.getSessionID(),
348				itemp->getPermissions().getOwner(),
349				viewer_object->getID(),
350				itemp->getUUID(),
351				itemp->getAssetUUID(),
352				itemp->getType(),
353				LLFloaterCompileQueue::scriptArrived,
354				(void*)datap);
355		}
356	}
357}
358
359// This is the callback for when each script arrives
360// static
361void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
362										  LLAssetType::EType type,
363										  void* user_data, S32 status, LLExtStat ext_status)
364{
365	llinfos << "LLFloaterCompileQueue::scriptArrived()" << llendl;
366	LLScriptQueueData* data = (LLScriptQueueData*)user_data;
367	if(!data)
368	{
369		return;
370	}
371	LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
372	
373	std::string buffer;
374	if(queue && (0 == status))
375	{
376		//llinfos << "ITEM NAME 3: " << data->mScriptName << llendl;
377
378		// Dump this into a file on the local disk so we can compile it.
379		std::string filename;
380		LLVFile file(vfs, asset_id, type);
381		std::string uuid_str;
382		asset_id.toString(uuid_str);
383		filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + llformat(".%s",LLAssetType::lookup(type));
384		
385		const bool is_running = true;
386		LLViewerObject* object = gObjectList.findObject(data->mTaskId);
387		if (object)
388		{
389			std::string url = object->getRegion()->getCapability("UpdateScriptTask");
390			if(!url.empty())
391			{
392				// Read script source in to buffer.
393				U32 script_size = file.getSize();
394				U8* script_data = new U8[script_size];
395				file.read(script_data, script_size);
396
397				queue->mUploadQueue->queue(filename, data->mTaskId, 
398										   data->mItemId, is_running, queue->mMono, queue->getKey().asUUID(),
399										   script_data, script_size, data->mScriptName);
400			}
401			else
402			{
403				// It's now in the file, now compile it.
404				buffer = LLTrans::getString("CompileQueueDownloadedCompiling") + (": ") + data->mScriptName;
405
406				// Write script to local file for compilation.
407				LLFILE *fp = LLFile::fopen(filename, "wb");	 /*Flawfinder: ignore*/
408				if (fp)
409				{
410					const S32 buf_size = 65536;
411					U8 copy_buf[buf_size];
412					
413					while (file.read(copy_buf, buf_size)) 	 /*Flawfinder: ignore*/
414					{
415						if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1)
416						{
417							// return a bad file error if we can't write the whole thing
418							status = LL_ERR_CANNOT_OPEN_FILE;
419						}
420					}
421
422					fclose(fp);
423				}
424				else
425				{
426					llerrs << "Unable to find object to compile" << llendl;
427				}
428
429				// TODO: babbage: No compile if no cap.
430				queue->compile(filename, data->mItemId);
431					
432				// Delete it after we're done compiling?
433				LLFile::remove(filename);
434			}
435		}
436	}
437	else
438	{
439		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
440
441		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
442		{
443			LLSD args;
444			args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound");
445			LLNotificationsUtil::add("SystemMessage", args);
446			
447			buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mScriptName;
448		}
449		else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
450		{
451			LLSD args;
452			args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload");
453			LLNotificationsUtil::add("SystemMessage", args);
454
455			buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mScriptName;
456		}
457		else
458		{
459			buffer = LLTrans::getString("CompileQueueUnknownFailure") + (" ") + data->mScriptName;
460		}
461
462		llwarns << "Problem downloading script asset." << llendl;
463		if(queue) queue->removeItemByItemID(data->mItemId);
464	}
465	if(queue && (buffer.size() > 0)) 
466	{
467		queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
468	}
469	delete data;
470}
471
472// static
473void LLFloaterCompileQueue::onSaveTextComplete(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
474{
475	llinfos << "LLFloaterCompileQueue::onSaveTextComplete()" << llendl;
476	if (status)
477	{
478		llwarns << "Unable to save text for script." << llendl;
479		LLSD args;
480		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
481		LLNotificationsUtil::add("CompileQueueSaveText", args);
482	}
483}
484
485// static
486void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
487{
488	llinfos << "LLFloaterCompileQueue::onSaveBytecodeComplete()" << llendl;
489	LLCompileQueueData* data = (LLCompileQueueData*)user_data;
490	LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
491	if(queue && (0 == status) && data)
492	{
493		queue->saveItemByItemID(data->mItemId);
494		queue->removeItemByItemID(data->mItemId);
495	}
496	else
497	{
498		llwarns << "Unable to save bytecode for script." << llendl;
499		LLSD args;
500		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
501		LLNotificationsUtil::add("CompileQueueSaveBytecode", args);
502	}
503	delete data;
504	data = NULL;
505}
506
507// compile the file given and save it out.
508void LLFloaterCompileQueue::compile(const std::string& filename,
509									const LLUUID& item_id)
510{
511	LLUUID new_asset_id;
512	LLTransactionID tid;
513	tid.generate();
514	new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
515	
516	std::string uuid_string;
517	new_asset_id.toString(uuid_string);
518	std::string dst_filename;
519	dst_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string) + ".lso";
520	std::string err_filename;
521	err_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string) + ".out";
522
523	gAssetStorage->storeAssetData(filename, tid,
524								  LLAssetType::AT_LSL_TEXT,
525								  &onSaveTextComplete, NULL, FALSE);
526
527	const BOOL compile_to_mono = FALSE;
528	if(!lscript_compile(filename.c_str(), dst_filename.c_str(),
529						err_filename.c_str(), compile_to_mono,
530						uuid_string.c_str(), gAgent.isGodlike()))
531	{
532		llwarns << "compile failed" << llendl;
533		removeItemByItemID(item_id);
534	}
535	else
536	{
537		llinfos << "compile successful." << llendl;
538		
539		// Save LSL bytecode
540		LLCompileQueueData* data = new LLCompileQueueData(getKey().asUUID(), item_id);
541		gAssetStorage->storeAssetData(dst_filename, new_asset_id,
542									LLAssetType::AT_LSL_BYTECODE,
543									&LLFloaterCompileQueue::onSaveBytecodeComplete,
544									(void*)data, FALSE);
545	}
546}
547
548void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id)
549{
550	llinfos << "LLFloaterCompileQueue::removeItemByAssetID()" << llendl;
551	for(S32 i = 0; i < mCurrentScripts.count(); )
552	{
553		if(asset_id == mCurrentScripts.get(i)->getUUID())
554		{
555			mCurrentScripts.remove(i);
556		}
557		else
558		{
559			++i;
560		}
561	}
562	if(mCurrentScripts.count() == 0)
563	{
564		nextObject();
565	}
566}
567
568const LLInventoryItem* LLFloaterCompileQueue::findItemByItemID(const LLUUID& asset_id) const
569{
570	LLInventoryItem* result = NULL;
571	S32 count = mCurrentScripts.count();
572	for(S32 i = 0; i < count; ++i)
573	{
574		if(asset_id == mCurrentScripts.get(i)->getUUID())
575		{
576			result = mCurrentScripts.get(i);
577		}
578	}
579	return result;
580}
581
582void LLFloaterCompileQueue::saveItemByItemID(const LLUUID& asset_id)
583{
584	llinfos << "LLFloaterCompileQueue::saveItemByAssetID()" << llendl;
585	LLViewerObject* viewer_object = gObjectList.findObject(mCurrentObjectID);
586	if(viewer_object)
587	{
588		S32 count = mCurrentScripts.count();
589		for(S32 i = 0; i < count; ++i)
590		{
591			if(asset_id == mCurrentScripts.get(i)->getUUID())
592			{
593				// *FIX: this auto-resets active to TRUE. That might
594				// be a bad idea.
595				viewer_object->saveScript(mCurrentScripts.get(i), TRUE, false);
596			}
597		}
598	}
599	else
600	{
601		llwarns << "Unable to finish save!" << llendl;
602	}
603}
604
605///----------------------------------------------------------------------------
606/// Class LLFloaterResetQueue
607///----------------------------------------------------------------------------
608
609LLFloaterResetQueue::LLFloaterResetQueue(const LLSD& key)
610  : LLFloaterScriptQueue(key)
611{
612	setTitle(LLTrans::getString("ResetQueueTitle"));
613	setStartString(LLTrans::getString("ResetQueueStart"));
614}
615
616LLFloaterResetQueue::~LLFloaterResetQueue()
617{ 
618}
619
620void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
621										  LLInventoryObject::object_list_t* inv)
622{
623	// find all of the lsl, leaving off duplicates. We'll remove
624	// all matching asset uuids on compilation success.
625	LLDynamicArray<const char*> names;
626	
627	LLInventoryObject::object_list_t::const_iterator it = inv->begin();
628	LLInventoryObject::object_list_t::const_iterator end = inv->end();
629	for ( ; it != end; ++it)
630	{
631		if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
632		{
633			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
634
635			if (object)
636			{
637				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
638				std::string buffer;
639				buffer = getString("Resetting") + (": ") + item->getName();
640				getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
641				LLMessageSystem* msg = gMessageSystem;
642				msg->newMessageFast(_PREHASH_ScriptReset);
643				msg->nextBlockFast(_PREHASH_AgentData);
644				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
645				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
646				msg->nextBlockFast(_PREHASH_Script);
647				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
648				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
649				msg->sendReliable(object->getRegion()->getHost());
650			}
651		}
652	}
653
654	nextObject();	
655}
656
657///----------------------------------------------------------------------------
658/// Class LLFloaterRunQueue
659///----------------------------------------------------------------------------
660
661LLFloaterRunQueue::LLFloaterRunQueue(const LLSD& key)
662  : LLFloaterScriptQueue(key)
663{
664	setTitle(LLTrans::getString("RunQueueTitle"));
665	setStartString(LLTrans::getString("RunQueueStart"));
666}
667
668LLFloaterRunQueue::~LLFloaterRunQueue()
669{ 
670}
671
672void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
673										  LLInventoryObject::object_list_t* inv)
674{
675	// find all of the lsl, leaving off duplicates. We'll remove
676	// all matching asset uuids on compilation success.
677	LLDynamicArray<const char*> names;
678	
679	LLInventoryObject::object_list_t::const_iterator it = inv->begin();
680	LLInventoryObject::object_list_t::const_iterator end = inv->end();
681	for ( ; it != end; ++it)
682	{
683		if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
684		{
685			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
686
687			if (object)
688			{
689				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
690				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
691				std::string buffer;
692				buffer = getString("Running") + (": ") + item->getName();
693				list->setCommentText(buffer);
694
695				LLMessageSystem* msg = gMessageSystem;
696				msg->newMessageFast(_PREHASH_SetScriptRunning);
697				msg->nextBlockFast(_PREHASH_AgentData);
698				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
699				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
700				msg->nextBlockFast(_PREHASH_Script);
701				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
702				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
703				msg->addBOOLFast(_PREHASH_Running, TRUE);
704				msg->sendReliable(object->getRegion()->getHost());
705			}
706		}
707	}
708
709	nextObject();	
710}
711
712///----------------------------------------------------------------------------
713/// Class LLFloaterNotRunQueue
714///----------------------------------------------------------------------------
715
716LLFloaterNotRunQueue::LLFloaterNotRunQueue(const LLSD& key)
717  : LLFloaterScriptQueue(key)
718{
719	setTitle(LLTrans::getString("NotRunQueueTitle"));
720	setStartString(LLTrans::getString("NotRunQueueStart"));
721}
722
723LLFloaterNotRunQueue::~LLFloaterNotRunQueue()
724{ 
725}
726
727void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,
728										  LLInventoryObject::object_list_t* inv)
729{
730	// find all of the lsl, leaving off duplicates. We'll remove
731	// all matching asset uuids on compilation success.
732	LLDynamicArray<const char*> names;
733	
734	LLInventoryObject::object_list_t::const_iterator it = inv->begin();
735	LLInventoryObject::object_list_t::const_iterator end = inv->end();
736	for ( ; it != end; ++it)
737	{
738		if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
739		{
740			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
741
742			if (object)
743			{
744				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
745				LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
746				std::string buffer;
747				buffer = getString("NotRunning") + (": ") +item->getName();
748				list->setCommentText(buffer);
749	
750				LLMessageSystem* msg = gMessageSystem;
751				msg->newMessageFast(_PREHASH_SetScriptRunning);
752				msg->nextBlockFast(_PREHASH_AgentData);
753				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
754				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
755				msg->nextBlockFast(_PREHASH_Script);
756				msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
757				msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
758				msg->addBOOLFast(_PREHASH_Running, FALSE);
759				msg->sendReliable(object->getRegion()->getHost());
760			}
761		}
762	}
763
764	nextObject();	
765}
766
767///----------------------------------------------------------------------------
768/// Local function definitions
769///----------------------------------------------------------------------------