Porting Processing Code (algorithmic/ logic business )
Most areas of CLIP development ensure that portability from one hardware platform or configuration is a non-issue, since the circuitry is a logical description of the solution that can be mapped at run-time to any configuration, and the CLIP libraries abstract many of the hardware/operating system calls. Thus a simple re-link with the correct hardware/operating system libraries is all that is required.
However, when the Hardware or Operating System specific features are required in the user processing they need to be abstracted out. To this end CDL provides the Device Object. Device objects allow users to enter code that is hardware/operating system specific. By writing a generic API for the device, portability can be maintained, by simply re-writing the contents of the Device object. The main code need not change.
Porting GUIs
GUI's a special form of output device, fortunately Operating Systems provide a standard API to the graphics cards (they actually provide several APIs, X11, X-Motif, XFree86, PHIGS, DirectX, OpenGL, MFC, etc.) which at least saves the task of writting code for specific graphics cards (think back to the good old days of early games that would only run on specific graphics cards).
However, each Operating System (Windows, MacOS etc) have there own API's.
Abstracting these interfaces is a Holy-Grail of the software industry, many have tried (eg. Qt, wxWidgets, XVT and many others). CLIP does not attempt to address these issues it simply allows circuitry to be embedded in the various GUI applications (or even non-GUI applications), by providing two objects; Callbacks that allow CDL circuits to interface to the GUI and Interfaces that allow GUi's to interface to CDL circuits.
When porting applications between GUIs, the GUI part of the application will probably need to be completely re-written. However, the CDL Interfaces will not as they provide access to the CDL circuitry and encapsulate any access rules for the CDL objects, it is only how they are called in the GUI code that changes.
Callbacks will need to be modified when porting from one GUI to another, but there are a number of ways to minimise the complication:
- Separate GUI logic from Application logic - keep the GUI dumb about how the application works, keep the application dumb as to how the GUI works
Eg. Recorder Controls
Application logic - Recorder can only be in one of several states
- Stopped
- Playing
- Recording
- Play Paused
- Record Paused
- Stopped - error
GUI logic - which buttons are enabled for each system state
Play | Pause | Stop | Record | |
Stopped | Yes | No | No | Yes |
Playing | No | Yes | Yes | No |
Recording | No | Yes | Yes | No |
Play Paused | Yes | No | Yes | No |
Record Paused | No | No | Yes | Yes |
Stopped - error | No | No | Yes | No |
2. Write Callbacks to call Global Functions to pass system state/data to the GUI, thus the callback remains independent of the GUI. The Global Function calls the appropriate GUI Dialog/Widget function.
3. Use Interfaces, when GUIs need to interrogate the application for allowable state/mode transitions etc.. In the recorder example above, it is well understood which states can be entered from any other state. But what 'processing modes' can be selected when the system is replaying recorded data as opposed to live data, or what alarms should be generated in Training mode.
The section on GUI Programming describes the use of Callbacks and Interfaces.