add a props.condition(property) command that evaluates a property branch
as <condition> according to the rules set out in $FG_ROOT/Docs/README.condition
This commit is contained in:
parent
5f7104ac8a
commit
0b4e6f934e
1 changed files with 75 additions and 7 deletions
|
@ -84,7 +84,7 @@ Node._setChildren = func {
|
||||||
if(typeof(val) == "scalar") { subnode.setValue(val); }
|
if(typeof(val) == "scalar") { subnode.setValue(val); }
|
||||||
elsif(typeof(val) == "hash") { subnode.setValues(val); }
|
elsif(typeof(val) == "hash") { subnode.setValues(val); }
|
||||||
elsif(typeof(val) == "vector") {
|
elsif(typeof(val) == "vector") {
|
||||||
for(i=0; i<size(val); i=i+1) {
|
for(i=0; i<size(val); i+=1) {
|
||||||
iname = name ~ "[" ~ i ~ "]";
|
iname = name ~ "[" ~ i ~ "]";
|
||||||
me._setChildren(iname, val[i]);
|
me._setChildren(iname, val[i]);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ Node._setChildren = func {
|
||||||
# Node object to the console. Try binding "props.dump(props.globals)"
|
# Node object to the console. Try binding "props.dump(props.globals)"
|
||||||
# to a key for a fun hack.
|
# to a key for a fun hack.
|
||||||
#
|
#
|
||||||
dump = func {
|
var dump = func {
|
||||||
if(size(arg) == 1) { prefix = ""; node = arg[0]; }
|
if(size(arg) == 1) { prefix = ""; node = arg[0]; }
|
||||||
else { prefix = arg[0]; node = arg[1]; }
|
else { prefix = arg[0]; node = arg[1]; }
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ dump = func {
|
||||||
# Recursively copy property branch from source Node to
|
# Recursively copy property branch from source Node to
|
||||||
# destination Node. Doesn't copy aliases.
|
# destination Node. Doesn't copy aliases.
|
||||||
#
|
#
|
||||||
copy = func(src, dest) {
|
var copy = func(src, dest) {
|
||||||
foreach(c; src.getChildren()) {
|
foreach(c; src.getChildren()) {
|
||||||
name = c.getName() ~ "[" ~ c.getIndex() ~ "]";
|
name = c.getName() ~ "[" ~ c.getIndex() ~ "]";
|
||||||
copy(src.getNode(name), dest.getNode(name, 1));
|
copy(src.getNode(name), dest.getNode(name, 1));
|
||||||
|
@ -139,14 +139,14 @@ copy = func(src, dest) {
|
||||||
# Utility. Turns any ghosts it finds (either solo, or in an
|
# Utility. Turns any ghosts it finds (either solo, or in an
|
||||||
# array) into Node objects.
|
# array) into Node objects.
|
||||||
#
|
#
|
||||||
wrap = func {
|
var wrap = func {
|
||||||
argtype = typeof(arg[0]);
|
argtype = typeof(arg[0]);
|
||||||
if(argtype == "ghost") {
|
if(argtype == "ghost") {
|
||||||
return wrapNode(arg[0]);
|
return wrapNode(arg[0]);
|
||||||
} elsif(argtype == "vector") {
|
} elsif(argtype == "vector") {
|
||||||
v = arg[0];
|
v = arg[0];
|
||||||
n = size(v);
|
n = size(v);
|
||||||
for(i=0; i<n; i=i+1) { v[i] = wrapNode(v[i]); }
|
for(i=0; i<n; i+=1) { v[i] = wrapNode(v[i]); }
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
return arg[0];
|
return arg[0];
|
||||||
|
@ -157,7 +157,7 @@ wrap = func {
|
||||||
# Node object and its _g (ghost) field set to the specified object.
|
# Node object and its _g (ghost) field set to the specified object.
|
||||||
# Nasal's literal syntax can be pleasingly terse. I like that. :)
|
# Nasal's literal syntax can be pleasingly terse. I like that. :)
|
||||||
#
|
#
|
||||||
wrapNode = func { { parents : [Node], _g : arg[0] } }
|
var wrapNode = func { { parents : [Node], _g : arg[0] } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# Global property tree. Set once at initialization. Is that OK?
|
# Global property tree. Set once at initialization. Is that OK?
|
||||||
|
@ -172,7 +172,7 @@ props.globals = wrapNode(_globals());
|
||||||
# path under each node of that name to set (e.g. "throttle"), arg[2]
|
# path under each node of that name to set (e.g. "throttle"), arg[2]
|
||||||
# is the value.
|
# is the value.
|
||||||
#
|
#
|
||||||
setAll = func {
|
var setAll = func {
|
||||||
node = props.globals.getNode(arg[0]);
|
node = props.globals.getNode(arg[0]);
|
||||||
if(node == nil) { return; }
|
if(node == nil) { return; }
|
||||||
name = node.getName();
|
name = node.getName();
|
||||||
|
@ -183,3 +183,71 @@ setAll = func {
|
||||||
if(c.getName() == name) {
|
if(c.getName() == name) {
|
||||||
c.getNode(arg[1], 1).setValue(arg[2]); }}
|
c.getNode(arg[1], 1).setValue(arg[2]); }}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Evaluates a <condition> property branch according to the rules
|
||||||
|
# set out in $FG_ROOT/Docs/README.condition.
|
||||||
|
#
|
||||||
|
var condition = func(p) {
|
||||||
|
if(!isa(p, props.Node)) { p = props.globals.getNode(p); }
|
||||||
|
return _cond_and(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _cond_and = func(p) {
|
||||||
|
foreach(var c; p.getChildren()) {
|
||||||
|
if(!_cond(c)) { return 0; }
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _cond_or = func(p) {
|
||||||
|
foreach(var c; p.getChildren()) {
|
||||||
|
if(_cond(c)) { return 1; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _cond = func(p) {
|
||||||
|
var n = p.getName();
|
||||||
|
if(n == "not") { return !_cond_and(p); }
|
||||||
|
if(n == "and") { return _cond_and(p); }
|
||||||
|
if(n == "or") { return _cond_or(p); }
|
||||||
|
if(n == "equals") { return _cond_cmp(p, "EQ"); }
|
||||||
|
if(n == "not-equals") { return !_cond_cmp(p, "EQ"); }
|
||||||
|
if(n == "less-than") { return _cond_cmp(p, "LT"); }
|
||||||
|
if(n == "greater-than") { return _cond_cmp(p, "GT"); }
|
||||||
|
if(n == "less-than-equals") { return !_cond_cmp(p, "GT"); }
|
||||||
|
if(n == "greater-than-equals") { return !_cond_cmp(p, "LT"); }
|
||||||
|
if(n == "property") { return getprop(p.getValue()); }
|
||||||
|
printlog("alert", "condition: invalid operator ", n);
|
||||||
|
dump(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _cond_cmp = func(p, op) {
|
||||||
|
var left = p.getChild("property", 0, 0);
|
||||||
|
if(left != nil) { left = getprop(left.getValue()); }
|
||||||
|
else {
|
||||||
|
printlog("alert", "condition: no left value");
|
||||||
|
dump(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
var right = p.getChild("property", 1, 0);
|
||||||
|
if(right != nil) { right = getprop(right.getValue()); }
|
||||||
|
else {
|
||||||
|
right = p.getChild("value", 0, 0);
|
||||||
|
if(right != nil) { right = right.getValue(); }
|
||||||
|
else {
|
||||||
|
printlog("alert", "condition: no right value");
|
||||||
|
dump(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(left == nil or right == nil) {
|
||||||
|
printlog("alert", "condition: comparing with nil");
|
||||||
|
dump(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return op == "LT" ? left < right : op == "GT" ? left > right : left == right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue