diff --git a/code/nel/tools/pipeline/pipeline_service/callback.cpp b/code/nel/tools/pipeline/pipeline_service/callback.cpp
new file mode 100644
index 000000000..a4347388b
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/callback.cpp
@@ -0,0 +1,51 @@
+/**
+ * \file callback.cpp
+ * \brief CCallback
+ * \date 2009-03-03 18:09GMT
+ * \author Jan Boon (Kaetemi)
+ * CCallback
+ */
+
+/*
+ * Copyright (C) 2009-2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#include
+#include "callback.h"
+
+// STL includes
+
+// NeL includes
+// #include
+
+// Project includes
+
+using namespace std;
+// using namespace NLMISC;
+
+namespace PIPELINE {
+
+typedef CCallback CTestCallback;
+bool test_blah(const int &) { return false; }
+class CTestMeeeee { public: CTestMeeeee() { } bool test_method(const int &) { return true; } };
+void dummy_callback_cpp() { int whaha = 0; CTestCallback testCallback; testCallback.callback(whaha); testCallback = CTestCallback(test_blah);
+ CTestMeeeee blahsomething; testCallback = CTestCallback(&blahsomething, &CTestMeeeee::test_method); }
+
+} /* namespace PIPELINE */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/callback.h b/code/nel/tools/pipeline/pipeline_service/callback.h
new file mode 100644
index 000000000..114fb3d12
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/callback.h
@@ -0,0 +1,326 @@
+/**
+ * \file callback.h
+ * \brief PIPELINE_CALLBACK_ARGS_CLASS
+ * \date 2009-03-03 18:09GMT
+ * \author Jan Boon (Kaetemi)
+ * PIPELINE_CALLBACK_ARGS_CLASS
+ */
+
+/*
+ * Copyright (C) 2009-2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#ifndef PIPELINE_CALLBACK_H
+#define PIPELINE_CALLBACK_H
+#include
+
+// STL includes
+
+// NeL includes
+#include
+
+// Project includes
+
+namespace PIPELINE {
+
+#define PIPELINE_CALLBACK_TEMPLATE \
+/** \
+ * \brief PIPELINE_CALLBACK_ARGS_CLASS \
+ * \date 2009-03-03 18:09GMT \
+ * \author Jan Boon (Kaetemi) \
+ * Awesome callback template \
+ */ \
+template \
+class PIPELINE_CALLBACK_ARGS_CLASS \
+{ \
+ /* Very simple reference counting callback base */ \
+ class CCallbackBase \
+ { \
+ public: \
+ CCallbackBase() : m_RefCount(0) \
+ { \
+ \
+ } \
+ \
+ virtual ~CCallbackBase() \
+ { \
+ nlassert(!m_RefCount); \
+ } \
+ \
+ void refAdd() \
+ { \
+ ++m_RefCount; \
+ } \
+ \
+ void refRemove() \
+ { \
+ --m_RefCount; \
+ if (!m_RefCount) \
+ delete this; \
+ } \
+ \
+ virtual TReturn callback(PIPELINE_CALLBACK_ARGS_DECL) = 0; \
+ \
+ virtual bool equals(const CCallbackBase *callbackBase) = 0; \
+ \
+ /* disable copy */ \
+ CCallbackBase(const CCallbackBase &); \
+ CCallbackBase &operator=(const CCallbackBase &); \
+ \
+ private: \
+ uint m_RefCount; \
+ }; \
+ \
+ typedef TReturn TCallbackFunction(PIPELINE_CALLBACK_ARGS_DECL); \
+ class CCallbackFunction : public CCallbackBase \
+ { \
+ public: \
+ CCallbackFunction(TCallbackFunction *callbackFunction) : m_CallbackFunction(callbackFunction) \
+ { \
+ nlassert(m_CallbackFunction); \
+ } \
+ \
+ virtual ~CCallbackFunction() \
+ { \
+ m_CallbackFunction = NULL; \
+ } \
+ \
+ virtual TReturn callback(PIPELINE_CALLBACK_ARGS_DECL) \
+ { \
+ return m_CallbackFunction(PIPELINE_CALLBACK_ARGS_IMPL); \
+ } \
+ \
+ virtual bool equals(const CCallbackBase *callbackBase) \
+ { \
+ const CCallbackFunction *callbackFunction = \
+ dynamic_cast(callbackBase); \
+ if (!callbackFunction) return false; \
+ return m_CallbackFunction == callbackFunction->m_CallbackFunction; \
+ } \
+ \
+ private: \
+ TCallbackFunction *m_CallbackFunction; \
+ }; \
+ \
+ template \
+ class CCallbackMethod : public CCallbackBase \
+ { \
+ typedef TReturn (TClass::*TCallbackMethod)(PIPELINE_CALLBACK_ARGS_DECL); \
+ public: \
+ CCallbackMethod(TClass *callbackObject, TCallbackMethod callbackMethod) : m_CallbackObject(callbackObject), m_CallbackMethod(callbackMethod) \
+ { \
+ nlassert(m_CallbackObject); \
+ nlassert(m_CallbackMethod); \
+ } \
+ \
+ virtual ~CCallbackMethod() \
+ { \
+ m_CallbackObject = NULL; \
+ m_CallbackMethod = NULL; \
+ } \
+ \
+ virtual TReturn callback(PIPELINE_CALLBACK_ARGS_DECL) \
+ { \
+ return (m_CallbackObject->*m_CallbackMethod)(PIPELINE_CALLBACK_ARGS_IMPL); \
+ } \
+ \
+ virtual bool equals(const CCallbackBase *callbackBase) \
+ { \
+ const CCallbackMethod *callbackMethod = \
+ dynamic_cast(callbackBase); \
+ if (!callbackMethod) return false; \
+ return m_CallbackObject == callbackMethod->m_CallbackObject \
+ && m_CallbackMethod == callbackMethod->m_CallbackMethod; \
+ } \
+ \
+ private: \
+ TClass *m_CallbackObject; \
+ TCallbackMethod m_CallbackMethod; \
+ }; \
+ \
+public: \
+ CCallback() : m_CallbackBase(NULL) \
+ { \
+ \
+ } \
+ \
+ CCallback(TCallbackFunction *callbackFunction) : m_CallbackBase(new CCallbackFunction(callbackFunction)) \
+ { \
+ nlassert(m_CallbackBase); \
+ m_CallbackBase->refAdd(); \
+ } \
+ \
+ template \
+ CCallback(TClass *callbackObject, TReturn (TClass::*callbackMethod)(PIPELINE_CALLBACK_ARGS_DECL)) : m_CallbackBase(new CCallbackMethod(callbackObject, callbackMethod)) \
+ { \
+ nlassert(m_CallbackBase); \
+ m_CallbackBase->refAdd(); \
+ } \
+ \
+ CCallback(const CCallback &callback) \
+ { \
+ m_CallbackBase = callback.m_CallbackBase; \
+ if (m_CallbackBase) \
+ m_CallbackBase->refAdd(); \
+ } \
+ \
+ CCallback &operator=(const CCallback &callback) \
+ { \
+ if (m_CallbackBase != callback.m_CallbackBase) \
+ { \
+ if (m_CallbackBase) \
+ m_CallbackBase->refRemove(); \
+ m_CallbackBase = callback.m_CallbackBase; \
+ if (m_CallbackBase) \
+ m_CallbackBase->refAdd(); \
+ } \
+ return *this; \
+ } \
+ \
+ ~CCallback() \
+ { \
+ if (m_CallbackBase) \
+ { \
+ m_CallbackBase->refRemove(); \
+ m_CallbackBase = NULL; \
+ } \
+ } \
+ \
+ TReturn callback(PIPELINE_CALLBACK_ARGS_DECL) \
+ { \
+ nlassert(m_CallbackBase); \
+ return m_CallbackBase->callback(PIPELINE_CALLBACK_ARGS_IMPL); \
+ } \
+ \
+ TReturn operator()(PIPELINE_CALLBACK_ARGS_DECL) \
+ { \
+ nlassert(m_CallbackBase); \
+ return m_CallbackBase->callback(PIPELINE_CALLBACK_ARGS_IMPL); \
+ } \
+ \
+ bool valid() const \
+ { \
+ return m_CallbackBase != NULL; \
+ } \
+ \
+ operator bool() const \
+ { \
+ return m_CallbackBase != NULL; \
+ } \
+ \
+ bool operator==(const CCallback &callback) \
+ { \
+ return m_CallbackBase->equals(callback.m_CallbackBase); \
+ } \
+ \
+private: \
+ CCallbackBase *m_CallbackBase; \
+ \
+}; /* class CCallback */ \
+
+template
+class CCallback;
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME
+#define PIPELINE_CALLBACK_ARGS_DECL
+#define PIPELINE_CALLBACK_ARGS_IMPL
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB, argsC
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+
+#define PIPELINE_CALLBACK_ARGS_CLASS CCallback
+#define PIPELINE_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF, typename TArgsG
+#define PIPELINE_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF, TArgsG argsG
+#define PIPELINE_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF, argsG
+PIPELINE_CALLBACK_TEMPLATE
+#undef PIPELINE_CALLBACK_ARGS_CLASS
+#undef PIPELINE_CALLBACK_ARGS_TYPENAME
+#undef PIPELINE_CALLBACK_ARGS_DECL
+#undef PIPELINE_CALLBACK_ARGS_IMPL
+#undef PIPELINE_CALLBACK_ARGS_CLASSNAME
+
+#undef PIPELINE_CALLBACK_TEMPLATE
+
+} /* namespace PIPELINE */
+
+#endif /* #ifndef PIPELINE_CALLBACK_H */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/database_status.cpp b/code/nel/tools/pipeline/pipeline_service/database_status.cpp
new file mode 100644
index 000000000..bc46fe030
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/database_status.cpp
@@ -0,0 +1,141 @@
+/**
+ * \file database_status.cpp
+ * \brief CDatabaseStatus
+ * \date 2012-02-18 18:11GMT
+ * \author Jan Boon (Kaetemi)
+ * CDatabaseStatus
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#include
+#include "database_status.h"
+
+// STL includes
+
+// NeL includes
+// #include
+#include
+#include
+
+// Project includes
+
+using namespace std;
+using namespace NLMISC;
+
+namespace PIPELINE {
+
+void CFileError::serial(NLMISC::IStream &stream)
+{
+ uint version = stream.serialVersion(1);
+ stream.serial(Project);
+ stream.serial(Process);
+ stream.serial(Message);
+}
+
+void CFileStatus::serial(NLMISC::IStream &stream)
+{
+ uint version = stream.serialVersion(1);
+ stream.serial(FirstSeen);
+ stream.serial(LastChanged);
+ stream.serial(LastUpdate);
+ stream.serial(CRC32);
+}
+
+CDatabaseStatus::CDatabaseStatus()
+{
+
+}
+
+CDatabaseStatus::~CDatabaseStatus()
+{
+
+}
+
+bool CDatabaseStatus::getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const
+{
+ return false;
+}
+
+void CDatabaseStatus::updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath)
+{
+
+}
+
+struct CDatabaseStatusUpdater
+{
+public:
+ CCallback Callback;
+
+ CMutex Mutex;
+ uint FilesRequested;
+ uint FilesUpdated;
+ bool Ready;
+ bool CallbackCalled;
+
+ void fileUpdated(const std::string &filePath, const CFileStatus &fileStatus)
+ {
+ bool done = false;
+ Mutex.enter();
+ ++FilesUpdated;
+ if (FilesRequested == FilesUpdated && Ready && !CallbackCalled)
+ {
+ done = true;
+ CallbackCalled = true;
+ }
+ Mutex.leave();
+
+ if (done) Callback();
+ }
+};
+
+void CDatabaseStatus::updateDatabaseStatus(const CCallback &callback)
+{
+ CDatabaseStatusUpdater updater;
+ updater.Callback = callback;
+ updater.FilesRequested = 0;
+ updater.FilesUpdated = 0;
+ updater.Ready = false;
+ updater.CallbackCalled = false;
+
+ // recursive loop ...
+ {
+ updater.Mutex.enter();
+ ++updater.FilesRequested;
+ updater.Mutex.leave();
+ updateFileStatus(TFileStatusCallback(&updater, &CDatabaseStatusUpdater::fileUpdated), "");
+ }
+
+ bool done = false;
+ updater.Mutex.enter();
+ updater.Ready = true;
+ if (updater.FilesRequested == updater.FilesUpdated && !updater.CallbackCalled)
+ {
+ done = true;
+ updater.CallbackCalled = true;
+ }
+ updater.Mutex.leave();
+
+ if (done) updater.Callback();
+}
+
+} /* namespace PIPELINE */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/database_status.h b/code/nel/tools/pipeline/pipeline_service/database_status.h
new file mode 100644
index 000000000..ca17dc7ae
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/database_status.h
@@ -0,0 +1,106 @@
+/**
+ * \file database_status.h
+ * \brief CDatabaseStatus
+ * \date 2012-02-18 18:11GMT
+ * \author Jan Boon (Kaetemi)
+ * CDatabaseStatus
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#ifndef PIPELINE_DATABASE_STATUS_H
+#define PIPELINE_DATABASE_STATUS_H
+#include
+
+// STL includes
+#include
+
+// NeL includes
+#include
+#include
+
+// Project includes
+#include "callback.h"
+
+namespace PIPELINE {
+
+#define PIPELINE_DATABASE_STATUS_SUBDIR "database.status"
+#define PIPELINE_DATABASE_ERRORS_SUBDIR "database.errors"
+
+struct CFileError
+{
+public:
+ uint32 Time; // The time when this error occured.
+ std::string Project;
+ std::string Process;
+ std::string Message;
+
+ void serial(NLMISC::IStream &stream);
+};
+
+/// Errors set by a process when the file causes a build failure.
+typedef std::vector CFileErrors;
+
+struct CFileStatus
+{
+public:
+ uint32 FirstSeen;
+ uint32 LastChanged; // The modification date value read when the CRC32 was calculated.
+ uint32 LastUpdate; // The start time when the CRC32 was calculated.
+ uint32 CRC32;
+
+ void serial(NLMISC::IStream &stream);
+};
+
+typedef CCallback TFileStatusCallback;
+
+/**
+ * \brief CDatabaseStatus
+ * \date 2012-02-18 18:11GMT
+ * \author Jan Boon (Kaetemi)
+ * CDatabaseStatus
+ */
+class CDatabaseStatus
+{
+protected:
+ NLMISC::CMutex m_StatusMutex;
+ NLMISC::CMutex m_ErrorMutex;
+
+public:
+ CDatabaseStatus();
+ virtual ~CDatabaseStatus();
+
+ /// 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);
+ /// Forces an update of the complete database status.
+ void updateDatabaseStatus(const CCallback &callback);
+
+ void getFileErrors(CFileErrors &fileErrors, const std::string &filePath, uint32 newerThan = 0) const;
+ void addFileError(const std::string &filePath, const CFileError &fileError);
+
+}; /* class CDatabaseStatus */
+
+} /* namespace PIPELINE */
+
+#endif /* #ifndef PIPELINE_DATABASE_STATUS_H */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp
new file mode 100644
index 000000000..5828e5677
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp
@@ -0,0 +1,268 @@
+/**
+ * \file pipeline_service.cpp
+ * \brief CPipelineService
+ * \date 2012-02-18 17:25GMT
+ * \author Jan Boon (Kaetemi)
+ * CPipelineService
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#include
+#include "pipeline_service.h"
+
+// STL includes
+#include
+#ifdef NL_OS_WINDOWS
+# define NOMINMAX
+# include
+#endif
+
+// NeL includes
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Project includes
+#include "pipeline_workspace.h"
+
+// using namespace std;
+using namespace NLMISC;
+using namespace NLNET;
+using namespace NLGEORGES;
+
+namespace PIPELINE {
+
+bool g_IsMaster = false;
+std::string g_DatabaseDirectory;
+std::string g_PipelineDirectory;
+
+namespace {
+
+#define PIPELINE_LONG_SERVICE_NAME "pipeline_service"
+#define PIPELINE_SHORT_SERVICE_NAME "PLS"
+
+/// Enum
+enum EState
+{
+ STATE_IDLE,
+ STATE_RELOAD_SHEETS,
+ STATE_DATABASE_STATUS,
+};
+
+/// Data
+UFormLoader *s_FormLoader = NULL;
+CPipelineWorkspace *s_PipelineWorkspace = NULL;
+CTaskManager *s_TaskManager = NULL;
+
+EState s_State = STATE_IDLE;
+CMutex s_StateMutex;
+
+// ******************************************************************
+
+/// Service wants to broadcast all users trough pipeline
+void cbNull(CMessage & /* msgin */, const std::string & /* serviceName */, TServiceId /* sid */) // pipeline_server
+{
+ // null
+}
+
+/// Callbacks from shard
+TUnifiedCallbackItem s_ShardCallbacks[] = // pipeline_server
+{
+ { "N", cbNull },
+};
+
+// ******************************************************************
+
+void initSheets()
+{
+ std::string leveldesignDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDirectory").asString();
+ std::string leveldesignDfnDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDfnDirectory").asString();
+
+ if (leveldesignDfnDirectory.find(leveldesignDirectory) == std::string::npos)
+ {
+ nlinfo("Adding 'LeveldesignDfnDirectory' to search path");
+ CPath::addSearchPath(leveldesignDfnDirectory, true, false);
+ }
+
+ nlinfo("Adding 'LeveldesignDirectory' to search path");
+ CPath::addSearchPath(leveldesignDirectory, true, false);
+
+ s_FormLoader = UFormLoader::createLoader();
+
+ s_PipelineWorkspace = new CPipelineWorkspace(s_FormLoader, IService::getInstance()->ConfigFile.getVar("WorkspaceSheet").asString());
+}
+
+void releaseSheets()
+{
+ delete s_PipelineWorkspace;
+ s_PipelineWorkspace = NULL;
+
+ UFormLoader::releaseLoader(s_FormLoader);
+ s_FormLoader = NULL;
+
+ CPath::releaseInstance();
+}
+
+class CReloadSheets : public IRunnable
+{
+ virtual void getName (std::string &result) const
+ { result = "CReloadSheets"; }
+
+ virtual void run()
+ {
+ releaseSheets();
+ initSheets();
+
+ s_StateMutex.enter();
+ s_State = STATE_IDLE;
+ s_StateMutex.leave();
+ }
+};
+CReloadSheets s_ReloadSheets;
+
+bool reloadSheets()
+{
+ bool result = false;
+ s_StateMutex.enter();
+ result = (s_State == STATE_IDLE);
+ if (result)
+ {
+ s_State = STATE_RELOAD_SHEETS;
+ }
+ s_StateMutex.leave();
+ if (!result) return false;
+
+ s_TaskManager->addTask(&s_ReloadSheets);
+
+ return true;
+}
+
+// ******************************************************************
+
+/**
+ * \brief CPipelineService
+ * \date 2012-02-18 17:25GMT
+ * \author Jan Boon (Kaetemi)
+ * CPipelineService
+ */
+class CPipelineService : public IService
+{
+private:
+
+public:
+ CPipelineService()
+ {
+
+ }
+
+ virtual ~CPipelineService()
+ {
+
+ }
+
+ /** Called before the displayer is created, no displayer or network connection are built.
+ Use this callback to check some args and perform some command line based stuff */
+ virtual void commandStart()
+ {
+ // setup the randomizer properly
+ {
+ // get a good seed value from cpu dependent ticks or just milliseconds local
+ uint32 s = (uint32)(CTime::getPerformanceTime() & 0xFFFFFFFF);
+ if (!s) s = (uint32)(CTime::getLocalTime() & 0xFFFFFFFF);
+ // seed the randomizer
+ srand(s);
+ }
+ }
+
+ /// Initializes the service (must be called before the first call to update())
+ virtual void init()
+ {
+ g_IsMaster = ConfigFile.getVar("IsMaster").asBool();
+ g_DatabaseDirectory = ConfigFile.getVar("DatabaseDirectory").asString();
+ g_PipelineDirectory = ConfigFile.getVar("PipelineDirectory").asString();
+
+ s_TaskManager = new CTaskManager();
+
+ initSheets();
+ }
+
+ /// This function is called every "frame" (you must call init() before). It returns false if the service is stopped.
+ virtual bool update()
+ {
+ return true;
+ }
+
+ /// Finalization. Release the service. For example, this function frees all allocations made in the init() function.
+ virtual void release()
+ {
+ releaseSheets();
+
+ delete s_TaskManager;
+ }
+
+}; /* class CPipelineService */
+
+} /* anonymous namespace */
+
+} /* namespace PIPELINE */
+
+NLMISC_DYNVARIABLE(std::string, pipelineServiceState, "State of the pipeline service.")
+{
+ // we can only read the value
+ if (get)
+ {
+ switch (PIPELINE::s_State)
+ {
+ case PIPELINE::STATE_IDLE:
+ *pointer = "IDLE";
+ break;
+ case PIPELINE::STATE_RELOAD_SHEETS:
+ *pointer = "RELOAD_SHEETS";
+ break;
+ case PIPELINE::STATE_DATABASE_STATUS:
+ *pointer = "DATABASE_STATUS";
+ break;
+ }
+ }
+}
+
+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 true;
+}
+
+NLMISC_COMMAND(updateDatabaseStatus, "Updates the entire database status. This also happens on the fly during build.", "")
+{
+ if(args.size() != 0) return false;
+
+
+}
+
+NLNET_SERVICE_MAIN(PIPELINE::CPipelineService, PIPELINE_SHORT_SERVICE_NAME, PIPELINE_LONG_SERVICE_NAME, 0, PIPELINE::s_ShardCallbacks, "", "")
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_service.h b/code/nel/tools/pipeline/pipeline_service/pipeline_service.h
new file mode 100644
index 000000000..bbf8ea32a
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/pipeline_service.h
@@ -0,0 +1,49 @@
+/**
+ * \file pipeline_service.h
+ * \brief CPipelineService
+ * \date 2012-02-18 17:25GMT
+ * \author Jan Boon (Kaetemi)
+ * CPipelineService
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#ifndef PIPELINE_PIPELINE_SERVICE_H
+#define PIPELINE_PIPELINE_SERVICE_H
+#include
+
+// STL includes
+#include
+
+// NeL includes
+
+// Project includes
+
+namespace PIPELINE {
+
+extern bool g_IsMaster;
+extern std::string g_DatabaseDirectory;
+extern std::string g_PipelineDirectory;
+
+} /* namespace PIPELINE */
+
+#endif /* #ifndef PIPELINE_PIPELINE_SERVICE_H */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.cpp b/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.cpp
new file mode 100644
index 000000000..e625c8d0b
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.cpp
@@ -0,0 +1,60 @@
+/**
+ * \file pipeline_workspace.cpp
+ * \brief CPipelineWorkspace
+ * \date 2012-02-18 17:23GMT
+ * \author Jan Boon (Kaetemi)
+ * CPipelineWorkspace
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#include
+#include "pipeline_workspace.h"
+
+// STL includes
+
+// NeL includes
+// #include
+#include
+
+// Project includes
+
+using namespace std;
+// using namespace NLMISC;
+using namespace NLGEORGES;
+
+namespace PIPELINE {
+
+CPipelineWorkspace::CPipelineWorkspace(NLGEORGES::UFormLoader *formLoader, const std::string &sheetName) : m_FormLoader(formLoader)
+{
+ m_Form = formLoader->loadForm(sheetName.c_str());
+ std::string description;
+ m_Form->getRootNode().getValueByName(description, "Description");
+ nlinfo("Loading pipeline workspace: '%s'", description.c_str());
+}
+
+CPipelineWorkspace::~CPipelineWorkspace()
+{
+
+}
+
+} /* namespace PIPELINE */
+
+/* end of file */
diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.h b/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.h
new file mode 100644
index 000000000..f5867e854
--- /dev/null
+++ b/code/nel/tools/pipeline/pipeline_service/pipeline_workspace.h
@@ -0,0 +1,68 @@
+/**
+ * \file pipeline_workspace.h
+ * \brief CPipelineWorkspace
+ * \date 2012-02-18 17:23GMT
+ * \author Jan Boon (Kaetemi)
+ * CPipelineWorkspace
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#ifndef PIPELINE_PIPELINE_WORKSPACE_H
+#define PIPELINE_PIPELINE_WORKSPACE_H
+#include
+
+// STL includes
+#include
+#include