25#include <simgear/compiler.h>
26#include <simgear/structure/exception.hxx>
27#include <simgear/props/props_io.hxx>
28#include <simgear/misc/strutils.hxx>
29#include <simgear/timing/sg_time.hxx>
30#include <simgear/misc/sg_path.hxx>
31#include <simgear/scene/model/particles.hxx>
32#include <simgear/sound/soundmgr.hxx>
57 loggingResult = sglog().getLogClassesAsString();
58 return loggingResult.c_str();
67 sglog().parseLogClasses(c);
76 switch (sglog().get_log_priority()) {
89 SG_LOG(SG_GENERAL, SG_WARN,
"Internal: Unknown logging priority number: "
90 << sglog().get_log_priority());
106 if (priority.empty()) {
107 sglog().set_log_priority(SG_INFO);
110 sglog().set_log_priority(logstream::priorityFromString(priority));
111 }
catch (std::exception& e) {
112 SG_LOG(SG_GENERAL, SG_WARN,
"Unknown logging priority: " << priority);
123bool FGProperties::getFreeze()
const
132void FGProperties::setFreeze(
bool f)
140 auto p = simgear::ParticlesGlobalManager::instance();
143 _simFreezeNode->fireValueChanged();
153 return globals->get_sim_time_sec();
165 SGTime * st =
globals->get_time_params();
171 struct tm * t = st->getGmt();
172 snprintf(buf, 64,
"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
173 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
174 t->tm_hour, t->tm_min, t->tm_sec);
185 SGTime * st =
globals->get_time_params();
186 struct tm * current_time = st->getGmt();
191 new_time.tm_isdst = 0;
192 int ret = sscanf(date_string,
"%d-%d-%dT%d:%d:%d",
193 &(new_time.tm_year), &(new_time.tm_mon),
194 &(new_time.tm_mday), &(new_time.tm_hour),
195 &(new_time.tm_min), &(new_time.tm_sec));
202 SG_LOG(SG_INPUT, SG_WARN,
"Date/time string " << date_string
203 <<
" not in YYYY-MM-DDTHH:MM:SS format; skipped");
208 new_time.tm_year -= 1900;
209 new_time.tm_mon -= 1;
214 mktime(&new_time) - mktime(current_time) +
globals->get_warp();
226 SGTime * st =
globals->get_time_params();
232 struct tm *t = st->getGmt();
233 snprintf(buf, 16,
"%.2d:%.2d:%.2d",
234 t->tm_hour, t->tm_min, t->tm_sec);
241SGConstPropertyNode_ptr FGProperties::_longDeg;
242SGConstPropertyNode_ptr FGProperties::_latDeg;
243SGConstPropertyNode_ptr FGProperties::_lonLatformat;
247const char* FGProperties::getLongitudeString ()
249 const double d = _longDeg->getDoubleValue();
250 auto format =
static_cast<strutils::LatLonFormat
>(_lonLatformat->getIntValue());
251 const char c = d < 0.0 ?
'W' :
'E';
253 static char longitudeBuffer[64];
254 const auto s = strutils::formatLatLonValueAsString(d, format, c);
255 memcpy(longitudeBuffer, s.c_str(), s.size() + 1);
256 return longitudeBuffer;
259const char* FGProperties::getLatitudeString ()
261 const double d = _latDeg->getDoubleValue();
262 auto format =
static_cast<strutils::LatLonFormat
>(_lonLatformat->getIntValue());
263 const char c = d < 0.0 ?
'S' :
'N';
265 static char latitudeBuffer[64];
266 const auto s = strutils::formatLatLonValueAsString(d, format, c);
267 memcpy(latitudeBuffer, s.c_str(), s.size() + 1);
268 return latitudeBuffer;
283 memset(&_lastUtc, 0,
sizeof(
struct tm));
284 memset(&_lastRealTime, 0,
sizeof(
struct tm));
291 if (r->getType() == simgear::props::NONE) {
292 r->setDoubleValue(v);
300 _longDeg =
fgGetNode(
"/position/longitude-deg",
true);
301 _latDeg =
fgGetNode(
"/position/latitude-deg",
true);
302 _lonLatformat =
fgGetNode(
"/sim/lon-lat-format",
true);
304 _offset =
fgGetNode(
"/sim/time/local-offset",
true);
307 _uyear =
fgGetNode(
"/sim/time/utc/year",
true);
308 _umonth =
fgGetNode(
"/sim/time/utc/month",
true);
309 _uday =
fgGetNode(
"/sim/time/utc/day",
true);
310 _uhour =
fgGetNode(
"/sim/time/utc/hour",
true);
311 _umin =
fgGetNode(
"/sim/time/utc/minute",
true);
312 _usec =
fgGetNode(
"/sim/time/utc/second",
true);
313 _uwday =
fgGetNode(
"/sim/time/utc/weekday",
true);
314 _udsec =
fgGetNode(
"/sim/time/utc/day-seconds",
true);
317 _ryear =
fgGetNode(
"/sim/time/real/year",
true);
318 _rmonth =
fgGetNode(
"/sim/time/real/month",
true);
319 _rday =
fgGetNode(
"/sim/time/real/day",
true);
320 _rhour =
fgGetNode(
"/sim/time/real/hour",
true);
321 _rmin =
fgGetNode(
"/sim/time/real/minute",
true);
322 _rsec =
fgGetNode(
"/sim/time/real/second",
true);
323 _rwday =
fgGetNode(
"/sim/time/real/weekday",
true);
325 _tiedProperties.setRoot(
globals->get_props());
330 _simFreezeNode =
fgGetNode(
"/sim/freeze/master",
true);
331 _tiedProperties.Tie(_simFreezeNode,
this, &FGProperties::getFreeze, &FGProperties::setFreeze);
332 _simFreezeNode->setAttribute(SGPropertyNode::LISTENER_SAFE,
true);
336 _timeGmtNode->setAttribute(SGPropertyNode::LISTENER_SAFE,
true);
338 _timeGmtStringNode = _tiedProperties.Tie<
const char*>(
"/sim/time/gmt-string",
getGMTString);
339 _timeGmtStringNode->setAttribute(SGPropertyNode::LISTENER_SAFE,
true);
341 _tiedProperties.Tie<
const char*>(
"/position/latitude-string", getLatitudeString);
342 _tiedProperties.Tie<
const char*>(
"/position/longitude-string", getLongitudeString);
344 _headingMagnetic =
initDoubleNode(
"/orientation/heading-magnetic-deg", 0.0);
345 _trackMagnetic =
initDoubleNode(
"/orientation/track-magnetic-deg", 0.0);
346 _magVar =
initDoubleNode(
"/environment/magnetic-variation-deg", 0.0);
354 _tiedProperties.Untie();
361 _timeGmtNode.clear();
362 _timeGmtStringNode.clear();
363 _simFreezeNode.clear();
369 _offset->setIntValue(
globals->get_time_params()->get_local_offset());
372 struct tm *u =
globals->get_time_params()->getGmt();
373 if (memcmp(u, &_lastUtc,
sizeof(
struct tm)) != 0) {
375 _uyear->setIntValue(u->tm_year + 1900);
376 _umonth->setIntValue(u->tm_mon + 1);
377 _uday->setIntValue(u->tm_mday);
378 _uhour->setIntValue(u->tm_hour);
379 _umin->setIntValue(u->tm_min);
380 _usec->setIntValue(u->tm_sec);
381 _uwday->setIntValue(u->tm_wday);
382 _udsec->setIntValue(u->tm_hour * 3600 + u->tm_min * 60 + u->tm_sec);
384 _timeGmtNode->fireValueChanged();
385 _timeGmtStringNode->fireValueChanged();
390 time_t real = time(0);
391 struct tm *r = localtime(&real);
392 if (memcmp(r, &_lastRealTime,
sizeof(
struct tm)) != 0) {
394 _ryear->setIntValue(r->tm_year + 1900);
395 _rmonth->setIntValue(r->tm_mon + 1);
396 _rday->setIntValue(r->tm_mday);
397 _rhour->setIntValue(r->tm_hour);
398 _rmin->setIntValue(r->tm_min);
399 _rsec->setIntValue(r->tm_sec);
400 _rwday->setIntValue(r->tm_wday);
403 const double magvar = _magVar->getDoubleValue();
404 const auto hdgMag = SGMiscd::normalizePeriodic(0, 360.0, _trueHeading->getDoubleValue() - magvar);
405 _headingMagnetic->setDoubleValue(hdgMag);
407 const auto trackMag = SGMiscd::normalizePeriodic(0, 360.0, _trueTrack->getDoubleValue() - magvar);
408 _trackMagnetic->setDoubleValue(trackMag);
427 fgSetBool(
"/sim/presets/onground",
false);
435 writeProperties(output,
globals->get_props(), write_all);
436 }
catch (
const sg_exception &e) {
450 SGPropertyNode props;
452 readProperties(input, &props);
453 }
catch (
const sg_exception &e) {
458 fgSetBool(
"/sim/presets/onground",
false);
462 copyProperties(&props,
globals->get_props());
469fgLoadProps (
const std::string& path, SGPropertyNode * props,
bool in_fg_root,
int default_mode)
473 SGPath loadpath(
globals->get_fg_root());
474 loadpath.append(path);
477 fullpath = SGPath::fromUtf8(path);
481 readProperties(fullpath, props, default_mode);
482 }
catch (
const sg_exception &e) {
497 return globals->get_props()->getNode(path, create);
503 return globals->get_props()->getNode(path, index, create);
515 fgGetNode(path,
true)->addChangeListener(listener);
520 const char * path,
int index)
522 fgGetNode(path, index,
true)->addChangeListener(listener);
528 return globals->get_props()->getBoolValue(
name, defaultValue);
534 return globals->get_props()->getIntValue(
name, defaultValue);
540 return globals->get_props()->getLongValue(
name, defaultValue);
546 return globals->get_props()->getFloatValue(
name, defaultValue);
552 return globals->get_props()->getDoubleValue(
name, defaultValue);
558 return globals->get_props()->getStringValue(
name, defaultValue);
564 return globals->get_props()->setBoolValue(
name, val);
570 return globals->get_props()->setIntValue(
name, val);
576 return globals->get_props()->setLongValue(
name, val);
582 return globals->get_props()->setFloatValue(
name, val);
588 return globals->get_props()->setDoubleValue(
name, val);
594 return globals->get_props()->setStringValue(
name, val);
600 SGPropertyNode * node =
globals->get_props()->getNode(
name);
602 SG_LOG(SG_GENERAL, SG_DEBUG,
603 "Attempt to set archive flag for non-existant property "
606 node->setAttribute(SGPropertyNode::ARCHIVE, state);
612 SGPropertyNode * node =
globals->get_props()->getNode(
name);
614 SG_LOG(SG_GENERAL, SG_DEBUG,
615 "Attempt to set read flag for non-existant property "
618 node->setAttribute(SGPropertyNode::READ, state);
624 SGPropertyNode * node =
globals->get_props()->getNode(
name);
626 SG_LOG(SG_GENERAL, SG_DEBUG,
627 "Attempt to set write flag for non-existant property "
630 node->setAttribute(SGPropertyNode::WRITE, state);
636 SGPropertyNode* node =
globals->get_props()->getNode(
name);
638 SG_LOG(SG_GENERAL, SG_WARN,
"fgUntie: unknown property " <<
name);
642 if (!node->isTied()) {
646 if (!node->untie()) {
647 SG_LOG(SG_GENERAL, SG_WARN,
"Failed to untie property " <<
name);
653 SGPropertyNode* node =
globals->get_props()->getNode(
name);
658 if (!node->isTied()) {
662 if (!node->untie()) {
663 SG_LOG(SG_GENERAL, SG_WARN,
"Failed to untie property " <<
name);
void update(double dt) override
long fgGetLong(const char *name, long defaultValue)
Get a long value for a property.
void fgAddChangeListener(SGPropertyChangeListener *listener, const char *path)
Add a listener to a node.
static void setDateString(const char *date_string)
Set the current Zulu time.
bool fgHasNode(const char *path)
Test whether a given node exists.
double fgGetDouble(const char *name, double defaultValue)
Get a double value for a property.
void fgSetReadable(const char *name, bool state)
Set the state of the read attribute for a property.
void fgUntie(const char *name)
Untie a property from an external data source.
bool fgLoadProps(const std::string &path, SGPropertyNode *props, bool in_fg_root, int default_mode)
Load properties from a file.
bool fgGetBool(const char *name, bool defaultValue)
Get a bool value for a property.
SGSubsystemMgr::Registrant< FGProperties > registrantFGProperties
static const char * getDateString()
Return the current Zulu time.
static double getElapsedTime_sec()
Return the number of milliseconds elapsed since simulation started.
static const char * getLoggingPriority()
Get the logging priority.
bool fgSaveFlight(std::ostream &output, bool write_all)
Save the current state of the simulator to a stream.
bool fgSetDouble(const char *name, double val)
Set a double value for a property.
bool fgSetBool(const char *name, bool val)
Set a bool value for a property.
void setLoggingPriority(const char *p)
Set the logging priority.
void fgUntieIfDefined(const std::string &name)
@brfief variant of the above which doesn't warn if the property does not exist
bool fgLoadFlight(std::istream &input)
Restore the current state of the simulator from a stream.
static SGPropertyNode_ptr initDoubleNode(const std::string &path, const double v)
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
float fgGetFloat(const char *name, float defaultValue)
Get a float value for a property.
bool fgSetLong(const char *name, long val)
Set a long value for a property.
bool fgSetInt(const char *name, int val)
Set an int value for a property.
bool fgSetString(const char *name, const char *val)
Set a string value for a property.
void fgSetWritable(const char *name, bool state)
Set the state of the write attribute for a property.
bool fgSetFloat(const char *name, float val)
Set a float value for a property.
void setLoggingClasses(const char *c)
Set the logging classes.
static const char * getGMTString()
Return the GMT as a string.
static const char * getLoggingClasses()
void fgSetArchivable(const char *name, bool state)
Set the state of the archive attribute for a property.
SGPropertyNode * fgGetNode(const char *path, bool create=false)
Get a property node.
void setLoggingPriority(const char *p)
Set the logging priority.
void setLoggingClasses(const char *c)
Set the logging classes.
void fgSetArchivable(const char *name, bool state=true)
Set the state of the archive attribute for a property.
void guiErrorMessage(const char *txt)