8 #include "PlusConfigure.h" 9 #include "vtkIGSIORecursiveCriticalSection.h" 16 #ifdef PLUS_USE_STEALTHLINK 19 #ifdef PLUS_USE_CLARIUS 22 #ifdef PLUS_USE_OPTIMET_CONOPROBE 25 #ifdef PLUS_USE_ATRACSYS 28 #ifdef PLUS_USE_CAPISTRANO_VIDEO 31 #ifdef PLUS_USE_WINPROBE_VIDEO 34 #ifdef PLUS_USE_USDIGITALENCODERS_TRACKER 37 #ifdef PLUS_USE_MMF_VIDEO 57 #include "igtl_header.h" 60 #include <vtkImageData.h> 61 #include <vtkMatrix4x4.h> 62 #include <vtkObjectFactory.h> 63 #include <vtkXMLUtilities.h> 70 , Threader(vtkSmartPointer<vtkMultiThreader>::New())
71 , Mutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
72 , CommandExecutionActive(std::make_pair(false, false))
73 , CommandExecutionThreadId(-1)
91 #ifdef PLUS_USE_CAPISTRANO_VIDEO 94 #ifdef PLUS_USE_STEALTHLINK 97 #ifdef PLUS_USE_CLARIUS 100 #ifdef PLUS_USE_OPTIMET_CONOPROBE 103 #ifdef PLUS_USE_ATRACSYS 106 #ifdef PLUS_USE_WINPROBE_VIDEO 109 #ifdef PLUS_USE_USDIGITALENCODERS_TRACKER 112 #ifdef PLUS_USE_MMF_VIDEO 122 for (
auto& kv : this->RegisteredCommands)
124 kv.second->UnRegister(
this);
131 this->Superclass::PrintSelf(os, indent);
132 os << indent <<
"Registered commands: ";
133 for (
auto iter = this->RegisteredCommands.begin();
iter != this->RegisteredCommands.end(); ++
iter)
135 os << indent <<
" " <<
iter->first << std::endl;
142 if (this->CommandExecutionThreadId < 0)
144 this->CommandExecutionActive.first =
true;
145 this->CommandExecutionThreadId = this->Threader->SpawnThread((vtkThreadFunctionType)&
CommandExecutionThread,
this);
154 if (this->CommandExecutionThreadId >= 0)
156 this->CommandExecutionActive.first =
false;
157 while (this->CommandExecutionActive.second)
160 vtkIGSIOAccurateTimer::Delay(0.2);
162 this->CommandExecutionThreadId = -1;
165 LOG_DEBUG(
"Command execution thread stopped");
175 self->CommandExecutionActive.second =
true;
178 while (self->CommandExecutionActive.first)
180 self->ExecuteCommands();
182 const double commandQueuePollIntervalSec = 0.010;
184 Sleep(commandQueuePollIntervalSec * 1000);
186 usleep(commandQueuePollIntervalSec * 1000000);
191 self->CommandExecutionThreadId = -1;
192 self->CommandExecutionActive.second =
false;
200 int numberOfExecutedCommands(0);
203 vtkSmartPointer<vtkPlusCommand> cmd;
205 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
206 if (this->CommandQueue.empty())
208 return numberOfExecutedCommands;
210 cmd = this->CommandQueue.front();
211 this->CommandQueue.pop_front();
214 LOG_DEBUG(
"Executing command");
217 LOG_ERROR(
"Command execution failed");
222 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
223 cmd->PopCommandResponses(this->CommandResponseQueue);
226 numberOfExecutedCommands++;
230 return numberOfExecutedCommands;
238 LOG_ERROR(
"vtkPlusCommandProcessor::RegisterPlusCommand received an invalid command object");
242 std::list<std::string> cmdNames;
244 if (cmdNames.empty())
246 LOG_ERROR(
"Cannot register command: command name is empty");
250 for (std::list<std::string>::iterator nameIt = cmdNames.begin(); nameIt != cmdNames.end(); ++nameIt)
252 this->RegisteredCommands[*nameIt] = cmd;
261 vtkSmartPointer<vtkXMLDataElement> cmdElement = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromString(commandStr.c_str()));
262 if (cmdElement.GetPointer() == NULL)
264 LOG_ERROR(
"failed to parse XML command string (received: " + commandStr +
")");
268 if (STRCASECMP(cmdElement->GetName(),
"Command") != 0)
270 LOG_ERROR(
"Command element expected (received: " + commandStr +
")");
274 if (this->RegisteredCommands.find(commandName) == this->RegisteredCommands.end())
277 LOG_ERROR(
"Unknown command: " << commandName);
281 vtkPlusCommand* cmd = (this->RegisteredCommands[commandName])->Clone();
287 LOG_ERROR(
"Failed to initialize command from string: " + commandStr);
296 if (commandString.empty())
298 LOG_ERROR(
"Command string is undefined");
302 if (commandName.empty())
304 LOG_ERROR(
"Command name is undefined");
308 vtkSmartPointer<vtkPlusCommand> cmd = vtkSmartPointer<vtkPlusCommand>::Take(
CreatePlusCommand(commandName, commandString, metaData));
309 if (cmd.GetPointer() == NULL)
311 if (!respondUsingIGTLCommand)
317 this->
QueueCommandResponse(
PLUS_FAIL, deviceName, clientId, commandName, uid,
"Error attempting to process command.",
"Unknown command type requested.");
322 cmd->SetCommandProcessor(
this);
323 cmd->SetClientId(clientId);
326 cmd->SetRespondWithCommandMessage(respondUsingIGTLCommand);
329 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
330 this->CommandQueue.push_back(cmd);
338 vtkSmartPointer<vtkPlusCommandStringResponse> response = vtkSmartPointer<vtkPlusCommandStringResponse>::New();
340 std::ostringstream replyStr;
341 replyStr <<
"<CommandReply";
342 replyStr <<
" Status=\"" << (status ==
PLUS_SUCCESS ?
"SUCCESS" :
"FAIL") <<
"\"";
343 replyStr <<
" Message=\"";
345 vtkXMLUtilities::EncodeString(replyString.c_str(), VTK_ENCODING_NONE, replyStr, VTK_ENCODING_NONE, 1 );
349 response->SetMessage(replyStr.str());
350 response->SetClientId(clientId);
351 response->SetStatus(status);
354 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
355 this->CommandResponseQueue.push_back(response);
363 vtkSmartPointer<vtkPlusCommandRTSCommandResponse> response = vtkSmartPointer<vtkPlusCommandRTSCommandResponse>::New();
364 response->SetClientId(clientId);
366 response->SetOriginalId(uid);
367 response->SetRespondWithCommandMessage(
true);
369 response->SetStatus(status);
372 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
373 this->CommandResponseQueue.push_back(response);
381 vtkSmartPointer<vtkPlusGetImageCommand> cmdGetImage = vtkSmartPointer<vtkPlusGetImageCommand>::New();
382 cmdGetImage->SetCommandProcessor(
this);
383 cmdGetImage->SetClientId(clientId);
384 cmdGetImage->SetDeviceName(
deviceName.c_str());
385 cmdGetImage->SetNameToGetImageMeta();
389 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
390 this->CommandQueue.push_back(cmdGetImage);
398 vtkSmartPointer<vtkPlusGetImageCommand> cmdGetImage = vtkSmartPointer<vtkPlusGetImageCommand>::New();
399 cmdGetImage->SetCommandProcessor(
this);
400 cmdGetImage->SetClientId(clientId);
401 cmdGetImage->SetDeviceName(
deviceName.c_str());
402 cmdGetImage->SetNameToGetImage();
406 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
407 this->CommandQueue.push_back(cmdGetImage);
415 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
419 responses.splice(responses.end(), this->CommandResponseQueue, this->CommandResponseQueue.begin(), this->CommandResponseQueue.end());
425 return this->CommandExecutionActive.second;
vtkPlusCommand * CreatePlusCommand(const std::string &commandName, const std::string &commandStr, const igtl::MessageBase::MetaDataMap &metaData)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
This is an abstract superclass for commands in the OpenIGTLink network interface for Plus.
const char ** errorString
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
PlusStatus QueueGetImage(unsigned int clientId, const std::string &deviceName)
Creates a PlusCommand from a string. If the commands are to be executed on the main thread then call ...
static void * CommandExecutionThread(vtkMultiThreader::ThreadInfo *data)
virtual PlusStatus QueueStringResponse(PlusStatus status, const std::string &deviceName, unsigned int clientId, const std::string &replyString)
vtkStandardNewMacro(vtkPlusCommandProcessor)
void SetMetaData(const igtl::MessageBase::MetaDataMap &metaData)
virtual void GetCommandNames(std::list< std::string > &cmdNames)=0
virtual PlusStatus RegisterPlusCommand(vtkPlusCommand *cmd)
virtual PlusStatus QueueCommandResponse(PlusStatus status, const std::string &deviceName, unsigned int clientId, const std::string &commandName, uint32_t uid, const std::string &replyString, const std::string &errorString)
PlusStatus QueueGetImageMetaData(unsigned int clientId, const std::string &deviceName)
virtual PlusStatus Start()
vtkPlusCommandProcessor()
virtual void SetPlusServer(vtkPlusOpenIGTLinkServer *)
std::list< vtkSmartPointer< vtkPlusCommandResponse > > PlusCommandResponseList
virtual PlusStatus QueueCommand(bool respondUsingIGTLCommand, unsigned int clientId, const std::string &commandName, const std::string &commandString, const std::string &deviceName, uint32_t uid, const igtl::MessageBase::MetaDataMap &metaData)
virtual void PopCommandResponses(PlusCommandResponseList &responses)
virtual ~vtkPlusCommandProcessor()
virtual PlusStatus Stop()