Rewrite of AIStateMachine, version 2.

This commit is contained in:
Aleric Inglewood
2013-03-01 00:59:06 +01:00
parent 4851cc174e
commit c4dceaf3e9
22 changed files with 1375 additions and 974 deletions

View File

@@ -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

View File

@@ -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"))

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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);