Added: Content database status update command.

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 13 years ago
parent 5dfa3ea35a
commit 3fe8c02aa5

@ -36,6 +36,7 @@
#include <nel/misc/path.h>
// Project includes
#include "pipeline_service.h"
using namespace std;
using namespace NLMISC;
@ -71,14 +72,24 @@ CDatabaseStatus::~CDatabaseStatus()
bool CDatabaseStatus::getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const
{
// mutex here when reading
return false;
}
void CDatabaseStatus::updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath)
void CDatabaseStatus::updateFileStatus(TFileStatusCallback &callback, const std::string &filePath)
{
// ONLY WHEN MASTER
// mutex when writing
// dummy
CFileStatus fs;
callback(filePath, fs);
// todo add to queue
}
// ******************************************************************
namespace {
struct CDatabaseStatusUpdater
{
public:
@ -106,6 +117,38 @@ public:
}
};
void updateDirectoryStatus(CDatabaseStatus* ds, CDatabaseStatusUpdater &updater, const std::string &dir)
{
std::string dirPath = CPath::standardizePath(dir, true);
std::vector<std::string> dirContents;
CPath::getPathContent(dirPath, false, true, true, dirContents);
for (std::vector<std::string>::iterator it = dirContents.begin(), end = dirContents.end(); it != end; ++it)
{
const std::string subPath = *it;
if (CFile::isDirectory(subPath)) // if the file is a directory!
{
updateDirectoryStatus(ds, updater, subPath);
}
else
{
updater.Mutex.enter();
++updater.FilesRequested;
updater.Mutex.leave();
CFileStatus fileStatus;
if (!ds->getFileStatus(fileStatus, subPath))
{
ds->updateFileStatus(TFileStatusCallback(&updater, &CDatabaseStatusUpdater::fileUpdated), subPath);
}
}
}
}
} /* anonymous namespace */
void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
{
CDatabaseStatusUpdater updater;
@ -115,13 +158,12 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
updater.Ready = false;
updater.CallbackCalled = false;
// recursive loop ...
{
updater.Mutex.enter();
++updater.FilesRequested;
updater.Mutex.leave();
updateFileStatus(TFileStatusCallback(&updater, &CDatabaseStatusUpdater::fileUpdated), "");
}
nlinfo("Starting iteration through database, queueing file status updates.");
// recursive loop
updateDirectoryStatus(this, updater, g_DatabaseDirectory);
nlinfo("Iteration through database, queueing file status updates complete.");
bool done = false;
updater.Mutex.enter();
@ -136,6 +178,8 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
if (done) updater.Callback();
}
// ******************************************************************
} /* namespace PIPELINE */
/* end of file */

@ -90,7 +90,7 @@ public:
/// Tries to read the last file status. Return false if the status is invalid. Call updateFileStatus if the result is false to update asynchronously.
bool getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const;
/// Updates the file status asynchronously. The new file status is broadcast to clients and slaves afterwards.
void updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath);
void updateFileStatus(TFileStatusCallback &callback, const std::string &filePath);
/// Forces an update of the complete database status.
void updateDatabaseStatus(const CCallback<void> &callback);

@ -46,6 +46,7 @@
// Project includes
#include "pipeline_workspace.h"
#include "database_status.h"
// using namespace std;
using namespace NLMISC;
@ -75,6 +76,7 @@ enum EState
UFormLoader *s_FormLoader = NULL;
CPipelineWorkspace *s_PipelineWorkspace = NULL;
CTaskManager *s_TaskManager = NULL;
CDatabaseStatus *s_DatabaseStatus = NULL;
EState s_State = STATE_IDLE;
CMutex s_StateMutex;
@ -93,21 +95,35 @@ TUnifiedCallbackItem s_ShardCallbacks[] = // pipeline_server
{ "N", cbNull },
};
bool tryStateTask(EState state, IRunnable *task)
{
bool result = false;
s_StateMutex.enter();
result = (s_State == STATE_IDLE);
if (result)
{
s_State = state;
}
s_StateMutex.leave();
if (!result) return false;
s_TaskManager->addTask(task);
return true;
}
// ******************************************************************
void initSheets()
{
std::string leveldesignDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDirectory").asString();
std::string leveldesignDfnDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDfnDirectory").asString();
std::string leveldesignPipelineDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignPipelineDirectory").asString();
if (leveldesignDfnDirectory.find(leveldesignDirectory) == std::string::npos)
{
nlinfo("Adding 'LeveldesignDfnDirectory' to search path");
CPath::addSearchPath(leveldesignDfnDirectory, true, false);
}
nlinfo("Adding 'LeveldesignDfnDirectory' to search path (%s)", leveldesignDfnDirectory.c_str());
CPath::addSearchPath(leveldesignDfnDirectory, true, false);
nlinfo("Adding 'LeveldesignDirectory' to search path");
CPath::addSearchPath(leveldesignDirectory, true, false);
nlinfo("Adding 'LeveldesignPipelineDirectory' to search path (%s)", leveldesignPipelineDirectory.c_str());
CPath::addSearchPath(leveldesignPipelineDirectory, true, false);
s_FormLoader = UFormLoader::createLoader();
@ -144,19 +160,33 @@ CReloadSheets s_ReloadSheets;
bool reloadSheets()
{
bool result = false;
s_StateMutex.enter();
result = (s_State == STATE_IDLE);
if (result)
return tryStateTask(STATE_RELOAD_SHEETS, &s_ReloadSheets);
}
// ******************************************************************
class CUpdateDatabaseStatus : public IRunnable
{
virtual void getName (std::string &result) const
{ result = "CUpdateDatabaseStatus"; }
void databaseStatusUpdated()
{
s_State = STATE_RELOAD_SHEETS;
s_StateMutex.enter();
s_State = STATE_IDLE;
s_StateMutex.leave();
}
s_StateMutex.leave();
if (!result) return false;
s_TaskManager->addTask(&s_ReloadSheets);
virtual void run()
{
s_DatabaseStatus->updateDatabaseStatus(CCallback<void>(this, &CUpdateDatabaseStatus::databaseStatusUpdated));
}
};
CUpdateDatabaseStatus s_UpdateDatabaseStatus;
return true;
bool updateDatabaseStatus()
{
return tryStateTask(STATE_DATABASE_STATUS, &s_UpdateDatabaseStatus);
}
// ******************************************************************
@ -206,6 +236,8 @@ public:
s_TaskManager = new CTaskManager();
initSheets();
s_DatabaseStatus = new CDatabaseStatus();
}
/// This function is called every "frame" (you must call init() before). It returns false if the service is stopped.
@ -217,9 +249,13 @@ public:
/// Finalization. Release the service. For example, this function frees all allocations made in the init() function.
virtual void release()
{
delete s_DatabaseStatus;
s_DatabaseStatus = NULL;
releaseSheets();
delete s_TaskManager;
s_TaskManager = NULL;
}
}; /* class CPipelineService */
@ -252,15 +288,22 @@ NLMISC_COMMAND(reloadSheets, "Reload all sheets.", "")
{
if(args.size() != 0) return false;
if (!PIPELINE::reloadSheets())
{
nlinfo("I'm afraid I cannot do this, my friend.");
return false;
}
return true;
}
NLMISC_COMMAND(updateDatabaseStatus, "Updates the entire database status. This also happens on the fly during build.", "")
{
if(args.size() != 0) return false;
if (!PIPELINE::updateDatabaseStatus())
{
nlinfo("I'm afraid I cannot do this, my friend.");
return false;
}
return true;
}
NLNET_SERVICE_MAIN(PIPELINE::CPipelineService, PIPELINE_SHORT_SERVICE_NAME, PIPELINE_LONG_SERVICE_NAME, 0, PIPELINE::s_ShardCallbacks, "", "")

@ -13,5 +13,7 @@
<LOG>Sat Feb 18 13:48:48 2012 (Kaetemi) .Name = Ryzom Core
Sat Feb 18 13:48:48 2012 (Kaetemi) formName Resized = 1
Sat Feb 18 14:44:25 2012 (Kaetemi) .Description = Ryzom Core
Sat Feb 18 14:44:37 2012 (Kaetemi) .Projects[0] = common_interface.pipeline_project</LOG>
Sat Feb 18 14:44:37 2012 (Kaetemi) .Projects[0] = common_interface.pipeline_project
Sat Feb 18 23:23:17 2012 (Kaetemi) .Description = Ryzom Core Test
Sat Feb 18 23:23:26 2012 (Kaetemi) .Description = Ryzom Core</LOG>
</FORM>

Loading…
Cancel
Save