Amulet Function Calls

Amulet widgets use the href parameter to specify a function call. See Widgets.htm for a detailed description of widgets. A function call can be a hyperlink to another page, a request for the value of an external variable, a command to invoke a Remote Procedure Call and much more. A function call can also send a command to other widgets, known as Inter-Widget Communication (IWC). See Appendix B for a comprehensive list of all available functions.

The Easy GUI operating system uses two general types of widgets: Control Widgets and View Widgets.

Control Widgets are user input widgets such as list widgets, slider widgets, radio buttons, checkboxes and function buttons. Anchors, META REFRESH objects and area maps can also call functions, like Control Widgets, but because they are not created using the <APPLET> tag, they are referred to as Control Objects. Typically, Control Widget/Object function calls are initiated by a "hit" of the widget. A "hit" can occur one of two ways.

The typical way is the physical "hit", which occurs when the active region of the object/widget on the touchscreen is touched and then released while still within the bounds of the active region. The object/widget must be in focus when letting up on the touchscreen for the object/widget to initiate its function calls. If you touch an active region, but move off the region while still touching the touchscreen, the object/widget will lose focus, therefore, letting up on the touchscreen will do nothing.

The alternative way a "hit" can occur is to have one Control Object/Widget invoke the forceHit() method of another Control Object/Widget. See IWC documentation for more information.

There are two exceptions to the rule that a "hit" initiates all function calls. The first exception is the Slider Widget. As soon as a pen down event occurs within the boundaries of a slider, a function call is initiated. If, while still in the pen down state, new values of the slider are selected, new function calls will be initiated. The second exception is Custom/Function Buttons which are set up to auto-repeat. If an auto-repeatable Custom/Function Button is touched, and stays in a pen down state longer than the time specified by the repeatDelay attribute, then a function call is initiated. As long as the button remains in a pen down state, the function calls will repeat at the frequency specified by the repeatRate attribute.

Control Objects/Widgets cannot call functions that return a value. See Appendix B for a comprehensive list of all valid control functions.

Multiple Function Calls

Control Objects/Widgets can call multiple functions at one time by separating the functions by a comma. There is a limit of 36 multiple functions that can be attached to a single Control Widget/Object href. To illustrate how to use multiple functions, see the following example. To create a function button that invokes an external RPC #5 and then links to page2.html, use the following:

<APPLET CODE="FunctionButton.class" WIDTH="150" HEIGHT="25" NAME="Button1">
<PARAM NAME="href" VALUE="Amulet:UART.invokeRPC(5), page2.html">
<PARAM NAME="buttonType" VALUE="spring-loaded">
<PARAM NAME="label" VALUE="test 5">
</APPLET>

Multiple function calls are performed in the order they are entered on the line, from left to right*. In the previous example, Amulet:UART.invokeRPC(5) would be called first, and then a hyperlink to page2.html would follow. As soon as a page is linked to, any subsequent function calls are discarded. For this reason, if it is desired to link to another page, that must be the last function call within a multiple function call.

*Important notes regarding the order of multiple function calls: If there is a mix of UART and InternalRAM or IWC function, the functions might not be performed from left to right. The reason for this is that UART functions are loaded into a UART transmit buffer whereas InternalRAM and IWC functions are loaded into a different function buffer. Due to the nature of UART transmissions, they will take a considerable amount of processor time to complete the function call in comparison to InternalRAM and IWC functions. Therefore, any InternalRAM or IWC function which is part of a multiple function call will most likely be finished prior to any UART function call which is part of the same multiple function call.

Another important point to note is that when functions are loaded into the function buffer, the value of the argument is loaded at that time. Most of the time, this is of no consequence. But, when you have a multiple function call that performs an action on an InternalRAM variable and then later within the multiple function call that same InternalRAM variable is used as an argument for another function, things might not happen in the order that you expect. The reason this is a problem is that the value of the InternalRAM used as the argument is loaded into the function buffer prior to the action taken on that InternalRAM variable. For example, let's say you have a multiple function call that looks like this:

Amulet:InternalRAM.byte(0).inc(),Amulet:InternalRAM.byte(1).setValue(InternalRAM.byte(0))

Most likely, the person who created this multiple function call would expect InternalRAM.byte(0) to be incremented and the result of that increment will be saved into InternalRAM.byte(1). Unfortunately, this will not happen as expected. This is because both functions are loaded into the function buffer at the same time and the value of InternalRAM.byte(0) at that time is loaded as the argument for the second function. So, even though the increment takes place before InternalRAM.byte(1) has the setValue performed on it, the value used to store into InternalRAM.byte(1) is the value of InternalRAM.byte(0) prior to the increment.

Assuming you understand this explanation, the next obvious question is "how do I work around this?" The way to handle this is to use a separate META Refresh tag which will hold the second function call and the new multiple function call will perform a forceHit() on this META. This fixes the problem because the META Refresh's function isn't loaded into the function buffer until after the first function is actually performed. For example, the META Refresh would look like this:

<META http-equiv="Refresh" content="0;URL=Amulet:InternalRAM.byte(1).setValue(InternalRAM.byte(0));NAME=metaSet1">

and the new multiple function call will look like this:

Amulet:InternalRAM.byte(0).inc(),Amulet:document.metaSet1.forceHit() 


Sequenced Function Calls

Control Objects/Widgets can also call sequenced functions by separating the functions by semi-colons. Sequenced functions allow for different function calls at each successive "hit". Sequenced function calls are performed in the order they are entered on the line, from left to right. The sequences continually wrap, so the first sequence follows the last sequence. To illustrate how to use sequenced functions, see the following example. To create a toggle type custom button that invokes an external RPC #5 when toggled down and invokes an external RPC #6 when toggled up, use the following:

<APPLET CODE="CustomButton.class" WIDTH="150" HEIGHT="25" NAME="CustomBtn1">
<PARAM NAME="href" VALUE="Amulet:UART.invokeRPC(5);Amulet:UART.invokeRPC(6)">
<PARAM NAME="buttonType" VALUE="toggle">
<PARAM NAME="upImage" VALUE="myUpImage.gif">
<PARAM NAME="downImage" VALUE="myDownImage.gif">
</APPLET>

Sequenced function calls can also be made up of multiple function calls. There is a limit of 36 different sequences per Control Widget/Object href and each sequence can have a maximum of 36 multiple function calls. To help illustrate this, use the previous example, but instead of invoking RPC #5 for one sequence, and then RPC #6 for another sequence, let's assume we would like the first sequence to invoke RPC #4 and RPC #5, and the second sequence to invoke RPC #6 and RPC #7. To accomplish this, use: Amulet:UART.invokeRPC(4),Amulet:UART.invokeRPC(5);Amulet:UART.invokeRPC(6),Amulet:UART.invokeRPC(7) notice the sequences are separated by the semi-colon, and the multiple function calls are separated by the commas.

Sequenced function calls can be considered a sub-object of a control object. In order to be referenced via IWC, the sequenced function call must be given a name. To accomplish this, use the optional SeqFuncName parameter within the control object. The name specified by the SeqFuncName parameter is the name used within an IWC call to reference the sequenced function call object. The only IWC method applicable for sequenced function calls is the reset() method, which resets the function pointer back to the first function within the sequence.

View Widget Function Calls

View Widgets are used for displaying data. View Widgets include lineplots and bargraphs. View Widget function calls are initiated by either a timer event or the IWC method forceUpdate. The frequency of the timer event is specified by the updateRate parameter. They can only call a single function, and that function must return either a byte, word(2-bytes), or ASCII string. The returned value is used as the input to the View Widget.

Function Call Conventions

Amulet function calls borrow some of it syntax from Java Script, a scripting language used within HTML. Except for hyperlinks to other pages, all Amulet function calls start with "Amulet:". The Amulet: signifies that what follows is an Amulet specific command. If it is desired to hyperlink to another HTML page, then just use the name of the file to link to in the href parameter.

Amulet function calls also borrow concepts from Java, an Object-Oriented Programming(OOP) language. When it is required to interface to an external server, use "Amulet:UART." The UART. can be thought of as a UART object. As in OOP, each object has its own set of data and a set of well-defined interfaces to that data. As in Java, these interfaces are known as methods. Methods are just functions that are specific to a particular object. Each object has its own set of methods.

Examples:  

"Amulet:UART.byte(0).value()"
UART specifies that a serial message will go out the UART.
byte(0) specifies byte variable 0.
value() specifies the value of byte variable 0 is returned.

"Amulet:internalRAM.word(5).setValue(0xF020)"
internalRAM
specifies the dual port RAM onboard the Amulet.
word(5) specifies the internal RAM word variable 5.
setValue(0xF020) specifies internal RAM word variable 5 is to be set to the value 0xF020.

'Amulet:internalRAM.string(5).setValue("Your String")'
internalRAM
specifies the dual port RAM onboard the Amulet.
string(5) specifies the internal RAM string variable 5.
setValue("Your String") specifies that internal RAM string variable 5 is to contain the null terminated string "Your String". Note that the string variable is enclosed within double quotes while the entire function is enclosed within single quotes. For more information regarding string variables, see the note regarding string variables.

The same nomenclature as Java is used, where a method is called by using the object's name followed by the dot operator, followed by the method. Amulet has added a new wrinkle with the concept of multiple byte, word and string variables. Since there can be 256 different byte variables, 256 different word variables and 201 different 19-character string variables, there needs to be a way of specifing the type of variable as well as the variable number. Therefore, if the object is a byte, word, or string variable, the nomenclature is of the following type:
Amulet:object.variable(variable #).method(argument, if needed).
Amulet: specifies an Amulet specific command.
object can be UART or InternalRAM. variable.
variable can be byte, word or string.
variable # can be a number from 0-255 for byte and word variables, and 0-200 for string variables.
method can be any number of methods described in Appendix B.

See example below, where a function button, when pressed, causes a Remote Procedure Call # 5 to be sent out the UART to the external server:

<APPLET CODE="FunctionButton.class" WIDTH="150" HEIGHT="25" NAME="Button1">
<PARAM NAME="href" VALUE="Amulet:UART.invokeRPC(5)">
<PARAM NAME="label" VALUE="test 5">
</APPLET>

The href line invokes the invokeRPC() method on UART. That is, it calls invokeRPC() relative to the UART object. Thus, the call to UART.invokeRPC() causes the UART in the Amulet controller to send out an "invokeRPC" command.

The method invokeRPC() requires an argument (a parameter that is passed to the method that the method uses as its input). As a rule of thumb, the argument passed to any method is the intrinsic value of the calling widget/object. Only Control Widgets/Objects have an intrinsic value. Function buttons can specify an intrinsic value by using <PARAM NAME="buttonValue" VALUE="5"> or by including a number between the ()'s. Widgets that can have multiple intrinsic values, like lists and sliders, must not include a number between the ()'s, since their intrinsic value is dependent upon the state of the widget.

For a list of all available functions, see Appendix B.



Amulet HTMLCompiler,
Copyright © 2000-2006 by
Amulet Technologies, LLC

 
Back to Welcome - Contact Amulet - Amulet Home