Nasal CDU Framework

From FlightGear wiki
Revision as of 18:29, 9 May 2011 by Hcc23 (talk | contribs) (→‎CDU)
Jump to navigation Jump to search

This page is a rather technical description of the Nasal code for the framework used to implement a Boeing style CDU.

WIP.png Work in progress
This article or section will be worked on in the upcoming hours or days.
Note: Hcc23 is working on this. Find him in the FG IRC channel to discuss this page.
See history for the latest developments.

Note: Although this is meant as a documentation for the code, it obviously will (always) be (slightly) outdated. However, after reading through this page, the actual source code at https://gitorious.org/fg/fgdata/trees/master/Aircraft/Instruments-3d/cdu should not present any major surprises. Hcc23 10:07, 7 May 2011 (EDT)


Basic Classes

Line

The line class represents data to be shown on a row of the CDU's display matrix. This does not mean that a line has to span a complete row of the CDU's display matrix.

 var Line = {
   # "Static"
   vector 	byID,
   func 	registerInPropTree(path),
   func 	formatOutput(input_data),
   func 	getScreenTextVector(),
   func 	new(line_data,ptp),
   
   # "Public"
   scalar 	me.id,
   scalar 	me.ptp,
   vector 	me.used_properties,
   vector 	me.line_data,
   scalar 	me.line_string_length,
   func 	me.enable(),
   func 	me.disable(),
   
   # "Private"
   scalar 	me.active,
 };

Field

A field holds two lines, the label and the data line, as well as information about what the associated line select key does.

 var Field = {
   # "Static"
   vector 	byID,
   func 	registerInPropTree(path=nil),
   func 	new(label,data,key_action=nil,ptp=nil),
   
   # "Public"
   scalar 	me.id,
   scalar 	me.ptp,
 
   func 	me.get_label_line(),
   func 	me.get_label_line(),
   func 	me.used_properties(),
   func 	me.lsk_binding(),
   func 	me.enable_lsk(),
   func 	me.disable_lsk(),
 
   # "Private"
   (Line)	me.label_line,	
   (Line) 	me.data_line,
   scalar 	me.lsk_active,
 };

SubPage

A SubPage is actually the main element in the CDU framework. It holds the content via its fields and manages the updating of the CDU screen.

 var SubPage = {
   # "Static"
   vector 	byID,
   (Field) 	blankField,
   func 	registerInPropTree(path=nil),
   func 	updateField(field, side, lsk_index),	
   func 	displayFields(field_vector, side),
   func 	displayPage(),
   func 	new(parent_base_page,name=nil,ptp=nil),
   
   # "Public"
   scalar 	me.id,
   scalar      me.separator,
   scalar 	me.ptp,
   func 	me.register_field(field_pos,field),
   func 	me.activate(),
   (Field) 	me.home
 
   # "Private"
   scalar 	me.parent,
   scalar      me.title,
   scalar      me.status,
   vector 	me.left_field,
   vector      me.right_field,
 };

BasePage

A BasePage is exactly that: a base to hold sub pages. A base page most closely represents the concept of a page in a CDU.

 var BasePage = {
   # "Static"
   vector 	byID,
   func 	displayPage(),
   func 	regiserInPropTree(path)
   func 	new(name,ptp=nil),
   
   # "Public"
   scalar 	me.id,
   scalar 	me.active_sub_page_id,
   func 	me.activate(),
   (Field) 	me.home,
   scalar 	me.ptp,
   
   # "Private"
   vector 	me.sub_pages,
   scalar 	me.title,
   scalar 	me.status,
   
 };  

CDU

The CDU is the main class for the instrument. Each simulated CDU should have one and only one CDU instance associated to it. This is intended to support multiple CDUs showing different content in the future.


 var CDU = {
   # "STATIC"
   func 	M_ERROR(message_string),
   func 	M_WARNING(message_string),
   func 	M_NOTE(message_string),
   func 	M_HINT(message_string),
 
   func 	updateDisplay(),
   scalar 	activeBasePageID,
 
   (ScratchPad) 		scratchPad,
   (Timer) 			timer,
   (ListenerCollection) 	listOfListeners,
 };

Additional Infrastructure

The previous section was more concerned with the conceptually necessary pieces for a/the CDU. This section introduces the other elements the framework introduces in order to code a functional CDU.


ScratchPad

The ScratchPad is the input/output line in the CDU(s). The scratch pas as such is kind of different from the rest of the CDU(s) as the scratch pad messages are truly static, i.e. they happen to be displayed on all CDUs in the cockpit, no matter what the individual CDU is otherwise showing.

 var ScratchPad = {
   # "STATIC"
   vector 	messages,
   scalar 	deleteString, # "DELETE"~""
   func 	displayScratchPad(),
   func 	new(),
 
   # "PUBLIC"
   scalar 	me.input_string,
   func 	me.erase,
   
   # "PRIVATE"
   scalar 	me.pm_trigger,
   func 	me.plusminus(),
   func 	me.clear(pressedTime),
   func 	me.erase(),
 };


ListenerCollection

In order to update fields that are tied to a (potentially changing) property, fields that need a (potentially changing) property to compute their data can (and automatically will) register a property listener on the relevant properties whenever the relevant field is displayed. In order to unregister the listener for pages that are no longer displayed, the class CDU keeps a collection of the currently active listeners, such allowing the unregisterling for unneeded listeners.

 var ListenerCollection = {
   # "STATIC"
   func 	registerInPropTree(path),
   func 	add(prop, field_id, subpage_id, side, lsk_index),
   func 	clearAll(),
   func 	new(ptp=nil),
 
   # "PRIVATE"
   scalar 	me.ptp,
   vector 	me.listener_list,
   vector 	me.property_list,
 };