Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// G4GenericMessenger
26//
27// Author: P.Mato, CERN - 27 September 2012
28// --------------------------------------------------------------------
29
30#include "G4GenericMessenger.hh"
31#include "G4Types.hh"
32#include "G4UImessenger.hh"
33#include "G4UIcommand.hh"
36#include "G4UIdirectory.hh"
37#include "G4Threading.hh"
38
39#include <iostream>
40
41class G4InvalidUICommand : public std::bad_cast
42{
43 public:
44
46 virtual const char* what() const throw()
47 {
48 return "G4InvalidUICommand: command does not exist or is of invalid type";
49 }
50};
51
53 const G4String& doc)
54 : directory(dir)
55 , object(obj)
56{
57 // Check if parent commnand is already existing.
58 // In fact there is no way to check this. UImanager->GetTree()->FindPath()
59 // will always rerurn NULL is a dicrectory is given
60 std::size_t pos = dir.find_last_of('/', dir.size() - 2);
61 while(pos != 0 && pos != std::string::npos)
62 {
63 G4UIdirectory* d = new G4UIdirectory(dir.substr(0, pos + 1).c_str());
64 G4String guidance = "Commands for ";
65 guidance += dir.substr(1, pos - 1);
66 d->SetGuidance(guidance);
67 pos = dir.find_last_of('/', pos - 1);
68 }
69 dircmd = new G4UIdirectory(dir);
70 dircmd->SetGuidance(doc);
71}
72
74{
75 delete dircmd;
76 for(auto i = properties.cbegin(); i != properties.cend(); ++i)
77 delete i->second.command;
78 for(auto i = methods.cbegin(); i != methods.cend(); ++i)
79 delete i->second.command;
80}
81
83 const G4String& name, const G4AnyType& var, const G4String& doc)
84{
85 G4String fullpath = directory + name;
86 G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
87 if(doc != "")
88 cmd->SetGuidance(doc);
89 char ptype;
90 if(var.TypeInfo() == typeid(int) || var.TypeInfo() == typeid(long) ||
91 var.TypeInfo() == typeid(unsigned int) ||
92 var.TypeInfo() == typeid(unsigned long))
93 ptype = 'i';
94 else if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double))
95 ptype = 'd';
96 else if(var.TypeInfo() == typeid(bool))
97 ptype = 'b';
98 else if(var.TypeInfo() == typeid(G4String))
99 ptype = 's';
100 else
101 ptype = 's';
102 cmd->SetParameter(new G4UIparameter("value", ptype, false));
103 return properties[name] = Property(var, cmd);
104}
105
107 const G4String& name, const G4String& defaultUnit, const G4AnyType& var,
108 const G4String& doc)
109{
110 if(var.TypeInfo() != typeid(float) && var.TypeInfo() != typeid(double) &&
111 var.TypeInfo() != typeid(G4ThreeVector))
112 {
113 return DeclareProperty(name, var, doc);
114 }
115 G4String fullpath = directory + name;
116 G4UIcommand* cmd;
117 if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double))
118 {
119 cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
120 (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))
121 ->SetParameterName("value", false, false);
122 (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
123 }
124 else
125 {
126 cmd = new G4UIcmdWith3VectorAndUnit(fullpath.c_str(), this);
127 (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))
128 ->SetParameterName("valueX", "valueY", "valueZ", false, false);
129 (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
130 }
131
132 if(doc != "")
133 cmd->SetGuidance(doc);
134 return properties[name] = Property(var, cmd);
135}
136
138 const G4String& name, const G4AnyMethod& fun, const G4String& doc)
139{
140 G4String fullpath = directory + name;
141 G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
142 if(doc != "")
143 cmd->SetGuidance(doc);
144 for(std::size_t i = 0; i < fun.NArg(); ++i)
145 {
146 cmd->SetParameter(new G4UIparameter("arg", 's', false));
147 }
148 return methods[name] = Method(fun, object, cmd);
149}
150
152 const G4String& name, const G4String& defaultUnit, const G4AnyMethod& fun,
153 const G4String& doc)
154{
155 G4String fullpath = directory + name;
156 if(fun.NArg() != 1)
157 {
159 ed << "G4GenericMessenger::DeclareMethodWithUnit() does not support a "
160 "method that has more than\n"
161 << "one arguments (or no argument). Please use "
162 "G4GenericMessenger::DeclareMethod method for\n"
163 << "your command <" << fullpath << ">.";
164 G4Exception("G4GenericMessenger::DeclareMethodWithUnit()", "Intercom70002",
165 FatalException, ed);
166 }
167 G4UIcommand* cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
168 (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))
169 ->SetParameterName("value", false, false);
170 (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
171 if(doc != "")
172 cmd->SetGuidance(doc);
173 return methods[name] = Method(fun, object, cmd);
174}
175
177{
178 if(properties.find(command->GetCommandName()) != properties.cend())
179 {
180 Property& p = properties[command->GetCommandName()];
181 return p.variable.ToString();
182 }
183 else if(methods.find(command->GetCommandName()) != methods.cend())
184 {
185 G4cout << " GetCurrentValue() is not available for a command defined by "
186 "G4GenericMessenger::DeclareMethod()."
187 << G4endl;
188 return G4String();
189 }
190 else
191 {
192 throw G4InvalidUICommand();
193 }
194}
195
197{
198 // Check if there are units on this commands
199 if(typeid(*command) == typeid(G4UIcmdWithADoubleAndUnit))
200 {
203 }
204 else if(typeid(*command) == typeid(G4UIcmdWith3VectorAndUnit))
205 {
208 }
209
210 if(properties.find(command->GetCommandName()) != properties.cend())
211 {
212 Property& p = properties[command->GetCommandName()];
213 p.variable.FromString(newValue);
214 }
215 else if(methods.find(command->GetCommandName()) != methods.cend())
216 {
217 Method& m = methods[command->GetCommandName()];
218 if(m.method.NArg() == 0)
219 m.method.operator()(m.object);
220 else if(m.method.NArg() > 0)
221 {
222 m.method.operator()(m.object, newValue);
223 }
224 else
225 {
226 throw G4InvalidUICommand();
227 }
228 }
229}
230
232{
233 dircmd->SetGuidance(s);
234}
235
237 const G4String& unit, UnitSpec spec)
238{
239 // Change the type of command (unfortunatelly this is done a posteriory)
240 // We need to delete the old command before creating the new one and therefore
241 // we need to recover the information before the deletetion
243 {
244 G4String cmdpath = command->GetCommandPath();
246 ed << "G4GenericMessenger::Command::SetUnit() is thread-unsafe and should "
247 "not be used\n"
248 << "in multi-threaded mode. For your command <" << cmdpath << ">, use\n"
249 << " DeclarePropertyWithUnit(const G4String& name, const G4String& "
250 "defaultUnit,\n"
251 << " const G4AnyType& variable, const G4String& "
252 "doc)\n"
253 << "or\n"
254 << " DeclareMethodWithUnit(const G4String& name, const G4String& "
255 "defaultUnit,\n"
256 << " const G4AnyType& variable, const G4String& "
257 "doc)\n"
258 << "to define a command with a unit <" << unit << ">.";
259 if(spec != UnitDefault)
260 {
261 ed << "\nPlease use a default unit instead of unit category.";
262 }
263 G4Exception("G4GenericMessenger::Command::SetUnit()", "Intercom70001",
264 FatalException, ed);
265 return *this;
266 }
267
268 G4String cmdpath = command->GetCommandPath();
269 G4UImessenger* messenger = command->GetMessenger();
270 G4String range = command->GetRange();
271 std::vector<G4String> guidance;
273 G4bool par_omitable = command->GetParameter(0)->IsOmittable();
274 for(std::size_t i = 0; i < command->GetGuidanceEntries(); ++i)
275 guidance.push_back(command->GetGuidanceLine(i));
276 // Before deleting the command we need to add a fake one to avoid deleting
277 // the directory entry and with its guidance
278 G4UIcommand tmp((cmdpath + "_tmp").c_str(), messenger);
279 delete command;
280
281 if(*type == typeid(float) || *type == typeid(double))
282 {
284 new G4UIcmdWithADoubleAndUnit(cmdpath, messenger);
285 if(spec == UnitDefault)
286 cmd_t->SetDefaultUnit(unit);
287 else if(spec == UnitCategory)
288 cmd_t->SetUnitCategory(unit);
289 cmd_t->SetParameterName(par_name, par_omitable);
290 command = cmd_t;
291 }
292 else if(*type == typeid(G4ThreeVector))
293 {
295 new G4UIcmdWith3VectorAndUnit(cmdpath, messenger);
296 if(spec == UnitDefault)
297 cmd_t->SetDefaultUnit(unit);
298 else if(spec == UnitCategory)
299 cmd_t->SetUnitCategory(unit);
300 command = cmd_t;
301 }
302 else
303 {
304 G4cerr << "Only parameters of type <double> or <float> can be associated "
305 "with units"
306 << G4endl;
307 return *this;
308 }
309 for(std::size_t i = 0; i < guidance.size(); ++i)
310 command->SetGuidance(guidance[i]);
311 command->SetRange(range);
312 return *this;
313}
314
316 const G4String& name, G4bool omittable, G4bool currentAsDefault)
317{
318 G4UIparameter* theParam = command->GetParameter(0);
319 theParam->SetParameterName(name);
320 theParam->SetOmittable(omittable);
321 theParam->SetCurrentAsDefault(currentAsDefault);
322 return *this;
323}
324
326 const G4String& candList)
327{
328 G4UIparameter* theParam = command->GetParameter(0);
329 theParam->SetParameterCandidates(candList);
330 return *this;
331}
332
334 const G4String& defVal)
335{
336 G4UIparameter* theParam = command->GetParameter(0);
337 theParam->SetDefaultValue(defVal);
338 return *this;
339}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
bool G4bool
Definition: G4Types.hh:86
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
std::size_t NArg() const
Definition: G4AnyMethod.hh:158
void FromString(const std::string &val)
Definition: G4AnyType.hh:129
const std::type_info & TypeInfo() const
Definition: G4AnyType.hh:116
std::string ToString() const
Definition: G4AnyType.hh:127
Command & DeclareMethod(const G4String &name, const G4AnyMethod &fun, const G4String &doc="")
void SetGuidance(const G4String &s)
virtual void SetNewValue(G4UIcommand *command, G4String newValue)
Command & DeclareProperty(const G4String &name, const G4AnyType &variable, const G4String &doc="")
virtual G4String GetCurrentValue(G4UIcommand *command)
Command & DeclareMethodWithUnit(const G4String &name, const G4String &defaultUnit, const G4AnyMethod &fun, const G4String &doc="")
G4GenericMessenger(void *obj, const G4String &dir="", const G4String &doc="")
Command & DeclarePropertyWithUnit(const G4String &name, const G4String &defaultUnit, const G4AnyType &variable, const G4String &doc="")
virtual const char * what() const
void SetDefaultUnit(const char *defUnit)
void SetUnitCategory(const char *unitCategory)
void SetUnitCategory(const char *unitCategory)
void SetDefaultUnit(const char *defUnit)
void SetParameterName(const char *theName, G4bool omittable, G4bool currentAsDefault=false)
G4UImessenger * GetMessenger() const
Definition: G4UIcommand.hh:144
const G4String & GetGuidanceLine(G4int i) const
Definition: G4UIcommand.hh:132
G4UIparameter * GetParameter(G4int i) const
Definition: G4UIcommand.hh:139
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:430
const G4String & GetCommandPath() const
Definition: G4UIcommand.hh:136
void SetParameter(G4UIparameter *const newParameter)
Definition: G4UIcommand.hh:146
void SetGuidance(const char *aGuidance)
Definition: G4UIcommand.hh:156
std::size_t GetGuidanceEntries() const
Definition: G4UIcommand.hh:128
void SetRange(const char *rs)
Definition: G4UIcommand.hh:120
static G4double ConvertToDimensionedDouble(const char *st)
Definition: G4UIcommand.cc:570
const G4String & GetCommandName() const
Definition: G4UIcommand.hh:137
const G4String & GetRange() const
Definition: G4UIcommand.hh:127
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
Definition: G4UIcommand.cc:594
void SetDefaultValue(const char *theDefaultValue)
void SetParameterName(const char *pName)
G4bool IsOmittable() const
void SetOmittable(G4bool om)
void SetParameterCandidates(const char *theString)
void SetCurrentAsDefault(G4bool val)
const G4String & GetParameterName() const
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:130
Command & SetParameterName(const G4String &, G4bool, G4bool=false)
Command & SetCandidates(const G4String &)
Command & SetDefaultValue(const G4String &)
const std::type_info * type
Command & SetUnit(const G4String &, UnitSpec=UnitDefault)