Nasal scripting language: Difference between revisions

Jump to navigation Jump to search
Line 58: Line 58:


Also, note that as of 05/2009, Nasal in FlightGear does not yet support any form of dependency resolution. In other words, there's no "import", "require" or "include" directive - this is also why most code in FlightGear is wrapped inside a _setlistener() call instead, which in turn waits for a FlightGear signal before executing the code (see below for details).
Also, note that as of 05/2009, Nasal in FlightGear does not yet support any form of dependency resolution. In other words, there's no "import", "require" or "include" directive - this is also why most code in FlightGear is wrapped inside a _setlistener() call instead, which in turn waits for a FlightGear signal before executing the code (see below for details).
== Using Hashs to map keys to functions ==
You can easily reduce the complexity of huge conditional (IF) statements, such as this one:
<syntaxhighlight lang="php">
    if (a==1) function_a();
    else
    if (a==2) function_b();
    else
    if (a==3) function_c();
    else
    if (a==4) function_d();
    else
    if (a==5) function_e();
</syntaxhighlight>
.. just by using the variable as a key (index) into a hash, so that you can directly call the corresponding function:
<syntaxhighlight lang="php">
    var mapping = {1:function_a, 2:function_b, 3:function_c, 4:function_d,5:function_e};
    mapping[a] ();
</syntaxhighlight>
This initializes first a hash map of values and maps a function "pointer" to each value, so that accessing mapping[x] will return the function pointer for the key "x".
Next, you can actually call the function by appending a list of function arguments (empty parentheses for no args) to the hash lookup.
Using this technique, you can reduce the complexity of huge conditional blocks. For example, consider:
    # weather_tile_management.nas
    460        if (code == "altocumulus_sky"){weather_tiles.set_altocumulus_tile();}
    461        else if (code == "broken_layers") {weather_tiles.set_broken_layers_tile();}
    462        else if (code == "stratus") {weather_tiles.set_overcast_stratus_tile();}
    463        else if (code == "cumulus_sky") {weather_tiles.set_fair_weather_tile();}
    464        else if (code == "gliders_sky") {weather_tiles.set_gliders_sky_tile();}
    465        else if (code == "blue_thermals") {weather_tiles.set_blue_thermals_tile();}
    466        else if (code == "summer_rain") {weather_tiles.set_summer_rain_tile();}
    467        else if (code == "high_pressure_core") {weather_tiles.set_high_pressure_core_tile();}
    468        else if (code == "high_pressure") {weather_tiles.set_high_pressure_tile();}
    469        else if (code == "high_pressure_border") {weather_tiles.set_high_pressure_border_tile();}
    470        else if (code == "low_pressure_border") {weather_tiles.set_low_pressure_border_tile();}
    471        else if (code == "low_pressure") {weather_tiles.set_low_pressure_tile();}
    472        else if (code == "low_pressure_core") {weather_tiles.set_low_pressure_core_tile();}
    473        else if (code == "cold_sector") {weather_tiles.set_cold_sector_tile();}
    474        else if (code == "warm_sector") {weather_tiles.set_warm_sector_tile();}
    475        else if (code == "tropical_weather") {weather_tiles.set_tropical_weather_tile();}
    476        else if (code == "test") {weather_tiles.set_4_8_stratus_tile();}
    477        else ...
While this is not a very complex or huge block of code, it is an excellent example for very good naming conventions used already, because the consistency of naming variables and functions can pay off easily here, with just some very small changes, you can already reduce the whole thing to a hash lookup like this:
  weather_tiles["set_"~code~"_tile"]();  # naming convention
This would dynamically concatenate a key consisting of "set_" + code + "_title" into the hash named weather_tiles, and then call the function that is returned from the hash lookup.
So for this to work you only need to enforce consistency when naming your functions (i.e. this would of course CURRENTLY fail when the variable code contains "test" because there is no such hash member (it's "4_8_stratus" instead).
The same applies to cumulus sky (fair weather), stratus/overcast stratus.
But these are very simple changes to do (just renaming these functions to match the existing conventions). When you do that, you can easily replace such huge IF statements and replace them with a single hash lookup and function call:
hash[key] (arguments...);
For example, consider:
<syntaxhighlight lang="php">
var makeFuncString = func(c) return tolower("set_"~c~"_tile");
var isFunc = func(f) typeof(f)=='func';
var hasMethod = func(h,m) contains(h,m) and isFunc;
var callIfAvailable = func(hash, method, unavailable=func{} ) {
  var c=hasMethod(hash,makeFuncString(m) ) or unavailable();
  hash[makeFuncString(m)] ();
}
callIfAvailable( weather_tiles,code, func {die("key not found in hash or not a func");} );
</syntaxhighlight>


== Initializing data structures ==
== Initializing data structures ==

Navigation menu