This section is for developers who would like to know how we used the SansGUI Development Environment to create this Unit Conversion for SansGUI utility program. Without any surprise, we spent most of our development time on calculating and entering the unit conversion multipliers and writing this manual.
Because Unit Conversion for SansGUI is designed to handle single value, vector, and matrix unit conversion in one operation, we created Collection, Table, Matrix classes for all the unit dimensions in addition to the unit objects in the Schema Definition.
Collection Reference Classes: implement single value unit conversion for all the unit dimensions in a single unit category; therefore, each unit category occupies one class derived from Class Collection.
Table Reference Classes: implement 1-dimensional array (vector) unit conversion. Each subclass represents one unit dimension and has 6 non-intrinsic attributes, one for each data column. The first column is of In/Out scope to allow users to enter the values. The other 5 columns are for output only. The values are copied from the first column when the user clicks on the Check Data button. The source code of the copy function is listed below. Because the copy operations are the same in all Table derived classes, we created an intermediate Vector class to implement the common copy operation and call this copy routine from all the subclasses.
Matrix Reference Classes: implement matrix unit conversion. Each subclass represents one unit dimension and has exactly one attribute that uses the units in the unit dimension. All the matrix classes are set to have column-major order data storage.
Component Classes: implement switchboards for all unit categories. In each component class, a set of object references are created to let user select and jump to the appropriate reference class easily.
The only code needed is to copy the data vector from the user data column to the other five target columns in Class Table.Vector.<UnitDimension>. All data in the objects are in base units. Because the copy operations of all the <UnitDimension>s are the same, we created the intermediate class Vector to implement a common copy function. Once again, the code sections in red color are manually entered; others are generated by the SansGUI Source Code Framework. We have implemented and tested C/C++ and Fortran versions independently. Source code written in both languages are listed in the following.
/* Table_Vector.c
* - DLL routines for class <Reference>Table.Vector
* DATE: Friday, April 12, 2002 TIME: 01:58:18 PM
* The skeleton of this file is generated by SansGUI(tm)
*/
#include <stdio.h>
#include <memory.h>
#include "SGdll.h"
#ifdef __cplusplus
extern "C"
{
#endif
SG_EXPORT SG_SIM_FUNC SG_xEndEdit_Table_Vector;
SG_EXPORT SG_SIM_FUNC SG_xLoadSize_Table_Vector;
SG_EXPORT SG_SIM_FUNC SG_xLoad_Table_Vector;
#ifdef __cplusplus
}
#endif
/* Macros for attribute indices in class version [1.1.0.0] */
#define SG_NDX_ISIZE 0 /* iSize - Table Size */
#define SG_NDX_ISHEETS 1 /* iSheets - Number of Sheets */
/* Manually added macros for subclass attribute access */
#define SG_NDX_DATA 2 /* Data - User Data */
/* ============================================================
* SG_xEndEdit - End Edit Check
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xEndEdit_Table_Vector(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
INT i, iSize;
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
if (self->iNumVars > SG_NDX_DATA)
{
iSize = sizeof(FLOAT) * self->zValues[SG_NDX_DATA].iSize;
// simply copy data from user data column to all the other columns
for (i = (SG_NDX_DATA + 1); i < self->iNumVars; i++)
memcpy(self->zValues[i].fData, self->zValues[SG_NDX_DATA].fData, iSize);
}
return SG_R_OK;
}
/* ============================================================
* SG_xLoadSize - Resize for Load
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xLoadSize_Table_Vector(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
return SG_R_OK;
}
/* ============================================================
* SG_xLoad - Load Data
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xLoad_Table_Vector(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
return SG_R_OK;
}
The SG_xLoadSize_Table_Vector() and SG_xLoad_Table_Vector() are merely place holders to allow user overriding routines.
The SG_xEndEdit_Table_Vector_<UnitDimension> functions for the <UnitDimension> subclasses implement only one call to the base class function SG_xEndEdit_Table_Vector()with all the parameters passed. For example, in Class Table.Vector.Length, we do
/* ============================================================
* SG_xEndEdit - End Edit Check
* ------------------------------------------------------------
*/
SG_RET_CODE SG_xEndEdit_Table_Vector_Length(SG_OBJ *const self,
SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
SG_OBJ *const refObjs[], const INT *const piRefObjs,
SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
TCHAR *const cMessage, const INT iMsgLen,
TCHAR *const cCommand, const INT iCmdLen,
SG_FILE *const pOutFile )
{
/* TODO: declare your local variables here */
extern SG_RET_CODE SG_xEndEdit_Table_Vector();
if (!SG_IsSchemaOK(self->nSGobjSchema))
return SG_R_SCHM;
/* TODO: put your simulator code here */
/* call the interface function in the base class */
return SG_xEndEdit_Table_Vector(self, simCtrl, chgChild,
refObjs, piRefObjs, adjObjs, piAdjObjs,
lnkObjs, piLnkObjs, cMessage, iMsgLen,
cCommand, iCmdLen, pOutFile );
}
The Fortran 95/90 standard maximum identifier length is 31 and Compaq Visual Fortran (CVF) allows up to 63 characters. We relied on this CVF feature to create this utility program. The longest identifier in the project is 56 characters in length. Besides, we use Project>Settings>Fortran Language>Force Free Form option for the Source Form option in the DLL project.
! Table_Vector.f
! - DLL routines for class <Reference>Table.Vector
! DATE: Friday, April 12, 2001 TIME: 01:58:30 PM
! The skeleton of this file is generated by SansGUI(tm)
! Attribute indices in class version [1.1.0.0]
! 1: iSize - Table Size
! 2: iSheets - Number of Sheets
! ======================================================================
! SG_xEndEdit - End Edit Check
! ----------------------------------------------------------------------
integer function SG_xEndEdit_Table_Vector(self, &
& simCtrl, chgChild, &
& pRefObjs, iRefObjs, &
& pAdjObjs, iAdjObjs, &
& pLnkObjs, iLnkObjs, &
& cMessage, cCommand, pOutFile )
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: SG_xEndEdit_Table_Vector
!DEC$ END IF
include "SGdllf.h"
! TODO: declare your local variables here
real*4, dimension(*) :: UserData
real*4, dimension(*) :: ColumnData
integer :: i, iSize
POINTER(PTR_UserData, UserData)
POINTER(PTR_ColumnData, ColumnData)
integer, parameter :: SG_NDX_DATA = 3
if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then
SG_xEndEdit_Table_Vector = SG_R_SCHM
return
end if
! TODO: put your simulator code here
if (self%iNumVars .gt. SG_NDX_DATA) then
PTR_zValues = self%pzValues
PTR_UserData = zValues(SG_NDX_DATA)%vData
iSize = zValues(SG_NDX_DATA)%iSize
! simply copy data from user data column to all the other columns
do i = SG_NDX_DATA + 1, self%iNumVars
PTR_ColumnData = zValues(i)%vData
call copyDataColumn(UserData, ColumnData, iSize)
end do
end if
SG_xEndEdit_Table_Vector = SG_R_OK
return
end
! ======================================================================
! copyDataColumn - copy data from the user data column to another
! ----------------------------------------------------------------------
subroutine copyDataColumn(fromColumn, toColumn, iLength)
integer :: iLength
intent (in) iLength
real*4, dimension(iLength) :: fromColumn, toColumn
! use Fortran array copying feature
toColumn = fromColumn
return
end
! ======================================================================
! SG_xLoadSize - Resize for Load
! ----------------------------------------------------------------------
integer function SG_xLoadSize_Table_Vector(self, &
& simCtrl, chgChild, &
& pRefObjs, iRefObjs, &
& pAdjObjs, iAdjObjs, &
& pLnkObjs, iLnkObjs, &
& cMessage, cCommand, pOutFile )
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: SG_xLoadSize_Table_Vector
!DEC$ END IF
include "SGdllf.h"
! TODO: declare your local variables here
if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then
SG_xLoadSize_Table_Vector = SG_R_SCHM
return
end if
! TODO: put your simulator code here
SG_xLoadSize_Table_Vector = SG_R_OK
return
end
! ======================================================================
! SG_xLoad - Load Data
! ----------------------------------------------------------------------
integer function SG_xLoad_Table_Vector(self, &
& simCtrl, chgChild, &
& pRefObjs, iRefObjs, &
& pAdjObjs, iAdjObjs, &
& pLnkObjs, iLnkObjs, &
& cMessage, cCommand, pOutFile )
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: SG_xLoad_Table_Vector
!DEC$ END IF
include "SGdllf.h"
! TODO: declare your local variables here
if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then
SG_xLoad_Table_Vector = SG_R_SCHM
return
end if
! TODO: put your simulator code here
SG_xLoad_Table_Vector = SG_R_OK
return
end
The SG_xLoadSize_Table_Vector() and SG_xLoad_Table_Vector() are merely place holders to allow user overriding routines.
The SG_xEndEdit_Table_Vector_<UnitDimension> functions for the <UnitDimension> subclasses implement only one call to the base class function SG_xEndEdit_Table_Vector()with all the parameters passed. For example, in Class Table.Vector.Length, we do
! ======================================================================
! SG_xEndEdit - End Edit Check
! ----------------------------------------------------------------------
integer function SG_xEndEdit_Table_Vector_Length(self, &
& simCtrl, chgChild, &
& pRefObjs, iRefObjs, &
& pAdjObjs, iAdjObjs, &
& pLnkObjs, iLnkObjs, &
& cMessage, cCommand, pOutFile )
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: SG_xEndEdit_Table_Vector_Length
!DEC$ END IF
include "SGdllf.h"
! TODO: declare your local variables here
integer SG_xEndEdit_Table_Vector
if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then
SG_xEndEdit_Table_Vector_Length = SG_R_SCHM
return
end if
! TODO: put your simulator code here
SG_xEndEdit_Table_Vector_Length = &
&SG_xEndEdit_Table_Vector(self, simCtrl, chgChild, &
& pRefObjs, iRefObjs, pAdjObjs, iAdjObjs, &
& pLnkObjs, iLnkObjs, cMessage, cCommand, &
& pOutFile )
return
end
Brownridge, Dennis R. 1994. "Metric in Minutes: The Comprehensive Resource for Learning the Metric System (SI)", Professional Publications, Inc., Belmont, California. ISBN: 0-912045-71-X.
IEEE/ASTM SI 10-1997. "Standard for Use of the International System of Units (SI): The Modern Metric System", IEEE, New York, New York. ISBN: 1-55937-901-4.
Melaragno, Michele. 1991. "Quantification in Science: The VNR Dictionary of Engineering Units and Measures", Van Nostrand Reinhold, New York, New York. ISBN: 0-442-00641-1.
ProtoDesign, Inc. 2002. "SansGUI Version 1.0 Document Set with Version 1.1 Addenda", ProtoDesign, Inc., Bolingbrook, Illinois.
Wildi, Theodore. 1995. "Metric Units and Conversion Charts: A Metrication Handbook for Engineers, Technologists, and Scientists", 2nd Ed., IEEE Press, Piscataway, New Jersey. ISBN: 0-7803-1050-0.
Unit Conversion for SansGUI Version 1.1
Copyright © 2001-2003 ProtoDesign, Inc. All rights reserved.