6
edits
No edit summary |
mNo edit summary |
||
(7 intermediate revisions by 4 users not shown) | |||
Line 9: | Line 9: | ||
----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ||
To toggle the Parking brake, use this. Entire code-block shown. Non-repeatable button. (You have to specifically set <repeatable> to true if you want repeatable. It is assumed to be false. | To toggle the Parking brake, use this. Entire code-block shown. Non-repeatable button. (You have to specifically set <repeatable> to true if you want repeatable. It is assumed to be false.) | ||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<button n="1"> | <button n="1"> | ||
Line 43: | Line 43: | ||
props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture")) | props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture")) | ||
</pre> | </pre> | ||
----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ||
----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ||
Line 68: | Line 64: | ||
=== if ... then ... else === | === if ... then ... else === | ||
Sometimes you only want to do something if a certain condition is true (or false.) In this case you use an if clause. The general form is | Sometimes you only want to do something if a certain condition is true (or false.) In this case you use an if clause. The general form in most programming languages is | ||
: '''if''' '''('''condition''')''' '''then''' action '''endif''' | |||
In Nasal, we write "then" as "{" and "endif" as "}". Each "action" (or statement) is terminated by a semicolon: | |||
<syntaxhighlight lang="nasal"> | |||
if (condition) | |||
{ # the opening curly brace means THEN | |||
action; | |||
} # the closing curly brace means ENDIF, i.e. end of this block | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Actions can be arbitrary Nasal expressions, including function calls and other conditional blocks. | Actions can be arbitrary Nasal expressions, including function calls and other conditional blocks. | ||
==== An example ==== | |||
Lets say that if x is less than 5 we want to add 2 to it. We write: | Lets say that if x is less than 5 we want to add 2 to it. We write: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { x = x + 2; } | |||
</syntaxhighlight> | </syntaxhighlight> | ||
The more readable way of writing it is | The more readable way of writing it is | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x = x + 2; | |||
} | |||
</syntaxhighlight> | |||
And we can even omit the braces if there's only one action: | |||
<syntaxhighlight lang="nasal"> | |||
if (x < 5) # no opening brace... | |||
x = x + 2; # ...so the if statement ends at the first semicolon | |||
</syntaxhighlight> | </syntaxhighlight> | ||
If we also want to add 1 to y if the condition is true, we write | If we also want to add 1 to y if the condition is true, we write | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x = x + 2; | |||
y = y + 1; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 115: | Line 115: | ||
For example: | For example: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x += 2; # means x = x + 2 | |||
y += 1; # means y = y + 1 | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 125: | Line 125: | ||
Now lets pretend that we still want to increase x by 2 if it less than 5, and if it is 5 or more we want to add 1 to it. We use else. | Now lets pretend that we still want to increase x by 2 if it less than 5, and if it is 5 or more we want to add 1 to it. We use else. | ||
It looks like this | It looks like this | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x = x + 2; | |||
} else { | |||
x = x + 1; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Now lets say we have the following rules: | Now lets say we have the following rules: | ||
* If x < 5 add 2 to it | |||
* If x < 10 add 1 to it | |||
* If x is 10 or more add 7 to it. | |||
In English our code would be | In English our code would be | ||
* If (x < 5) then (x = x + 2) else if (x < 10) then (x = x + 1). | |||
* If none of these are true then (x = x + 7). | |||
* End of if clause. | |||
We test for x < 5 first. If it fails we test for x < 10. If x , 5 succeeds we do (x = x + 2) and then move on past the end of if clause. | We test for x < 5 first. If it fails we test for x < 10. If x , 5 succeeds we do (x = x + 2) and then move on past the end of if clause. | ||
Line 147: | Line 147: | ||
Writing our code properly we get | Writing our code properly we get | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x = x + 2; | |||
} elsif (x < 10) { | |||
x = x + 1; | |||
} else { | |||
x = x + 7; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
You can use more than one | You can use more than one elsif, but it gets messy. If you have a number of tests then it might be better to test for each case individually. | ||
Easier to understand and much less chance of an error. | Easier to understand each condition separately and much less chance of an error. | ||
Our above example would become | Our above example would become | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (x < 5) { | |||
x = x + 2; | |||
} | |||
if (x >= 5) and (x < 10) { | |||
x = x + 1; | |||
} | |||
if (x >= 10) { | |||
x = x + 7; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 179: | Line 176: | ||
But the advantage is that we are forced to write out each condition exactly as it should be tested. Easier to understand and easier to maintain. | But the advantage is that we are forced to write out each condition exactly as it should be tested. Easier to understand and easier to maintain. | ||
==== Another example ==== | |||
Lets say that you want something to happen only if the gear is up. But the only property you can read is | Lets say that you want something to happen only if the gear is up. But the only property you can read is GearDown. Then you write | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
if (!GearDown) { | |||
action; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
The ! means not. So it translates as: If the gear is not down perform action. | The ! means not. So it translates as: If the gear is not down perform action. | ||
See the discussion of variables below for an example of the use of if. | See the discussion of variables below for an example of the use of if. | ||
Line 248: | Line 242: | ||
BTW Here the props in props.setAll is short for property, not propellers. | BTW Here the props in props.setAll is short for property, not propellers. | ||
Line 347: | Line 340: | ||
'''Method 1''' | '''Method 1''' | ||
<nowiki> <data> | |||
<mode type="int">1</mode> # Initialise mode to 1 | <mode type="int">1</mode> # Initialise mode to 1 | ||
</data> | </data> | ||
Line 353: | Line 346: | ||
<nasal> | <nasal> | ||
<script> | <script> | ||
<![CDATA[ | |||
var self = cmdarg().getParent(); | var self = cmdarg().getParent(); | ||
var data = self.getNode("data"); | var data = self.getNode("data"); | ||
var mode = data.getNode("mode"); | var mode = data.getNode("mode"); | ||
get_mode = func { mode.getValue(); } | |||
]]></script> | ]]> | ||
</script> | |||
</nasal> | </nasal> | ||
</nowiki> | |||
This goes right at the top of your xml file, just after </name>. | This goes right at the top of your xml file, just after </name>. | ||
The code for the button (non-repeatable)that changes mode looks like this | The code for the button (non-repeatable)that changes mode looks like this | ||
m = get_mode(); | var m = get_mode(); | ||
m = m + 1; | m = m + 1; | ||
if (m == 4) { | if (m == 4) { | ||
Line 374: | Line 368: | ||
When a button is pressed, the code looks like this | When a button is pressed, the code looks like this | ||
m = get_mode(); | var m = get_mode(); | ||
if (m == 1) { | if (m == 1) { | ||
ground-action | ground-action | ||
Line 431: | Line 425: | ||
be used somewhere in the system files. In the xml file for the Saitek Yoke, where I use a variable to control the assignments | be used somewhere in the system files. In the xml file for the Saitek Yoke, where I use a variable to control the assignments | ||
of the levers on the quadrant, I call the variable ''SaitekMultiMode''. Unlikely to be used by the FG programmers, or anybody else. | of the levers on the quadrant, I call the variable ''SaitekMultiMode''. Unlikely to be used by the FG programmers, or anybody else. | ||
=== perIndexAxisHandler === | === perIndexAxisHandler === | ||
Line 458: | Line 450: | ||
See [http://flightgear.org | See [http://forum.flightgear.org/viewtopic.php?f=24&t=17851 this post] for an example of using this. | ||
Line 475: | Line 467: | ||
Any complaints/suggestions/questions/kudos can be posted [http://flightgear.org | Any complaints/suggestions/questions/kudos can be posted [http://forum.flightgear.org/viewtopic.php?f=24&t=17892 here]. | ||
edits