|
|
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 == |