Files
geant4/source/interfaces/XVT/src/G4UIxvt.cc
T
2016-06-08 16:39:52 +02:00

820 lines
25 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4UIxvt.cc,v 1.4 2001/07/11 10:01:19 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
#ifdef G4UI_BUILD_XVT_SESSION
////////////////////////////////////////////////////////////////////////////
// XVT driver class implementation
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Written by: Simon Prior
// Date: 23/04/97
//
// Updated for state machine: 12/08/97
//
// The update consisted of adding the new state methods and I also deleted
// a lot of old redundant code (like ChangeDirectory etc which aren't
// needed with the XVT GUI).
//
////////////////////////////////////////////////////////////////////////////
#include "G4UIxvt.hh"
#include "G4StateManager.hh"
#include "G4UIxvtMessenger.hh"
////////////////////////////////////////////////////////////////////////////
//
// G4UIxvt - Consructor
//
// Initalise the class variables.
//
// Note: number is the number of bytes transfered with each read or write.
//
////////////////////////////////////////////////////////////////////////////
G4UIxvt::G4UIxvt()
{
UI = G4UImanager::GetUIpointer();
iExit = false;
iCont = false;
for(int i=0;i<4;i++)
{
brktbl[i] = false;
}
noBreakFlag = true;
verboseFlag = true;
new G4UIxvtMessenger(this);
number = 100;
currentPosition = 0;
lastPosition = 100;
}
////////////////////////////////////////////////////////////////////////////
//
// ~G4UIxvt - Destructor
//
////////////////////////////////////////////////////////////////////////////
G4UIxvt::~G4UIxvt()
{
}
////////////////////////////////////////////////////////////////////////////
//
// Notify
//
// Notifies the user of the state changes of the system.
//
////////////////////////////////////////////////////////////////////////////
//G4bool G4UIxvt::Notify(G4ApplicationState requestedState)
//{
// G4StateManager * statM = G4StateManager::GetStateManager();
// G4ApplicationState previousState = statM->GetPreviousState();
//
// if(verboseFlag)
// {
// writeGeantToXvt("========== STATE CHANGE ===========");
// writeGeantToXvt("FROM: " + statM->GetStateString(previousState));
// writeGeantToXvt(" TO: " + statM->GetStateString(requestedState));
// writeGeantToXvt("===================================");
// }
//
// if(requestedState==Pause || breakRequested(previousState,requestedState))
// {
// additionalSession();
// }
//
// return true;
//}
////////////////////////////////////////////////////////////////////////////
//
// breakRequested
//
// Notifies and puts breaks in the Geant4 run.
//
////////////////////////////////////////////////////////////////////////////
G4bool G4UIxvt::breakRequested(G4ApplicationState previousState,
G4ApplicationState requestedState)
{
if(noBreakFlag) return false;
G4bool ans = false;
if(previousState==Idle && requestedState==GeomClosed && brktbl[0])
{
writeGeantToXvt("====== BREAKPOINT NOTIFICATION ======");
writeGeantToXvt("BreakPoint at: BEGIN OF RUN");
writeGeantToXvt("Enter 'continue' command to proceed");
writeGeantToXvt("=====================================");
ans = true;
}
if(previousState==GeomClosed && requestedState==EventProc && brktbl[1])
{
writeGeantToXvt("====== BREAKPOINT NOTIFICATION ======");
writeGeantToXvt("BreakPoint at: BEGIN OF EVENT");
writeGeantToXvt("Enter 'continue' command to proceed");
writeGeantToXvt("=====================================");
ans = true;
}
if(previousState==EventProc && requestedState==GeomClosed && brktbl[2])
{
writeGeantToXvt("====== BREAKPOINT NOTIFICATION ======");
writeGeantToXvt("BreakPoint at: END OF EVENT");
writeGeantToXvt("Enter 'continue' command to proceed");
writeGeantToXvt("=====================================");
ans = true;
}
if(previousState==GeomClosed && requestedState==Idle && brktbl[3])
{
writeGeantToXvt("====== BREAKPOINT NOTIFICATION ======");
writeGeantToXvt("BreakPoint at: END OF RUN");
writeGeantToXvt("Enter 'continue' command to proceed");
writeGeantToXvt("=====================================");
ans = true;
}
return ans;
}
////////////////////////////////////////////////////////////////////////////
//
// set_verbose
//
// Toggles the Verbose state of the GUI concerning the state machine.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::set_verbose(void)
{
verboseFlag = !verboseFlag;
if (verboseFlag)
{
writeGeantToXvt("Verbose mode switched ON");
}
else
{
writeGeantToXvt("Verbose mode switched OFF");
}
}
////////////////////////////////////////////////////////////////////////////
//
// SessionStart
//
// Informs user of Geant Kernel starting and does a 'brief' command listing.
// Update: 12/08/97 - now used as main control of Geant (get command is
// currently called from here NOT from the UIManager.
//
////////////////////////////////////////////////////////////////////////////
//void G4UIxvt::SessionStart(void)
G4UIsession* G4UIxvt::SessionStart(void)
{
openConnections();
writeGeantToXvt("Connection to Geant open...\0");
G4UImanager * UI = G4UImanager::GetUIpointer();
G4UIcommandTree * comTree = UI->GetTree();
fillArrayEntries(comTree, 0);
G4cout << " --------- List of Array Entries ---------- " << G4endl;
listCommandArray();
briefListCommands();
// --- Enter main program control --- //
iExit = true;
while( iExit )
{
G4String newCommand = GetCommand();
if(newCommand.length()>1) UI->ApplyCommand(newCommand);
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////
//
// additionalSession
//
//
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::additionalSession(void)
{
writeGeantToXvt("=== Entering Addtional Session ===");
iCont = true;
while( iCont )
{
G4String newCommand = GetCommand();
if(newCommand.length()>1) UI->ApplyCommand(newCommand);
}
}
////////////////////////////////////////////////////////////////////////////
//
// SessionTerminate
//
// Informs user that Geant has terminated.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::SessionTerminate(void)
{
writeGeantToXvt("XVT <-> Geant4 terminating...");
}
////////////////////////////////////////////////////////////////////////////
//
// openConnections
//
// This method opens the IPC connection.
//
// Open the named pipes in the current directory using the
// appropriate permissions.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::openConnections(void)
{
int o_flags;
o_flags = O_WRONLY | O_NONBLOCK;
if((fd_GeantToXvt = open(GeantToXvt, o_flags)) == -1)
{
errorHandler("GeantToXvt pipe opening");
}
o_flags = O_RDONLY | O_NONBLOCK;
if((fd_XvtToGeant = open(XvtToGeant, o_flags)) == -1)
{
errorHandler("XvtToGeant pipe opening");
}
}
////////////////////////////////////////////////////////////////////////////
//
// checkXvtToGeantPipe
//
// This method checks to see if the XvtToGeant pipe contains anything.
// Thus meaning it will be readable without blocking.
//
// Returns 0 if nothing present, 1 otherwise.
//
////////////////////////////////////////////////////////////////////////////
int G4UIxvt::checkXvtToGeantPipe(void)
{
int nbytes;
ioctl(fd_XvtToGeant, FIONREAD, &nbytes);
if (nbytes > 0)
return 1;
else
return 0;
}
////////////////////////////////////////////////////////////////////////////
//
// readXvtToGeant
//
// This method grabs the data in the XvtToGeant named pipe, and
// returns it to the caller.
//
////////////////////////////////////////////////////////////////////////////
G4String G4UIxvt::readXvtToGeant(void)
{
int bytes_read = read(fd_XvtToGeant, textDump, number);
textDump[bytes_read] = '\0';
G4String newString = textDump;
return newString;
}
////////////////////////////////////////////////////////////////////////////
//
// writeGeantToXvt
//
// This method writes the passed string to the GeantToXvt named pipe.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::writeGeantToXvt(const G4String& theString)
{
int write_check = write(fd_GeantToXvt, theString, number);
if(write_check == -1)
G4cout << "ERROR WITH WRITE!!" << G4endl;
}
///////////////////////////////////////////////////////////////////////////////
//
// errorHandler
//
// A general purpose error handler. It can be called by any method. A string
// is passed so that this method simply prints a message via G4cout that explains
// what the error is.
//
///////////////////////////////////////////////////////////////////////////////
void G4UIxvt::errorHandler(const G4String& theError)
{
G4cout << "Error with " << theError << G4endl;
}
////////////////////////////////////////////////////////////////////////////
//
// GetCommand
//
// This method is called by SessionStart to get a command from the user.
//
// It enters a loop to repeatedly check the Geant end of the named pipe.
// When something is present in the pipe (sent by XVT GUI) it then grabs it
// and returns the string to the caller.
//
////////////////////////////////////////////////////////////////////////////
G4String G4UIxvt::GetCommand()
{
G4String newCommand('\0');
G4UImanager * UI = G4UImanager::GetUIpointer();
while( 1 )
{
int Done = 0;
while (!Done)
{
if (checkXvtToGeantPipe())
{
newCommand = readXvtToGeant();
Done = 1;
}
else
; // Pipe is empty so loop again
}
G4String nC = newCommand;
if(nC == "getCommands")
{
sendArrayEntriesToXvt();
}
else if( nC == "/control/exit" )
{
if( iCont )
{
writeGeantToXvt("You are now processing RUN.");
writeGeantToXvt("Please abort it using \"/run/abort\" command first");
writeGeantToXvt("and use \"continue\" command until the application");
writeGeantToXvt("becomes Idle.");
}
else
{
iExit = false;
newCommand = "/";
break;
}
}
else if( nC(0,4) == "cont" )
{
iCont = false;
newCommand = "/";
break;
}
else
{
break;
}
}
if( newCommand(0) != '/' )
G4cerr << "IT GOT THERE!!!!" << G4endl;
// If you ever see the error message in the output something has gone
// wrong.
return newCommand;
}
////////////////////////////////////////////////////////////////////////////
//
// codeGen
//
// Traverses the command tree and retrieves the directories and
// subdirectories of available commands.
//
// This does a 'brief' listing, i.e. does not List the guidance or
// parameters.
//
// I have updated this method from the TCL implementation for XVT.
// The differences are that G4cout is not used and some string concatenation
// is Done differently (i.e. not with G4cout).
//
// This is still however not really needed and might be deleted.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::codeGen(G4UIcommandTree * tree, int level)
{
int treeEntry;
int commandEntry;
treeEntry = tree->GetTreeEntry();
commandEntry = tree->GetCommandEntry();
G4String commandPath;
G4String pathName; //tree name
G4UIcommandTree * t;
// --- this loop lists the current directory and its commands --- //
for(int com=0; com<commandEntry; com++)
{
commandPath = tree->GetCommand(com+1)->GetCommandPath();
if(level==0)
{
// This is not normally executed
writeGeantToXvt(commandPath); // Unsure as to what this does
}
else
{
writeGeantToXvt(commandPath + " command"); // this gives the commands
}
}
if(treeEntry == 0)
return; //end recursion
for(int i=0; i< treeEntry; i++)
{
t = tree->GetTree(i+1);
pathName = t->GetPathName();
if(level == 0)
{
writeGeantToXvt(pathName); // This is the directory name
}
else
{
writeGeantToXvt(pathName + " cascade"); // This is the sub dirs
}
codeGen(t, level+1);
}
}
////////////////////////////////////////////////////////////////////////////
//
// briefListCommands
//
// This method uses codeGen to traverse the tree and List the commands
// and directories - it does a brief listing, i.e. no parameters or guidance
// accompanying the text.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::briefListCommands(void)
{
writeGeantToXvt("--- Brief List of available commands ---");
G4UIcommandTree * comTree = UI->GetTree();
codeGen(comTree, 0);
}
////////////////////////////////////////////////////////////////////////////
//
// ListCurrentDirectory
//
// This is the XVT specific implementation of the 'List Current' method
// from the G4UICommandTree class.
//
// It is almost the same only instead of any couts all the data is written
// to the named pipe for XVT to process.
//
// Although this is entirely XVT specific it may be deleted because it is
// not really needed. (most directory navigation methods that were so
// important in the terminal session aren't needed in this XVT GUI
// implementation.)
//
// I have left it here in case similar code is needed in the future - this
// demonstrates how to access the command tree etc.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::listCurrentDirectory(void)
{
G4UIcommandTree * comTree = UI->GetTree();
G4String path = comTree->GetPathName();
writeGeantToXvt("Command Directory Path: " + path);
// --- Guidance code --- //
G4UIcommand * tempGuidance = (G4UIcommand *)comTree->GetGuidance();
if (tempGuidance != NULL)
{
writeGeantToXvt("Command: " + tempGuidance->GetCommandPath());
writeGeantToXvt("Guidance: ");
int n_guidanceEntry = tempGuidance->GetGuidanceEntries();
for (int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ )
{
writeGeantToXvt(tempGuidance->GetGuidanceLine(i_thGuidance));
}
int n_parameterEntry = tempGuidance->GetParameterEntries();
if(n_parameterEntry > 0)
{
for( int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
{
G4UIparameter * tempParameter = (G4UIparameter *)tempGuidance->GetParameter(i_thParameter);
writeGeantToXvt("Parameter: " + tempParameter->GetParameterName());
writeGeantToXvt(tempParameter->GetParameterGuidance());
writeGeantToXvt("Parameter type: " + tempParameter->GetParameterType());
// --- remember to fix the below bug --- //
// writeGeantToXvt("Omittable: " + tempParameter->IsOmittable());
writeGeantToXvt("Default Value: " + tempParameter->GetDefaultValue());
writeGeantToXvt("Parameter Range: " + tempParameter->GetParameterRange());
}
}
}
// --- End of Guidance code --- //
writeGeantToXvt("Sub Directories: ");
int n_treeEntry = comTree->GetTreeEntry();
for( int i_thTree = 0; i_thTree < n_treeEntry; i_thTree++ )
{
G4UIcommandTree * tempTree = comTree->GetTree(i_thTree + 1);
writeGeantToXvt(tempTree->GetPathName() + tempTree->GetTitle());
}
writeGeantToXvt("Commands : ");
int n_commandEntry = comTree->GetCommandEntry();
for( int i_thCommand = 0; i_thCommand < n_commandEntry; i_thCommand++ )
{
G4UIcommand * tempCommand = comTree->GetCommand(i_thCommand + 1);
writeGeantToXvt(tempCommand->GetCommandName() + tempCommand->GetTitle());
}
}
////////////////////////////////////////////////////////////////////////////
// Methods for handling the command information //
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
// sendArrayEntriesToXvt
//
// This goes through the commandArray when called and sends all the command
// information down the named pipe to XVT.
//
// It must first send the control command 'comTree' to alert XVT of the
// following commands - XVT can then take action to fill its own 'commandArray'
// with the ensuing strings passed to it.
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::sendArrayEntriesToXvt(void)
{
writeGeantToXvt("comTree");
char theInt[5];
sprintf(theInt, "%d", currentPosition);
writeGeantToXvt(theInt);
// --- Output all the Data from the array to the named pipe --- //
for (int i = 0; i < currentPosition; i++)
{
// --- Send flag to XVT --- //
sprintf(theInt, "%d",commandArray[i].flag);
writeGeantToXvt(theInt);
// --- Send name and guidance --- //
writeGeantToXvt(commandArray[i].name);
writeGeantToXvt(commandArray[i].guidance);
// --- Send number of parameters --- //
sprintf(theInt, "%d", commandArray[i].numOfParameters);
writeGeantToXvt(theInt);
// --- if there are parameters send them next --- //
if (commandArray[i].numOfParameters > 0)
{
for(int x = 0; x < commandArray[i].numOfParameters; x++)
{
writeGeantToXvt(commandArray[i].parameters[x].name);
writeGeantToXvt(commandArray[i].parameters[x].guidance);
writeGeantToXvt(commandArray[i].parameters[x].defaultValue);
writeGeantToXvt(commandArray[i].parameters[x].range);
writeGeantToXvt(commandArray[i].parameters[x].candidate);
writeGeantToXvt(commandArray[i].parameters[x].type);
writeGeantToXvt(commandArray[i].parameters[x].omittable);
}
}
// --- Send number --- //
sprintf(theInt, "%d", commandArray[i].commandNumber);
writeGeantToXvt(theInt);
}
}
////////////////////////////////////////////////////////////////////////////
//
// fillArrayEntries
//
// This traverses the command tree and fills in the command structures in
// the class variable 'commandArray'.
//
// Note: for flag value:
//
// 0 = Directory
// 1 = command
// 2 = subdirectory
//
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::fillArrayEntries(G4UIcommandTree * tree, int level)
{
int treeEntry;
int commandEntry;
treeEntry = tree->GetTreeEntry();
commandEntry = tree->GetCommandEntry();
G4String commandPath;
G4String pathName; //tree name
G4UIcommandTree * t;
// New variables
G4UIcommand * tempCommand;
G4UIparameter * tempParameter;
// --- this loop lists the current directory and its commands --- //
for(int com=0; com<commandEntry; com++)
{
tempCommand = (G4UIcommand *)tree->GetCommand(com+1);
commandPath = tree->GetCommand(com+1)->GetCommandPath();
if(level==0)
{
// --- This code shouldn't ever get executed --- //
G4cout << "Printing command Path" << commandPath << G4endl;
}
else
{
commandArray[currentPosition].flag = 1;
commandArray[currentPosition].name = commandPath;
commandArray[currentPosition].guidance = tempCommand->GetTitle();
commandArray[currentPosition].numOfParameters = tempCommand->GetParameterEntries();
int numParam = tempCommand->GetParameterEntries();
if(numParam != 0)
{
for(int x = 0; x < numParam; x++)
{
tempParameter = (G4UIparameter*)tempCommand->GetParameter(x);
commandArray[currentPosition].parameters[x].name = tempParameter->GetParameterName();
commandArray[currentPosition].parameters[x].guidance = tempParameter->GetParameterGuidance();
commandArray[currentPosition].parameters[x].defaultValue = tempParameter->GetDefaultValue();
commandArray[currentPosition].parameters[x].range = tempParameter->GetParameterRange();
commandArray[currentPosition].parameters[x].candidate = tempParameter->GetParameterCandidate();
commandArray[currentPosition].parameters[x].type = tempParameter->GetParameterType();
// commandArray[currentPosition].parameters[x].omittable = tempParameter->IsOmittable();
}
}
commandArray[currentPosition].commandNumber = currentPosition;
currentPosition = currentPosition + 1;
}
}
if(treeEntry == 0)
return; //end recursion
G4UIcommand * treeGuidance;
for(int i=0; i< treeEntry; i++)
{
t = tree->GetTree(i+1);
pathName = t->GetPathName();
treeGuidance = (G4UIcommand *)t->GetGuidance();
if(level == 0)
{
commandArray[currentPosition].flag = 0;
commandArray[currentPosition].name = pathName;
commandArray[currentPosition].guidance = treeGuidance->GetTitle();
commandArray[currentPosition].numOfParameters = 0;
commandArray[currentPosition].commandNumber = currentPosition;
currentPosition = currentPosition + 1;
}
else
{
commandArray[currentPosition].flag = 2;
commandArray[currentPosition].name = pathName;
commandArray[currentPosition].guidance = treeGuidance->GetTitle();
commandArray[currentPosition].numOfParameters = 0;
commandArray[currentPosition].commandNumber = currentPosition;
currentPosition = currentPosition + 1;
}
fillArrayEntries(t, level+1);
}
}
////////////////////////////////////////////////////////////////////////////
// A debugging routine //
// //
// This method is purely used for debugging purposes - will be deleted //
// from the final code (when we are sure it is bug free) //
// //
////////////////////////////////////////////////////////////////////////////
void G4UIxvt::listCommandArray(void)
{
for(int i = 0; i < currentPosition; i++)
{
G4cout << "CommandArray, Entry-> " << i << G4endl
<< "Flag-> " << commandArray[i].flag << G4endl
<< "Name-> " << commandArray[i].name << G4endl
<< "Guidance-> " << commandArray[i].guidance << G4endl
<< "Number of Parameters-> " << commandArray[i].numOfParameters << G4endl;
int numParam = commandArray[i].numOfParameters;
if (numParam != 0)
{
for(int x = 0; x < numParam; x++)
{
G4cout << "Parameters for this command: " << G4endl << G4endl
<< "Parameter Name-> " << commandArray[i].parameters[x].name << G4endl
<< "Parameter Guidance-> " << commandArray[i].parameters[x].guidance << G4endl
<< "Parameter Default Value-> " << commandArray[i].parameters[x].defaultValue << G4endl
<< "Parameter Range-> " << commandArray[i].parameters[x].range << G4endl
<< "Parameter Candidate-> " << commandArray[i].parameters[x].candidate << G4endl
<< "Parameter Type-> " << commandArray[i].parameters[x].type << G4endl
<< "Parameter Omittable-> " << commandArray[i].parameters[x].omittable << G4endl
<< G4endl << G4endl;
}
}
G4cout << "Number-> " << commandArray[i].commandNumber << G4endl << G4endl;
}
}
#endif