diff options
Diffstat (limited to 'linden/indra/newview/llcompilequeue.cpp')
-rw-r--r-- | linden/indra/newview/llcompilequeue.cpp | 775 |
1 files changed, 775 insertions, 0 deletions
diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp new file mode 100644 index 0000000..e42677d --- /dev/null +++ b/linden/indra/newview/llcompilequeue.cpp | |||
@@ -0,0 +1,775 @@ | |||
1 | /** | ||
2 | * @file llcompilequeue.cpp | ||
3 | * @brief LLCompileQueueData class implementation | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | /** | ||
29 | * | ||
30 | * Implementation of the script queue which keeps an array of object | ||
31 | * UUIDs and manipulates all of the scripts on each of them. | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | |||
36 | #include "llviewerprecompiledheaders.h" | ||
37 | |||
38 | #include "llcompilequeue.h" | ||
39 | |||
40 | #include "llagent.h" | ||
41 | #include "llchat.h" | ||
42 | #include "llviewerwindow.h" | ||
43 | #include "llcallbacklist.h" | ||
44 | #include "llviewerobject.h" | ||
45 | #include "llviewerobjectlist.h" | ||
46 | #include "llviewerregion.h" | ||
47 | #include "lscript_rt_interface.h" | ||
48 | #include "llviewercontrol.h" | ||
49 | #include "llviewerobject.h" | ||
50 | #include "llviewerregion.h" | ||
51 | #include "llresmgr.h" | ||
52 | #include "llbutton.h" | ||
53 | #include "lldir.h" | ||
54 | #include "llfloaterchat.h" | ||
55 | #include "llviewerstats.h" | ||
56 | #include "llvieweruictrlfactory.h" | ||
57 | |||
58 | // XUI:translate | ||
59 | |||
60 | ///---------------------------------------------------------------------------- | ||
61 | /// Local function declarations, constants, enums, and typedefs | ||
62 | ///---------------------------------------------------------------------------- | ||
63 | |||
64 | // XUI:translate | ||
65 | const char* COMPILE_QUEUE_TITLE = "Recompilation Progress"; | ||
66 | const char* COMPILE_START_STRING = "recompile"; | ||
67 | const char* RESET_QUEUE_TITLE = "Reset Progress"; | ||
68 | const char* RESET_START_STRING = "reset"; | ||
69 | const char* RUN_QUEUE_TITLE = "Set Running Progress"; | ||
70 | const char* RUN_START_STRING = "set running"; | ||
71 | const char* NOT_RUN_QUEUE_TITLE = "Set Not Running Progress"; | ||
72 | const char* NOT_RUN_START_STRING = "set not running"; | ||
73 | |||
74 | struct LLCompileQueueData | ||
75 | { | ||
76 | LLUUID mQueueID; | ||
77 | LLUUID mOldAssetID; | ||
78 | LLCompileQueueData(const LLUUID& q_id, const LLUUID& old_asset_id) : | ||
79 | mQueueID(q_id), mOldAssetID(old_asset_id) {} | ||
80 | }; | ||
81 | |||
82 | struct LLScriptQueueData | ||
83 | { | ||
84 | LLUUID mQueueID; | ||
85 | LLString mScriptName; | ||
86 | LLScriptQueueData(const LLUUID& q_id, const char* name) : | ||
87 | mQueueID(q_id), mScriptName(name) {} | ||
88 | }; | ||
89 | |||
90 | ///---------------------------------------------------------------------------- | ||
91 | /// Class LLFloaterScriptQueue | ||
92 | ///---------------------------------------------------------------------------- | ||
93 | |||
94 | // static | ||
95 | LLMap<LLUUID, LLFloaterScriptQueue*> LLFloaterScriptQueue::sInstances; | ||
96 | |||
97 | |||
98 | // Default constructor | ||
99 | LLFloaterScriptQueue::LLFloaterScriptQueue(const std::string& name, | ||
100 | const LLRect& rect, | ||
101 | const char* title, | ||
102 | const char* start_string) : | ||
103 | LLFloater(name, rect, title, | ||
104 | RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, | ||
105 | DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES) | ||
106 | { | ||
107 | |||
108 | gUICtrlFactory->buildFloater(this,"floater_script_queue.xml"); | ||
109 | |||
110 | childSetAction("close",onCloseBtn,this); | ||
111 | childSetEnabled("close",FALSE); | ||
112 | |||
113 | setTitle(title); | ||
114 | |||
115 | if (!getHost()) | ||
116 | { | ||
117 | LLRect curRect = getRect(); | ||
118 | translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); | ||
119 | } | ||
120 | |||
121 | mStartString = start_string; | ||
122 | mDone = FALSE; | ||
123 | sInstances.addData(mID, this); | ||
124 | } | ||
125 | |||
126 | // Destroys the object | ||
127 | LLFloaterScriptQueue::~LLFloaterScriptQueue() | ||
128 | { | ||
129 | sInstances.removeData(mID); | ||
130 | } | ||
131 | |||
132 | // find an instance by ID. Return NULL if it does not exist. | ||
133 | // static | ||
134 | LLFloaterScriptQueue* LLFloaterScriptQueue::findInstance(const LLUUID& id) | ||
135 | { | ||
136 | if(sInstances.checkData(id)) | ||
137 | { | ||
138 | return sInstances.getData(id); | ||
139 | } | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | |||
144 | // This is the callback method for the viewer object currently being | ||
145 | // worked on. | ||
146 | // NOT static, virtual! | ||
147 | void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object, | ||
148 | InventoryObjectList* inv, | ||
149 | S32, | ||
150 | void* q_id) | ||
151 | { | ||
152 | llinfos << "LLFloaterScriptQueue::inventoryChanged() for object " | ||
153 | << viewer_object->getID() << llendl; | ||
154 | |||
155 | //Remove this listener from the object since its | ||
156 | //listener callback is now being executed. | ||
157 | |||
158 | //We remove the listener here because the function | ||
159 | //removeVOInventoryListener removes the listener from a ViewerObject | ||
160 | //which it internally stores. | ||
161 | |||
162 | //If we call this further down in the function, calls to handleInventory | ||
163 | //and nextObject may update the interally stored viewer object causing | ||
164 | //the removal of the incorrect listener from an incorrect object. | ||
165 | |||
166 | //Fixes SL-6119:Recompile scripts fails to complete | ||
167 | removeVOInventoryListener(); | ||
168 | |||
169 | if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) | ||
170 | { | ||
171 | handleInventory(viewer_object, inv); | ||
172 | } | ||
173 | else | ||
174 | { | ||
175 | // something went wrong... | ||
176 | // note that we're not working on this one, and move onto the | ||
177 | // next object in the list. | ||
178 | llwarns << "No inventory for " << mCurrentObjectID | ||
179 | << llendl; | ||
180 | nextObject(); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | |||
185 | // static | ||
186 | void LLFloaterScriptQueue::onCloseBtn(void* user_data) | ||
187 | { | ||
188 | LLFloaterScriptQueue* self = (LLFloaterScriptQueue*)user_data; | ||
189 | self->close(); | ||
190 | } | ||
191 | |||
192 | void LLFloaterScriptQueue::addObject(const LLUUID& id) | ||
193 | { | ||
194 | mObjectIDs.put(id); | ||
195 | } | ||
196 | |||
197 | BOOL LLFloaterScriptQueue::start() | ||
198 | { | ||
199 | //llinfos << "LLFloaterCompileQueue::start()" << llendl; | ||
200 | char buffer[MAX_STRING]; | ||
201 | sprintf(buffer, "Starting %s of %d items.", mStartString, mObjectIDs.count()); | ||
202 | |||
203 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(this, "queue output"); | ||
204 | list->addSimpleItem(buffer); | ||
205 | |||
206 | return nextObject(); | ||
207 | } | ||
208 | |||
209 | BOOL LLFloaterScriptQueue::isDone() const | ||
210 | { | ||
211 | return (mCurrentObjectID.isNull() && (mObjectIDs.count() == 0)); | ||
212 | } | ||
213 | |||
214 | // go to the next object. If no objects left, it falls out silently | ||
215 | // and waits to be killed by the window being closed. | ||
216 | BOOL LLFloaterScriptQueue::nextObject() | ||
217 | { | ||
218 | S32 count; | ||
219 | BOOL successful_start = FALSE; | ||
220 | do | ||
221 | { | ||
222 | count = mObjectIDs.count(); | ||
223 | llinfos << "LLFloaterScriptQueue::nextObject() - " << count | ||
224 | << " objects left to process." << llendl; | ||
225 | mCurrentObjectID.setNull(); | ||
226 | if(count > 0) | ||
227 | { | ||
228 | successful_start = popNext(); | ||
229 | } | ||
230 | llinfos << "LLFloaterScriptQueue::nextObject() " | ||
231 | << (successful_start ? "successful" : "unsuccessful") | ||
232 | << llendl; | ||
233 | } while((mObjectIDs.count() > 0) && !successful_start); | ||
234 | if(isDone() && !mDone) | ||
235 | { | ||
236 | |||
237 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(this, "queue output"); | ||
238 | |||
239 | mDone = TRUE; | ||
240 | char buffer[MAX_STRING]; | ||
241 | sprintf(buffer, "Done."); | ||
242 | list->addSimpleItem(buffer); | ||
243 | childSetEnabled("close",TRUE); | ||
244 | } | ||
245 | return successful_start; | ||
246 | } | ||
247 | |||
248 | // returns true if the queue has started, otherwise false. This | ||
249 | // method pops the top object off of the queue. | ||
250 | BOOL LLFloaterScriptQueue::popNext() | ||
251 | { | ||
252 | // get the first element off of the container, and attempt to get | ||
253 | // the inventory. | ||
254 | BOOL rv = FALSE; | ||
255 | S32 count = mObjectIDs.count(); | ||
256 | if(mCurrentObjectID.isNull() && (count > 0)) | ||
257 | { | ||
258 | mCurrentObjectID = mObjectIDs.get(0); | ||
259 | llinfos << "LLFloaterScriptQueue::popNext() - mCurrentID: " | ||
260 | << mCurrentObjectID << llendl; | ||
261 | mObjectIDs.remove(0); | ||
262 | LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); | ||
263 | if(obj) | ||
264 | { | ||
265 | llinfos << "LLFloaterScriptQueue::popNext() requesting inv for " | ||
266 | << mCurrentObjectID << llendl; | ||
267 | LLUUID* id = new LLUUID(mID); | ||
268 | registerVOInventoryListener(obj,id); | ||
269 | requestVOInventory(); | ||
270 | rv = TRUE; | ||
271 | } | ||
272 | } | ||
273 | return rv; | ||
274 | } | ||
275 | |||
276 | |||
277 | ///---------------------------------------------------------------------------- | ||
278 | /// Class LLFloaterCompileQueue | ||
279 | ///---------------------------------------------------------------------------- | ||
280 | |||
281 | // static | ||
282 | LLFloaterCompileQueue* LLFloaterCompileQueue::create() | ||
283 | { | ||
284 | S32 left, top; | ||
285 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
286 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
287 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
288 | LLFloaterCompileQueue* new_queue = new LLFloaterCompileQueue("queue", | ||
289 | rect); | ||
290 | new_queue->open(); | ||
291 | return new_queue; | ||
292 | } | ||
293 | |||
294 | LLFloaterCompileQueue::LLFloaterCompileQueue(const std::string& name, const LLRect& rect) | ||
295 | : LLFloaterScriptQueue(name, rect, COMPILE_QUEUE_TITLE, COMPILE_START_STRING) | ||
296 | { } | ||
297 | |||
298 | LLFloaterCompileQueue::~LLFloaterCompileQueue() | ||
299 | { | ||
300 | } | ||
301 | |||
302 | void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object, | ||
303 | InventoryObjectList* inv) | ||
304 | { | ||
305 | // find all of the lsl, leaving off duplicates. We'll remove | ||
306 | // all matching asset uuids on compilation success. | ||
307 | |||
308 | typedef std::map<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map; | ||
309 | uuid_item_map asset_item_map; | ||
310 | |||
311 | InventoryObjectList::const_iterator it = inv->begin(); | ||
312 | InventoryObjectList::const_iterator end = inv->end(); | ||
313 | for ( ; it != end; ++it) | ||
314 | { | ||
315 | if((*it)->getType() == LLAssetType::AT_LSL_TEXT) | ||
316 | { | ||
317 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
318 | // Check permissions before allowing the user to retrieve data. | ||
319 | if (item->getPermissions().allowModifyBy(gAgent.getID()) && | ||
320 | item->getPermissions().allowCopyBy(gAgent.getID()) ) | ||
321 | { | ||
322 | LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item); | ||
323 | mCurrentScripts.put(script); | ||
324 | |||
325 | if (!asset_item_map.count(item->getAssetUUID())) | ||
326 | { | ||
327 | // No entry, put in an entry for this supposedly permissive script | ||
328 | asset_item_map[item->getAssetUUID()] = item; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if (asset_item_map.empty()) | ||
335 | { | ||
336 | // There are no scripts in this object. move on. | ||
337 | nextObject(); | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | // request all of the assets. | ||
342 | uuid_item_map::iterator iter; | ||
343 | for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++) | ||
344 | { | ||
345 | LLInventoryItem *itemp = iter->second; | ||
346 | LLScriptQueueData* datap = new LLScriptQueueData(getID(), itemp->getName().c_str()); | ||
347 | |||
348 | //llinfos << "ITEM NAME 2: " << names.get(i) << llendl; | ||
349 | gAssetStorage->getInvItemAsset(viewer_object->getRegion()->getHost(), | ||
350 | gAgent.getID(), | ||
351 | gAgent.getSessionID(), | ||
352 | itemp->getPermissions().getOwner(), | ||
353 | viewer_object->getID(), | ||
354 | itemp->getUUID(), | ||
355 | itemp->getAssetUUID(), | ||
356 | itemp->getType(), | ||
357 | LLFloaterCompileQueue::scriptArrived, | ||
358 | (void*)datap); | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | |||
364 | // This is the callback for when each script arrives | ||
365 | // static | ||
366 | void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, | ||
367 | LLAssetType::EType type, | ||
368 | void* user_data, S32 status) | ||
369 | { | ||
370 | llinfos << "LLFloaterCompileQueue::scriptArrived()" << llendl; | ||
371 | LLScriptQueueData* data = (LLScriptQueueData*)user_data; | ||
372 | if(!data) return; | ||
373 | LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*> | ||
374 | (LLFloaterScriptQueue::findInstance(data->mQueueID)); | ||
375 | char buffer[MAX_STRING]; | ||
376 | buffer[0] = '\0'; | ||
377 | if(queue && (0 == status)) | ||
378 | { | ||
379 | //llinfos << "ITEM NAME 3: " << data->mScriptName << llendl; | ||
380 | |||
381 | // Dump this into a file on the local disk so we can compile it. | ||
382 | char filename[LL_MAX_PATH] = ""; | ||
383 | LLVFile file(vfs, asset_id, type); | ||
384 | char uuid_str[UUID_STR_LENGTH]; | ||
385 | asset_id.toString(uuid_str); | ||
386 | sprintf(filename,"%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type)); | ||
387 | |||
388 | FILE *fp = LLFile::fopen(filename, "wb"); | ||
389 | if (fp) | ||
390 | { | ||
391 | const S32 buf_size = 65536; | ||
392 | U8 copy_buf[buf_size]; | ||
393 | while (file.read(copy_buf, buf_size)) | ||
394 | { | ||
395 | if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1) | ||
396 | { | ||
397 | // return a bad file error if we can't write the whole thing | ||
398 | status = LL_ERR_CANNOT_OPEN_FILE; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | fclose(fp); | ||
403 | } | ||
404 | |||
405 | // It's now in the file, now compile it. | ||
406 | sprintf(buffer, "Downloaded, now compiling '%s'.", data->mScriptName.c_str()); | ||
407 | queue->compile(filename, asset_id); | ||
408 | |||
409 | // Delete it after we're done compiling? | ||
410 | LLFile::remove(filename); | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | if( gViewerStats ) | ||
415 | { | ||
416 | gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); | ||
417 | } | ||
418 | |||
419 | if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) | ||
420 | { | ||
421 | LLChat chat("Script not found on server."); | ||
422 | LLFloaterChat::addChat(chat); | ||
423 | sprintf(buffer, "Problem downloading %s.", | ||
424 | data->mScriptName.c_str()); | ||
425 | } | ||
426 | else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) | ||
427 | { | ||
428 | LLChat chat("Insufficient permissions to download a script."); | ||
429 | LLFloaterChat::addChat(chat); | ||
430 | sprintf(buffer, "Insufficient permissions for '%s'.", | ||
431 | data->mScriptName.c_str()); | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | sprintf(buffer, "Unknown failure to download %s.", | ||
436 | data->mScriptName.c_str()); | ||
437 | } | ||
438 | |||
439 | llwarns << "Problem downloading script asset." << llendl; | ||
440 | if(queue) queue->removeItemByAssetID(asset_id); | ||
441 | } | ||
442 | if(queue) | ||
443 | { | ||
444 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(queue, "queue output"); | ||
445 | list->addSimpleItem(buffer); | ||
446 | } | ||
447 | delete data; | ||
448 | } | ||
449 | |||
450 | // static | ||
451 | void LLFloaterCompileQueue::onSaveTextComplete(const LLUUID& asset_id, void* user_data, S32 status) // StoreAssetData callback (fixed) | ||
452 | { | ||
453 | llinfos << "LLFloaterCompileQueue::onSaveTextComplete()" << llendl; | ||
454 | if (status) | ||
455 | { | ||
456 | llwarns << "Unable to save text for script." << llendl; | ||
457 | LLString::format_map_t args; | ||
458 | args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status)); | ||
459 | gViewerWindow->alertXml("CompileQueueSaveText", args); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | // static | ||
464 | void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void* user_data, S32 status) // StoreAssetData callback (fixed) | ||
465 | { | ||
466 | llinfos << "LLFloaterCompileQueue::onSaveBytecodeComplete()" << llendl; | ||
467 | LLCompileQueueData* data = (LLCompileQueueData*)user_data; | ||
468 | LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*> | ||
469 | (LLFloaterScriptQueue::findInstance(data->mQueueID)); | ||
470 | if(queue && (0 == status) && data) | ||
471 | { | ||
472 | queue->updateAssetID(data->mOldAssetID, asset_id); | ||
473 | queue->saveItemByAssetID(asset_id); | ||
474 | queue->removeItemByAssetID(asset_id); | ||
475 | } | ||
476 | else | ||
477 | { | ||
478 | llwarns << "Unable to save bytecode for script." << llendl; | ||
479 | LLStringBase<char>::format_map_t args; | ||
480 | args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status)); | ||
481 | gViewerWindow->alertXml("CompileQueueSaveBytecode", args); | ||
482 | } | ||
483 | delete data; | ||
484 | data = NULL; | ||
485 | } | ||
486 | |||
487 | // compile the file given and save it out. | ||
488 | void LLFloaterCompileQueue::compile(const char* filename, | ||
489 | const LLUUID& asset_id) | ||
490 | { | ||
491 | LLUUID new_asset_id; | ||
492 | LLTransactionID tid; | ||
493 | tid.generate(); | ||
494 | new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
495 | |||
496 | char uuid_string[UUID_STR_LENGTH]; | ||
497 | new_asset_id.toString(uuid_string); | ||
498 | char dst_filename[LL_MAX_PATH]; | ||
499 | sprintf(dst_filename, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str()); | ||
500 | char err_filename[LL_MAX_PATH]; | ||
501 | sprintf(err_filename, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str()); | ||
502 | |||
503 | gAssetStorage->storeAssetData(filename, tid, | ||
504 | LLAssetType::AT_LSL_TEXT, | ||
505 | &onSaveTextComplete, NULL, FALSE); | ||
506 | if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike())) | ||
507 | { | ||
508 | llwarns << "compile failed" << llendl; | ||
509 | removeItemByAssetID(asset_id); | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | llinfos << "compile successful." << llendl; | ||
514 | // Save the bytecode | ||
515 | LLCompileQueueData* data = new LLCompileQueueData(mID, asset_id); | ||
516 | gAssetStorage->storeAssetData(dst_filename, tid, | ||
517 | LLAssetType::AT_LSL_BYTECODE, | ||
518 | &onSaveBytecodeComplete, | ||
519 | (void*)data, FALSE); | ||
520 | } | ||
521 | } | ||
522 | |||
523 | void LLFloaterCompileQueue::removeItemByAssetID(const LLUUID& asset_id) | ||
524 | { | ||
525 | llinfos << "LLFloaterCompileQueue::removeItemByAssetID()" << llendl; | ||
526 | for(S32 i = 0; i < mCurrentScripts.count(); ) | ||
527 | { | ||
528 | if(asset_id == mCurrentScripts.get(i)->getAssetUUID()) | ||
529 | { | ||
530 | mCurrentScripts.remove(i); | ||
531 | } | ||
532 | else | ||
533 | { | ||
534 | ++i; | ||
535 | } | ||
536 | } | ||
537 | if(mCurrentScripts.count() == 0) | ||
538 | { | ||
539 | nextObject(); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | void LLFloaterCompileQueue::saveItemByAssetID(const LLUUID& asset_id) | ||
544 | { | ||
545 | llinfos << "LLFloaterCompileQueue::saveItemByAssetID()" << llendl; | ||
546 | LLViewerObject* viewer_object = gObjectList.findObject(mCurrentObjectID); | ||
547 | if(viewer_object) | ||
548 | { | ||
549 | S32 count = mCurrentScripts.count(); | ||
550 | for(S32 i = 0; i < count; ++i) | ||
551 | { | ||
552 | if(asset_id == mCurrentScripts.get(i)->getAssetUUID()) | ||
553 | { | ||
554 | // *FIX: this auto-resets active to TRUE. That might | ||
555 | // be a bad idea. | ||
556 | viewer_object->saveScript(mCurrentScripts.get(i), TRUE, false); | ||
557 | } | ||
558 | } | ||
559 | } | ||
560 | else | ||
561 | { | ||
562 | llwarns << "Unable to finish save!" << llendl; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | // find old_asst_id, and set the asset id to new_asset_id | ||
567 | void LLFloaterCompileQueue::updateAssetID(const LLUUID& old_asset_id, | ||
568 | const LLUUID& new_asset_id) | ||
569 | { | ||
570 | S32 count = mCurrentScripts.count(); | ||
571 | for(S32 i = 0; i < count; ++i) | ||
572 | { | ||
573 | if(old_asset_id == mCurrentScripts.get(i)->getAssetUUID()) | ||
574 | { | ||
575 | mCurrentScripts.get(i)->setAssetUUID(new_asset_id); | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | |||
580 | ///---------------------------------------------------------------------------- | ||
581 | /// Class LLFloaterResetQueue | ||
582 | ///---------------------------------------------------------------------------- | ||
583 | |||
584 | // static | ||
585 | LLFloaterResetQueue* LLFloaterResetQueue::create() | ||
586 | { | ||
587 | S32 left, top; | ||
588 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
589 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
590 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
591 | LLFloaterResetQueue* new_queue = new LLFloaterResetQueue("queue", | ||
592 | rect); | ||
593 | new_queue->open(); | ||
594 | return new_queue; | ||
595 | } | ||
596 | |||
597 | LLFloaterResetQueue::LLFloaterResetQueue(const std::string& name, const LLRect& rect) | ||
598 | : LLFloaterScriptQueue(name, rect, RESET_QUEUE_TITLE, RESET_START_STRING) | ||
599 | { } | ||
600 | |||
601 | LLFloaterResetQueue::~LLFloaterResetQueue() | ||
602 | { | ||
603 | } | ||
604 | |||
605 | void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, | ||
606 | InventoryObjectList* inv) | ||
607 | { | ||
608 | // find all of the lsl, leaving off duplicates. We'll remove | ||
609 | // all matching asset uuids on compilation success. | ||
610 | LLDynamicArray<const char*> names; | ||
611 | |||
612 | InventoryObjectList::const_iterator it = inv->begin(); | ||
613 | InventoryObjectList::const_iterator end = inv->end(); | ||
614 | for ( ; it != end; ++it) | ||
615 | { | ||
616 | if((*it)->getType() == LLAssetType::AT_LSL_TEXT) | ||
617 | { | ||
618 | LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); | ||
619 | |||
620 | if (object) | ||
621 | { | ||
622 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
623 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(this, "queue output"); | ||
624 | char buffer[MAX_STRING]; | ||
625 | sprintf(buffer, "Resetting '%s'.", item->getName().c_str()); | ||
626 | list->addSimpleItem(buffer); | ||
627 | LLMessageSystem* msg = gMessageSystem; | ||
628 | msg->newMessageFast(_PREHASH_ScriptReset); | ||
629 | msg->nextBlockFast(_PREHASH_AgentData); | ||
630 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
631 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
632 | msg->nextBlockFast(_PREHASH_Script); | ||
633 | msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); | ||
634 | msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); | ||
635 | msg->sendReliable(object->getRegion()->getHost()); | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | |||
640 | nextObject(); | ||
641 | } | ||
642 | |||
643 | ///---------------------------------------------------------------------------- | ||
644 | /// Class LLFloaterRunQueue | ||
645 | ///---------------------------------------------------------------------------- | ||
646 | |||
647 | // static | ||
648 | LLFloaterRunQueue* LLFloaterRunQueue::create() | ||
649 | { | ||
650 | S32 left, top; | ||
651 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
652 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
653 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
654 | LLFloaterRunQueue* new_queue = new LLFloaterRunQueue("queue", | ||
655 | rect); | ||
656 | new_queue->open(); | ||
657 | return new_queue; | ||
658 | } | ||
659 | |||
660 | LLFloaterRunQueue::LLFloaterRunQueue(const std::string& name, const LLRect& rect) | ||
661 | : LLFloaterScriptQueue(name, rect, RUN_QUEUE_TITLE, RUN_START_STRING) | ||
662 | { } | ||
663 | |||
664 | LLFloaterRunQueue::~LLFloaterRunQueue() | ||
665 | { | ||
666 | } | ||
667 | |||
668 | void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, | ||
669 | InventoryObjectList* inv) | ||
670 | { | ||
671 | // find all of the lsl, leaving off duplicates. We'll remove | ||
672 | // all matching asset uuids on compilation success. | ||
673 | LLDynamicArray<const char*> names; | ||
674 | |||
675 | InventoryObjectList::const_iterator it = inv->begin(); | ||
676 | InventoryObjectList::const_iterator end = inv->end(); | ||
677 | for ( ; it != end; ++it) | ||
678 | { | ||
679 | if((*it)->getType() == LLAssetType::AT_LSL_TEXT) | ||
680 | { | ||
681 | LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); | ||
682 | |||
683 | if (object) | ||
684 | { | ||
685 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
686 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(this, "queue output"); | ||
687 | char buffer[MAX_STRING]; | ||
688 | sprintf(buffer, "Running '%s'.", item->getName().c_str()); | ||
689 | list->addSimpleItem(buffer); | ||
690 | |||
691 | LLMessageSystem* msg = gMessageSystem; | ||
692 | msg->newMessageFast(_PREHASH_SetScriptRunning); | ||
693 | msg->nextBlockFast(_PREHASH_AgentData); | ||
694 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
695 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
696 | msg->nextBlockFast(_PREHASH_Script); | ||
697 | msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); | ||
698 | msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); | ||
699 | msg->addBOOLFast(_PREHASH_Running, TRUE); | ||
700 | msg->sendReliable(object->getRegion()->getHost()); | ||
701 | } | ||
702 | } | ||
703 | } | ||
704 | |||
705 | nextObject(); | ||
706 | } | ||
707 | |||
708 | ///---------------------------------------------------------------------------- | ||
709 | /// Class LLFloaterNotRunQueue | ||
710 | ///---------------------------------------------------------------------------- | ||
711 | |||
712 | // static | ||
713 | LLFloaterNotRunQueue* LLFloaterNotRunQueue::create() | ||
714 | { | ||
715 | S32 left, top; | ||
716 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
717 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
718 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
719 | LLFloaterNotRunQueue* new_queue = new LLFloaterNotRunQueue("queue", | ||
720 | rect); | ||
721 | new_queue->open(); | ||
722 | return new_queue; | ||
723 | } | ||
724 | |||
725 | LLFloaterNotRunQueue::LLFloaterNotRunQueue(const std::string& name, const LLRect& rect) | ||
726 | : LLFloaterScriptQueue(name, rect, NOT_RUN_QUEUE_TITLE, NOT_RUN_START_STRING) | ||
727 | { } | ||
728 | |||
729 | LLFloaterNotRunQueue::~LLFloaterNotRunQueue() | ||
730 | { | ||
731 | } | ||
732 | |||
733 | void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, | ||
734 | InventoryObjectList* inv) | ||
735 | { | ||
736 | // find all of the lsl, leaving off duplicates. We'll remove | ||
737 | // all matching asset uuids on compilation success. | ||
738 | LLDynamicArray<const char*> names; | ||
739 | |||
740 | InventoryObjectList::const_iterator it = inv->begin(); | ||
741 | InventoryObjectList::const_iterator end = inv->end(); | ||
742 | for ( ; it != end; ++it) | ||
743 | { | ||
744 | if((*it)->getType() == LLAssetType::AT_LSL_TEXT) | ||
745 | { | ||
746 | LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); | ||
747 | |||
748 | if (object) | ||
749 | { | ||
750 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
751 | LLScrollListCtrl* list = LLUICtrlFactory::getScrollListByName(this, "queue output"); | ||
752 | char buffer[MAX_STRING]; | ||
753 | sprintf(buffer, "Not running '%s'.", item->getName().c_str()); | ||
754 | list->addSimpleItem(buffer); | ||
755 | |||
756 | LLMessageSystem* msg = gMessageSystem; | ||
757 | msg->newMessageFast(_PREHASH_SetScriptRunning); | ||
758 | msg->nextBlockFast(_PREHASH_AgentData); | ||
759 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
760 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
761 | msg->nextBlockFast(_PREHASH_Script); | ||
762 | msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); | ||
763 | msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); | ||
764 | msg->addBOOLFast(_PREHASH_Running, FALSE); | ||
765 | msg->sendReliable(object->getRegion()->getHost()); | ||
766 | } | ||
767 | } | ||
768 | } | ||
769 | |||
770 | nextObject(); | ||
771 | } | ||
772 | |||
773 | ///---------------------------------------------------------------------------- | ||
774 | /// Local function definitions | ||
775 | ///---------------------------------------------------------------------------- | ||