Preview only show first 10 pages with watermark. For full document please download

Sl-gms Examples Manual

   EMBED


Share

Transcript

SL-GMS® Examples Manual SL Corporation® OBJECT-ORIENTED GRAPHICAL MODELING SYSTEM Version 6.2a- 26 May 2006 Part Number EXAM-360526 The information in this document is subject to change without notice and should not be construed as a commitment by the Sherrill-Lubinski Corporation. The Sherrill-Lubinski Corporation assumes no responsibility for any errors that may appear in this document. The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. This software is based in part on the work of the Independent JPEG Group. Symbol Factory TM artwork is licensed from Software Toolbox, Inc. SL-GMS Examples Manual This manual is for use only in connection with the described software and may not be used for any commercial purpose or copied, distributed, sold, displayed, modified, published, or posted in whole or in part without the prior written permission of Sherrill-Lubinski Corporation. SL-GMS, SL Corporation, the SL Logo, and all Sherrill-Lubinski product names referenced in this manual are trademarks or registered trademarks of the Sherrill-Lubinski Corporation; any unauthorized use of these marks is strictly prohibited. All trademarks and registered trademarks referenced in this document are property of their respective companies. SL-GMS (6.2x) 26 May 2006 Configuration: C62a1_360526 Copyright (c) 1987-2006 Sherrill-Lubinski Corporation. All Rights Reserved. LIMITATIONS ON USE Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in the Technical Data - Commercial Items clause at DFARS 252.227-7015, the Rights in Data - General clause at FAR 52.227-14, and any other applicable provisions of the DFARS, FAR, or the NASA FAR supplement. SL Corporation 240 Tamal Vista Blvd., Suite 110 Corte Madera, CA 94925 TECHNICAL SUPPORT Phone 800.548.6881 (inside U.S.) 415.927.8400 Fax 415.927.8401 E-mail [email protected] 5/26/06 v6.2x Table of Contents 1. Overview Goal of the Manual ...................................................................... 1-1 Prerequisites ................................................................................ 1-2 Using SL-GMSTutor to run the examples..................................... 1-3 Manual Structure ......................................................................... 1-4 2. Application & Component Frameworks Framework Portability ................................................................. 2-1 Common SL-GMS Application .................................................... 2-4 ActiveX FrameWork .................................................................... 2-6 JavaBeans Framework.................................................................. 2-11 Motif Framework (Unix).............................................................. 2-15 Win32 Framework (Windows)...................................................... 2-18 MFC - SDI Framework (Windows) .............................................. 2-21 MFC - MDI Framework (Windows) ............................................. 2-23 3. Basic Techniques Creating Windows and Manipulating Models ............................... 3-4 Fundamental Variable Definitions ................................................ 3-13 Handling Events .......................................................................... 3-17 Using a Basic Dialog State .......................................................... 3-21 Creating a Run-time Model .......................................................... 3-24 Simple Zooming/Panning Using a View Manager State ................ 3-28 4. Variable Handling Registering Variables ................................................................... 4-2 Scoping Variables ........................................................................ 4-20 Variable Linkage Techniques ....................................................... 4-31 5. Advanced Use of Dialogs Using GISMOs to Invoke a Dialog State Interface ....................... 5-5 Using an Object Selection State to Invoke a Dialog State ............. 5-9 6. Performance Optimization Introduction ................................................................................. 6-1 User Interaction and Program Architecture .................................. 6-3 Appendix A — Detailed Analysis: myproject_common Introduction ................................................................................. A-1 Execution Options ....................................................................... A-1 Version 6.2a- 26 May 2006 SL-GMS Examples Manual i Source and Model Files ............................................................... A-1 State Tree Diagram ...................................................................... A-2 Source File Analysis .................................................................... A-2 Appendix B — Detailed Analysis: myproject_ax & myproject_vb Introduction ................................................................................. B-1 Source Files ................................................................................. B-1 Properties .................................................................................... B-3 Methods ...................................................................................... B-3 SL-GMS / ActiveX Interface........................................................ B-3 ActiveX and HTML ..................................................................... B-7 ActiveX and Visual Basic ............................................................ B-9 Limitations .................................................................................. B-13 Appendix C — Detailed Analysis: myproject_jb Introduction ................................................................................. C-1 Examples ..................................................................................... C-1 SL-GMS Java Bean...................................................................... C-4 Building a GmsBean demo in Visual Café PDE 2.5 ...................... C-9 Appendix D — Detailed Analysis: myproject_motif Introduction ................................................................................. D-1 Motif Framework ......................................................................... D-1 Motif Framework Source Files ..................................................... D-3 Framework Enhancement ............................................................. D-11 myproject_motif .......................................................................... D-22 Appendix E — Detailed Analysis: myproject_win Introduction ................................................................................. E-1 Win32 Framework ....................................................................... E-1 Win32 Framework Source Files ................................................... E-4 Framework Enhancement ............................................................. E-8 myproject_win ............................................................................. E-20 Appendix F — Detailed Analysis: myproject_mfc_sdi Introduction ................................................................................. F-1 SDI Framework ........................................................................... F-1 Framework Enhancement ............................................................. F-2 Version 6.2a- 26 May 2006 SL-GMS Examples Manual ii Appendix G — Detailed Analysis: myproject_mfc_mdi Introduction ................................................................................. G-1 MDI Framework .......................................................................... G-1 Framework Enhancement ............................................................. G-3 Version 6.2a- 26 May 2006 SL-GMS Examples Manual iii List of Figures Number Title Page Figure 1-1: “SL-GMS Tutor” window .............................................................. 1-3 Figure 2-1: Myproject_common with windtunnel Model ................................. 2-4 Figure 2-2: State Tree diagram for "myproject_common" ............................... 2-5 Figure 2-3: Web Page with SL-GMS ActiveX Control ..................................... 2-6 Figure 2-4: ActiveX Visual Basic Example..................................................... 2-9 Figure 2-5: Java Application Using the SL-GMS Bean ................................... 2-11 Figure 2-6: Applet Using the SL-GMS Bean .................................................. 2-12 Figure 2-7: GmsBeanMain Example ............................................................. 2-12 Figure 2-8: Myproject_motif Example Displaying a Model.............................. 2-15 Figure 2-9: Myproject_motif with a Dynactions Demo Model ......................... 2-17 Figure 2-10: Myproject_win Displaying a Model .............................................. 2-18 Figure 2-11: Myproject_win with a Dynactions Demo Model ............................ 2-20 Figure 2-12: Myproject_mfc_sdi Displaying a Model........................................ 2-21 Figure 2-13: Myproject_mfc_sdi Displaying a Dynactions Demo Model ........... 2-22 Figure 2-14: Myproject_mfc_mdi with Multiple Models .................................... 2-23 Figure 2-15: Myproject_mfc_mdi Displaying Dynactions Demo Models............ 2-25 Figure 3-1: The "main" Model ....................................................................... 3-5 Figure 3-2: State tree when the "basic1" example is first invoked .................. 3-6 Figure 3-3: "Child" and "Sibling" windows and associated State tree diagrams3-7 Figure 3-4: "stack" and "replace" Models with associated State tree diagrams 3-10 Figure 3-5: The “main” Model ....................................................................... 3-14 Figure 3-6: State tree for "basic2" example ................................................... 3-15 Figure 3-7: "window1" and "window2" with associated State tree diagram ..... 3-18 Figure 3-8: User interaction and State tree for "basic4" example ................... 3-22 Figure 3-9: User interaction and State tree for "basic5" example ................... 3-25 Figure 3-10: "zppanel" and "pipeline" Models.................................................. 3-29 Figure 4-1: User interaction and State tree for Variable Registration examples 4-3 Figure 4-2: "Window 1" and "Window 2" with associated State tree diagram.. 4-23 Figure 4-3: User interaction and State tree for “varscope2” example ............. 4-27 Figure 4-4: User interaction and State tree for “dynalloc” example ................ 4-35 Figure 4-5: User interaction and State tree for “Shared Memory” example ..... 4-41 Figure 4-6: User interaction and State tree for "socket" example ................... 4-46 Version 6.2a- 26 May 2006 SL-GMS Examples Manual iv Figure 5-1: User interaction and State tree for "dialog1" example .................. 5-7 Figure 5-2: User interaction and State tree for "dialog2" example .................. 5-10 Figure 6-1: User interaction and State tree for "subcache" example .............. 6-3 Figure A-1 State Tree diagram for "myproject" .............................................. A-2 Figure B-1 Web Page with SL-GMS ActiveX Control ..................................... B-7 Figure B-2 ActiveX Visual Basic Example..................................................... B-9 Figure D-1 Initial Motif-only version of myproject_motif ................................. D-2 Figure D-2 Myproject_motif Help menu ........................................................ D-17 Figure D-3 Myproject_motif About Window ................................................... D-18 Figure D-4 Myproject_motif File Selection Dialog ......................................... D-19 Figure D-5 Myproject_motif with a Dynactions Demo Model ......................... D-23 Figure E-1 Initial Win32-only version of myproject_win ................................. E-4 Figure E-2 Myproject_win with a Dynactions Demo Model ............................ E-21 Figure F-1 SDI Application Produced by AppWizard ..................................... F-2 Figure F-2 About Window Modifications ....................................................... F-4 Figure F-3 Myproject_mfc_sdi Displaying a Dynactions Demo Model ........... F-19 Figure G-1 MFC - MDI AppWizard Application .............................................. G-2 Figure G-2 Myproject_mfc_mdi Displaying Dynactions Demo Models............ G-21 Version 6.2a- 26 May 2006 SL-GMS Examples Manual v Overview Sherrill−Lubinski Goal of the Manual The Enhanced State Management System Library provides over one hundred pre-defined State Classes referred to as States. These States simplify the development of the dynamic display of data and the graphical user interface (GUI) of a real-time application. Each State has a single, well-defined focus, such as managing a drawing area or defining the variables that animate a Model. However, the flexibility of the system allows expansion of the capacity of these functional blocks so that each State can cover a broad range of features which are usually cumbersome to develop. The developer can thus concentrate on building functions unique to the custom application. After much consideration, a few representative States and features were eventually chosen from the large library. The resulting examples establish a solid background in the new State Management System and show how to build the features most commonly needed in the GUI of a real-time application. The examples focus on the functionality to be achieved more than the representation of the real-time process itself. For example, Models are simple enough to be understood quickly without requiring any particular knowledge of the underlying application. These examples can be expanded to create more sophisticated features to meet application challenges. The examples are independent of each other; they can be approached according to the user’s needs. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 1-1 Prerequisites Before starting this manual, the developer must have a rough understanding of SL-GMS, as described in the following table. Important References Topic Manual Chapter State methodology SL-GMS Enhanced State Management System User’s Guide Chapter 2 — Using States to Accelerate Program Development Chapter 4 — The "Myproject" Template Chapter 5 — General Application Development Standard Control Objects SL-GMS Control Object Reference Manual 2 - Native Control Objects Overview SL-GMSDra w Model Building tool SL-GMSDraw User’s Guide 4 - Dynamics Description of available States and their features SL-GMS State Class Library Reference Manual 3 - State Class Descriptions and Features Version 6.2a- 26 May 2006 SL-GMS Examples Manual 1-2 Using SL-GMSTutor to run the examples The SL-GMSTutor program provides easy access to the basic1 through basic6 examples. When the SL-GMSTutor application is invoked, the SL-GMS Tutor window appears, as shown in . Figure 1-1: “SL-GMS Tutor” window Clicking one of the buttons labelled Basic 1 through Basic 6 starts the corresponding application, allowing the user to see and test the first six basic examples described in Chapter 3 — Basic Techniques. The remainder of the examples will be added in the future. Each of the examples may also be invoked by the user from the command line and run by itself in the corresponding work directory. The individual chapters explain how to invoke each of the examples. The name of the SL-GMSTutor executable on a Motif platform is gmstutor_xm; on a 32-bit Windows 1 platform, it is gmstutor_nt. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 1-3 Manual Structure Each of the five chapters in this manual presents a separate case study. Each chapter begins with a general statement of purpose, followed by a summary table which includes the following for each example: • subject • source modules • Models • executables • directory The structure of the manual and the code examples allow for code development in a reasonable time frame. Chapter 1 — Basic Techniques The examples in this chapter provide the tools needed to build a simple application displaying Models driven by simple dynamics. The concepts presented include: • Setting parameters (display connection, graphical context, workstation screen) required by the windowing system in use and creating a window to display and manipulate Models in a codeless way. • Defining basic types of variables to drive the dynamic behavior of Models. • Processing locator/key and window events per Model. • Modifying a data string variable using an SL-GMS Dialog Window and services. • Creating Model parts at run-time. • Zooming and panning a Model in a codeless manner. 1. Refers to a platform with a 32-bit architecture running Mircrosoft Windows NT or Windows 95. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 1-4 Chapter 2 — Application Frameworks This chapter explores the use of SL-GMS within different application development frameworks. • Common SL-GMS Application — Examines the features of the underlying SL-GMS application used by all examples in Chapter 2. • Native Toolkit Examples — Shows how to build a framework for an SL-GMS application using 32-bit Windows and Motif toolkits. • Native Component Examples — Demonstrates how to deliver an SL-GMS application as an ActiveX Control, a Java Bean, or a Netscape Plug-In. Chapter 3 — Variable Handling All three sections of this chapter discuss the management of the variables used to animate Models. • Variable Registration — Focuses on the different methods available to pass a Model’s variable information to the application. Five methods are presented. • Variable Scoping — Concentrates on increasing information retrieval performance by storing the variables in the local variable tables instead of the application. • Variable Linkage — Shows methods to link SL-GMS applications and Models to external sources of data. Such methods demonstrate the use of shared memory, sockets, and dynamic allocation. Chapter 4 — Advanced Use of a Dialog State This chapter gives more insight into the possible use of the SL-GMS Dialog features. Among the most important are how to trigger a dialog popup window with the selection of objects in a Model and how to implement system-dependent and system-independent dialogs. Chapter 5 — Performance Optimization This chapter shows a method to reduce the overhead involved in replicating and freeing the same Model Instance by an application. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 1-5 2 Application & Component Frameworks Introduction This chapter examines the use of SL-GMS in application and component frameworks. Application and component frameworks are both designed to simplify and increase the productivity of software development. An application framework is characterized by a group of functions and/or objects written in a particular programming language that serve as programming building blocks. Examples of application frameworks are the Unix based Motif toolkit and the Microsoft Foundation Class (MFC) library for 32-bit Windows. Component frameworks are characterized by an interface specification that is contained in an Application Programming Interface (API). The goal of a component framework is the construction of reusable software components that can be used by an application, but are defined seperately from the primary application module. Components are typically stored in a Dynamic Link Library (32-bit Windows), or shared library (Unix). The programming language used in the primary application may not be the same as that used to build the components it uses. Examples of component frameworks are Microsoft’s ActiveX and Sun Microsystem’s JavaBeans. A series of examples, known as the myproject examples, are provided with SL-GMS to address the issues related to using SL-GMS in application and component frameworks. The first example in the myproject examples is a simple, standalone application called myproject. The myproject example shows how to use the enhanced State Management System (SMS) to build an application that can display an SL-GMS Model and animate it with data. See the SL-GMS® Enhanced State Management for a complete discussion of the myproject example. An enhanced version of the myproject example called myproject_common serves as the base application for the remaining application and component framework examples. Framework Portability The myproject_common example contains enhancements that make it portable between frameworks. The advantage of this approach is that the Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-1 Application & Component Frameworks SL-GMS functionality of the application is not recreated for each framework. Therefore, a high degree of code reuse is obtained with access to the unique features of each framework. Investment in SL-GMS is preserved and enhanced with the ability to quickly produce applications that take advantage of current and future frameworks. The example applications that demonstrate the use of SL-GMS within application and component frameworks are listed in the table below. Myproject Examples Description Directory Section The SL-GMS application common to all application framework examples. myproject_common page 2-4 Motif example myproject_motif page 2-6 Win32 example myproject_win page 2-18 MFC Single Document Interface example myproject_mfc_sdi page 2-21 MFC Multiple Document Interface example myproject_mfc_mdi page 2-23 ActiveX / web page example myproject_ax page 2-6 ActiveX / Visual Basic example myproject_ax_vb page 2-9 JavaBeans example myproject_jb page 2-11 Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-2 Application & Component Frameworks Each directory includes the appropriate "Makefile" that is used to build the application and link it to the SL-GMS run-time libraries. To build an application in one of the working directories type: make on Unix platforms or nmake on 32-bit Windows platforms. Each directory also includes a README files that contains a list of the directory’s contents and instructions for building and running the application. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-3 Application & Component Frameworks Common SL-GMS Application The myproject_common example defines the SL-GMS features that are common to all of the myproject examples. It is an enhanced version of the myproject example. The enhancements include additional methods that extend myproject for use within frameworks. Typically, the window in which an SL-GMS Model is displayed is created by the framework, not by SL-GMS. So, myproject_common contains methods that are used by the framework to pass in the appropriate window handle. The framework also manages the application event loop. Since SL-GMS needs access to events related to the window that displays the Model, myproject_common contains methods and functions that allow the framework to forward the appropriate events to SL-GMS. For a detailed analysis of the myproject_common example, see Appendix A. Figure 2-1: Myproject_common with windtunnel Model Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-4 Application & Component Frameworks The myproject_common example displays an SL-GMS Model in a window. The Model to display and the data update rate are passed as command line arguments to the application. For simplicity, two Models called windtunnel and mymodel are used in all myproject examples. The data generation functions contained in the myproject_common example generate data for both Models. Figure 2-1: shows the myproject_common example running the windtunnel Model. It is also important to note that applications based on myproject_common can also display any SL-GMS Model that is animated by a data generation file (.dat file) such as those found in the dynactions demo directory. State Tree Diagram When myproject_common is executed, the State tree shown in Figure 2-2: is created. Custom Top State Standard Top State Standard Backplane WinModState windtunnel Figure 2-2: State Tree diagram for "myproject_common" The State tree shown above is also created within the SL-GMS portion of each framework example since they include source modules from myproject_common. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-5 Application & Component Frameworks ActiveX FrameWork ActiveX components are based on Microsoft’s COM (Component Object Model). COM defines how objects expose themselves for use within other objects and how objects communicate between processes and across a network. COM allows ActiveX controls to support two-way communication from the control to the client application. This enables the control to notify the client of events or invoke a method or event. It also enables the client to communicate directly with the control. SL-GMS ActiveX Control The SL-GMS ActiveX control, "myproject_ax.ocx", is based on the SL-GMS myproject_common example, which is a portable, standalone application that displays a Model with real-time animation driven by simulated data. The myproject_common example is then connected to the ActiveX interface so it can function as an OLE control class. Figure 2-3: Web Page with SL-GMS ActiveX Control Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-6 Application & Component Frameworks The SL-GMS ActiveX control can be used with any application that can function as an OLE container. The MS Internet Explorer browser is one such application. MS Visual Basic and Visual C++ applications can also be configured to serve as OLE containers which can make use of the SL-GMS ActiveX control. Properties The SL-GMS ActiveX control has one property: 1. modelname -- Defines the name of the SL-GMS Model file to display in the control. It can contain a drive letter and path. The modelname property can be used to configure the control to display Models located on any drive accessable to the system running the control. Methods The SL-GMS ActiveX control provides the following methods: 1. SendStateMessage - This method is used to communicate to the underlying SL-GMS application. 2. CloseModel - This method is used to close the Model. 3. GetWinModName - This method is used to query the name of the WinModState that manages the Model displayed. 4. SetModelname - This is the “set” method for the modelname property. It displays the specified Model in an existing window. 5. GetModelname - This is the “get” method for the modelname property. It returns the name of the current Model. ActiveX and HTML The myproject_ax directory contains an HTML page for use with web browsers that support ActiveX controls. The content of the HTML page is shown below. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-7 Application & Component Frameworks SL-GMS ActiveX Demo
Where • OBJECT -- This tag is used to embed the ActiveX control in the web page. • ID -- This attribute defines a name for the control instance • WIDTH -- Defines the width in pixels of the window that the browser creates for the control • HEIGHT -- Defines the height in pixels of the window that the browser creates for the document. • CLASSID -- A unique identifier for the control • PARAM -- This attribute is used to specify the name and value of parameters that are passed to the control. CODEBASE The CODEBASE attribute of the OBJECT tag is not used because the location of the SL-GMS ActiveX control is defined in the system registry when the demo is installed and built. When viewed in MS Internet Explorer the sample HTML page appears as shown in Figure 2-3:. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-8 Application & Component Frameworks ActiveX and Visual Basic The ActiveX Visual Basic example, myproject_ax_vb, uses the same SL-GMS ActiveX control as the HTML example. While the HTML example only used the control’s modelname property, the Visual Basic example adds use of the control’s SendStateMessage method to control the underlying SL-GMS application. The Visual Basic example uses ComboBoxes and CommandButtons to interface with the control’s features. The buttons and code provided demonstrate how to configure the Enhanced State Management System’s View Manager, how to change the update period of the SL-GMS application, how to interactively change the current Model, and how to perform zoom and pan operations with the View Manager. Figure 2-4: ActiveX Visual Basic Example User Interface The Form used by the Visual Basic example contains three CommandButtons, four ComboBoxes, one Label, and one Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-9 Application & Component Frameworks instance of the SL-GMS ActiveX control. The ComboBox at the top of the form is used to select a data update rate. The three ComboBoxes on the right side of the form are used to select the SL-GMS Model displayed by the SL-GMS ActiveX control. See Appendix B for a detailed analysis of the SL-GMS ActiveX control. Limitations • SL-GMS ActiveX not certified The SL-GMS ActiveX object is not yet officially certified by a registration firm. This means that to view this object locally or on the Internet, the security settings on the MS Internet Explorer must be set to accept downloads of all ActiveX objects: settings are safety level = NONE. • SL-GMS environment Clients must have SL-GMS installed and GMS_HOME defined as a system environment variable. • MS Visual C++ 4.2 DLLs The SL-GMS ActiveX object relies on specific MS Visual C++ 4.2 DLLs. Without the runtime DLLs being present on the client's system path, it will not operate. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-10 Application & Component Frameworks JavaBeans Framework JavaBeans is a product of Sun Microsystems, Inc. According to Sun’s JavaBeans FAQ, "JavaBeans is a portable, platform-independent component model written in the Java programming language, developed in collaboration with industry leaders." A component in the JavaBeans model is known as a Bean. JavaBeans Example (Windows) The SL-GMS JavaBeans example for Windows, myproject_jb, is based on the myproject_common example which is a portable, stand alone application that displays a Model with real-time animation driven by simulated data. The myproject_jb directory contains several examples that use the SL-GMS Bean. The first example is a Java application which is defined in the file "MyProjectJavaBean.java." MyProjectJavaBean is shown in Figure 2-5:. . Figure 2-5: Java Application Using the SL-GMS Bean The second example is an applet which is defined in the file "GmsBeanApplet.java." The applet example is shown in Figure 2-6: running in Netscape Navigator. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-11 Application & Component Frameworks . Figure 2-6: Applet Using the SL-GMS Bean Figure 2-7: GmsBeanMain Example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-12 Application & Component Frameworks The third example is an application called GmsBeanMain that uses two instances of GmsBean as shown in Figure 2-7:. The GmsBeanMain example uses additional Java datasource beans as well as additional standard beans. The SL-GMS Bean The SL-GMS Bean, "GmsBean.class", is a Bean which displays and animates an SL-GMS Model. It can be used directly in any application or applet that can include JavaBeans, or it can be studied as an example of a Java Bean that incorporates an SL-GMS application. There are two major parts to the SL-GMS Bean. The first part is the Java classes that define the Bean. The second part is a Dynamic Link Library (DLL) that contains the C and C++ modules that define the SL-GMS application, and the modules that integrate the SL-GMS application with the bean. The Java code executes functions in the DLL through the Java Native Interface. Properties The SL-GMS Bean has three properties, which can be set either in the Property Sheet at design time, or by sending a message (e.g. from a text edit field or a button) at run time. 1. modelName A String containing the name of the SL-GMS Model to be displayed. It can contain a drive letter and path. 2. gmsDataSource A boolean flag. If gmsDataSource is true, all GmsBeans in the application will use SL-GMS datasources. If gmsDataSource is false, external datasources will be used. 3. gmsEventDelay The SL-GMS thread event loop delay, in milliseconds. The Java Bean executes SL-GMS native functions in a single thread, which polls for events that require SL-GMS functionality. This thread sleeps for 'gmsEventDelay' milliseconds when its event queue is empty. External Datasources Following the JavaBeans API, a GmsBean can receive data variables and values in a PropertyChange event. Sample Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-13 Application & Component Frameworks Datasource beans, written in Java, are supplied to demonstrate the GmsBean and to show how a data source interacts with a GmsBean. If Datasource beans are used, the gmsDataSource property should be set false. The two sample GmsDataSource beans have been specifically coded to provide data to animate certain SL-GMS models. The class DataSourceW systematically generates dynamic variable data for the SL-GMS Model windtunnel.m1, while the class DataSourceDyn generates random data for the models in the directory demo/dynactions of the SL-GMS distribution system. The DataSource beans are coded completely in Java, and are intended to be examples of the type of data source that feeds data to GmsBeans. They define and assign values to the variables used in the models. At timed intervals they generate new data values and fire a PropertyChange event that contains the variable names and values. GmsBeans and other objects can register as listeners and thus be informed each time that new data values are generated. Multiple SL-GMS Java Beans An application can contain any number of GmsBeans, each displaying the same or a different SL-GMS Model, and each listening to the same or different DataSource beans. Visual Application Builder The GmsBean can be used in a visual application builder, such as Symantec's Visual Café, on either Windows NT, Windows 95, or Sun Solaris. It is placed in the builders's component library, and, like any Java Bean, dragged to the designer work area and hooked up to other beans. For a detailed analysis of the JavaBeans examples, and tutorial exercises for building them, see Appendix C. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-14 Application & Component Frameworks Motif Framework (Unix) The Motif framework example, myproject_motif, is based on the myproject_common example which is a portable, stand alone application that displays an SL-GMS Model with real-time animation driven by simulated data. Figure 2-8: shows myproject_motif displaying the Model mymodel. Figure 2-8: Myproject_motif Example Displaying a Model Motif Framework The Motif framework provides the following basic application features: 1. A main window containing a menu bar and a drawing area. 2. A menu bar with selections for • Application termination • Activation of a file selection browser • Activation of an "About" window Framework Enhancements The Motif framework enhancements for SL-GMS include: Command Line Processing The SL-GMS data update rate and an SL-GMS Model file can be specified on the command line. Main event loop selection is also provided from the command line. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-15 Application & Component Frameworks Model Selection The Motif XmFileSelectionDialog widget is used to select an SL-GMS Model file once the application is running. SL-GMS Initialization Proper initialization of SL-GMS within the Motif framework is illustrated. Utilization of myproject_common The files in the myproject_common directory define the SL-GMS functionality that allows the application to: • Create the initial SL-GMS State hierarchy • Display the specified SL-GMS Model in the drawing area window created by the application • Generate data for the SL-GMS Model • Use an SL-GMS Model in the "About" window Event Processing Three main event loops are provided that show how to pass events to SL-GMS from the Motif framework. 1. The standard SL-GMS event loop provided in the function gmsRunMainLoop( ). 2. A simple user-defined event loop example in which SL-GMS controls timer events. 3. An advanced user-defined event loop that shows how to • Initiate and control timeouts for SL-GMS dynamic updates • Pass events to SL-GMS • Configure the event loop as a blocking event loop • Configure the event loop to execute a specified "work" function during idle time after all pending events have been processed. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-16 Application & Component Frameworks Figure 2-9: Myproject_motif with a Dynactions Demo Model For a detailed analysis of myproject_motif, see Appendix D. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-17 Application & Component Frameworks Win32 Framework (Windows) The Win32 framework example, myproject_win, is based on the myproject_common example which is a portable, stand alone application that displays an SL-GMS Model with real-time animation driven by simulated data. Figure 2-10: shows myproject_win displaying the Model mymodel. Figure 2-10: Myproject_win Displaying a Model Win32 Framework The Win32 framework provides the following basic application features: 1. A main window containing a menu bar and a drawing area. 2. A menu bar with selections for • Application termination • Activation of a file selection browser • Activation of an "About" window Framework Enhancements The Win32 framework enhancements for SL-GMS include: Command Line Processing The SL-GMS data update rate and an SL-GMS Model file can be specified on the command line. Main event loop selection is also provided from the command line. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-18 Application & Component Frameworks Model Selection The native Win32 file selection browser is used to select an SL-GMS Model file once the application is running. SL-GMS Initialization Proper initialization of SL-GMS within the Win32 framework is illustrated. Utilization of myproject_common The files in the myproject_common directory define the SL-GMS functionality that allows the application to: • Create the initial SL-GMS State hierarchy • Display the specified SL-GMS Model in the drawing area window created by the application • Generate data for the SL-GMS Model • Use an SL-GMS Model in the "About" window Event Processing Three main event loops are provided that show how to pass events to SL-GMS from the Motif framework. 1. The standard SL-GMS event loop provided in the function gmsRunMainLoop( ). 2. A simple user-defined event loop example in which SL-GMS controls timer events. 3. An advanced user-defined event loop that shows how to • Initiate and control timeouts for SL-GMS dynamic updates • Pass events to SL-GMS • Configure the event loop as a blocking event loop • Configure the event loop to execute a specified "work" function during idle time after all pending events have been processed. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-19 Application & Component Frameworks Figure 2-11: Myproject_win with a Dynactions Demo Model For a detailed analysis of myproject_win, see Appendix E. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-20 Application & Component Frameworks MFC - SDI Framework (Windows) The MFC - SDI framework example, myproject_mfc_sdi, can also display a single SL-GMS Model as shown in Figure 2-12:. Figure 2-12: Myproject_mfc_sdi Displaying a Model The SDI framework provides the following basic application features: 1. A main window containing a menu bar and a drawing area. 2. A menu bar with selections for • Application termination • File selection browser • Activation of an "About" window The SDI framework enhancements for SL-GMS include: 1. Command line processing for data update rate and SL-GMS Model file specification. 2. Selection of an SL-GMS Model file using the native file selection browser. 3. Initialization of SL-GMS 4. Use of the files from myproject_common to • Create the initial SL-GMS State hierarchy • Display the specified SL-GMS Model in the drawing area window created by the application Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-21 Application & Component Frameworks • Generate data for the SL-GMS Model 5. Use of the files from the mfc_common directory which provide data structures and classes that facilitate integration of SL-GMS into MFC applications. Figure 2-13: Myproject_mfc_sdi Displaying a Dynactions Demo Model For a detailed analysis of myproject_mfc_sdi, see Appendix F. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-22 Application & Component Frameworks MFC - MDI Framework (Windows) The MFC - MDI framework example, myproject_mfc_mdi, can display multiple SL-GMS Models as shown in Figure 2-14:. Figure 2-14: Myproject_mfc_mdi with Multiple Models The MDI framework provides the following basic application features: 1. A main window containing a menu bar and a drawing area. 2. A menu bar with selections for • Application termination • File selection browser • Activation of an "About" window Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-23 Application & Component Frameworks The MDI framework enhancements for SL-GMS include: 1. Command line processing for data update rate and SL-GMS Model file specification. 2. Selection of an SL-GMS Model file using the native file selection browser. 3. Initialization of SL-GMS 4. Use of the files from myproject_common to • Create the initial SL-GMS State hierarchy • Display the specified SL-GMS Model in the drawing area window created by the application • Generate data for the SL-GMS Model 5. Use of the files from the mfc_common directory which provide data structures and classes that facilitate integration of SL-GMS into MFC applications. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-24 Application & Component Frameworks Figure 2-15: Myproject_mfc_mdi Displaying Dynactions Demo Models For a detailed analysis of myproject_mfc_mdi, see Appendix G. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 2-25 3 Basic Techniques Purpose The following examples show how to create the features that make up the framework of any application using SL-GMS. These basic techniques include: • creating windows and manipulating Models • defining variables attached to Models to be displayed • creating custom input-event handlers • creating a simple dialog State • creating a Model at run-time • simple zooming/panning Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-1 Basic Techniques The table below provides the location of each example, as well as the modules and Models that comprise it. Basic Technique Directory Module Model file Section Creation of Windows and Manipulation of Models basic1 basic1.c basic1_top.c main.m1 child.m1 sibling.m1 stack.m1 stack2.m1 replace.m1 about.m1 page 3-4 Fundamental Variable Definitions basic2 basic2.c basic2_top.c basic2_ds.c main.m1 about.m1 page 3-13 Event Handling basic3 basic3.c basic3_top.c evt_st.c window1.m1 window2.m1 about.m1 page 3-17 Basic Usage of DialogState basic4 basic4.c basic4_top.c basic4_ds.c basic4_dsmgr.c main.m1 basicTypes.m1 about.m1 page 3-21 Run-time Model Creation basic5 basic5.c basic5_top.c basic5_ds.c main.m1 template.m1 about.m1 page 3-24 Zooming and Panning Using a WinModState basic6 basic6.c basic6_top.c basic6_ds.c zppanel.m1 pipeline.m1 about.m1 page 3-28 The name of the executable on a Motif platform is _xm (e.g., basic1_xm, basic2_xm, and so on); on a Windows NT platform, it is _nt (e.g., basic1_nt, basic2_nt, and so on). Each example displays an About This Example window which is an online summary. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-2 Basic Techniques In addition, each of the basic1 through basic6 directories includes the appropriate "Makefile" that is used to build the application and link it to the SL-GMS run-time libraries. To build an application in one of the working directories type: make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-3 Basic Techniques Creating Windows and Manipulating Models Purpose This example shows how to create windows and manipulate Models in a codeless way, using only State messages sent as a result of activation of Native Control Objects. 1 Specifically, it shows how to: • invoke a new window displaying a Model as a child or as a sibling of the window that receives the input event • overlay Models in the same window • replace an existing Model in a window with a new one Source and Models Module/Model file Description basic1.c Main routine basic1_top.c Defines the custom Top State main.m1 main Model displayed when the application is invoked child.m1 Model displayed by the New Window (child) button in the main Model sibling.m1 Model displayed by the New Window (sibling) button in the main Model stack.m1 Model displayed by the Stack button in the main Model stack2.m1 Model displayed by the Stack 2 button in the stack Model replace.m1 Model displayed by the Replace button in the main Model about.m1 Online summary of the example 1. Further information is provided in the section entitled Native Control Objects Overview in the SL-GMS Control Object Reference Manual. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-4 Basic Techniques User Interaction and Program Architecture When the application is invoked, the main Model appears, as shown in Figure 3-1:. Figure 3-1: The "main" Model The main Model has four Button Control Objects, shown in Figure 3-1:, each of which sends a standard message to a State. Methods Used by Buttons in the "main" Model Reference State Button Standard Method Purpose New Window (child/sibling) new_model_window Creates a Window Model State with user-specified attributes. Window Model State Stack stack_model Creates a Model State with user-specified attributes. Model State Replace model_name Replaces the Model displayed by a Model State. Window Model State Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-5 Basic Techniques State Tree Diagram When the application is invoked, the State tree is created, as shown in Figure 3-2:. Custom Top State Standard Top State Standard Backplane WinModState main Figure 3-2: State tree when the "basic1" example is first invoked NOTE: For this example, the custom Top State has been created only for modularity. This State has only standard attributes and standard methods. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-6 Basic Techniques Creating a Separate Window to Display a Model The New Window (child) button creates a child window of the window that displays the main Model. This child window displays the child Model. The New Window (sibling) button creates a sibling window of the window that displays the main Model. This sibling window displays the sibling Model, as shown in Figure 3-3:. Standard Backplane WinModState main WinModState child child Model Standard Backplane WinModState WinModState main sibling sibling Model Figure 3-3: "Child" and "Sibling" windows and associated State tree diagrams Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-7 Basic Techniques The Renamed Variables for the New Window (child) and New Window (sibling) Buttons in the main Model both send the same message (msg_strmsg) to the same State (msg_statename); however, the value sent with the message differs. Messages and Values Sent by the "New Window" Buttons Renamed Variables Button msg_state name1 msg_strmsg value2 New Window (child) NULL "new_model_window" "child\twin_position 0.5 0.5" New Window (sibling) NULL "new_model_window" "sibling +\twin_position 0.5 0.0" 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. 2. "\t" is the separator between each message-value pair Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-8 Basic Techniques The "Parent State" portion of the value string determines whether the new window is a child or sibling of the window that displays the main Model. Description of the "value" String Parent State1 (SuperState) Model name State name2 Window position Result child NULL NULL 0.5 0.5 Window Model State is created under the current State that displays the main Model sibling + NULL 0.5 0.5 Window Model State is created under the Backplane State 1. A value of NULL is equivalent to "the State that receives the message"; + is equivalent to "use the direct parent State of the State that receives the message." However, the NULL value does not need to be included in the value string, as it is the default. 2. A value of NULL is equivalent to "system generated." However, the NULL value does not need to be included in the value string, as it is the default. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-9 Basic Techniques Stacking and Replacing Models in the Same Window The Stack Button of the main Model stacks the Models. The new Model displayed is stack, as shown in Figure 3-4:. NOTE: This stacking behavior can continue as long as system memory allows. Stacking functionality displays a new Model in a window while maintaining the dynamic updating of the previous Model. The Replace button replaces the Model displayed in the window-manager window. The new Model displayed is replace, as shown in Figure 3-4:. Standard Backplane WinModState main ModelState stack stack Model ModelState stack2 Clicking the Stack 2 button invokes another ModelState that displays the stack2 Model Standard Backplane WinModState replace replace Model Figure 3-4: "stack" and "replace" Models with associated State tree diagrams Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-10 Basic Techniques Both the Renamed Variables for the Stack and Replace buttons in the main Model send a standard message to the Window Model State. Messages and Values Sent by the "Stack"and "Replace" Buttons Renamed Variables Button msg_statename1 msg_strmsg value Stack NULL "stack_model" "stack" Replace NULL "model_name" "replace" 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. Description of the "value" String Model name Parent State1 (SuperState) stack NULL NULL Model State created under the current State that displays the main Model replace NULL NULL Replace the Model displayed by the Window Model State State name2 Result 1. A value of NULL is equivalent to "the State that receives the message." However, the NULL value does not need to be included in the value string, as it is the default. 2. A value of NULL is equivalent to "system generated." However, the NULL value does not need to be included in the value string, as it is the default. The Stack 2 button in the stack Model sends a "stack_model" message with a value of "stack2" to the Window Model State. A Model State displaying Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-11 Basic Techniques the stack2 Model is invoked as a SubState of the Model State displaying the stack Model. Messages and Values Sent by the "Stack 2" Button Renamed Variables Button Stack 2 msg_statename NULL Version 6.2a- 26 May 2006 msg_strmsg "stack_model" value "stack2" SL-GMS Examples Manual 3-12 Basic Techniques Fundamental Variable Definitions Purpose This example shows the definition of basic data types using the Data Source Model State (DsModelState). These are: • Integer • Real • String • String Array All variables are known beforehand and are statically declared. This example also illustrates how to update the variable types by: • input-event (User Interaction) • timer-event (Program Update) Source and Models Module/Model file Description basic2.c Main routine basic2_top.c Defines the custom Top State basic2_ds.c Defines the custom data handlers main.m1 main Model displayed when the application is invoked about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-13 Basic Techniques User Interaction Figure 3-5: is the display seen when the application is running. Figure 3-5: The “main” Model The two sections of the Model, “User Interaction” and “Program Updating,” are described below and in the About This Example window. User Interaction The User Interaction section includes two Scale Control Objects and a Text Edit Box Control Object displaying the default value of an integer, a real, and a string variable. The integer and real data types can be modified by using the Scale Control Objects. The string data type is modified using the Text Edit Box Control Object by typing the new value of the variable and pressing or clicking another object. The string variable can also be updated by selecting a string from the list of strings in the Text List Box shown at the bottom of the Model. Any update of these variables (integer, real, or string) is displayed in the text rectangle shown to the right of each item. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-14 Basic Techniques Program Updating Program Updating uses three Text Filled Rectangles whose attached dynamics display the value of integer, real, or string variables updated by the code according to a timer-event. Program Architecture Figure 3-6: shows the program architecture in terms of the States built by the code. Custom Top State Standard Top State DsModelState vardefs attached to Custom Top State Standard Backplane WinModState main Figure 3-6: State tree for "basic2" example The DsModelState is Instanced as a SubState of the Custom Top State and the Variable Definitions (vardefs) have been attached to the Custom Top State. Attaching the vardefs to the Custom Top State creates "global variables," which allow every State in the State tree (below the Custom Top State) to reference the value of these variables. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-15 Basic Techniques Attaching the vardefs to a particular State is performed in the user_activate_fctn( ) function, in the "basic2_ds.c" file. The user_activate_fctn( ) function is passed the variable vardef_state. user_activate_fctn (state, vardef_state, ds_string, mydataptrptr) The variable vardef_state is set when the DsModelState Instance is invoked in "basic2_top.c". In this example, the "vardef_statename" message passed with the value top_state_name sets the vardef_state variable passed to user_activate_fctn( ) equal to the id of the Custom Top State.2 /* get name of custom Top State */ top_state_name = gmsQStName(state); /* invoke a Data Source Model State under the Top State */ STINVOKE("data_source","DsModelState", top_state_name, "vardef_statename",top_state_name,0 ); In "basic2_ds.c" the following function defines the variables. gmsStVarDefineChanged(state, name address, type, count, size); If an integer variable, var_i, is defined with this function using the vardef_state variable passed to user_activate_fctn( ), then the vardef is attached to the Custom Top State Instance, thereby creating a "global variable". gmsStVarDefineChanged(vardef_state, "var_i", &var_i,G_INTEGER, 1, 1); 2. Sending the "vardef_statename" message when invoking the DsModelState Instance allows the user to set the value of vardef_state. If the "vardef_statename" message is not sent when invoking the DsModelState Instance, SL-GMS automatically sets the value of the vardef_state variable equal to the id of the SuperState of the DsModelState Instance. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-16 Basic Techniques Handling Events Purpose This example shows how to build the custom Event State to catch any locator, key, or window events allowed by SL-GMS and occurring in a Workstation/Window object. Two Instances of the same Event State are used to capture events in two different windows. Source and Models Module/Model file Description basic3.c Main routine basic3_top.c Defines the custom Top State only for modularity purposes. evt_st.c Custom Event State that defines all possible methods/event handlers window1.m1 Top Model where the event will take place window2.m1 Bottom Model where the event will take place about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-17 Basic Techniques User Interaction and Program Architecture When the application is invoked, two windows are created displaying the Models window1 and window2, as shown in Figure 3-7:. These two Models include two Text Edit Rectangle GISMOs, both with the same input dynamics. Standard Backplane WinModState window1 Custom Event State WinModState window2 Custom Event State Figure 3-7: "window1" and "window2" with associated State tree diagram The top Text Edit Rectangle (named "tedit1" in window1 and "tedit2" in window2 using SL-GMSDraw) has been defined in the code as being the object that will "echo" any Character Event generated by the user in the window (refer to the activate method in the file "basic3_top.c", and to the "tedit_obj_name" method in the file "evt_st.c"). Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-18 Basic Techniques After SL-GMS determines in which State Instance the event occurred based upon the State’s Workstation/Window, the event is passed to the custom State Class method for that type of event. When the application is invoked, the Text Edit Rectangles named "tedit1" and "tedit2" are highlighted. 3 Any characters that are typed in window1 will automatically appear in "tedit1" and any characters typed in window2 will automatically appear in "tedit2". NOTE: All characters are displayed in the top and bottom Text Edit Rectangles as capital letters. The "key_filter" method in "evt_st.c" converts all lower case letters to upper case. Selecting the bottom Text Edit Rectangle sets it to be the one that captures and displays the Character Events. When the bottom Text Edit Rectangle object is selected, its frame is highlighted. It keeps the focus until the top Text Edit Rectangle is selected again. The GISMO actions responsible for the behavior of the top and bottom Text Edit Rectangles, and included in the object’s Dynamic Properties,4 are: • gms_textentry_var( ) • gms_hilite_edge_selobj( ) All events, including Character Events, are printed in the window from which the demo was invoked after having been processed by the Event States. 3. At present, two problems occur with this example: 1) when the application is first invoked, the top Text Edit Rectangle should be highlighted but it is not; and 2) when changing window focus, the Text Rectangle in the previous window remains highlighted (i.e., the Text Edit Rectangle in the previous window should become unhighlighted, and the Text Edit Rectangle that has focus in the current window should become highlighted, but it doe s not). Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-19 Basic Techniques The output messages are displayed in the following formats: Event Description Output Message Format locator locator press/ release/ motion 1) method in "evt_st.c" being executed 2) name of the State that receives the event 3) mouse button in use 4) internal coordinates of the locator event 5) button that triggers the event 6) combination of other keys and buttons pressed simultaneously character key press/ release filter 1) method in "evt_st.c" being executed 2) name of the State that receives the event 3) the code of the key in use 4) combination of other keys and buttons pressed simultaneously window window expose/ focus in or out/ destroy 1) method in "evt_st.c" being executed 2) name of the State that receives the event window resize 1) method in "evt_st.c" being executed 2) name of the State that receives the event 3) window extent 4) the SL-GMS Viewport extent window enter or leave 1) method in "evt_st.c" being executed 2) name of the State that receives the event 3) the State’s Workstation/Window The following example shows the output message for a "window expose" Event: state: window1_EventState 4. The Appendix entitled in SL-GMS GISMO Library Reference in the SL-GMS Reference Manual provides additional information. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-20 Basic Techniques Using a Basic Dialog State Purpose This example illustrates the use of a Dialog State to edit strings. It also shows how to build a system-independent dialog Model. Source and Models Module/Model file Description basic4.c Main routine basic4_top.c Defines the custom Top State basic4_ds.c Defines the custom data handlers basic4_dsmgr.c Simple dialog manager for editing strings main.m1 main Model displayed when the application is invoked basicTypes.m1 Dialog interface window about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-21 Basic Techniques User Interaction and Program Architecture A custom Top State is created at the top of the tree to hold the definition of a custom method “invoke_dialog” that is responsible for the installation of a Dialog State in the occurrence of an input event. Custom Top State Standard Top State DsModelState Vardefs attached to Top State Standard Backplane WinModState main main Model Custom Dialog Manager State Dialog State Pressing the Invoke Dialog to Change Data button displays a window which allows editing of a string, integer, or real data variable. basicTypes Model Figure 3-8: User interaction and State tree for "basic4" example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-22 Basic Techniques Clicking the Invoke Dialog to Change Data button invokes a Dialog Box. When clicked, this Button Control Object sends a message to the custom Top State that then invokes an Edit Dialog State under the Dialog Manager State. A dialog window is then displayed that allows editing of a string, integer, or real data variable. The Dialog Interface Model displays a copy, in Text Edit Boxes, of the value of the string, integer, and real data variables. It includes three push buttons: • Apply button — Overwrites the value of the variables displayed by objects in the main Model with the newly-edited copy. The old values are lost. • Reset button — Overwrites the edited copy of the value of the variables shown in the Text Edit Boxes with a copy of the last value “applied”, that is, as they were before being edited. • Close button — Closes the dialog interface window. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-23 Basic Techniques Creating a Run-time Model Purpose This example shows how to dynamically add properly initialized parts to an existing Model using the DsModelState callbacks. Notice that the Data Source Model State activate callback is a convenient place for this addition because it is executed before the Model’s dynamics are initialized by the ModelState. Source and Models Module/Model file Description basic5.c Main routine basic5_top.c Defines the custom Top State basic5_ds.c Defines the custom data handlers main.m1 main Model displayed when the application is invoked template.m1 Run-time skeleton Model about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-24 Basic Techniques User Interaction and Program Architecture When the application is invoked, the main Model appears, as shown in Figure 3-9:. Standard Backplane WinModState main Pressing the Model #1 button displays model1 WinModState WinModState model1 model2 Pressing the Model #2 button displays model2 main Model model1 Model model2 Model Figure 3-9: User interaction and State tree for "basic5" example The display of the Window Model States, invoked by the push buttons Model #1 and Model #2, is composed of two elements. First is the Model "template," or base Model, containing a simple rectangle. Second are push buttons added in the rectangular area at run-time. The only difference between Model #1 and Model #2 is the number of push buttons generated. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-25 Basic Techniques When either the Model#1 or Model#2 button is activated, the push buttons generated are made completely functional; they have properly initialized dynamics and variables. As in the basic1 example, the invocation of the Window Model States that display model1 and model2 is performed in a codeless way by renaming the Model #1 and Model #2 buttons’ variables. Messages and Values Sent by the "Model #1 and Model #2" Buttons Renamed Variables Button msg_statename1 value2 msg_strmsg Model #1 NULL "new_model_window" Model #2 NULL "new_model_window" "template + win1 \twin_position 0.4 0.42 \ttitle model1 \tds_string 11" "template + win2 \twin_position 0.4 \ttitle model2 \tds_string 21" 0.1 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. 2. "\t" is the separator between each message-value pair. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-26 Basic Techniques Description of the "value" String From Button Model Parent State1 State Window Attributes Model #1 template + win1 position title (Refer to value above.) Model #2 template + win2 position title (Refer to value above.) 1. A "+" is equivalent to "use the direct parent State of the State that receives the message." Here it is the Backplane State. Description of the "ds_string" Value From Button Number of Buttons To Generate Model #1 11 Model #2 21 NOTE: The two Models have the Backplane State as parent, as does the main Model of the application. Therefore, all Window Model States are siblings. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-27 Basic Techniques Simple Zooming/Panning Using a View Manager State Purpose This example shows how to build a zooming/panning feature using the View Manager State. Source and Models Module/Model file Description basic6.c Main routine basic6_top.c Defines the custom Top State. zppanel.m1 Zoom panel window pipeline.m1 Pipeline paths that can be zoomed in/out or panned about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-28 Basic Techniques When the application is invoked, the pipeline Model, including paths that can be zoomed in/out or panned, appears next to a custom zooming/panning tools panel, as shown in Figure 3-10:. Figure 3-10: "zppanel" and "pipeline" Models The pipeline Model was built with an original size of 100x75 (100 = width; 75 = height) starting at (0,0). When the application begins, only 50% of the Model, taken equally from the center point of the Model, is shown. In the code, this is accomplished during invocation of the Window Model State by setting the World Coordinate Extent5 of the View with the computed coordinates of the area to display. By setting the "mapping_factor" to 100%, the size of the window that appears is half of the screen width and height. Notice that the area of the Model that is shown is only half of the original size. With the same "mapping_factor," the display of the original Model would have taken up the entire screen. 5. The SL-GMS® State Class Library Reference provides further information about "view_wc_extent" and "mapping_ factor" attributes of the Window Model State. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-29 Basic Techniques The zooming/panning capability is achieved by the View Manager State. This State is invoked under the Backplane State. Note that the Instance must specifically be called "viewmgr" to work properly. The name of a custom zooming/panning tools panel for user interaction with the Model is passed to the View Manager State as soon as activation is complete, 6 using the “view_tools_window” method. The features offered in the zoom/pan panel are as follows: • Reset View button — resets the view to its original appearance • Pan button — pans the Model • Zoom In button — zooms in continuously until limit7 is reached NOTE: To limit the zoom in, the zoomfactor_limit attribute has been set to 10%. Once the original visible area dimensions have decreased by 10%, the user cannot zoom in further. • Zoom Out button — zooms out continuously until limit is reached NOTE: To limit the zoom out, the boundary_percent attribute has been set to 50%. Once the area displayed is 50% more than the original area seen, the user cannot zoom out further. In fact, at this time, the entire pipeline Model is visible. • Zoom In/Out button — zooms in and out continuously • Zoom In Once button — zooms in once • Zoom Out Once button — zooms out once • Zoom by Extent button — zooms by extent • Dump States button — view the State tree 6. The "view_tools_window" method described in theViewMgrState in the SL-GMS State Class Library Reference provides further information. 7. The WinModState (Window Model State) and the ViewMgrState (View Manager State) sections in the SL-GMS State Class Library Reference provide more details about zoomfactor and boundary_percent. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-30 Basic Techniques Except for the "zoom-in and out once options," click first on the selection and then hold the left mouse button on the Model, or pick a rectangular area if zooming by extent. In the case of "zoom-in/out," hold the left mouse button depressed to zoom-in and add the key to switch to zoom-out mode. Messages and Values Sent by the "Zoom/Pan" Buttons Renamed Variables Button msg_staten ame1 msg_strmsg Reset View NULL reset_view Pan NULL pan Zoom In NULL zoomin Zoom Out NULL zoomout Zoom In/Out NULL zoominout Zoom In Once NULL zoomin_once Zoom Out Once NULL zoomout_once Zoom by Extent NULL zoomrect Dump States NULL dump_states 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the View Manager State that is displaying the main Model. Since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 3-31 4 Variable Handling Purpose A vital part of any application is the manner in which it handles data. Techniques used in one application may not be appropriate for another application due to platform, database, interface, or performance requirements. The examples in this section address the following concerns regarding data and application variables: • How to determine the data items required to drive a Model • How to manage the application variables and Variable Definitions (VarDefs) 1 associated with the data that drives a Model • How to link variables to real data In many applications, the data items required to drive a particular Model are not known until the Model is used at run time. Therefore, the application must have a way to determine at run time the set of variables that a Model requires. In general, two approaches are used. One approach utilizes information contained in the Model itself. The other approach relies on information separate from the Model to provide the list of data items. This chapter is divided into three parts: • Variable Registration — determining the data items required to drive a Model and creating the VarDefs • Variable Scoping — determining the State to which the VarDefs are available (e.g., the variables can be defined as local variables to a particular State or global variables available to all States in the application) • Variable Linkage Techniques — linking the variables in the Model to real data 1. A “VarDef” is an SL-GMS object that links variables used in a Model’s dynamics to the corresponding application variables. SL-GMS® Reference provides further information. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-1 Variable Handling Registering Variables Purpose This set of examples shows how to determine the list of variables required to drive a Model and create the appropriate VarDefs. The task of variable registration is shared between two modules: • The DataSource Model State (DsModelState) that includes a set of callbacks — activate, update, deactivate — that use information embedded in the Model when it was created to initialize the variables. (This is specific to each example.) • The Custom DataSource Management State that uses information supplied from the DsModelState callbacks to create and manage variables and VarDefs. (This is common to all examples.) For simplicity, all variables are statically declared in the custom DataSource Management State. Furthermore, all VarDefs are kept in the Top State Variable Table. Although the examples have similar displays, they use Model construction and coding techniques to register variables that are partially different. In the following pages, the similarities between the Models and modules of all examples are discussed. Models Used in the Variable Registration Examples When the application is invoked, the mytop Model appears, as shown in Figure 4-1:. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-2 Variable Handling Custom Top State Custom DataSource Manager State Standard Top State Standard Backplane WinModState mytop WinModState model1 Data Source Model State WinModState model2 Data Source Model State mytop Model Pressing the Model #1 button displays model1 model1 Model Variables Used var_A (for temperature value) var_B (for pressure value) var_C (for flow rate value) Pressing the Model #2 button displays model2 model2 Model Variables Used var_B (for pressure value) var_D (for volume of h2s) var_E (for RPM value) Figure 4-1: User interaction and State tree for Variable Registration examples Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-3 Variable Handling The two Models refer to the same VarDef, var_B. When a Model is closed, the ModelState becomes deactivated. The VarDefs specific to this Model are then removed from the Global Variable Table. The VarDef var_B, common to the two Models, is not removed unless both Models are closed. NOTE: Variable creation and removal is printed in the window from which the application was invoked. The mytop Model has two Button Control Objects. The details about the renamed variables of the buttons are shown in the following tables. Messages and Values Sent by the "Model #1 and Model #2" Buttons Renamed Variables Button msg_state name1 Model #1 NULL Model #2 NULL value2 msg_strmsg "new_model_window" "model1 \twin_position 0.4 0.42 \twin_size 0.6 0.288 \ttitle model1 \tds_string...(*"3 "new_model_window" "model2 \twin_position 0.4 0.1 \twin_size 0.6 0.288 \ttitle model2 \tds_string ...(*)" 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. 2. "\t" is the separator between each message-value pair. 3. (*) "ds_string" is a Window Model State attribute that allows sending of information about the variables used in a Model’s dynamics. This will differ with each example. Detailed explanation will be given at a future time. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-4 Variable Handling Description of the "value" String From Button Model Parent State1 State2 Window Attributes Model #1 model1 NULL NULL position size title (Refer to "value" in the previous table) Model #2 model2 NULL NULL position size title (Refer to "value" in the previous table) 1. A value of NULL is equivalent to "the State that receives the message"; + is equivalent to "use the direct parent State of the State that receives the message." However, the NULL value does not need to be included in the value string, as it is the default. 2. A value of NULL is equivalent to "system generated." However, the NULL value does not need to be included in the value string, as it is the default. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-5 Variable Handling Source Modules The modules listed below are common to the five examples which are part of the Variable Registration set. Description of the Source Modules Module Description of Module States Invoked by Module Description of Invoked State varreg.c Initializes SL-GMS Custom Top State varreg_top.c Invokes a series of States Standard Top State Creates the initial State Hierarchy and sets up the application parameters required by the windowing system. Window Model State Displays the mytop Model Custom DsMgrState State Manages the data Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-6 Variable Handling Description of the Source Modules Module topdsmgr.c Description of Module Defines custom DsMgrState State States Invoked by Module Description of Invoked State Performs simple data management functions, such as declaring/updating static variables of various types and managing the corresponding VarDefs. Contains the following functions: user_activate_var( ): Initializes all data variables (called by standard method: activate) user_update_var( ): Generates random values for data variables (called by standard method: update) user_define_var( ): Defines the VarDefs in the Top State Variable Table define_variable( ): Creates VarDef based upon a variable name and attaches it to a proper variable in the Global Top State Variables Table. Calls the function user_define_var( ) . Notice that this module has been divided into two parts for clarity: 1) SL-GMS standard methods 2) user-defined functions The unique features of the examples in the Variable Registration set are provided in the following pages. The following table describes the location of each example, as well as the modules and Models that comprise them. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-7 Variable Handling Source Modules and Models Example Topic Directory Module Model file Section Use of "ds_string" varreg1 varreg.c varreg_top.c topdsmgr.c varreg1_ds.c model1.m1 model2.m1 mytop.m1 about.m1 page 4-10 Use of UserData varreg2 varreg.c varreg_top.c topdsmgr.c varreg2_ds.c model1.m1 model2.m1 mytop.m1 about.m1 page 4-12 Use of ASCII file varreg3 varreg.c varreg_top.c topdsmgr.c varreg3_ds.c model1.m1 model2.m1 mytop.m1 about.m1 page 4-14 Use of Custom VarInit Function varreg4 varreg.c varreg_top.c topdsmgr.c varreg4_ds.c model1.m1 model2.m1 mytop.m1 about.m1 page 4-16 Use of DynInit Intercept Function varreg5 varreg.c varreg_top.c topdsmgr.c varreg5_ds.c model1.m1 model2.m1 mytop.m1 about.m1 page 4-18 The name of the executable on a Motif platform is _xm; on a Windows NT platform, _nt (e.g., varreg1_xm, varreg2_xm , varreg1_nt , varreg2_nt , and so on). Each example displays an About This Example window which is an online summary. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-8 Variable Handling In addition, each of the varreg1 through varreg5 directories includes the appropriate "Makefile" used to build the application and link it to the SL-GMS run-time libraries. To build an application in one of the working directories, type one of the following: make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-9 Variable Handling Using "ds_string" to Hold Variables Attached to a Model Purpose The varreg1 example demonstrates how the "ds_string" attribute of the DsModelState can be used to hold a list of variables for a Model that are then parsed by the Data Source Model State callbacks. Source Modules Refer to Source Modules on page 4-6 for an explanation about the modules "varreg.c", "varreg_top.c" and "topdsmgr.c". The module specific to this example, "varreg1_ds.c", contains the following user-defined Data Source Model State callbacks: • activate — parses the "ds_string" value and calls the define_variable( ) function for each variable found. • deactivate — sends a message to the ModelState to unlink the VarDefs that are no longer in use and removes them from the Top State Variable Table. Models When the application is invoked, the main Model mytop is displayed. Refer to Models Used in the Variable Registration Examples on page 4-2. The Model #1 and Model #2 buttons in the main window are each configured with a "ds_string" that is sent to the WinModState when activated. The WinModState passes the "ds_string" to the DsModelState where the variable names are extracted from the "ds_string" and sent to the custom DataSource manager where Variable Definition objects (VarDefs) are created. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-10 Variable Handling Part of the "value" String (specific to this example) From Button Model Use of "ds_string" to Define Variables Variables Parsed by the Data Source Callbacks Model #1 model1 ds_string var_A+var_B+var_C var_A var_B var_C Model #2 model2 ds_string var_B+var_D+var_E var_B var_D var_E Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-11 Variable Handling Using UserData to Hold Variables Attached to a Model Purpose The varreg2 example demonstrates how the variables used in any object's dynamics can be specified in a UserData string attached to the object. After loading a Model and before initializing its dynamics, SL-GMS, through the Data Source Model State callbacks, examines all Models’ parts for a UserData string. A VarDef is created for each variable name found. NOTE: A UserData string is an arbitrary string that can be attached directly using SL-GMSDraw (click the Object Pull-Down Menu and choose Properties, then select Userdata ) to any part of a Model. The UserData string’s function is to give an application a way to "label" a part and to decide, given the information, on further initialization or use of the object. Here the UserData string contains the names of the variables. Source Modules Refer to Source Modules on page 4-6 for an explanation about the modules "varreg.c", "varreg_top.c", and "topdsmgr.c". The module specific to this example, "varreg2_ds.c", contains the user-defined Data Source Model State callbacks: • activate — looks first for the Model ID, then for the list of objects included in the Model, and loops through all the parts looking for a UserData string. For each variable name found, creates and attaches a VarDef. NOTE: All parts of the Model are traversed twice: once by the activate callback and once by the function that initializes the dynamics, gmsDynInit( ) . Example varreg4 , described on page 4-16, combines the UserData technique with a DynInit intercept and eliminates one pass through the Model’s parts list. • deactivate — sends a message to the ModelState to unlink the VarDefs that are no longer in use and removes them from the Top State Variable Table. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-12 Variable Handling Models When the application is invoked, the main Model mytop appears. Refer to Models Used in the Variable Registration Examples on page 4-2. The renamed variables of the Model #1 and Model #2 buttons differ from those of the previous example for the "ds_string" part. The "ds_string" has the default value " * " to signify that Data Source Model State callbacks are used. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-13 Variable Handling Using an ASCII File to Hold Variables Attached to a Model Purpose The varreg3 example demonstrates how the variables part of any object's dynamic can be contained in an associated ASCII file. After the Model is loaded, this ASCII file, whose name is sent to the Window Model State, is opened. For any variable name found, a VarDef is created. Source Modules Refer to Source Modules on page 4-6 for an explanation about the modules "varreg.c", "varreg_top.c", and "topdsmgr.c" . The ASCII files containing the list of respective variables for the Models displayed by pressing the buttons Model #1 and Model #2 are "model1.var" and "model2.var". These files are expected to be in the current directory. The ASCII file can be produced by hand with a text editor, by a variable scanner program that scans a Model for variable information, or by a customized Model Editor that builds and saves the ASCII file whenever a Model is saved. The module specific to this example, "varreg3_ds.c", contains the following user-defined callbacks: • activate — opens the ASCII file associated with each Model and creates for each variable found a VarDef in the Top Variable Table, using the Data Manager function define_variable( ). • deactivate — same as the varreg2 example described on page 4-12. Models When the application is invoked, the main Model mytop is displayed. Refer to Models Used in the Variable Registration Examples on page 4-2. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-14 Variable Handling The renamed variables of the buttons Model #1 and Model #2 differ from those of the previous example for the "ds_string" part. Part of the "value" String (specific to this example) Use of "ds_string" to Define an ASCII File Name ASCII File Name Parsed by the Data Source Callbacks model1 ds_string model1.var model1.var model2 ds_string model2.var model2.var From Button Model Model #1 Model #2 Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-15 Variable Handling Using a Custom Variable Initialization Function Purpose The example varreg4 demonstrates how a custom Variable Initialization function ( VarInitFctn ) can be used to replace the existing internal function just before initialization is completed. The existing function defines the VarDef for each VarRef2 included in a Model's dynamic properties. This example differs from the others in that an external source of information such as an ASCII file, UserData string, Data Base, or server are needed for the set of variables. During the process of initializing a Model's dynamics using the gmsDynInit( ) function, each variable reference found in any of the Model's parts is passed to a standard VarInit Function.3 This function finds and returns the Variable Definition with the same given name. The VarInit function simply searches State Variable Tables upward through the State tree for the specified variable. If the variable name is not found in any State Tables, the Global Variable Table is searched. If it is still not found, a VarDef is created with the same name as the VarRef variable. The internal VarInitFctn can be replaced by a custom user function, as shown in this example. Source Modules Refer to Source Modules on page 4-6 for an explanation about the modules "varreg.c", "varreg_top.c", and "topdsmgr.c". The module specific to this example, "varreg4_ds.c", contains the user-defined Data Source Model State callbacks: • activate: Installs a custom VarInit function using a call to gmsVarInitFctn( ) . The custom VarInit function myvarinit( ) simply calls the Data Manager function define_variable( ) used in Examples 1 through 3. Notice that the Data Source Model State activate callback is the perfect place to install such a function in the way that it is being executed before the Model is 2. “VarRef” is short for Variable Reference. The SL-GMS® Reference provides additional information about Variable References. 3. “VarInit” is short for a Variable Initialization function. The SL-GMS® Reference provides additional information about the standard Variable Initialization function. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-16 Variable Handling initialized. The VarInit function must be installed twice, once for each Model, because as soon as a DsModelState activation is complete, the standard VarInitFctn is restored. • deactivate — same as the varreg2 example described on page 4-12. Models When the application is invoked, the main Model mytop is displayed. Refer to Models Used in the Variable Registration Examples on page 4-2. Nothing is embedded in the renamed variables of the buttons except the "ds_string" attribute with the "* " default value to signify to the system that Data Source Model State Callbacks are used. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-17 Variable Handling Using DynInit Intercept Functions Purpose The object DynInit intercept, varreg5, can replace code for traversing a Model's parts. The ModInst DynInit intercept is useful when Model Instances contain information needed to complete the definition of variables or VarDefs. As in the varreg2 example, varreg5 uses the UserData method to specify the Variable References included in any object's dynamics. Refer to Source Modules on page 4-12. However, another technique is combined with the UserData method to prevent traversing the Model's parts twice: once in the DsModelState activate callback and once during initialization of the Model's parts in gmsDynInit( ) . 4 In this example, a special function, called a DynInit intercept, is registered for the Model Instance and Graphical Primitive objects. This function is executed during initialization whenever gmsDynInit( ) encounters a Model Instance or a Graphical Primitive object. For every VarRef present in the dynamic properties of the found object, a VarDef is created (if it does not already exist) in the Top Variable Table. Source Modules Refer to Source Modules on page 4-6 for an explanation about the modules "varreg.c", "varreg_top.c, and "topdsmgr.c". The module specific to this example, "varreg5_ds.c", contains the following specific functions and user-defined Data Source Model State callbacks: • my_dyninit_fctn ( ) — loops through all Models’ parts looking for a UserData string. For each variable name found, calls the Data Manager function define_variable( ) — (presented in the previous examples) to create and attach a VarDef. • activate — registers the user my_dyninit_fctn( ) for the Model Instances and the Graphical Primitives objects. 4. Further information about the gmsDynInit( ) function is provided in the section entitled Dynamics — initialize, update, restore, end in the SL-GMS Function Reference Manual. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-18 Variable Handling The gmsPrmDynInitFctn( ) function is used for Primitives and the gmsInsDynInitFctn( ) function is used for Model Instances. NOTE: gmsPrmDynInitFctn( ) and gmsInsDynInitFctn( ) must be installed in the Data Source Model State initialization function with the respective SL-GMS calls, gmsInstallPrmDynInitIntrcpt( ) and gmsInstallInsDynInitIntrcpt( ) , before being used. • deactivate — same as the varreg2 example described on page 4-12. Models When the application is invoked, the main Model mytop is displayed. Refer to Models Used in the Variable Registration Examples on page 4-2. The "ds_string" has the default value "* " to signify that Data Source Model State callbacks need to be created. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-19 Variable Handling Scoping Variables Purpose The following examples show how to define the Variable Definition in the Model State instead of the Top State, as is done in the "varreg" examples. This process can be useful when there are a large number of variables. Keeping all the variables in the Top State Table would considerably slow the update process. The following table describes the location of each example as well as the modules and Models that comprise the example. Source Modules and Models Example Topic Directory Module Model file Section Use of the "ds_string" in ModelState Scoping varscope1 varscope1.c varscope1_ds.c varscope1.m1 about.m1 page 4-22 Data Scoping on ModelState varscope2 varscope2.c varscope2_ds.c varscope2_top.c moddsmgr.c main.m1 model1.m1 model2.m1 about.m1 page 4-25 The name of the executable on a Motif platform is _xm; on a Windows NT platform, _nt (e.g., varscope1_xm, varscope2_xm , varscope1_nt , varscope2_nt , and so on). Each example displays an About This Example window which is an online summary. NOTE: Other examples will be added in future releases, such as the implementation of a custom data State. In addition, each of the varscope1 and varscope2 directories includes the appropriate "Makefile" used to build the application and link it to the SL-GMS run-time libraries. To build an application in one of the working directories, type one of the following: Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-20 Variable Handling make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-21 Variable Handling Using the "ds_string" in ModelState Scoping Purpose The varscope1 example shows how to simultaneously drive the same Model with different sets of data, using the "ds_string" attribute of the Window Model State. In this example, two Instances of the same Model are displayed. Each variable included in the Model’s dynamic is attached to two different VarDefs. Each VarDef is stored in the respective Model State’s Instance VarDef Table and retrieved by means of the "ds_string" value. Furthermore, the Model was built to show the update of the three basic types of variables (integer, real, and string) through input and timer events using Native Control Objects and GISMOs. Source and Models Module/Model file Description varscope1.c Main routine: Includes invocation of Window Model State to display the two Instances of Model varscope1 . Note : For modularity purposes, a custom Top State could have been created to do the above. varscope1_ds.c Defines the custom data handlers; includes the user-defined Data Source Model State callbacks that interpret the "ds_string" renamed variables. varscope1.m1 Model instanced twice and showing two different sets of the same data. about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-22 Variable Handling User Interaction and Program Architecture When the application is invoked, two Instances of the Window Model State display the varscope1 Model, as shown in Figure 4-2:. Standard Top State Standard Backplane WinModState WinModState varscope1 varscope1 DsModelState VarDefs attached to ModelState DsModelState VarDefs attached to ModelState Figure 4-2: "Window 1" and "Window 2" with associated State tree diagram The Model is divided into two parts: • User Interaction, the left section, allows update of variables based on user input events Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-23 Variable Handling • Program Updating, the right section, drives the update with the SL-GMS timer The User Interaction section includes two Scale Control Objects and a Text Edit Box Control Object. The Text Edit Box displays the default values of an integer, a real, and a string variable. The integer and real data types can be modified using the Scale. The string data type is modified using the Text Edit Box by typing the new value of the variable and pressing or clicking another object. The string variable can also be updated by selecting a string from the list of strings in the Text List Box, shown at the bottom of the Model. Any update of these variables (integer, real or string) is displayed in the text rectangle shown to the right of each item. The Program Updating section includes three Text Filled Rectangles whose attached dynamics display the value of the integer, real, or string variables updated by the code according to a timer-event. Program Architecture Each of the two Window Model State Instances displays the same Model with different data. The use of different data sources is realized through the "ds_string" attribute. First, a different "ds_string" value is attached to each of the Window Model States during creation. Then, during initialization and update of the Model Instances, a set of Data Source Model State callbacks interpret the "ds_string" value passed and change the data of the appropriate Model accordingly. Two data structures are defined in the file “varscope1_ds.c”. One holds the data for the first Instance of the varscope1 Model and the other holds the data for the second Instance of the same Model. NOTE: All variables are known in advance. For a more realistic example, either method presented in the previous Variable Registration set of examples could be used to find the VarRefs. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-24 Variable Handling Scoping Data on ModelState and Dynamic Allocation Purpose The varscope2 example illustrates how to define variables at run time using application data specification. Two Models, including some common variables, are used. The VarDefs are kept in the corresponding ModelState Variable Table. The variables common to both Models are associated with a VarDef in each of the two ModelState Variable Tables. A custom Data State keeps track of all the Model States using each VarDef in order to free it only when it is not referred to. Source and Models Module/Model file Description varscope2.c Initializes SL-GMS and invokes the custom Top State varscope2_ds.c Contains two callbacks: 1) activate: Parses the "ds_string" and calls the define_variable() function for each variable name found. 2) deactivate: Sends a message to the custom Data Manager State to deactivate the data no longer in use. varscope2_top.c Defines the custom Top State and invokes the Window Model States moddsmgr.c Defines a custom Data Manager State that defines /updates /frees the variables main.m1 main Model displayed when the application is invoked model1.m1 Model displayed when the Model #1 button in the main Model is selected Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-25 Variable Handling Source and Models Module/Model file Description model2.m1 Model displayed when the Model #2 button in the main Model is selected about.m1 Online summary of the example User Interaction and Program Architecture When the application is invoked, the varscope2 Model appears, as shown in Figure 4-3:. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-26 Variable Handling Custom Top State Standard Top State Custom DataSource Manager State Standard Backplane WinModState main WinModState DsModelState VarDefs attached to ModelState main Model Pressing the Model #1 button displays model1 model1 Model Variables Used var_I (for radio buttons) var_F (for float value) var_C (for character value) WinModState model1 model2 DsModelState VarDefs attached to ModelState Pressing the Model #2 button displays model2 model2 Model Variables Used var_F (for float value) var_SA (for string array) var_D (for double value) var_C (for character value) Figure 4-3: User interaction and State tree for “varscope2” example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-27 Variable Handling Details about the renamed variables of the buttons are shown in the following tables: Messages and Values Sent by the "Model #1 and Model #2" Buttons Renamed Variables Button msg_statename msg_strmsg value Model #1 my_top "custom_invoke" "model1 var_I var_F var_C" Model #2 my_top "custom_invoke" "model2 var_F var_SA var_C var_D" Explanation of the "value" String From Button Model Variable List Model #1 model1 var_I var_F var_C Model #2 model2 var_F var_SA var_C var_D Compare the message information sent by the buttons of this example to the ones of example varreg1. Refer to the "msg_statename", "msg_strmsg", and "value" attributes of Model #1 of varreg1 . The names of the variables attached to each Model are passed through the renamed variable message "value" of the buttons without using the "ds_string" attribute. The invocation of the Window Model State is done through the use of a custom method custom_invoke instead of the new_model_window standard method. A custom method is used to provide a placeholder where a custom Window Model State creation can be defined. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-28 Variable Handling When activated, the buttons send the message “custom_invoke” to the custom Top State; this method scans the value string. The first argument, Model name, is passed to the Window Model State to be invoked. The remaining arguments are given to the Data Source Model State as the value of the “ds_string” attribute at the time of the WinModState creation. Program Architecture A custom State was created to define and manage the data and VarDefs for each of the two Model States, and to generate random values to be displayed in Model #1 and Model #2. The “moddsmgr.c” module defines the custom State that manages the data. Memory for the variables is allocated upon request. All variable types have been presented: integer, float, double, character, and string array. The data specifications required by SL-GMS to create the Variable Definition Objects for those variables (type, maximum, and minimum values) have been stored in a data structure in the Data Manager State. This information could just as well have come from any other sources such as a file, database, or server. The VarDefs used by each Model are associated with the ModelState that owns the Model. Therefore, a single variable can be associated with more than one VarDef. The var_F and var_C variables are defined in both ModelState Variable Tables, whereas var_SA , var_D, and var_I are not. NOTE: var_F and var_C are associated with a VarDef in each of the two ModelStates. However, the two VarDefs for var_F both point to the same memory location allocated for var_F, and the two VarDefs for var_C both point to the same memory location allocated for var_C, to obtain the current values of the variables. The Model Data Manager State keeps track of which ModelStates use a variable. Only when a variable is not used by any Model States is the memory freed. Therefore, notice that Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-29 Variable Handling when a Model is closed, a variable that is common to both Models is still updated. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-30 Variable Handling Variable Linkage Techniques Purpose The following examples show methods to solve problems involved in linking SL-GMS applications and Models to external sources of data. These methods are used to combine variable handling techniques from previous examples with real, functional Data Sources. The following table describes the location of each example, as well as the modules and Models that comprise the example. Source Modules and Models Example Topic Directory Module Model file Section Dynamic Variable Allocation dynalloc dynalloc.c dynalloc_top.c dynalloc_ds.c topdsmgr.c model1.m1 model2.m1 main.m1 meter.m1 about.m1 page 4-33 Shared Memory shmem shmem.c shmem_top.c dataproc.c main.m1 xhtrend.m1 about.m1 page 4-39 Socket socket socket.c socket_top.c socket_ds.c datasvr.c sktfuns.c xhtrend.m1 about.m1 page 4-45 The name of the executable on a Motif platform is _xm; on a Windows NT platform, _nt (e.g., dynalloc_xm , shmem_xm, dynalloc_nt , shmem_nt , and so on). Each example displays an About This Example window which is an online summary. NOTE: Other examples will be added in future releases, such as one with data information available from a table. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-31 Variable Handling In addition, each of the dynalloc, shmem, and socket directories includes the appropriate "Makefile" used to build the application and link it to the SL-GMS run-time libraries. To build an application in one of the working directories, type one of the following: make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-32 Variable Handling Allocating Dynamic Variables Purpose The dynalloc example is an enhanced version of the varreg1 example. As in the varreg1 example, the "ds_string" attribute of the Data Source Model State is used to hold the list of variables included in the dynamic properties of a Model. The "ds_string" is then parsed by the Data Source Model State callbacks to create the Variable Definition objects. Unlike the varreg1 example, however, the application variables in the dynalloc example are created dynamically at run-time in the custom DataSource Management State. In this example, the data have been defined directly in the code and the emphasis has been put on the dynamic allocation of the variables. In a real world application, the data could have originated from a file, a server, or any other external source. Source and Models Module/Model file Description dynalloc.c Main routine dynalloc_top.c Defines the custom Top State dynalloc_ds.c Defines the custom data handlers topdsmgr.c Defines a custom State that performs data management functions main.m1 main Model displayed when the application is invoked meter.m1 meter SubModel model1.m1 Model invoked by Model #1 button model2.m1 Model invoked by Model #2 button about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-33 Variable Handling User Interaction and Program Architecture When the application is invoked, the main Model appears, as shown in Figure 4-4:. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-34 Variable Handling Custom Top State Custom DataSource Manager State Standard Top State Standard Backplane WinModState main WinModState model1 main Model Pressing the Model #1 button displays model1 model1 Model Variables Used var_A (for temperature value) var_B (for pressure value) var_C (for flow rate value) DsModelState VarDefs attached to Top State WinModState model2 DsModelState VarDefs attached to Top State Pressing the Model #2 button displays model2 model2 Model Variables Used var_B (for pressure value) var_D (for volume of h2s) var_E (for RPM value) Figure 4-4: User interaction and State tree for “dynalloc” example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-35 Variable Handling Details about the renamed variables of the buttons are shown in the following tables: Messages and Values Sent by the "Model #1 and Model #2" Buttons Renamed Variables Button Model #1 msg_statena me1 NULL value2 msg_strmsg "new_model_window" "model1 \twin_position \twin_size 0.6 \ttitle model1 \tds_string 0.4 0.42 0.288 var_A+var_B+var_C"3 Model #2 NULL "new_model_window" "model2 \twin_position \twin_size 0.6 \ttitle model2 \tds_string 0.4 0.1 0.288 var_B+var_D+var_E" 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename , it does not actually need to be renamed by the user. 2. "\t" is the separator between each message-value pair. 3. (*) "ds_string" is a Window Model State attribute that allows sending of information about the variables used in a Model’s dynamics. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-36 Variable Handling Description of the "value" String From Button Model Parent State1 State2 Window Attributes Model #1 model1 NULL NULL position size title (Refer to "value" described in the previous table) Model #2 model2 NULL NULL position size title (Refer to "value" described in the previous table) 1. A value of NULL is equivalent to "the State that receives the message"; + is equivalent to "use the direct parent State of the State that receives the message." However, the NULL value does not need to be included in the value string, as it is the default. 2. A value of NULL is equivalent to "system generated." However, the NULL value does not need to be included in the value string, as it is the default. Description of the "ds_string" Value Use of "ds_string" to Define Variables Variables Parsed by the Data Source Callbacks Model #1 ds_string var_A+var_B+var_C var_A var_B var_C Model #2 ds_string var_B+var_D+var_E var_B var_D var_E From Button Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-37 Variable Handling The custom Data Manager State, defined in "topdsmgr.c", performs simple data management functions, such as dynamically declaring/updating variables of various types and managing the corresponding VarDefs. The custom Data Manager State contains the following functions: • user_update_var( ) — generates random values for data variables (called by standard method: update). • user_define_var( ) — defines the VarDefs in the Top State Variable Table and allocates memory for the application variables when one of the Buttons, Model #1 or Model #2, is activated. • define_variable( ) — creates VarDef based upon a variable name and attaches it to a proper variable in the Global Top State Variables Table. Calls the function user_define_var( ). • user_deactivate( ) — frees memory allocated to the application variables. Note that the unused VarDefs are purged from the Global Variables Table by the data handler deactivate of the Data Source Model State. The variable var_B, common to the two Models, is not removed unless both of the Model States are deactivated. Notice that "topdsmgr.c" has been divided into two parts for clarity: 1. SL-GMS standard methods 2. user-defined functions NOTE: Variable creation and removal is printed in the window from which the application was invoked. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-38 Variable Handling Using Shared Memory Purpose This example shows how to use shared memory and pipes to communicate data between SL-GMS applications and data generator processes. It illustrates an SL-GMS program that accesses a given shared memory segment and displays the incoming data in one sample graph. This example does not use the "ds_string" parameter or the Data Source Model State. A data generation process, dataproc, is used to generate data for this example. This program creates a shared memory segment and reports the id of the segment so it can be referenced by the SL-GMS application. Source and Models Module/Model file Description shmem.c Main routine shmem_top.c Defines the custom Top State dataproc.c Data generation process main.m1 main Model displayed when the application is invoked xhtrend.m1 Model used by this example about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-39 Variable Handling User Interaction and Program Architecture When the application is invoked, the main Model appears, as shown in Figure 4-5:. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-40 Variable Handling Custom Top State Clicking the Generate Data button begins the dataproc process Standard Top State Standard Backplane WinModState main WinModState xhtrend Clicking the Create Window button displays xhtrend Model main Model Clicking the Start Display button begins the trending on xhtrend Model xhtrend Model Figure 4-5: User interaction and State tree for “Shared Memory” example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-41 Variable Handling The Model is divided into two parts: • The first starts the data generator process and the SL-GMS application that handles the display of the data in a sample graph. When the Generate Data button is activated, the data process is executed in the background. The id of a shared memory area, in which this process writes the data, is provided to the SL-GMS application as soon as the Start Display button is activated. NOTE: A window displaying the graph must be created first. The Create Window button displays the graph. The xhtrend Model is the sample graph displayed when the button Create Window is activated. The button Start Display begins the Model’s graph line movement. • The second allows the user to stop and start data generation by clicking Stop or Go. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-42 Variable Handling The details about the renamed variables of the buttons are shown in the following tables. Messages and Values Sent by the Buttons Renamed Variables Button msg_state name1 value2 msg_strmsg G_NULL_INTEGER3 Generate Data NULL "launch" Create Window NULL "new_model_window" "xhtrend \twin_position 0.5 \twin_size .4 .3" 0.50 Start Display NULL "start" G_NULL_INTEGER Stop NULL "stop" G_NULL_INTEGER Restart NULL "restart" G_NULL_INTEGER 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since NULL is the default value for msg_statename , it does not actually need to be renamed by the user. 2. "\t" is the separator between each message-value pair. 3. Renaming the value variable to G_NULL_INTEGER , along with setting value_valtype to 2 (indicates that the data type of value is an integer), sets value equal to zero. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-43 Variable Handling Description of the "value" string for the "Create Window" button Model xhtrend Parent State1 NULL State2 NULL Window Attributes position size (Refer to "value" in the previous table) 1. A value of NULL is equivalent to "the State that receives the message"; + is equivalent to "use the direct parent State of the State that receives the message." However, the NULL value does not need to be included in the value string, as it is the default. 2. A value of NULL is equivalent to "system generated." However, the NULL value does not need to be included in the value string, as it is the default. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-44 Variable Handling Using Sockets Purpose This example shows how to integrate the SL-GMS Screen Management System into an application which uses UNIX TCP/IP “sockets” for communication of data between processes. Two separate processes are run to demonstrate the sockets: socket_xm and datasvr. The socket_xm program sets up the SL-GMS environment and displays the main Model. Clicking the Launch button in the main Model starts the datasvr process and displays the xhtrend Model. The datasvr process responds to commands from socket_xm , and when enabled, generates random data and sends it via a socket to socket_xm for display. These processes can access the sockets via UDP or TCP function calls. The user is prompted to select the desired protocol. The processes can be run on the same node or on separate nodes. The socket_xm process prompts the user for the host name of the node on which the server is running. Source and Models Module/Model file Description socket.c Main routine socket_top.c Defines the custom Top State socket_ds.c Defines the custom data handlers datasvr.c Data generation server sktfuns.c Functions needed by the example xhtrend.m1 The main Model displayed when the application is invoked about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-45 Variable Handling User Interaction and Program Architecture When the socket_xm application is invoked, the main Model appears, as shown in Figure 4-6:. Custom Top State Standard Top State Standard Backplane main Model WinModState WinModState main xhtrend DsModelState VarDefs attached to Backplane Clicking the Launch button in the main Model displays xhtrend xhtrend Model Figure 4-6: User interaction and State tree for "socket" example Clicking the Launch button in the main Model starts the datasvr process with the data generator DISABLED. The data generation process may be "started" by clicking on the Go button in the main Model. Clicking the Go button initiates data trending on the different graph Instances. The data generation process may be stopped again by clicking the Stop button. The time interval for writing data on the socket may also be set using the scale in the main Model. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 4-46 5 Advanced Use of Dialogs Purpose The following examples show different methods used to invoke a system-independent Dialog State. The examples demonstrate: • the use of GISMOs to invoke a Dialog State (dialog1) • the use of an Object Selection State that allows selection of objects using the mouse to invoke a Dialog State (dialog2) • attaching an arbitrary string (UserData) to an object displayed on the screen. For these examples, the string contains the type of symbol (i.e., PUMP or VALVE) and the data structure index of the variable used to drive the dynamics of the object to which it is attached. The string is passed to the application when the object is selected on the screen and is used to determine whether the pump or valve dialog interface Model should be displayed and which valve or pump’s data was selected and should be displayed. • the use of a Dialog State interface to edit information of a selected object The following table describes the location of each example, as well as the modules and Models that comprise the example. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-1 Advanced Use of Dialogs Source Modules and Models Example Topic Directory Module Models and Data files Section Use of GISMO function dialog1 dialog1.c dialog1_top.c dialog1_ds.c dialog1_dsmgr.c dialog1_top.m1 about.m1 pumpdialog.m1 valdialog.m1 i_vlve_a.m1 i_vlve_t.m1 i_pump.m1 page 5-5 Use of Object Selection State dialog2 dialog2.c dialog2_top.c dialog2_ds.c dialog2_dsmgr.c dialog2_top.m1 pumpdialog.m1 valdialog.m1 about.m1 page 5-9 The name of the executable on a Motif platform is _xm; on a Windows NT platform, _nt (e.g., dialog1_xm, dialog2_xm, dialog1_nt, dialog2_nt, and so on). Each example displays an About This Example window which is an online summary. NOTE: Future examples will show simultaneous use of system-dependent and system-independent dialogs. In addition, each of the dialog1 and dialog2 directories includes the appropriate "Makefile" used to build the application and link it to the SL-GMS run-time libraries. To build the application in one of the working directories, type one of the following: make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-2 Advanced Use of Dialogs Program Architecture The Data Source Model State is invoked directly under the custom Top State instead of being automatically installed under the Window Model State (by passing the argument “ds_string” to the Window Model State). The only purpose is to make all variable definitions global. In addition to containing the definition of the Data Source Model State, the “dialog1_ds.c” and “dialog2_ds.c” files also contain the methods that the target State 1 of the dialog interface (the Data Source Manager State) uses to query, define, apply, and change the pump and valve data structures displayed in the dialog interface window. Two types of data are defined in the “dialog1_ds.c” and “dialog2_ds.c” files: • variables controlling the dynamic behavior of objects in the dialog1_top/ dialog2_top Model that are defined in the activate method • pump and valve data structures, displayed/updated with the dialog interface Model, that are defined in the my_ds_define_dialog_structure_vars( ) function NOTE: The pump and valve dialogs both contain a value for the status of the pump/valve. This is the same status that is controlling the dynamic behavior, using a color change of the pump/valve on the dialog1_top/dialog2_top Model. Therefore, the my_ds_apply_dialog_structure( ) function, in addition to copying the temporary data structure into the defined variables for the object, also contains a call to gmsStVarChanged( ) to mark the value of the object’s status as changed so that it is updated on the dialog1_top/dialog2_top Model. A Dialog State Instance is invoked under the Target State to display a dialog window and to update the information concerning the object selected. The dialog1_top/dialog2_top Model represents a refinery plant, including valves and pumps. Any pump or valve can be selected. The dialog win1. The Target State is the State that manages the data. The Dialog State provides an interface between the Target State and a dialog box that allows update of the data. The section entitled DialogState in the SL-GMS State Class Library Reference Manual provides further information. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-3 Advanced Use of Dialogs dow appears that corresponds to the object selected. If a pump is selected, the Pump Dialog window appears. If a valve is selected, the Valve Dialog window appears. Each of the two windows displays the information relating to the object in a form ready for editing. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-4 Advanced Use of Dialogs Using GISMOs to Invoke a Dialog State Interface Purpose The dialog1 example makes use of a GISMO event function to invoke a system-independent Dialog State interface. This differs from the dialog2 example, which uses an Object Selection State to invoke the Dialog State interface. Source and Models Four source code files and seven Models are associated with this example. Source and Models Module/Model file Description dialog1.c Main routine dialog1_top.c Defines the custom Top State dialog1_ds.c Defines the custom data handlers, as well as the functions used by the dialog manager to query, update, and change the valve and pump data structures dialog1_dsmgr.c Defines a simple dialog manager for editing values — the Target State of the dialog interface dialog1_top.m1 The main Model displayed when the application is invoked pumpdialog.m1 Dialog interface Model used to display/update pump information valdialog.m1 Dialog interface Model used to display/update valve information i_pump.m1 GISMO SubModel instanced to display a pump; calls the user-defined function invoke_dialog( ) when selected Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-5 Advanced Use of Dialogs Source and Models (continued) Module/Model file Description i_vlve_a.m1 GISMO SubModel instanced to display an “A” type valve; calls the user-defined function invoke_dialog( ) when selected i_vlve_t.m1 GISMO SubModel instanced to display a “T” type valve; calls the user-defined function invoke_dialog( ) when selected about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-6 Advanced Use of Dialogs User Interaction and Program Architecture When the application is invoked, the dialog1_top Model appears, as shown inFigure 5-1:. Custom Top State dialog1_top Standard Top State DsModelState Vardefs attached to Top State Standard Backplane dialog1_top Model Pressing a valve symbol displays a window which allows editing of the name, status, and position of the valve. valdialog Model WinModState Custom Target State dialog1_top data manager Dialog Pressing a pump symbol State displays a window which allows editing of the name, status, and speed of the pump. pumpdialog Model Figure 5-1: User interaction and State tree for "dialog1" example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-7 Advanced Use of Dialogs Using GISMOs and a DialogState Interface A custom Top State, dialog1_top, is created at the top of the tree to hold the definition of a user-defined function 2 invoke_dialog that is responsible for installing a Dialog State when either a pump or valve GISMO is selected. Any valve or pump symbol can be selected to display information about that GISMO symbol. Upon selection, the invoke_dialog( ) user-defined function is executed. The invoke_dialog( ) function parses the UserData string of the selected GISMO to determine: • whether the object was a valve or pump • the index into the valve or pump data structure The function then invokes a DialogState Instance to display a dialog window. A dialog window appears that corresponds to the object selected. If a pump is selected, the Pump Dialog window appears. If a valve is selected, the Valve Dialog window appears. Each of the two windows displays the information relating to the object in a form ready for editing. 2. Further information about user-defined functions is provided in the section entitled Dynamics in the SL-GMS Reference Manual. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-8 Advanced Use of Dialogs Using an Object Selection State to Invoke a Dialog State Purpose The dialog2 example makes use of an Object Selection State that allows selection of objects using the mouse. Selecting a pump or valve object invokes a Dialog State interface. This differs from the dialog1 example which uses a GISMO to invoke the Dialog State interface. Source and Models Four source code files and four Models are associated with this example. Source and Models Module/Model file Description dialog2.c Main routine dialog2_top.c Defines the custom Top State dialog2_ds.c Defines the custom data handlers as well as the functions used by the dialog manager to query, update, and change the valve and pump data structures dialog2_dsmgr.c Defines a simple dialog manager for editing values — the Target State of the dialog interface dialog2_top.m1 The main Model displayed when the application is invoked pumpdialog.m1 Dialog interface Model used to display/update pump information valdialog.m1 Dialog interface Model used to display/update valve information about.m1 Online summary of the example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-9 Advanced Use of Dialogs User Interaction and Program Architecture When the application is invoked, the dialog2_top Model appears, as shown in Figure 5-2:. Custom Top State dialog2_top Standard Top State DsModelState Vardefs attached to Top State Standard Backplane dialog2_top Model WinModState dialog2_top Custom Target State data manager ObjSelState Pressing a valve symbol displays a window which allows editing of the name, status, and position of the valve. valdialog Model Dialog State Pressing a pump symbol displays a window which allows editing of the name, status, and speed of the pump. pumpdialog Model Figure 5-2: User interaction and State tree for "dialog2" example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-10 Advanced Use of Dialogs Using an Object Selection State and a DialogState Interface A custom Top State, dialog2_top, is created at the top of the tree to hold the definition of a custom method, object_selected, that is responsible for installing a Dialog State in the occurrence of an object selection. Any valve or pump symbol can be selected to display information about that symbol. Upon selection, a message is sent by the Object Selection State to the custom Top State that, in response, invokes a Dialog State. The dialog window appears that corresponds to the object selected. If a pump is selected, the Pump Dialog window appears. If a valve is selected, the Valve Dialog window appears. Each of the two windows displays the information relating to the object in a form ready for editing. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 5-11 6 Performance Optimization Introduction This example shows how to implement a SubModel cache in order to improve the performance of an application that uses Models which include many Instances of the same SubModel. 1 The user can request that SL-GMS store the SubModel Instances of the Model in memory instead of freeing them when the Model is closed. Therefore, the next time the Model is displayed, Instances kept in memory (i.e., the SubModel cache) are used, which decreases the loading time of the Model. This section explains how to: • create a cache for a SubModel • incrementally load the cache • clear the cache • pre-load the cache 1. SubModel caching is further described in the section in the SL-GMS Reference Manual and the section Model Instance (ModInst) — caching in the SL-GMS Function Reference Manual. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-1 Performance Optimization Source and Models Module/Model file Description subcache.c Initializes SL-GMS and invokes the custom Top State for SubModel caching. subcache_top.c Defines the custom Top State and includes the methods used to create, load, and clear the cache. Handles the definition and the update of the cache variables. main.m1 main Model displayed when the application is invoked target.m1 SubModel instanced several times to demonstrate the advantage of SubModel caching test_model.m1 Model displayed which includes 252 Instances of the target SubModel about.m1 Online summary of the example The name of the executable on a Motif platform is subcache_xm; on a Windows NT platform, subcache_nt. The example displays an About This Example window which is an online summary. In addition, the subcache directory includes the appropriate "Makefile" used to build the application and link it to the SL-GMS run-time libraries. To build the application in the subcache directory type one of the following: make on Unix platforms or nmake on 32-bit Windows platforms Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-2 Performance Optimization User Interaction and Program Architecture When the application is invoked, the subcache Model appears, as shown in Figure 6-1:. Custom Top State main Model Standard Top State Standard Backplane WinModState WinModState main test_model Pressing the 0, 10, 25, 100, or test_model Model 252 button displays test_model Model, which contains 252 Instances of the target Submodel Figure 6-1: User interaction and State tree for "subcache" example Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-3 Performance Optimization The Model is divided into three columns: • The first column allows the user to choose whether or not to use a SubModel cache. Click the 0 button to load the test_model Model without using a SubModel cache. Click the 10, 25, 100, or 252 buttons to create a cache and load 10, 25, 100, or 252 replicates (the number of target SubModel Instances contained in the test_model Model) into the cache. • The second column displays the time taken to create the SubModel cache. • The third column displays the time taken to load the test_model Model. Each button sends the “create_cache_and_hold” message to the Custom Top State and sets the value of the curr_cache_capacity variable in the application. However, each button sets the curr_cache_capacity variable to a different value. curr_cache_capacity is set to whatever the value parameter is renamed to. For instance, if value is renamed to 25, then curr_cache_capacity is set to 25 in the application. The messages and values sent by the different buttons is shown in the table Messages and Values Sent by the Buttons on page 6-5. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-4 Performance Optimization Messages and Values Sent by the Buttons Renamed Variables Button msg_state name1 msg_strmsg set_variable value 0 NULL “create_cache_and_load” curr_cache_capacity 0 10 NULL “create_cache_and_load” curr_cache_capacity 10 25 NULL “create_cache_and_load” curr_cache_capacity 25 100 NULL “create_cache_and_load” curr_cache_capacity 100 252 NULL “create_cache_and_load” curr_cache_capacity 252 1. Renaming the msg_statename variable to NULL indicates that the message should be sent to the current State, which in this example is the Window Model State that is displaying the main Model. Since the WinModState does not contain the create_cache_and_load method, it will pass this message up the State tree to the Custom Top State. In addition, since NULL is the default value for msg_statename, it does not actually need to be renamed by the user. The create_cache_and_load method performs the following functions: • Frees all Instances, the designated SubModel, and resets all cache parameters to zero. • Pre-loads the designated SubModel target to allow creation of a cache referencing it. • Sets the flag that prevents the designated SubModel from being automatically freed when the last Model Instance referencing it is freed. • Sets the maximum number of SubModel replicates which can be stored in the cache (i.e., the capacity of the cache) equal to curr_cache_capacity. • Pre-loads the number of replicates designated by the user. The value of curr_cache_capacity determines the number of Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-5 Performance Optimization replicates of the target SubModel that are loaded into the SubModel cache. • Invokes a Window Model State to display the test_model Model that includes 252 Instances of the target SubModel. This example allows the user to experiment with using a SubModel cache and varying the number of Instances loaded into the cache to observe the effect on the time taken to create the cache and to load the Model. NOTE: The capacity of the cache is the maximum number of SubModel replicates which can be stored in the cache for future use. The closer the cache capacity is to the actual number of replicates which will exist in memory, the greater the optimization. The count of the cache is the sum of the number of inactive2 SubModel replicates stored in the cache and the number of existing active SubModel replicates which have the potential to be stored in the cache, up to the limit of the capacity of the cache. No Data Source Model State has been created to define and update the variables that are displayed; everything is handled in the Custom Top State. 2. A SubModel that is currently referenced by a Model Instance is "ACTIVE," otherwise it is "INACTIVE." Only "INACTIVE" SubModel replicates can be stored in a SubModel cache. When an "ACTIVE" Model is made "INACTIVE," an attempt is made to store it in the appropriate SubModel Cache. If it is not possible, either because the cache does not exist or the cache has reached its storage capacity, the replicate is freed. Version 6.2a- 26 May 2006 SL-GMS Examples Manual 6-6 Detailed Analysis: myproject_common A Introduction The myproject_common example, defines the SL-GMS features that are common to all of the myproject examples. It is an enhanced version of the myproject example. The enhancements include additional methods that extend myproject for use within frameworks. Execution Options The executable program file for the myproject_common example is "myproject" which is executed as follows: myproject [-Umsecs] modelname Where msecs is the data update rate in milliseconds, and modelname is the name of an SL-GMS Model. Source and Model Files The files that are used by the myproject_common example are listed in the table below. Source and Model Files File Description gmsmain.c Main routine. user_top.c Defines the custom Top State. user_ds.c Generates data for the windtunnel and mymodel Models. gmsfuns.c Support functions. *.m1 SL-GMS Models provided for use by the myproject_common example. Version 6.2a- 26 May 2006 SL-GMS Examples Manual A-1 State Tree Diagram When the application is executed, the State tree shown in Figure A-1 is created. Custom Top State Standard Top State Standard Backplane WinModState windtunnel Figure A-1State Tree diagram for "myproject" Source File Analysis gmsmain.c The "gmsmain.c" file contains the main( ) function which initiates program execution. Within the main( ) function, the following steps are performed: • SL-GMS is initialized • The custom Top State class is initialized. • Command line arguments are processed. • An instance of the custom Top State class is created and activated. Version 6.2a- 26 May 2006 SL-GMS Examples Manual A-2 • The main event loop is executed. The "gmsmain.c" file is unique to the myproject_common example. The other myproject examples, perform the same steps in modules appropriate to the particular application framework. user_top.c The "user_top.c" file contains the definition of the custom Top State class MyTopState. The methods and variables of the MyTopState class are described below. MyTopState Class Variables Variable model_name Type string winmodst_name string count integer Description The name of the Model to display The name of the WinModState instance displaying the Model A utility counter variable. MyTopState Class Methods Variable copyfrom activate model_name Version 6.2a- 26 May 2006 Description Copies State variable values from the exemplar to an instance. Invokes a StandardTopState instance. Invokes a WinModState instance if a Model name has been stored in the model_name variable. Stores a string in the State model_name variable. If a WinModState instance is active, it is sent a message to replace the current Model with the new Model. If a WinModState instance does not exist, one is invoked to display the Model. SL-GMS Examples Manual A-3 MyTopState Class Methods Variable winmodstate_name Description Stores a string in the State winmodst_name variable which defines the name of the WinModState instance invoked to display a Model. get_winmod_name A query method that returns the current value of the winmodst_name variable. app_window_handle Stores a window handle created by an application framework. This is usually the handle of a top-level or shell window. app_subwindow_handle Stores the handle of a window created by an application framework in which an SL-GMS Model is drawn. custom_control_method An example of a method that can be executed from a control object. The State counter variable is incremented and its current value is printed to standard output. g_app_quit Calls the ExternalMessage( ) function to send a "Quit" message to the application framework. user_ds.c The "user_ds.c" file contains functions that generate data for the windtunnel and mymodel Models that are commonly used by the "myproject" examples. All "myproject" applications can also run any Model whose data is generated by a .dat file. The variables created and updated by the functions in "user_ds.c" are listed below. Version 6.2a- 26 May 2006 SL-GMS Examples Manual A-4 Variables for windtunnel Model Variable Type press1 integer press2 integer nozzle integer alpha integer choke integer bleed integer clamp double Variables for mymodel Model Variable display_msg Type string (length = 1024 characters) gmsfuns.c The file "gmsfuns.c" contains support functions that allow the application frameworks to access and control SL-GMS features. Version 6.2a- 26 May 2006 SL-GMS Examples Manual A-5 Detailed Analysis: myproject_ax & myproject_vb B Introduction The SL-GMS ActiveX example, myproject_ax, is based on the SL-GMS myproject_common example, which is a portable, stand-alone application that displays a Model with real-time animation driven by simulated data. The myproject_common example is then connected to the ActiveX interface so it can function as an OLE control class. The SL-GMS ActiveX control can be used with any application that can function as an OLE container. The MS Internet Explorer browser is one such application. MS Visual Basic and Visual C++ applications can also be configured to serve as OLE containers which can make use of the SL-GMS ActiveX control. Source Files The SL-GMS ActiveX control is built from several sets of files which are listed below. Files Generated by the ActiveX Control Wizard File Description myproject_ax.cpp Performs registration, initialization, and termination of the ActiveX control. Calls to SL-GMS start-up and termination functions are added to this file. myproject_ax.h Main header file for the control's class. myproject_axCtl.cpp Implements the "CMyproject_axCtrl" OLE control class. SL-GMS specific code and methods are added to this file using the Class Wizard. myproject_axCtl.h Declares the "CMyproject_ctrl" OLE control class. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-1 Files Generated by the ActiveX Control Wizard File Description myproject_axPpg.cpp Implements the control's property page. myproject_axPpg.h Header file for the control's property page. myproject_ax.odl Project type library source. myproject_ax.rc Resources file. myproject_ax.def Defines the OLE modules parameters. StdAfx.cpp Implementation file for standard MFC include files. StdAfx.h Header file for standard MFC include files. The files in the next table define the features of the SL-GMS application and connect it to the ActiveX interface. SL-GMS / ActiveX Integration Files File Description gms_cntrl.cpp Contains methods that process events of interest to SL-GMS. gms_cntrl.h Defines the base class of the SL-GMS ActiveX demo. The class is called "GMS_Cntrl”, and is a subclass of COLEControl. gmsfuns.c Contains SL-GMS utility functions needed by the ActiveX demo. gmsmain.c Contains the main "hook" functions that initialize and start SL-GMS. user_top.c Defines the custom Top state class. It is located in the myproject_common directory. user_ds.c Defines the user data source functions. It is located in the myproject_common directory. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-2 Properties The SL-GMS ActiveX control has one property: 1. modelname -- Defines the name of the SL-GMS Model file to display in the control. It can contain a drive letter and path. The modelname property can be used to configure the control to display Models located on any drive accessible to the system running the control. Methods The SL-GMS ActiveX control provides the following methods: SL-GMS ActiveX Control Methods Method Description SendStateMessage This method is used to communicate to the underlying SL-GMS application. CloseModel This method is used to close the Model. GetWinModName This method is used to query the name of the WinModState that manages the Model displayed. SetModelname This is the “set” method for the modelname property. It displays the specified Model in an existing window. GetModelname This is the “get” method for the modelname property. It returns the name of the current Model. SL-GMS / ActiveX Interface The declarations, functions and methods that connect SL-GMS with the ActiveX framework are defined in the files "gmsmain.c", "gms_cntrl.cpp" and "gms_cntrl.h". In this section the services and features provided by these files are examined. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-3 The GMS_Cntrl Class The class for the SL-GMS ActiveX control is defined in the file "gms_cntrl.h" and is called GMS_Cntrl. The GMS_Cntrl class is a subclass of the COleControl class. The GMS_Cntrl class provides the overrides and definitions required for SL-GMS to properly obtain and dispatch events. SL-GMS Initialization SL-GMS is initialized by the init_gms() function in "gmsmain.c". The init_gms() function is called from the application’s InitInstance method in "myproject_ax.cpp" as shown below BOOL CMyproject_axApp::InitInstance() { BOOL bInit = COleControlModule::InitInstance(); if (bInit) { init_gms(0,NULL); /* Next line prevents this DLL from being unloaded until the container exits. GMS will be in memory during all container's lifetime. */ AfxOleLockApp( ); } return bInit; } SL-GMS Termination There are two ways to terminate SL-GMS from the control. The first is contained in the application’s ExitInstance method: BOOL CMyproject_axApp::ExitInstance() { int ret = COleControlModule::ExitInstance(); Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-4 if (ret == 0) gmsQuit(); return ret; } The second termination method is provided by the control’s CloseModel method void CMyproject_axCtrl::CloseModel() { char winmod_name[256]; create_winmod_name(winmod_name, (unsigned long)m_hWnd); deactivate_state(winmod_name); } Displaying the Model To display a Model, an SL-GMS State framework is required. The control’s OnCreate method calls the neccessary functions to create the State framework and display the Model. int CMyproject_axCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct ) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; // create an instance of custom top // state if (!gmsQStTopState()) { invoke_top_state(); } // Display the Model if modelname set Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-5 if (m_modelname != "") { set_model_name(m_hWnd, m_modelname); } return 0; } The SetModelname method creates the SL-GMS Window Model State that displays the Model using the window already created by the container. The width and height of the window are set in the control’s m_hWnd attribute. void CMyproject_axCtrl::SetModelname(LPCTSTR lpszNewValue) { m_modelname = lpszNewValue; set_model_name(m_hWnd, m_modelname); SetModifiedFlag(); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-6 ActiveX and HTML The myproject_ax directory contains an HTML page for use with web browsers that support ActiveX controls. When displayed using MS Internet Explorer, the page appears as shown in Figure B-1. Figure B-1Web Page with SL-GMS ActiveX Control The content of the HTML page is shown below. SL-GMS ActiveX Demo Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-7
Where • OBJECT -- This tag is used to embed the ActiveX control in the web page. • ID -- This attribute defines a name for the control instance • WIDTH -- Defines the width in pixels of the window that the browser creates for the control • HEIGHT -- Defines the height in pixels of the window that the browser creates for the document. • CLASSID -- A unique identifier for the control • PARAM -- This attribute is used to specify the name and value of parameters that are passed to the control. CODEBASE The CODEBASE attribute of the OBJECT tag is not used because the location of the SL-GMS ActiveX control is defined in the system registry when the demo is installed and built. When viewed in MS Internet Explorer the sample HTML page appears as shown in Figure B-1 on page -7. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-8 ActiveX and Visual Basic The ActiveX Visual Basic example, myproject_ax_vb, uses the same SL-GMS ActiveX control as the HTML example. While the HTML example only used the control’s modelname property, the Visual Basic example adds use of the control’s SendStateMessage method to control the underlying SL-GMS application. The Visual Basic example uses ComboBoxes and CommandButtons to interface with the control’s features. The buttons and code provided demonstrate how to configure the Enhanced State Management System’s View Manager, how to change the update period of the SL-GMS application, how to interactively change the current Model, and how to perform zoom and pan operations with the View Manager. Figure B-2ActiveX Visual Basic Example Initialization The Form’s Form_Load method contains code that defines all ComboBox items, loads the initial Model, sets the initial update period, and invokes the View Manager as shown below. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-9 Private Sub Form_Load() Dim winmodname, viewname g_home = Environ("GMS_HOME") If (g_home = "") Then MsgBox ("GMS_HOME not defined - demo will not function") End If Myproject_ax1.modelname = "pidface_24" g_status = Myproject_ax1.SendStateMessage("my_std_topst", "update_period", "500") g_status = Myproject_ax1.SendStateMessage("my_std_topst", "stupdate_flag", "1") g_status = Myproject_ax1.SendStateMessage("WinModState", "app_window_handle", "") g_status = Myproject_ax1.SendStateMessage("WinModState", "app_subwindow_handle", "") winmodname = Myproject_ax1.GetWinModName viewname = winmodname + "_" + "ViewState" g_status = Myproject_ax1.SendStateMessage("ViewMgrState", "state_create", "viewmgr") g_status = Myproject_ax1.SendStateMessage("viewmgr", "zoomfactor_limit", "0.1") g_status = Myproject_ax1.SendStateMessage("viewmgr", "pan_percent", "0.20") g_status = Myproject_ax1.SendStateMessage("viewmgr", "boundary_percent", "0") Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-10 g_status = Myproject_ax1.SendStateMessage("viewmgr", "view_state_name", viewname) g_status = Myproject_ax1.SendStateMessage("viewmgr", "state_activate", "my_std_topst_backplane") rate_box.AddItem ("100 msecs") rate_box.AddItem ("250 msecs") rate_box.AddItem ("500 msecs") rate_box.AddItem ("1000 msecs") rate_box.ListIndex = 1 graph_box.AddItem ("Cluster Bars") graph_box.AddItem ("Custom") graph_box.AddItem ("Difference Bars") graph_box.AddItem ("Horiz Bars Shift") graph_box.AddItem ("Horiz Bars") graph_box.AddItem ("Horiz Trend") graph_box.AddItem ("Horiz Trend Bar") graph_box.AddItem ("Line Plot") graph_box.AddItem ("Linear Log") graph_box.AddItem ("Log Log") graph_box.AddItem ("Mark Line") graph_box.AddItem ("Radial") graph_box.AddItem ("Scatter") graph_box.AddItem ("Stacked Bars") graph_box.AddItem ("Stock Price") graph_box.AddItem ("Time Plot") graph_box.AddItem ("Vert Trend") graph_box.AddItem ("Vert Trend Bar") graph_box.ListIndex = 0 dynactions_box.AddItem dynactions_box.AddItem dynactions_box.AddItem dynactions_box.AddItem dynactions_box.AddItem dynactions_box.AddItem Version 6.2a- 26 May 2006 ("Arc dynamics") ("Edge/Fill dynamics") ("Redraw dynamics") ("Submodel dynamics") ("Fill percent dynamics") ("Graph dynamics") SL-GMS Examples Manual B-11 dynactions_box.AddItem ("Math functions") dynactions_box.AddItem ("Nested dynamics") dynactions_box.AddItem ("Path dynamics") dynactions_box.AddItem ("Special dynamics") dynactions_box.AddItem ("Scale/Rotate dynamics") dynactions_box.AddItem ("Text dynamics") dynactions_box.ListIndex = 8 process_box.AddItem ("PID") process_box.AddItem ("Plant Status") process_box.AddItem ("Batch Reactor") process_box.AddItem ("Batch Mixer") process_box.AddItem ("Meters") process_box.AddItem ("Truck Factory") process_box.AddItem ("Generation Facility") process_box.ListIndex = 0 End Sub User Interface The Form used by the Visual Basic example contains three CommandButtons, four ComboBoxes, one Label, and one instance of the SL-GMS ActiveX control. The ComboBox at the top of the form is used to select a data update rate. The three ComboBoxes on the right side of the form are used to select the SL-GMS Model displayed by the SL-GMS ActiveX control. The CommandButtons and the ComboBoxes have each have a Click method with code that communicates with the SL-GMS ActiveX Control. The Click methods for the three ComboBoxes on the right side of the form use the control’s modelname property to change the Model displayed by the control as shown by the code for the process_box_Click method below. Private Sub process_box_Click() Dim modelname As String If (process_box.Text = "Truck Factory") Then modelname = "truck_fact" ElseIf (process_box.Text = "Meters") Then Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-12 modelname = "moremeters" ElseIf (process_box.Text = "Generation Facility") Then modelname = "generate" ElseIf (process_box.Text = "Plant Status") Then modelname = "a_status" ElseIf (process_box.Text = "Batch Reactor") Then modelname = "batreactor" ElseIf (process_box.Text = "Batch Mixer") Then modelname = "bmixer" Else modelname = "pidface_24" End If Label1.Caption = process_box.Text Myproject_ax1.modelname = modelname g_status = Myproject_ax1.SendStateMessage("viewmgr", "reset_view", "") End Sub The CommandButton Click methods use the SL-GMS ActiveX Control’s SendStateMessage method to send zoom messages to the SL-GMS View Manager as shown below. Private Sub zoomout_Click() g_status = Myproject_ax1.SendStateMessage("viewmgr", "zoomout_once", "") End Sub Limitations • SL-GMS ActiveX not certified The SL-GMS ActiveX object is not yet officially certified by a registration firm. This means that to view this object locally or on the Internet, the security settings on the MS Internet Explorer must be set to accept downloads of all ActiveX objects: settings are safety level = NONE. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-13 • SL-GMS environment Clients must have SL-GMS installed and GMS_HOME defined as a system environment variable. • MS Visual C++ 4.2 DLLs The SL-GMS ActiveX object relies on specific MS Visual C++ 4.2 DLLs. Without the runtime DLLs being present on the client's system path, it will not operate. Version 6.2a- 26 May 2006 SL-GMS Examples Manual B-14 Detailed Analysis: myproject_jb C Introduction The SL-GMS Java Bean ("GmsBean") is a Java Bean which displays and animates an SL-GMS Model. It can be used directly in a Java application, or it can be studied as an example of a Java Bean that incorporates an SL-GMS application. An application can contain any number of GmsBeans, each displaying the same or a different SL-GMS Model, and each listening to the same or different DataSource beans. Following the Java Beans API, a GmsBean can receive data - variables and values in a PropertyChange event. Sample DataSource beans, written in Java, are supplied to demonstrate the GmsBean and to show how a data-source interacts with a GmsBean. The GmsBean can be used in a visual IDE, such as Symantec's Visual Café, on either Windows NT, Windows 95, or Sun Solaris. It is placed in the IDE's Component Library, and, like any Java Bean, dragged to the designer work area and hooked up to other Beans. The GmsBean has been tested in Symantec Visual Café, and testing in Borland JBuilder, IBM Visual Age, and Sun Studio is underway. Examples The myproject_jb directory not only contains the files required to build the SL-GMS Java Bean, it also contains several examples of its use. 1. MyProjectJavaBean MyProjectJavaBean is a Java application which is defined in the file "MyProjectJavaBean.java". Once the GmsBean is built, and the Java environment is properly configured, the MyProjectJavaBean example is executed with the following command line: java MyProjectJavaBean Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-1 . Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-2 2. GmsBeanApplet The file "GmsBeanApplet.java" defines an applet that can be used in HTML pages as shown below. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-3 3. GmsBeanMain The file "GmsBeanMain.java" is generated by performing the tutorial steps described later in this chapter with Visual Café PDE 2.5. The GmsBeanMain example uses additional beans and classes. It demonstrates how to build a Java datasource and interface it with a GmsBean. The final application is shown below. SL-GMS Java Bean There are two major parts to the SL-GMS Bean. The first part is the Java classes that define the Bean. The second part is a native shared library, either GmsBeanC.dll (for 32-bit Windows) or GmsBeanC.so (for Solaris) that contains the C and C++ modules that define the SL-GMS application, and the modules that integrate the SL-GMS application with the bean. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-4 Java Source Files The SL-GMS Bean is defined by the following Java files: SL-GMS Bean Java Files File Description GmsBean.java Defines the GmsBean class. GmsBean extends the Java Canvas class. GmsThread.java Defines the thread in which SL-GMS code is executed. This class also initializes SL-GMS, and uses an event loop to monitor and forward events to SL-GMS GmsStateMessage.java Supports the GmsThread class with the ability to store SL-GMS State Class Library Interface message components. Currently provided as a seperate class due to the lack of inner class support in some commercial IDE products. GmsStateVariables.jav a Supports the GmsThread class with the ability to store dynamic variables. Currently provided as a seperate class due to the lack of inner class support in some commercial IDE products. GmsVariable.java An interface class that contains the API for interfacing dynamic variables to a GmsBean. Variable.java A sample implementation of the GmsVariable interface. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-5 DLL Source Files The DLL, "GmsBeanC.dll", is built from the following files: DLL Source Files File Description gmsbeanc.c Contains the SL-GMS C language functions that are called through the Java Native Interface. The functions initialize SL-GMS, activate a specified SL-GMS Model, process events, and send SL-GMS messages. GmsBeanWin.cpp Contains the C++ code that creates a WIN32 window. gmsfuns.c Contains SL-GMS support and utility functions. com_sl_GmsThread.h This file is generated by the Java Development Kit javah utility for "GmsThread.java". It contains the prototypes of Java Native Interface functions that call the C language funtions in "gmsbeanc.c". jnifunc.c Contains implementations of the functions specified in "com_sl_GmsThread.h". user_ds.c Defines the data generation functions for the myproject_common example. user_top.c Defines the custom Top State for the myproject_common example. user_ds1.c Contains a set of data functions that are used with Java datasources. Properties The name of the SL-GMS Model to be displayed is a GmsBean property, and it can be set either in the Property Sheet at design time, or by sending a message at run time. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-6 Building the DLL To build GmsBeanC.dll you must have a SL-GMS development system installed and configured correctly. 1. Be sure that the file 'com_sl_GmsThread.h' is in the GmsBeanC subdirectory of the GmsBean base directory. (See "Installing the GmsBean C/C++ shared library module", above.) 2. Start Microsoft Visual C++. 3. From the File menu pick New, and from the New dialog pick 'Win32 Dynamic-Link Library'. In the Location slot enter the path to the subdirectory GmsBeanC. Enter the project name 'GmsBeanC' and hit OK. 4. From the Project menu pick 'Add to Project', 'Files'. The Insert dialog that appears should show the GmsBeanC directory, and the three C and C++ files should appear. Select all three files and hit OK. 5. Set the Visual C++ Project settings for compiling: pick Settings from the Project menu, and pick the C++ tab in the dialog. • In the General category, add 'WINNT' to the 'Preprocessor definitions' slot. • In the Code Generation category under 'Use run-time library' select 'Multithreaded DLL'. • In the Preprocessor category, in directories' slot, put: • C:\%GMS-HOME%\lib;C:\VisualCafePDE\Java\Include; C:\VisualCafePDE\Java\Include\win32 the 'Additional include 6. Set the Visual C++ Project settings for linking: pick the Link tab in the Project Settings dialog. • In the General Category, under 'Output file name' enter the full path to the GmsBean library directory, followed by '\GmsBeanC.dll'. • In the General Category, look at the 'Object/library modules' slot. Besides the default libraries (beginning kernel32.lib and ending odbccp32.lib) the following are needed: javai.lib spromeps.lib Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-7 libsmsnew.lib libsmsnt.lib libsms.lib libgmd.lib libdms.lib libgms.lib libgws.lib libgwsnt.lib. If they are not there, add them in front of kernel32.lib. • In the Input Category, look at the 'Object/library modules' slot. It should contain the same values as the Object/library modules' slot in the General Category. • In the Input Category, in the 'Additional library path' slot, put: C:\%GMS_HOME%\lib;C:\VisualCafePDE\Java\Lib 7. Hit OK in the Project Settings dialog. 8. Now build the GmsBeanC.dll library by picking 'Build GmsBeanC.dll' in the Build menu. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-8 Building a GmsBean demo in Visual Café PDE 2.5 The GmsBeanMain example discussed earlier, is built using Symantec Visual Café with the procedures described in this section. The resulting file "GmsBeanMain.java" can be compiled and executed by any Java system. The GmsBeanMain demo uses three custom JavaBeans and a number of standard beans. The custom beans are the GmsBean, and two GmsDataSource beans. GmsBean extends the Java Canvas class. In a visual IDE a GmsBean can be dragged to a Java Container object, positioned and sized, and have its properties set. Once the bean is placed in a container and its ModelName property is set, it calls native C/C++ functions that invoke the SL-GMS dynamic graphics engine to display a SL-GMS model in the bean's canvas. An abstract class, "GmsDataSource.java", and two beans which extend it, "DataSourceW.java" and "DataSourceDyn.java", are provided to show how a Java-coded data source is connected to a GmsBean. "DataSourceW.java" generates data for a specific SL-GMS model ("windtunnel") while "DataSourceDyn.java" generates data for the models in the "demo/dynactions" directory of the SL-GMS distributed system. Also included is a timer class, Timer.java, which is used by the GmsDataSource beans. The DataSource beans are coded completely in Java, and are intended to be examples of the type of data source that feeds data to GmsBeans. They define and assign values to the variables used in the models. At timed intervals they generate new data values and fire a PropertyChange event that contains the variable names and values. GmsBeans and other objects can register as listeners and thus be informed each time that new data values are generated. Preparations 1. Setting up the directories • Select a base directory under GMS_HOME, for example, \gmsbean. • Put the SL-GMS test models in this base directory. Make the models by executing 'gm1 *.g'. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-9 • Under the base directory make the subdirectories com\sl and put the java class files there. This is necessary because the GmsBean java classes are in the package com.sl. • Under the base directory make the subdirectory GmsBeanC; put the c/cpp/h files there. • Pick a directory for the C shared library file (GmsBeanC.dll). For Windows NT 'winnt\system32' is a good choice, since it is in the system path. • Pick a directory for the Java jar file (gmsbean.jar). You may wish to use a default path used by Visual Café PDE which is 'VisualCafePDE\java\lib'. 2. Setting up the paths to run in either Visual Café or a DOS window • Add the directory chosen for C shared library file to the System Properties User Variables 'path' environment variable, if it is not already there. • Add to the System Properties User Variables 'classpath' environment variable both the jar file directory name and the directory name followed by '\gmsbean.jar'; e.g., if the library directory is C:\ VisualCafePDE\java\lib then add both 'C:\ VisualCafePDE\java\lib' and 'C:\ VisualCafePDE\java\lib \gmsbean.jar'. • Add to the Visual Café sc.ini file 'CLASSPATH=' line both the jar file directory name and the directory name followed by '\gmsbean.jar', if they are not already there. 3. Building the Java classes • Run Visual Café (Version PDE 2.5 was used for this example). • Close any open projects. • From the File menu pick 'New Project'. • In the New Project dialog pick 'Empty Project', OK. • From the Insert menu pick 'Files into Project'. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-10 • In the Project Files dialog browse to the \com\sl directory; you will see the Java files there; pick 'Add All', OK. In the Project window at the left you will see Java objects; pick the Files tab and you will see the file names. • From the File menu pick 'Save All'; in the Save As dialog browse to the GmsBean base directory and enter 'gmsbean' in the File name slot; hit Save. • From the Project menu pick 'JAR'. The java files will be compiled (you will see "Build Successful" in the lower left corner) and a JAR Packager dialog will appear. • In the JAR dialog pick GmsBean.class and (with the Control key held down) DataSourceW.class and DataSourceDyn.class, so that all three are selected. Pick the 'Java Bean' check box at the right -- this will mark the selected classes as Java beans. In the 'JAR File:' slot at the bottom, enter the full path to the gmsbean.jar directory chosen in Step 1, followed by '\gmsbean.jar'. Now hit OK in the lower right corner. This will create the jar file and place it in the specified directory. • Close the project by picking 'Close Project' from the File menu. 4. Installing the GmsBean C/C++ shared library module (GmsBeanC.dll) • If GmsBeanC.dll is included in your distribution, then move it to the C shared library file directory chosen in Step 1 above. • If GmsBeanC.dll does not exist, you must build it. First, produce the GmsBean native function include files. Open a DOS window and change directory to the GmsBean base directory. Type the following command: 'javah -jni com.sl.GmsThread'. This will produce the file 'com_sl_GmsThread.h', which contains declarations of the C functions which implement the Java native methods. Move this .h file to the GmsBeanC subdirectory • To build the library file, see "Building the GmsBean C/C++ shared library module" in the Notes at the end of this document. 5. Loading the beans into the Visual Café Component Library • Start Visual Café, if it is not already running. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-11 • Locate the Component Library window in the Visual Café window. It is probably at the left. If it is not there, pick 'Component Library' from the View menu and it will appear. • Open a Windows file window - e.g., Explorer - and browse to the gmsbean.jar directory. You will see the file gmsbean.jar there. Drag gmsbean.jar to the Visual Café Component Library window; after a delay you will see a 'gmsbean' folder appear there, containing GmsBean, DataSourceW and DataSourceDyn. If they fail to appear, there is probably a path error - see "troubleshooting" below. You are now ready to build the GmsBeanMain demo. Building the demo First, be sure that the SL-GMS environment is properly set up - key, dongle, environment variables, etc. Be sure the paths are correctly set, and that the jar file and the shared library are in the correct places. Start Visual Café, if it is not already running. Look at the Component Library window. If the gmsbean folder is not there, add it, as explained above. 1. Create the application. • Start with File/New Project and select "Empty Project" from the wizard, then hit OK. From the Insert menu pick 'Form', and pick "Frame" in the dialog that appears. A "Form Designer" window appears. Size the Window as you wish. It is a Java Container a Frame - in which GmsBeans and other beans will be placed. • If the Property List window is not open, pick 'Property List' from the View menu to open it. Pick the Container and change the Name and Title in the Property List to whatever you wish, e.g.: Name | GmsBeanMain Title | SL-GMS JavaBean Demo 2. Put GmsBeans in the Container. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-12 • Drag one or more GmsBean beans from the Component Library window into the Form Designer window. Position and size them as desired. • Pick a GmsBean; its properties appear in the Property List window. Only the 'ModelName' property is specific to a GmsBean; the other properties are properties of Canvas, which GmsBean extends. Any of the properties can be changed. The ModelName property is initially blank; enter the name of a SL-GMS model that is in the directory in which the application is being built, e.g., "windtunnel" or "fp_attrs". 3. Specify the interactions between the GmsBeans and the Container. • Right-mouse in the Container and pick 'Add Interaction'. • In the wizard that appears pick 'windowActivated' in the first box, 'gmsBean1' in the second, and 'containerActivated' in the third; hit Finish. This causes the GmsBean to be informed when its container window has been activated, so that the GmsBean can find the window handle and prepare to display a SL-GMS model. • Repeat for the other GmsBeans. • Right-mouse in the Container and pick 'Add Interaction'. • In the wizard that appears pick 'windowClosing' in the first box, 'gmsBean1' in the second, and 'containerClosing' in the third; hit Finish. This causes the GmsBean to be informed when its container window will be closing (the user picked "X" in the upper right corner of the window), so that the GmsBean can terminate the SL-GMS system and exit the application. Do this for only one of the GmsBeans. 4. Build and save the application. • Pick 'Build Application' from the Project menu. The application will be compiled, and "Build Successful" will appear in the lower left corner of the Visual Café window. • Pick 'Save All' from the File menu. In the File dialog that appears, pick a directory that contains SL-GMS models. For the Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-13 File name use the Container name, e.g., "GmsBeanMain". Hit Save. 5. Run the application. • Pick 'Execute' from the Project menu. A DOS window will appear, followed by a window labeled "SL-GMS JavaBean Demo" (or whatever you specified as the Title of the main Container) and containing the GmsBeans you created; each GmsBean will display the SL-GMS model named in its ModelName property. • Quit by hitting the "X" in the upper right corner of the window. Add DataSource Beans 1. Put a DataSource bean in the application. • Drag either a DataSourceW bean or a DataSourceDyn bean from the Component Library to the Form Designer window and place it somewhere out of the way. It is an "invisible bean", i.e. a bean that has no GUI component and consequently will not appear at runtime. Which DataSource bean you use depends on the dynamic variables in the SL-GMS models you intend to display. • In the Property List for the DataSource bean, 'TimerInterval' is the only property that can be set; it is the time interval in milliseconds between generations of data. Set it to a reasonable value, say 500. 2. In each GmsBean be sure that the ModelName property names a model that uses the variables defined in the DataSource bean, e.g., "windtunnel" for the DataSourceW bean, or "fp_attrs" for the DataSourceDyn bean. 3. Specify the interactions of the DataSource bean with the GmsBeans. (This must be done by editing source code, since Visual Café does not see the PropertyChange event of the DataSource bean as an 'interaction') • Right-mouse the DataSource bean and pick 'Edit Source'. In the source-code window that opens pick 'dataSourceW1' or Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-14 'DataSourceDyn1' in the Objects box, and 'propertyChange' in the Events/Methods box. • The window scrolls to 'dataSourceW1_propertyChange' or 'dataSourceDyn1_propertyChange'. This method will be executed when the dataSource bean generates a propertyChange event. At 'to do: code goes here' enter: 'gmsBean1.propertyChange(event);'. This will cause the event to be passed to gmsBean1. • Pick the 'X' in the upper right corner of the source-code window to close the window. Visual Café will automatically save the source code changes. • Repeat for the other GmsBeans. 4. Build and run the application. • Pick 'Execute' from the Project menu. The models displayed in the GmsBeans will animate. Add TextFields In this section text fields are added to show the Model name and allow the Model to be changed. 1. For each GmsBean drag a TextField component from the Standard folder in the Component Library and place it under the GmsBean; position and size the TextFields. 2. 2. Show the model name in each TextField. • Right-mouse in the Container and pick 'Add Interaction'. • In the wizard pick 'windowActivated' in the first box, 'textField1' in the second, and 'set the text for the TextField' in the third; hit Next. • In the next dialog pick 'Another Item', then 'gmsBean1' in the first box and 'getModelName' in the second; hit Finish. This causes the TextField to show the initial model name of the corresponding GmsBean. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-15 • Repeat for the other GmsBeans. 3. Change the SL-GMS model in the GmsBean if the model name is changed. • Right-mouse the first TextField and pick 'Add Interaction'. • In the wizard pick 'enterHit' in the first box, 'gmsBean1' in the second, and 'setModelName' in the third; hit Next. • In the next wizard, pick 'Another Item', then 'textField1' in the first box and 'Get the contents of the TextField' in the second; hit Finish. Now when Enter is hit in the text field, the GmsBean setModelName method will be called, and the bean will know that the SL-GMS model name has been changed. • Repeat for any additional TextFields and GmsBeans. 4. Build and run the application. • Pick 'Execute' from the Project menu. The models displayed in the GmsBeans will animate, and the model names will appear in the TextFields. • Type a model name in one of the TextFields, and hit Enter. The newly named model will be displayed in the GmsBean, and - if the model references variables defined in the DataSource bean it will animate. You may enter the name of a model in the current directory, or you may enter a model name with a directory path to select a model in another directory. • Type the full path name of the demo/dynactions/dyn_top model into the TextField of a GmsBean that is attached to a DataSourceDyn bean. The model 'dyn_top' will appear; pick any button in 'dyn_top' (but not the "P" button - see "Bugs" below) and a dynactions model will appear and animate. Right-mouse in the window and the GmsBean will return to the top model. Sending an SL-GMS State Message A SL-GMS State Message has three String arguments: 'state_name', the name of the SL-GMS state to send the message to; 'state_message', the message to send; and 'state_argument', the argument of the message. The GmsBean class has a 'stateMessage(name, message, argument)' Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-16 method; however, to interact more smoothly with Visual Café, three single-argument methods are provided: 'setStateName(String name)', 'setMessage(String message)', and 'setArgument(String argument)'. If the state_name argument is null or is not supplied, the message will be sent to the state with the same name as the GmsBean. (This is a WinModState, a state that displays a model in a window.) To demonstrate the GmsBean State Message capability, the following will send a "view_wc_extent" message to the GmsBean's WinModState. This message takes a string argument that contains four integers which represent a rectangular extent in SL-GMS world coordinates. The message causes the size of the window to change so that the window displays the specified extent. 1. Provide a labeled text field in which to enter the extent. • Drag a TextField to the Form Designer window and position it under the first GmsBean. Note the TextField's name in the Property List. • Drag a Label and position it to the left of the TextField. • Enter "Set extent (X Y X Y): " in the text Property of the Label. 2. Send the contents of the text field in a "view_wc_extent" message. • Right-mouse the TextField and pick 'Add Interaction'. • In the wizard pick 'enterHit' in the first box, 'gmsBean1' in the second, and 'setMessage' in the third; hit Next. • In the next wizard pick 'a java.lang.String constant or an expression' and enter "view_wc_extent" (without the quotes) in the field. Hit Finish. • Again right-mouse the TextField and pick 'Add Interaction'. • In the wizard pick 'enterHit' in the first box, 'gmsBean1' in the second, and 'setArgument' in the third; hit Next. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-17 • In the next wizard, pick 'Another Item', then the TextField's name in the first box and 'Get the contents of the TextField' in the second; hit Finish. 3. Build and run the application. • Pick 'Execute' from the Project menu. • Type an extent (e.g., "0 0 72 54", without quotes) in the 'Extent' text field, and hit Enter. The display in the gmsBean1 window will scale so that the specified extent (in SL-GMS world coordinates) will fill the window. Zooming In and Out The display in the GmsBean can be zoomed in or out by sending SL-GMS State Messages. The GmsBean class has methods that send the proper messages to cause zooming. 1. 1. Provide "Zoom In" and "Zoom Out" buttons. • Drag two Buttons to the Form Designer window, and position and size them. Select one and, in its Property List, change its Label to 'Zoom In'. Select the other and change its Label to 'Zoom Out'. • Right-mouse the Zoom In button and pick 'Add Interaction'. • In the wizard pick 'actionPerformed' in the first box, 'gmsBean1' in the second, and 'zoomIn' in the third; hit Finish. • Right-mouse the Zoom Out button and pick 'Add Interaction'. • In the wizard pick 'actionPerformed' in the first box, 'gmsBean1' in the second, and 'zoomOut' in the third; hit Finish. 2. Build and run the application. • Pick 'Execute' from the Project menu. The models will display and animate, as before. • Use the Zoom buttons to zoom the display in and out. NOTE: The following steps provide no further interaction with the SL-GMS Java Beans. Their purpose is to illustrate Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-18 enhancements to the use of the Java DataSource beans by adding timer control and a text display. Adding Timer Control. The timer in the DataSource bean can be controlled by executing the DataSource methods startTimer, stopTimer and setTimerInterval. To control the timer with standard Java GUI beans, do the following: 1. Use two Buttons to start and stop the timer. • Drag two Buttons to the Form Designer window, and position and size them. Select one and, in its Property List, change its Label to 'Start'. Select the other and change its Label to 'Stop'. • Right-mouse the Start button and pick 'Add Interaction'. • In the wizard pick 'actionPerformed' in the first box, 'dataSourceW1' or 'dataSourceDyn1' in the second, and 'startTimer' in the third; hit Finish. • Right-mouse the Stop button and pick 'Add Interaction'. • In the wizard pick 'actionPerformed' in the first box, 'dataSourceW1' or 'dataSourceDyn1' in the second, and 'stopTimer' in the third; hit Finish. 2. Use a Horizontal Scrollbar to set the timer interval. • Drag a Horizontal Scrollbar object to the Form Designer window, and position and size it. • In the Scrollbar Property List set Minimum to 100, Maximum to 2000, and Unit Increment to 50. • Right-mouse the Scrollbar and pick 'Add Interaction'. • In the wizard pick 'adjustmentValueChanged' in the first box, 'dataSourceW1' or 'dataSourceDyn1' in the second, and 'setTimerInterval' in the third; hit Next. • In the next wizard, pick 'Another Item', then 'horizontalScrollbar1' in the first box and 'Get the Scrollbar's value' in the second; hit Finish. Now when the slider of the scrollbar is moved, the Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-19 DataSource's setTimerInterval method will be called, and the timer interval will be changed. • Right-mouse in the Container and pick 'Add Interaction'. • In the wizard pick 'windowActivated' in the first box, 'horizontalScrollbar1' in the second, and 'set the Scrollbar's value' in the third; hit Next. • In the next dialog pick 'Another Item', then 'dataSourceW1' or 'dataSourceDyn1' in the first box and 'getTimerInterval' in the second; hit Finish. This initializes the Scrollbar. 3. Use a Label to display the timer interval. • Drag a Label object to the Form Designer window, position above the ScrollBar and size it fairly small. • In the Label's Property List set the 'Alignment' property to CENTER, and the 'Text' property to blank. Notice the Label's name (probably 'label2'). • Right-mouse the Scrollbar and pick 'Add Interaction'. • In the wizard pick 'adjustmentValueChanged' in the first box, 'label2' in the second, and 'set the text for Label' in the third; hit Next. • In the next wizard, pick 'Another Item', then 'dataSourceW1' or 'dataSourceDyn1' in the first box and 'getTimerIntervalString' in the second; hit Finish. Now when the slider of the scrollbar is moved, the Label will be updated by getting the timer interval in String form from the dataSource bean. • Right-mouse in the Container and pick 'Add Interaction'. • In the wizard pick 'windowActivated' in the first box, 'label2' in the second, and 'set the text for Label' in the third; hit Next. • In the next dialog pick 'Another Item', then 'dataSourceW1' or 'dataSourceDyn1' in the first box and 'getTimerIntervalString' in the second; hit Finish. This initializes the Label. 4. Build and run the application. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-20 • Pick 'Execute' from the Project menu. The models will display and animate, as before. The timer interval will be displayed in the Label field. • Control the timer using the 'Start' and 'Stop' buttons, and the Scrollbar. Notice that the timer control only affects the GmsBeans that are attached to the specified DataSource. Add Another Listener Objects other than GmsBeans can listen to data changes from the DataSource beans. The object must know how to handle the data formats provided by a DataSource bean. They use an array of com.sl.Variable, and provide to the listeners a reference to this array in a PropertyChangeEvent; GmsBeans know how to handle the Variable array. The DataSource beans also provide a list of variable names and latest values in their toString methods. The following uses PropertyChangeEvent and DataSourceW.toString( ) or DataSourceDyn.toString( ) to display the generated data in a TextArea. 1. Create a TextArea to display the data. • Drag a TextArea object to the Form Designer window. Size the object large enough to display 8 lines about 20 characters long. • Pick the TextArea and observe its name - assume it to be 'textArea1'. 2. Connect the TextArea to the DataSource bean. • Right-mouse the DataSource bean and pick 'Edit Source'. Pick 'dataSourceW1' or 'dataSourceDyn1' in the Objects box, and 'propertyChange' in the Events/Methods box. • The window scrolls to a method named 'dataSource[W/Dyn]1_propertyChange'. This method will be executed when the dataSource[W/Dyn]1 bean generates a propertyChange event. At 'to do: code goes here' add the line 'textArea1.setText(dataSource[W/Dyn]1.toString());'. This will cause the variable names and values to be displayed in the TextArea each time DataSource fires a PropertyChange event. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-21 • Pick the 'X' in the upper right corner of the source-code window to close the window. 3. Build and run the application. • Pick 'Execute' from the Project menu. The models will display and animate, as before. The names, types and values of the variable data generated by the DataSource bean will appear in the TextArea, changing each time new values are generated. Running the finished demo in a DOS window Build the application in Visual Café or some other visual IDE. Locate the Java class that contains the main( ) method - we will assume it is named 'GmsBeanMain'. Be sure that the SL-GMS environment is properly set up and that the GmsBean C/C++ shared library module is in a directory that is in the system library path. Set the system CLASSPATH environment variable to include the path of the gmsbean.jar file. Open a DOS window and change directory to the directory that contains GmsBeanMain.class. In the DOS window type: java GmsBeanMain Creating an Applet To use Visual Cafe to make an applet that uses the GmsBean JavaBean: 1. Create the applet. • Start with File/New Project and select "Basic Applet" from the wizard, then hit OK. A "Form Designer" window appears. Size the Window as you wish. • If the Property List window is not open, pick 'Property List' from the View menu to open it. • Pick the Applet and change the Name in the Property List to whatever you wish, e.g.: Name | GmsBeanApplet 2. Put GmsBeans in the applet. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-22 • Drag one or more GmsBean beans from the Component Library window into the Form Designer window. Position and size them as desired. • Pick a GmsBean; its properties appear in the Property List window. Only the 'ModelName' property is specific to a GmsBean; the other properties are properties of Canvas, which GmsBean extends. Any of the properties can be changed. The ModelName property is initially blank; enter the name of a SL-GMS model that is in the directory in which the application is being built, e.g., "windtunnel" or "fp_attrs". 3. Specify the interactions between the GmsBeans and the applet. • Right-mouse in the Container and pick 'Edit Source'. • Make the following changes in the Java source file that appears: - Take out the line beginning "symantec.itools.awt.util.StatusScroller". - Add the following line to public void init( ) at the end: gmsBean1.containerActivated( ); - Add the following method: public void destroy( ) { gmsBean1.appletClosing( ); } 4. Put a DataSource bean in the application. • Drag either a DataSourceW bean or a DataSourceDyn bean from the Component Library to the Form Designer window and place it somewhere out of the way. • In each GmsBean be sure that the ModelName property names a model that uses the variables defined in the DataSource bean, Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-23 e.g., "windtunnel" for the DataSourceW bean, or "fp_attrs" for the DataSourceDyn bean. 5. Specify the interactions of the DataSource bean with the GmsBeans. • Right-mouse the DataSource bean and pick 'Edit Source'. In the source-code window that opens pick 'dataSourceW1' or 'DataSourceDyn1' in the Objects box, and 'propertyChange' in the Events/Methods box. • The window scrolls to 'dataSourceW1_propertyChange' or 'dataSourceDyn1_propertyChange'. At 'to do: code goes here' enter: 'gmsBean1.propertyChange(event);'. • Pick the 'X' in the upper right corner of the source-code window to close the window. • Repeat for the other GmsBeans. 6. Build and save the applet. • Pick 'Build Applet' from the Project menu. The applet will be compiled, and "Build Successful" will appear in the lower left corner of the Visual Café window. • Pick 'Save All' from the File menu. In the File dialog that appears, pick a directory that contains SL-GMS models. For the File name use the Applet name, e.g., "GmsBeanApplet". Hit Save. 7. Run the applet. • Pick 'Execute' from the Project menu. An Applet Viewer window will appear containing the GmsBeans you created; each GmsBean will display the SL-GMS model named in its ModelName property. • Quit by hitting the "X" in the upper right corner of the window. Using the Applet To run a GmsBean applet in Netscape Navigator on the local file system: Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-24 1. Install Sun's Java Plug-in, version 1.1.1, from the Sun website java.sun.com/products/plugin/. Follow the detailed instructions given on that site. 2. Be sure that the directory of gmsbean.jar is in CLASSPATH. 3. Make a 'GmsBeanApplet.html' file as required by the Java Plugin. Here is an example: SL-GMS JavaBean Applet Demo No JDK 1.1 support for APPLET 4. Execute the html file in Netscape Navigator. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-25 Limitations NOTE: The current version of GmsBean does not allow the bean to be destroyed without exiting the main program. Therefore if a browser is displaying an applet containing a GmsBean, and the browser page is either left or reloaded, then the browser itself will exit. The Java security system prevents an applet from accessing the client's file system unless either the applet originates there or the applet is signed by a trusted signer. The above example works because the applet is launched from the same local file system that contains the GmsBean's native code library. To execute on a web page received from a remote server, an applet containing native code must be signed. Information on signing an applet is available on the above-referenced Sun website. At a later date SL Corporation will provide a detailed procedure for signing a GmsBean applet. Bugs 1. If the full path name of the demo/dynactions/dyn_top model is entered into a GmsBean, the model 'dyn_top' will appear; if the "P" button is hit, causing the model 'path_dyn' to be loaded, the program crashes. 2. Zoom-out leaves traces of the previous display in the window. Troubleshooting To avoid java.lang.UnsatisfiedLinkError: 1. All native calls must have entry points in the shared library (GmsBeanC.dll). 2. The entry point must name have the full package name with the correct signature, e.g., for cGmsInitialize in GmsThread.java in the package com.sl the entry point name is Java_com_sl_GmsThread_cGmsInitialize(JNIEnv *, jobject, jint). 3. The shared library must be in the path: • If running from a DOS window, do 'set path' and be sure the library is in the path. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-26 • If running from Visual Café check the 'PATH=' setting in VisualCafePDE/bin/sc.ini. 4. Avoid having another library by the same name as the one that is in the path, as it may have different entry point names. If Visual Café does not recognize a bean, i.e., if the bean cannot be inserted in Visual Café's Component Library, or if Visual Café hangs when the bean is inserted: 1. The jar containing the bean must be in the classpath: • If running from a DOS window, do 'set classpath' and be sure the jar is in the path. • If running from Visual Café check the 'CLASSPATH=' setting in VisualCafePDE/bin/sc.ini 2. The manifest file in the jar file must specify that the class is a bean. If building the jar file with Visual Café - by using JAR from the Project menu - then specify which classes are Java Beans in the JAR dialog. 3. If the bean calls native functions, the links to the native code entry points must be correctly resolved. 4. An error in the bean code, or something in the bean code that triggers a bug in Visual Café, can cause the Visual Café introspection either to fail to recognize the class as a bean or to hang after installing the bean in the Component Library. For example, either creating a GmsThread or calling the native function cGmsInitialize in a static initializer causes Visual Café to hang when the gmsbean.jar file is inserted into the Component Library. Version 6.2a- 26 May 2006 SL-GMS Examples Manual C-27 Detailed Analysis: myproject_motif D Introduction The myproject_motif example is based on the myproject_common example. The analysis of myproject_motif begins with a Motif framework. A simple Motif-only application is built which has a main window, a menu bar, and a drawing area in which an SL-GMS Model will be displayed. Then, the steps required to add myproject_common to the Motif application are examined. Motif Framework The Motif-only application is based on two source files, "gmsmain.c" and "motif_stuff.c". The steps to build the iniital program are listed below. The major steps required myproject_motif are: to produce the Motif framework for 1. Create an Application Context and a top level shell. shelltop_level = XtAppInitialize(&appContext, "MyprojectMotif", (XrmOptionDescList) NULL, 0, (Cardinal *)&argc, argv,(String *)NULL, args, n); 2. Create a MainWindow widget n = 0; main_win = XmCreateMainWindow(top_level, "MainWin", args, n); XtManageChild (main_win); 3. Create a menu bar. menu_bar = create_menu_bar(main_win); XtManageChild(menu_bar); 4. Create a Widget that SL-GMS can draw in. Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-1 display = XtDisplay(top_level); drawing_area = create_drawing_area(main_win, display); XtManageChild(drawing_area); 5. Attach the menu bar and drawing area to the Main Window. XmMainWindowSetAreas(main_win, menu_bar, NULL, NULL, NULL, drawing_area); 6. Realize the top level shell and enter the event loop. XtRealizeWidget(top_level); XtAppMainLoop(appContext); When executed, the initial version of myproject_motif appears as shown in Figure D-1. Figure D-1Initial Motif-only version of myproject_motif Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-2 Motif Framework Source Files The source files that produce the Motif application discussed in the previous section are provided below for reference. gmsmain.c /********************************************************************** * SL-GMS On-Line Examples: * Topic: Motif Application Framework * Example #:myproject_motif * Purpose:SL-GMS within a Motif framework * Module: gmsmain.c - main module * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #include /* X11 and OSF/Motif include files */ #include #include #include #include #include /* EXPORT */ Widget top_level; /* IMPORT */ Widget create_menu_bar(); Widget create_drawing_area(); /* PRIVATE */ static int evtloop_flag = 0; static XtAppContext appContext; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-3 /**********************************************************************/ /* MAIN */ int main (argc, argv) int argc; char *argv[]; { Arg args[20]; Cardinaln; Widget main_win, menu_bar, drawing_area; Display*display; /* Initialize toolkit and create application context */ n = 0; XtSetArg(args[n], XmNtitle, "Myproject Motif"); n++; top_level = XtAppInitialize(&appContext, "MyprojectMotif", (XrmOptionDescList) NULL, 0, (Cardinal *)&argc, argv, (String *)NULL, args, n); /* Create MainWindow Widget */ n = 0; main_win = XmCreateMainWindow(top_level, "MainWin", args, n); XtManageChild (main_win); /* Create menu bar */ menu_bar = create_menu_bar(main_win); XtManageChild(menu_bar); /* Create drawing area Widget */ display = XtDisplay(top_level); drawing_area = create_drawing_area(main_win, display); XtManageChild(drawing_area); /* Set MainWindow components */ XmMainWindowSetAreas(main_win, menu_bar, NULL, NULL, NULL, drawing_area); XtRealizeWidget(top_level); Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-4 XtAppMainLoop(appContext); } motif_stuff.c /********************************************************************** * SL-GMS On-Line Examples: * Topic: Motif Application Framework * Example #:myproject_motif * Purpose:SL-GMS within Motif framework * Module: motif_stuff.c - Widget creation and callbacks * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #include /* X11 and OSF/Motif include files */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* EXPORT */ /* IMPORT */ extern Widget top_level; /* PRIVATE */ Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-5 static Widget open_dialog; XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET; #define MENU_HELP200 #define MENU_EXIT201 #define MENU_OPEN202 /**********************************************************************/ /* Cancel callback from file selection dialog */ static void cancel_cb (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { XtUnmanageChild(open_dialog); } /**********************************************************************/ /* File selection callback from file selection dialog */ static void file_select_cb (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { char *filename; XmFileSelectionBoxCallbackStruct *cbs; /* Get file name from callback struct */ cbs = (XmFileSelectionBoxCallbackStruct *)call_data; if (!XmStringGetLtoR(cbs->value, #ifdef XmVERSION_STRING XmFONTLIST_DEFAULT_TAG, #else XmSTRING_DEFAULT_CHARSET, #endif &filename)) return; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-6 if (!*filename) { printf("No File selected.\n"); XtFree(filename); return; } /* Do something with the file name here */ XtFree(filename); } /**********************************************************************/ /* Pulldown menu callback */ /* Process menu selections */ static void menu_cb (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { int n; Arg args[10]; char *command; XmString tcs; switch ((int)client_data) { case MENU_EXIT: /* exit this program */ exit(0); break; case MENU_OPEN: if (open_dialog) { XtManageChild(open_dialog); } else { n = 0; open_dialog = XmCreateFileSelectionDialog(top_level, Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-7 "Model Open", args, n); XtAddCallback(open_dialog, XmNcancelCallback, cancel_cb, NULL); XtAddCallback(open_dialog, XmNokCallback, file_select_cb, NULL); XtManageChild(open_dialog); XmStringFree(tcs); } break; default: fprintf(stderr, "Warning: Invalid menu selection.\n"); break; } } /**********************************************************************/ /* CREATE MOTIF MENUBAR */ Widget create_menu_bar (parent) Widget parent; { Widget menu_bar; Widget cascade1, cascade2, cascade3; Widget menu_pane1, menu_pane2, menu_pane3; Widget button1, button2, button3; Arg args[10]; intn; XmString tcs, tcs1; /* Create menu bar */ n = 0; menu_bar = (Widget)XmCreateMenuBar(parent, "menu_bar", args, n); /* Create "File", "Flags" and "Help" menu panes */ n = 0; menu_pane1 = (Widget)XmCreatePulldownMenu(menu_bar, "file_pane", args, n); menu_pane2 = (Widget)XmCreatePulldownMenu(menu_bar, "help_pane", args, n); menu_pane3 = (Widget)XmCreatePulldownMenu(menu_bar, "flags_pane", Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-8 args, n); /* Create "File" cascade button */ n = 0; XtSetArg(args[n], XmNsubMenuId, menu_pane1); n++; tcs = XmStringCreateLtoR("File", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, ’F’); n++; cascade1 = XmCreateCascadeButton(menu_bar, "File", args, n); XtManageChild(cascade1); XmStringFree(tcs); /* Create "Flags" cascade button */ n = 0; XtSetArg(args[n], XmNsubMenuId, menu_pane3); n++; tcs = XmStringCreateLtoR("Flags", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, 'F'); n++; cascade3 = XmCreateCascadeButton(menu_bar, "Flags", args, n); XtManageChild(cascade3); XmStringFree(tcs); /* Create "Help" cascade button */ n = 0; XtSetArg(args[n], XmNsubMenuId, menu_pane2); n++; tcs = XmStringCreateLtoR("Help", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, ’H’); n++; cascade2 = XmCreateCascadeButton(menu_bar, "Help", args, n); XtManageChild(cascade2); XmStringFree(tcs); /* Create "Open" menu button */ n = 0; tcs = XmStringCreateLtoR("Open", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, ’O’); n++; button1 = (Widget)XmCreatePushButton(menu_pane1, "Open", args, n); XtAddCallback(button1, XmNactivateCallback, menu_cb, (XtPointer)MENU_OPEN); XtManageChild(button1); XmStringFree(tcs); Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-9 /* Create "Exit" menu button */ n = 0; tcs = XmStringCreateLtoR("Exit", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, ’E’); n++; tcs1 = XmStringCreateLtoR("F3", charset); XtSetArg(args[n], XmNacceleratorText, tcs1); n++; XtSetArg(args[n], XmNaccelerator, "F3:"); n++; button2 = (Widget)XmCreatePushButton(menu_pane1, "Exit", args, n); XtAddCallback(button2, XmNactivateCallback, menu_cb, (XtPointer)MENU_EXIT); XtManageChild(button2); XmStringFree(tcs); XmStringFree(tcs1); /* Create "Tight Loop" menu button */ n = 0; tcs = XmStringCreateLtoR("Tight Loop", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, 'L'); n++; button4 = (Widget)XmCreateToggleButton(menu_pane3, "Tight Loop", args, n); XtAddCallback(button4, XmNvalueChangedCallback, loop_button_cb, 0); XtManageChild(button4); XmStringFree(tcs); n = 0; XtSetArg(args[n], XmNmenuHelpWidget, cascade2); XtSetValues(menu_bar, args, n); n++; return(menu_bar); } /**********************************************************************/ /* CREATE MOTIF DRAWING AREA */ Widget create_drawing_area (parent, display) Widget parent; Display *display; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-10 { Widget aWidget; Argargs[20]; int i; i = 0; XtSetArg(args[i], XmNx,0); i++; XtSetArg(args[i], XmNy,0); i++; XtSetArg(args[i], XmNwidth, 400); i++; XtSetArg(args[i], XmNheight, 300); i++; aWidget = (Widget)XmCreateDrawingArea(parent, "drawable", args, i); return (aWidget); } Framework Enhancement The Motif framework is now ready for SL-GMS enhancements. The enhancements made which result in the final application are summarized below. Modifications to "gmsmain.c" First, modify the main( ) function in "gmsmain.c" as follows: 1. Initialize SL-GMS after XtAppInitialize( ) gmsInitialize(&argc, argv, 0); 2. Send the top level Widget to the StandardTopState class after the top level Widget is realized. app_widget_handle = (void *)top_level; STMSG_P(G_STDTOPSTATE_CLASSNAME, "app_widget_handle", app_widget_handle); 3. Set window handle variables and initialize the custom Top State. app_window_handle = top_level; app_subwindow_handle = drawing_area; my_top_initialize(); Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-11 4. Add command line processing after my_top_initialize( ). parse_command_line(argc, argv, modelname); 5. Invoke an instance the custom Top State. STINVOKE("my_top", "MyTopState", "", NULL); 6. If a Model name was specified on the command line, send it to the Top State. if (strlen(modelname) > 0) start_gms_model(modelname); 7. Replace XtAppMainLoop( ) with the SL-GMS main event loop, or a custom main loop. switch( evtloop_flag ) { case 0: gmsRunMainLoop(); break; case 1: simple_external_loop(); break; case 2: user_main_loop_run(); default: break; } Then, add the functions to "gmsmain.c" that support the additions made above. The required functions are: 1. parse_command_line( ) static int parse_command_line (argc, argv, modelname) int argc; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-12 char **argv; char*modelname; { int i; char*arg; for (i = 1; i < argc; i++) { arg = argv[i]; /* process args that begin with '-' */ if (*arg == '-') { switch (*++arg) { /* Set event loop flag */ case 'l': case 'L': evtloop_flag = atoi(++arg); break; /* pass -u argument to StdTopState */ case 'u': case 'U': STMSG("StandardTopState", "update_period", ++arg); default: break; } /* arg does not begin with a '-', assume it's a Model file name */ } else { strcpy(modelname, arg); } } Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-13 return (1); } 2. start_gms_model( ) int start_gms_model (filename) char *filename; { char*dir_name; char*modelname; char*strptr; charbuf[G_MAXFILENAME]; /* Copy file name to buffer */ strcpy(buf, filename); /* Remove m1 suffix */ strptr = strstr(buf, ".m1"); if (strptr) *strptr = 0; /* Scan back from end of pathname until a '/' is found */ if (strstr(buf, "/")) { dir_name = &buf[strlen(buf)]; while (*dir_name != '/') dir_name--; /* Split buf into 2 parts: the directory name and the file name */ *dir_name = 0; modelname = ++dir_name; dir_name = buf; /* Set the current directory */ gmsChdir(dir_name); } else { Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-14 /* buf contains only a Model name */ modelname = buf; } /* Send window handles and Model name to the Top State */ STMSG_P("my_top", "app_window_handle", app_window_handle); STMSG_P("my_top", "app_subwindow_handle", app_subwindow_handle); STMSG("my_top", "model_name", modelname); return 1; } 3. simple_external_loop( ) static int simple_external_loop () { XEvent event; int test; /* disable the chain of SL-GMS internal Timer TimeOuts since this is an external event loop */ gmsTimerEventMask(G_DISABLE); while (1) { /* tell GMS that the event loop is blocking, so that timer events get handled properly */ STMSG_V("my_std_topst", "blocking_events_flag", 1); XtAppNextEvent(appContext, &event); printf("main(): Event type: %d\n", event.type); Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-15 XtDispatchEvent(&event); if (event.type != MotionNotify) { test = gmsDispatchInputEvents(); test += gmsDispatchTimerEvents(); test += gmsQGUIWidgetEvents(1); if (test) STMSG("my_std_topst", "update_all_states", ""); } } } 4. ExternalMessage( ) int ExternalMessage (arg1, arg2, arg3) char *arg1; char *arg2; char *arg3; { if (strcmp(arg2, "g_app_quit") == 0) { gmsExit(); } return 1; } The final version of "gmsmain.c"is myproject_motif directory. included with SL-GMS in the Modifications to "motif_stuff.c" The next step is to change "motif_stuff.c". Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-16 1. Modify file_select_cb( ) to send the selected Model file name to the Top State by replacing the comment /* Do something with the file name here */ with start_gms_model(filename); 2. Add a button to the Help menu that activates the About window as shown in Figure D-2. n = 0; tcs = XmStringCreateLtoR("About My Project", charset); XtSetArg(args[n], XmNlabelString, tcs); n++; XtSetArg(args[n], XmNmnemonic, 'T'); n++; button3 = (Widget)XmCreatePushButton(menu_pane2, "About My Project", args, n); XtAddCallback(button3, XmNactivateCallback, menu_cb, (XtPointer)MENU_ABOUT); XtManageChild(button3); XmStringFree(tcs); Figure D-2Myproject_motif Help menu Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-17 3. Add a case to help_cb( ) that invokes the About window shown in Figure D-3. case MENU_ABOUT: STMSG("my_std_topst", "about_myproject_window", "); break; Figure D-3Myproject_motif About Window 4. Modify the file selection dialog created in menu_cb( ) so that it displays only Model file names as shown in Figure D-4. tcs = XmStringCreateLtoR("*.m1", charset); XtSetArg(args[n], XmNpattern, tcs); n++; 5. Add the loop_buton_cb( ) callback function which is called from the "Tight Loop" button. static void loop_button_cb (w, client_data, call_data) Widget w; XtPointer client_data; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-18 XtPointer call_data; { static int tight = 0; tight ^= 1; XmToggleButtonSetState( w, tight, 0); printf( "\n%s tight loop.\n\n", tight ? "Entering" : "Leaving" ); user_main_loop_tight( tight ); } Figure D-4Myproject_motif File Selection Dialog The final version of "motif_stuff.c" is included with SL-GMS in the myproject_motif directory. Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-19 Add "eventloop_xm.c" Create the file "eventloop_xm.c" and define the function which contains the advanced event loop, user_main_loop_run( ). int user_main_loop_run() { intany_events; intgms_events; id appst; /* get the timeout interval from the StandardTopState exemplar */ STMSG_P("StandardTopState", "get_update_period", &dyn_timeout_interval); printf( "(Timeout interval = %d)\n", dyn_timeout_interval ); appst = gmsStFindByName("std_appst"); appcon_handle = (XtAppContext)gmsStStrMsg( appst, "get_appcon_handle"); /* Add an SL-GMS dynamics timeout */ start_dynamics(); /* disable the chain of SL-GMS internal Timer TimeOuts since this is an external event loop */ gmsTimerEventMask(G_DISABLE); /**********************************/ /* this is the "forever" event loop; it is exited only by setting the "main_loop_runing" flag off */ main_loop_running = 1; Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-20 while (main_loop_running) { /******************************/ /* if GMS is in a "tight loop", first dispatch all pending events, without blocking; if no events, then go ahead and do the "work_method" */ if (tight_loop_flag) { dispatch_all_events_dont_block( &any_events, &gms_events); if (gms_events) STMSG("std_appst", "process_gms_events", ""); /* if any events dispatched, go back and check for more */ if (any_events) continue; /* only execute work method if no events processed */ do_work_method(); /******************************/ /* if not in tight loop, block until input events occur, then process them - which may result in setting of the tight_loop_flag*/ } else { block_then_dispatch_all_events( &any_events, &gms_events); if (gms_events) STMSG("std_appst", "process_gms_events", ""); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-21 } return 1; } The advanced event loop works in two modes. The mode is determined by the tight_loop_flag variable. When tight_loop_flag is off, the event loop functions as a blocking event loop. When the tight_loop_flag is on, the event loop dispatches all pending events and then calls a "work" function. The "work" function is executed only when there are no events waiting in the event queue. Define the support functions for the advanced event loop which are user_main_loop_stop( ), user_main_loop_interval( ), user_main_loop_tight( ), start_dynamics( ), block_then_dispatch_all_events( ), dispatch_all_events_dont_block( ), dispatch_one_event( ), handle_the_timeout( ), filter_x_events( ), timer_cb( ), do_work_method( ), and seconds_elapsed( ). The final version "eventloop_xm.c" is included with SL-GMS in the myproject_motif directory. myproject_motif The final versions of "gmsmain.c", "motif_stuff.c" and "eventloop_xm.c" are then combined with "user_top.c" and "user_ds.c" from the myproject_common directory to create the myproject_motif example. The resulting application can generate data for the windtunnel and mymodel Models as well as display any Model whose data is generated by a .dat file such as the Models in the dynactions demo. The Motif file selection dialog can be used to navigate to other directories that contain SL-GMS Models and display them as shown in Figure D-5. Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-22 Figure D-5Myproject_motif with a Dynactions Demo Model The myproject_motif example has the following execution options: myproject_motif [-Umsecs] [-Ln] [modelname] Where • msecs - the data update rate in milliseconds • n 0 1 2 • modelname - the path and name of an SL-GMS Model. - the event loop selector = Use gmsRunMainLoop( ) = Use the simple event loop = Use the advanced event loop Version 6.2a- 26 May 2006 SL-GMS Examples Manual D-23 Detailed Analysis: myproject_win E Introduction The myproject_win example is based on the myproject_common example. The analysis of myproject_win begins with a program framework based on Microsoft’s Win32 API. A simple Win32-only application is built which has a main window, a menu bar, and a drawing area in which an SL-GMS Model will be displayed. Then, the steps required to add myproject_common to the Win32 application are examined. Win32 Framework The Win32-only application is based on two source files, "gmsmain.c" and "win_stuff.c". The steps to build the iniital program are listed below. The major steps required myproject_win are: to produce the Win32 framework for 1. Define the application’s resources #define #define #define #define IDM_OPEN101 IDM_EXIT102 IDM_LOOP201 IDM_ABOUT301 MyProjectWin MENU { POPUP "&File" { MENUITEM "&Open...", MENUITEM "E&xit", } POPUP "&Flags" { MENUITEM "&Tight Loop", } Version 6.2a- 26 May 2006 IDM_OPEN IDM_EXIT IDM_LOOP SL-GMS Examples Manual E-1 POPUP "&Help" { MENUITEM "&About My Project", } } IDM_ABOUT 2. Define and register the application’s Window class wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = appname; wndclass.lpszClassName = appname; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx (&wndclass); 3. Define the Window Procedure LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_COMMAND: switch( LOWORD(wParam) ) { case IDM_EXIT: exit(0); case IDM_ABOUT: Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-2 MessageBox(hwnd, "About My Project", "About", MB_OK); return 0; } } return DefWindowProc(hwnd, msg, wParam,lParam); } 4. Create and show an instance of the application’s Window. w = GetSystemMetrics(SM_CXFULLSCREEN) * 0.5; h = GetSystemMetrics(SM_CYFULLSCREEN) * 0.5; style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; hwndMain = CreateWindow (appname,"My Project Windows", style, CW_USEDEFAULT, CW_USEDEFAULT, w, h, NULL, NULL, hInstance, NULL); ShowWindow(hwndMain, show); UpdateWindow(hwndMain); 5. Enter the main event loop while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } When executed, the initial version of myproject_win appears as shown in Figure E-1. Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-3 Figure E-1Initial Win32-only version of myproject_win Win32 Framework Source Files The source files that produce the Win32 application discussed in the previous section are provided below for reference. gmsmain.c /********************************************************************** * SL-GMS On-Line Examples: * Topic: Windows Application Framework * Example #:myproject_win * Purpose:SL-GMS within a Windows (Win32) framework * Module: gmsmain.c - WinMain definition * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #include int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdline, int show) { UINT msg; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-4 main_window( hInstance, show ); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } resources.h /********************************************************************** * SL-GMS On-Line Examples: * Topic: Windows Application Framework * Example #:myproject_win * Purpose:SL-GMS within a Windows (Win32) framework * Module: resources.h - Window Resource definitions * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #define #define #define #define IDM_OPEN101 IDM_EXIT102 IDM_LOOP201 IDM_ABOUT301 resources.rc /********************************************************************** * SL-GMS On-Line Examples: * Topic: Windows Application Framework * Example #:myproject_win * Purpose:SL-GMS within a Windows (Win32) framework * Module: resources.rc - Windows Resource file * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #include "resources.h" MyProjectWin MENU { POPUP "&File" { MENUITEM "&Open...", MENUITEM "E&xit", Version 6.2a- 26 May 2006 IDM_OPEN IDM_EXIT SL-GMS Examples Manual E-5 } POPUP "&Flags" { MENUITEM "&Tight Loop", } POPUP "&Help" { MENUITEM "&About My Project", } } IDM_LOOP IDM_ABOUT win_stuff.c /********************************************************************** * SL-GMS On-Line Examples: * Topic: Windows Application Framework * Example #:myproject_win * Purpose:SL-GMS within a Windows (Win32) framework * Module: win_stuff.c - Windows callbacks * * Copyright (c) 1998 Sherrill-Lubinski. All Rights Reserved. **********************************************************************/ #include #include "resources.h" LRESULT CALLBACK WndProc(); /**********************************************************************/ /* Create main window */ HWND main_window (HINSTANCE hInstance, int show) { WNDCLASSEX wndclass; HWND hwndMain; int w, h, style; char appname[] = "MyProjectWin"; /* Register our window class */ wndclass.cbSize wndclass.style wndclass.lpfnWndProc wndclass.cbClsExtra wndclass.cbWndExtra Version 6.2a- 26 May 2006 = = = = = sizeof(wndclass); CS_HREDRAW | CS_VREDRAW; WndProc; 0; 0; SL-GMS Examples Manual E-6 wndclass.hInstance wndclass.hIcon wndclass.hCursor wndclass.hbrBackground wndclass.lpszMenuName wndclass.lpszClassName wndclass.hIconSm = = = = = = = hInstance; LoadIcon(NULL, IDI_APPLICATION); LoadCursor(NULL, IDC_ARROW); (HBRUSH) GetStockObject(WHITE_BRUSH); appname; appname; LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx (&wndclass); /* Choose a reasonable size */ w = GetSystemMetrics(SM_CXFULLSCREEN) * 0.5; h = GetSystemMetrics(SM_CYFULLSCREEN) * 0.5; style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; /* Create and show our main window */ hwndMain = CreateWindow (appname,// window "My Project Windows",// window caption style,// window style CW_USEDEFAULT, // CW_USEDEFAULT, // w,// initial x size h,// initial y size NULL, // NULL, // hInstance, // NULL); // class name initial x position initial y position parent window handle window menu handle program instance handle creation parameters ShowWindow(hwndMain, show); UpdateWindow(hwndMain); return 0; } /**********************************************************************/ /* Main window procedure */ LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_COMMAND: Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-7 switch( LOWORD(wParam) ) { case IDM_EXIT: exit(0); case IDM_ABOUT: MessageBox(hwnd, "About My Project", "About", MB_OK); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); } Framework Enhancement The Win32 framework is now ready for SL-GMS enhancements. The enhancements made which result in the final application are summarized below. Modifications to "gmsmain.c" First, modify the main( ) function in "gmsmain.c" as follows: 1. Add a console window and direct standard output to it. AllocConsole( ); freopen("CON:", "w", stdout); 2. Construct argc and argv from the Windows command line buffer. build_argc_argv(cmdline, &argc, &argv); 3. Initialize SL-GMS gmsInitialize(&argc, argv, 0); 4. Create the main window with the existing main_window( ) function. 5. Initialize the custom Top State my_top_initialize(); Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-8 6. Parse the command line parse_command_line(argc, argv, modelname); 7. Invoke an instance of the custom Top State STINVOKE("my_top", "MyTopState", "", NULL); 8. If a Model name was supplied on the command line, load and run it. if ( strlen(modelname) > 0 ) start_gms_model(modelname); 9. Replace the main event loop switch( evtloop_flag ) { case 0: printf( "Using SL-GMS Main Loop...\n" ); gmsRunMainLoop(); break; case 1: printf( "Using basic event loop...\n" ); simple_external_loop(); break; case 2: printf( "Using advanced event loop...\n" ); user_main_loop_run(); break; } Then, add the functions that are used in the above changes to main( ). 1. Add the support function build_argc_argv( ). static int build_argc_argv (cmdline, argc, argv) char*cmdline; int*argc; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-9 char***argv; { char*tmp = cmdline; intn_fields; char**argv_t; charbuf[1024]; inti; *argc = 0; /* loop over the command line argument to find out how any arguments there are */ while (1) { n_fields = sscanf(tmp, "%s", buf); if (n_fields == EOF) break; else { (*argc)++; tmp += strlen(buf); } } /* allocate memory for argv (allocate at least one pointer for argv[0]) */ argv_t = (char**)malloc((*argc) * sizeof(char*)); if (!argv_t) return 0; /* loop over the command line argument and copy them into argv[] */ tmp = cmdline; for (i = 0; i < *argc; i++) { n_fields = sscanf(tmp, "%s", buf); if (n_fields == EOF) break; argv_t[i] = (char*)malloc(strlen(buf)+1); if (!argv_t[i]) return 0; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-10 strcpy(argv_t[i], buf); if (i != 0) tmp += strlen(buf); } *argv = argv_t; return 1; } 2. Add the support function parse_command_line( ). static int parse_command_line (argc, argv, modelname) int argc; char **argv; char*modelname; { int i; char*arg; for (i = 0; i < argc; i++) { arg = argv[i]; /* process args that begin with '-' */ if (*arg == '-') { switch (*++arg) { /* Set event loop flag */ case 'l': case 'L': evtloop_flag = atoi(++arg); break; /* pass -u argument to StdTopState */ Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-11 case 'u': case 'U': STMSG("StandardTopState", "update_period", ++arg); default: break; } /* arg does not begin with a '-', assume it's a Model file name */ } else { strcpy(modelname, arg); } } return (1); } 3. Add the support function start_gms_model( ). int start_gms_model (filename) char *filename; { char*dir_name; char*modelname; char*strptr; charbuf[G_MAXFILENAME]; /* Copy file name to buffer */ strcpy(buf, filename); /* Remove m1 suffix */ strptr = strstr(buf, ".m1"); if (strptr) *strptr = 0; /* Scan back from end of pathname until a '\' is found */ if (strstr(buf, "\\")) { dir_name = &buf[strlen(buf)]; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-12 while (*dir_name != '\\') dir_name--; /* Split buf into 2 parts: the directory name and the file name */ *dir_name = 0; modelname = ++dir_name; dir_name = buf; /* Set the current directory */ gmsChdir(dir_name); } else { /* buf contains only a Model name */ modelname = buf; } /* Send window handle and Model name to the Top State */ STMSG_P("my_top", "app_window_handle", mainwin); STMSG_P("my_top", "app_subwindow_handle", mainwin); STMSG("my_top", "model_name", modelname); return 1; } 4. Add the support function ExternalMessage( ) which provides a way for the underlying SL-GMS application to send messages to the Win32 framework. int ExternalMessage (arg1, arg2, arg3) char *arg1; char *arg2; char *arg3; { if (strcmp(arg2, "g_app_quit") == 0) { gmsExit(); } return 1; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-13 } 5. Add the support function simple_external_loop( ). static int simple_external_loop () { MSGmsg; inttest; /* disable the chain of SL-GMS internal Timer TimeOuts since this is an external event loop */ gmsTimerEventMask(G_DISABLE); while (GetMessage(&msg, 0, 0, 0)) { /* Displatch the next Windows event */ TranslateMessage( &msg ); DispatchMessage( &msg ); /* Dispatch the accumulated SL-GMS events */ test = gmsDispatchInputEvents(); test += gmsDispatchTimerEvents(); test += gmsQGUIWidgetEvents(1); if (test) STMSG("my_std_topst", "update_all_states", ""); } return 1; } The final version of "gmsmain.c" is supplied with SL-GMS in the myproject_win directory. Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-14 Modifications to "win_stuff.c" The changes required to "win_stuff.c" are listed below. 1. Change the return value of main_window( ) so that the main window handle is available to functions in "gmsmain.c". return hwndMain; 2. Update the main window prodecure to handle all menu selections and events which terminate the application. LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HANDLE callback; HWND child; switch( msg ) { case WM_COMMAND: // If lParam is 0, msg is from menu if ( lParam == 0 ) { switch( LOWORD(wParam) ) { case IDM_OPEN: AppOpen(hwnd); break; case IDM_EXIT: AppExit(); case IDM_ABOUT: STMSG("my_std_topst", "about_myproject_window", ""); break; case IDM_LOOP: AppLoop(hwnd, IDM_LOOP); break; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-15 } return 0; } break; case WM_CLOSE: case WM_DESTROY: AppExit(); } return GMS_SmsNtWindowProc(hwnd, msg, wParam, lParam); } Next, add the support functions used in the main window procedure. 1. Add AppExit( ). static int AppExit () { /* Close standard output */ fclose( stdout ); /* Shut down SL-GMS */ user_main_loop_stop(); PostQuitMessage(0); gmsExit(); } 2. Add AppOpen( ). static int AppOpen (HWND hwnd) { OPENFILENAME *ofn; char modelname[G_MAXFILENAME]; char filter[] = "Model Files (*.M1)\0*.m1\0\0"; Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-16 ofn = calloc( 1, sizeof(OPENFILENAME) ); ofn->lStructSize ofn->hwndOwner ofn->lpstrFileTitle ofn->nMaxFileTitle ofn->lpstrFilter = ofn->lpstrDefExt = sizeof (OPENFILENAME); = hwnd; = modelname; = G_MAXFILENAME; filter; = "m1"; if ( GetOpenFileName(ofn) ) start_gms_model(modelname); free(ofn); return 1; } 3. Add AppLoop( ) which is used to toggle the tight_loop_flag in the advanced main event loop. static int AppLoop (HWND hwnd, int entry) { HMENU menu; static int tight = 0; tight ^= 1; menu = GetMenu(hwnd); CheckMenuItem( menu, entry, tight ? MF_CHECKED : MF_UNCHECKED ); printf( "\n%s tight loop.\n\n", tight ? "Entering" : "Leaving" ); fflush( stdout ); user_main_loop_tight( tight ); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-17 The final version of "win_stuff.c" is supplied with SL-GMS in the myproject_win directory. Add "eventloop_win.c" Create the file "eventloop_win.c" and define the function which contains the advanced event loop, user_main_loop_run( ). int user_main_loop_run() { intany_events; intgms_events; /* get the timeout interval from the StandardTopState exemplar */ STMSG_P("StandardTopState", "get_update_period", &dyn_timeout_interval); printf( "(Timeout interval = %d)\n", dyn_timeout_interval ); /* Add an SL-GMS dynamics timeout */ start_dynamics(); /* disable the chain of SL-GMS internal Timer TimeOuts since this is an external event loop */ gmsTimerEventMask(G_DISABLE); /**********************************/ /* this is the "forever" event loop; it is exited only by setting the "main_loop_runing" flag off */ main_loop_running = 1; while (main_loop_running) { /******************************/ /* if GMS is in a "tight loop", first dispatch all pending Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-18 events, without blocking; if no events, then go ahead and do the "work_method" */ if (tight_loop_flag) { dispatch_all_events_dont_block( &any_events, &gms_events); if (gms_events) STMSG("my_std_topst", "process_gms_events", ""); /* if any events dispatched, go back and check for more */ if (any_events) continue; /* only execute work method if no events processed */ do_work_method(); /******************************/ /* if not in tight loop, block until input events occur, then process them - which may result in setting of the tight_loop_flag */ } else { block_then_dispatch_all_events( &any_events, &gms_events); if (gms_events) STMSG("my_std_topst", "process_gms_events", ""); } } return 1; } Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-19 The advanced event loop works in two modes. The mode is determined by the tight_loop_flag variable. When tight_loop_flag is off, the event loop functions as a blocking event loop. When the tight_loop_flag is on, the event loop dispatches all pending events and then calls a "work" function. The "work" function is executed only when there are no events waiting in the event queue. Define the support functions for the advanced event loop which areuser_main_loop_stop( ), user_main_loop_interval( ), user_main_loop_tight( ), start_dynamics( ), block_then_dispatch_all_events( ), dispatch_all_events_dont_block( ), dispatch_one_event( ),timer_cb( ), do_work_method( ), seconds_elapsed( ), get_workst_by_handle( ), get_state_by_handle( ), and get_widget_list( ). The final version "eventloop_win.c" is included with SL-GMS in the myproject_win directory. myproject_win The final versions of "gmsmain.c", "motif_stuff.c" and "eventloop_win.c" are then combined with "user_top.c" and "user_ds.c" from the myproject_common directory to create the myproject_win example. The resulting application can generate data for the windtunnel and mymodel Models as well as display any Model whose data is generated by a .dat file such as the Models in the dynactions demo. The Win32 file selection dialog can be used to navigate to other directories that contain SL-GMS Models and display them as shown in Figure E-2. Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-20 Figure E-2Myproject_win with a Dynactions Demo Model The myproject_win example has the following execution options: myproject_win [-Umsecs] [-Ln] [modelname] Where • msecs - the data update rate in milliseconds • n - the event loop selector 0 = Use gmsRunMainLoop( ) 1 = Use the simple event loop 2 = Use the advanced event loop • modelname - the path and name of an SL-GMS Model. Version 6.2a- 26 May 2006 SL-GMS Examples Manual E-21 Detailed Analysis: myproject_mfc_sdi F Introduction The myproject_mfc_sdi example is based on the myproject_common example. The analysis of myproject_mfc_sdi begins with an MFC Single Document Interface (SDI) framework. A simple SDI application is built using the Visual C++ AppWizard that has a main window, a menu bar, and a drawing area in which an SL-GMS Model will be displayed. Then, the steps required to add myproject_common to the application are examined. SDI Framework The case study for myproject_mfc_sdi begins with an application generated by the Visual C++ AppWizard. The AppWizard settings used to create the initial application are: • Project name: myproject_mfc NOTE: For simplicity, subsequent references to files assume that the AppWizard project has the same parent directory as the myproject_mfc_sdi example provided with SL-GMS. • Type of application: Single document • Language: US English • Database Support: None • Other Support: None Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-1 • Features: Context sensitive help 3D controls How many files in recent file list: 4 Generate source file comments: Yes How to use the MFC library: shared DLL The resulting application is shown in Figure F-1. Figure F-1SDI Application Produced by AppWizard Framework Enhancement The MFC - SDI framework is now ready for SL-GMS enhancements. The enhancements fall into four catagories: 1. Project Configuration 2. Resource Modifications 3. Header Modifications 4. Class Modifications Project Configuration Changes to the project settings are required as well as the addition of files to the project. Use the Visual C++ Project Settings dialog to make the following changes. Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-2 • Automatic use of precompiled headers • Additional include file locations . ..\..\lib ..\..\work\mfc_common • Set Object/library modules list ..\..\lib\spromeps.lib rpcrt4.lib ..\..\lib\libsmsnew.lib ..\..\lib\libsmsnt.lib ..\..\lib\libsms.lib ..\..\lib\libgmd.lib ..\..\lib\libdms.lib ..\..\lib\libgms.lib ..\..\lib\libgws.lib ..\..\lib\libgwsnt.lib • Ignore Libraries: libc.lib,libcmt.lib,libcd.lib,libcmtd.lib,msvcrtd. lib Use the Visual C++ Insert Files into Project dialog to add the following files to the project. • Additional classes provided with SL-GMS for MFC development ..\..\work\mfc_common\gms_app.cpp ..\..\work\mfc_common\gms_app.h ..\..\work\mfc_common\gms_view.cpp ..\..\work\mfc_common\gms_view.h ..\..\work\mfc_common\gms_frm.cpp ..\..\work\mfc_common\gms_frm.h ..\..\work\mfc_common\gms_interface.cpp ..\..\work\mfc_common\gms_interface.h Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-3 • Additional SL-GMS application files. ..\..\work\myproject_common\user_top.c ..\..\work\myproject_common\user_ds.c Resource Modifications The resource modifications add text to the application’s About window. The extra text in the About window identifies the SL-GMS configuration. First, use the Resource Symbols dialog to add the following name and value: IDC_CORE_CONFIG 1002 Next, edit the IDD_ABOUTBOX resource adding text that identifies the SL-GMS configuration as shown in Figure F-2. Figure F-2About Window Modifications Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-4 Header Modifications The header file modifications make the SL-GMS supplied classes available to the application through inclusion of SL-GMS header files and changes to the class hierarchy. The files that require changes are: • MainFrm.h • myproject_mfc.h • myproject_mfcDoc.h • myproject_mfcView.h MainFrm.h: 1. Add SL-GMS related macros and data structure for variable definitions. // GMS_ADDED #define #define #define #define G_ARRAY 0x4000 G_CHAR 0x10 G_DOUBLE 0x8 G_INTEGER0x2 #define MAXVARDEFS 256 struct vardef_str { int index; void *vardef; void *addr; int type; }; class CMainFrame : public CFrameWnd 2. Add variables that support the SL-GMS interface. // Attributes public: // GMS_ADDED // These support gms_interface.cpp Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-5 vardef_str vardef_str_table[MAXVARDEFS]; int vardef_str_index; myproject_mfc.h: 1. Add SL-GMS include files. #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h" // main symbols #include "gms_app.h"// GMS_ADDED 2. Change the base class of CMyproject_mfcApp from CWinApp to GMS_App. class CMyproject_mfcApp : public GMS_App 3. Use ClassWizard to add a message handler function for ID_FILE_OPEN to the CMyproject_mfcApp class. myproject_mfcDoc.h: 1. Add a class variable for the SL-GMS Model displayed. // Attributes public: CString model_name;// GMS_ADDED // 2. Use ClassWizard to add a virtual function override for the OnOpenDocument message to the CMyproject_mfcDoc class. 3. Use ClassWizard to add a message handler function for ID_FILE_NEW to the CMyproject_mfcDoc class. myproject_mfcView.h: 1. Add SL-GMS include near top of file. #include "gms_view.h"// GMS_ADDED // Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-6 2. Change the base class of CMyproject_mfcView from CView to GMS_View. class CMyproject_mfcView : public GMS_View 3. Add a variable for window sizing operations. // Operations public: int resizing; 4. Use ClassWizard to delete the override for the OnDraw message from the CMyproject_mfcView class. Then delete the implementation of the OnDraw message from myproject_mfcView.cpp. 5. Use ClassWizard to add an override for the OnInitialUpdate message to the CMyproject_mfcView class. 6. Use ClassWizard to add a message handler function for the WM_SIZE message to the CMyproject_mfcView class. Class Modifications The class modifications add the code required to support SL-GMS within the MFC framework. The class files that require changes are: • myproject_mfc.cpp • myproject_mfcDoc.cpp • myproject_mfcView.cpp • MainFrm.cpp myproject_mfc.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // #include "myproject_mfc.h" #include "MainFrm.h" #include "myproject_mfcDoc.h" Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-7 #include "myproject_mfcView.h" #include "gms_interface.h"// GMS_ADDED // 2. Add an extern statement for external SL-GMS functions. // GMS_ADDED // - extern to point out external C functions. extern "C" { HWND get_parent_window(); int int int int int g_make_argv (const char* m_lpCmdLine, int* argc, char*** argv); g_free_argv (int argc, char **argv); myproject_main(int argc, char** argv); my_top_initialize(); parse_command_line (int argc, char **argv, char *model_name); } 3. Change the base class of CMyproject_mfcApp from CWinApp to GMS_App. BEGIN_MESSAGE_MAP(CMyproject_mfcApp, GMS_App) 4. Use ClassWizard to add a message handler function for the ID_FILE_OPEN message if one does not exist. 5. Add variables for the command line arguments to InitInstance( ). // GMS_ADDED - command line arguments and Model name char **argv; int argc; char model_name[1024]; 6. Comment out and replace the command line processing code. // Parse command line for standard shell commands, DDE, file open // CCommandLineInfo cmdInfo; Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-8 // ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line // if (!ProcessShellCommand(cmdInfo)) // return FALSE; // GMS_ADDED - create interface class with GMS GMS_App::InitInstance(); // GMS_ADDED - create arg vector from line g_make_argv(m_lpCmdLine, &argc, &argv); /* initialize custom Top State */ my_top_initialize(); /* parse command-line arguments */ strcpy(model_name, ""); parse_command_line(argc, argv, model_name); // GMS_ADDED - Free memory for argv */ g_free_argv(argc, argv); /* invoke the custom Top State */ STINVOKE("my_top", "MyTopState", "", 0); /* Disable the event mask */ gmsTimerEventMask(0); // GMS_ADDED // see the get_parent_window // extern c function in this module for // a description of the gmsWidgetFunctionTable gmsWidgetFunctionTableCreate(1); Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-9 gmsWidgetFunctionAdd ("get_parent", get_parent_window); if (strlen(model_name) > 0) { // GMS_ADDED Open the Model if one was provided // on the command line if (!strstr(model_name, ".m1")) strcat(model_name, ".m1"); CWinApp::OpenDocumentFile(model_name); } else { // GMS_ADDED // OnFileNew added because the command line // processing provided by MFC (above) was // commented out, and this provided the // OnFileNew command. OnFileNew(); 7. Add the code for the ExternalMessage( ) function. // GMS_ADDED External Message Function extern "C" int ExternalMessage (char *target, char *msg, char *arg) { HWND main_hwnd; CWnd *main_cwnd; if (strcmp(msg, "g_app_quit") == 0) { /* return the window handle of the main application window */ main_cwnd = AfxGetMainWnd(); main_hwnd = main_cwnd->m_hWnd; return SendMessage(main_hwnd, WM_CLOSE, 0, 0L); Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-10 } else { return 0; } } 8. Add the code for the parse_command_line( ) function. // GMS_ADDED //Parse the command line for GMS arguments static "C" int parse_command_line (int argc, char **argv, char *model_name) { int i; char *arg; for (i = 0; i < argc; i++) { arg = argv[i]; if (*arg == '-') { switch (*++arg) { /* pass -u argument to StdTopState */ case 'u': case 'U': STMSG("StandardTopState", "update_period", ++arg); break; default: break; } /* if arg does not begin with a '-', assume it's a Model file name */ Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-11 } else { strcpy(model_name, arg); } } return (1); } 9. Use ClassWizard to add a message handler function for the WM_INITDIALOG message to the CAboutDlg class. 10. Use ClassWizard to add a member variable to the CAboutDlg class for IDC_CORE_CONFIG that will hold the SL-GMS configuration string. Set the maximum number of characters to 256. CString m_g_c_config 11. Add appropriate file filter and file open code to OnFileOpen( ). static char BASED_CODE szFilter[] = "Model files (*.m1)|*.M1|All Files (*)|*||"; static char BASED_CODE szDefExt[] = "m1"; static char BASED_CODE szFileName[] = "*.m1"; CFileStatusfileStatus; CFile modelFile; // popup the file open dialog box // and accept the file name. CFileDialog modelDlg(TRUE, szDefExt, szFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); if (modelDlg.DoModal() == IDOK) { // verify that the file exists Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-12 VERIFY(modelFile.GetStatus(modelDlg.GetPathName(), fileStatus)); // open the document with the file CWinApp::OpenDocumentFile(modelDlg.GetPathName()); } 12. Add the get_parent_window( ) function. // // // // // // GMS_ADDED this makes certain that the mainfraim owns all gms windows invoked, so that they are destroyed when the mainfraim is and so that they stay above the main window - it will be moved to mfc_common and done automatically at a later date static "C" HWND get_parent_window() { CWnd*main_window; /* return the window handle of the main application window */ main_window = AfxGetMainWnd(); return main_window->m_hWnd; } 13. Add code to OnInitDlg( ) to set the configuration variable. m_g_c_config = gmsQConfig(); 14. Add a message handler function to the CAboutDlg class for the WM_RBUTTONUP message. 15. Add code to the OnRButtonUp( ) function that activates the State Tools window. Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-13 { STMSG("my_std_topst", "show_states", ""); } myproject_mfcDoc.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED #include "myproject_mfc.h" #include "myproject_mfcDoc.h" 2. Add code to the OnOpenDocument( ). // GMS_ADDED SetTitle(lpszPathName); SetPathName(lpszPathName); // set the model name member in the document class model_name = (lpszPathName); myproject_mfcView.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // #include "myproject_mfc.h" 2. Add extern for SL-GMS functions. // GMS_ADDED extern "C" { char *stripSuffix( const char *name ); } 3. Change base class of CMyproject_mfcView from CView to GMS_View. Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-14 IMPLEMENT_DYNCREATE(CMyproject_mfcView, GMS_View) BEGIN_MESSAGE_MAP(CMyproject_mfcView, GMS_View) 4. Add initialization of resizing variable in the constructor. // GMS_ADDED - resizing flag resizing = 0; 5. Add code to OnInitialUpdate( ). charbuf[1024]; char*dir_name; char*modelname; CMyproject_mfcDoc* pDoc = GetDocument(); VERIFY(pDoc); if (pDoc && strlen(pDoc->model_name) > 0) { // store the Model name and path in a buffer strcpy(buf, (const char *)pDoc->model_name); // Send the Top State the info it needs to // invoke a WinModState in the window // created by MFC STMSG_S("my_top", "winmodstate_name", "my_window"); STMSG_P("my_top", "app_subwindow_handle", m_hWnd); STMSG_P("my_top", "app_window_handle", GetParent()->m_hWnd); STMSG_S("my_top", "model_name", buf); PostMessage(WM_USER+1); } 6. Change Cview in OnSize( ) to GMS_View. GMS_View::OnSize (nType, cx, cy); Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-15 7. Add the function stripSuffix( ) to the end of the file. static char *stripSuffix( const char *name ) { int i; static charnew_name[G_MAXFILENAME]; strcpy(new_name, name); for (i=strlen(name);i>=0;i--) { if (name[i] == '.') { new_name[i] = '\0'; break; } } return new_name; } 8. Remove the OnDraw( ) function if it exists. MainFrm.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // #include "myproject_mfc.h" 2. Inialize vardef_str_index in CMainFrame( ) vardef_str_index = 0; 3. Add code to PreCreateWindow( ) that retrieves window placement information from the registry. WINDOWPLACEMENTwplace; char keyname[128]; HKEY hkey; DWORD wp_size, val_size; Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-16 LONG status; /* Get the main window placement from the Registry, or use a default. */ sprintf( keyname, "%s\\%s", G_REGKEY_SL, AfxGetAppName() ); status = RegOpenKeyEx( HKEY_CURRENT_USER, keyname, 0, KEY_QUERY_VALUE, &hkey ); if ( status == ERROR_SUCCESS ) { wp_size = val_size = wplace.length = sizeof( WINDOWPLACEMENT ); status = RegQueryValueEx( hkey, G_REGVAL_MW, 0, 0, (LPBYTE) &wplace, &val_size ); if ( status == ERROR_SUCCESS && val_size == wp_size ) { cs.x = wplace.rcNormalPosition.left; cs.y = wplace.rcNormalPosition.top; cs.cx = wplace.rcNormalPosition.right - cs.x; cs.cy = wplace.rcNormalPosition.bottom - cs.y; if ( wplace.showCmd == SW_SHOWMAXIMIZED ) cs.style |= WS_MAXIMIZE; } RegCloseKey( hkey ); } /* If we couldn't get window position settings from the Registry, use a default size. */ if ( status != ERROR_SUCCESS ) { HDC s_dc= ::GetDC(NULL); cs.x = cs.y = 0; Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-17 cs.cx = (int)( GetDeviceCaps(s_dc, HORZRES) * 0.95 ); cs.cy = (int)( GetDeviceCaps(s_dc, VERTRES) * 0.95 ); ::ReleaseDC(NULL, s_dc); } 4. Use ClassWizard to add a WM_DESTROY message handler to the CMainFrame class. 5. Add code to the OnDestroy( ) function to that saves the window placement on the registry. WINDOWPLACEMENTwplace; char keyname[128]; HKEY hkey; LONG status; /* Save main window size and position in Registry. */ wplace.length = sizeof( WINDOWPLACEMENT ); ::GetWindowPlacement( m_hWnd, &wplace ); sprintf( keyname, "%s\\%s", G_REGKEY_SL, AfxGetAppName() ); status = RegCreateKeyEx( HKEY_CURRENT_USER, keyname, 0, (char*)AfxGetAppName(), 0, KEY_ALL_ACCESS, NULL, &hkey, NULL ); if ( status == ERROR_SUCCESS ) { status = RegSetValueEx( hkey, G_REGVAL_MW, 0, REG_BINARY, (LPBYTE)&wplace, wplace.length ); RegCloseKey(hkey); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-18 The resulting application has the following command line options: myproject_mfc_sdi [-Umsecs] [modelname] Where msecs is the data update rate in milliseconds, and modelname is the path and name of an SL-GMS Model. The final version of myproject_mfc_sdi uses "user_top.c" and "user_ds.c" from the myproject_common directory, and can generate data for the windtunnel and mymodel Models. Any Model whose data is generated by a .dat filecan also be displayed. The MFC file selection dialog can be used to navigate to other directories that contain SL-GMS Models and display them as shown in Figure F-3. Figure F-3Myproject_mfc_sdi Displaying a Dynactions Demo Model Version 6.2a- 26 May 2006 SL-GMS Examples Manual F-19 G Detailed Analysis: myproject_mfc_mdi Introduction The myproject_mfc_mdi example is based on the myproject_common example. The analysis of myproject_mfc_sdi begins with an MFC Multiple Document Interface (MDI) framework. A simple MDI application is built using the Visual C++ AppWizard that has a main window, a menu bar, and a drawing area in which an SL-GMS Model will be displayed. Then, the steps required to add myproject_common to the application are examined. MDI Framework The case study for myproject_mfc_sdi begins with an application generated by the Visual C++ AppWizard. The AppWizard settings used to create the initial application are: • Project name: myproject_mfc NOTE: For simplicity, subsequent references to files assume that the AppWizard project has the same parent directory as the myproject_mfc_mdi example provided with SL-GMS. • Type of application: Multiple document • Language: US English • Database Support: None • Other Support: None Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-1 • Features: Context sensitive help 3D controls Initial status bar How many files in recent file list: 4 Generate source file comments: Yes How to use the MFC library: shared DLL The resulting MDI application is shown in Figure G-1. Figure G-1MFC - MDI AppWizard Application Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-2 Framework Enhancement The MFC - MDI framework is now ready for SL-GMS enhancements. The enhancements fall into four catagories: 1. Project Configuration 2. Resource Modifications 3. Header Modifications 4. Class Modifications Project Configuration Changes to the project settings are required as well as the addition of files to the project. Use the Visual C++ Project Settings dialog to make the following changes. • Automatic use of precompiled headers • Additional include file locations . ..\..\lib ..\mfc_common • Set Object/library modules list ..\..\lib\spromeps.lib rpcrt4.lib ..\..\lib\libsmsnew.lib ..\..\lib\libsmsnt.lib ..\..\lib\libsms.lib ..\..\lib\libgmd.lib ..\..\lib\libdms.lib ..\..\lib\libgms.lib ..\..\lib\libgws.lib ..\..\lib\libgwsnt.lib Use the Visual C++ Insert Files into Project dialog to add the following files to the project. • Additional classes provided with SL-GMS for MFC development Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-3 ..\..\work\mfc_common\gms_app.cpp ..\..\work\mfc_common\gms_app.h ..\..\work\mfc_common\gms_view.cpp ..\..\work\mfc_common\gms_view.h ..\..\work\mfc_common\gms_frm.cpp ..\..\work\mfc_common\gms_frm.h ..\..\work\mfc_common\gms_interface.cpp ..\..\work\mfc_common\gms_interface.h • Additional SL-GMS application files. ..\..\work\myproject_common\user_top.c ..\..\work\myproject_common\user_ds.c Resource Modifications The resource modifications add text to the application’s About window. The extra text in the About window identifies the SL-GMS configuration. First, use the Resource Symbols dialog to add the following name and value: IDC_CORE_CONFIG 1002 Next, edit the IDD_ABOUTBOX resource adding text that identifies the SL-GMS configuration. Header Modifications The header file modifications make the SL-GMS supplied classes available to the application through inclusion of SL-GMS header files and changes to the class hierarchy. The files that require changes are: • MainFrm.h • myproject_mfc.h • myproject_mfcDoc.h • myproject_mfcView.h Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-4 MainFrm.h: 1. Add SL-GMS related macros and data structure for variable definitions. // GMS_ADDED #define G_ARRAY0x4000 #define G_CHAR0x10 #define G_DOUBLE0x8 #define G_INTEGER0x2 #define MAXVARDEFS 256 struct vardef_str { int index; void *vardef; void *addr; int type; }; class CMainFrame : public CFrameWnd 2. change the base class of CMainFrame from CMDIFrameWnd to GMS_Frm. class CMainFrame : public CMDIFrameWnd 3. Add variables that support the SL-GMS interface. // Attributes public: // GMS_ADDED // These support gms_interface.cpp vardef_str vardef_str_table[MAXVARDEFS]; int vardef_str_index; Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-5 4. Use ClassWizard to remove the PreCreateWindow( ) virtual function override from the CMainFrame class. 5. Remove the implementation of PreCreateWindow( ) from MainFrm.cpp. 6. Use ClassWizard to add a message handler function for the WM_PALETTECHANGED message to the CMainFrame class. 7. Use ClassWizard to add a message handler function for the WM_QUERYNEWPALETTE message to the CMainFrame class. myproject_mfc.h: 1. Add SL-GMS include files. #include "resource.h" // main symbols #include "gms_app.h"// GMS_ADDED #include "gms_view.h"// GMS_ADDED 2. Change the base class of CMyproject_mfcApp from CWinApp to GMS_App. class CMyproject_mfcApp : public GMS_App 3. Use ClassWizard to add a message handler function for ID_FILE_OPEN to the CMyproject_mfcApp class. myproject_mfcDoc.h: 1. Add a class variable for the SL-GMS Model displayed. // Attributes public: CString model_name; // GMS_ADDED void OnGmsCloseDocument(); // GMS_ADDED 2. Use ClassWizard to add a virtual function override for the OnOpenDocument message to the CMyproject_mfcDoc class. 3. Use ClassWizard to add a virtual function override for the OnCloseDocument message to the CMyproject_mfcDoc class. Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-6 myproject_mfcView.h: 1. Change the base class of CMyproject_mfcView from CView to GMS_View. class CMyproject_mfcView : public GMS_View 2. Add a variable for window sizing operations. // Operations public: int resizing; // GMS_ADDED 3. Use ClassWizard to delete the override for the OnDraw message from the CMyproject_mfcView class. 4. Delete the implementation of the InDraw( myproject_mfcView.cpp. ) function from 5. Use ClassWizard to add an override for the OnInitialUpdate message to the CMyproject_mfcView class. 6. Use ClassWizard to add an override for the Create message to the CMyproject_mfcView class. Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-7 Class Modifications The class modifications add the code required to support SL-GMS within the MFC framework. The class files that require changes are: • MainFrm.cpp • myproject_mfc.cpp • myproject_mfcDoc.cpp • myproject_mfcView.cpp MainFrm.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // #include "myproject_mfc.h" 2. Change references to CMDIFrameWnd to GMS_Frm. IMPLEMENT_DYNAMIC(CMainFrame, GMS_Frm) BEGIN_MESSAGE_MAP(CMainFrame, GMS_Frm) 3. Inialize vardef_str_index in CMainFrame( ) vardef_str_index = 0; 4. Change the code in OnPaletteChanged( ). GMS_Frm::OnPaletteChanged(pFocusWnd); 5. Change the code in OnQueryNewPalette( ). return GMS_Frm::OnQueryNewPalette(); myproject_mfc.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-8 #include "myproject_mfc.h" #include #include #include #include "MainFrm.h" "ChildFrm.h" "myproject_mfcDoc.h" "myproject_mfcView.h" #include "gms_interface.h"// GMS_ADDED // 2. Add an extern statement for external SL-GMS functions. // GMS_ADDED // - extern to point out external C functions. extern "C" { HWND get_parent_window(); int gmsWidgetFunctionTableCreate(int); int build_argc_argv (const char* m_lpCmdLine, int* argc, char*** argv); char* gmsQConfig(); int g_make_argv (const char* m_lpCmdLine, int* argc, char*** argv); int g_free_argv (int argc, char **argv); int my_top_initialize(); char *stripSuffix( const char *name ); int parse_command_line (int argc, char **argv, int *num_models, char name_array[100][256]); } 3. Change the base class of CMyproject_mfcApp from CWinApp to GMS_App. BEGIN_MESSAGE_MAP(CMyproject_mfcApp, GMS_App) Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-9 4. Use ClassWizard to add a message handler function for the ID_FILE_OPEN message if one does not exist. 5. Add variables for the command line arguments to InitInstance( ). // GMS_ADDED //- command line arguments char **argv; int argc; int imodel; int model_count; char modelname_array[100][256]; 6. Comment out and replace the command line processing code. // GMS_ADDED - commented out the following lines // for GMS, which has its own command line // processing... // // // // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line // if (!ProcessShellCommand(cmdInfo)) // return FALSE; // The main window has been initialized, so show and update it. pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); // GMS_ADDED // - (create the interface class with GMS GMS_App::InitInstance(); // GMS_ADDED - create arg vector from line Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-10 g_make_argv(m_lpCmdLine, &argc, &argv); /* initialize custom Top State */ my_top_initialize(); /* parse command-line arguments */ model_count = 0; parse_command_line(argc, argv, &model_count, modelname_array); // GMS_ADDED - Free memory for argv */ g_free_argv(argc, argv); /* invoke the custom Top State */ STINVOKE("my_top", "MyTopState", "", 0); /* Disable the event mask */ gmsTimerEventMask(0); // GMS_ADDED // see the get_parent_window // extern c function in this module for // a description of the gmsWidgetFunctionTable gmsWidgetFunctionTableCreate(1); gmsWidgetFunctionAdd ("get_parent", get_parent_window); // GMS_ADDED // Open Models passed on the command line if (model_count > 0) { for (imodel = 0; imodel < model_count;imodel++){ Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-11 if (!strstr(modelname_array[imodel], ".m1")) strcat(modelname_array[imodel], ".m1"); CWinApp::OpenDocumentFile(modelname_array[im odel]); } } 7. Add the code for the ExternalMessage( ) function. // GMS_ADDED External Message Function extern "C" int ExternalMessage (char *target, char *msg, char *arg) { HWND main_hwnd; CWnd *main_cwnd; if (strcmp(msg, "g_app_quit") == 0) { /* return the window handle of the main application window */ main_cwnd = AfxGetMainWnd(); main_hwnd = main_cwnd->m_hWnd; return SendMessage(main_hwnd, WM_CLOSE, 0, 0L); } else { return 0; } } 8. Add the code for the parse_command_line( ) function. // GMS_ADDED //Parse the command line for GMS arguments extern "C" int parse_command_line (int argc, char **argv, int *num_models, char name_list[100][256]) { int i; Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-12 char*arg; for (i = 0; i < argc; i++) { arg = argv[i]; if (*arg == '-') { switch (*++arg) { /* pass -u argument to StdTopState */ case 'u': case 'U': STMSG("StandardTopState", "update_period", ++arg); break; default: break; } /* if arg does not begin with a '-', assume it's a Model file name */ } else { /* store up to 100 Model names */ if (*num_models < 100) { strcpy(name_list[*num_models], arg); (*num_models)++; } } } return (1); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-13 9. Use ClassWizard to add a message handler function for the WM_INITDIALOG message to the CAboutDlg class. 10. Use ClassWizard to add a message handler function for the WM_RBUTTONUP message to the CAboutDlg class. 11. Use ClassWizard to add a member variable to the CAboutDlg class for IDC_CORE_CONFIG that will hold the SL-GMS configuration string. Set the maximum number of characters to 256. CString m_g_c_config 12. Add appropriate file filter and file open code to OnFileOpen( ). static char BASED_CODE szFilter[] = "Model files (*.m1)|*.M1|All Files (*)|*||"; static char BASED_CODE szDefExt[] = "m1"; static char BASED_CODE szFileName[] = "*.m1"; CFileStatusfileStatus; CFile modelFile; // popup the file open dialog box // and accept the file name. CFileDialog modelDlg(TRUE, szDefExt, szFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); if (modelDlg.DoModal() == IDOK) { // verify that the file exists VERIFY(modelFile.GetStatus(modelDlg.GetPathName(), fileStatus)); // open the document with the file Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-14 CWinApp::OpenDocumentFile(modelDlg.GetPathName()); } 13. Add the get_parent_window( ) function. // // // // // // GMS_ADDED this makes certain that the mainfraim owns all gms windows invoked, so that they are destroyed when the mainfraim is and so that they stay above the main window - it will be moved to mfc_common and done automatically at a later date static "C" HWND get_parent_window() { CWnd*main_window; /* return the window handle of the main application window */ main_window = AfxGetMainWnd(); return main_window->m_hWnd; } 14. Add code to OnInitDlg( ) to set the configuration variable. m_g_c_config = gmsQConfig(); 15. Add code to OnRButtonUp( ) that activates the SL-GMS State Tools window. { STMSG("my_std_topst", "show_states", ""); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-15 myproject_mfcDoc.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED #include "myproject_mfc.h" #include "myproject_mfcDoc.h" 2. Add an extern statement for SL-GMS functions. extern "C" { char *stripSuffix( const char *name ); } 3. Add code to OnOpenDocument( ). // GMS_ADDED SetTitle(lpszPathName); SetPathName(lpszPathName); // set the model name member in the document class model_name = (lpszPathName); 4. Add code to OnCloseDocument( ). char buf[1024]; char*dir_name; char*model_name_ptr; charstatename[MAX_NAME] = "my_window_"; strcpy(buf, model_name); /* scan the full file name from the end until a '\' found. */ dir_name = &buf[strlen(buf)]; while (*dir_name != '\\') dir_name--; Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-16 /* split the string into 2 parts. The first is the directory name and the second is the model name */ model_name_ptr = ++dir_name; /* build the name of the WinModState displaying the Model */ strcat(statename, stripSuffix(model_name_ptr)); /* ask the WinModState to close the window */ if (gmsStFindByName(statename)) STMSG(statename, "close_window", ""); 5. Add the OnGmsCloseDocument method. void CMyproject_mfcDoc::OnGmsCloseDocument() { /* The child frame window received a WM_GMS_CLOSE message. Close the document */ CDocument::OnCloseDocument(); } myproject_mfcView.cpp: 1. Add SL-GMS include files. #include "stdafx.h" #include "gms_include.h"// GMS_ADDED // #include "myproject_mfc.h" 2. Add extern for SL-GMS functions. // GMS_ADDED extern "C" { char *stripSuffix( const char *name ); } Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-17 3. Change base class of CMyproject_mfcView from CView to GMS_View. IMPLEMENT_DYNCREATE(CMyproject_mfcView, GMS_View) BEGIN_MESSAGE_MAP(CMyproject_mfcView, GMS_View) 4. Add initialization of resizing variable in the constructor. // GMS_ADDED - resizing flag resizing = 0; 5. Add code to OnInitialUpdate( ). char char char char buf[1024]; *dir_name; *modelname; statename[1024]; CMyproject_mfcDoc* pDoc = GetDocument(); VERIFY(pDoc); if (pDoc && strlen(pDoc->model_name) > 0) { // store the Model name and path in a buffer strcpy(buf, (const char *)pDoc->model_name); // Scan back from end of pathname until a '\' is found dir_name = &buf[strlen(buf)]; while (*dir_name != '\\') dir_name--; // Split string into 2 parts: // the directory name and the file name *dir_name = 0; modelname = stripSuffix(++dir_name); dir_name = buf; Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-18 // Set the current directory gmsChdir(dir_name); // Send the Top State the info it needs to // invoke a WinModState in the window // created by MFC strcpy(statename, "my_window_"); strcat(statename, modelname); STMSG_S("my_top", "winmodstate_name", statename); STMSG_P("my_top", "app_subwindow_handle", m_hWnd); STMSG_P("my_top", "app_window_handle", GetParent()->m_hWnd); STMSG_S("my_top", "model_name", modelname); } OnSetFocus(NULL); ::SetWindowPos(GetParent()->m_hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); CView::OnInitialUpdate(); 6. Add code to Create( ) . // GMS_ADDED // For the controls to be displayed and not // clipped by graphics BOOL CMyproject_mfcView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { dwStyle |= WS_CLIPCHILDREN; Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-19 return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } 7. Add the stripSufix( ) function. extern "C " char *stripSuffix( const char *name ) { int i; static char new_name[G_MAXFILENAME]; strcpy(new_name, name); for (i=strlen(name);i>=0;i--) { if (name[i] == '.') { new_name[i] = '\0'; break; } } return new_name; } 8. Remove code from the OnDraw( ) method if it exists. The resulting application has the following command line options: myproject_mfc_sdi [-Umsecs] [model1]...[modelN] msecs = data update rate in milliseconds model1 = first Model path and name modelN = last Model path and name Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-20 The final version of myproject_mfc_sdi uses "user_top.c" and "user_ds.c" from the myproject_common directory, and can generate data for the windtunnel and mymodel Models. Any Model whose data is generated by a .dat filecan also be displayed. The MFC file selection dialog can be used to navigate to other directories that contain SL-GMS Models and display them as shown in Figure G-2. Figure G-2Myproject_mfc_mdi Displaying Dynactions Demo Models Version 6.2a- 26 May 2006 SL-GMS Examples Manual G-21 Index A ActiveX control HTML page ..................................B-7 terminate SL-GMS .......................B-4 ActiveX control (SL-GMS) class definition .............................B-4 files ..............................................B-1 methods ............................... 2-7, B-3 overview....................................... 2-6 properties............................. 2-7, B-3 ActiveX framework example .......................................B-1 overview....................................... 2-6 ActiveX Visual Basic example ...........B-9 AppExit( ) .........................................E-16 applet creating ..................................... C-22 limitations.................................. C-26 running...................................... C-24 application building ........................................ 2-3 application framework description ................................... 2-1 AppLoop( ) .......................................E-17 Apply Button Dialog Interface Model............... 3-23 AppOpen( ) ......................................E-16 ASCII file hold variables in Model .............. 4-14 B build applications ............................... 2-3 build_argc_argv( )..............................E-9 C caching SubModels example ....................................... 6-1 child Window...................................... 3-7 class modifications.............................F-7 Version 6.2a- 26 May 2006 Click methods.................................. B-13 Client State (dialog data manager state) definition .................................5-3 example.......................... 5-5, 5-9 Close Button Dialog Interface Model ...............3-23 CloseModel method ...................B-3, B-5 ComboBox items example....................................... B-9 component frameworks description....................................2-1 custom method custom_invoke invoke WinModState ............4-28 object_selected ..........................5-11 custom State Client State (dialog data manager State)..5-5, 5-9 Data Source Manager State4-2, 4-33, 4-38 Event State.................................3-17 Top State application with... 3-22, 3-23, 5-8, 5-11 custom_invoke used instead of standard method4-28 D Data Source Manager State example..................... 4-2, 4-33, 4-38 Data Source Model State ......... 3-13, 4-2 global variables ..........................3-15 use to create Model at run time..3-24 data structures for dialog interface define variables ............................5-3 dataproc process..............................4-39 DataSource bean adding a listener........................ C-21 SL-GMS Examples Manual i Index adding to GmsBeanMain .......... C-14 controlling the timer .................. C-19 datasvr process ............................... 4-46 define_variable( ) ...........4-10, 4-16, 4-18 Dialog Interface Model..................... 3-23 Apply button............................... 3-23 Close button............................... 3-23 Reset button .............................. 3-23 Dialog State (DialogState State Class) ............ 5-3 example of interface with3-21, 5-1, 5-5, 5-9 overview............................... 3-23 DLL source files SL-GMS Bean............................. C-6 ds_string ........................4-19, 4-29, 4-33 hold list of variables in Model..... 4-10 in ModelState scoping ............... 4-22 DsModelState 3-13, 3-15, 3-16, 4-2, 4-18 global variables.......................... 3-15 use to create Model at run time . 3-24 used with VarInit function........... 4-17 Dump States Button basic6 example.......................... 3-30 E Edit Dialog State .............................. 3-23 Event State custom ....................................... 3-17 ExitInstance method example .......................................B-4 F Form_Load method ...........................B-9 framework ActiveX example .................................B-1 overview................................. 2-6 description ................................... 2-1 JavaBeans Version 6.2a- 26 May 2006 examples ............................... C-1 overview ...............................2-11 MFC Multiple Document Interface (MDI) example.................................G-1 overview ...............................2-23 MFC Single Document Interface (SDI) example................................. F-1 overview ...............................2-21 Microsoft’s Win32 API example................................. E-1 overview ...............................2-18 SL-GMS enhancements .......2-18 Motif example................................. D-1 overview ...............................2-15 SL-GMS enhancements .......2-15 portability......................................2-1 G GetModelname method..................... B-3 GetWinModName method................. B-3 GISMOs used to invoke Dialog State example..................................5-1 global variables . 3-15, 3-16, 4-2, 4-4, 5-3 gms_ gms_hilite_edge_selobj( ) ................3-19 gms_textentry_var( ) ........................3-19 gmsB GmsBean applet .......................................... C-3 limitations ............................ C-26 building the DLL .......................... C-7 connect Java-coded data source C-9 creating an applet...................... C-22 description................................... C-1 DLL Source files.......................... C-6 SL-GMS Examples Manual ii Index external datasources ................. 2-13 installing the DLL ...................... C-11 Java source files ......................... C-5 overview..................................... 2-13 properties........................... 2-13, C-6 running an applet ...................... C-24 sending an SL-GMS State message . C-16 zooming .............................. C-18 use of multiple............................ 2-14 GmsBeanApplet description .................................. C-3 GmsBeanMain add text fields............................ C-15 building in Visual Cafe ................ C-9 building the demo ..................... C-12 description .................................. C-4 execution .................................. C-14 running demo............................ C-22 gmsD GmsDataSource bean description .................................. C-9 GMSDataSource.java ....................... C-9 gmsDynInit( ) ................................... 4-18 gmsI gmsInsDynInitFctn( )........................ 4-19 gmsInstallInsDynInitIntrcpt( ) ........... 4-19 gmsInstallPrmDynInitIntrcpt( ) ......... 4-19 gmsP gmsPrmDynInitFctn( )...................... 4-19 gmsR gmsRunMainLoop( ) .... 2-16, 2-19, D-23, E-21 gmsS gmsStVarDefineChanged( )............. 3-16 Version 6.2a- 26 May 2006 gmsV gmsVarInitFctn( )..............................4-16 H HTML page myproject_ax................................2-7 I input-event .......................................3-13 integer ..............................................3-13 Invoke Dialog to Change Data button3-23 invoke dialog using GISMO................5-8 invoke_dialog method basic4 example ..........................3-22 invoke_dialog user-defined function...5-8 J Java class ......................................... C-9 DatasorceDyn.java...................... C-9 DataSourceW.java ...................... C-9 Timer.java ................................... C-9 JavaBeans example add DataSource bean ............... C-14 applet limitations ............................ C-26 applet example...........................2-11 building Java classes ................ C-10 building the GmsBeanMain demoC-12 creating an applet...................... C-22 custom GMSDataSource bean ... C-9 displaying an SL-GMS Model...... C-1 external datasources..................2-13 GmsBeanApplet .........................2-11 GmsBeanMain ...........................2-13 add text fields ...................... C-15 executing ............................. C-14 installing the DLL....................... C-11 loading the beans into Visual Cafe ................... C-11 SL-GMS Examples Manual iii Index MyProjectJavaBean ................... 2-11 overview..................................... 2-11 running...................................... C-22 running an applet ...................... C-24 send SL-GMS State message .. C-16 zooming .............................. C-18 set-up directories ........................ C-9 set-up paths for Visual Cafe or DOS ....... C-10 SL-GMS Java Bean .................... C-4 timer control .............................. C-19 JavaBeans framework overview..................................... 2-11 K key event custom Event State.................... 3-17 L locator event custom Event State.................... 3-17 M main Model ........................................ 3-5 MainFrm.............................................F-5 messages output basic3 example .................... 3-20 MFC Multiple Document Interface (MDI) framework example ...................................... G-1 overview..................................... 2-23 MFC Single Document Interface (SDI) framework example .......................................F-1 overview..................................... 2-21 Microsoft Win32 API framework example .......................................E-1 overview..................................... 2-18 SL-GMS enhancements ............ 2-18 Version 6.2a- 26 May 2006 Microsoft’s COM.................................2-6 Model create at run time example................................3-24 replace in a Window...................3-10 stacking in a Window .................3-10 ModelState Variable Table...............4-25 Motif framework example....................................... D-1 overview .....................................2-15 SL-GMS enhancements.............2-15 motif_stuff.c enhancements........................... D-16 listing ........................................... D-5 my_dyninit_fctn( ).............................4-18 my_top_initialize( ) .......................... D-12 mymodel Model variables...................................... A-5 myproject.........................................G-16 myproject examples listing of ........................................2-2 myproject_ax "myproject_ax.cpp" file ................ B-4 CloseModel method .................... B-5 control class ................................ B-4 creating the SL-GMS WinModState . B-6 displaying a Model ...................... B-5 ExitInstance method.................... B-4 HTML page .......................... 2-7, B-7 InitInstance method..................... B-4 OnCreate method........................ B-5 overview .......................................2-6 SL-GMS initialization................... B-4 SL-GMS termination.................... B-4 myproject_ax.ocx ...............................2-6 myproject_ax_vb Click methods............................ B-13 ComboBox definiton.................... B-9 details.......................................... B-9 SL-GMS Examples Manual iv Index Form_Load method .....................B-9 initialization ..................................B-9 limitations......................... 2-10, B-13 process_box_Click method........B-12 SendStateMessage method2-9, B-13 user interaction ............................ 2-9 myproject_common "gmsfuns.c" file ............................A-5 "gmsmain.c" file ...........................A-2 "user_ds.c" file .............................A-4 "user_top.c" file ............................A-3 custom Top State.........................A-3 data generation............................A-4 details ..........................................A-1 execution options .........................A-1 initiation........................................A-2 overview....................................... 2-4 source and Model files.................A-1 State tree ............................. 2-5, A-2 support functions .........................A-5 variables mymodel Model......................A-5 windtunnel Model ...................A-5 myproject_jb overview..................................... 2-11 myproject_mfc_mdi add button to Help menu ............ G-4 add text to About window............ G-4 class modifications...................... G-8 MainFrm.cpp ......................... G-8 myproject_mfc.cpp................ G-8 myproject_mfcDoc.cpp ....... G-16 myproject_mfcView.cpp ...... G-17 header file changes .................... G-4 MainFrm.h............................. G-5 myproject_mfc.h.................... G-6 myproject_mfcDoc.h ............. G-6 myproject_mfcView.h............ G-7 overview..................................... 2-23 parse command line ................. G-12 Version 6.2a- 26 May 2006 project setting changes ...............G-3 resource modifications ................G-4 SL-GMS enhancements..............G-3 myproject_mfc_sdi ............................ F-7 add button to Help menu............. F-4 add text to About window ............ F-4 adding SL-GMS to MFC-SDI framework.............. F-2 AppWizard settings ............. F-1, G-1 class modifications MainFrm.cpp ....................... F-16 myproject_mfc.cpp ................ F-7 myproject_mfcDoc.cpp........ F-14 myproject_mfcView.cpp ...... F-14 create initial application............... F-1 ExternalMessage( ) ................... F-10 header file changes..................... F-5 MainFrm.h ............................. F-5 myproject_mfc.h .................... F-6 myproject_mfcDoc.h.............. F-6 myproject_mfcView.h ............ F-6 open Model files ........................ F-12 overview .....................................2-21 parse command line.................. F-11 project settings ............................ F-2 resource modifications ................ F-4 myproject_motif advanced event loop ................. D-20 command line options ............... D-23 custom event loop ..................... D-11 eventloop_xm.c ......................... D-20 ExternalMessage( ) ................... D-16 gmsmain.c................................... D-3 enhancements..................... D-11 main module................................ D-3 motif_stuff.c................................. D-5 enhancements..................... D-16 overview .....................................2-15 parsing the command line ......... D-12 running ...................................... D-23 SL-GMS Examples Manual v Index simple_external_loop( ) ............ D-15 source files.................................. D-1 start_gms_model( )................... D-14 widget creation and callbacks..... D-5 myproject_win add user_top.c and user_ds.c ...E-20 advanced event loop..................E-18 support functions..................E-20 command line options ................E-21 external event loop ....................E-14 gmsmain.c ...................................E-4 SL-GMS enhancements.........E-8 overview..................................... 2-18 parse the command line ............E-11 produce Win32 framework ...........E-1 define resources ....................E-1 define Window Procedure......E-2 display Window ......................E-3 register Window class ............E-2 resources.h ..................................E-5 resources.rc .................................E-5 SL-GMS send message to Win32E-13 source files...................................E-4 support functions advanced event loop............E-20 AppExit( ) .............................E-16 AppLoop( ) ...........................E-17 AppOpen( ) ..........................E-16 build_argc_argv( ) ..................E-9 ExternalMessage( )..............E-13 parse_command_line( ) .......E-11 simple_external_loop( )........E-14 start_gms_model( ) ..............E-12 user_main_loop_run( )...............E-18 win_stuff.c....................................E-6 SL-GMS enhancements.......E-15 Windows callbacks ......................E-6 Windows resource definitions ......E-5 Windows resource files ................E-5 WinMain definition .......................E-4 Version 6.2a- 26 May 2006 MyProjectJavaBean command line.............................. C-1 description................................... C-1 myproject-win adding SL-GMS........................... E-8 mytop Model.......................................4-2 O Object Selection State with a Dialog State interface example................................ 5-1, 5-9 object_selected method ...................5-11 OnCreate method.............................. B-5 P Pan Button basic6 example ..........................3-30 panning example......................................3-28 performance optimizing .....................................6-1 pipeline Model ..................................3-29 portability example........................................2-1 process_box_Click method ............. B-12 Program Architecture basic1 example ............................3-5 basic2 example ..........................3-15 basic3 example ..........................3-18 basic4 example ..........................3-22 basic5 example ..........................3-25 common to dialog1 and dialog2 examples ..........................5-3 dialog1 example ...........................5-7 dialog2 example .........................5-10 dynalloc example .......................4-34 shmem example.........................4-40 socket example ..........................4-46 subcache example .......................6-3 varscop1 example ......................4-23 SL-GMS Examples Manual vi Index varscope2 example.................... 4-26 Program Updating............................ 4-24 basic2 example.......................... 3-15 Pump Dialog Window ........5-4, 5-8, 5-11 R Real, String ...................................... 3-13 Replace button basic1 example.......................... 3-10 Reset Button basic6 example.......................... 3-30 Dialog Interface Model............... 3-23 resources.h listing............................................E-5 resources.rc listing............................................E-5 S Scale Control Objects .............3-14, 4-24 scoping variables ............................. 4-20 SendStateMessage method2-9, B-3, B-9, B-13 SetModelname method.............. B-3, B-6 shared memory value of variables ....................... 4-39 sibling Window................................... 3-7 simple_external_loop( ) ...................E-14 SL-GMS Java Bean, see GmsBean SL-GMS Tutor window....................... 1-3 SL-GMS/ActiveX integration files.......B-2 SL-GMS/ActiveX interface control class.................................B-4 example .......................................B-3 SL-GMS initialization ...................B-4 SL-GMS termination ....................B-4 SL-GMSTutor name of executable on Motif........ 1-3 name of executable on Windows . 1-3 socket TCP/IP for variable values ......... 4-45 Version 6.2a- 26 May 2006 Stack button basic1 example ..........................3-10 StandardTopState ........................... D-11 start_gms_model( ) ......................... E-12 State tree myproject_common.............. 2-5, A-2 String Array ......................................3-13 SubModel using a cache to ptimize performance...............6-1 SubModel cache active replicates ...........................6-6 capacity definition .................................6-6 count definition .................................6-6 creating ........................................6-5 disabling .......................................6-5 inactive replicates.........................6-6 Symantec Visual Cafe building a GmsBean demo.......... C-9 Symantec's Visual Café ...................2-14 T TCP/IP socket used for value of Model variables4-45 Text Edit Box Control Object.. 3-14, 4-24 Text Edit Rectangle..........................3-18 Text Filled Rectangles......................3-15 timer-event ............................. 3-13, 3-15 U update variables changed in dialog interface ..........5-3 User Interaction................................4-24 basic1 example ............................3-5 basic2 example ..........................3-14 basic3 example ..........................3-18 output messages ..................3-20 basic4 example ..........................3-22 SL-GMS Examples Manual vii Index basic5 example.......................... 3-25 basic6 example.......................... 3-29 dialog1 example........................... 5-7 dialog2 example......................... 5-10 dynalloc example ....................... 4-34 myproject_ax_vb example ........... 2-9 shmem example ........................ 4-40 socket example.......................... 4-46 subcache example ....................... 6-3 varscope1 example.................... 4-23 varscope2 example.................... 4-26 user_activate_fctn( ) ........................ 3-16 user_mail_loop_run( )......................E-18 UserData hold list of variables in object..... 4-12 pass variable name...................... 5-1 user-defined function ......................... 5-8 Using Different Data Sources example ..................................... 4-23 V Valve Dialog Window.........5-4, 5-8, 5-11 VarDef.............................................. 4-16 vardef_state ..................................... 3-16 variables common between Models ............ 4-4 defining to SL-GMS data structures for dialog interface5-3 use custom VarInitFctn( )..... 4-16 using DynInit Intercept functions4-18 determine those in a Model ......... 4-2 use an ASCII file .................. 4-14 use ds_string........................ 4-10 use UserData string ....4-12, 4-18 global definition. 3-15, 3-16, 4-2, 4-4, 5-3 linkage Version 6.2a- 26 May 2006 definition .................................4-1 obtain values thru TCP/IP sockets ... 4-45 registration definition .................................4-1 source modules for examples 4-6 run time creation .............. 4-25, 4-33 scoping definition .................................4-1 examples ..............................4-20 scoping on ModelState...............4-25 shared memory example............4-39 update apply function for dialog interface5-3 input event............................3-13 timer-event ...........................3-13 VarRef ..............................................4-16 View Manager State.........................3-28 Visual Cafe creating an applet...................... C-22 W win_stuff.c listing ........................................... E-6 SL-GMS enhancements............ E-15 Window create "child" ................................3-7 create "sibling" .............................3-7 invoke with custom method........4-28 window events custom Event State ....................3-17 windtunnel Model variables...................................... A-5 WinModState....................................4-29 invoke with custom method........4-28 X XtAppInitialize( ) .............................. D-11 SL-GMS Examples Manual viii Index XtAppMainLoop( )........................... D-12 Z Zoom by Extent Button basic6 example.......................... 3-30 Zoom in Button basic6 example.......................... 3-30 Zoom In Once Button basic6 example.......................... 3-30 Zoom in/out Button basic6 example.......................... 3-30 Zoom out Button basic6 example.......................... 3-30 Zoom Out Once Button basic6 example.......................... 3-30 zooming and panning example ..................................... 3-28 Version 6.2a- 26 May 2006 SL-GMS Examples Manual ix