From 0be80148c3d12019253f563b02582abfdea04a64 Mon Sep 17 00:00:00 2001 From: ehofman Date: Mon, 1 Dec 2003 14:36:22 +0000 Subject: [PATCH] Add Nasal Vs. 1.5 --- Nasal/globals.nas | 33 +++++++++++++++ Nasal/props.nas | 101 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 Nasal/globals.nas create mode 100644 Nasal/props.nas diff --git a/Nasal/globals.nas b/Nasal/globals.nas new file mode 100644 index 000000000..7afbe86ce --- /dev/null +++ b/Nasal/globals.nas @@ -0,0 +1,33 @@ +## +# Returns true if the first object is an instance of the second +# (class) object. Example: isa(someObject, props.Node) +# +isa = func { + obj = arg[0]; class = arg[1]; + if(!contains(obj, "parents")) { return 0; } + foreach(c; obj.parents) { + if(c == class) { return 1; } + elsif(isa(obj, c)) { return 1; } + } + return 0; +} + +## +# Invokes a FlightGear command specified by the first argument. The +# second argument specifies the property tree to be passed to the +# command as its argument. It may be either a props.Node object or a +# string, in which case it specifies a path in the global property +# tree. +# +fgcommand = func { + if(isa(arg[1], props.Node)) { _fgcommand(arg[0], arg[1]._g) } + _fgcommand(arg[0], propTree); +} + +## +# Returns the SGPropertyNode argument to the currently executing +# function. Wrapper for the internal _cmdarg function that retrieves +# the ghost handlet to the argument and wraps it in a +# props.Node object. +# +cmdarg = func { props.wrapNode(_cmdarg()) } diff --git a/Nasal/props.nas b/Nasal/props.nas new file mode 100644 index 000000000..e10241366 --- /dev/null +++ b/Nasal/props.nas @@ -0,0 +1,101 @@ +## +# Node class definition. The class methods simply wrap the +# low level exention functions which work on a "ghost" handle to a +# SGPropertyNode object stored in the _g field. +# +# Not all of the features of SGPropertyNode are supported. There is +# no support for ties, obviously, as that wouldn't make much sense +# from a Nasal context. The various get/set methods work only on the +# local node, there is no equivalent of the "relative path" variants +# available in C++; just use node.getNode(path).whatever() instead. +# There is no support for the "listener" interface yet. The aliasing +# feature isn't exposed, except that you can get an "ALIAS" return +# from getType to detect them (to avoid cycles while walking the +# tree). +# +Node = { + getType : func { wrap(_getType(me._g, arg)) }, + getName : func { wrap(_getName(me._g, arg)) }, + getIndex : func { wrap(_getIndex(me._g, arg)) }, + getValue : func { wrap(_getValue(me._g, arg)) }, + setValue : func { wrap(_setValue(me._g, arg)) }, + setIntValue : func { wrap(_setIntValue(me._g, arg)) }, + setBoolValue : func { wrap(_setBoolValue(me._g, arg)) }, + setDoubleValue : func { wrap(_setDoubleValue(me._g, arg)) }, + getParent : func { wrap(_getParent(me._g, arg)) }, + getChild : func { wrap(_getChild(me._g, arg)) }, + getChildren : func { wrap(_getChildren(me._g, arg)) }, + removeChild : func { wrap(_removeChild(me._g, arg)) }, + getNode : func { wrap(_getNode(me._g, arg)) }, + +}; + +# Static constructor. Accepts a hash as an argument and duplicates +# its contents in the property node. ex: +# Node.new({ value : 1.0, units : "ms" }); +Node.new : func { + result = wrapNode(_new()); + if(typeof(arg[0]) == "hash") { + foreach(k; keys(arg[0]) { + result.getNode(k, 1).setValue(arg[0][k]); + } + } +} + +## +# Useful debugging utility. Recursively dumps the full state of a +# Node object to the console. Try binding "props.dump(props.globals)" +# to a key for a fun hack. +# +dump = func { + if(size(arg) == 1) { prefix = ""; node = arg[0]; } + else { prefix = arg[0]; node = arg[1]; } + + index = node.getIndex(); + type = node.getType(); + name = node.getName(); + val = node.getValue(); + + if(val == nil) { val = "nil"; } + name = prefix ~ name; + if(index > 0) { name = name ~ "[" ~ index ~ "]"; } + print(name, " {", type, "} = ", val); + + # Don't recurse into aliases, lest we get stuck in a loop + if(type != "ALIAS") { + children = node.getChildren(); + foreach(c; children) { dump(name ~ "/", c); } + } +} + +## +# Utility. Turns any ghosts it finds (either solo, or in an +# array) into Node objects. +# +wrap = func { + argtype = typeof(arg[0]); + if(argtype == "ghost") { + return wrapNode(arg[0]); + } elsif(argtype == "vector") { + v = arg[0]; + n = size(v); + for(i=0; i