ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4GenericMessenger.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4GenericMessenger.cc
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 //
27 
28 #include "G4GenericMessenger.hh"
29 #include "G4Types.hh"
30 #include "G4UImessenger.hh"
31 #include "G4UIcommand.hh"
34 #include "G4UIdirectory.hh"
35 #include "G4Threading.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 
186  // Change the type of command (unfortunatelly this is done a posteriory)
187  // We need to delete the old command before creating the new one and therefore we need to recover the information
188  // before the deletetion
190  G4String cmdpath = command->GetCommandPath();
192  ed<<"G4GenericMessenger::Command::SetUnit() is thread-unsafe and should not be used\n"
193  <<"in multi-threaded mode. For your command <"<<cmdpath<<">, use\n"
194  <<" DeclarePropertyWithUnit(const G4String& name, const G4String& defaultUnit,\n"
195  <<" const G4AnyType& variable, const G4String& doc)\n"
196  <<"or\n"
197  <<" DeclareMethodWithUnit(const G4String& name, const G4String& defaultUnit,\n"
198  <<" const G4AnyType& variable, const G4String& doc)\n"
199  <<"to define a command with a unit <"<<unit<<">.";
200  if(spec!=UnitDefault) { ed<<"\nPlease use a default unit instead of unit category."; }
201  G4Exception("G4GenericMessenger::Command::SetUnit()","Intercom70001",FatalException,ed);
202  return *this;
203  }
204 
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  G4bool par_omitable = command->GetParameter(0)->IsOmittable();
211  for (size_t 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 }
237 
239  G4UIparameter* theParam = command->GetParameter(0);
240  theParam->SetParameterName(name);
241  theParam->SetOmittable(omittable);
242  theParam->SetCurrentAsDefault(currentAsDefault);
243  return *this;
244 }
245 
247  G4UIparameter * theParam = command->GetParameter(0);
248  theParam->SetParameterCandidates(candList);
249  return *this;
250 }
251 
253  G4UIparameter * theParam = command->GetParameter(0);
254  theParam->SetDefaultValue(defVal);
255  return *this;
256 }
257 
258 
259