Personal tools
You are here: Home / cmgui / Zinc / Program flow for a zinc application

Program flow for a zinc application

Introduction

The code for a zinc application is written using xul and javascript. The layout of the buttons, sliders, scene viewer etc are all specified using xul. The application program logic is written in javascript.

Before writing your own application I suggest looking at a relatively simple application such as the Melanoma example to understand the program flow.

XUL file

First open up the melanoma.xul file in a text editor. Below the window tag there are some script tags to include specified javascript files in the page. When the broswer parses the xul file it simply replaces the script tag by the contents of the javascript file. There is one script tag to include zinc functions from the zinc plugin. There is another script tag to included the javascript for the specific application.

Near the top of the xul file is the window tag. Within this tag an 'onload' variable is initialised. This is the name of the function to call when the window is loaded. For zinc applications the function to call is conventionally called 'init'. This function will be defined in the application javascript file.

Javascript file

Now open up the javascript file melanoma.js. At first glance this file looks complicated and it can be difficult to see how program execution flows. We are hampered by the fact that in javascript if one function calls another, the one it calls must be defined above it. This leads to functions being listed in the file in roughly the reverse order of execution.

It is useful to bear in mind that any function starting with the word zinc is a function that is part of the installed plugin. The rest of the functions called are written by the application developer and placed in the javascript file.

It is also important to realize that the next function to run is often passed as an argument to the current function about to be executed. Once the current function has finished execution it will then call the one that was passed in as an argument.

When the page first loads up a sequence of function calls occur (starting with init) to initialise the zinc application, configure it and set up the scene viewed by the plugin. After that various function calls are triggered by the user clicking buttons, moving sliders, etc.

Init function

Scroll down or search for the init routine. As init is the first function called it checks whether the plugin version is compatible with the application. This is done by specifying the maximum and minimum valid versions and calling the function 'zincCheckValidVersion'. If this routine returns false an error message is generated inidicating the version of zinc is incompatible with this application. If this routine returns true then zinc can now be initalised. This is done by calling the zinc function 'zincInitialise', with the name of the next function to run once zincInitialise has successfully executed. This next function is called CmguiReadyFunction.

CmguiReadyFunction

The CmguiReadyFunction is called from the zincInitialse function. It has the zincCommandData object passed to it as an argument (this object was created by the zincInitialise function). It assigns the zincCommandData object to a global variable so that all the code can access it and then calls the routine while will load all the required data files. For the melanoma example this is called load_skin_files.

Load data files into memory

The load_skin_files function loads all the required data files for the application into memory. This is done assynchronously and it is important that all files are downloaded before program execution continues. To keep track of the number of objects downloaded the function zincCreateDownloadMonitor is used to create a download monitor. When the function is called it is passed the function name of the function to run once all files are downloaded as well as the zincCommandData ojbect. The 'zincDefineMemoryBlock' function is used to specify file names to read into memory and the name they will be referred to once stored in memory. In the case of the melanoma example, once all the files are downloaded to memory the 'setup_skin_files' function is called.

Read files from memory into cmgui

We are now ready to start using cmgui commands and create a scene viewer. Node and element files can be efficiently read from the memory blocks that have been previously created. To create a scene viewer we need to hook it up to the embedded zinc plugin. This is done using the 'zincCreateSceneViewer' function, which requires the plugin element (fetched from the xul), the zincCommandData object and the function to execute after the scene viewer has been created which is called 'scene1ReadyFunction'.

scene1ReadyFunction

Once the scene viewer has been created the sceneViewer object is passed to the scene1ReadyFunction. The scene viewer is now ready to by used so it can be configured by specifying sceneViewer object attributes or by using the executeCommand function, which executes cmgui commands. To use the executeCommand function the zincCommandData object is fetched from the global variable where it was stored.

RunnableFunctionWrapper

Recall that often the next function to run is passed as an argument to the current function about to be executed. In general for this work to work the function passed in needs to be a runnable object. To make a function runnable you can wrap it using the RunnableFunctionWrapper which returns a runnable function. We did not need to this with the zinc functions called as part of initialistion process because they all check if an object is runnable and wrap it if it is not. The RunnableFunctionWrapper definition and its prototype are usually included at the top of the javascript file. When writing your own functions it is usually simpler to wrap the function to be passed in as an argument, rather than getting the called function to check the argument and wrap it if it isn't runnable.