Rewrite of AIStateMachine, version 2.
This commit is contained in:
@@ -236,6 +236,9 @@ extern BOOL gRandomizeFramerate;
|
||||
extern BOOL gPeriodicSlowFrame;
|
||||
extern BOOL gDebugGL;
|
||||
|
||||
extern void startEngineThread(void);
|
||||
extern void stopEngineThread(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// All from the last globals push...
|
||||
const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard
|
||||
@@ -654,7 +657,7 @@ bool LLAppViewer::init()
|
||||
|
||||
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
|
||||
|
||||
AIStateMachine::setMaxCount(gSavedSettings.getU32("StateMachineMaxTime"));
|
||||
AIEngine::setMaxCount(gSavedSettings.getU32("StateMachineMaxTime"));
|
||||
|
||||
{
|
||||
AIHTTPTimeoutPolicy policy_tmp(
|
||||
@@ -1804,6 +1807,7 @@ bool LLAppViewer::cleanup()
|
||||
llinfos << "Message system deleted." << llendflush;
|
||||
|
||||
LLApp::stopErrorThread(); // The following call is not thread-safe. Have to stop all threads.
|
||||
stopEngineThread();
|
||||
AICurlInterface::cleanupCurl();
|
||||
|
||||
// Cleanup settings last in case other classes reference them.
|
||||
@@ -1880,6 +1884,9 @@ bool LLAppViewer::initThreads()
|
||||
LLWatchdog::getInstance()->init(watchdog_killer_callback);
|
||||
}
|
||||
|
||||
// State machine thread.
|
||||
startEngineThread();
|
||||
|
||||
AICurlInterface::startCurlThread(gSavedSettings.getU32("CurlMaxTotalConcurrentConnections"),
|
||||
gSavedSettings.getU32("CurlConcurrentConnectionsPerHost"),
|
||||
gSavedSettings.getBOOL("NoVerifySSLCert"));
|
||||
@@ -3823,7 +3830,7 @@ void LLAppViewer::idle()
|
||||
|
||||
{
|
||||
LLFastTimer t(FTM_STATEMACHINE);
|
||||
AIStateMachine::mainloop();
|
||||
gMainThreadEngine.mainloop();
|
||||
}
|
||||
|
||||
// Must wait until both have avatar object and mute list, so poll
|
||||
|
||||
@@ -1351,17 +1351,17 @@ void AIMeshUpload::initialize_impl()
|
||||
set_state(AIMeshUpload_start);
|
||||
}
|
||||
|
||||
void AIMeshUpload::multiplex_impl()
|
||||
void AIMeshUpload::multiplex_impl(state_type run_state)
|
||||
{
|
||||
switch (mRunState)
|
||||
switch (run_state)
|
||||
{
|
||||
case AIMeshUpload_start:
|
||||
mMeshUpload.run(this, AIMeshUpload_threadFinished);
|
||||
idle(AIMeshUpload_start); // Wait till the thread finished.
|
||||
idle(); // Wait till the thread finished.
|
||||
break;
|
||||
case AIMeshUpload_threadFinished:
|
||||
mMeshUpload->postRequest(mWholeModelUploadURL, this);
|
||||
idle(AIMeshUpload_threadFinished); // Wait till the responder finished.
|
||||
idle(); // Wait till the responder finished.
|
||||
break;
|
||||
case AIMeshUpload_responderFinished:
|
||||
finish();
|
||||
@@ -1402,14 +1402,6 @@ void LLMeshUploadThread::postRequest(std::string& whole_model_upload_url, AIMesh
|
||||
}
|
||||
}
|
||||
|
||||
void AIMeshUpload::abort_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void AIMeshUpload::finish_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void dump_llsd_to_file(const LLSD& content, std::string filename)
|
||||
{
|
||||
if (gSavedSettings.getBOOL("MeshUploadLogXML"))
|
||||
|
||||
@@ -445,11 +445,9 @@ public:
|
||||
|
||||
protected:
|
||||
// Implement AIStateMachine.
|
||||
/*virtual*/ const char* state_str_impl(state_type) const;
|
||||
/*virtual*/ const char* state_str_impl(state_type run_state) const;
|
||||
/*virtual*/ void initialize_impl();
|
||||
/*virtual*/ void multiplex_impl();
|
||||
/*virtual*/ void abort_impl();
|
||||
/*virtual*/ void finish_impl();
|
||||
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||
};
|
||||
|
||||
class LLMeshRepository
|
||||
|
||||
@@ -136,7 +136,7 @@ static bool handleTerrainScaleChanged(const LLSD& inputvalue)
|
||||
bool handleStateMachineMaxTimeChanged(const LLSD& newvalue)
|
||||
{
|
||||
F32 StateMachineMaxTime = newvalue.asFloat();
|
||||
AIStateMachine::setMaxCount(StateMachineMaxTime);
|
||||
AIEngine::setMaxCount(StateMachineMaxTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ typedef AIAccess<AIRegisteredStateMachines> registered_statemachines_wat;
|
||||
// static
|
||||
void AIEvent::Register(AIEvents event, AIStateMachine* statemachine, bool one_shot)
|
||||
{
|
||||
statemachine->idle();
|
||||
registered_statemachines_wat registered_statemachines_w(registered_statemachines_list[event]);
|
||||
registered_statemachines_w->Register(statemachine, one_shot);
|
||||
}
|
||||
|
||||
@@ -49,19 +49,20 @@ class AIInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsOb
|
||||
protected:
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
mStateMachine->set_state(AIFetchInventoryFolder_folderCompleted);
|
||||
mStateMachine->advance_state(AIFetchInventoryFolder_folderCompleted);
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
AIStateMachine* mStateMachine;
|
||||
LLPointer<AIStateMachine> mStateMachine;
|
||||
};
|
||||
|
||||
AIInventoryFetchDescendentsObserver::AIInventoryFetchDescendentsObserver(AIStateMachine* statemachine, LLUUID const& folder) :
|
||||
mStateMachine(statemachine),
|
||||
LLInventoryFetchDescendentsObserver(folder)
|
||||
{
|
||||
mStateMachine->idle();
|
||||
// Call idle() on the parent state machine before passing it.
|
||||
llassert(mStateMachine->waiting());
|
||||
startFetch();
|
||||
if(isFinished())
|
||||
{
|
||||
@@ -97,14 +98,15 @@ void AIFetchInventoryFolder::initialize_impl(void)
|
||||
set_state(AIFetchInventoryFolder_checkFolderExists);
|
||||
if (!gInventory.isInventoryUsable())
|
||||
{
|
||||
// This immediately calls this->idle(), and then when the event occurs cont().
|
||||
idle();
|
||||
// This calls this->cont() when the event occurs.
|
||||
AIEvent::Register(AIEvent::LLInventoryModel_mIsAgentInvUsable_true, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AIFetchInventoryFolder::multiplex_impl(void)
|
||||
void AIFetchInventoryFolder::multiplex_impl(state_type run_state)
|
||||
{
|
||||
switch (mRunState)
|
||||
switch (run_state)
|
||||
{
|
||||
case AIFetchInventoryFolder_checkFolderExists:
|
||||
{
|
||||
@@ -172,6 +174,7 @@ void AIFetchInventoryFolder::multiplex_impl(void)
|
||||
}
|
||||
case AIFetchInventoryFolder_fetchDescendents:
|
||||
{
|
||||
idle(); // Wait till the state is set to AIFetchInventoryFolder_folderCompleted.
|
||||
// This sets the state to AIFetchInventoryFolder_folderCompleted once the folder is complete.
|
||||
new AIInventoryFetchDescendentsObserver(this, mFolderUUID);
|
||||
break;
|
||||
@@ -193,10 +196,6 @@ void AIFetchInventoryFolder::multiplex_impl(void)
|
||||
}
|
||||
}
|
||||
|
||||
void AIFetchInventoryFolder::abort_impl(void)
|
||||
{
|
||||
}
|
||||
|
||||
void AIFetchInventoryFolder::finish_impl(void)
|
||||
{
|
||||
if (mNeedNotifyObservers)
|
||||
|
||||
@@ -138,10 +138,7 @@ class AIFetchInventoryFolder : public AIStateMachine {
|
||||
/*virtual*/ void initialize_impl(void);
|
||||
|
||||
// Handle mRunState.
|
||||
/*virtual*/ void multiplex_impl(void);
|
||||
|
||||
// Handle aborting from current bs_run state.
|
||||
/*virtual*/ void abort_impl(void);
|
||||
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||
|
||||
// Handle cleaning up from initialization (or post abort) state.
|
||||
/*virtual*/ void finish_impl(void);
|
||||
|
||||
@@ -66,7 +66,7 @@ char const* AIFilePicker::state_str_impl(state_type run_state) const
|
||||
return "UNKNOWN STATE";
|
||||
}
|
||||
|
||||
AIFilePicker::AIFilePicker(void) : mPluginManager(NULL), mAutoKill(false), mCanceled(false)
|
||||
AIFilePicker::AIFilePicker(void) : mPluginManager(NULL), mCanceled(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ void AIFilePicker::initialize_impl(void)
|
||||
set_state(AIFilePicker_initialize_plugin);
|
||||
}
|
||||
|
||||
void AIFilePicker::multiplex_impl(void)
|
||||
void AIFilePicker::multiplex_impl(state_type run_state)
|
||||
{
|
||||
mPluginManager->update(); // Give the plugin some CPU for it's messages.
|
||||
LLPluginClassBasic* plugin = mPluginManager->getPlugin();
|
||||
@@ -355,7 +355,7 @@ void AIFilePicker::multiplex_impl(void)
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
switch (mRunState)
|
||||
switch (run_state)
|
||||
{
|
||||
case AIFilePicker_initialize_plugin:
|
||||
{
|
||||
@@ -430,10 +430,6 @@ void AIFilePicker::multiplex_impl(void)
|
||||
}
|
||||
}
|
||||
|
||||
void AIFilePicker::abort_impl(void)
|
||||
{
|
||||
}
|
||||
|
||||
void AIFilePicker::finish_impl(void)
|
||||
{
|
||||
if (mPluginManager)
|
||||
@@ -442,12 +438,6 @@ void AIFilePicker::finish_impl(void)
|
||||
mPluginManager = NULL;
|
||||
}
|
||||
mFilter.clear(); // Check that open is called before calling run (again).
|
||||
if (mAutoKill)
|
||||
{
|
||||
// The default behavior is to delete the plugin. This can be overridden in
|
||||
// the callback by calling run() again.
|
||||
kill();
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called when a new message is received from the plugin.
|
||||
@@ -467,7 +457,7 @@ void AIFilePicker::receivePluginMessage(const LLPluginMessage &message)
|
||||
if (message_name == "canceled")
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "received message \"canceled\"" << LL_ENDL;
|
||||
set_state(AIFilePicker_canceled);
|
||||
advance_state(AIFilePicker_canceled);
|
||||
}
|
||||
else if (message_name == "done")
|
||||
{
|
||||
@@ -478,7 +468,7 @@ void AIFilePicker::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
mFilenames.push_back(*filename);
|
||||
}
|
||||
set_state(AIFilePicker_done);
|
||||
advance_state(AIFilePicker_done);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -136,8 +136,8 @@ new AIFilePicker
|
||||
which sets the state to AIFilePicker_canceled or AIFilePicker_done
|
||||
respectively, causing a call to AIStateMachine::finish(), which calls
|
||||
AIFilePicker::finish_impl which destroys the plugin (mPluginBase),
|
||||
the plugin manager (mPluginManager) and calls AIStateMachine::kill()
|
||||
causing the AIFilePicker to be deleted.
|
||||
the plugin manager (mPluginManager) after which the state machine
|
||||
calls unref() causing the AIFilePicker to be deleted.
|
||||
|
||||
*/
|
||||
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
AIFilePicker(void);
|
||||
|
||||
// Create a dynamically created AIFilePicker object.
|
||||
static AIFilePicker* create(bool auto_kill = true) { AIFilePicker* filepicker = new AIFilePicker; filepicker->mAutoKill = auto_kill; return filepicker; }
|
||||
static AIFilePicker* create(void) { AIFilePicker* filepicker = new AIFilePicker; return filepicker; }
|
||||
|
||||
// The starting directory that the user will be in when the file picker opens
|
||||
// will be the same as the directory used the last time the file picker was
|
||||
@@ -191,7 +191,6 @@ private:
|
||||
typedef std::map<std::string, std::string> context_map_type; //!< Type of mContextMap.
|
||||
static AIThreadSafeSimpleDC<context_map_type> sContextMap; //!< Map context (ie, "snapshot" or "image") to last used folder.
|
||||
std::string mContext; //!< Some key to indicate the context (remembers the folder per key).
|
||||
bool mAutoKill; //!< True if the default behavior is to delete itself after being finished.
|
||||
|
||||
// Input variables (cache variable between call to open and run).
|
||||
open_type mOpenType; //!< Set to whether opening a filepicker to select for saving one file, for loading one file, or loading multiple files.
|
||||
@@ -215,10 +214,7 @@ protected:
|
||||
/*virtual*/ void initialize_impl(void);
|
||||
|
||||
// Handle mRunState.
|
||||
/*virtual*/ void multiplex_impl(void);
|
||||
|
||||
// Handle aborting from current bs_run state.
|
||||
/*virtual*/ void abort_impl(void);
|
||||
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||
|
||||
// Handle cleaning up from initialization (or post abort) state.
|
||||
/*virtual*/ void finish_impl(void);
|
||||
|
||||
Reference in New Issue
Block a user