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 54 #include "igtl_header.h" 57 #include <vtkImageData.h> 58 #include <vtkMatrix4x4.h> 59 #include <vtkObjectFactory.h> 60 #include <vtkXMLUtilities.h> 67 , Threader(vtkSmartPointer<vtkMultiThreader>::New())
68 , Mutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
69 , CommandExecutionActive(std::make_pair(false, false))
70 , CommandExecutionThreadId(-1)
88 #ifdef PLUS_USE_CAPISTRANO_VIDEO 91 #ifdef PLUS_USE_STEALTHLINK 94 #ifdef PLUS_USE_CLARIUS 97 #ifdef PLUS_USE_OPTIMET_CONOPROBE 100 #ifdef PLUS_USE_ATRACSYS 103 #ifdef PLUS_USE_WINPROBE_VIDEO 106 #ifdef PLUS_USE_USDIGITALENCODERS_TRACKER 116 for (
auto& kv : this->RegisteredCommands)
118 kv.second->UnRegister(
this);
125 this->Superclass::PrintSelf(os, indent);
126 os << indent <<
"Registered commands: ";
127 for (
auto iter = this->RegisteredCommands.begin();
iter != this->RegisteredCommands.end(); ++
iter)
129 os << indent <<
" " <<
iter->first << std::endl;
136 if (this->CommandExecutionThreadId < 0)
138 this->CommandExecutionActive.first =
true;
139 this->CommandExecutionThreadId = this->Threader->SpawnThread((vtkThreadFunctionType)&
CommandExecutionThread,
this);
148 if (this->CommandExecutionThreadId >= 0)
150 this->CommandExecutionActive.first =
false;
151 while (this->CommandExecutionActive.second)
154 vtkIGSIOAccurateTimer::Delay(0.2);
156 this->CommandExecutionThreadId = -1;
159 LOG_DEBUG(
"Command execution thread stopped");
169 self->CommandExecutionActive.second =
true;
172 while (self->CommandExecutionActive.first)
174 self->ExecuteCommands();
176 const double commandQueuePollIntervalSec = 0.010;
178 Sleep(commandQueuePollIntervalSec * 1000);
180 usleep(commandQueuePollIntervalSec * 1000000);
185 self->CommandExecutionThreadId = -1;
186 self->CommandExecutionActive.second =
false;
194 int numberOfExecutedCommands(0);
197 vtkSmartPointer<vtkPlusCommand> cmd;
199 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
200 if (this->CommandQueue.empty())
202 return numberOfExecutedCommands;
204 cmd = this->CommandQueue.front();
205 this->CommandQueue.pop_front();
208 LOG_DEBUG(
"Executing command");
211 LOG_ERROR(
"Command execution failed");
216 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
217 cmd->PopCommandResponses(this->CommandResponseQueue);
220 numberOfExecutedCommands++;
224 return numberOfExecutedCommands;
232 LOG_ERROR(
"vtkPlusCommandProcessor::RegisterPlusCommand received an invalid command object");
236 std::list<std::string> cmdNames;
238 if (cmdNames.empty())
240 LOG_ERROR(
"Cannot register command: command name is empty");
244 for (std::list<std::string>::iterator nameIt = cmdNames.begin(); nameIt != cmdNames.end(); ++nameIt)
246 this->RegisteredCommands[*nameIt] = cmd;
255 vtkSmartPointer<vtkXMLDataElement> cmdElement = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromString(commandStr.c_str()));
256 if (cmdElement.GetPointer() == NULL)
258 LOG_ERROR(
"failed to parse XML command string (received: " + commandStr +
")");
262 if (STRCASECMP(cmdElement->GetName(),
"Command") != 0)
264 LOG_ERROR(
"Command element expected (received: " + commandStr +
")");
268 if (this->RegisteredCommands.find(commandName) == this->RegisteredCommands.end())
271 LOG_ERROR(
"Unknown command: " << commandName);
275 vtkPlusCommand* cmd = (this->RegisteredCommands[commandName])->Clone();
281 LOG_ERROR(
"Failed to initialize command from string: " + commandStr);
290 if (commandString.empty())
292 LOG_ERROR(
"Command string is undefined");
296 if (commandName.empty())
298 LOG_ERROR(
"Command name is undefined");
302 vtkSmartPointer<vtkPlusCommand> cmd = vtkSmartPointer<vtkPlusCommand>::Take(
CreatePlusCommand(commandName, commandString, metaData));
303 if (cmd.GetPointer() == NULL)
305 if (!respondUsingIGTLCommand)
311 this->
QueueCommandResponse(
PLUS_FAIL, deviceName, clientId, commandName, uid,
"Error attempting to process command.",
"Unknown command type requested.");
316 cmd->SetCommandProcessor(
this);
317 cmd->SetClientId(clientId);
320 cmd->SetRespondWithCommandMessage(respondUsingIGTLCommand);
323 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
324 this->CommandQueue.push_back(cmd);
332 vtkSmartPointer<vtkPlusCommandStringResponse> response = vtkSmartPointer<vtkPlusCommandStringResponse>::New();
334 std::ostringstream replyStr;
335 replyStr <<
"<CommandReply";
336 replyStr <<
" Status=\"" << (status ==
PLUS_SUCCESS ?
"SUCCESS" :
"FAIL") <<
"\"";
337 replyStr <<
" Message=\"";
339 vtkXMLUtilities::EncodeString(replyString.c_str(), VTK_ENCODING_NONE, replyStr, VTK_ENCODING_NONE, 1 );
343 response->SetMessage(replyStr.str());
344 response->SetClientId(clientId);
345 response->SetStatus(status);
348 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
349 this->CommandResponseQueue.push_back(response);
357 vtkSmartPointer<vtkPlusCommandRTSCommandResponse> response = vtkSmartPointer<vtkPlusCommandRTSCommandResponse>::New();
358 response->SetClientId(clientId);
360 response->SetOriginalId(uid);
361 response->SetRespondWithCommandMessage(
true);
363 response->SetStatus(status);
366 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
367 this->CommandResponseQueue.push_back(response);
375 vtkSmartPointer<vtkPlusGetImageCommand> cmdGetImage = vtkSmartPointer<vtkPlusGetImageCommand>::New();
376 cmdGetImage->SetCommandProcessor(
this);
377 cmdGetImage->SetClientId(clientId);
378 cmdGetImage->SetDeviceName(
deviceName.c_str());
379 cmdGetImage->SetNameToGetImageMeta();
383 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
384 this->CommandQueue.push_back(cmdGetImage);
392 vtkSmartPointer<vtkPlusGetImageCommand> cmdGetImage = vtkSmartPointer<vtkPlusGetImageCommand>::New();
393 cmdGetImage->SetCommandProcessor(
this);
394 cmdGetImage->SetClientId(clientId);
395 cmdGetImage->SetDeviceName(
deviceName.c_str());
396 cmdGetImage->SetNameToGetImage();
400 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
401 this->CommandQueue.push_back(cmdGetImage);
409 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
413 responses.splice(responses.end(), this->CommandResponseQueue, this->CommandResponseQueue.begin(), this->CommandResponseQueue.end());
419 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()