diff --git a/code/nel/tools/pipeline/pipeline_library/pipeline_interface.h b/code/nel/tools/pipeline/pipeline_library/pipeline_interface.h index 5ab09db18..f5b93dcc4 100644 --- a/code/nel/tools/pipeline/pipeline_library/pipeline_interface.h +++ b/code/nel/tools/pipeline/pipeline_library/pipeline_interface.h @@ -33,11 +33,13 @@ // NeL includes #include +#include // Project includes namespace NLMISC { class CConfigFile; + class IRunnable; } namespace PIPELINE { @@ -56,9 +58,18 @@ public: static IPipelineInterface *getInstance(); + /// Get the configuration file of the pipeline service. Must only be used for configuration values that may be different on different services, such as tool paths. virtual NLMISC::CConfigFile &getConfigFile() = 0; + + /// Register a process class with the pipeline service. You should use the PIPELINE_REGISTER_CLASS macro. virtual void registerClass(const std::string &className, NLMISC::IClassable* (*creator)(), const std::string &typeidCheck) throw(NLMISC::ERegistry) = 0; + /// Runs a runnable task if STATE_IDLE. You must call endedRunnableTask when the task has ended. + virtual bool tryRunnableTask(std::string stateName, NLMISC::IRunnable *task) = 0; + + /// Call when a runnable task has ended to reset to STATE_IDLE. + virtual void endedRunnableTask() = 0; + }; /* class IPipelineInterface */ #define PIPELINE_REGISTER_CLASS(_class_) PIPELINE::IPipelineInterface::getInstance()->registerClass(#_class_, _class_::creator, typeid(_class_).name()); diff --git a/code/nel/tools/pipeline/pipeline_plugin_max/process_max_shape.cpp b/code/nel/tools/pipeline/pipeline_plugin_max/process_max_shape.cpp index 1c2dba78a..3f80111e3 100644 --- a/code/nel/tools/pipeline/pipeline_plugin_max/process_max_shape.cpp +++ b/code/nel/tools/pipeline/pipeline_plugin_max/process_max_shape.cpp @@ -32,8 +32,11 @@ // NeL includes // #include +#include +#include // Project includes +#include "../pipeline_library/pipeline_interface.h" using namespace std; // using namespace NLMISC; @@ -50,6 +53,35 @@ CProcessMaxShape::~CProcessMaxShape() } +namespace { + +class CMaxExportShapeCommand : public NLMISC::IRunnable +{ + virtual void getName(std::string &result) const + { result = "CMaxExportShapeCommand"; } + + virtual void run() + { + // ... + + PIPELINE::IPipelineInterface::getInstance()->endedRunnableTask(); + } +}; +CMaxExportShapeCommand s_MaxExportShapeCommand; + +} /* anonymous namespace */ + } /* namespace PIPELINE */ +NLMISC_CATEGORISED_COMMAND(max, maxExportShape, "Export shapes from a .max file manually.", " ") +{ + if(args.size() != 2) return false; + if (!PIPELINE::IPipelineInterface::getInstance()->tryRunnableTask("COMMAND_MAX_EXPORT_SHAPE", &PIPELINE::s_MaxExportShapeCommand)) + { + log.displayNL("Busy."); + return false; + } + return true; +} + /* end of file */ diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.cpp b/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.cpp index a340a7b71..03f168ec6 100644 --- a/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.cpp +++ b/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.cpp @@ -37,6 +37,7 @@ #include // Project includes +#include "pipeline_service.h" using namespace std; // using namespace NLMISC; @@ -66,6 +67,16 @@ void CPipelineInterfaceImpl::registerClass(const std::string &className, NLMISC: nldebug("Registered class '%s'", className.c_str()); } +bool CPipelineInterfaceImpl::tryRunnableTask(std::string stateName, NLMISC::IRunnable *task) +{ + return PIPELINE::tryRunnableTask(stateName, task); +} + +void CPipelineInterfaceImpl::endedRunnableTask() +{ + PIPELINE::endedRunnableTask(); +} + } /* namespace PIPELINE */ /* end of file */ diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.h b/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.h index 3fdb6d2a1..994f2a866 100644 --- a/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.h +++ b/code/nel/tools/pipeline/pipeline_service/pipeline_interface_impl.h @@ -62,6 +62,8 @@ public: virtual NLMISC::CConfigFile &getConfigFile(); virtual void registerClass(const std::string &className, NLMISC::IClassable* (*creator)(), const std::string &typeidCheck) throw(NLMISC::ERegistry); + virtual bool tryRunnableTask(std::string stateName, NLMISC::IRunnable *task); + virtual void endedRunnableTask(); }; /* class CPipelineInterfaceImpl */ } /* namespace PIPELINE */ diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp index 674c7b080..0659cf295 100644 --- a/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp +++ b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp @@ -102,6 +102,7 @@ enum EState STATE_IDLE, STATE_RELOAD_SHEETS, STATE_DATABASE_STATUS, + STATE_RUNNABLE_TASK, }; /// Data @@ -112,6 +113,7 @@ CDatabaseStatus *s_DatabaseStatus = NULL; CPipelineInterfaceImpl *s_PipelineInterfaceImpl = NULL; EState s_State = STATE_IDLE; +std::string s_StateRunnableTaskName = ""; CMutex s_StateMutex; std::vector s_LoadedLibraries; @@ -141,14 +143,51 @@ bool tryStateTask(EState state, IRunnable *task) } s_StateMutex.leave(); if (!result) return false; + + nlassert(s_State != STATE_IDLE); s_TaskManager->addTask(task); return true; } +} /* anonymous namespace */ + +bool tryRunnableTask(std::string stateName, IRunnable *task) +{ + // copy paste from above. + + bool result = false; + s_StateMutex.enter(); + result = (s_State == STATE_IDLE); + if (result) + { + s_State = STATE_RUNNABLE_TASK; + s_StateRunnableTaskName = stateName; + } + s_StateMutex.leave(); + if (!result) return false; + + nlassert(s_State != STATE_IDLE); + + s_TaskManager->addTask(task); + + return true; +} + +void endedRunnableTask() +{ + nlassert(s_State != STATE_IDLE); + + s_StateMutex.enter(); + s_State = STATE_IDLE; + s_StateMutex.leave(); +} + // ****************************************************************** +namespace { + void initSheets() { std::string leveldesignDfnDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDfnDirectory").asString(); @@ -186,9 +225,7 @@ class CReloadSheets : public IRunnable releaseSheets(); initSheets(); - s_StateMutex.enter(); - s_State = STATE_IDLE; - s_StateMutex.leave(); + endedRunnableTask(); } }; CReloadSheets s_ReloadSheets; @@ -207,9 +244,7 @@ class CUpdateDatabaseStatus : public IRunnable void databaseStatusUpdated() { - s_StateMutex.enter(); - s_State = STATE_IDLE; - s_StateMutex.leave(); + endedRunnableTask(); } virtual void run() @@ -349,6 +384,9 @@ NLMISC_DYNVARIABLE(std::string, pipelineServiceState, "State of the pipeline ser case PIPELINE::STATE_DATABASE_STATUS: *pointer = "DATABASE_STATUS"; break; + case PIPELINE::STATE_RUNNABLE_TASK: + *pointer = PIPELINE::s_StateRunnableTaskName; + break; } } } diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_service.h b/code/nel/tools/pipeline/pipeline_service/pipeline_service.h index 01e9e9f8a..20b336dad 100644 --- a/code/nel/tools/pipeline/pipeline_service/pipeline_service.h +++ b/code/nel/tools/pipeline/pipeline_service/pipeline_service.h @@ -36,6 +36,10 @@ // Project includes +namespace NLMISC { + class IRunnable; +} + namespace PIPELINE { #if defined(PIPELINE_MASTER) @@ -59,6 +63,9 @@ std::string unMacroPath(const std::string &path); /// Macros a path, and standardizes it in advance. std::string macroPath(const std::string &path); +bool tryRunnableTask(std::string stateName, NLMISC::IRunnable *task); +void endedRunnableTask(); + extern bool g_IsExiting; } /* namespace PIPELINE */