This class can be used as RWLOCK parameter to AIThreadSafe to check that
data is only accessed by a single thread (like
AIThreadSafeSingleThreaded) AND is never write locked when a read or
write lock was already obtained (by the same thread). It doesn't
actually lock anything, it just keeps track if the "lock" was obtained
before. The use case is to check if STL containers aren't being used
(read or write locked) by a calling function when additional write
access is necessary, as write access might invalidate iterator that
point to the container (where the previous lock was taken).
This allows passing a different type than the default AIRWLock for
debugging purposes.
The signature of the class used for RWLOCK should be:
struct RWLock {
// Default constructor.
RWLock(void);
// Block until it's safe to read the data.
// high_priority is a hint that granting this thread the read lock is more important than granting another thread a write lock.
void rdlock(bool high_priority = false);
// Release the obtained read lock.
void rdunlock();
// Block until it's safe to write to the data.
void wrlock();
// Release the obtained write lock.
void wrunlock();
// Convert the obtained write lock into a read lock.
void wr2rdlock();
// Block until it is possible to convert the obtained read lock into a write lock.
void rd2wrlock();
// Return true when a read or write is obtained and subsequent calls to release the lock are expected.
bool isLocked() const;
};
Changes:
Adds LLUICtrlFactory::getBuiltFloater() to return LLFloater* when a floater has been built.
In llviewermenu.cpp's LLShowFloater::handleEvent():
Return early if the floater_name is empty,
otherwise if no anticipated floater is found, build one,
unless one of the same name is already built, then bring it to focus.
Documentation:
In order to add simple codeless floaters, a general understanding of our XMLs is necessary...
A simple codeless floater can be a few things, perhaps not limited to: media browsers, settings controls, and holders for inventory_panels.
So how do you make them conform to the codeless standard?
For the purpose of these examples, my floater file will always be floater_name.xml
Let's start with a shortened xml menu entry:
<menu_item_call label="Name!" name="name">
<on_click function="ShowFloater" userdata="floater_name.xml"/>
</menu_item_call>
Alright, that wasn't so hard, just remember the key in this is ShowFloater is the function and userdata is the filename.
The next part is the actual floater, which isn't so different from making a complex floater..
There are two ways to do this, depending upon desired behavior:
The first behavior is to have only one of the floater open at a time, the following short xml exemplifies this:
<floater name="floater_name.xml" title="Name!"/>
Having a floater with this behavior will cause the menu entry to bring it into focus.
The other behavior is to allow more than one of the floater open at a time:
<floater name="name" title="Name!"/>
In this case, the menu entry will spawn a new version of the floater with every click, regardless of previous ones existing.
Granted, these short <floater/>'s probably aren't but examples and will not likely stand alone.
* Removes polling stuff (call to gMeshRepo.update()) which did
nothing but check if uploads already finished.
* Just creates and runs the state machine (AIMeshUpload) instead
of creating an LLThread derived class (LLMeshUploadThread) and
adding that to a queue, then have the main thread start it
after adding it to another queue in order to keep track of
the instances (both queues are gone).
* mWholeModelUploadURL was moved to the state machine, because
it needs a life time till the responders finishes (can't be
part of the thread object).
* LLMeshUploadThread is now derived from AIThreadImpl instead
of LLThread, so it can be run in a state machine thread.
* The call to LLHTTPClient::post is now done from the main
thread instead of from the thread, but I don't think that is
a problem.