57 std::vector<std::shared_ptr<Node>>
_nodes;
63 struct Node : SGPropertyChangeListener
65 explicit Node(
const char* spec);
102 NodeDump(
const Node& node,
const std::string& indent=
"",
bool deep=
false);
134 std::map<std::string, std::shared_ptr<Stat>>
stats;
156 std::shared_ptr<Sequence>
getSequence(
const char* spec);
182 for (
const char* s=spec; ; ++s) {
184 assert(nesting == 0);
212 for (
const char* s=spec; ; ++s) {
214 assert(nesting == 0);
218 if (spec[0] !=
'(') {
228 if (spec[0] ==
'(' && nesting == 0) {
247 debug.statsAdd(
"valueChanged");
248 SG_LOG(SG_VIEW, SG_DEBUG,
"valueChanged():"
249 <<
" node->_sgnode_listen->getPath()='" <<
_sgnode_listen->getPath() <<
"'"
250 <<
" node->getPath()='" << node->getPath() <<
"'"
264 for (
auto sequence: node.
_parents) {
272 for (
auto node: sequence.
_parents) {
301 if (spec[0] == 0 || spec[0] ==
')') {
305 std::shared_ptr<Sequence> sequence;
311 for(
const char* s = spec;;) {
312 std::shared_ptr<Node> node
315 sequence->_nodes.push_back(node);
316 s += (node->_end - node->_begin);
321 sequence = it->second;
326 sequence->_parents.begin(),
327 sequence->_parents.end(),
330 if (it == sequence->_parents.end()) {
331 sequence->_parents.push_back(parent);
339 if (spec[0] == 0 || spec[0] ==
')') {
343 std::shared_ptr<Node> node;
349 node.reset(
new Node(spec));
350 if (node->_begin[0] ==
'(') {
360 if (std::find(node->_parents.begin(), node->_parents.end(), parent)
361 == node->_parents.end()) {
362 node->_parents.push_back(parent);
379 std::shared_ptr<Sequence> sequence
382 SG_LOG(SG_VIEW, SG_DEBUG,
383 "Created new sequence:\n"
395 assert(node.
_begin[0] ==
'(');
401 SGPropertyNode* sgnode = NULL;
403 debug.statsAdd(
"propertypath_getNode");
404 sgnode =
globals->get_props()->getNode(path,
true );
406 debug.statsAdd(
"propertypath_getNode_failed");
407 SG_LOG(SG_VIEW, SG_DEBUG,
": getNodeSGNode(): getNode() failed, path='" << path <<
"'");
417 node.
_sgnode->removeChangeListener(&node);
422 node.
_sgnode->addChangeListener(&node,
false );
426 if (!node.
_sgnode && path !=
"") {
439 if (node.
_begin[0] ==
'(') {
442 debug.statsAdd(
"property_getStringValue");
463 for (
auto node: sequence.
_nodes) {
474 assert(sequence.
_nodes.size() == 1);
493 if (!node->getParent()) {
497 if (node->getType() == simgear::props::BOOL) {
503 if (node->getStringValue()[0] == 0) {
509 return node->getDoubleValue();
516 if (node->getStringValue()[0] != 0) {
517 return node->getBoolValue();
525 std::shared_ptr<Sequence> sequence =
getSequence(spec);
531 std::shared_ptr<Sequence> sequence =
getSequence(spec);
532 if (sequence->_nodes.size() != 1 || sequence->_nodes.front()->_begin[0] !=
'(') {
533 SG_LOG(SG_VIEW, SG_DEBUG,
"bad sequence for getDoubleValue() - must have outermost '(...)': '" << spec);
542 std::shared_ptr<Sequence> sequence =
getSequence(spec);
543 if (sequence->_nodes.size() != 1 || sequence->_nodes.front()->_begin[0] !=
'(') {
544 SG_LOG(SG_VIEW, SG_DEBUG,
"bad sequence for getBoolValue() - must have outermost '(...)': '" << spec);
553 out <<
"ViewPropertyEvaluator\n";
557 out <<
" " << (
i+1) <<
"/" <<
spec_to_sequence.size() <<
": spec: " << it.first <<
"\n";
565 <<
": spec='" << it.first <<
"'"
574 <<
": spec='" << it.first <<
"'"
575 <<
": " <<
NodeDump(*it.second,
"",
false )
579 out <<
" Number of listens: " <<
debug.listens.size() <<
"\n";
581 for (
auto it:
debug.listens) {
582 out <<
" " << (
i+1) <<
"/" <<
debug.listens.size()
583 <<
": " << it->getPath()
596 out <<
"ViewPropertyEvaluator\n";
599 out <<
" " <<
": spec: '" << dumpone.
_spec <<
"'\n";
633 debug.listens.push_back(node);
638 auto it = std::find(
debug.listens.begin(),
debug.listens.end(), node);
639 if (it ==
debug.listens.end()) {
640 SG_LOG(SG_VIEW, SG_ALERT,
"Unable to find node in debug.listens");
643 debug.listens.erase(it);
649 time_t t = time(NULL);
650 time_t dt = t -
debug.statsT0;
652 out <<
"ViewPropertyEvaluator stats: dt=" << dt <<
"\n";
653 for (
auto it:
debug.stats) {
654 const std::string&
name = it.first;
655 int n = it.second->n;
656 out <<
" : n=" << n <<
" n/sec=" << (1.0 * n / dt) <<
": " <<
name <<
"\n";
662 for (
auto it:
debug.stats) {
665 debug.statsT0 = time(NULL);
669 if (
debug.statsT0 == 0)
debug.statsT0 = time(NULL);
670 std::shared_ptr<Debug::Stat>& stat =
debug.stats[
name];
677 static time_t t0 = time(NULL);
678 time_t t = time(NULL);
685 SG_LOG(SG_VIEW, SG_BULK,
Dump());
694 spec += std::string(node->_begin, node->_end);
698 <<
"Sequence at " << &self.
_sequence <<
":"
703 <<
" spec='" << spec <<
"'"
716 <<
"Node at " << &self.
_node <<
":"
742 std::cerr <<
Dump() <<
"\n";
const char * getSequenceEnd(const char *spec)
void rescanSequence(Sequence &sequence)
std::shared_ptr< Sequence > getSequenceInternal(const char *spec, Node *parent)
void rescanNode(Node &node)
std::map< std::string, std::shared_ptr< Node > > string_to_node
const std::string & getSequenceStringValue(Sequence &sequence)
std::map< const char *, std::shared_ptr< Sequence > > spec_to_sequence
double getSequenceDoubleValue(Sequence &sequence, double default_=0)
const std::string & getNodeStringValue(Node &node)
const char * getNodeEnd(const char *spec)
const std::string & getStringValue(const char *spec)
bool getSequenceBoolValue(Sequence &sequence, bool default_)
std::shared_ptr< Node > getNodeInternal(const char *spec, Sequence *parent)
std::shared_ptr< Sequence > getSequence(const char *spec)
std::map< std::string, std::shared_ptr< Sequence > > string_to_sequence
double getDoubleValue(const char *spec, double default_)
std::ostream & operator<<(std::ostream &out, const Dump &dump)
SGPropertyNode * getSequenceNode(Sequence &sequence)
SGPropertyNode * getNodeSGNode(Node &node, bool cache=true)
bool getBoolValue(const char *spec, bool default_)
std::vector< SGPropertyNode_ptr > listens
void listensAdd(SGPropertyNode_ptr node)
void listensRemove(SGPropertyNode_ptr node)
std::map< std::string, std::shared_ptr< Stat > > stats
friend std::ostream & operator<<(std::ostream &out, const StatsShow &)
void statsAdd(const char *name)
DumpOne(const char *spec)
NodeDump(const Node &node, const std::string &indent="", bool deep=false)
const std::string & _indent
friend std::ostream & operator<<(std::ostream &out, const NodeDump &self)
std::vector< Sequence * > _parents
SGPropertyNode_ptr _sgnode_listen
void valueChanged(SGPropertyNode *node)
SGPropertyNode_ptr _sgnode
std::shared_ptr< Sequence > _child
const Sequence & _sequence
friend std::ostream & operator<<(std::ostream &out, const SequenceDump &self)
const std::string & _indent
SequenceDump(const Sequence &sequence, const std::string &indent="", bool deep=false)
std::vector< Node * > _parents
std::vector< std::shared_ptr< Node > > _nodes