Geant4  10.01.p03
G4GenericMessenger.cc
Go to the documentation of this file.
1 // ********************************************************************
2 // * License and Disclaimer *
3 // * *
4 // * The Geant4 software is copyright of the Copyright Holders of *
5 // * the Geant4 Collaboration. It is provided under the terms and *
6 // * conditions of the Geant4 Software License, included in the file *
7 // * LICENSE and available at http://cern.ch/geant4/license . These *
8 // * include a list of copyright holders. *
9 // * *
10 // * Neither the authors of this software system, nor their employing *
11 // * institutes,nor the agencies providing financial support for this *
12 // * work make any representation or warranty, express or implied, *
13 // * regarding this software system or assume any liability for its *
14 // * use. Please see the license in the file LICENSE and URL above *
15 // * for the full disclaimer and the limitation of liability. *
16 // * *
17 // * This code implementation is the result of the scientific and *
18 // * technical work of the GEANT4 collaboration. *
19 // * By using, copying, modifying or distributing the software (or *
20 // * any work based on the software) you agree to acknowledge its *
21 // * use in resulting scientific publications, and indicate your *
22 // * acceptance of all terms of the Geant4 Software license. *
23 // ********************************************************************
24 //
25 //
26 // $Id: G4UIaliasList.cc,v 1.6 2006-06-29 19:08:33 gunter Exp $
27 //
28 
29 #include "G4GenericMessenger.hh"
30 #include "G4Types.hh"
31 #include "G4UImessenger.hh"
32 #include "G4UIcommand.hh"
35 #include "G4UIdirectory.hh"
36 
37 #include <iostream>
38 
39 class G4InvalidUICommand: public std::bad_cast {
40 public:
42  virtual const char* what() const throw() {
43  return "G4InvalidUICommand: command does not exists or is of invalid type";
44  }
45 };
46 
47 
48 G4GenericMessenger::G4GenericMessenger(void* obj, const G4String& dir, const G4String& doc): directory(dir), object(obj) {
49  // Check if parent commnand is already existing.
50  // In fact there is no way to check this. UImanager->GetTree()->FindPath() will always rerurn NULL is a dicrectory is given
51  size_t pos = dir.find_last_of('/', dir.size()-2);
52  while(pos != 0 && pos != std::string::npos) {
53  G4UIdirectory* d = new G4UIdirectory(dir.substr(0,pos+1).c_str());
54  G4String guidance = "Commands for ";
55  guidance += dir.substr(1,pos-1);
56  d->SetGuidance(guidance);
57  pos = dir.find_last_of('/', pos-1);
58  }
59  dircmd = new G4UIdirectory(dir);
60  dircmd->SetGuidance(doc);
61 }
62 
64  delete dircmd;
65  for (std::map<G4String, Property>::iterator i = properties.begin(); i != properties.end(); i++) delete i->second.command;
66  for (std::map<G4String, Method>::iterator i = methods.begin(); i != methods.end(); i++) delete i->second.command;
67 }
68 
69 
72  G4String fullpath = directory+name;
73  G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
74  if(doc != "") cmd->SetGuidance(doc);
75  char ptype;
76  if(var.TypeInfo() == typeid(int) || var.TypeInfo() == typeid(long) ||
77  var.TypeInfo() == typeid(unsigned int) || var.TypeInfo() == typeid(unsigned long)) ptype = 'i';
78  else if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double)) ptype = 'd';
79  else if(var.TypeInfo() == typeid(bool)) ptype = 'b';
80  else if(var.TypeInfo() == typeid(G4String)) ptype = 's';
81  else ptype = 's';
82  cmd->SetParameter(new G4UIparameter("value", ptype, false));
83  return properties[name] = Property(var, cmd);
84 }
85 
86 
88 (const G4String& name, const G4String& defaultUnit, const G4AnyType& var, const G4String& doc) {
89  if(var.TypeInfo()!=typeid(float) && var.TypeInfo()!=typeid(double) && var.TypeInfo()!= typeid(G4ThreeVector))
90  { return DeclareProperty(name,var,doc); }
91  G4String fullpath = directory+name;
92  G4UIcommand* cmd;
93  if(var.TypeInfo()==typeid(float) || var.TypeInfo()==typeid(double))
94  {
95  cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
96  (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetParameterName("value",false,false);
97  (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
98  }
99  else
100  {
101  cmd = new G4UIcmdWith3VectorAndUnit(fullpath.c_str(), this);
102  (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetParameterName("valueX","valueY","valueZ",false,false);
103  (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
104  }
105 
106  if(doc != "") cmd->SetGuidance(doc);
107  return properties[name] = Property(var, cmd);
108 }
109 
110 
112 G4GenericMessenger::DeclareMethod(const G4String& name, const G4AnyMethod& fun, const G4String& doc) {
113  G4String fullpath = directory+name;
114  G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
115  if(doc != "") cmd->SetGuidance(doc);
116  for (size_t i = 0; i < fun.NArg(); i++) {
117  cmd->SetParameter(new G4UIparameter("arg", 's', false));
118  }
119  return methods[name] = Method(fun, object, cmd);
120 }
121 
123  (const G4String& name, const G4String& defaultUnit, const G4AnyMethod& fun, const G4String& doc) {
124  G4String fullpath = directory+name;
125  if(fun.NArg()!=1) {
127  ed<<"G4GenericMessenger::DeclareMethodWithUnit() does not support a method that has more than\n"
128  <<"one arguments (or no argument). Please use G4GenericMessenger::DeclareMethod method for\n"
129  <<"your command <"<<fullpath<<">.";
130  G4Exception("G4GenericMessenger::DeclareMethodWithUnit()","Intercom70002",FatalException,ed);
131  }
132  G4UIcommand* cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
133  (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetParameterName("value",false,false);
134  (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
135  if(doc != "") cmd->SetGuidance(doc);
136  return methods[name] = Method(fun, object, cmd);
137 }
138 
139 
141  if ( properties.find(command->GetCommandName()) != properties.end()) {
142  Property& p = properties[command->GetCommandName()];
143  return p.variable.ToString();
144  }
145  else if ( methods.find(command->GetCommandName()) != methods.end()) {
146  G4cout<<" GetCurrentValue() is not available for a command defined by G4GenericMessenger::DeclareMethod()."<<G4endl;
147  return G4String();
148  }
149  else {
150  throw G4InvalidUICommand();
151  }
152 }
153 
155  // Check if there are units on this commands
156  if (typeid(*command) == typeid(G4UIcmdWithADoubleAndUnit)) {
158  }
159  else if (typeid(*command) == typeid(G4UIcmdWith3VectorAndUnit)) {
161  }
162 
163  if ( properties.find(command->GetCommandName()) != properties.end()) {
164  Property& p = properties[command->GetCommandName()];
165  p.variable.FromString(newValue);
166  }
167  else if (methods.find(command->GetCommandName()) != methods.end()) {
168  Method& m = methods[command->GetCommandName()];
169  if(m.method.NArg() == 0)
170  m.method.operator()(m.object);
171  else if (m.method.NArg() > 0) {
172  m.method.operator()(m.object,newValue);
173  }
174  else {
175  throw G4InvalidUICommand();
176  }
177  }
178 }
179 
180 
182  dircmd->SetGuidance(s);
183 }
184 
185 
187  // Change the type of command (unfortunatelly this is done a posteriory)
188  // We need to delete the old command before creating the new one and therefore we need to recover the information
189  // before the deletetion
190 #ifdef G4MULTITHREADED
191  G4String cmdpath = command->GetCommandPath();
193  ed<<"G4GenericMessenger::Command::SetUnit() is thread-unsafe and should not be used\n"
194  <<"in multi-threaded mode. For your command <"<<cmdpath<<">, use\n"
195  <<" DeclarePropertyWithUnit(const G4String& name, const G4String& defaultUnit,\n"
196  <<" const G4AnyType& variable, const G4String& doc)\n"
197  <<"or\n"
198  <<" DeclareMethodWithUnit(const G4String& name, const G4String& defaultUnit,\n"
199  <<" const G4AnyType& variable, const G4String& doc)\n"
200  <<"to define a command with a unit <"<<unit<<">.";
201  if(spec!=UnitDefault) { ed<<"\nPlease use a default unit instead of unit category."; }
202  G4Exception("G4GenericMessenger::Command::SetUnit()","Intercom70001",FatalException,ed);
203  return *this;
204 #else
205  G4String cmdpath = command->GetCommandPath();
206  G4UImessenger* messenger = command->GetMessenger();
207  G4String range = command->GetRange();
208  std::vector<G4String> guidance;
209  G4String par_name = command->GetParameter(0)->GetParameterName();
210  bool par_omitable = command->GetParameter(0)->IsOmittable();
211  for (G4int i = 0; i < command->GetGuidanceEntries(); i++) guidance.push_back(command->GetGuidanceLine(i));
212  // Before deleting the command we need to add a fake one to avoid deleting the directory entry and with its guidance
213  G4UIcommand tmp((cmdpath+"_tmp").c_str(), messenger);
214  delete command;
215 
216  if (*type == typeid(float) || *type == typeid(double) ) {
217  G4UIcmdWithADoubleAndUnit* cmd_t = new G4UIcmdWithADoubleAndUnit(cmdpath, messenger);
218  if(spec == UnitDefault) cmd_t->SetDefaultUnit(unit);
219  else if(spec == UnitCategory) cmd_t->SetUnitCategory(unit);
220  cmd_t->SetParameterName(par_name, par_omitable);
221  command = cmd_t;
222  }
223  else if (*type == typeid(G4ThreeVector)) {
224  G4UIcmdWith3VectorAndUnit* cmd_t = new G4UIcmdWith3VectorAndUnit(cmdpath, messenger);
225  if(spec == UnitDefault) cmd_t->SetDefaultUnit(unit);
226  else if(spec == UnitCategory) cmd_t->SetUnitCategory(unit);
227  command = cmd_t;
228  }
229  else {
230  G4cerr << "Only parameters of type <double> or <float> can be associated with units" << G4endl;
231  return *this;
232  }
233  for (size_t i = 0; i < guidance.size(); i++) command->SetGuidance(guidance[i]);
234  command->SetRange(range);
235  return *this;
236 #endif
237 }
238 
240  G4UIparameter* theParam = command->GetParameter(0);
241  theParam->SetParameterName(name);
242  theParam->SetOmittable(omittable);
243  theParam->SetCurrentAsDefault(currentAsDefault);
244  return *this;
245 }
246 
248  G4UIparameter * theParam = command->GetParameter(0);
249  theParam->SetParameterCandidates(candList);
250  return *this;
251 }
252 
254  G4UIparameter * theParam = command->GetParameter(0);
255  theParam->SetDefaultValue(defVal);
256  return *this;
257 }
258 
259 
260 
void SetParameter(G4UIparameter *const newParameter)
Definition: G4UIcommand.hh:152
virtual G4String GetCurrentValue(G4UIcommand *command)
The concrete, but generic implementation of this method.
const G4String & GetRange() const
Definition: G4UIcommand.hh:133
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
CLHEP::Hep3Vector G4ThreeVector
void SetOmittable(G4bool om)
void SetParameterCandidates(const char *theString)
const std::type_info * type
std::map< G4String, Method > methods
Command & DeclareProperty(const G4String &name, const G4AnyType &variable, const G4String &doc="")
Declare Methods.
G4String name
Definition: TRTMaterials.hh:40
This class represents any object method.
Definition: G4AnyMethod.hh:67
G4String GetParameterName() const
void SetDefaultUnit(const char *defUnit)
void SetUnitCategory(const char *unitCategory)
G4UIdirectory * dircmd
Command & DeclareMethod(const G4String &name, const G4AnyMethod &fun, const G4String &doc="")
void SetDefaultValue(const char *theDefaultValue)
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:371
virtual const char * what() const
Command & DeclareMethodWithUnit(const G4String &name, const G4String &defaultUnit, const G4AnyMethod &fun, const G4String &doc="")
void SetUnitCategory(const char *unitCategory)
void SetParameterName(const char *theName)
const std::type_info & TypeInfo() const
Query.
Definition: G4AnyType.hh:106
int G4int
Definition: G4Types.hh:78
void SetParameterName(const char *theNameX, const char *theNameY, const char *theNameZ, G4bool omittable, G4bool currentAsDefault=false)
const G4String & GetGuidanceLine(G4int i) const
Definition: G4UIcommand.hh:137
static G4double ConvertToDimensionedDouble(const char *st)
Definition: G4UIcommand.cc:451
void SetCurrentAsDefault(G4bool val)
virtual void SetNewValue(G4UIcommand *command, G4String newValue)
The concrete, generic implementation of this method converts the string "newValue" to action...
G4bool IsOmittable() const
static const double s
Definition: G4SIunits.hh:150
Command & SetDefaultValue(const G4String &)
void FromString(const std::string &val)
String conversion.
Definition: G4AnyType.hh:118
std::string ToString() const
String conversion.
Definition: G4AnyType.hh:114
G4GLOB_DLL std::ostream G4cout
size_t NArg() const
Number of arguments.
Definition: G4AnyMethod.hh:126
G4GenericMessenger(void *obj, const G4String &dir="", const G4String &doc="")
Contructor.
bool G4bool
Definition: G4Types.hh:79
void SetRange(const char *rs)
Definition: G4UIcommand.hh:125
virtual ~G4GenericMessenger()
Destructor.
void SetGuidance(const char *aGuidance)
Definition: G4UIcommand.hh:161
G4UIparameter * GetParameter(G4int i) const
Definition: G4UIcommand.hh:145
std::map< G4String, Property > properties
const G4String & GetCommandPath() const
Definition: G4UIcommand.hh:139
void SetGuidance(const G4String &s)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
const G4String & GetCommandName() const
Definition: G4UIcommand.hh:141
This class represents any data type.
Definition: G4AnyType.hh:63
Command & SetCandidates(const G4String &)
void SetDefaultUnit(const char *defUnit)
G4UImessenger * GetMessenger() const
Definition: G4UIcommand.hh:149
Command & SetParameterName(const G4String &, G4bool, G4bool=false)
#define G4endl
Definition: G4ios.hh:61
static const double m
Definition: G4SIunits.hh:110
G4int GetGuidanceEntries() const
Definition: G4UIcommand.hh:135
Command & DeclarePropertyWithUnit(const G4String &name, const G4String &defaultUnit, const G4AnyType &variable, const G4String &doc="")
void SetParameterName(const char *theName, G4bool omittable, G4bool currentAsDefault=false)
static const G4double pos
G4GLOB_DLL std::ostream G4cerr
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
Definition: G4UIcommand.cc:473
Command & SetUnit(const G4String &, UnitSpec=UnitDefault)