Chapter 5. Integrating with Cogent Software

Table of Contents

5.1. Callbacks and Cascade DataHub Points

5.1. Callbacks and Cascade DataHub Points

Gamma is an integral part of the rest of Cogent's software. Using Gamma with Photon gives you a way to create GUIs, and then join them quickly and seamlessly with other Cogent tools, such as the Cascade DataHub. Using all these tools together, you can create powerful and reliable applications with substantially less work than it would take in C.

Here is an example, written with about 50 lines of code, that creates a "Talk Box", a simple communications device that uses the Cascade DataHub. It works by writing to and reading a single data point on the Cascade DataHub. As the picture illustrates, the text entered on any Talk Box is sent to every other Talk Box that has access to the same datahub point.

Since this program uses the Cascade DataHub, you must ensure that it is running. If not, start it with this command issued at a shell prompt:

[sh]$  datahub

When the Cascade DataHub is running, enter the command for Talk Box followed by a point name argument, like this:

$ phgamma talkbox.g Name &

Gamma will then run the following code, starting up a Talk Box. To start more Talk Boxes, enter the same command again, with a different Name. Each Talk Box shows its process ID number in the top right-hand corner. To view the Cascade DataHub, press the DataHub Viewer button on any Talk Box.

#!/usr/cogent/bin/phgamma

/*
 * This example loads a Talk Box with a text-entry line for writing,
 * and a multi-text field for reading.  When you enter text, it is
 * sent to the datahub, and then appended to the bottom of the text
 * in the multi-text field for reading.
 *
 * This program should be called from the command line like this:
 *
 * > gamma talkbox.g <Name> &
 *
 * Where <Name> can be any name.  If no name is provided the program
 * will assign the process ID number as the name.
 *
 * First, load the necessary Photon and PhAB files, and initialize Photon.
 */
 
require_lisp("PhotonWidgets.lsp");
require_lisp("PhabTemplate.lsp");
PtInit(nil);

/*
 * Then create a unique name for this Talk Box, based on its node
 * and process ID numbers. This allows multiple Talk Boxes to run
 * simultaneously.
 */
uniq_name = string(getnid(), ".", getpid());

/*
 * Initialize IPC, read the point name from the command line, and
 * register to receive all changes made to the point.
 */
init_ipc(uniq_name, uniq_name);
dhpoint = "";
register_point(#dhpoint);
if (cadr(argv))
  name = cadr(argv);
else name = string(getpid());
princ("Name: ", name, "\n");

/*
 * Read the widget file, create it, and assign symbols to the widgets
 * to be used.
 */
wfile = PhabReadWidgetFile (string(_os_, "-WidgetFiles/wgt/talkbox.wgtw"));
window = PhabCreateWidgets(wfile, nil, nil);

tlkbx = PhabLookupWidget(window,#talkbox,nil);
enttxt = PhabLookupWidget(window,#EntryText,nil);
distxt= PhabLookupWidget(window,#DisplayText,nil);
dhviewbut = PhabLookupWidget(window,#DHviewButton,nil);
sendlab = PhabLookupWidget(window,#SendLabel,nil);
idlab = PhabLookupWidget(window,#IDLabel,nil);
ebut = PhabLookupWidget(window,#TalkboxExitButton,nil);
PtAttachCallback(ebut, Pt_CB_ACTIVATE, #exit_program(1));

/*
 * Make the reader window display-only.
 */
distxt.text_flags = cons(Pt_EDITABLE, nil);

/*
 * Create a function to write the entered text to the datahub
 * and then delete it from the entry widget.
 */
function entry_cb(entry, dhpoint, name, text)
{
  write_point(#dhpoint, string(name, ": ", enttxt.text_string));
  entry.text_string = "";
}

/* Attach a callback to the above function, and another callback 
 * to bring up the datahub viewer when that button is pushed.
 */
PtAttachCallback(enttxt, Pt_CB_ACTIVATE, `entry_cb(@enttxt, @dhpoint, @name, @distxt));		 
PtAttachCallback(dhviewbut, Pt_CB_ACTIVATE, #system("phdhview &"));

/*
 * Create a function to add new text to the display and scroll the
 * display to show the text properly. 
 */
function display_txt(new_text, wgt)
{
  wgt.text_string = string(wgt.text_string, new_text, "\n");
  wgt.multitext_y_scroll_pos = wgt.multitext_num_lines + 2;
}

/* Add an exception function (the display_txt() function) to the
 * datahub point so that when the value changes as a result of other
 * Talkboxes, the text will get displayed.
 */
add_exception_function(#dhpoint, `display_txt(dhpoint, @distxt));

/* Add an echo function (the display_txt() function) to the
 * datahub point so that when the value changes as a result of this
 * Talkbox, the text will get displayed.  The Gamma substr() function
 * is used to remove the name from the text message, and the Gamma
 * string() function is used to add the string "Me: " to the beginning
 * of the substring.
 */
add_echo_function(#dhpoint,
		  `display_txt(string("Me: ", substr(dhpoint, (strlen(name) + 2), -1)),
			       @distxt));

/*
 * Have the labels show the sender and PID number.
 */
sendlab.text_string = string("Sender: ", name);
idlab.text_string = string("Process ID: ", getpid());

PtRealizeWidget(tlkbx);
//PtMainLoop();
while(t) next_event();