Selection Manager

Category:Viewer Architecture
== Selection Objects ==
Groups of in-world items (e.g. objects and plots of land) that are referenced by the second life UI must be accessed through a selection object. Selection objects are returned by all selection modification functions, such as selectObject() or selectParcelAt(). These selection objects wrap a collection of selected items with simple container-style queries, iterators, and functors. Higher level operations are exposed via the appropriate selection manager object which may either operate on the current default selection, or take a handle to a selection object as a parameter.
=== Selection Handles ===
Selection objects are always accessed through an LLHandle. LLHandles have the semantics of handles and the syntax of pointers. Specifically, LLHandle is a reference counting pointer that can never be NULL. Whenever NULL is assigned to an LLHandle, the handle will instead point to a default empty instance of the referenced object (in this case, an empty selection object). It is up to the referenced object to expose an API to query for validity. There is usually an existing mechanism for this, such as LLObjectSelection::isEmpty(). 
For example:
 LLHandle<LLObjectSelection> object_selection = gSelectMgr->getSelection();
 llinfos << object_selection->getNumObjects() << llendl;
Prints the number of objects currently selected.
 object_selection = NULL;
 llinfos << object_selection->getNumObjects() << llendl;
Prints "0", as object_selection now points to an empty selection. Notice that it is always safe to dereference an LLHandle.
Any time you modify a given selection, you need to update your handle to point to a potentially new selection. For example:
Note: the following code samples refer to a forthcoming selection manager API
 LLHandle<LLObjectSelection> selected_objects = gSelectMgr->getSelection();
 selected_objects = gSelectMgr->addObject(selected_objects, object_ptr);
Generally, a selection will be built once (or modified by an LLTool instance) and the handle will be passed to the selection manager to perform various operations:
Note: the following code samples refer to a forthcoming selection manager API
 gSelectMgr->selectionDelete(selected_objects);
LLHandles, like LLPointers, can be declared via forward declarations in your header files to avoid unecessary dependencies on the referenced object's definition. For example:
 // llfloaterfoo.h
 #include "llmemory.h" // definition of LLHandle
 
 // forward-declare LLObjectSelection without including "llselectmgr.h"
 class LLObjectSelection;
 
 class Foo
 {
 protected:
 LLHandle<LLObjectSelection> mSelection;
 };
=== Selection Lifetime ===
Selections will persist as long as one object selection handle remains in use. As soon as the last UI element loses its selection object handle, the selection manager is free to deselect the corresponding items, and to reuse the referenced selection object. This is normally triggered through a per-frame call to deselectUnused();
Selection managers are also free to invalidate an open selection at any time by clearing its contents. For example, when teleporting away from a set of selected objects, the object selection manager can invalidate all open selections on those objects. As long as the appropriate UI elements reference the selection via a selection object and not direct object pointers, the UI can clean up gracefully. This is usually more efficient and easier to code than alternatives such as referencing objects via UUID.