1
0
Fork 0

- add props.nodeList() function which turns property ghosts, props.Nodes,

and path strings into a list of props.Nodes. It also digests lists of
  properties, or lists of lists of properties etc., thus allowing things
  like props.nodeList(arg), props.nodeList(n.getChildren("foo")). This is
  meant for functions like aircraft.data.add() or screen.display.add().
- remove some redundant braces
- fix comment
This commit is contained in:
mfranz 2008-05-15 15:17:56 +00:00
parent e5c027786d
commit a329a7ba14

View file

@ -8,10 +8,9 @@
# from a Nasal context. The various get/set methods work only on the # from a Nasal context. The various get/set methods work only on the
# local node, there is no equivalent of the "relative path" variants # local node, there is no equivalent of the "relative path" variants
# available in C++; just use node.getNode(path).whatever() instead. # available in C++; just use node.getNode(path).whatever() instead.
# There is no support for the "listener" interface yet. The aliasing # The aliasing feature isn't exposed, except that you can get an
# feature isn't exposed, except that you can get an "ALIAS" return # "ALIAS" return from getType to detect them (to avoid cycles while
# from getType to detect them (to avoid cycles while walking the # walking the tree).
# tree).
# #
Node = { Node = {
getType : func { wrap(_getType(me._g, arg)) }, getType : func { wrap(_getType(me._g, arg)) },
@ -160,11 +159,11 @@ var copy = func(src, dest, attr = 0) {
} }
var type = src.getType(); var type = src.getType();
var val = src.getValue(); var val = src.getValue();
if(type == "ALIAS" or type == "NONE") { return; } if(type == "ALIAS" or type == "NONE") return;
elsif(type == "BOOL") { dest.setBoolValue(val); } elsif(type == "BOOL") dest.setBoolValue(val);
elsif(type == "INT") { dest.setIntValue(val); } elsif(type == "INT" or type == "LONG") dest.setIntValue(val);
elsif(type == "DOUBLE") { dest.setDoubleValue(val); } elsif(type == "FLOAT" or type == "DOUBLE") dest.setDoubleValue(val);
else { dest.setValue(val); } else dest.setValue(val);
if(attr) dest.setAttribute(src.getAttribute()); if(attr) dest.setAttribute(src.getAttribute());
} }
@ -217,6 +216,37 @@ var setAll = func {
c.getNode(arg[1], 1).setValue(arg[2]); }} c.getNode(arg[1], 1).setValue(arg[2]); }}
} }
##
# Turns about anything into a list of props.Nodes, including ghosts,
# path strings, vectors or hashes containing, as well as functions
# returning any of the former and in arbitrary nesting. This is meant
# to be used in functions whose main purpose is to handle collections
# of properties.
#
var nodeList = func {
var list = [];
foreach(var a; arg) {
var t = typeof(a);
if(isa(a, props.Node))
append(list, a);
elsif(t == "scalar")
append(list, props.globals.getNode(a, 1));
elsif(t == "vector")
foreach(var i; a)
list ~= nodeList(i);
elsif(t == "hash")
foreach(var i; keys(a))
list ~= nodeList(a[i]);
elsif(t == "func")
list ~= nodeList(a());
elsif(t == "ghost" and ghosttype(a) == ghosttype(props._globals()))
append(list, props.wrapNode(a));
else
die("nodeList: invalid nil property");
}
return list;
}
## ##
# Evaluates a <condition> property branch according to the rules # Evaluates a <condition> property branch according to the rules
# set out in $FG_ROOT/Docs/README.conditions. Undefined conditions # set out in $FG_ROOT/Docs/README.conditions. Undefined conditions
@ -224,37 +254,35 @@ var setAll = func {
# branch and returns nil on error. # branch and returns nil on error.
# #
var condition = func(p) { var condition = func(p) {
if(p == nil) { return 1; } if(p == nil) return 1;
if(!isa(p, props.Node)) { p = props.globals.getNode(p); } if(!isa(p, props.Node)) p = props.globals.getNode(p);
return _cond_and(p) return _cond_and(p)
} }
var _cond_and = func(p) { var _cond_and = func(p) {
foreach(var c; p.getChildren()) { foreach(var c; p.getChildren())
if(!_cond(c)) { return 0; } if(!_cond(c)) return 0;
}
return 1; return 1;
} }
var _cond_or = func(p) { var _cond_or = func(p) {
foreach(var c; p.getChildren()) { foreach(var c; p.getChildren())
if(_cond(c)) { return 1; } if(_cond(c)) return 1;
}
return 0; return 0;
} }
var _cond = func(p) { var _cond = func(p) {
var n = p.getName(); var n = p.getName();
if(n == "or") { return _cond_or(p); } if(n == "or") return _cond_or(p);
if(n == "and") { return _cond_and(p); } if(n == "and") return _cond_and(p);
if(n == "not") { return !_cond_and(p); } if(n == "not") return !_cond_and(p);
if(n == "equals") { return _cond_cmp(p, 0); } if(n == "equals") return _cond_cmp(p, 0);
if(n == "not-equals") { return !_cond_cmp(p, 0); } if(n == "not-equals") return !_cond_cmp(p, 0);
if(n == "less-than") { return _cond_cmp(p, -1); } if(n == "less-than") return _cond_cmp(p, -1);
if(n == "greater-than") { return _cond_cmp(p, 1); } if(n == "greater-than") return _cond_cmp(p, 1);
if(n == "less-than-equals") { return !_cond_cmp(p, 1); } if(n == "less-than-equals") return !_cond_cmp(p, 1);
if(n == "greater-than-equals") { return !_cond_cmp(p, -1); } if(n == "greater-than-equals") return !_cond_cmp(p, -1);
if(n == "property") { return !!getprop(p.getValue()); } if(n == "property") return !!getprop(p.getValue());
printlog("alert", "condition: invalid operator ", n); printlog("alert", "condition: invalid operator ", n);
dump(p); dump(p);
return nil; return nil;
@ -284,8 +312,8 @@ var _cond_cmp = func(p, op) {
dump(p); dump(p);
return nil; return nil;
} }
if(op < 0) { return left < right; } if(op < 0) return left < right;
if(op > 0) { return left > right; } if(op > 0) return left > right;
return left == right; return left == right;
} }