Technical Reference

Download as pdf or txt
Download as pdf or txt
You are on page 1of 465

Copyright © 1987-2019 by Imagine That Inc. All rights reserved. Printed in the United States of America.

You may not copy, transmit, or translate all or any part of this document in any form or by any means, electronic
or mechanical, including photocopying, recording, or information storage and retrieval systems, for any purpose
other than your personal use without the prior and express written permission of Imagine That Inc.

License, Software Copyright, Trademark, and Other Information

The software described in this manual is furnished under a separate license and warranty agreement. The soft-
ware may be used or copied only in accordance with the terms of that agreement. Please note the following:

ExtendSim blocks and components (including but not limited to icons, dialogs, and block code)
are copyright © by Imagine That Inc. and/or its Licensors. ExtendSim blocks and components
contain proprietary and/or trademark information. If you build blocks, and you use all or any
portion of the blocks from the ExtendSim libraries in your blocks, or you include those
ExtendSim blocks (or any of the code from those blocks) in your libraries, your right to sell, give
away, or otherwise distribute your blocks and libraries is limited. In that case, you may only sell,
give, or distribute such a block or library if the recipient has a valid license for the ExtendSim
product from which you have derived your block(s) or block code. For more information,
contact Imagine That Inc.

Imagine That!, the Imagine That logo, ExtendSim, Extend, and ModL are either registered trademarks or
trademarks of Imagine That Incorporated in the United States and/or other countries. Mac OS is a registered
trademark of Apple Computer, Inc. Microsoft is a registered trademark and Windows is a trademark of Mic-
rosoft Corporation. GarageGames, Inc. is the copyright owner of the Torque Game Engine (TGE), and the
copyright for Stat::Fit® is owned by Geer Mountain Software. All other product names used in this manual
are the trademarks of their respective owners. TGE and Stat::Fit are licensed to Imagine That, Inc. for distri-
bution with ExtendSim. All other ExtendSim products and portions of products are copyright by Imagine
That Inc. All right, title and interest, including, without limitation, all copyrights in the Software shall at all
times remain the property of Imagine That Inc. or its Licensors.

Acknowledgments

Extend was created in 1987 by Bob Diamond; it was re-branded as ExtendSim in 2007.

Chief architects for ExtendSim 10: Steve Lamperti and Bob Diamond

Simulation Engineers: Anthony Nastasi, Cecile Pieper, Peter Tag, and Dave Krahl

Graphics, documentation, and editing: Kathi Hansen, Carla Sackett, and Pat Diamond

Imagine That Inc • 6830 Via Del Oro, Suite 230 • San Jose, CA 95119 USA
408.365.0305 • fax 408.629.1251 • [email protected]
www.ExtendSim.com
Table of Contents
TABLE OF CONTENTS

TECHNICAL OVERVIEW
Introduction ..............................................................................................................1
About the Technical Reference.......................................................................................2
Additional resources.......................................................................................................3
Parts of a Block.........................................................................................................5
The Example block.........................................................................................................6
The block’s user interface—its dialog............................................................................6
The block’s structure ......................................................................................................6
Overview of block parts, by tab and pane ......................................................................7
Icon tab ...........................................................................................................................9
Script tab.........................................................................................................................11
Dialog tab .......................................................................................................................13
Help tab ..........................................................................................................................14
Dialog items....................................................................................................................14
Connectors......................................................................................................................20
ModL Overview........................................................................................................25
ModL feature overview ..................................................................................................26
ModL compared to other programming languages ........................................................27
ModL language terminology ..........................................................................................30
Differences between equation blocks and programmed blocks .....................................31
Structure of a block’s ModL code ..................................................................................32
Accessing connectors from a block’s code ....................................................................34
Accessing dialog items from a block’s code ..................................................................35
Accessing code from other languages ............................................................................42
External source code.......................................................................................................42

TUTORIAL
Creating a Block .......................................................................................................43
Building a simple block that converts miles to feet .......................................................44
Adding user interaction and display features .................................................................48
Adding an intermediate results feature...........................................................................51
Adding 2D animation .....................................................................................................53
Other features you might have used ...............................................................................54
Defining functions ..........................................................................................................56

INTEGRATED DEVELOPMENT ENVIRONMENT (IDE)


The ModL Language ................................................................................................59
Names .............................................................................................................................60
Data types: definitions and declarations.........................................................................60
Scope of global, local, and static variables.....................................................................62
Constant definitions........................................................................................................62
Constants that are pre-defined ........................................................................................63
BLANK and NoValue .................................................................................................... 63
Numeric type conversion ............................................................................................... 64
Arrays............................................................................................................................. 65
Array-like structures ...................................................................................................... 67
Operators........................................................................................................................ 68
Control statements and loops ......................................................................................... 70
User-defined functions................................................................................................... 72
Message handlers ........................................................................................................... 75
System variables ............................................................................................................ 76
Global variables ............................................................................................................. 76
Conditional compilation ................................................................................................ 76
Programming Tools...................................................................................................77
Script Editor ................................................................................................................... 78
Debugging and profiling ................................................................................................ 81
Include files.................................................................................................................... 81
Conditional compilation ................................................................................................ 82
External source code control.......................................................................................... 83
Extensions ...................................................................................................................... 85
DLLs .............................................................................................................................. 86
Shared libraries .............................................................................................................. 88
Sounds............................................................................................................................ 89
Picture and movie files .................................................................................................. 89
Protecting libraries ......................................................................................................... 89
Programming Techniques .........................................................................................91
Data source indexing and organization.......................................................................... 92
Equation block programs ............................................................................................... 92
Working with dialogs ..................................................................................................... 93
Remote access to dialog variables ................................................................................. 97
Working with connectors ............................................................................................... 100
Working with arrays....................................................................................................... 101
Working with linked lists ............................................................................................... 109
Using message handlers................................................................................................. 109
Working with databases ................................................................................................. 111
Reading text blocks as commands ................................................................................. 113
Changing data while the simulation is running ............................................................. 115
Scripting......................................................................................................................... 116
OLE and ActiveX Automation....................................................................................... 117
Animation Using ModL............................................................................................125
2D animation.................................................................................................................. 126
3D animation.................................................................................................................. 135
Simulation Architecture ............................................................................................157
Running a simulation ..................................................................................................... 158
How discrete event blocks and models work................................................................. 166
Globals in discrete event blocks .................................................................................... 181
Creating blocks for discrete event models ..................................................................... 185
How discrete rate blocks and models work ................................................................... 185
Globals in discrete rate blocks ....................................................................................... 185
Globals for ARM (Advanced Resource Management).................................................. 187
Other reserved global variables ......................................................................................187
Debugging ................................................................................................................189
Debugging models..........................................................................................................190
Profiling..........................................................................................................................190
Debugging block code without the Source Code Debugger ..........................................191
Source Code Debugger...................................................................................................192
Debugger tutorial............................................................................................................192
Source code debugger reference.....................................................................................203

VARIABLES, MESSAGES, & FUNCTIONS


ModL Variables.........................................................................................................209
System variables.............................................................................................................210
Global variables..............................................................................................................211
Messages and Message Handlers .............................................................................213
Summary of messages ....................................................................................................214
Simulation messages ......................................................................................................214
Model Status messages...................................................................................................216
Block Status messages....................................................................................................217
Dialog messages .............................................................................................................219
Connector messages .......................................................................................................221
Block to block messages ................................................................................................222
Dynamic Link messages.................................................................................................223
OLE messages ................................................................................................................223
3D messages ...................................................................................................................223
ModL Functions........................................................................................................225
ModL function overview ................................................................................................226
Math functions................................................................................................................227
I/O functions...................................................................................................................242
Animation .......................................................................................................................270
Blocks and inter-block communications ........................................................................295
Models and notebook .....................................................................................................331
Scripting .........................................................................................................................337
Reporting ........................................................................................................................345
Plotting/Charts................................................................................................................345
Database functions..........................................................................................................354
Arrays, pointers, queues, delay, linked list, and string lookup table functions ..............376
Miscellaneous functions .................................................................................................394
User-defined functions for ADO ....................................................................................405

APPENDIX
Menu Command Numbers........................................................................................409
Upper Limits.............................................................................................................413
ASCII Table ..............................................................................................................417
Cross-Platform Considerations.................................................................................419
Libraries..........................................................................................................................420
Models ........................................................................................................................... 420
Menu and keyboard equivalents .................................................................................... 420
Menu and keyboard equivalents for developers ............................................................ 421
Transferring files between operating systems................................................................ 421
IPC or multi-server considerations ................................................................................ 423
Cross-platform code....................................................................................................... 424

INDEX
Technical Overview

Introduction
Where you learn where you need to begin

“‘Begin at the beginning,’ the King said, gravely,


‘and go ‘til you come to the end; then stop.’”
— Lewis Carroll
2 Overview
About the Technical Reference

About the Technical Reference


The purpose of the Technical Reference is to reveal the ExtendSim integrated development
Overview

environment (IDE) so that you can:


• Use equations, logic statements, and function calls in equation-based blocks
• Create new blocks or modify copies of ExtendSim blocks
• Interface with ExtendSim using external code such as DLL’s or VBA
• Build and control models using scripting
This manual is a companion to the ExtendSim User Reference which is a guide for those build-
ing models.
ExtendSim IDE
The Technical Reference reveals the ExtendSim IDE, which has several components:
• The ModL language, a variation of C++ that has been customized for simulation
• An equation editor for creating logic statements, formulas, and programming code in equa-
tion blocks
• A script editor for modifying or creating custom-programmed blocks that are fully integrated
with ExtendSim
• A built-in compiler so the custom blocks you create are compiled into machine language and
saved in libraries. The blocks that ship with ExtendSim, and the blocks that you created, are
pre-compiled for use in models.
• A graphical user interface for building custom blocks, including an icon builder and a dialog
editing environment so you can modify or create custom dialogs
• Programming tools, such as include files and external source code capability, that support
and simplify your programming efforts
• A built-in source-code debugger that helps to locate errors in the blocks or equations you
create
☞ The Technical Reference presumes that you know how to create models in ExtendSim. See one
of the ExtendSim Quick Start Guides for model-building information.
How the Technical Reference is organized
The Technical Reference is organized into several sections:
• Overview
• “Parts of a Block” (which starts on page 5) describes the internal parts (structure) of
blocks. This chapter is also helpful for non-developers, to understand how the blocks in
their models work.
• “ModL Overview” (starting on page 27) gives an overview of the “action” part of a
block – the ModL code. If you use equation-based blocks — Equation and Optimizer
blocks (Value library), Equation(I) and Queue Equation blocks (Item library), or the
Buttons block (Utilities library) — you will also find this chapter helpful.
• Tutorial
• The “Creating a Block” chapter provides a tutorial on how to build a new block; the
chapter starts on page 44.
Introduction 3
Additional resources

• Integrated Development Environment


• “The ModL Language” on page 59 describes ModL’s structure and constructs in detail.

Overview
It presumes you have read the chapters in the Overview module.
• “Programming Tools” describes all the tools, such as include files and external source
code control, that ExtendSim provides to help you program efficiently; it starts on
page 81.
• “Programming Techniques” gives procedures and suggestions for programming using
ModL and for interfacing ExtendSim with other languages, such as VBA. That chapter
starts on page 91.
• “Animation Using ModL”, starting onpage 125, describes the ExtendSim 2D capabil-
ity and features.
• “Simulation Architecture” gives important information about how ExtendSim runs
simulations and how discrete event and discrete rate models and blocks work. The
chapter starts on page 157.
• “Debugging”, which begins on page 190, discusses model and code debugging and
shows how to use the ExtendSim source code debugger.
• Reference
Starting on page 210 are three chapters that list and discuss all of the ExtendSim variables,
messages, and functions.

• Appendices
• Appendix A: upper limit values for ExtendSim
• Appendix B: an ASCII table
• Appendix C: menu commands and numbers for the ExecuteMenuCommand function
• Appendix D: cross-platform (Windows and Macintosh) considerations
As you will see, programming blocks in ExtendSim is quite easy, especially if you have ever
programmed in any language.
Additional resources
Imagine That Inc. provides several resources to support your simulation experience.
1) Getting Started. The Getting Started model open when you launch ExtendSim. Use this
interface to explore sample models and to view tutorials on building and running models.
2) Online help:
• Access the electronic User Reference and Technical Reference by giving the command
Help > ExtendSim Help or press F1 on your keyboard.
• Use tooltips to identify interface elements.
• Get complete definition of how a block works, including descriptions of its dialog
items and connectors, by clicking a block’s Help button.
3) Web advice. FAQs are available at www.ExtendSim.com/support/advice/faq.html.
4) Networking. Links for ExtendSim user forums, networks, and blogs are at www.Extend-
Sim.com/support/advice/forum.html. For example, the ExtendSim E-Xchange is a user
4 Overview
Additional resources

forum for sharing ideas, insights, and modeling techniques with other ExtendSim users.
Use this forum to post issues and solutions, share blocks and models, and to talk directly to
Overview

other people developing simulations. You must register to join, but access is free and avail-
able to all ExtendSim modelers.
5) Complimentary support. Get technical assistance for installation issues, basic usage ques-
tions, and troubleshooting for up to 60 days after purchasing a new product or upgrade.

Contacting Imagine That Inc. Technical Support


You must be registered to receive technical support. Support is complimentary for the first 90
days after purchase. After that, you must either subscribe to the ExtendSim Maintenance Plan
or purchase per-incident support.
When you contact our support representatives, please provide the following information:
1) ExtendSim serial number or activation code, product name, and release number:
Windows: Located in the Help > About ExtendSim menu command, on the title page of
the User Reference, or on the tear-off remainder of your registration card.
Mac OS: Located in the ExtendSim > About ExtendSim menu command, on the title
page of the User Reference, or the tear-off remainder of your registration card.
2) Name and contact information (telephone, email, and/or fax), so we can reply.
3) Type of computer.
4) Operating system and version.
Be sure you are using the current version of ExtendSim. Free software updates are available at
our web site (www.extendsim.com). Upgrades to newer versions may be purchased separately
if your license is not covered by a support plan.
Overview

Parts of a Block
An introduction to the internals of a block

“We shape our buildings;


thereafter they shape us.”
— Winston Churchill
6 Overview
The Example block

This chapter discusses a typical ExtendSim block’s internal structure—its icon, dialog, code,
and more.
Overview

☞ The Technical Reference assumes you know how to build models since many of the concepts
used when building blocks assume an understanding of how blocks are used in models.
The Example block
The Example block is a good source for investigating the dialog and internals of a block and
will be used throughout this chapter. It is a copy of the Simulation Variable block (Value
library) that ships with ExtendSim.
Any changes you make to a block in an ExtendSim library will affect that block in all existing
models and will get discarded whenever the library is updated. Thus, it is important that you
don’t make any changes to the blocks that are shipped with your ExtendSim product. Instead,
make a copy of the block and save it with a new name and in a new library, as was done
for this example.
Open a new model worksheet.
Open the Tutorial library located at ExtendSim/Documents/Libraries/Example Libraries.
From the Tutorial library’s library window, select the Example block and place it on the
model worksheet.
The block’s user interface—its dialog
Every block has a dialog, which may be as simple as just the OK and Cancel buttons or it may
be quite complex. A block’s dialog is its user interface—that is what modelers see when they
double-click the block’s icon.
Dialog of the Example block
Double-click the icon of the Exam-
ple block. This opens its dialog,
revealing two tabs:
• An Options tab dealing with
the system variables
• A Comments tab for user com-
ments
The frame, text, buttons, and entry
boxes that are seen in the tabs are col-
lectively known as dialog items.
In each block’s dialog, a Help button,
block label field, and View popup are
located at the bottom of the dialog and
to the left of the scroll bar, if there is one.
The block’s structure
A block’s internal structure is where the user-interface and block behavior is created and where
it’s icon, ModL code, dialog items, and other block components are defined. ExtendSim has
built-in editing tools for creating or modifying blocks.
Parts of a Block 7
Overview of block parts, by tab and pane

How to open a block’s internal structure


There are three ways to access an existing block’s internal structure:

Overview
1) Select the block by clicking once on its icon in a model worksheet. Then choose Develop>
Open Block Structure.
2) Right-click the block’s icon in a model worksheet or in the library window. Then select
Open Block Structure.
3) Double-click the block’s icon on a model worksheet or the library window while holding
down the Alt (Windows) or Option (Mac OS) key.

Examining the internal structure of the Example block


Open the internal structure for the Example block using one of the methods from above.
The block’s Script tab opens in front by default.
• On the left side are tabs for Icon, Script, Dialog, and Help.
• For each of these tabs:
• The title bar displays the name of the block and the name of the library the block
resides in
• There are panes for Connectors and Dialog Item Names on the right
Overview of block parts, by tab and pane
A block is composed of many parts, which are created in the tabs of the block’s structure win-
dow. These parts comprise a block’s internal structure and are interconnected. For example, the
code reads information from the connectors, the help text is displayed through the dialog, and
so on. All of the block’s parts can be controlled by ModL code.
The parts are listed below, by tab, and discussed in more detail later in this chapter.
Script tab
This tab is where the block’s code is entered. The code is written in ModL, the ExtendSim pro-
gramming language. ModL is what makes the block work and determines how it behaves.

Part Description Pages


ModL ModL code can read and write information via the connectors, 11
code dialog, ExtendSim database, the model environment, and other
blocks, as well as control all the parts of a block. This pane is
also where you enter headings about the block and comments
about the code.
Functions This pane lists the message handlers (in all caps) and functions 12
used in the block.
Includes This pane lists and opens the includes that are used in the code. 12

Icon tab
The Icon tab is for creating the icon and everything else in its environment. The icon is the
visual representation of the block as seen in a model. Icons can display 2D animation and most
often have connectors that facilitate the exchange of data between blocks.
8 Overview
Overview of block parts, by tab and pane

Part Description Pages


Overview

Icon Icons are created using the ExtendSim drawing environment or 9


a painting program, or by copying/pasting clip art.
2D Objects for 2D animation are part of the icon environment but 10
Animation can display anywhere in the model, even outside the icon’s
footprint. 2D animation can show motion, levels, and values,
and can alter an icon’s static look.
Connec- Connectors appear in the model as part of the icon. They are 20
tors used to transmit information to and from each block’s ModL
code. Connectors can be normal (single) or variable (a row of
single connectors).
☞ Blocks can also transmit information without using connec-
tors by sending messages to other blocks and by using
global variables, global arrays, or an ExtendSim database.
Icon views Icons can have one or more views such as a Forward and a 9
Reverse.
Show icon Used if connection lines are out of alignment when a model 10
positioner built in ExtendSim 9 or earlier is opened in ExtendSim 10+.

Dialog tab
The Dialog tab is where the block’s dialog is created and, if wanted, tabs for grouping dialog
items. The dialog is the window that appears when you double-click a block’s icon.

Part Description Pages


Dialog When creating a block, you specify the frames, text, buttons, 14
items tables, and entry boxes that go into the dialog (collectively
known as dialog items).
Tabs You can place all the dialog items in one dialog, or separate 13
them into functional groupings using tabs.
Dialog Allows you to set the default bottom and right-side edges for 13
Resizer each tab separately.

Help tab

Part Description Pages


Help text The text that appears when you click the Help button to the left 14
of the dialog’s bottom scroll bar. When the Help dialog is open,
buttons at the bottom can be used to find a block, or display
information about blocks, in all open libraries.

Connectors pane
This pane lists the names of the block’s connectors, if any. It is also used to edit the default
connector names so they can more closely represent their function. See “Editing connector
names” on page 22.
Parts of a Block 9
Icon tab

Dialog Item Names pane


This pane lists the names defined for the block’s dialog items. The name of a dialog item is

Overview
sent to the block code as a message when the dialog item is activated. By default, these names
are listed in order created; they can also be sorted alphabetically.
Icon tab
The Icon tab of the Example
block’s structure is shown at
right.
The area at the left of the
Icon tab is used to enter and
edit the icon(s) for the block
and to add animation
objects, block connectors,
and icon views.
The Example block’s icon
has one input connector on
the left of its icon and two
animation objects, numbered
1 and 2.
☞ The panes on the right of the
Icon tab are for Connectors
and Dialog Item Names as discussed on page 8.
Icon
A block’s icon is its most obvious aspect since it appears on the model worksheet. An icon
consists of a drawing or group of drawn objects, the block’s connectors, and possibly one or
more animation objects.
A block can have more than one icon; which one is shown is determined by which view is
selected, as discussed in “Icon views” on page 9.
There are two ways to create an icon:
1) With the ExtendSim drawing tools, as discussed in the User Reference. The Shapes and
Alignment tools provide a drawing environment for quickly creating icons.
2) By pasting drawings from the Clipboard. You can use a painting or drawing program to
create an icon. Then copy and paste it into the Icon tab.
Use the same tools for selecting objects in the icon pane as you would use to select graphic
objects in the model worksheet or notebook.
Icon views
The Icon views popup is located at the
top of the Icon tab. Each block has at
least one icon, which is its default. It is
also possible for blocks to display dif-
ferent icons. For example, a block
could have a Forward view icon and a
different icon with a Reverse view. Or
10 Overview
Icon tab

the block could show a different icon depending on the type of machine it represents or based
on a selection in the block’s dialog. ExtendSim accomplishes this by facilitating the creation of
Overview

different views of a block’s icon.


The modeler selects icon views by right-clicking on a block or using the Views menu to the
right of the block’s label in its dialog, as seen on page 6.
Developers give a block additional icons using the Icon views popup in the Icon tab. The first
icon that is created becomes the default view. As each view is added, ExtendSim copies the
current icon. This gives the developer something to start with instead of having to redraw all of
the icon. The Rotate and Flip buttons in the Alignment toolbar facilitate creating a new view
that represents a flow in a new direction.
The IconViewChange message is sent when the modeler changes the icon view or when a
ModL function call from a block changes the icon view; see page 219. There are also several
functions for managing icon views; see “Icon views” on page 330.
Views can be deleted or renamed at any time by using the commands in the Views popup
menu. An example of a block with multiple views is the Select Value Out block (Value library).
☞ All views have the same number of connectors, but connectors can be selectively hidden in a
view when it is created, or hidden and shown dynamically using ModL functions. ExtendSim
automatically adds and deletes connectors from all views when the number of connectors on a
block is changed.
Icon positioner
When models that were built prior to ExtendSim 10 are converted to ExtendSim 10 or later, the
position of the model’s blocks could be slightly different, causing connection lines to be
unaligned. In those cases, the icon positioner can be used to adjust the relative location of the
icon within the Icon tab so that the connection lines to the block are correctly aligned.
This adjustment has already been made in the current ExtendSim libraries, but you may want
to use the positioner for any custom blocks that have been converted from earlier versions.
The Show icon positioner checkbox, located in the Icon tab of the block’s structure,
hides and shows the icon positioner, the pink icon shown here. By default, the icon
positioner is located at the upper leftmost position of the icon’s graphic items. The
Reset Icon Positioner button resets the location of the icon positioner to the default.
To use the icon positioner, first determine approximately how many pixels and in what direc-
tion the icon needs to move so that the connection lines are aligned. Then in the Icon tab select
the icon positioner and move it with the cursor or the keyboard arrow keys.
There is also a ModL function, blockAdjustPosition, that uses the location of the item posi-
tioner to shift the location of the block by the offset of the positioner location.
Connectors
See “Connectors” on page 20.
2D animation
In the Example block’s icon shown above, the white rectangles at the center of the icon
(labeled with the numbers 1 and 2) are animation objects. When the block is created, one or
more animation objects can be added to the icon using the Animation Object button in the Icon
toolbar.
Parts of a Block 11
Script tab

The block’s ModL code interacts with animation objects, causing them to show various behav-
iors. Depending on how the objects are coded, the display could change due to user interaction

Overview
with the block (its dialog or connectors) and/or due to information received during the simula-
tion run. For the Example block, the animation object for the Example displays as text which
system variable has been selected in the block’s dialog.
There are several ways to animate a block using 2D animation objects:
• Typically, the block’s icon would be animated but it is also possible to animate outside the
icon’s footprint.
• Blocks can: show, hide, and change the colors of text and shapes; move a shape and increase
or decrease its size; show a changing level; show a picture or a movie; or move a picture
along connection lines between two blocks.
The Item and Rate libraries use 2D animation extensively.
For more information about 2D animation
• The ExtendSim User Reference gives an overview of 2D animation, including block-to-
block animation that flows along the connections in discrete event models.
• In this Technical Reference, the tutorial “Adding 2D animation” on page 53 shows how to
add 2D animation objects to a custom block.
• The section “2D animation” on page 126 has a lot more information about programming 2D
animation effects.
• ExtendSim has many functions that facilitate customizing animation depending on which
icon views are being selected by the modeler. See the functions for “Icon views” on
page 330.
Script tab
12 Overview
Script tab

he Script tab of the Example block looks like the screenshot above. This tab is used to enter
and edit the block’s ModL code and comments. ModL is the internal programming language
Overview

for ExtendSim.
Unlike the other block parts, which can be seen by the modeler, ModL code can only be
accessed through a block’s structure window or in an equation-based block’s editor window.
☞ As shown on page 78 there is a Script dialog in the Edit > Options menu that is used to specify
characteristics for a block structure’s Script tab. For example, you can change the colors of
user functions or keywords. When the block’s Script tab is the active window, use Alt + O to
open the Script dialog.
ModL code
If you know a programming language, you will probably recognize the structure of the ModL
code. ModL is essentially C++ with some enhancements and extensions to make it more robust
for simulation modeling.
☞ When you build blocks using ModL, the block’s program is compiled to native machine code.
Layout
After the copyright and modification history information, the first lines are the declaration of
the types of variables used in the code. Following is the code which is grouped into sections,
where each section is either a message handler or a function. Lines that begin with “//”, “**”,
or “/*” are comments.
For more information about the ModL language
• “ModL Overview” on page 25
• A tutorial starting on page 44
• “The ModL Language” on page 59

Functions
This popup lists the message handlers (in all caps) and functions used in the block.
Selecting something from the list causes the code to scroll to the section that uses the function
or message handler. It also opens the include file if the function or message handler is used in
an include.
For more information
• “Messages and Message Handlers” on page 213
• “ModL Functions” on page 225.

Includes
Lists and opens the include files that are used in the code. Include files are standard header
files that are put in ModL code and can contain ModL commands such as definitions, assign-
ments, and functions. The purpose of an include file is to simplify maintenance when several
blocks use similar variable definitions and functions. Include files are discussed on page 81.
Parts of a Block 13
Dialog tab

Dialog tab

Overview
The Dialog tab for the Example block’s structure looks like the screenshot shown here.
Dialog items
The buttons, parameter fields, check boxes, and so forth that comprise a block’s dialog are
known as dialog items.
☞ For a complete list and description of dialog items, see page 14.
Tabs
The block’s Dialog tab has two tabs at the top—Options and Comments.
Tabs in a dialog are used to group dialog items by function. When you create or modify a
block’s dialog you can:
• Add tabs to the dialog by clicking the + sign
• Add dialog items to a tab after bringing the tab to the front
• Rename a tab by double-clicking its name and choosing a new name in the window that
appears
• Delete a tab by clicking its close button, the X next to its name
• Move dialog items from one tab to another using the Cut, Copy, and Paste commands
Be careful when deleting a tab with dialog items on it. See the caution on page 18 about delet-
ing dialog items from blocks that are used in models.
Dialog Resizer
Since they usually have different numbers and types of dialog items, a block’s tabs are often
different sizes. The Dialog Resizer allows you to position the right and bottom edges of each
tab separately. This determines what is visible for each tab when it becomes the active window.
14 Overview
Help tab

Use the keyboard’s arrow keys, or drag the bottom right corner of the resizer, to set the default
size for each tab. ModL functions can also be used to set or reset the size of each tab in the dia-
Overview

log.
☞ The arrow keys can be used to change the position of the resizer’s bottom right corner.
Help tab
This tab is used to enter and edit the online Help for the block. This text appears when you
click the Help button in the lower left corner of a block’s dialog and is about the block and how
it can be used in a model. It is not available through the ExtendSim Help menu command,
which provides help for using the ExtendSim application.
You can add formatting to the text by selecting it and using the buttons in the Text toolbar.
☞ By default the block’s name and the first sentence of the text in the Help tab is displayed as a
tooltip when the cursor is hovered over the block. You can choose that just the block name, but
not the Help text, be displayed. To do this, turn off the “Include additional block information”
option in the Edit > Options > Model tab.
Dialog items
The frames, text, buttons, tables, and entry boxes that go into a dialog are collectively known
as dialog items. Dialog items are created on the Dialog tab using buttons from the Dialog Items
toolbar, shown below. Each dialog item is then configured or defined using options in its Prop-
erties window.
☞ See “Accessing dialog items from a block’s code” on page 35 for how dialog items are called in
ModL.

Types of dialog items


The buttons in the Dialog Items toolbar are shown above. The types of dialog items are sum-
marized in the this table in the same sequence as the buttons.

Type Description Page


Parameter Entry box that takes and/or displays a number. Users can 36
(Number) dynamically link parameters to a cell in an ExtendSim database
or global array instead of just entering data.
Popup A shadowed rectangle containing a menu of items. Each item 39
Menu in a popup menu has a label which can be changed using Modl
code. Note: popup menu indexes start at 1, not 0. Each item in
the list can have its text label formatted.
Checkbox Square buttons that have a check mark in them when they are 37
selected; the boxes are empty when not selected. Checkboxes
can have labels that appear as text to their right; the labels can
be changed using ModL code.
Button A button that can be clicked, such as an OK or Cancel button. 38
A button’s label appears as text inside the button; the labels can
be changed using ModL code.
Parts of a Block 15
Dialog items

Type Description Page

Overview
Radio Round buttons that appear in groups where each group has a 37
Button unique group number. Only one button in the group can be
selected at a time; this causes all the other buttons in the group
to become deselected. Radio buttons can have labels that
appear as text to their right; the labels can be changed using
ModL code.
Frame Used to group dialog items. Has an optional label that will 40
appear at the top of the frame. Does not require a dialog item
name. This dialog item can have its text label formatted.
Static Text Text that appears as a label in the dialog. Can be changed 39
(Label) through ModL code but not by the modeler. Can be formatted.
Dynamic Entry box that takes or displays text. Limited to 32,000 charac- 36
Text ters. This item uses an automatically resized dynamic array to
store the text. It is useful for larger amounts of text such as for
comments or for equations in the Equation and Optimizer
blocks.
Editable Entry box that takes or displays text. Limited to 255 characters. 36
Text Users can dynamically link editable text to a cell in an Extend-
Sim database or global array instead of just entering data.
Editable Same as Editable Text, above, but limited to 31 characters to 36
Text 31 save memory.
Data Table A two-dimensional table with scrollbars and adjustable column 38
widths (similar to a spreadsheet) for holding numbers. If block
code provides for it, modelers can change the number of rows
and columns and can dynamically link tables to an ExtendSim
database or global array. Can have its text label formatted.
Text Table A two-dimensional table with scrollbars and adjustable column 38
widths (similar to a spreadsheet) for holding text. If block code
provides for it, modelers can change the number of rows and
columns and can dynamically link tables to an ExtendSim data-
base or global array. The text can be formatted.
The Text Table uses a significant amount of memory and
searching strings is slower than searching data. If possible,
use the Data Table dialog item instead, especially if the
table is large.
Slider A control that allows you to select from a range of values by 41
moving a value indicator. You can manually drag the knob to
change a value or use ModL code to move the knob to show a
value.
Meter An output-only item that shows a needle in a meter. 41
Switch A switch that resembles a light switch. It has two values, 0 (off) 41
and 1 (on).
Calendar Takes an ExtendSim date value and displays it on a calendar. 42
16 Overview
Dialog items

Type Description Page


Overview

Clock Displays the time component of an ExtendDate value on a digi- 42


tal clock.
Embedded A placeholder for an OLE ActiveX object which can be manu- 41
Object ally inserted by the modeler or inserted by the block’s ModL
(Windows code.
only)

Properties of dialog items


To see the definition of a dialog item:
Open the block’s internal structure using one of the methods on page 7.
For example, open the structure of the Examples block (the block is located at Extend-
Sim/Documents/Libraries/Example Libraries/ Tutorial library)
In the structure’s Dialog tab, double-click the dialog item or right-click and select Properties
For example, double-click the “Add” dialog item of the Example block.
This opens the definition window for the designated dialog item. In this example, it opens
the properties for the dialog item labeled Add, as shown here.

Each properties window displays the properties of the selected dialog item. For the Add dialog
item, the information is:
• The dialog item is of the type Static Text; its button in the Dialog Items toolbar is shown to
the right of its type
• The variable name, for use in the script, is Static_Text8_lbl
• The dialog item’s dimensions and position in the dialog are given
• Its zOrder is 0
• The text label that appears in the dialog is Add
• The label is visible on this dialog tab, but not visible on all the block’s dialog tabs
Parts of a Block 17
Dialog items

Options in the dialog item’s properties window


Each dialog item’s properties window has multiple options, as discussed below. Not all options

Overview
are available for all dialog items.
☞ In addition to the options in the properties window, some dialog items can have their text or
labels stylized or aligned as discussed in “Stylizing and aligning dialog items” on page 19.

Option Description
Type A dialog item’s type (static text, frame, etc) is determined by which dia-
log item you choose from the Dialog Items toolbar and cannot be
changed through the properties window. Dialog item types are listed on
page 14.
Name A dialog item’s Name is the variable name or message name used by the
block’s code to interact with that item in the dialog, as discussed in
“Accessing dialog items from a block’s code” on page 35. As of Extend-
Sim 10 names are required for all dialog items; default names are entered
by the system for frames and static text. The name:
1) Must start with a letter
2) Cannot contain any non-alphanumeric characters
3) Can be up to 31 characters in length
X,Y,W,H By default, the fields (X, Y, W, and H) reflect the size and position of
dialog items as they are created. Their size and position can also be
adjusted after the dialog item created.
zOrder zOrder is the forward/backward position of dialog items. It's what is
effected by the Bring to Front and Send to Back buttons in the Alignment
toolbar. The zOrder numeric value gives programmers complete control
over the dialog item.
Format Parameters only. The number formats are: General, 2 decimal places,
Integer, Scientific, and Percent.
Fill Color Colors the text label. Works the same as the Fill Color tool in the Shapes
toolbar. For dialog items with multiple labels (such as the Popup Menu)
the selected color will be applied to all the labels.
☞ ModL code allows more control over dialog item appearance. For
example, use the SetDialogItemColor function to set a color, and
other functions to change the color or border depending on model
circumstances. See “Dialog items” on page 305.
Border Color Works the same as the Border Color tool in the Shapes toolbar. See
above note.
Label Dialog items have optional text labels. These can be up to 255 characters
in length. If defined, labels are displayed as part of or along with the dia-
log item in the block’s dialog. For example, the text that appears to the
right of a checkbox is a label. For tables, labels are used to name the col-
umns.
☞ If a dialog item has a label that will be displayed in the block’s dia-
log, that label can sometimes be formatted using standard charac-
ters. See “Stylizing and aligning dialog items” on page 19.
18 Overview
Dialog items

Option Description
Overview

DI ID Upon creation, each dialog item is assigned a unique ID. Some functions
use this identification number in addition to the Name, to control the
item.
Tab Number Determines which dialog tab the dialog item is on. For dialog items that
are set to be visible on all tabs, the Tab Number is -1. For other items, the
numbering starts with 0, indicating the first tab.
Tab Order Many dialog items have a tab order number. This determines the order
dialog items will be selected when modelers tab between entry boxes on
the dialog. When the tab order is changed for one dialog item, the tab
order for the other dialog items is automatically adjusted.
Be careful when changing the tab order of dialog items. If the block
is used in a model, changing a dialog item’s tab order can cause the
block’s cloned dialog items to become confused. In this case the clone
will present itself with multiple question marks; it must be deleted and
replaced.
Rows/Columns/Row Text Tables and Data Tables only. These numbers are for the body rows
Height and columns only; headers will be added automatically.
Visible By default dialog items are visible in the tab in which they are created.
(See below for making a dialog item visible in all tabs.) Unchecking this
option provides a safe alternative to deleting a dialog item when you no
longer want it in an existing block.
Deleting a dialog item from a block that is used in a model could dis-
rupt the order of the data in the dialog. The data will have to be reen-
tered for each instance of that block in all models that use it. Instead
of deleting the dialog item, hide it by unchecking the Visible option.
When the Visible option is unselected, the item will not appear in the dia-
log of the block in the model. It will, however, show in the Dialog tab as
a red rectangle without text. Hidden dialog items can be moved in the
Dialog tab. You can also revert a hidden dialog item by opening its prop-
erties and selecting the Visible option.
☞ You can also temporarily hide and show dialog items using the Hide-
DialogItem function; it is described in the dialog item function list
that starts on page 305. Also consider using the DIMoveTo and
DIMoveBy functions to move dialog items out of the way depend-
ing on dialog settings.
Visible in all tabs If a dialog has tabs, this option will cause the dialog item to appear on
every tab. This is common for static text that describes the purpose of the
block as well as the OK and Cancel buttons. For dialog items that are
visible in all tabs, their Tab Number (discussed above) is -1.
Parts of a Block 19
Dialog items

Option Description

Overview
Display only Under normal circumstances, many dialog items are editable or respond
to clicks in the dialog. Checking the Display only option means that a
modeler can’t change the dialog item, or that a click will be ignored, in
the block’s dialog. Instead, it can only be set through ModL code.
This option is typically used to display results or to temporarily or per-
manently disable a dialog item depending on settings in the block.
In a block structure’s Dialog tab, display-only
items have a gray outer border instead of the
standard black border; this is shown at right.
They also appear as dimmed in the block’s dia-
log. Display-only dialog items can still be cop-
ied and cloned
☞ Using ModL functions, the state of any dialog item can be dynami-
cally changed between editable and not editable.
Add to right click Buttons only. Cause the block’s Button dialog items to appear in a menu when
menu a block on the model worksheet is right-clicked. These commands can then be
executed without having to open the block’s dialog to click the button.

☞There are also functions that can control many dialog item properties. See “Dialog items” on
page 305.
Stylizing and aligning dialog items
In addition to the above property options, numbers, and colors, some dialog items can have the
style (and sometimes the alignment) of their text labels formatted in their Properties windows.
Dialog items that support stylizing and/or alignment
• Data tables
• Frames
• Popup menus
• Static text
• Text tables

Available formats
As indicated below, formatting is not case sensitive.

STYLE ALIGNMENT
Bold: <B> or <b> Left: <L> or <l>
Italicized: <I> or <i> Right: <R> or <r>
Underlined: <U> or <u> Centered: <C> or <c>

☞ For dialog items with multiple labels (such as popup menus or tables) set styles separately for
each label.
20 Overview
Connectors

How to format the text label


To format a label’s style or alignment, in
Overview

the dialog item’s Properties window pre-


cede its text label with the initial(s) of the
desired format within angle brackets as shown here.
Combined formats.
To combine formats, put multiple initials within one set of angle brackets. For example, a label
that is bold, italicized, and right adjusted would be preceded by <bir>. The order of the initials
for combined formatting does not matter.
☞ Text label formatting will only appear in the block’s dialog, not in the Dialog tab. To see the
format implemented, close and compile the block, then open its dialog.
Dialog item tooltips on block dialogs and in the Dialog tab
As indicated in the table above, each dialog item can have a name. This is how the items are
referenced in equation-based blocks and in block code. If a dialog item has a name, tooltips
will provide that information without you having to access the dialog item’s properties win-
dow.
The command Edit > Options > Misc tab allows you to have tooltips show in the block’s dialog
and/or on the block structure’s Dialog tab. With tooltips turned on, resting the cursor above a
dialog item displays the name of the dialog item; the window will be blank if there is no dialog
item name.
For more information about dialog items, see:
• “Accessing dialog items from a block’s code” on page 35
• “Working with dialogs” on page 93
• “Block connectors and connection information” on page 299
Connectors
Most blocks have connectors that transmit information to and from ModL code. Connectors
and animation objects are added to a block in its structure window’s Icon tab using the Icon
toolbar shown below.
The Icon toolbar
The Icon toolbar is used to add connectors and animation objects to block icons, both for hier-
archical blocks and for the custom blocks you create. In both cases this is done in the Icon tab
of the block’s structure window.

Connector types
The first six buttons in the Icon toolbar are for selecting the type of connector.
• The ExtendSim User Reference describes the use of the first five connectors: value, item,
flow, universal, and array.
• The user-defined (or “diamond”) connector does not have any “special” properties, and is
provided for your convenience for custom applications. For example, if you design a new set
of blocks and want to be sure that modelers only connect those blocks to each other, you
Parts of a Block 21
Connectors

would use this connector. If the modeler tries to connect a diamond connector to a value or
item connector, ExtendSim will not let them.

Overview
☞ By default new connectors are added to the icon as a normal (single/non-variable) connectors.
They can be changed to variable connectors (arrays of single connectors) using the connector
option tools, below.
Connector options
After the connectors, the next six buttons in the Icon toolbar are options for causing a connec-
tor to be variable rather than normal. While normal connectors represent one input or output,
variable connectors act like a row of single connectors, where the row can be expanded or con-
tracted to provide a required number of inputs or outputs.
The first five choices allow you to select, respectively, a variable connector that the modeler
can expand downward, to the right, upward, or to the left, or which cannot be manually
expanded or contracted (variable connector with no resize bar).
The sixth choice converts a variable connector into a normal connector. Use this if you selected
a variable connector by mistake.
In the block’s code, you can specify a maximum and minimum number of variable connectors
and change the number of connectors dynamically. An example of using normal and variable
connectors is the Math block (Value library). To work with variable connectors, see the writeup
on page 35 and the functions on page 303.
☞ Regardless of connector type (Value, Item, etc.), each connector can be normal or variable
depending on the option selected in the Icon toolbar. However, the entire row of a variable con-
nector must be of only one type of connector.
Animation object
The last button in the Icon toolbar is the Animation Object button. This is used to add 2D ani-
mation objects to a block’s icon environment as discussed in “2D animation” on page 10 and
“Adding 2D animation” on page 53.
Connector names
By default each connector is assigned a unique name which can be changed. The last part of a
connector name defines whether it is an input or output connector.
Connector names are shown in the Connectors pane of a block’s structure.
For example, the name of the connector for the Example block is as shown
at right. This block has one normal (non variable) value output connector
named VariableOut.
When you add connectors to the icon, they are all initially input connectors.
To make one of these connectors an output connector, change its name to
something that ends with “Out.
Rules for connector names
• Connector names are not case sensitive
• The name must start with a letter
• The name cannot contain any non-alphanumeric characters or spaces
• The name must be fewer than 32 characters in length
• Input connectors must end in some form of the word “In” (IN, in, In, iN)
22 Overview
Connectors

• Output connectors must end in some form of the word “Out” (OUT, out, Out, ouT, etc)
Overview

Editing connector names


To change the name of a connector:
Double-click the connector name in the connector pane. ExtendSim highlights that connec-
tor in the icon pane so you can identify it.
Type a new name or edit the name.
Press the enter or return key or click anywhere else in the connector pane to save the edited
name.
☞ You can name a connector anything you want as long as it follows the rules above.
Adding connectors to the icon
To add a connector to an icon:
In the Icon toolbar (shown on page 20), click on one of the connector type buttons (Value,
Item, Flow, Universal, Array, or User Defined)
Then click in the block structure’s Icon tab at the desired position
This will place a connector in the icon pane. By default, the connector is a “normal” connector.
To change the default normal connector to a variable connector:
Select the connector in the Icon pane
Select one of the variable connector options (down, right, up, left, or
no resize) in the Icon toolbar
Changing connector types
If you selected the wrong type of connector (such as a value connector
when you wanted an item connector), you can easily change its type:
Click on the connector in the block structure’s Icon tab
Click on the correct connector type in the toolbar
When you build blocks it is important that you use the above method to change connector
types, rather than deleting a connector. If you delete a connector for a block that is used in any
model, the order of the connections will be disrupted and existing connections to the block
might become incorrect.
Connector labels
A connector label is associated with a particular connector and makes a block’s inputs and out-
puts more understandable. Connector labels can be positioned, colored, and formatted, and are
especially helpful to distinguish one input or output from the others when using variable con-
nectors. Most ExtendSim blocks have one or more connector labels.
Connector label functions start on page 305. Connector labels are defined using the Connector-
LabelsSet function. The function’s arguments allow setting the position and color of the label.
To format a connector label, precede the label text with angle brackets (“< “and “>”) that
enclose the desired format, using the same techniques shown in “Stylizing and aligning dialog
items” on page 19. For instance, a bold, right-adjusted label named “want” would be entered as
“<rb>want” in the Script tab.
Parts of a Block 23
Connectors

Connector tooltips
Tooltips can display custom text when the mouse hovers over a connector. This is helpful to

Overview
show additional information about the connector (including its value during the simulation)
and what it can be used for. See “Connector tool tips” on page 305 and the Equation block
(Value library).
For more information about connectors see:
• “Accessing connectors from a block’s code” on page 34
• “Working with connectors” on page 100
• “Block connectors and connection information” on page 299
24 Overview
Connectors
Overview
Overview

ModL Overview
Creating ModL code and dialogs for custom blocks

“I must create a system,


or be enslaved by another man’s.”
— William Blake
26 Overview
ModL feature overview

This chapter and the others that follow will teach you how to create new blocks, modify exist-
ing blocks, or call functions from equation-type blocks such as the Equation and Optimizer
Overview

blocks (Value library) and the Equation(I) and Queue Equation blocks (Item library).
☞ These chapters only describe creating standard blocks, not hierarchical blocks. Hierarchical
blocks contain ExtendSim blocks and are created through the user interface, without program-
ming, as described in the User Reference.
As you saw in the preceding chapter, there are many parts of a block, the most complex of
which is the ModL code. This chapter shows how a block’s code is laid out and the basic ways
that ModL code lets blocks interact with other blocks, with their own dialogs, and with the
general parameters of a simulation.
☞ This overview of the ModL language is a prelude to, and should be read before, the “The ModL
Language” reference chapter that starts on page 59.
ModL feature overview
As you will see, ModL is very much like C, although it is not as complicated and not case sen-
sitive. ModL also has some enhancements that will help you create block code:
• Block code is organized as message handlers and function definitions, rather than just func-
tion definitions. Message handlers and functions can be overridden (e.g. if they are from
include files) and can have local variables.
• The names of connectors and dialog items are treated as static variables that can be read or
set from within message handlers or functions. The dialog and connector changes take effect
immediately.
• Blocks can query, control, and send messages to other blocks, even if they are not connected.
• Blocks can have icon views facilitating the direction of model flow.
• The ModL language has several string data types. Strings can be up to 255 characters and
can be concatenated (strung together) with the + (plus) operator.
• ModL has subscript checking, causing the code to abort if you try to access an element
beyond the size of an array.
• There are over 1,200 ModL functions for performing general and simulation-specific tasks.
In addition, there are many global variables that can be accessed from ModL code as well as
some predefined constants.
• Including 2D animation in a block is easy. You do not need to do any graphics in your block
code. Instead, you can position animation objects on the icon and use animation functions to
show pictures or text within the objects.
• You can use multi-dimensional arrays (with up to five sets of dimensions). Arrays can be
passed to blocks or functions as entire arrays or as individual elements. ModL arrays can be
fixed (specified size) or dynamic (one dimension undeclared). You can use dynamic arrays to
hold values when you do not know how many elements will be needed.
• You can create ExtendSim databases, linked lists, and global arrays that are useful as in-
memory data repositories. You can also use ExtendSim blocks or code to access external
spreadsheets and ADO and ODBC compatible databases.
• ModL allows for efficient connectivity with other languages, so you can make use of other
features and technologies.
ModL Overview 27
ModL compared to other programming languages

• ExtendSim has an internal source code editor (with code completion, syntax colorization,
and more) as well as a source code debugger.

Overview
• An external source code feature allows multiple people to efficiently and effectively work on
the code of blocks at the same time.
ModL compared to other programming languages
An ExtendSim block’s code is written in ModL, a programming language that is much like C
or C++ that has been enhanced for simulation purposes.
☞ DLLs and Shared Libraries provide a method for incorporating other technologies, such as
Visual Basic, Java, or Visual C++, into ExtendSim. For more information, see “DLLs” on
page 86.
If you code, and if you don’t
• If you have some familiarity with C or C++: Although ModL is specialized for simulation, it
uses many concepts from C++ and you can certainly program in ModL. Note that you do not
need to know much C/C++ in order to be completely comfortable in ModL. The table that
starts on page 27 lists major differences between ModL and C++.

• If you program in a language other than C/C++: ModL should not present much of a chal-
lenge. You can use your programming knowledge to program using ModL or write DLLs in
other languages and call them from within ExtendSim code. The table that starts on page 29
compares common constructs for ModL and for some other common languages.

• If you do not program: You can still use the equation-based blocks, make some modifica-
tions to existing blocks, and build simple blocks without programming experience.

☞ Whether you know programming or not, the equation-based blocks provide access to ModL
functions and variables. This is useful for accomplishing specialized tasks without having to
program a block. The equation-based blocks are listed in the User Reference.
ModL compared to C++
There are only a few differences between ModL and C++. They are:

ModL C++
case insensitive case sensitive
real or double (Mac OS and Windows: 16 significant digits) double
integer or long (32 bit) long
string or Str255 (255 characters maximum) typedef struct Str255
{
unsigned char length;
unsigned char str[255];
} Str255;
28 Overview
ModL compared to other programming languages

ModL C++
Overview

Str15 (15 characters maximum) typedef struct StrN


Str31 (31 characters maximum) {
Str63 (63 characters maximum) unsigned char length;
Str127 (127 characters maximum) unsigned char str[N];
} StrN;
Array bounds subscript checking produces error messages No array bounds checking
when array bounds are exceeded
Functions declared using ANSI declaration only (prototype Functions can be declared either
declarations). K&R or ANSI
Functions and message handlers can be overridden. Not available in C, but available
in C++.
“i++;” is a statement. It cannot be used as an expression. See “i++” is a statement which can
below. be used as an expression
Statements cannot be used as expressions. For example “a[++i] Expressions can be statements
= 5;” or “a[i=i+1] = 5;” are not allowed. Instead they must be of
the format “i++;”, or “i=i+1;” and “a[i] = 5;”, or “a[i+1] = 5;”
The ModL “for” statement is: The C “for” statement is:
for (statement; boolean; statement) for (expression; expression;
expression)
^ is used as the exponentiation operator (like it is in BASIC and ^ is used as the exclusive-OR
spreadsheets) operator in logical expressions
To concatenate a string use: The C equivalent is:
stringVar = stringVar+“abc”; strcat(stringVar, "abc")
To convert a number to a string: The C equivalent is:
stringVar = x; ftoa(x, str);
if (stringVar < "abc") if (strcmp(stringVar, “abc”) < 0)
{ {
... ...
} }
Resizable dynamic arrays (pointertypes can hold the address of Pointers
a dynamic array)
Linked lists support complex data structures Structures
!= or <> are not-equal operators != is the not-equal operator
% or MOD are the modulo operators % is the modulo operator
Bit handling done by functions (such as BitAnd(n, m)) Bit handling done by operators
(such as n&m)
ModL Overview 29
ModL compared to other programming languages

ModL C++

Overview
#define, #include, #ifdef, #ifndef, #else, #endif can be used as Macro definition is allowed in
preprocessor directives to conditionally compile code if a sym- addition to preprocessor direc-
bol of any type is defined (e.g. constant, variable, connector, tives.
function, etc.). There is no macro definition.

ModL compared to languages other than C++


The following table compares some of the common constructs in ModL to other languages.
☞ DLLs (Windows) and Shared Libraries (Macintosh) provide a method for linking languages
other than ModL to ExtendSim. For more information, see “Accessing code from other lan-
guages” on page 42 and “DLLs” on page 86.

ModL Java Visual Basic FORTRAN


real a[10], x; double[] a = new double[10]; dim a(9) as single real a(9), x
double x;
integer i; int i; dim i as integer integer i

for (i = 0; i < 10; for (i = 0; i < 10; i++){ do i = 0,9


i++) if (i == 5) { for i = 0 to 9 if (i .EQ. 5)
{ x = 3; if i = 5 then then
if (i == 5) }else{ x=3 x=3
x = 3; x = 5+i; else else
else } x = 5+i x = 5+i
x = 5+i; a[i] = x; a(i) = x end if
a[i] = x; } end if a(i) = x
} next i end do
integer b[10][5]; int[][] b = new int[10][5] dim b(9,4) as inte- integer b(9,4)
ger
switch (i) switch (i) { select case i select case i
{ case 0: case 0 case (0)
case 0: x = 3; x=3 x=3
x = 3; break; case 1 case (1,2)
break; case 1: case 2 x = 5+i
case 1: case 2: x = 5+i case default
case 2: x = 5+i; case else x=0
x = 5+i; break; x=0 end select
break; default: end select
default: x = 0;
x = 0; break;
break; }
}
while (i < 10) while (i < 10) { while i < 10 do while (i .LT. 10)
{ x = x+i; x = x+i; x = x+i;
x = x+i; i = i+1; i = i+1; i = i+1;
i = i+1; } wend end do
}
30 Overview
ModL language terminology

ModL Java Visual Basic FORTRAN


Overview

do do { do 10 x = x+i;
{ x = x+i; x = x+i i = i+1;
x = x+i; i = i+1; i = i+1 if (i .LT. 10) goto
i = i+1; }while (i < 10); loop while i < 10 10
}
while (i < 10);
//comments //comments rem comments ! comments
** comments ' comments
/* enclose multi-line /* enclose multi-line comments (NOTE: only to end (NOTE: only to
comments like this like this */ of current line) end of current line)
*/
strng = strng+"abc"; strng = strng+"abc"; strng = strng&"abc" strng = strng // 'abc'
strng = x; strng = double.toString(x); strng = Str(x) depends on imple-
mentation
if (strng < "abc") if (strng.compareTo("abc") < 0) if strng <"abc" if (strng .LT. 'abc')
... { then then
... ... ...

ModL language terminology


The following table describes the terms used in ModL coding.

Term Description
array An indexed list of numbers or strings, with indices starting at 0 (zero).
Arrays can be fixed or dynamic. Dynamic arrays are static and cannot be locally
declared. Fixed arrays can be declared as static or local.
constant Value that does not change.
data type The type of storage used for the data: real, integer, string, pointertype
E notation or Exponential number specified as a number raised to a power of 10. For example,
scientific nota- “6.3E3” means 6,300 and “5E-1” means 0.5.
tion
function Predefined named group of code instructions with specified arguments that may
return a value (void functions don’t return a value) and can be called in a block’s
code. Can be overridden by defining the function in an include file which can
then be overridden in the block’s code.
global variables Variables that are used to pass information between blocks. They are predefined
by ExtendSim and can be viewed or modified by any block or equation. These
variables’ values are preserved between simulation runs and are saved with the
model. See “Scope of global, local, and static variables” on page 62 for more
information regarding the scope of those variables.
identifier Name that is entered.
ModL Overview 31
Differences between equation blocks and programmed blocks

Term Description

Overview
literal Number or string that is entered as a constant.
local variable Variable that is locally declared and is valid only within the message handler or
user-defined function in which it is defined. Note that these are temporary vari-
ables and their values are not preserved after exiting a message handler or func-
tion. See “Scope of global, local, and static variables” on page 62 for more
information.
Do not give local and static variables the same name; local variables with
the same names as static variables override the static variables.
message han- Grouping of code that tells ExtendSim what to do in a particular circumstance
dler that is defined by the message. Can be overridden.
statement Section of code ending with “;”.
static variables Variable that is valid throughout the block’s code in which it is defined. The val-
ues for these variables are preserved and are stored with the model when it is
saved. See “Scope of global, local, and static variables” on page 62 for more
information.
Use caution when deleting static variables for blocks already used in mod-
els. It has the same harmful effect as deleting dialog items (discussed in the
section on “Hiding/showing dialog items” on page 95).
system variable Provide information about the state of the simulation. Like global variables, sys-
tem variables are valid in any block in a model, are declared by ExtendSim, and
can be viewed or modified by any block or equation.
type declara- Defining a variable as a certain data type: real, integer, string, or pointertype.
tion

Differences between equation blocks and programmed blocks


The equation-based blocks in the Value and Item libraries provide access to over 1,200 ModL
functions; you can also use operators to enter logical statements, write compound conditions,
and specify loops. The equation is automatically compiled when you click OK in the block’s
dialog.
Using an equation-based block you can accomplish much of what can be done with a custom-
built block. However, there are some differences and limitations.

Feature Equation-Based Blocks Custom Blocks


Custom dialog No Yes
Pre-defined input and output variables Yes No
Data type declarations (real, integer, string, pointertype) Yes Yes
Constant definitions (e.g. “Constant N is 5”) Not directly; use an include Yes
Pre-defined constants (Pi, Blank, True, False) Yes Yes
Dynamic arrays No Yes
Static fixed arrays Not directly; use an include Yes
32 Overview
Structure of a block’s ModL code

Feature Equation-Based Blocks Custom Blocks


Overview

Locally declared fixed arrays Yes Yes


Static variables Not directly; use an include or Yes
declare as an input variable
Global variables Yes Yes
Locally declared variables Yes Yes
ModL functions Yes Yes
User-defined functions Not directly; use an include Yes
Message handlers Not directly; instead call Yes
SendMsgToBlock()
Syntax coloring Yes Yes
Code completion Yes Yes
Conditional compilation Yes Yes
Debugger Yes Yes
Call include files Yes (see note) Yes (see note)

☞ Include files used with equations are normally saved in the same location as the model using
them; this makes it easy to move both the model and the includes it uses to a different location.
Include files used in block code should be saved in the Extensions/Includes folder.
Structure of a block’s ModL code
ModL is essentially C++ with enhancements and extensions to make it more robust for simula-
tion modeling.
Layout of the code
Like C programs, a block’s code starts with data type declarations and constant definitions
(see page 33). Because you declare these at the beginning of the code, before any message han-
dlers or user-defined functions, they are considered static or permanent variables. Unless over-
ridden by a local variable declaration, static variables are valid throughout the block’s code.
However, their scope does not extend outside of that block’s code. Global variables are pre-
defined and have a global scope, making them valid in every block.
☞ For more information about the scope of variables, see “Scope of global, local, and static vari-
ables” on page 62 for more information.
After the type declarations, there are function (and void function) definitions and many mes-
sage handlers (see page 33). This is where you write code and define the behavior of the block.
The functions and message handlers are just definitions; they need to be called in order to be
executed. They can also be overridden by re-declaring any number of times below the first
declaration.
• Message handlers begin with a line “on messageName” and tell ExtendSim what to do in
various circumstances; they are usually executed by the application. For example, a message
handler in every block begins with “on Simulate” and the code within the message handler
starts and ends with curly braces (“{“ and “}”).
ModL Overview 33
Structure of a block’s ModL code

• Functions are of the form “type functionName(type argument, ...)” or “void function-
Name(type argument, ...)” depending on whether they return a value. Functions are called

Overview
within message handlers or from other parts of the block’s code.
When you type the first letters of ModL functions in the Script tab, code completion pops up a
window so you can get the correct spelling and arguments. As code is written, syntax coloring
gives visual cues about its structure.
Like C, ModL ignores blank lines and indentation. Of course, it is a good idea to indent code
with Tab characters and use comments. Single line comments are preceded by “//” or “**”.
Multi-line comments start with a “/*” and end with a “*/”.
Data types
There are four main data types in ModL:

Data Type Page


Real or double 60
Integer or long 60
String (Str15, Str31, Str63, Str127, Str255 or String) 61
Pointertype 61

Constants
Constant declarations can be of data type real, integer, or string, but not pointertype. The gen-
eral form for a constant definition is:
CONSTANT id IS literal;
ModL includes four general-purpose predefined constants: Pi, Blank, True, and False. For
more information, see page 62.
Constants are not directly supported in equation-based blocks; use an include or set the value
from a Constant block (Value library).
Functions, message handlers, and local variables
ModL code has functions and message handlers that group the code into sections.
• Functions are procedures that do calculations and can be called from different points in the
code. Functions can return a value; void functions do not return a value.
• Message handlers interpret messages that come from the simulation, from another block, or
from user interaction with a block’s dialog. Message handlers begin with a line “on mes-
sageName”, where messageName is the name of the message. ExtendSim runs the message
handler whenever one of the messages is passed to the block.
• Local variables are variables that are declared in message handlers and user-defined func-
tions. Their scope is just the message handler or function in which they are declared.
Message handlers cannot be declared in equation-based blocks; instead call SendMsgToB-
lock(). See the table onpage 31 for additional differences when using equation blocks.
Message handler structure
Message handlers are denoted by:
34 Overview
Accessing connectors from a block’s code

on messagename
{
Overview

zero or more declarations and/or statements;


}
MessageName must be the name of one of the messages listed in the chapter “Messages and
Message Handlers”. The code of the message handler is contained between the curly braces
(“{” and “}”) and tells ExtendSim what to do in the specific circumstance. To exit from a mes-
sage handler before the ending brace, use a Return statement or an Abort statement.
For example, in a continuous model, the code in the “on Simulate” message handler is exe-
cuted for every step in the simulation. However, the code in the “on InitSim” message handler
is only executed once, at the beginning of the simulation.
You can declare local variables at the beginning of a message handler. However, you should not
have a global and a local variable with the same name. The local variable is temporary and
loses its value when the message handler is exited. Also, within each message handler, local
variables can override static variables. (If a local variable is defined with the same name as a
static variable, any references to that name within that routine or message handler will change
or reference the local variable, and the static variable will not be modified.)
Overriding user-defined functions and message handlers
Message handlers and user-defined functions can be overridden by being re-declared any num-
ber of times below the first declaration. This is useful in that include files can have basic forms
of functions and message handlers which can then be re-declared and overridden in the main
block code. See “Include files” on page 81.
☞ Message handlers are discussed more in “Message handlers” on page 75 and “Using message
handlers” on page 109. For a list of messages, see the chapter “Messages and Message Han-
dlers” that starts on page 213.
Other ModL features
• Syntax coloring gives visual cues about the structure and state of a block’s code, making it
easier to follow the logic. See “Syntax styling” on page 78.
• Code completion speeds up the coding process by reducing typos and other common mis-
takes. See “Code completion and call tips” on page 79.
• Conditional compilation allows segments of code to be compiled only if certain conditions
are met. For more information, see “Conditional compilation” on page 82.
Accessing connectors from a block’s code
As discussed in “Editing connector names” on page 22, when you create a block each connec-
tor’s name must end in either “In” or “Out”. Connector names are used as variables in ModL
code.
☞ All connector names are real type variables. If you set a connector name to an integer, Extend-
Sim automatically converts the integer to a real.
☞ Typically, connectors pass values one at a time. As discussed in “Passing arrays” on page 102,
connectors can also pass arrays of multiple values. Passing arrays is an easy way to pass more
than one piece of information at a time through blocks.
There are several types of connectors as listed on page 20. No matter what their type, connec-
tors can be single (“normal”) or multiple (“variable”).
ModL Overview 35
Accessing dialog items from a block’s code

Normal (single) connectors


By default a new connector is added as a normal (single or non-variable) input connector. That

Overview
connector can be changed to a normal output connector by adding “Out” to the end of its name.
• To read from an input connector, use its name in the right side of a statement. For instance,
read from an input connector called “firstConIn” with:
myNumber = firstConIn;
• To set the value of an output connector, assign it a value. For example, to set the value of an
output connector called “totalOut”, use:
if (myNumber > 0)
totalOut = 1.0;

Variable connectors
Each variable connector is actually a row of single connectors where the row expands and con-
tracts. This allows the developer and modeler to control how many connectors are displayed
for a particular purpose. They are described in the User Reference.
☞ See “Adding connectors to the icon” on page 22 for the steps required to change the default
(normal) connector into a variable connector.
Accessing a variable connector from code
• Use the function ConArrayGetValue to read from a variable input connector. Note that input
connector indexes start at 0.
• To set the value of an variable output connector, use the function ConArraySetValue. Note
that output connector indexes start at 0.

Setting the number of connectors


The number of variable connectors can be managed directly within the code with the functions
ConArraySetNumCons and ConArrayGetNumCons.
If the number of variable connectors changes, the application sends two messages to the con-
cerned block. The first message is ConArrayChanged followed with the ConArrayChanged-
Complete message.
For an example of how to access variable connectors from a block’s code and change the num-
ber of connectors based on what is needed, see the code of the Math block (Value library).
☞ The entire row in a variable connector must be of only one type (Value, Item, etc.) and must be
either an input or an output. Also, connector indexes start at 0 (zero).
Accessing dialog items from a block’s code
The section “Dialog items” on page 14 introduced dialog items, including their definitions,
options, and use.
Overview
The default dialog item names (OK and Cancel), as well as the names for any dialog items
added to a block, are listed in the Dialog Item Names pane of the block’s structure window.
Use the Edit > Copy and Edit > Paste commands to copy dialog item names from that pane to
use in ModL code.
36 Overview
Accessing dialog items from a block’s code

As of ExtendSim 10 names are required for all dialog items. The system supplies a default
name for static text and frames; it can be changed following the rules given in “Options in the
Overview

dialog item’s properties window” on page 17.


Using the names of the dialog items, you can read and set them as variables in the same way as
you do connectors. Dialog item names can also be used as message names for use with mes-
sage handlers.
☞ Any dialog name can be used in the ModL code as both a variable name and a message name.
Dialog messages
Message handlers were introduced on page 33. They interpret messages that come from the
simulation, from another block, or from modeler interaction with the dialog.
Dialog messages come from modeler interaction with a block’s dialog items. When a button in
a dialog is clicked or a parameter is unselected (for example, after it has been changed),
ExtendSim sends a message with the same name as the dialog item (e.g. on DialogItemName)
to the ModL code.
For example, assume a block has a Count button. When that button is clicked in the block’s
dialog, ExtendSim sends the “Count” message to the block. If the block has an “on Count”
message handler, it will be executed; if not, nothing happens.
Names assigned to a block’s dialog items are listed in the block structure’s Dialog Item Names
pane.
Parameters and editable text
Assume that a parameter dialog item has the name “numberOfRecords”. In the block’s code
you could have a statement such as:
myNumber = numberOfRecords/100;
Dialog items can also be set from inside the ModL code. For instance, to set the value shown in
the “numberOfRecords” field to “1000”, use the statement:
numberOfRecords = 1000;
The same methods work for editable text:
if (temp > 1500)
displayHeat = "Hot";
else displayHeat = "Cool";
Parameters and editable text dialog items have a limit of 255 characters; editable text 31 has a
limit of 31 characters and is used to save memory. In the dialog item’s properties window you
can choose the Display only option for a parameter or editable text dialog item. With this
option selected, the item cannot be changed directly in the dialog; it can only be changed in the
block’s code, using the same techniques just shown.
Dynamic text
Dynamic text items allow up to 32,000 characters, whereas editable text dialog items are lim-
ited to 255 characters each. Dynamic text is useful when you need more text area than an edit-
able text item can have. However, it is a little more complex to work with because ModL code
needs to be written to set it up before it is usable and accessible. This is commonly done in the
CreateBlock message handler (which occurs when the block is added to the model), but it can
be done at other times to suit the functionality of the block.
ModL Overview 37
Accessing dialog items from a block’s code

Dynamic text items can be accessed directly via the string dynamic array assigned to the
dynamic text item or using the dynamic text functions (see “Dynamic text items” on page 320).

Overview
For an example of using dynamic text items, see the Equation block (Value library).
To declare the string dynamic array:
string aStringDynamicArray[]; // the dynamic array declaration
....
To set up the dynamic text item in the CreateBlock message handler:
myDynamicTextItem = DynamicTextArrayNumber(aStringDynamicArray);
To directly access the text:
first255Characters = aStringDynamicArray[0];
The example above shows a dynamic text dialog item attached to a string array. Dynamic text
dialog items can be attached to arrays of any size string.
Use the dynamic text functions to find and replace text. See “Dynamic text items” on
page 320.
Checkboxes and radio buttons
Checkbox and radio button dialog items return true/false values: true if the checkbox or radio
button is selected, false if not. They also send their dialog item name (as a message name) to
the block’s code when they are clicked. The code could have an “On DialogItemName” mes-
sage handler to process the message. The dialog item name could also be used as a variable to
query or set the dialog item’s value.
For example, if a block represents a teller in a
bank, instead of entering a number you could
use radio buttons to set the teller’s speed. The
dialog might look like the one shown at the
right.
The five radio buttons would have the dialog
names VSlow, Slow, Med, Fast, and VFast. To
make sure that only one of them can be
selected at a time, they must all have the same
Radio Group ID when they are defined. In this
example, the group ID was left at the default
(group 0).
To set the variable “theDelay” based on which
button was chosen, the code uses the state-
ments:
if (VSlow)theDelay = initDelay * 1.25; // v slow is 1.25 normal
if (Slow) theDelay = initDelay * 1.1;// slow is 1.1 of normal
if (Med) theDelay = initDelay * 1.0;// medium is 1 of normal
if (Fast) theDelay = initDelay * 0.91;// fast is 0.91 of normal
if (VFast)theDelay = initDelay * 0.8;// v fast is 0.8 of normal
The “if” statements are executed only if that button value is True (non-zero); of course, only
one of them can be true because they are all in the same radio button group. You could also
structure the checking with five message handlers, such as:
38 Overview
Accessing dialog items from a block’s code

on VSlow // VSlow radio button was clicked


{
Overview

theDelay = initDelay * 1.25;


}
Note that in the first instance, the “if” statements would be executed during the simulation,
usually in the InitSim message handler. In the second instance, the VSlow button message han-
dler would be executed when you clicked the button labeled “Very slow.”
To specify that the “Medium” button should be pre-selected when the block is placed in a
model, the CreateBlock message handler contains:
Med = TRUE;
This also sets the other radio buttons in the group to FALSE.
☞ When setting the state of a radio button group in ModL code, always explicitly state which but-
ton is set to True so that the remaining radio buttons in the group will be set to False. Just set-
ting a radio button to False will not affect the state of the other radio buttons in the group. Thus
it is possible to have a condition in which all radio buttons in the group are initially set to False.
In most cases, this would be an error condition.
Use the DITitleSet function to change the title of a check box or radio button.
Buttons
When buttons are clicked, they send a message to the block’s ModL code. The most common
buttons in a block are OK and Cancel, which are handled automatically. If you add other but-
tons, such as shown later in this chapter, message handlers must be added for those buttons.
To change the text label of a button, assign the button’s dialog item name as a variable to a
string value in the code.
☞ The changed button text is not stored in the block. Thus the read value of the button’s text is
always what was originally entered when the dialog item was defined, even if the text is
changed by setting it to a different value in ModL code. If you use the dialog item name in an
equation, you will always get the text that was entered when the dialog item was created.
If you change the text label of a button, your code must set the text when the modeler opens the
block. Do this using the On DialogOpen message handler.
on DialogOpen
{
myButton = "desired button text"; // set it when the dialog opens
}
See also “Changing text in response to a user’s action” on page 94.
Data tables and text tables
A data table or text table dialog item represents a two-dimensional array of either real numbers
or text. Tables have an interface that allows modelers to type in any input and also, like all dia-
log items, allows you to display values generated in the code. If your block code provides for
it, modelers can change the number of rows and columns and can dynamically link tables to an
ExtendSim database or global array.
You define the number of rows, number of columns, number format, and headings for the col-
umns, but all of these are changeable with ModL code, including the ability to create and
manipulate extremely large tables with up to 255 characters per cell.
ModL Overview 39
Accessing dialog items from a block’s code

The following code fragment shows how to read and write to a data table named “dataTable”
that has 4 rows and 3 columns. Data tables are treated as arrays, which are discussed in detail

Overview
in “Arrays, pointers, queues, delay, linked list, and string lookup table functions” on page 376.
As in the C language, array subscripts start at 0, not 1.
. . .
// Read the first row, second column cell into myValue.
myValue = dataTable[0][1];
. . .
// Set the fourth row, third column cell to myValue
dataTable[3][2] = myValue;
Data tables can be attached to dynamic arrays. They can also have variable columns and the
behavior of the columns can be extensively customized. For more information, see the descrip-
tion and functions in “Block data tables” on page 312 and “Formatting/interactivity using col-
umn and parameter tags” on page 321.
The text table allows you to type in text, numbers, or both. Since all entries are strings, to use
the numbers in ModL code you must first convert them to real values using the StrToReal
function.
The headers for data tables and text tables can be styled and aligned, as discussed in “Stylizing
and aligning dialog items” on page 19.
Static text (label)
Static text appears in a dialog as a label and is non-editable by the modeler. The system assigns
default names to static text; the names can be changed by the block developer according to the
rules given in “Options in the dialog item’s properties window” on page 17. Names can be
used in the ModL code to change the text label, show and hide it, and so forth.
☞ The changed text label is not stored in the block. Thus the read value of static text is always
what was originally entered when the dialog item was defined, even if it is changed by setting
it to a different text value in the code. If you use the dialog item name in an equation, you will
always get the text that was entered when the dialog item was created.
If you change the text of a label, your code must set the text when the modeler opens the block.
Do this using the On DialogOpen message handler.
on DialogOpen
{
myLabel = "desired text"; // set it every time the dialog opens
}
See also “Changing text in response to a user’s action” on page 94.
Popup menu items
When an item in a popup menu is selected, the menu’s dialog item name returns a value which
is the integer corresponding to the position of the item in the menu, where 1 is the value for the
first item in the list. For example, in a 5-item menu, the values of its dialog item name will be
set to 1, 2, 3, 4, or 5 based on which menu item the modeler chooses.
☞ For historical reasons, popup menu indexes start at 1, not 0.
40 Overview
Accessing dialog items from a block’s code

Popup menus replace series of radio buttons. For


instance, instead of using several radio buttons
Overview

to represent teller speed, as shown in “Check-


boxes and radio buttons” on page 37, you could
use a popup menu. The dialog would look like
the screenshot at right.
This popup menu has the dialog item name
“MyMenu”. The five menu items have the titles
as shown above. Since “Very slow” is selected,
MyMenu is set to 1. If “Medium” were selected,
MyMenu would be set to 3.
To set the variable “theDelay” based on which menu item is selected, the code in the InitSim
message handler has these statements:
if(MyMenu == 1)theDelay = initDelay * 1.25;// v slow is 125% normal
if(MyMenu == 2)theDelay = initDelay * 1.1; // slow is 110% of normal
if(MyMenu == 3)theDelay = initDelay * 1; // medium is normal
if(MyMenu == 4)theDelay = initDelay * 0.91;// fast is 91% of normal
if(MyMenu == 5)theDelay = initDelay * 0.8;// v fast is 80% of normal
To specify that, when a block is placed in the model, the “Medium” menu item should be pre-
selected, the CreateBlock message handler contains:
MyMenu = 3; // defaults to the “Medium” menu item, third in the list
You can use the popup menu’s dialog name (for example, MyMenu) as the message handler
name (for example, On MyMenu) to perform specific actions when the modeler selects a menu
item. For instance, you could use this to report errors to the modeler, show or hide other dialog
items, or cause a sound to play.
The text in popup menus can be styled and aligned, as discussed in “Stylizing and aligning dia-
log items” on page 19.
☞ Using the column tag functions listed in “Formatting/interactivity using column and parameter
tags” on page 321, data tables can have popup menus in their columns.There are also functions
to dynamically popup a menu on the fly, whenever the modeler clicks something.
Frame
A frame allows you to visually isolate or
group dialog items by framing them with a
rectangular box. Once a frame has been
added to the Dialog tab, it can be resized and
positioned to surround the items of interest. If
present, the frame’s label is displayed in its
upper left corner, as shown at the right.
Frames are required to have names and the system assigns a default. The default name can be
changed following the rules discussed in “Options in the dialog item’s properties window” on
page 17. Names can be called as a variable in the block’s code. This is helpful for showing and
hiding the frame under different circumstances, dynamically repositioning it, or dynamically
changing its label.
The frame’s label can be styled and aligned, as discussed in “Stylizing and aligning dialog
items” on page 19.
ModL Overview 41
Accessing dialog items from a block’s code

Switch
A switch looks like a standard light switch.

Overview
When you click on the side that is not down, it makes a small clicking sound,
changes to the other value, and sends a message to the ModL code.
The switch dialog name always returns either 0 (off) or 1 (on), depending on the value of the
switch. You can also control the switch by setting its variable name to 0 or 1 in the code.
Slider
A slider allows you to enter a value by dragging its knob along its length.
The minimum and maximum values can be set from ModL code; the modeler can
change the minimum and maximum values by clicking and editing them in the
block’s dialog. The current value can be set from the code and can also be set as the
model runs by dragging the slider up or down. In this way, you can use the slider
both for visual output and for input.
The slider is represented in a three-element array of reals that represent the minimum, maxi-
mum, and current values. Thus, if a slider is called “theSlider,” it could be initialized with the
lines:
theSlider[0]=0.0; // Minimum of 0
theSlider[1]=10.0; // Maximum of 10
theSlider[2]=3.33; // Starting value of 3.33
As the model runs, the value of the slider can be checked by reading the third array element:
theSetting = theSlider[2];

Meter
A meter allows you to view a value on a meter.
You set the minimum, maximum, and current values from the ModL code.
The meter is represented in a three-element array of reals that represent the mini-
mum, maximum, and current values. Thus, if your meter is called “theMeter,” you
might initialize it with the lines:
theMeter[0] = 0.0; // Minimum of 0
theMeter[1] = 30.0; // Maximum of 30
theMeter[2] = 10.0; // Starting value of 10
As the model runs, you can set the value shown on the meter in the third array element, such
as:
theMeter[2] = theSetting;

Embedded object (Windows only)


An embedded object is an OLE object that can be chosen via the block code from
available types, such as an Excel spreadsheet or chart. The object can then be
manipulated by the code of the block. When first placed in a dialog editor window,
an embedded object looks like the image at right.
The functions are listed in “Interprocess Communication (IPC)” on page 250 and “OLE/COM
(Windows only)” on page 253. Also see the User Reference for information about using
embedded objects in models.
42 Overview
Accessing code from other languages

Calendar
The Calendar dialog item takes an ExtendSim date value (discussed
Overview

in “Calendar Date functions” on page 397) and visually displays it in


a combination calendar/clock format. For example, assume a calen-
dar dialog item named MyCalendar has been added to a block’s dia-
log. That dialog item will display December 1, 2007 12:01 am when
the following line of code is executed:
MyCalendar = 39417.000694444;
The dialog item would then look like the screenshot to the right.
Clock
The Clock dialog item takes an ExtendSim date value (discussed in “Calendar Date functions”
on page 397) and visually displays the time component of that date value (hours, minutes and
seconds) in a digital clock format. For example, assume a clock dialog item named MyClock
has been added to a block’s dialog. That dialog item will display 12:01:00 when the following
line of code is executed:
MyClock = 39417.000694444;
If you need to display the complete date value, and not just the time component, consider the
Calendar dialog item, discussed above.
Accessing code from other languages
You can use other languages, such as Visual C++, Java, C++, and others, to provide additional
functionality to ModL or to make use of a legacy of pre-built code. For instance, you may
already have thousands of lines of C++ code which perform a specific calculation. You can add
this functionality to your block by recompiling the C++ code as a DLL (dynamic link library
for Windows) or Shared Library (external command for Mac OS). DLLs and Shared Libraries
are the standard interface technologies for communicating between programming environ-
ments. When you want to do the calculation, use the ExtendSim built-in function calls to call
the DLL or Shared Library.
One advantage of this method is that you don’t have to program the interface in the external
language. Instead, you can leverage the ExtendSim built-in interface and dialog creating capa-
bilities.
☞ Even though you are using an external language, the resulting block will fit seamlessly into the
ExtendSim environment and be indistinguishable from other blocks.
To learn more see “DLLs” on page 86 and “Shared libraries” on page 88.
External source code
ExtendSim supports a mechanism for saving the source code of individual blocks or libraries
of blocks as external files. This external source code feature is useful for situations where mul-
tiple developers work on the code of blocks and/or libraries at the same time. For more infor-
mation, see “External source code control” on page 83.
Tutorial

Creating a Block
Learn how to build an ExtendSim block
and save it in a library

“Knowledge is of two kinds. We know a subject ourselves,


or we know where we can find information upon it.”
— Samuel Johnson
44 Tutorial
Building a simple block that converts miles to feet

This chapter shows how to create a continuous block and have it perform some tasks. So you
have something to compare to, the final block, called “Miles”, is located in the Custom Blocks
library which is located in the folder ExtendSim/Documents/Libraries/Example Libraries.
Building a simple block that converts miles to feet
For this first section, the Miles block will have two value connectors, an input and an output.
The block will look at the value of the input connector (the number of miles), multiply it by
5280 (the number of feet in a mile), and copy the result to the output connector.
Create the block
Tutorial

Choose the command


Develop > New Block.
At the bottom of the dialog,
click the Create New
Library button.
Name the library Convert
and click Save. Notice that
in the pane on the left, the
new library is automati-
cally selected.
Enter the name Miles for
the new block, as shown at
right.
Be sure the correct library
is selected, then click the
Install in Selected Library
button.
ExtendSim creates the block and opens its structure window.
Dialog tab
By default, the structure’s Script tab opens in front so you can easily edit an existing block.
However, when building a new block it is best to start with the Dialog tab.
Bring the structure window’s Dialog tab to the front
The dialog is empty except for the OK and Cancel buttons, which are in every new block by
default, a frame to indicate the default size of the dialog, and tabs at the top.
Double-click the name of the first tab (Tab 1) and rename it to Converter
To add some explanatory text for this block:
If the toolbar is not already open, choose the command Tools > Dialog Items.
In the Dialog Items toolbar, select the Static Text dialog item.
Click on the structure window’s Dialog tab to create the Static Text dialog item.
Double-click the dialog item to open its properties window.
To set the properties for this dialog item:
Creating a Block 45
Building a simple block that converts miles to feet

To be consistent with the ExtendSim style guide, set X: 10, Y: 16, Width: 220, Height: 16.
(Alternatively you could resize and position the dialog item on the Dialog tab.)
In case you will add more tabs, check the box so that this text label will be Visible in all
tabs.
In the Label field, enter <b>Converts miles to
another length. (As discussed on “Stylizing
and aligning dialog items” on page 19, enter-
ing “<b>” in front of the text formats it as

Tutorial
bold; this style will appear once the block is
compiled.)
Leave the rest of the options as is and click
OK to close the properties window
With those coordinates, the label will be placed in the upper left corner of the Dialog tab. It
should now look like the screenshot here.
Save the block
It’s a good idea to save the block as you make changes to it. Since there isn’t any code in this
block yet, you should save it without compiling.
Choose File > Save Block
This saves the structure of the block without compiling the code. Alterna-
tively, you could close the structure window and, in the window that appears,
choose to Save Without Compiling.
☞ In the library window, uncompiled blocks are displayed with their names in red italics.
Icon tab
The Icon tab is for creating an icon and adding connectors.
Go to the structure window’s Icon tab
The Icon tab has a default icon
Icon and text
For the icon you could use the ExtendSim drawing environment or a painting program, or copy
clip art and paste it in. For this tutorial, just keep the default icon and add text.
Double-click on the Icon tab worksheet to create a text box:
Enter the text Miles->???
With the text selected, use the Bold command in the toolbar to
make the text bold and the Fill Color button in the Shapes toolbar
to make the text red
Position the text on top of the icon.
As needed, resize the icon and text using their resize buttons
The icon should now look similar to the one shown above.
46 Tutorial
Building a simple block that converts miles to feet

Connectors
The Miles block needs two value connectors, an input and an output. As discussed on page 20,
connectors can be either normal (a single connector) or variable (a row of single connectors).
The default is that connectors are normal, and that is what is required for the Miles block.
Adding connectors
If the Icon tool is not already open, choose the command Tools > Icon.
In the Icon toolbar select the Value connector, the first one in the list.
Click near the left side of the icon to add that value input connector. Notice that the name of
Tutorial

the connector (Con0In) is listed in the Connectors pane.


Select another Value connector from the Icon toolbar and place it on the right side of the
icon.
Select each connector and either drag it or use the arrow keys so that
the connectors are positioned on each side of the icon.
☞ To align the top of the connectors, either drag or use the arrow keys to
move one connector until its Y position (as shown in the Cursor Posi-
tion field of the ExtendSim toolbar) is the same as the other connector’s Y position.
Renaming the connectors and changing an input to an output
When connectors are added to an icon, they are by default all input connectors with the default
connector names Con0In, Con1In, and so on.
Connector names are not case sensitive. While input connectors must end in some form of the
word “In” and output connectors must end in a form of the word “Out”, the rest of the connec-
tor name can be customized as discussed on page 21.
In the Connectors pane at the right side of the Icon tab, double-click the connector name
Con0In.
Type MilesIn. This changes the name of the connector on the left of the icon.
Double-click the connector name Con1In and type UnitsOut. This
changes the connector on the right to an output connector, as shown.
Give the command File > Save Block. This saves your work without
having to compile the block.
When you select a connector name in the Connectors pane, the corresponding icon connector
gets highlighted.
☞ Because ModL is not case sensitive, the connector name “UnitsOut” could just as well have
been written as “unitsout” or “unitsOut” or “UNITSout”, etc.
Block help
This block has only one tab which is named Miles Converter. You could name another tab Help
or Information, and put text there to explain what the block does, who authored it, create and
modify dates, etc.
Script tab
☞ As shown on page 78 there is a Script dialog in the Edit > Options menu that is used to specify
characteristics for a block structure’s Script tab. For example, you can change the colors of
Creating a Block 47
Building a simple block that converts miles to feet

user functions or keywords. When the block’s Script tab is the active window, use Alt + O to
open the Script dialog.
Go to the structure window’s Script tab
As seen at the right, the Script tab is empty except
for a comment (“ModL code goes here”) and
three message handlers: Simulate, CheckData,
and InitSim.
These message handlers get automatically added

Tutorial
because most of the blocks you create will use
these messages and unused message are ignored.
For this block, the action happens in the Simulate message handler.The other default message
handlers can be left blank since there is nothing to check or initialize at the beginning of the
simulation run.
Below the opening bracket that follows the Simulate message, type: UnitsOut = MilesIn *
5280.0;
so that the code looks as follows:
on Simulate
{
UnitsOut = MilesIn * 5280.0;
}
☞ The spaces on each side of the operators are optional; the semicolon at the end of the state-
ment is not optional.
The code means that for each step of the simulation, ExtendSim reads the value at the input
connector, multiplies it by the real value 5280.0, and sets the output connector to that product.
Save and compile the block
After the code has been
entered:
Close the structure
window by clicking its
close box or giving the
command File > Close.
ExtendSim opens a
dialog for saving changes, seen at right. Click Save, Compile if Needed. This compiles the
ModL code and saves the changes to the block in the library.
If there are any compilation errors, ExtendSim will warn you.
☞ While not done for this block, the blocks you create can also be assigned categories, as
described on page 55.
Test the block
To test the Miles block:
Open a new model window if one is not already open.
If the model opens with an Executive block, delete the Executive block, since this isn’t a
discrete event simulation.
48 Tutorial
Adding user interaction and display features

Add your Miles block (Convert library) to the model worksheet.


Add a Constant block (Value library) to the left of the Miles block.
Connect the output of the Constant block to the input of the
Miles block.
In the Constant block’s dialog enter Constant value: 10.
Add a Line Chart block (Chart library) to the model. Constant block connected

Connect the output of the Miles block to the top


Tutorial

input of the Line Chart block as shown here.


Run the simulation.
Test model completed
As seen in the Line Chart block, the value 52800
(5280 x 10) should be output for the entire length of
the simulation. You can verify that the block works with other numbers by entering them in the
Constant block and running the simulation.
Adding user interaction and display features
If moving numbers between input and output connectors was all that ExtendSim did, it would
not be a very useful program. As you have seen in the User Reference, robust blocks:
• Let you change their parameters
• Give information about what is happening during the simulation

Dialog tab
The enhanced Miles dialog will have a popup menu for choosing a unit to convert to, parame-
ter fields for obtaining an input from the user and for displaying results, and a frame for orga-
nizing the dialog items.
Create a popup menu
Open the structure window for the Miles block, using one of the methods listed in “How to
open a block’s internal structure” on page 7.
Go to the block’s Dialog tab
If the Dialog Items toolbar isn’t already open, open it from the Tools menu
Click in the Dialog Items toolbar to select a Popup Menu and place it on the Dialog tab
Define the popup menu
Double-click the Popup Menu to open its prop-
erties and configure it as below:
Name: units_pop
X: 24
Y: 70
Width: 76
Height: 16
Label: Kilometers;Yards;Feet;Inches
Creating a Block 49
Adding user interaction and display features

Close the properties window


☞ While not required, coding conventions help when creating blocks. For instance, the popup’s
dialog item name (units_pop) is more intuitive to work with in the code, as can be seen later.
Add a text frame
Frames are used to organize dialog items on the window:
Add a Frame dialog item from the Dialog Items tool-
bar and stretch its opening so it surrounds Popup
Menu.

Tutorial
In its properties window, enter:
Label: Convert miles to:
It is not necessary to change the dialog item name or any other properties for the frame.
The Dialog tab should now look like the one shown above.
Save the dialog changes
Give the command File > Save Block to save your work
☞ This is a quick way to save changes without closing the block’s structure.
Add two parameter fields
To add entry and reporting fields for the numbers:
In the Dialog Items toolbar:
Click once to select the Parameter dialog item, but then...
While holding down the Alt key, click twice on the Dialog tab to create two parameter
fields
Press the escape key to stop placing parameters on the Dialog tab
Move the parameter fields so that they are at the same
horizontal position and below the frame
☞ To create multiple instances of a dialog item, hold the Alt or Option key down while repeatedly
clicking on the Dialog tab; then use the Escape key to finish. Alternatively, once you’ve placed
one parameter on the Dialog tab, you could use the Edit > Duplicate command to add copies of
dialog items to the Dialog tab, or just get the dialog item from the Dialog Items toolbar again.
Configure the parameter fields
In the properties window for the leftmost parameter:
Enter Name: InNum_prm
Set the width to 60 and the height to 16.
Click OK to close the properties window.
In the properties window for the parameter on the right:
Enter Name: OutNum_prm and click OK to close its properties window
Set the width to 60 and the height to 16.
50 Tutorial
Adding user interaction and display features

Select the Display only choice. This will cause the parameter value to be displayed in
the block’s dialog without being editable.
Click OK to close its properties window.
Adding more static text labels
The next step is to define two more Static Text dialog
items.
For the first static text item:
Tutorial

Enter In: for the label. Click OK.


Move it to the left of the first parameter box
and resize as needed.
For the second static text item:
Enter Out: for the label. Click OK.
Move it to the left of the second parameter box and resize as needed.
Save and compile the block as discussed on page 47.
Script tab
The next step is to enter code in the structure’s Script tab.
Go to the block structure’s Script tab
Declare constants
At the top of the Script tab, before any message handlers, enter the following:
constant UNITS_KILOMETERS is 1;
constant UNITS_YARDS is 2;
constant UNITS_FEET is 3;
constant UNITS_INCHES is 4;
The constants are set to the values of the menu items (kilometers, yards, etc) in the popup
menu.
CreateBlock message handler
The CreateBlock message handler can specify one of the conversions as the default for the
block when it is placed in the model. For instance, to make feet the default, enter the following:
// feet is the default setting
on CreateBlock// this gets executed when the user gets a new block
{
units_pop = UNITS_FEET;// make the FEET choice TRUE
}
You can put the CreateBlock handler anywhere in the block’s code as long as it is after the dec-
larations.
☞ The CreateBlock message handler is invoked whenever the Miles block is placed on a model
worksheet. If you’ve already got the block on the worksheet, feet won’t be the default setting.
Creating a Block 51
Adding an intermediate results feature

Simulate message handler


For each step in the simulation, you want to update the input parameter and the output parame-
ter, check which conversion is being performed, multiply the numbers. To do this, replace the
current code in the Simulate message handler with the following:
on Simulate
{
InNum_prm = MilesIn;
if (units_pop == UNITS_KILOMETERS)

Tutorial
UnitsOut = MilesIn * 1.609344;
else if (units_pop == UNITS_YARDS)
UnitsOut = MilesIn * 1760.0;
else if (units_pop == UNITS_FEET)
UnitsOut = MilesIn * 5280.0;
else if (units_pop == UNITS_INCHES)
UnitsOut = MilesIn * 63360.0;
OutNum_prm = UnitsOut;
}
Notice that “units_pop” is the name of the popup menu defined on page 48. Also notice that if
“Yards” is selected in the block’s dialog, the statement “if (units_pop == UNITS_KILOME-
TERS)” evaluates false and its “else” clause is executed. The “if (units_pop == UNITS_-
YARDS)” statement then evaluates true and executes its statement, and the “else” clauses
following it will not be executed.
☞ The numbers multiplied by MilesIn can be reals or integers. ModL performs all necessary type
conversions automatically. However, since connectors are always of type real, you should use
reals for values that are used with connectors. That way, ExtendSim will not need to convert
integers to reals on each step. (For more information about type conversions, see page 64.)
Save and compile the block
After you have finished writing the code, close the block by clicking its close box. Choose
Save, compile if needed to compile the new ModL code and save the block in the library.
Test the Miles block as you did before, trying all the conversions. Notice that you can keep the
Miles dialog open during the test.
Adding an intermediate results feature
You may have noticed something missing from the Miles block: what if you just want to con-
vert a single number without running a whole simulation? As stated earlier, ExtendSim passes
dialog messages to a block even if a simulation is not running. It is thus easy to make this block
useful even outside of a simulation.
52 Tutorial
Adding an intermediate results feature

Add a button to the Dialog tab


Open the block’s internal structure.
In the Dialog tab, choose a Button dialog
item from the Dialog Items toolbar and
place it on the dialog.
Enter Calculate_btn as the dialog
name and CALCULATE for the button
label.
Tutorial

Make the width 80 and the height 20.


Click OK.
Drag this new button below the input
and output fields, as shown at right.
Add ModL code to the Script tab
Add the following message handler somewhere below the Simulate message:
on Calculate_btn// Display the values
{
if (units_pop == UNITS_KILOMETERS)
OutNum_prm = InNum_prm * 1.609344;
else if (units_pop == UNITS_YARDS)
OutNum_prm = InNum_prm * 1760.0;
else if (units_pop == UNITS_FEET)
OutNum_prm = InNum_prm * 5280.0;
else if (units_pop == UNITS_INCHES)
OutNum_prm = InNum_prm * 63360.0;
}
Save the block and compile the ModL code.
☞ See “Other features you might have used” on page 54 for how to avoid typing the same code
twice in the future.
To test this new functionality:
Place the block on a model worksheet and double click to open the block’s dialog. You may
need to resize it to show the new dialog items.
Type a number in the In: entry box.
Click the Calculate button.
Note that the number in the Out: entry box is updated with the correct data.
☞ See “Accessing code from other languages” on page 42 for an example of how to do this using
a DLL.
Creating a Block 53
Adding 2D animation

Adding 2D animation
The icon of this block indicates that it converts miles to something, but that’s not very informa-
tive. Displaying text on an icon is a convenient method to show block conditions – in this case,
what kind of conversion the block is performing.
☞ The ModL code will ensure that the animated text is displayed even if the modeler doesn’t have
Show 2D Animation selected; the display is also independent of the simulation run.
Change the icon and add the animation object
As discussed in “2D animation” on page 10, the Animation Object tool is used to add

Tutorial
animation to icons. This tool is the last one in the Icon toolbar, shown below.

Open the structure window of the Miles block.


In the Icon tab, delete the ??? part of the icon’s text.
Move the remaining text to the left side of the icon.
In the Icon toolbar, select the Animation Object tool; it is the last button in the toolbar.
Click on the icon to place the Animation Object to the right of
the text.
Expand the Animation Object to the right. This creates a rectan-
gular animation object. Since this is the first animation object, it Animation object added
will have a “1” in it.
Expand the icon as necessary to provide enough room for the animation object.
Add code for the animation
☞ The code below contains a ModL function. It is easiest, and safest, to enter functions using
code completion, as described on page 79.
Add additional message handlers
Add the following message handlers to the end of the ModL code. Each message handler
receives a message when the corresponding radio button is clicked.
on units_pop
{
if(units_pop == UNITS_KILOMETERS)
{
AnimationTextTransparent(1, "KM");
AnimationShow(1);
}
else if(units_pop == UNITS_YARDS)
{
AnimationTextTransparent(1, "Yards");
AnimationShow(1);
54 Tutorial
Other features you might have used

}
else if(units_pop == UNITS_FEET)
{
AnimationTextTransparent(1, "Feet");
AnimationShow(1);
}
else if(units_pop == UNITS_INCHES)
Tutorial

{
AnimationTextTransparent(1, "Inches");
AnimationShow(1);
}
}
The ModL compiler will give an error message if code containing “smart quotes” is copied into
the Code pane. To fix the problem, replace the copied quotes with new ones in the Code pane.
Createblock message handler
Replace the code in the “On CreateBlock” message handler to initialize the animation text.
// feet is the default setting
on CreateBlock
{
units_pop = UNITS_FEET;
AnimationTextTransparent(1, "Feet");
AnimationShow(1);
}
Close the block’s internal structure, saving and compiling the changes.
☞ Notice that the text will show only when a new Miles block is placed on the model worksheet.
Testing the block
To test this new functionality:
When you place a new Miles block in a model, the default setting (Feet)
should be displayed on its icon. Icon with animation

Changing the selected radio button in the block’s dialog should cause a
corresponding change on the icon.
The final Miles block is located in the ExtendSim/Libraries / Example Libraries / Custom
Blocks library. See below for additional features to consider when building custom blocks.
☞ Animation objects can be layered on top of each other, then called in block code to appear or
not depending on circumstances. Use each animation object’s zOrder to place it in the layer
you want. For more information, see “Creating 2D animation objects” on page 127.
Other features you might have used
The preceding example showed how to build a simple block. This section describes some addi-
tional ExtendSim features that could have been used when building this block.
Creating a Block 55
Other features you might have used

Feature Description Page


Block categories Group blocks by category in the Library menu 55
Colors for dialog items Custom colors for text labels 17
Styles and alignment Some dialog items can have their style formatted 19
Tabs in dialogs Group dialog items by function 13
zOrder for dialog items Control the forward and backward position of dialog 17
items

Tutorial
Add to right-click menu Cause the block’s Button dialog items to appear when 17
a block is right-clicked
Dialog item tooltips Tooltips display dialog item names without having to 20
open the block’s dialog
Hiding/showing dialog items Use code to dynamically hide and show dialog items 95
based on model conditions
Icon views Multiple icons per block; user selectable 9
Variable connectors They act like a row of normal (single) connectors 21
Connector labels Tooltips display connector information such as results. 22
Connector tooltips Display custom text through tooltips 23
Column tags Put strings, checkboxes, buttons, dates, popup menus, 321
the infinity character, and so forth into a parameter
field or the cell of a data table
Programming tools Code completion, include files, debugger, conditional 78
compilation, and more
DLLs and Shared Libraries A legacy of code, or programming capabilities that are 86
outside of ModL’s range, can be accessed using DLLs 88
(for Windows) or Shared Libraries (on the Macintosh)
External source code control Saves the source code of blocks as external files so 83
multiple developers can work on it

Linking to a global array or ExtendSim database


Dynamic data linking (DDL) creates a link between a data table or parameter dialog item and
an internal data repository (global array or ExtendSim database). For instance, the Data Source
Create block (Value library) has a data table that is dynamically linked to a global array. To add
dynamic link capability to a block, see “Data table linking” on page 313 and “Dynamic link-
ing” on page 317.
To simply register a block so that it will be notified if there was a database change, see “Regis-
tered blocks” on page 111 and “Linking and notification” on page 374.
Block categories
It is common to build several blocks to put in a library. You can have all the blocks listed
alphabetically in the library, or you can specify a block category and cause blocks to be
grouped into submenus in the Library menu.
Each block has a 15-character string associated with it called the block category. The category
is used by ExtendSim to organize blocks into logical groups that perform a similar function.
56 Tutorial
Defining functions

For example, the Math block (Value library) performs basic math functions; therefore, its block
category is Math. ExtendSim uses the block category in two places: 1) to organize blocks
within the Library menu, and 2) to organize blocks within reports. Categories of blocks in
libraries and reports are discussed in the User Reference.
To set or edit a block’s category:
With the block’s structure window open,
select the command Develop > Set Block
Category.
Tutorial

In the Category dialog, either select an


existing category from the popup menu or
define a new one by entering it in the text
field.
Click OK.
The Edit > Options > Libraries tab has a
checkbox (List blocks in Library menu by category) that is used to determine how ExtendSim
will list this block within the Library menu. If checked, the block will be listed in a sub-menu
for the block category under the library name. If the box is unchecked, ExtendSim will not use
the category but will instead list the block alphabetically directly under the library name.
Defining functions
In the Miles block the Simulate and the Calculate message handlers have similar code. One
way to be more efficient and reduce errors would be to define a function to calculate the output
value and call it in the both the Simulate and Calculate message handlers.
Real CalculateOutput(Real inputValue)
{
InNum_prm = MilesIn;
if (units_pop == UNITS_KILOMETERS)
UnitsOut = MilesIn * 1.609344;
else if (units_pop == UNITS_YARDS)
UnitsOut = MilesIn * 1760.0;
else if (units_pop == UNITS_FEET)
UnitsOut = MilesIn * 5280.0;
else if (units_pop == UNITS_INCHES)
UnitsOut = MilesIn * 63360.0;
return(UnitsOut);
}
On Calculate_btn
{
OutNum_prm = CalculateOutput(InNum_prm);
}

On Simulate
{
InNum_prm = MilesIn;
Creating a Block 57
Defining functions

UnitsOut = CalculateOutput(MilesIn);
}

Tutorial
58 Tutorial
Defining functions
Tutorial
Integrated Development
Environment (IDE)

The ModL Language


A detailed description of ModL constructs and structure

“Knowledge is of two kinds. We know a subject ourselves,


or we know where we can find information upon it.”
— Samuel Johnson
60 IDE
Names

ModL is the ExtendSim programming language; it is structured much like C++.


☞ To get the most out of this chapter, you should first read the chapter “ModL Overview”. A table
comparing ModL to C++ starts on page 27; a comparison of ModL to other languages starts on
page 29.
This chapter describes the ModL structure and constructs. It is intended as a reference to the
ModL programming language; it is not a programming tutorial.
The best introduction to programming with ModL is familiarity with programming in C or
C++. If you are familiar with programming in some other language, that will help as well. If
you have not programmed in any language, a beginning programming class or tutorial would
probably be a better starting point than trying to learn programming by building ModL blocks.
Names
Names for variables, constants, and functions:
• Can be up to 127characters
• Can have letters, numbers, and the underscore (_) character
IDE

• Must begin with a letter or an underscore (_) character


• Are not case sensitive
ModL is a case insensitive language. This means that the following identifiers appear the same
to the ModL compiler:
Myname MYNAME MyName myname
☞ Some names are reserved for system use, as described throughout this chapter.
Data types: definitions and declarations
As discussed more below, there are four main data types in ModL:
1) real or double
2) integer or long
3) string (Str15, Str31, Str63, Str127, Str255 or String)
4) pointertype

Real data types


Real numbers are stored as Extended IEEE floating point numbers with 16 significant digits.
Numeric literals containing a decimal point or E notation are assumed by the compiler to be
real numbers. The range of real values is approximately ±1e±308.
A ModL real/double variable is the equivalent of a double variable in C++. It occupies 8 bytes
of memory.
Integer data types
Integer numbers are stored as 32-bit integers. The maximum value is 2147483647, and the
largest negative value is -2147483648.
A ModL integer /long variable is the equivalent of a long integer variable in C++. It occupies 4
bytes of memory.
☞ ModL treats a non-zero value as TRUE and a 0 value as FALSE. The constant TRUE is defined
as 1 and FALSE is defined as 0.
The ModL Language 61
Data types: definitions and declarations

String data types


StrXX may contain up to XX characters and Strings may contain up to 255 characters. String
literals (constants) are sequences of characters enclosed by quotes ("..."). The quote character
itself may appear in strings by using two adjacent quotes. For example:
"It's called ""ExtendSim"""
is evaluated as:
It's called "ExtendSim"
For a string literal that you want to extend past one line of the code, put a back slash (\) charac-
ter as the last character on the line. For example:
longString = "This is a very long string \
literal that is on more than one line";
A string variable is the equivalent of an unsigned char x[256] variable in C++. Str255 occupies
256 bytes of memory; smaller string types (StrXX) occupy XX+1 bytes of memory.

IIDE
ModL strings are not accessed in the same way as strings in C++. To access the contents of a
ModL string beyond assigning its contents, you need to use ModL functions.
☞ ModL strings are internally stored as Pascal style strings, with a leading size byte. In most
cases you will not have to worry about the internal storage of the string. However, it does
become relevant when you pass a string to outside code through a DLL function call. In that
case, the ModL functions DLLPtoCString and DLLCtoPString will be useful - see the function
list that starts on page 265.
Pointertype data types
This data type contains the address of data that is held in dynamic arrays and compiled equa-
tions. A pointertype can be stored in a real, which means that you can store pointertypes in a
real type array or in an ExtendSim database for use by the model.
Declaration examples
For the real/double and integer/long data types, the identifiers are interchangeable. The type
declarations and constant definitions are set up like they are in C.
Some typical type declarations might be:
real nextTime;
real dataArray[], averages[10], theMatrix[10][10];
str15 str15Array[];
str31 str31Array[];
string strArray[], errorStrings[6], theError;
integer checkUsed, multiArray [][3][5][10][2];
pointertype p;
As you can see from the example above, ModL has fixed and resizable (dynamic) arrays, and
arrays can be up to five dimensions.
ModL already has some pre-defined variables that can be treated just like other static variables.
These system variables are described in the “ModL Variables” chapter that starts on page 210.
☞ Each variable type consumes a different amount of data, with integers using 4 bytes, reals using
8 bytes, strings using 256 bytes, and pointertypes using 8 bytes. At the same time, there is a
limit on the total amount of static data that can be declared. Thus if you define a string array as
string x[200] (which uses 200x256 or 51,200 bytes of memory), it will exceed the local or
62 IDE
Scope of global, local, and static variables

static data limit of 32,767 bytes (not including dynamic arrays and pointertypes) and the com-
piler will report an error condition.
Scope of global, local, and static variables
Variables define memory that can store a value or values. There are several types of ModL
variables.
Whether a variable is global, static, or local defines what is known as its scope. The scope of a
variable determines where it can be accessed by code. The following information is important
to keep in mind when using variables in block code.
• Global variables are pre-defined in the IDE. A global variable’s scope is the entire model. In
a model, a global variable can be referenced from within any block’s code or within equa-
tion-based blocks.
• The scope of a static variable (a variable declared at the top of a block’s code) or dialog item
variable (the name of a dialog item) is the code of that specific block. This means that a
block’s static variable cannot be used directly in the code of other blocks or in the equations
used in equation-based blocks.
IDE

• A local variable’s scope is just the message handler or user-defined function in which it is
declared.

Static and local


Variables and constants must be declared before being used. Static and constant declarations
are made at the beginning of a block’s code and local declarations are made at the beginning of
a message handler or user-declared function.
The values of static variables are stored in the block and are saved in the model file. Thus, they
may be used to store data which must be preserved from one run of a simulation to the next.
However, they are not automatically initialized and must be initialized in your block code.
Within each block, and also locally within each function in block code, there is a limit on the
total amount of static data that can be declared. If you exceed this limit, the compiler will give
an error message when the block code is compiled. The total amount of data that can be
defined in static variables in the block, and in local variables within each routine, is 32,767
bytes of data. (See “Declaration examples” on page 61 for the amount of memory used by each
type of variable.)
This limitation is not an issue for most users because the more common and usually more use-
ful way to allocate large data structures is with dynamic array, global arrays, and database
tables. These structure are not subject to, or effected by, the static data limit.
☞ The advantages of using local variables are that they are not saved with the model and only use
memory when the function is called. The disadvantages are that the values of local variables
are not remembered after the message handler or function is left, and local variables can over-
ride static variables of the same name.
Uninitialized static variables can be subtle but serious bugs. The value of an uninitialized vari-
able will take any random number, causing code to not work in unpredictable ways.
Constant definitions
Constants can be of data type real, integer, or string, but not pointertype. A constant definition
might be:
The ModL Language 63
Constants that are pre-defined

constant maxPower is 52.5;


Note that in the constant definition the data type is implied by the format of the literal value. In
the above example, the type is real or double. However:
constant xstr is "x"; // quotes cause the constant to be string type
constant maxPower is 52 // data type is an integer or long
• For a constant to be real, it must either contain a decimal point or be in E notation
• A string must be enclosed in quotation marks
ModL includes four general-purpose predefined constants (Pi, Blank, true, and false); they are
discussed on page 63.
☞ Regardless of where they are defined in the ModL code, constants are always static
Constants are not directly supported in equation-based blocks; use an include or set the value
from a Constant block (Value library). For a list of the differences between equation blocks and
custom blocks, see page 31.

IIDE
Constants that are pre-defined
ModL includes four numerical predefined constants:
PI = 3.14159265358;
BLANK = (noValue);
TRUE = 1;
FALSE = 0;
Setting a dialog parameter to BLANK will make it display as an empty field. BLANK values
show nothing in a dialog’s text field and are NoValues for all math calculations.
☞ Do not compare the constant BLANK with a value to determine if the value is BLANK (that is,
NoValue). The result will always be FALSE. Use the NoValue function instead. This function
returns a TRUE if the value passed to it is a NoValue.
There are other predefined constants that are specific to functions, such as the color constants
used with the Animation functions.
BLANK and NoValue
The constant BLANK is a special value that represents “no value”. A NoValue can only be rep-
resented by a real variable, not an integer. Technically, it is not a number and appears in a dia-
log as a blank item. To make a variable a NoValue, assign BLANK to it (a = BLANK).
If a number and a NoValue are added, multiplied, divided or subtracted, the answer is always a
NoValue. Thus, if any of the values in any equation is a NoValue, the result will always be a
NoValue.
If a real value is divided by 0, the answer is a NoValue; the square root of a negative number is
also a NoValue. In fact, any operation on numbers that causes an undefined result or an infinity
produces a NoValue answer which can be tested with the NoValue function listed in the section
“Basic math” on page 227.
☞ To test for a NoValue, do not compare it to BLANK in an “if” statement. Instead, always use
the NoValue function:
if (myValue == BLANK) // WRONG! THIS WILL NOT WORK!

if (NoValue(myValue)) // this will always work


64 IDE
Numeric type conversion

NoValues can cause unexpected problems when converting reals to integers. It is a good idea
to screen for NoValues before converting reals to integers, as discussed in “Numeric type con-
version”, below.
Numeric type conversion
Generally, ModL performs all type conversion automatically. Thus, integer values can be
assigned to reals, and mixed-type arithmetic can be performed without explicit type conversion
beforehand.
☞ Because conversions are computer intensive, it is best to avoid numerical type conversions.
This is particularly true whenever there are repeated or often-used calculations.
ModL converts the arguments of function calls to the type needed by the function. For exam-
ple:
a = cos(integer);
Because the cosine function expects the argument to be a real value, the integer is converted
to a real value before the function is called.
IDE

Real to integer
Like all programming languages, converting from real numbers to integers in ModL is not
always exact. If a real number is also an integer, it will be exactly converted. Otherwise, the
conversion will cause the fractional value (mantissa) to be truncated. Thus, 0.001*1000.0 may
not equal 1 (the integer value), but may equal 0.99999... When this number is converted to an
integer, the answer is 0, not 1.
☞ In an operation between an integer and a real, the result is always a real.
NoValue to integer
As described above, setting a real value into an integer variable has a consistent result, namely
the truncation of the real value. This is true in all cases except where the real variable contains
a BLANK, or NoValue, value.
☞ If a real contains a BLANK or NoValue value, the NoValue will be too large to fit into an inte-
ger. Thus the integer will contain a meaningless value which could cause problems in calcula-
tions.
The best method for dealing with this potential problem is to screen the real values for NoVal-
ues before assigning them to the integer variable. The following code is an example of how to
do this.
Real realV;
integer intV;

if (NoValue(realV))
intV = 0; // Can’t convert NoValue to integer
// Meaningless result
else
intV = realV; // Can convert real to integer

Integer to real
There is no loss of information or special concerns when converting an integer to a real num-
ber.
The ModL Language 65
Arrays

However, using integer constants for real expressions is dangerous and can give the wrong
results.
For example, consider the following code:
z = 1/2*a;
In this case, z will always equal 0. The integer 1 divided by the integer 2 equals 0 because the
result of integer operations cannot be a fraction; it must be an integer. The statement should be
instead written as:
z = 1.0/2.0*a;

Integer or real to string


When the equation calls for it, ExtendSim automatically converts reals and integers to string
values. If a real variable is a NoValue, the resulting string will be an empty string.
☞ The result of an operation between any type and a string is a string.
This makes it easy to make strings that contain numeric results, such as:

IIDE
anOutputString = "The answer is " + aRealNum + ".";

String to real or integer


The StrToReal function converts a string value to a real number. If the string contains non-
numeric characters, the result will be a NoValue.
Do not assign a non-numeric string to an integer. This will assign an unusable value to the inte-
ger.
Arrays
You can use real, integer, or string arrays which can be fixed or dynamic. Any array can have
up to five dimensions, that is, up to five subscripts or indexes. Array indexes are limited to 2
billion elements. (There are also other array-structure types: linked lists and global arrays. See
“Array-like structures” on page 67.)
Array declarations
The number of dimensions and the magnitude of each dimension are determined by the array’s
type declaration. The magnitude of each dimension appears in the square brackets in the decla-
ration statement, and there must be one set of brackets for each dimension. The subscripts in an
array start at 0. The type declarations are of the form:
TYPE id[dim1][dim2]...;
Thus the declaration:
REAL MyArray[3][4];
declares an array of real numbers identified by the name MyArray. This is a two dimensional
array, with three rows and four columns.
Individual elements of arrays are treated just like variables in ModL. Thus, for an array
declared as
integer a[2][3]
you can assign the value 4 to the first row in the second column with:
a[0][1] = 4;
66 IDE
Arrays

Remember that array subscripts start at 0 and end at 1 less than the number of elements in the
declaration (that is, there are n elements in 0 to n-1).
Fixed and dynamic arrays
ModL has both fixed and dynamic arrays.
Fixed arrays have specified sizes that cannot be changed in the code. The leftmost dimension
of dynamic arrays are variable in size and can be assigned a size or resized without changing
existing data. Dynamic array size is limited to two billion elements, and you can declare up to
254 dynamic arrays per block. Dynamic arrays can be passed between blocks or used globally.
See “Passing arrays” on page 102.
Dynamic arrays are declared in the same manner as fixed arrays, except that their first dimen-
sion value is missing. For example:
REAL MyArray[ ][4];
defines a two-dimensional dynamic array of real numbers. There is a varying number of rows
and exactly four columns (indexed 0 through 3).
IDE

Dynamic arrays must be static variables, not local ones. Thus, you cannot declare a dynamic
array variable in a message handler. However, you can resize dynamic arrays inside of a mes-
sage handler or in a user-defined function.
There are several functions for sizing dynamic arrays:

Function Use

DisposeArray Frees memory when you are finished with the array
DynamicDataTableVariableColumns Causes the right dimension to be variable. This is only useful for
data tables.
GetDimension Returns the size of the missing left dimension
GetDimensionByName Returns the size of the missing left dimension based on the block
number and the name of the array
GetDimensionColumns Returns the number of columns in a two dimensional array
GetDimensionColumnsByName Returns the number of columns in the two dimensional array,
based on the block number and the name of the array
MakeArray Sets the size of the missing left dimension
MakeArray2 Sets the size of the missing left dimension for an array in any
block, including a block other than the one calling the code. It
allows resizing of dynamic arrays passed in to functions as a string
name.

The GetDimension function can be used with any array, not just dynamic arrays. GetDimen-
sion returns the value of the first (leftmost) dimension, whereas GetDimensionColumns
returns the value of the rightmost dimension in a two dimensional array.
These functions are described fully in “Dynamic and non-dynamic arrays” on page 376. Also
see “Variable column data tables” and “Dynamic data table resizing” on page 313.
The ModL Language 67
Array-like structures

Arrays as arguments to functions


When passing an array name to a function, it is necessary to differentiate between passing the
entire array and passing only an element of the array.
☞ To pass an entire array, supply only the array name, without subscripts. To instead pass only a
single element of an array, use a subscripted array name.
Many ModL functions take arrays as arguments. To pass an array that has the same dimensions
as the function needs, simply use the array’s name. For example, the arguments to the AddC
function must be arrays with two element; that is, declared such as real a[2]. Assume you have
three arrays declared as:
real x[2], y[2], z[2];
You would call the AddC function as:
AddC(x, y, z);
If you have an array with more dimensions than are needed by the function, you can specify an

IIDE
array segment as an argument. An array segment is an array with fewer dimensions than the
full array. Array segmenting can only be done by specifying the leftmost dimensions, not the
rightmost dimensions. For example, assume that you had the following declarations:
real x[2], y[2];
real z[50][2];
To pass the fifth row of z (which contains two elements), to a function such as AddC (which
only wants an array of one dimension), you would use:
AddC(x, y, z[4]);
Array-like structures
Global arrays
There is another kind of array that can be set up using functions and is useful for data needed
globally throughout the model. Global arrays provide a repository for model-specific data.
Global arrays are dynamic arrays that, like global variables, can be accessed by any block in
the model. However, they differ from global variables in the following ways:
• Global arrays are accessed and managed through a suite of functions.
• You create and dispose global arrays as they are needed. There is no limit to how many
global arrays can be associated with a given model.

See “Using passed arrays to make structures” on page 105 for an example of using global
arrays to make structures. The global array functions start on page 378.
Linked lists
ModL has a suite of functions to support a linked list data structure. A linked list is an internal
data structure that allows the construction and manipulation of complex lists of data. These
queue-like, multiple type structures maintain internal pointers between the different elements,
speeding movement of elements (sorting) around within the list.
• Each structure element can simultaneously contain any number of integer, real, and string
data types, allowing the creation of complex sorted structures.
68 IDE
Operators

• They are faster than their linear equivalent if their internal sorting functionality is taken
advantage of, as in a Queue block (Item library).

• They are owned by individual blocks but can be accessed globally from any block.

See “Linked lists” on page 385 for a suite of functions. See the queue blocks in the Item library
or the blocks in the Rate library for examples of using linked lists.
Database tables
ExtendSim database tables are array-like structures. For more information about the Extend-
Sim database see “Working with databases” on page 111. The list of database functions starts
on page 354.
Operators
ModL offers a full set of mathematical and logical operators, as shown below.
Assignment operators
IDE

Operator Description

id = expression; assignment statement


id += expression; equivalent to id = id + expression
id -= expression; equivalent to id = id - expression
id *= expression; equivalent to id = id * expression
id /= expression; equivalent to id = id / expression
id++; equivalent to id = id + 1
++id; also equivalent to id = id + 1
id--; equivalent to id = id - 1
--id; also equivalent to id = id - 1

Math operators

Operator Description

+ addition and concatenation


- subtraction
* multiplication
/ division
^ exponentiation. ModL (unlike C) uses ^ to
denote exponentiation, as in 2^4.
% modulo
MOD modulo

The + operator is used both to add numeric values and to concatenate strings. For example:
The ModL Language 69
Operators

str = "My name"+" is Ralph";


returns the string “My name is Ralph”.
str = "Time = " + currentTime;
returns the string “Time = 5.65” if currentTime equals 5.65.
The % and MOD operators return the remainder after integer division. For example, 5 MOD 2
returns 1 and -5 MOD 2 returns -1. If the MOD operator is used on real values, they will be
truncated to integers before the operation is carried out.
☞ Any operation involving a noValue (BLANK) produces a noValue result. NoValue results
appear as blank entries in tabular data and are not reflected in plotted traces at all.
Boolean and magnitude operators

Operator Type Description

IIDE
AND or && Boolean (logical) combination
OR or || Boolean (logical) conjunction
NOT or ! Boolean (logical) inverse
!= or <> Magnitude not equal to
< Magnitude less than
<= Magnitude less than or equal to
> Magnitude greater than
>= Magnitude greater than or equal to
== Magnitude equal to

The three standard Boolean operators are not bit-wise logical operators, but only operate on
TRUE or FALSE expression values.
The standard magnitude operators return a Boolean value (1 for true and 0 for false) after com-
paring their arguments.
Operators in an expression are generally evaluated from left to right; however there is a hierar-
chy of precedence among the operators. The following list is in descending order of prece-
dence; within each group, operators have equal precedence.
☞ Putting any expression in parentheses ensures that it will always be evaluated first.
1) ( )
2) - (negation)
3) NOT or !
4) ^
5) MOD or %, *, /
6) + (addition and concatenation), -
7) <, >, <=, >=, = =, <> or !=
8) OR or ||, AND or &&
70 IDE
Control statements and loops

Control statements and loops


ModL supports a full complement of structured programming control statements. In this table,
“boolean” evaluates to TRUE or FALSE. The control statements are:

Statement Use

Abort Abort;
Break Break;
Continue Continue;
Do-While Do
STATEMENT;
While (boolean); // Note semicolon
For For (init_assignment; boolean; incr_assignment)
STATEMENT;
IDE

GoTo GoTo label;


...
label: //note the colon
...
If If (boolean)
STATEMENT;
If-Else If (boolean)
STATEMENT_A;
Else
STATEMENT_B;
Return Return;
or
Return(value or expression);
Switch Switch (expression)
{
CASE integerConstant:
many STATEMENTS;
Break;
CASE integerConstant:
many STATEMENTS;
Break;
DEFAULT:
many STATEMENTS;
Break;
}
While While (boolean) // Note no semicolon
STATEMENT;

Multiple statements can be grouped with braces:


The ModL Language 71
Control statements and loops

{
statement;
statement;
...
} // Note no semicolon here
Use the If statement for boolean comparisons such as
if (total < 0)
{
isNegative = TRUE;
findings = abs(total);
}
...
You can also use the If-Else construct if you have two paths to choose from:
if (total < 0)
{

IIDE
isNegative = TRUE;
findings = 100 + total;
}
else
findings = 100 - total;
...
The FOR construct lets you set the initial value, continuing boolean condition, and action to
take on each step in the parentheses. For example:
for (i = 0; i <10; i++)
a[i] = i;
will set a[0] to 0, a[1] to 1, and so on up to a[9].
The While loop repeats the statement while the expression is true; the expression is evaluated
at the beginning of the loop. Thus,
x = 3;
y = 3;
while (y<3)
{
x++;
y++;
}
would leave x and y set to 3 because the loop is never executed.
The Do-While construct tests at the end of the loop, so
x = 3;
y = 3;
do
{
x++;
y++;
}
while (y<3);
would leave x and y set to 4 because the test occurs at the end of the loop, after x and y have
already been incremented.
72 IDE
User-defined functions

The Switch statement is used to check values against integer constants and act on those cases.
Note that the integers in the CASE statement must be constants, not variables. For instance,
switch (numberOfRepeats)
{
case 0:
UserError("You didn't run it.");
wasOK = FALSE;
break;
case 1:
UserError("Thank you, it ran once.");
wasOK = TRUE;
break;
default: // any other number
UserError("You ran it more than once; please stop.");
wasOK = FALSE;
break;
}
The GoTo syntax is supported only within a message handler or user-defined function. Control
IDE

is unconditionally transferred to the statements after the label.


The Abort statement stops the current message handler. You can use this at any point, even
inside loops. For example, in a DialogOpen message handler, the Abort statement would pre-
vent the dialog from opening. The two most common uses of the Abort statement are in the
CheckData and Simulate message handlers
• In CheckData, it can be used to abort if the modeler’s data is bad.
• In the Simulate message handler, it aborts the current simulation if something goes wrong
with the calculations. (See the AbortAllSims function to abort multiple simulations.)
ModL also provides two control statements for exiting from loops and other control structures:
• Break immediately exits an enclosing For, While, Do, or Switch construct.
• Continue immediately sends control to the next iteration of an enclosing loop.
The Return statement is used to exit message handlers and user-defined functions.
• When returning from a message handler or user-defined function that does not return a
value, use:
Return;
• When returning from a user-defined function that returns a value, use:
Return(value or expression);
User-defined functions
In addition to the many pre-defined ModL functions that are included with ExtendSim, you
can define your own functions and override them by re-declaring them. User-defined functions
make ModL code more readable and allow you to create tools that can be reused. They are
defined and called as they are in C.
User-defined functions have the following form:
The ModL Language 73
User-defined functions

TYPE (or VOID) name (TYPE id, TYPE id,…, TYPE id) // zero or more
arguments
{
optional local variable declarations

zero or more statements

Return(value);
}
In these definitions, VOID is a function that does not return any value and TYPE and VOID
can be integer, real or string. All arguments are optional. Arrays may be passed as arguments.
User-defined functions can be recursive, that is, they can call themselves.
Limitations
• Unless they are declared in include files, user-defined functions are local to the blocks in
which they are defined. To make one or more user-defined functions available for use by

IIDE
multiple blocks, create an include file as discussed in “Include files” on page 81.
• User-defined functions are not directly supported in equation-based blocks; they must be
declared in an include file. See the other limitations of equation blocks on page 31.

Defining
User-defined functions must be defined before they are used since the ModL compiler needs to
know the types of the arguments for type conversion. (Type conversions are discussed on
page 63.)
If you define a function that calls another user-defined function, both cannot be defined first.
The solution is to have a declaration of the function before it is actually called in the ModL
code:
TYPE (or VOID) name (TYPE id, TYPE id,…, TYPE id); //Note the ";"
This is called a forward declaration and tells ModL the types of the function and arguments,
and that the function will be defined later. The form is exactly the same as a function defini-
tion, but instead of braces, it ends in a semicolon.
Exiting
Exit a user-defined function at any point with a Return statement for Void type, Return(value)
for other types, or the Abort statement (see Abort, above).
For example:
real MyCalc(real x1, real x2)
{
real sum; // declare a temp variable

sum = x1+x2; // the calculation


Return(sum); // return the sum
}
...
y = MyCalc(a, b); // calc using function
...
74 IDE
User-defined functions

If Abort is called in a function that was otherwise going to return a value, the code is halted
completely and the return value is no longer necessary. That is, the code execution does not
return to the calling routine, so the return value of the function is moot.
Overriding user-defined functions
User-defined functions can be overridden by being re-declared any number of times below the
first declaration. In this case, the code that is executed is the final version of the routine. In the
code pane, the earlier versions of the routine will be colored brown to show that they have been
overridden.
Overriding is useful in that include files can have basic forms of functions and message han-
dlers which can be re-declared and overridden in the main block code. See “Include files” on
page 81.
Declaring arrays as arguments for user-defined functions
This section shows how to create a function that has arrays as arguments.
If the array size is not fixed, you can declare arrays as arguments to functions with the first
IDE

(leftmost) dimension blank; additional dimensions must have a value. This allows you to pass
either kind of array (fixed or dynamic) and any length of array to a user-defined function.
The following is an example of functions that add all of the elements of the rows in a variable-
sized array and return the sum.
real rowSum(real x[])
{
integer length, i; // Temporary variables
real sum;

length = GetDimension(x); // Returns first dimension


sum = 0.0; // Initialize sum

for (i=0; i<length; i++) // For all elements


sum = sum+x[i]; // Add element to sum

return(sum);
}

on Simulate
{
real valuesArray[36], mySum;
...
mySum = rowSum(valuesArray);
...
}

For more information


• “Block-to-block message” on page 110 for a method of defining “global” functions
• “Pass by value and reference (pointers)” on page 102 for information on passing arguments
to functions
• The user-defined ActiveX Data Object (ADO) functions listed on page 405
The ModL Language 75
Message handlers

Message handlers
Message handlers group code into sections. They interpret messages that come from the simu-
lation, from another block, or from user interaction with a block’s dialog. While messages can
originate either from the ExtendSim application or from blocks, it is always a block that is on
the receiving end of a message.
ExtendSim runs the message handler whenever one of the messages is passed to the block
The format of a message handler is:
on MessageName
{
zero or more declarations and/or statements;
}
MessageName must be the name of one of the messages listed in the chapter “Messages and
Message Handlers”. The code of the message handler is contained between the curly braces
(“{” and “}”) and tells ExtendSim what to do in the specific circumstance. To exit from a mes-

IIDE
sage handler before the ending brace, use a Return statement or an Abort statement, as
described above.
When you create a block, you can add message handlers that are executed at defined times,
such as when the dialog for the block is opened (so you can initialize the dialog’s contents),
when the simulation is stopped, when a dialog button was clicked, or when the block gets a
message from another block. No matter what happens, there is a message handler available to
perform an action.
Message handler example
The statements in the body of the message handler are in the same format as C functions. For
example, a simple message handler is:
on CreateBlock // The modeler added this block to a model worksheet
{
checkUsed = 1; // Static variable declared at top of the code
myNumber = 1; //Initial setting for dialog item
}
The statements in this message handler are executed when the block is added to the model
worksheet and thus receives the “CreateBlock” message from the ExtendSim application.
The variable “checkUsed” is a static variable for the block, defined at the top of the code. The
variable “myNumber” is the name of a parameter dialog item in the block’s dialog. This state-
ment initializes the parameter to 1 when the block is created (placed in the model).
Messages and message handlers are not supported in equation-based blocks. See the table on
page 31 for additional differences when using equation blocks.
Overriding message handlers
Message handlers can be overridden by being re-declared any number of times below the first
declaration. In this case, the code that is executed is the final version of the message handler. In
the block’s Script tab the earlier versions of the message handler will be colored brown to show
that they have been overridden.
Overriding is useful in that include files can have basic forms of functions and message han-
dlers which can be re-declared and overridden in the main block code. See “Include files” on
page 81.
76 IDE
System variables

You can declare local variables at the beginning of a message handler. However, you should not
have a global and a local variable with the same name. The local variable is temporary and
loses its value when the message handler is exited. Also, within each message handler, local
variables can override static variables. (If a local variable is defined with the same name as a
static variable, any references to that name within that routine or message handler will change
or reference the local variable, and the static variable will not be modified.)
For more information about message handlers, see:
• “Using message handlers” on page 109
• The list of message handlers starting on page 214
System variables
System variables give you information about the state of the simulation. You can read or write
to these variables, but you should be careful when writing to any of them.
The list of system variables starts on page 210.
Global variables
IDE

There are two types of global variables:


• General use global variables have a name that starts with “global”. They can be used any
way you want.
• Reserved global variables start with the word “SysGlobal”. These system globals are con-
trolled by the libraries that are included with ExtendSim and are reserved for use with those
libraries.
The list of global variables starts on page 211.
Conditional compilation
ModL supports several preprocessor directives to bracket ModL code. This allows specific
parts of the code to be compiled depending on circumstances. For more information, see “Con-
ditional compilation” on page 82.
Integrated Development
Environment (IDE)

Programming Tools
Features and capabilities you can use
as you program in ModL

“In baiting a mousetrap with cheese,


always leave room for the mouse.”
— Hector Hugh Munro
78 IDE
Script Editor

Writing ModL code takes much of the same talents as writing C/C++ programs. However,
ExtendSim provides tools to help make writing block code easier and safer, as discussed in this
chapter.
Script Editor
ExtendSim has an internal, integrated script (source code) editor for creating and debugging
source code.
Syntax styling
Syntax styling gives visual cues about the structure and state of a block’s code, making it easier
to follow the logic.
See the command Edit > Options > Script tab for the following:
• Colorization by syntax, as
shown to the right. The
colors can be customized
using the Change button.
IDE

• A Reset Defaults button.


• The ability to specify the
font and font size for the
text in the Script tab.
☞ When the block’s Script tab is the active window, use Alt + O to open the Script tab shown
above.
Syntax highlighting
• Smart highlighting. Selecting or double-clicking a string causes each instance of that string
in that window to be highlighted in green. (To find all the instances of a string in other win-
dows or files, see “Find in Files tab” on page 80.
• Brace matching. This feature highlights
matching sets of braces (square brackets,
curly brackets, or parentheses) to give imme-
diate feedback on misplaced brackets or
open-ended code segments. Click the cursor
to the right of an opening or closing brace
and it, as well as the corresponding brace,
will be highlighted in cyan.
• Matching #ifdef, #endif, and #else. Click on
the #ifdef line and it will highlight the closest
matching #endif or #else in cyan.
• Show end of line. The script editor places invisible characters at the end of each line. If this
option is selected in the Edit > Options > Script tab, those characters are made visible.
• Show white space. The script editor places invisible characters wherever there is a tab or
space. If this option is selected in the Edit > Options > Script tab, those tab and space charac-
ters are made visible.
Programming Tools 79
Script Editor

• Show indentation guides. This option is selected by default in the Edit > Options > Script
tab. It causes vertical lines to be shown in the Script tab’s margin, indicating the tab indenta-
tion of the code. This is useful for seeing if you’ve indented the code correctly, especially for
long indented sections of code.
• Code folding. Click on a code folding marker in the Script tab’s left margin to selectively
hide and display sections of the code.
• Auto indentation. Entering a return at the end of a line takes you to the same indentation
level right below that line. Tab or backspace to change the indentation as wanted.
• Line numbers. Each line in the code is automatically assigned a number in the left margin of
the Script tab. Use the Go To Line button in the Script tab (or the menu command Develop >
Go To Line) to find a specified line.

Code completion and call tips


By reducing typos and other common mistakes,

IDE
code completion speeds up the coding process.
When you type the first letters for a ModL function
or message handler in the block’s Script tab, code
completion pops up a window with a list of func-
tions that start with those letters. Scroll through the
list and double-click to select the desired function.
Once the function has been placed in the script,
type an open parenthesis “(” immediately follow-
ing it. This causes the parenthesis to turn red and
call tips to display the function’s arguments as
shown here. The first argument will be bolded.
When you enter it, the parenthesis will turn black. As you enter each argument, subsequent
arguments get bolded until all are entered.
☞ The opening parenthesis will stay black until you’ve entered all the arguments and followed
them with a closing parenthesis. At that point both parentheses will turn cyan.
Customizing code completion
Code completion and call tips are customizable. All the ModL functions and message handlers
are listed in the application.ini file located in the ExtendSim/Extensions/CodeCompletion
folder. The script editor looks to this text file for the code completion feature.
If you define your own functions or includes and want them to be available for code comple-
tion, create a new text file that follows the format of the application.ini file. Append the “.ini”
extension on the file, then place that new file within the CodeCompletion folder.
☞ Do not change the application.ini file; instead, create a new file. Otherwise, your custom
entries will be overwritten when ExtendSim is updated.
80 IDE
Script Editor

Search and replace


If the cursor is in the
Script or Help tab, the
Edit > Find command
opens the Find String dia-
log for searching and
replacing.
☞ The “Wrap around”
option is not available
when searching the Help
tab.
Use the dialog’s Find tab to find a string within the selected window. Or use its Replace tab to
replace one string with another within that window.
☞ By default the Find String dialog only searches within the window that has the cursor. For more
options, see the Find in Files tab, below.
IDE

Find in Files tab


Use the Find String dialog’s Find in Files tab to search through multiple files at once. The
options are to search the entire Includes folder, the source file folder, or only through includes
used in the block.
This process will find all instances of the searched for string, listing them at the bottom of the
dialog. To open a file to the location of the searched string, double-click its name.
Regular expressions
In addition to the normal search options such as matching case, the Find and Replace tabs
allow you to search regular expressions within the Script tab. This is a sequence of characters
that define a search pattern, such as searching for two spaces but only if they occur directly
after a period and before an upper case letter.
☞ The regular expressions search option is not available within a block’s Help tab nor within a
database table.
Regular expressions are useful in many contexts:
• Validating that a substring meets some criteria, e.g. is an integer or contains no whitespace.
• Advanced search capabilities based on a pattern. For example, match one of the words mail,
letter or correspondence, but none of the words email, mailman, mailer, letterbox, etc.
• Replace all occurrences of a substring with a different substring, e.g., replace all occurrences
of & with &amp; except where the & is already followed by an amp.
For more information, we suggest Mastering Regular Expressions by Friedl.
Enter Selections command
The Edit > Enter Selection command provides an easy method for finding the next instance of
some text that is in the code. Selecting the text before giving the Enter Selection command
causes the selected text to be placed in the Search for box when you give the Edit > Find com-
mand.
☞ Alternatively, use smart highlighting— select or double-click a function or message handler in
the Script tab, and the script editor will highlight each instance that is in the code.
Programming Tools 81
Debugging and profiling

Miscellaneous script editing features


• The Zoom In button in the Edit toolbar temporarily enlarges the Script pane. Use the Zoom
Normal button to return to the default. Note that font size for the script can be permanently
enlarged in the Edit > Options > Script tab.
• The Script tab’s Functions popup takes you to the first line that uses the selected function or
message handler. It also opens the include file if the function or message handler is used in
an include.
• The Go To Line button in the Script tab (or the Develop > Go To Line menu command)
causes the Script tab to scroll to that line number.
• To use the Develop > Go To Function/Message Handler command, select the name of the
function or message handler in the code, then give the command. This is equivalent to hold-
ing down the Alt (Windows) or Option (Mac OS) key while double clicking the function or
message handler name, or right-clicking on the function or message handler name.
• The Develop menu’s Shift Selected Code Left and Shift Selected Code Right commands let

IDE
you change the tabbed indentation on lines in ModL code. For example, if you copy lines
from another block’s code that are at a different indentation level, select the lines and use the
appropriate command to move them to the correct level.
• You can copy names from the Message pane of a block’s structure window for use in the
Script or Help tabs by right-clicking on the name and selecting Copy.
• The text on icons and the Help text can have character formatting. Select the text and give
commands from the Text toolbar. You can also specify a color for the text from the Graphics
toolbar’s Fill Color and Border Color tools.
Debugging and profiling
ExtendSim has a built-in source-code debugger, other debugging tools, and a profiling capabil-
ity that helps to locate code errors or inefficiencies. For more information, see:
• The Debugging Models chapter of the User Reference.
• “Source Code Debugger” on page 192, which works with the code of equation-based blocks
as well as with the blocks you build.
• “Debugging block code without the Source Code Debugger” on page 191, which discusses
how to use ExtendSim functions to do some debugging.
• “Profiling” on page 190. Profiling generates a text file that shows the percentage of time
individual blocks execute during a simulation, indicating if any of your custom blocks need
optimization.
Include files
Include files are standard header files. ExtendSim allows you to use include files in ModL
code; they can contain all ModL commands such as definitions, assignments, and functions.
They can also contain user-defined functions and predefined constants; the functions and con-
stants are accessible by any block that includes that file, including an equation-based block.
Like ModL in general, include files allow for the overriding of functions and message handlers
and can contain preprocessor statements for conditional compilation. Include files contain
user-defined functions and predefined constants; the functions and constants are accessible by
any block that includes that file.
82 IDE
Conditional compilation

Using include files simplifies programming tasks that are repeated in multiple blocks, such as a
library of blocks that use similar variable definitions and functions.
☞ As discussed on page 72, unless they are in an include file, user-defined functions are local to
the block in which they are defined.
Creating an include file
To start a new include file, choose the command Develop > New Include File. This opens an
untitled include file window.
Type the statements you want in this window and choose the File > Save Include File As com-
mand. This saves the include file into the ExtendSim\Extensions\Includes folder.
Naming conventions
For all platforms, the include file’s name must end with “.h” (as for standard C include files)
and the file must be either in, or in a subfolder within, the Extensions/Includes folder that
resides in the same folder as ExtendSim.
Referencing in a block
IDE

To reference an include file from a block’s code, enter a line in the code in the format:
#include "filename.h" (or #include "subfolder\filename.h")
or
#include <filename.h> (or #include <subfolder\filename.h>)
For example, if the name of the include file is “New_Defs,” you would use the command:
#include "New_Defs.h"
You can have as many include files as you wish, as long as all of them reside in the Includes
folder within the Extensions folder.
For an example of how include files are useful, see the Data Import Export block (Value
library) which uses an include file named ADO_DBFunctions. The ModL-coded ADO func-
tions for that include file are described on page 405.
☞ Include files are also called header files because they are usually included at the top or head of
the file. This is the source of their .h extension.
Conditional compilation
With conditional compilation, segments of code are compiled only if certain conditions are
present. Preprocessor directives are used to bracket code segments, causing parts of the code to
be compiled only if a particular symbol has been defined.
A symbol can be any kind of variable, function name, dialog item name, or constant. As seen
below some preprocessor symbols have been pre-defined. You can also define your own sym-
bols using #define, as discussed below.
Preprocessor directives
ModL supports several preprocessor directives to bracket the ModL code that you want condi-
tionally compiled:
• #ifdef symbol. If the symbol is defined, compile the code following the #ifdef until you get
to a #else or a #endif.
Programming Tools 83
External source code control

• #ifndef symbol. If the symbol is not defined, compile the code following the #ifdef until you
get to a #else or a #endif.
• #endif. Marks the end of the current preprocessor directive.
• #else. Used with #ifdef or #ifndef to give an alternative set of code to be compiled.
• #define symbol. Used to define your own symbols when you need to change your code based
on the existence of that new definition, for example within an include file. After defining a
new symbol, you can use it in the #ifdef and #ifndef directives. The syntax of the #define is:
#define myNewSymbol // define a new symbol

Pre-defined preprocessor symbols


The following preprocessor symbols have been defined in the compiler:
• Compiled_Debug. Defined only if a block has debugging code on (Develop > Set Break-
points and Add Debugging Code). It is only in release 10 and later.

IDE
• ExtendSim_10. This symbol is defined only if the application is release 10 or later.
• Platform_Windows_Defined_Symbol.
• Platform_Macintosh_Defined_Symbol

Examples
For example, you can create an include file that has code to modify a dialog item. But if that
dialog item isn’t used in a particular block, the code will be ignored by the preprocessor direc-
tives.
The following is an include file generalized for different blocks.
...
void AFunction(real anArgument)
{
...
#ifdef myDialogItem // Only if myDialogItem is present
myDialogItem = anArgument; // display result in the dialog
#endif
}
A common situation is to use #ifdef to compile a message handler only if a dialog variable
exists. For example, an include file may be used by many different blocks, only some of which
have the dialog variable MyValue_prm. To prevent the compiler from giving an error message
when a block does not include the dialog variable, add the following to the include file:
#ifdef MyValue_prm
On MyValue_prm
{
//message handler for dialog variable
}
#endif
External source code control
ExtendSim supports a mechanism for saving the source code of individual blocks or libraries
of blocks as external files. This external source code feature is useful for situations where mul-
tiple developers work on the code of blocks and/or libraries at the same time.
84 IDE
External source code control

Normally the code of blocks is saved in the library file, along with the blocks’ dialog item defi-
nitions and icons. When blocks or libraries are recompiled with the external source code option
turned on, the library file does not contain the master source code. Instead, the source code is
saved in a separate subfolder inside the Libraries folder. It can then be used with a separate
source code control or management application.
Externalizing source code for a block
Open the block’s structure and go to the Script tab
Choose the command Develop > External Source Code
Close the block’s structure window
In the dialog that appears, choose Save, compile if needed
This causes the block to be recompiled with its source code in an external file.
☞ If source code has been externalized, the green initials CM (for code management) will be dis-
played on the block’s icon in the library window.
IDE

Restoring the block’s code to its structure


Open the block’s structure and go to the Script tab
Unselect the command Develop > External Source Code
Close the block’s structure window
Save and compile the block
Externalizing source code for an entire library
Give the command Library > Library Tools > Add External Code to Libraries
In the dialog, select the libraries you want to have external source code
Click Add External Code
This recompiles the library and causes block source code to be placed in an external file.
☞ In the library’s Library Window, the green initials CM (for code management) will be dis-
played to the right of each block’s icon.
Restoring the source code to the library file
Open the Library Window for the desired library
Give the command Library > Tools > Remove External Code in Open Library Windows
The consequences of saving the code externally
Using the external code option for a block will:
• Automatically create a folder named “Source” within the Libraries folder, if the Source
folder does not already exist.
• Place a folder with the name of the library inside that Source folder, if that library folder
does not already exist.
• Create a source code text file for each block that has been recompiled with external source
code and places it in the library name folder. Each file will be named with the block name
and end with a .cm extension.
Programming Tools 85
Extensions

• Cause the green text CM (for “code management”) to appear on the icons in the library win-
dow, for each block that has been recompiled with external source code.
• Create a backup file, with the extension .ck, each time the block is recompiled.

Using the external source code with code management software


The primary reason for using the external source code option is in conjunction with a separate
source code control or management software. This allows multiple people to work on the code
of the blocks at the same time. For example, Subversion is an open source version-control sys-
tem that is available for download from the Web. The basic structure would be a situation
where Subversion or some other source code control software would maintain an archive on a
server and synchronize the source folders on each modeler’s machine with that central archive.
Because the source code for each block is saved in a separate .cm file, which is just a text file,
the source code control software can maintain the file and synchronize any changes made by
the modelers with what is in the central archive.

IDE
Cautions when using the external source code feature
Unlike block code, block dialogs, icons, and help text are not editable by multiple developers at
the same time.
Managing non-code parts of blocks
With external source code turned on, the source code for each block is saved as a text file. This
facilitates the management of block code by multiple developers using source code control
software. However, the block dialogs, icons, and help text are not saved in the external files.
Instead, they are saved in the original library file.
When changes need to be made to block dialogs, icons, or help text, the library should be
“locked” using the source code control software. That way, no one else can modify those parts
of the block while they are being changed. After the changes have been made, unlocking the
library releases the blocks so other developers can work on them.
Sharing libraries with others
When you have recompiled a library with the external code option, you need to be careful
about how you manage and share that library. For example, if you give the library to someone
else without giving them the source code files, they will receive warning messages when open-
ing the structures of the blocks. Before giving the library to another person, recompile the
library with the external source code option turned off.
Extensions
Extensions are files of various types, such as text, sound, image files, or DLLs. When you
installed ExtendSim, you also installed an Extensions folder in the same folder or directory as
the ExtendSim program. The Extensions folder contains various files stored in subfolders, such
as DLLs, Includes, and Pictures. In addition to the files shipped with ExtendSim, you can add
your own extension files to the Extensions folder.
☞ Extensions should be stored in the appropriate subfolder. If there is no subfolder for the type of
extension you are adding, put it at the top level of the Extensions folder.
Supported file types
ExtendSim supports the following types of files:
• Text files, which are used for includes and code completion purposes
86 IDE
DLLs

• DLLs
• WAV files
• Various kinds of image files
Macintosh resource files converted using the ExtendSim MacWin converter utility are sup-
ported as pictures for backwards compatibility with earlier versions of ExtendSim. The differ-
ent kinds of extensions are discussed individually later in this chapter.
Naming
Except for DLLs, the name referenced by the ModL functions will be the file name. For DLLs,
as described below, the name referenced will be the function name of the particular function
you are trying to call from the DLL.
For more information, see
• DLLs, below.
• “Shared libraries” on page 88
IDE

• “Sounds” on page 89
• “Picture and movie files” on page 89
• “Customizing code completion” on page 79
DLLs
As discussed in “Accessing code from other languages” on page 42, ExtendSim provides sets
of functions that allow you to call code segments written in a language other than ModL from
within a block’s code. This is handy if you want to access existing functions written in another
language or solve problems that are difficult in ModL. On Windows, these functions are iden-
tified as DLLs or dynamic-link libraries. (See “Shared libraries” on page 88 for how code from
other languages are accessed on Macintosh operating systems.)
For ExtendSim 10 or later, the DLL must be built for 64-bit execution
Overview
DLLs are libraries of code written and compiled in any language. Their standardized interface
provides a method for linking between ExtendSim and languages other than ModL. In order to
access these code libraries, they must be stored in the ExtendSim Extensions directory, dis-
cussed above.
The ExtendSim DLL functions allow you to call DLL code libraries from within a block's code
and use that code to perform operations. For example, you can use a DLL to calculate some
function, perform a task, or even access Windows API calls. DLLs can also be used to access
external devices, or to solve problems that might be difficult or impossible to solve in ModL.
DLL interface
The DLL functions allow you to access existing Windows DLLs. Because they have variable
argument lists, these functions allow you to call almost any existing DLL. This interface
includes the following functions: DLLLongCFunction, DLLDoubleCFunction, DLLBoolC-
Function, DLLVoidCFunction, DLLLongPascalFunction, DLLDoublePascalFunction, DLL-
BoolPascalFunction, DLLVoidPascalFunction, DLLMakeProcInstance.
See the DLL functions on page 265 for more information about this interface.
Programming Tools 87
DLLs

Turning code into a DLL


Taking existing code and turning it into an DLL involves the following:
Write or edit the DLL code using a Windows compiler that is capable of compiling DLLs.
For ExtendSim 10 or later, the DLL must be built for 64-bit execution.
Modify the DLL code by adding the DLL calling interface.
After compiling the code, you will have a DLL file. Place this file in the ExtendSim Exten-
sions\DLLs directory.
Restart ExtendSim. This will allow you to call the external code using the DLL functions in
your block code.
You should also make note of the following:
• If there is any possibility that your blocks will be used cross-platform (on both Windows and
Mac OS systems), the code in those blocks should include checks to allow for the differ-
ences between platforms. For more information, see “Cross-Platform Considerations” on

IDE
page 419.

• In the argument list, variables passed from the ModL code to a DLL are passed by value.

• Reals are 8-byte double precision


• Integers are 4-byte long integers (converted to 8-byte for the DLL)
• Pointertypes are 8-byte integers
• Strings and arrays are passed to DLLs as 8-byte pointers to data that has been allocated by
ExtendSim. Modifications to that data will affect the original information in ExtendSim.

• As discussed above, arrays that are passed to a DLL come through as pointers to the original
data in ExtendSim. Accessing and modifying the data is fine, but you should not try to resize
the pointer. If you do, ExtendSim will not be able to access the data and will probably crash.

• Strings are passed to DLLs from ModL as Pascal strings, not C strings. This means that the
string is preceded by a size byte and is not terminated by a zero. For example, if you pass a
string to a DLL, the DLL will get a pointer to 256 bytes of data in which the first byte con-
tains the number of characters in the string. To convert strings to C strings and back again,
see the DLLCtoPString and DLLPtoCString functions in the function list “DLLs and Shared
Libraries” on page 265.

• The most common problem associated with building and using a DLL is making sure that
the names of the routines that you want to call are exported and that they are exported with-
out Name Mangling or Name Decoration. Name Mangling is an option for how names are
exported from a DLL; it adds information about the arguments to the exported name.

☞ When building a DLL for use with ExtendSim, the Name Mangling option should be off.
DLL example
The following code calls a DLL that performs the same function as the ModL code (shown on
page 51) that you used to build the Miles block. (Note that you could accomplish the same
result, but in a slightly different manner, using a Shared Library for the Mac OS.)
88 IDE
Shared libraries

// Declare constants and static variables here.


long proc;
on Calculate_btn // Display the values
{
proc = DLLMakeProcInstance("convert");
if (proc > 0) // Check if proc>0 before you make the call
OutNum_prm = DLLDoubleCFunction(proc, inNum_prm,
kilometers_rbtn, yards_rbtn, feet_rbtn, inches_rbtn);
else
Beep(); // Couldn’t find the DLL function "convert"
}
// This message occurs for each step in the simulation.
on simulate
{
InNum_prm = MilesIn;/* Display the value input by setting the dialog
variable “InNum” to the input connector value */
proc = DLLMakeProcInstance("convert");
if (proc > 0)// Check if proc>0 before you make the call
IDE

unitsOut = DLLDoubleCFunction(proc, inNum_prm,


kilometers_rbtn, yards_rbtn, feet_rbtn, inches_rbtn);
else
Beep(); // Couldn’t find the DLL function "convert"
OutNum_prm = UnitsOut; /* Display the value output by setting the
dialog variable “OutNum” to the output connector value */
}
The code of the 64 bit DLL, written in C++, is:
double _export _fastCall convert(double x, long kilometers, long
yards, long feet, long inches)
{
if (kilometers)
return(x * 1.609334);
else if (yards)
return(x * 1760.0);
else if (feet)
return(x * 5280.0);
else if (inches)
return(x * 63360.0);
}
☞ At some point the ExtendSim/Examples/How To/Developer Tips/DLLs folder will have addi-
tional examples of writing a DLL in C and calling it from within an ExtendSim block.
Shared libraries
DLLs, described above, are a Windows construct. On the Macintosh, an equivalent functional-
ity can be found in Shared Libraries.
All of the DLL functions also support calling Shared Libraries on the Macintosh OS. And most
of the discussion about DLLs applies to Shared Libraries. Some differences and notes are:
• As it does on Windows, DLLMakeProcInstance will first attempt to load the library file
before trying to find the procedure within the library file. The loading of the library is imple-
mented internally with a call to the API function “dlopen”. The location of the procedure
name within the library is done through a call to “dlsym”.
Programming Tools 89
Sounds

• Shared Libraries on the Macintosh will have a .dylib extension.


• Once you have created a Shared Library that you want to use with ExtendSim, place it into
the DLLS folder within the Extensions folder.
Sounds
Depending on your operating system, ExtendSim has access to several sounds. You can play
sounds using the Notify block (Value library) or by calling the PlaySound function in the code
of a block.
There are two sources of sounds that ExtendSim can access:
• ExtendSim contains a “click” sound extension.
• You can also use .WAV files created by other applications or obtained from user groups.

You must copy the sound file into the Extensions directory, as discussed on page 85.
Picture and movie files

IDE
Pictures and movies are used for specialized 2D animation. See the functions in “2D Anima-
tion” on page 270, for more detail. To see an example of using pictures and movies for anima-
tion, see “Showing a picture on an icon” on page 132.
Naming conventions and limitations for pictures
You can have any number of pictures in the Extensions folder. Pictures with names that start
with a “@” will not show up in the block’s animation tab popup menu. This prevents the ani-
mation tab menus from being filled with other, larger types of pictures that are not suitable for
animation between blocks.
As mentioned in “Extensions” on page 85, pictures must be stored as a file in the Pictures sub-
folder of the Extensions folder. The AnimationPicture function will recognize most picture for-
mats.
Protecting libraries
ExtendSim normally keeps both the ModL code and compiled code in the block; if you remove
the ModL code, the compiled code is still there. When you build custom blocks and do not
want others to have access to your block code, you can protect your libraries by removing the
ModL code of the blocks. When a modeler attempts to edit a protected block, ExtendSim dis-
plays a dialog message that the block is protected and cannot be opened. The structure of the
protected block is never shown.
A protected library can be used the same as any other library except that you cannot view or
alter the ModL code. This means that someone using the library has all the functionality of the
blocks in that library but no ability to see how the blocks work. This is a convenient way to
hide proprietary programming while still giving modelers full access to the power of the block.
Protecting the ModL code has the added benefit of preventing someone from changing the icon
or the block’s help text.
☞ After a library is protected, you can never un-protect it. Thus it is good practice to make a copy
of the original and store it on some other media.
The steps for protecting a library are:
Select the command Library > Library Tools > Protect Library.
90 IDE
Protecting libraries

When you give the Protect Library command, ExtendSim warns you that protecting a
library’s ModL code will permanently and irrevocably prevent access to block code.
In the dialog that appears, select and open the library you want to protect.
The Create New Library dialog allows you to rename the library. However, since models
will be expecting the original library name, it is suggested that you leave the library name as
is. The protected library will have the extension “.lbrpr” rather than the normal “.lbr”, so
your original library won’t be overwritten.
When the library is saved, ExtendSim protects the library’s ModL code by cutting it from
the block.
Any copies you make of this protected library will also be protected. You can easily show that
a library is protected by opening it and attempting to edit the structure of a block in the library.
IDE
Integrated Development
Environment (IDE)

Programming Techniques
Procedures and suggestions for how to
create and modify ModL code

“In baiting a mousetrap with cheese,


always leave room for the mouse.”
— Hector Hugh Munro
92 IDE
Data source indexing and organization

This chapter focuses on using ModL functions to create custom blocks and simulation effects
in ExtendSim.
Data source indexing and organization
Communicating between various types of data sources has been greatly assisted by standard-
ized technologies, such as the ability of diverse applications to exchange data through a stan-
dard text file format. However, it is important to keep in mind that each standard has its own
conventions. This can cause data-confusion when transferring data from one type of source to
another.
Transferring data between a data table and a spreadsheet
ExtendSim data tables have zero-based indexes and are organized by row and column. Spread-
sheets are also organized by row and column, but they are one-based. When transferring data
from an ExtendSim data table to an Excel worksheet, the row and column numbers for Excel
must both be increased by 1 compared to their location in the ExtendSim data table.
☞ The first row in an ExtendSim data table could be labeled as 0 or as 1. However, no matter how
the row is labeled, the index for that first row is still 0.
IDE

Transferring data between a spreadsheet and a database


Databases are one-based like spreadsheets, but are organized by fields and records (equivalent
to columns and rows) rather than being organized by the spreadsheet convention of rows and
columns.
Indexing and organization
The following table lists indexing and organization conventions for different data source types.

Data Source Type Indexing How organized


ExtendSim Data Tables 0-based Row/Column
Spreadsheets 1-based Row/Column
ExtendSim Databases 1-based Column/Row
(Field/Record)
External Databases 1-based Column/Row
(Field/Record)
Arrays 0-based Row/Column
Text Files N/A Row/Column

Equation block programs


The equation-based blocks are: Equation, Optimizer, Query Equation (Value library); Equa-
tion(I), Queue Equation, Query Equation(I) (Item library); and Buttons (Utilities library). The
ExtendSim User Reference discusses how to use the equation-based blocks and how to debug
them.
Equation blocks can handle more than just the definition of an equation—they are capable of
compiling and executing complex ModL programming logic. Think of the equation blocks as a
method for including small programs on the fly without having to create a new block.
Programming Techniques 93
Working with dialogs

You can also use the functions described in “Equations” on page 238 to create your own blocks
that take in equations and even allow for debugging. For example, you might want to do this
when building scientific or engineering blocks and can’t predict ahead of time what formulas
you will need.
☞ To allow larger equations or programs into a block’s dialog, see “Equations” on page 238 for a
list of equation functions that support up to 32000 characters in a dialog item. Also, see the
Equation block (Value library) for an example of using a Dynamic text item and a syntax color-
ing window to edit a user-entered equation.
Equation-based blocks can call any of the ExtendSim built-in functions. However, user-defined
functions and procedures cannot be defined directly in an equation-based block; they must be
defined in an include file. For a list of the other differences between equation-based blocks and
the custom blocks you might create, see “Differences between equation blocks and pro-
grammed blocks” on page 31.
Working with dialogs

IDE
With a bit of creativity, you can make dialogs that provide a great deal of information about the
state of a simulation or that help you debug models-in-progress.
In addition to the following information, modifying and creating dialogs, as well as ModL code
interaction with dialogs, is described in more detail in “Accessing dialog items from a block’s
code” on page 35.
Changing text in dialogs
The Miles block example on page 44 showed the usefulness of keeping a dialog open and
watching the numbers in the entry boxes change as the simulation progresses. Dialogs can also
be used for displaying text or messages that might change during the simulation.
Changing text as the simulation runs
Changing the text displayed in a dialog is often more useful than displaying alerts since alerts
stop the simulation until the modeler clicks one of their buttons.
For example, assume that:
• You are modeling a factory that has three shifts, where the name of the shift (day, night,
swing) changes depending on the current time.
• You have a block with a static or editable entry box named Shift that you want to modify.
• Simulation times are in minutes.
You could display the time in the Shift dialog item as a number, but then you have to convert
the time to the shift name in your head:
Shift = (CurrentTime / 60) mod 24;
Instead, you could convert the time in the block’s code and display text in the dialog:
...
string name[2];
name[0] = "Day"; name[1] = "Night"; name[2] = "Swing";
...
Shift = name[((CurrentTime / 60) mod 24) / 8];
94 IDE
Working with dialogs

Changing text in response to a user’s action


ModL lets you change the text and titles of dialog items at any time. This allows you to decide
what to show based on what is done in the dialog. An example of this is the Random Number
block (Value library), which displays different parameter labels depending on the statistical
distribution that is selected.
When a control item (radio button, switch, meter, etc.) is clicked, two things happen:
• The value of the radio button’s variable name is set to TRUE; switches and checkboxes are
toggled from FALSE to TRUE and vice versa; and sliders are changed in value. Plain but-
tons don’t have a value but their titles can be changed.
• ExtendSim sends a message to any message handler with the control item name. This allows
the ModL code to take a special action.

For example, assume that you want to show values as either octanes (for gasoline) or cetanes
(for diesel fuel). There are two radio buttons that let you decide which unit to show:
// ShowOctaneValues radio button was clicked
IDE

on ShowOctaneValues
{
// set static text label above data table
SetDataTableLabels(“dataTable”, “Octane Values”);

for (row=0; row<numRows; row++)


for (col=0; col<numColumns; col++)
dataTable[row][col] = octaneVals[row][col];
}
// ShowCetaneValues radio button was clicked
on ShowCetaneValues
{
// set static text label above data table
SetDataTableLabels(“dataTable”, “Cetane Values”);

for (row=0; row<numRows; row++)


for (col=0; col<numColumns; col++)
dataTable[row][col] = cetaneVals[row][col];
}
// When the dialog is opened by the modeler
on DialogOpen
{
// Static labels are not "remembered" when dialog is closed
// so, when the modeler opens the dialog, restore the titles here

if (ShowCetaneValues) // ShowCetaneValues was TRUE


SetDataTableLabels(“dataTable”, “Cetane Values”);// restore
// title
else // else ShowOctaneValues TRUE
SetDataTableLabels(“dataTable”, “Octane Values”); // restore
// title
}
See also “Buttons” on page 38 and “Static text (label)” on page 39.
Programming Techniques 95
Working with dialogs

☞ If the octane and cetane arrays were dynamic, the DynamicDataTable function could be used to
switch the data table between the two dynamic arrays. This would execute more quickly and
require less code.
Hiding/showing dialog items
As discussed on page 18, by default dialog items are visible in at least one tab; they may be
hidden by unchecking the Visible checkbox. Dialog items where Visible is unchecked are
shown in red.
You can also choose to dynamically show and hide dialog items depending on a user action or
on the value of other dialog items. You do this using functions (such as HideDialogItem) in the
list that starts on page 305. When the dialog is opened by the modeler, you use a DialogOpen
message handler to show and hide certain items depending on the values of the controlling
items.
For example, the Decision block (Value library) has a parameter field for Relax that appears if
Use Hysteresis is checked. For more complex dialogs, see “Moving dialog items”.

IDE
In some cases you may want a dialog item to not be visible ever. This is common when you
don’t want to use a dialog item anymore, but shouldn’t delete it because the block is already
used in models. In this case, just uncheck the Visible checkbox.
Use caution when deleting a dialog item if the block is being used in any model. Deleting the
item could disrupt the order of the dialog’s data. The data will have to be reentered for each
instance of that block in all models that use it. Instead of deleting the dialog item from a block
used in a model, hide it by unchecking the Visible checkbox in its properties window. (Since
they don’t store data, text frames and static text labels may be safely deleted.)
When you copy or duplicate dialog items
You can copy/paste or duplicate dialog items within a tab, from one tab to different tab within
the same block, or from one block to another. To do this, select the dialog item, then give the
Duplicate (or Copy and Paste) commands.
When you duplicate or copy/paste a dialog item, its Label stays the same but a number is
appended to the original dialog item’s Name. Unless you change it, the new name (with the
appended number), is how the copy of the dialog item will be referenced in ModL code. The
name and Label can be changed by double-clicking the dialog item to access its definition.
Moving dialog items
• To manually move a dialog item within a dialog tab:
• Either select and drag it to the new location within the same window or tab
• Or, double-click it and change its X and Y coordinates in the properties window
• To manually move a dialog item from one tab in the Dialog tab to another, first select the
item, then use the Develop > Move Selected Items to Tab command. Then select the tab to
move the item to.
• You can also write code that moves a dialog item depending on a block’s settings. This is
often easier and more organized than placing all the dialog items on top of each other and
then hiding and showing them depending on the setting. For instance, the parameter fields in
the Random Number block (Value library) move based on which distribution the user
96 IDE
Working with dialogs

selects. The DIPosition functions, as well as DIMoveTo and DIMoveBy, can be used to
move dialog items. These functions are included in the list that starts on page 305.

Resizing dialog items


Many dialog items can be resized. Do this either through code or in the Dialog tab:
• Either select the item and drag one of its handles (the squares in the corners of the item)
• Or, double-click the item and change its W (width) and H (height) coordinates
• Or, through the code using the function DIPositionSet.

Changing the title of a radio button or checkbox


The function DITitleSet is useful for setting the title of a radio button or checkbox. ModL code
can thus change the title, and meaning, of the control at any time.
Changing and reading parameters globally from a block
The GetDialogVariable and SetDialogVariable functions can be used to read and set dialog
items by name for any block in the model from within one block. When you combine this with
IDE

the ability to read block names and labels, this feature can be used to build a block that can
globally control the model, gather statistics on a class of blocks, or change parameters within
all blocks that have a specified commonality.
☞ In addition to the GetDialogVariable function, see the GetStaticVariable function.
For example, as seen in the Get-Set Dialog Variable model located at Documents/ExtendSim/
Examples/Developer Tips, you can build a block that can cause specified Activity blocks (i.e.
Activity blocks whose labels include a specific wording, such as ABC) to double their entered
delay value. Below is sample code that does this:
Programming Techniques 97
Remote access to dialog variables

on doAllButton // modeler clicked button to change the blocks


{
integer nBlocks, i;
real value;
string name, label, paramStr;

nBlocks = NumBlocks();
for (i=0; i<nBlocks; i++) // all the blocks in the model
{
name = BlockName(i); // get the name of the block
label = GetBlockLabel(i); // get the block’s label

// look for Activity at beginning (with no case sensitivity)


// AND look for ABC anywhere in label
if (StrFind(name, “Activity”, FALSE, FALSE) == 0 &&
StrFind(label, “ABC”, FALSE, FALSE) >= 0)
{

IDE
// Found them. now read the parameter for the delay
paramStr = GetDialogVariable(i, “waitDelta_prm”, 0, 0);

if (paramStr != ““) // not empty means it was found


{
value = StrToReal(paramStr);
// now set it to double value
SetDialogVariable(i, “waitDelta_prm”, value*2.0, 0, 0);
}
}
}
}
Remote access to dialog variables
Sometimes it is useful to allow a modeler to use a stand-alone block to get or set the value of a
dialog variable in a remote block. For instance, this is how modelers set model factors and get
model responses using the Scenario Manager block, discussed in the User Reference.
In ExtendSim there are three mechanisms for interfacing dialog variables between a stand-
alone block and a remote block:
1) Manually enter the remote block number’s and dialog variable name into the stand-alone
block
2) Clone-drop, using the Clone tool to drag the parameter onto the icon of the stand-alone
block
3) Shift-click a dialog parameter and select from the popup menu of available options to add
that parameter to the stand-alone block. This is especially helpful when one or more of the
blocks is within a hierarchical block.
The Find and Replace (Utilities library), Optimizer and Scenario Manager (Value library), and
the Statistics block (Report library) reference dialog variables in other blocks. And all of the
Value, Item, and Rate blocks have interfaces that support this feature. These interfaces are also
available to developers, and taking advantage of them requires only minor additions to your
custom block code.
98 IDE
Remote access to dialog variables

Custom remote blocks interfacing with a stand-alone block


The blocks in the Value, Item, and Rate library have code that allows a stand-alone block to get
or set their dialog variables; they support all 3 of the above options. Your custom block can
also take advantage of this interface, allowing a stand-alone block to interface with your
block’s variables:
• Options 1 and 2 will automatically be implemented without any modification to your blocks.
• For option 3, you need to add the following code to your custom block:
Include MouseClick v10.h
#include "MouseClick v10.h"
Add the following code
On DialogClick // called whenever the modeler clicks a dialog item
{
if(do_keydown_mouse_click())
IDE

return;
}
☞ If you have additional code in this message handler, put it after this code.
Custom stand-alone block referencing remote dialog variables
If you create a stand-alone block that will reference (get or set) remote dialog variables in other
blocks, you can implement any or all of the above methods for collecting the information from
the remote block, as discussed below. (While it is also possible to develop your own interface,
using one or more of the ExtendSim interfaces will be easier and more consistent with existing
blocks.)
Manual data entry
Implementing a manual method for referencing from the list in a custom stand-alone block
depends on your particular implementation, interface, and needs. Some blocks, such as Find
and Replace (Utilities library), only work with one remote dialog variable at a time. Other
blocks, such as Statistics (Report library), have a list of remote dialog variables. For coding
examples, look at one of those blocks.
Clone drop
Adding a clone-drop interface to a custom block requires a DragCloneToBlock message han-
dler. This is called whenever a clone is dragged to the icon of that block.
Inside of this message handler, call GetDraggedCloneList. This function requires two argu-
ments – an integer dynamic array and a string dynamic array. It returns the number of clones
(usually 1) dropped onto the block. You then use this information to reference a dialog item in
another block.
Shift-click
The shift-click feature is more complicated to implement because it requires using a reserved
database (discussed on page 112) and an include file. The reserved database (_leftClickDB)
provides the necessary information for the shift-click action. The include file (MouseClick.h)
has two functions defined in it that are required for managing the reserved database:
Programming Techniques 99
Remote access to dialog variables

1) RegisterBlockInLeftClickDB(String blockNumberDialogVariable, String staticStringVari-


ableForRemoteBlockName, String sStaticStringVariableforRowAndColumn, String pop-
upMenuLabel, integer optionNumber). Registers a block in the database of blocks that add
a popup to a shift-click action. This is called in the CreateBlock, PasteBlock and Open-
Model message handlers. See the MouseClick include file for an explanation of the argu-
ments.
2) UnRegisterBlockInLeftClickDB. Removes a block from the database of blocks that add a
popup to a shift-click action. This should be called in the DeleteBlock message handler.
Coding for Shift-click
The key to the Shift-click functionality is a hidden dialog variable in the stand-alone block.
When this dialog variable is set by the remote block, the stand-alone block receives a message
that it has been sent a reference to a dialog variable in the remote block. The name of the hid-
den dialog variable is stored in a table in the reserved database (_leftClickDB) by the Register-
BlockInLeftClickDB function.

IDE
The information sent by the remote block must be processed in the message handler for the
hidden dialog variable. This information has been set in static variables in the stand-alone
block by the remote block. The names of the static variables are set in the RegisterBlockIn-
LeftClickDB function. The information includes the block number, dialog variable name, and
database table’s row and column. These values can be found in the Dialog and Static variables
that are arguments to the RegisterBlockInLeftClickDB function.
In the following code example, the stand-alone block gets:
• The block number for the remote block in the dialog variable AddFactor_prm
• The name of the remote block's dialog variable in the static string variable DialogVarName
• The row and column of the remote dialog variable in the RowColumnDialogVar static string
variable
And the popup menu is labeled “Scenario Manager: Add Factor”. Because the Scenario Man-
ager has two options (one for adding a factor and one for adding a response), this is option 1.
On OpenModel
{
RegisterBlockInLeftClickDB( "AddFactor_prm","DialogVarName",
"RowColumnDialogVar", "Scenario Manager: Add Factor", 1);
}
On AddFactor_prm
{
// Receive message from remote block and process hidden variables
// AddFactor_prm is the block number of the remote block
// DialogVarName is the dialog variable in the remote block
// RowColumn is the row and column in the remote block
}
100 IDE
Working with connectors

Shift-click example
When the Optimizer block (Value library) is added to a model it
creates the reserved database _leftClickDB. The entries in the
database table cause options, such as Optimizer: Add Parameter,
to be added to a menu that appears when an appropriate dialog
item is Shift-clicked.
Through block code, the Shift-click action causes the selected
variable to be used in the Optimizer block. Using this type of
architecture makes it easy for developers to add their own block
options to the Shift-click menu.
Working with connectors
Most blocks have connectors. You add and change connectors using the connector tools in the
Icon Tools tool at the right of the ExtendSim toolbar.
☞ For information about connector types, options, and names, see the writeup that starts on
page 20.
IDE

Variable connectors
By default new connectors are added as a normal (single) connector. This works well for sim-
ple blocks, but often a block will need several inputs or outputs.
As discussed in “Connector options” on page 21, when you select a type of connector (Value,
Item, etc.) it is by default a normal connector. You can then change the connector to be vari-
able. Variable connectors act like a row of normal connectors, where the row can be expanded
or contracted to provide a required number of connectors. To work with variable connectors,
see the writeup on page 35 and the functions on page 303. For an example of how variable
connectors are implemented, see the Math block (Value library).
Initializing connectors
The value of a connector is used to determine whether the block is connected to another block
during the CheckData message handler, and thus cannot be changed there. All connectors are
initialized by ExtendSim to 0.0 after the CheckData message handlers are executed. To initial-
ize connectors before the simulation runs, do it within the InitSim or PostInitSim handler.
For example, to initialize a connector before the simulation runs:
On InitSim // Or use On PostInitSim
{
conOut = initialValue;
}
The blocks in the Item library initialize their connectors in the InitSim handler.
Deleting connectors or changing connector types
ExtendSim keeps an ordered list of the connectors on a block. If you delete a connector on a
block used in a model, it changes the connector order. This may cause unexpected results – the
connectors could become disconnected or connected incorrectly.
For blocks used in existing models, changing connector order could cause a problem. When
you only need to change connector types, do not delete the connector. Instead, simply select it
and click on the correct connector tool. If you have to delete a connector on a block that is used
in a model, carefully examine the block’s connections afterwards.
Programming Techniques 101
Working with arrays

Bidirectional connectors
All ExtendSim connectors are bidirectional. This is useful if you want blocks to communicate
back and forth.
For example, you may want to simulate a network or a bus in which blocks need to both send
to, and receive information from, the other members of the network. Because ExtendSim does
not allow multiple output connectors to be connected together, you could use only input con-
nectors for all the blocks in the network.
Or you may also want source and sink connections, where a source block can have its output
value changed by the sink blocks that are connected to it. This is useful in simulations where
one block’s reserves are depleted by the other blocks connected to it.
To implement these features in blocks, assign or modify the value of an input connector. This
feature makes input connectors bidirectional. When the value of an input connector is modi-
fied, all connected blocks will see this new value when they get their next Simulate message.
The concept of using an input connector for both input and output is shown in the Bidirectional

IDE
Flows model, which is located in the Documents/ExtendSim/Examples/How to/Developer
Tips folder. In that model a power station supplies energy to cities. Each city block has a single
input connector. The block code for the cities subtracts an amount from the input, called “Pow-
erIn”, with the statement:
PowerIn = PowerIn - amountUsed;
This affects the Power Station block by reducing the output power value stored in its output
connector. The power station can check its output connector value and see if it went to 0 or
became negative, signifying that its power reserves have been depleted by the towns:
if (PowerOut <= 0.0) // check the reserve power
{
// Out of power. Tell when this occurred.
UserError("Brownout occurred at time= "+CurrentTime);
abort; // Stop the simulation.
}
Working with arrays
Since you will typically use arrays to store any data which is more complex than a single vari-
able, you will probably use them fairly often. ExtendSim provides lots of features and func-
tions that use arrays, especially regarding discrete event modeling. Note that, while ModL does
not directly support arbitrary user-defined structures, it supports a rich linked list structure (see
“Array-like structures” on page 67 and “Linked lists” on page 385) and it emulates other types
of structures using arrays of arrays. You will find that working with arrays in ExtendSim is
simpler and safer than using the data structures that are available in C.
☞ As shown in the table in “Data source indexing and organization” on page 92, arrays use zero-
based indexing.
Memory usage of variables, arrays, and items
For most models, you do not need to worry about how much memory your variables take up.
You may need this information in some circumstances, especially if you are using huge arrays.
☞ There is no overhead for using arrays.
102 IDE
Working with arrays

Type Memory used


Real 8 bytes (double)
Integer 4 bytes (long)
String or Str255 256 bytes per string containing up to 255 characters
Str15 16 bytes per string containing up to 15 characters
Str31 32 bytes per string containing up to 31 characters
Str63 64 bytes per string containing up to 63 characters
Str127 128 bytes per string containing up to 127 characters

The total of all static arrays (non-dynamic arrays) and variables in a block, including any static
data tables in the block’s dialog (which are real arrays, 8 bytes per element), cannot exceed
32,767 bytes. Dynamic data tables are not included in static memory allocation. See “Block
IDE

data tables” on page 312.


When a user-defined function is called, its local arrays can have up to 32,767 bytes. The size of
dynamic arrays are not included in any of the above calculations and can have up to 2 billion
elements each.
If your arrays are small, use fixed dimension static arrays since they are easier to declare. If
your arrays are large, use dynamic arrays.
Pass by value and reference (pointers)
In C, you can pass variable arguments to functions by value or by reference (pointers). When
you pass a variable by value, the value of that variable in the outside environment is not
affected by anything that function does. When you pass by reference, however, the function
can modify the contents of the variable and those modifications are seen by the outside envi-
ronment.
In ModL, all non-array variables and single elements of arrays (such as myArray[i]) are always
passed by value and are therefore never modified. Arrays, however, are always passed by ref-
erence (such as “myArray”, with no subscripts) and therefore can have their contents changed
by a ModL or user-defined function. If you are writing user-defined functions, this feature
makes it easy to return more than one value. Simply pass an array to your user-defined func-
tion and change the values in the array. All changes you make to the array in your function can
be seen in the message handler when the function returns.
Passing arrays
Essentially, a passed array is a pointer assigned to a real variable with the PassArray function
and it is read from that real variable and converted back to an array with the GetPassedArray
function. (In ModL, pointers have more information than just the address of data, so real vari-
ables are used to hold them.) These functions are listed in “Passing arrays” on page 377. The
Passing Arrays model in the Documents/ExtendSim/Examples/How To/Developer Tips folder
illustrates how to pass, receive, and modify an array.
Passed arrays must be dynamic arrays but they can be any type (real, integer, or string). A
passed array has the same properties as an array that you use in a single block.
Programming Techniques 103
Working with arrays

☞ If you pass arrays, those arrays can only be resized or disposed of in the same block where they
were created.
You can use the SendMsgToBlock function and the BlockReceive message handler to tell the
originating block to resize the array. An example of this is the Executive block (Item library).
It is important to note that any changes made to data in a passed array affects all blocks that
reference that array, including the block that originated the array. If you want to make a change
to a passed array that is not reflected in previous blocks in the model, copy the values from the
passed array to a new array, make changes to that new array, and pass that new array. (You can
copy an array quickly with a “for” loop, as described later in this chapter.)
Passing arrays through connectors
The blocks built in this manual pass single values through their connectors. You cannot pass
arrays as easily as you can single values, but it is not difficult to add the few functions that let
you pass arrays through the connectors.
Because a connector is a real variable, you can pass arrays through connectors. To read a

IDE
passed array from a connector, use the GetPassedArray(connector, array) function. For exam-
ple, assume that you are receiving an array through the input connector called ArrayConnec-
torIn. Your message handler might look like:
real theArray[];
...
on Simulate
{
if (GetPassedArray(ArrayConnectorIn, theArray)) // is it
passed
{
. . . // Yes, use the array
}
else
{
. . . // The array did not arrive yet
// or it is not a passed array
}
. . .
}
All of the values in the passed array can now be accessed and changed by using the theArray
variable in your code.
The process for passing multidimensional arrays is exactly the same, with the exception that
you need to confirm that the fixed dimensions are the same for both the passing and receiving
blocks.
There are two different ways to pass an array to an output connector, depending on whether the
array was passed to the block or it originated in the block. If the array was passed to the block,
simply set the output connector to the same value as the input connector:
ArrayConnectorOut = ArrayConnectorIn; // pass the old pointer on
To pass an array that originated in the block, use the PassArray(array) function. You can assign
the value of this function to an output connector (or to a real variable in your ModL code that is
then assigned to an output connector). Assume that you had changed the values of theArray
104 IDE
Working with arrays

in the example above and wanted to pass them out the connector named ArrayConnectorOut.
You would use:
ArrayConnectorOut = PassArray(theArray); // pass the new pointer
If you are just passing an array through a block without looking at it, you should not use Get-
PassedArray. Simply assign the output connector to the value of the input connector, and the
real number that holds the passed array will be handled with no overhead:
ArrayConnectorOut = ArrayConnectorIn; // pass the old pointer on

Passing arrays through global variables


You can use any real variable to hold passed arrays. This means that you can pass arrays
through the global variables global0 through global19 that are available to all blocks. If you
want an array to be globally accessible, pass it to one of the global variables and use GetPasse-
dArray to interpret the global variable when you want to get at the array values. Discrete event
blocks use this technique.
Precautions when passing arrays
IDE

The GetPassedArray function needs to be called before accessing a passed array. If an array is
created at the beginning of the simulation and the size is never changed and the array is not dis-
posed of during the simulation, then GetPassedArray only needs to be called once, at the
beginning of the simulation.
☞ If you pass arrays NOT during a run, call GetPassedArray() in any message handler that uses
those arrays before accessing those arrays.
However, GetPassedArray must be called again before accessing any passed array that may
have changed in size or been disposed of. Trying to access a passed array after the creator
block has disposed of or resized it can cause a crash if the GetPassedArray function is not
called immediately before access is attempted. When you resize or dispose of an array, its
memory location may change or otherwise become invalid. A crash can occur because the
block that received the array has a pointer to a specific location in memory, and will try to
access that memory point even if it no longer is a valid array location. Calling GetPassedArray
immediately before accessing the array will relink to the correct memory address if the array
has been resized and will return a FALSE value if the array has been disposed of.
Since GetPassedArray is extremely fast (because it only links the pointer of the array), the saf-
est action is to call it and test its return value before every series of accesses to the array.
☞ The following is an example of what NOT TO DO:
Block #1
integer x[];
on checkdata
{
Makearray(x, 10); // create the array
global9 = passarray(x);
}

on endsim
{
DisposeArray(x); // dispose of the array
}
Block #2 //this is not safe!
Programming Techniques 105
Working with arrays

integer x[];
on initSim
{
GetPassedArray(global9, x);
}

on endSim //this is not safe!!!!


{
for(i = 0; I<10; I++) // This is dangerous! Is the array still
available?
x[i] = 0;
}
The above code could cause a crash if the code in Block #2 is executed later in the simulation
than Block #1. The problem occurs because Block #2 tries to access the array it thinks is in the
variable x, while the array referenced by x has actually already been disposed of by Block #1.
☞ It would be safer to use the following approach in Block #2:

IDE
integer x[];
on initSim
{
GetPassedArray(global9, x);
}

on endSim
{
if (getPassedArray(global9, x)) // This is safer. Get and test the
array first.
{
for(i = 0; I<10; I++)
x[i] = 0;
}
}
For the same reason, it is important to call the function GetArrays() (see “Functions in discrete
event blocks” on page 180) in your custom discrete event block code each time before you
access the ItemArrays.
Using passed arrays to make structures
ModL does not support structures directly, except for linked lists (see “Linked lists” on
page 385). It does, however, allow you to emulate structures using arrays of arrays. This is
safer than using pointers and structures in C.
Suppose you want to pass an array consisting of real, string, and integer values. Since arrays
can be passed to any real variable, many arrays can be passed into a real array, and that array
can be passed through a connector or global variable. The receiving block can get the passed
structure array and then get the individual passed data arrays from that array.
The following shows an example of using passed arrays to make structures.
106 IDE
Working with arrays

// This block makes a structure and passes it.


// Declare the arrays at the top of the code.
real structureArray[]; // This is the structure
string stringValues[]; // Holds the strings
real realValues[]; // Holds the reals
integer integerValues[]; // Holds the logical values

on InitSim
{
// Give the arrays a size.
MakeArray(structureArray, 3); // Holds reals, strings, long.
MakeArray(stringValues, 10); // 10 elements for each array
MakeArray(integerValues, 10);
MakeArray(realValues, 10);

// Pass the arrays to the real structureArray.


// This needs to be done only once each simulation run.
structureArray[0] = PassArray(realValues);
IDE

structureArray[1] = PassArray(stringValues);
structureArray[2] = PassArray(integerValues);
}

on Simulate
{
// Put data into the realValues, stringValues,
// and integerValues arrays.
// For example, set one element of each array.
realValues[0] = 98.6;
stringValues[0] = "Octane rating";
integerValues[0] = TRUE;

// The data arrays were already passed to the structure-


Array.
// Now, pass the structureArray to the connector.
// This has to be done here because connectors are active
// only during "On Simulate".
DataOut = PassArray(structureArray);
}
The following is the receiving block’s code. This gets the passed structure array, then gets the
individual arrays from the structure array for use in the block:
// Declare the arrays at the top of the code.
real structureArray[]; // This is the structure
string stringValues[]; // Holds the strings
real realValues[]; // Holds the reals
integer integerValues[]; // Holds the logical values
Programming Techniques 107
Working with arrays

on Simulate
{
if (GetPassedArray(ConnectorIn, structureArray))
{
// Get the reals
GetPassedArray(structureArray[0], realValues);
// Get the strings
GetPassedArray(structureArray[1], stringValues);
// Get the logicals
GetPassedArray(structureArray[2], integerValues);
// Use the array values
if (stringValues[0] == "Octane rating")
. . .
}
else
{
// The structureArray did not arrive yet

IDE
// or is not an array.
. . .
}
}

Working with global arrays


As discussed in “Global arrays” on page 67, global arrays provide a repository for model-spe-
cific data; they are accessed and managed through a suite of functions listed on page 378.
Global arrays can be referenced either by name or index value.
The following is an example of how to create, access, and dispose of a global array:
// Declare the arrays at the top of the code.
integer arrayIndex; // index value for the global array

on initsim
{
arrayIndex = GAGetIndex("myGlobalArray"); // see if global array
already exists
108 IDE
Working with arrays

if (arrayIndex < 0) // if global array does not exist...


{
// Create a three column global array of real numbers named
// “myGlobalArray”. Assign array’s index to arrayIndex.
arrayIndex = GACreate(“myGlobalArray”, GAReal, 3);
// Resize array to contain 10 rows of data
GAResize(“myGlobalArray”, 10);
}
}

on simulate
{
real realNumber;
. . .
// Set second row and column of global array to realNumber
// (row and columns start at index zero)
GASetReal(realNumber, arrayIndex, 1, 1);
. . .
IDE

// Read third row and column of global array and assign to realNumber
realNumber = GAGetReal(arrayIndex, 2, 2);
}

On Endsim
{ // We are done with myGlo-
balArray.
if (GAGetIndex("myGlobalArray") != -1) // Only if myGlobalArray
still exists,
GADispose("myGlobalArray"); // dispose of it.
}

Copying arrays using “for” loops


Copying the elements of an array to another array is quite easy with the “for” loop construct.
The following copies a two-dimensional array that has 100 elements:
// Copy array a into array b.

integer a[10][10], b[10][10];


integer i, j;

for (i = 0; i < 10; i++)


for (j = 0; j < 10; j++)
b[i][j] = a[i][j];

Using arrays to import unknown rows of numbers


The Import function reads numbers into a real array. If you do not know how many lines are in
the file and you use a fixed-size array, you will lose lines if the array is too small or waste
memory space if the array is too long. Instead, use a dynamic array to be sure that you will get
all the rows without having to specify the dimension of the rows. The function returns the
number of rows read, so you can then reduce the size of the array after the call. For example:
Programming Techniques 109
Working with linked lists

integer numRowsRead;
real fileArray[];
string theFileName, thePrompt, theDelim;
...
MakeArray(fileArray, 10000);
numRowsRead = Import(theFileName, thePrompt, theDelim, fileArray);
MakeArray(fileArray, numRowsRead);
The second call to MakeArray reduces the size of the array without disturbing the contents in
the rows left. Of course, if you import into a two-dimensional array, you have to specify the
size of the second dimension.
Working with linked lists
As discussed on page 67, linked lists are complex structures that can enable sophisticated sort-
ing rules. The concepts behind linked lists are beyond the scope of this manual. See “Linked
lists” on page 385 for a basic strategy in working with linked lists. Also, see the Queue blocks
(Item library) for actual linked list code.

IDE
Using message handlers
☞ Messages and message handlers were discussed on page 33 (introduction) and page 75.
ExtendSim uses a sophisticated messaging architecture to signal blocks into action. For
instance, when you add a block to a model, ExtendSim sends the “CreateBlock” message to the
new block. If the block’s code contains a message handler for the “CreateBlock” message (that
is, a bracketed set of lines that are preceded by “on CreateBlock”), the code is executed; if not,
nothing happens.
While messages can originate either from the ExtendSim application or from blocks, it is
always a block that is on the receiving end of a message. When you run a simulation, some
messages are sent to all blocks; others are sent only to a specific block. For instance, the “Cre-
ateBlock” message is sent only to the block that was added to the model. However, the “Init-
Sim” message, which tells the blocks that a simulation is starting, is sent to all blocks.
☞ The messages that a block’s dialog items uses are listed in the Dialog Item Names pane in the
block’s structure window. Use the Copy and Paste commands to copy the message names from
the pane to use in ModL code.
Categories of messages
While there are dozens of messages, they could be thought of as falling into one of three cate-
gories:
1) Messages that are sent to a block when the modeler interacts with the block’s dialog. For
instance, when the modeler clicks the block dialog’s Cancel button.
2) ExtendSim allows blocks to “call” other blocks by sending them a message, whether the
blocks are connected or not. Blocks use this feature to cause an action in another block,
such as having it perform a calculation or open a plot. For example, the UpdateStatistics
message is typically sent to an Activities block by the Statistics block (Report library)
when its statistical variables need to be recalculated and updated.
3) Messages that are typically sent from the application to one or more blocks. For instance,
when a block is added to the model, while the simulation is running, during interaction with
an ExtendSim database, and so forth. For example, the LinkContent message sends the
message that data has changed in an ExtendSim database.
110 IDE
Using message handlers

☞ A complete list and description of ModL messages is in the chapter “Messages and Message
Handlers” that starts on page 213.
Message sent during user interaction with dialog
This example shows what happens when the modeler clicks a button in the dialog. The dialog
item name of the button is “MyExportButton”. (The text label of the button is “Export”; it is
not used in the code.)
// Sent when the modeler clicks a button in the block's dialog
on MyExportButton // The modeler clicked the Export Data button
{
MyExportFTP(); // Call my function to export the data to the web
}
☞ For examples of code for each dialog item, see “Dialog messages” on page 36.
Block-to-block message
When a button is clicked in the calling block, its code sends a message to the receiving block
IDE

and causes that block to return a value. Global variables are used to pass arguments to the
called block as well as to get results from the called block’s actions.
See the Item library for examples of blocks sending messages using connectors.
Calling block
on Button // called when the block’s Button is clicked
{
// globalInt0 contains the block number of the receiving block
// UserMsg0 is the message handler that calculates it
SendMsgToBlock(globalInt0, UserMsg0Msg); // Call it
myResult = global1; // Get the result of the call
}
Receiving block
on UserMsg0 // called from the calling block
{
global1 = 123.5; // assign value to global1
}

Message sent by the application


The following code uses the CheckData message that is sent by ExtendSim to all the blocks in
a model at the beginning of a simulation. If the block has a CheckData message handler, this
message tells the block to check the validity of its data before the simulation starts.
// Sent by ExtendSim to allow checking data before simulation
on CheckData
{
if (myParm < 0.0) // this parameter should not be negative
{
UserError("Data in " + MyBlockNumber() + " can't be negative.");
Abort; // Stop simulation and select the offending block
}
}
Programming Techniques 111
Working with databases

Working with databases


As discussed in the User Reference, an ExtendSim database provides a repository for model-
specific data.
☞ See also the separate document ExtendSim Database Tutorial and Reference.
Using the database API to read and write
ExtendSim databases can be accessed and managed through the Read and Write blocks in the
Value and Item libraries. You can also use the database API (see “Database functions” on
page 354) to create databases via execution of a block’s code.
The following is an example of how to create and access a database to store output from a
model:
// Declare static variables
integer databaseIndex;// index value for the output database
integer tableIndex;// index value for the output table
integer fieldIndex;// index value for the output field

IDE
integer recordIndex;// index for setting our record values

on initsim// create the database, table, field if not there


{
// Creates database parts only if it doesn’t exist already
DBDatabaseCreate(“myDB”);
databaseIndex = DBDatabaseGetIndex(“myDB”);// get index
DBTableCreate(“myDB”, “myTable”);
tableIndex = DBTableGetIndex(databaseIndex, “myTable”);
DBFieldCreate(“myDB”, “myTable”, “myField”, DB_FIELDTYPE_REAL_GENERAL,
8, FALSE, FALSE, FALSE); // real number field
fieldIndex = DBFieldGetIndex(databaseIndex, tableIndex, “myField”);

// create records as we need them during the run


recordIndex = 0;// initialize record index
}

on simulate
{
recordIndex++;// increment our record index first (one based)

// append one record to our table


DBRecordsInsert(databaseIndex, tableIndex, 0, 1);

// write one data value to our database


DBDataSetAsNumber(databaseIndex, tableIndex, fieldIndex, recordIndex,
myDataValue);
}
☞ As shown in the table in “Data source indexing and organization” on page 92, databases use
one-based indexing. Keep this in mind when transferring data between databases and Extend-
Sim data tables, which are zero-based.
Registered blocks
Block registration is a method for keeping a block informed when there is a change in the
linked data source. Unlike user-defined or code-defined links (which link a particular dialog
item to a data source), block registration functions link an entire block to a data source.
The block registration functions start with DBBlockRegister or GABlockRegister (see “Link-
ing and notification” on page 374). Depending on the function chosen, the block gets a Link-
112 IDE
Working with databases

Contents message if the content of the data source changes or a LinkStructure message if the
structure of the data source (such as the name of a table or the location of a field) changes.
An example of block registration for content changes is the Read block (Value library). When
Link Alerts is checked in its Options tab, the block registers itself so that it will be alerted if/
when changes are made to its source data.
Registered blocks can be located using the Find Links dialog (Edit > Open Dynamic Linked
Blocks) discussed in the User Reference.
Use registered blocks judiciously. Due to the extra messaging, a registered block can signifi-
cantly slow the simulation run.
Reserved databases
ExtendSim databases are internal repositories for storing, managing, and controlling model
data. A reserved database is a specialized type of ExtendSim database that can be hidden from
the modeler. Reserved databases provide database capabilities without the modeler having to
use, or even be aware of, the reserved database.
IDE

Typically a database would be created by a modeler for a specific model. A reserved database,
on the other hand, is usually created by a programmer using the database API.
Example
A common use of a reserved database is to support the architecture
of a block. For example, when the Resource Manager block (Item
library of ExtendSim DE and ExtendSim Pro) is added to a model it
creates a reserved database named _rM_Database. There are numer-
ous tables in that database, each focusing on different aspects of the
block and how it functions. For instance, the Dialog Colors table,
shown here, stores the HSV values of the colors used for text labels
in the block’s dialog. Other tables track filtering conditions, store
resources with their ranking and skill levels, and so forth. When the
modeler enters data and makes selections in the Resource Manager block, these are tracked in
the reserved database. This process is invisible to the modeler.
The Optimizer block (Value library) is an example where a reserved database is used to pro-
vide a feature for the modeler. This is discussed in “Shift-click example” on page 100.
Creating and editing
Reserved databases are created and edited in much the same manner as you would create or
edit any ExtendSim database. Some differences are:
• To notify ExtendSim that the database is to be reserved, enter a leading underscore (_) at the
beginning of the database’s name. For example, the name would look like “_ARe-
servedDB”.
• To prevent modelers from accidentally writing to reserved databases, they require special
write functions. These are listed on page 363. An error message will be displayed if the spe-
cial write functions are used for non-reserved databases, and vice versa.
• Since they are intended for developers, ExtendSim doesn’t support using blocks (such as
Read or Write) to access reserved databases. It also doesn’t allow modelers to link dialog
items to a reserved database.
Programming Techniques 113
Reading text blocks as commands

• When a block that requires a reserved database is added to a model, the code of the block
creates the database in the model. In most cases, unless a block that requires a reserved data-
base is placed in the model, the model will not have any reserved databases.
• If a model has reserved databases, they will not be displayed in the Database List or at the
bottom of the Database menu unless you first give the command Develop > Show Reserved
Databases. By default, this command is not selected. Furthermore, the command is re initial-
ized to off each time the model is opened.
• Even if a reserved database is not listed in the Database List or at the bottom of the Database
menu, it is always accessible through ModL functions.
Changing anything in a reserved database is equivalent to changing the code of a block. It is
likely to corrupt any blocks that uses it.
Reading text blocks as commands
Since every piece of text that you add to a model gets its own number, text on the model work-
sheet can be accessed in a block’s code.

IDE
The BlockName function returns the name of a block for the specific block number. However,
blocks aren’t the only items on the worksheet that have numbers. Because each piece of text
gets a number, and the text is equivalent to a block’s name, you can use BlockName to read
text. This can be useful if you want to see how you have changed some text on the model.
Use this feature to globally change parameters in block dialogs. For example, assume you want
to give a command to the model to change a specific parameter in many blocks. Normally, you
would have to open all of the blocks and type the new parameter value. Here is a strategy that
allows you to type some text, such as “Speed=55”, on the model window that will cause all of
the speed parameters in all of the blocks to change when the simulation is run. Note that the
following function can be put in any block and can be called for each typed value that the code
needs:
114 IDE
Reading text blocks as commands

real GetTypedValue(string name) // User defined function


{
integer nBlocks, i, position, nameLength;
string typedText, valuePart;
real valueFound;

nameLength = StrLen(name); // Number of characters


nBlocks = NumBlocks(); // Number of blocks

for (i=0; i<nBlocks; i++) // Loop thru all blocks


{
typedText = BlockName(i); // Get block name or text
// find the "name=" string
position = StrFind(typedText, name+"=", FALSE, FALSE);
if (position == 0) // Must not be part of a larger word
{
// Get numeric part of string (skip over "name=")
valuePart = StrPart(typedText, position+namLength+1,255);
IDE

valueFound = StrToReal(valuePart); // Convert to real


if (noValue(valueFound))
{
UserError("The value for "+name+" must be numeric");
abort; // Stop the simulation
}
else
return(valueFound); // Return the found value
}
}

// No "name=" was found


UserError("Your typed variable, "+name+", was not found");
abort; // Stop the simulation
}

// Get your values. If they’re not found or are bad,


// GetTypedValue stops the simulation with a message
on Checkdata
{
// SpeedValue & MassValue are names of dialog parameters
SpeedValue = GetTypedValue("Speed");
MassValue = GetTypedValue("Mass");
}

Global function block


// Before simulation runs, set up the block number so that
// other blocks can call it
on CheckData
{
globalInt0 = MyBlockNumber(); // Use a global integer variable
}
// A message from another block (a "global function" call)
Programming Techniques 115
Changing data while the simulation is running

on BlockReceive0
{
// globalInt1 contains the number of the function

switch(globalInt1) // Which function did they want?


{
case 1: // The Hochmeister function

// global0 has the argument, result goes into global1


global1 = cos(global0)^2.0+sin(global0)^2.0;
break;

case 2: // The Lemski-Pemski factor


// global0 has the argument, result goes into global1
global1 = Sin(global0)/Cos(global0)-Tan(global0);
break;

IDE
}
}
Changing data while the simulation is running
Sometimes you need to change values in a block’s dialog while the simulation is running. In
most cases, ExtendSim handles this by allowing you to change the value, which is then used
immediately in the block’s code (usually in the Simulate handler). However, there has to be a
special initializing procedure if the block needs to calculate intermediate values based on that
new data. ExtendSim provides a mechanism to tell the block that its data has been changed.
Then the block can do a recalculation of intermediate data before the simulation resumes.
When any data is changed in a dialog during a simulation, ExtendSim sends a ResumeSim
message to that block before the simulation can resume. It also sends a ResumeSimAllBlocks
message to all of the blocks in the model. These are optional message handlers because most
blocks do not need to recalculate intermediate data, they just use the dialog values directly. But
if the block has a ResumeSim or ResumeSimAllBlocks message handler, it can take some
action before the simulation resumes.
Here is an example of a block that needs to do a lengthy calculation before the simulation
resumes after a change in parameters. It recalculates the coefficient when the modeler changes
the dialog parameter, but doesn’t zero out the accumulated value so the simulation can con-
tinue properly:
real coeffValue, accum;
real CalcCoeffValue(real theValue) // This function does the
// coeffValue calculation
{
real coeff;
integer i;

coeff = 0.0; // Initialize the sum


for (i=0; i<100; i++) // Loop a hundred times
coeff = coeff+cos(theValue*i); // Use theValue,calculate coeff
return(coeff); // Done, return it
}
116 IDE
Scripting

on InitSim // Initialize values for beginning of simulation


{
coeffValue = CalcCoeffValue(dialogParameter); // Calc coeff and
accum = 0.0; // init to 0
}
// User changed dialogParameter during simulation.
on ResumeSim // Just calculate new coeffValue,
// don’t initialize accumulated value.
{
coeffValue = CalcCoeffValue(dialogParameter); // Just calc coeff,
// don’t zero accum
}
on Simulate // Calculate new values during the simulation
{
accum = accum+coeffValue*conIn; // Fast. Multiply input by coeff
conOut = accum; // Output accumulated value
}
IDE

Scripting
In ExtendSim, the process of building models typically relies heavily upon modeler interac-
tion. The standard process of placing blocks on the worksheet, connecting them together, and
filling in the appropriate dialogs (while graphical and intuitive), requires direct modeler partic-
ipation. However, models can also be built, modified, and controlled indirectly using Extend-
Sim’s scripting features.
Scripting is an extremely powerful feature which allows you to:
• Build, run, and control models from within another application
• Create custom wizards to simplify tasks or interact with modelers
• Develop self-modifying models

By using the scripting functions (see “Scripting” on page 337), you can tell ExtendSim which
blocks to place on the worksheet and where, how to connect the blocks together, and what val-
ues to use for the block’s dialog parameters. In addition, any menu command can be executed
by a function call, for instance to run a model. When used in conjunction with the IPC func-
tions (see “Interprocess Communication (IPC)” on page 250 or “OLE/COM (Windows only)”
on page 253), the scripting functions can be used to build and run entire models based on infor-
mation from another application.
The scripting functions can also provide a means for developing “wizards” – blocks that help
the modeler to perform a task by gathering information, then building or modifying a model
based upon that information.
You can also develop blocks that help models achieve desired results. You could build artificial
intelligence into your models by building blocks that query the model for specific metrics and
simultaneously modify the model based on those metrics. For instance, you would use this
self-modifying feature to automate the process of changing models in response to simulation
results or to build goal-seeking models.
See the Tutorial block (Example Libraries > ModL Tips library > Scripting category) for an
example of using the scripting functions.
Programming Techniques 117
OLE and ActiveX Automation

OLE and ActiveX Automation


ActiveX automation is the process of using ExtendSim’s OLE functions, or the scripting envi-
ronment of another application, to communicate with, exchange data with, or control another
application. ExtendSim functions allow an object from another application, such as an Excel
spreadsheet, to be embedded into an ExtendSim model.
☞ ExtendSim supports ActiveX automation as either an automation server or as an automation
client. ExtendSim also supports being a container for embedded objects or ActiveX controls.
Note that almost all of the OLE functions defined in ExtendSim have two versions – one for
controlling an embedded object with ExtendSim and one for controlling an outside object
through ActiveX Automation. The name and the arguments provide a method of distinguishing
between these two versions of the functions:
• The set of functions designed to control embedded objects start with the keyword 'OLE' and
include a block number and dialog item name as their first two arguments.
• The functions that can be used for Automation control start with 'OLEDispatch' and will take

IDE
a dispatch handle as their first argument.
☞ The Examples\How To\Developer Tips\OLE Automation folder contains examples of C++,
Visual Basic, and VBA code for ActiveX Automation. See explanation for those examples on
page 119 (C++), page 124 (VBA), and page 124 (Visual Basic).
COM DLL example
The “VB.net COM DLL example” model (Windows only) shows how to interface from
ExtendSim with a COM DLL created in VB.net. The COM DLL folder includes the model
plus an ExtendSim library with a custom block as well as the source code used to create the
COM DLL. ExtendSim is the Client in this automation example; this is the inverse of the Cli-
ent App example where VB is the Client.
☞ See the folder Documents/ExtendSim/Examples/How To/Developer Tips/OLE Automation/
VB/COM DLL
Controlling Embedded Objects from ModL script
A set of functions is available in ModL to access embedded objects. These are described in
detail on “OLE/COM (Windows only)” on page 253. They include:
• Functions to insert objects (OLEInsertObject)
• Functions to invoke methods and set properties of objects; (OLEInvoke, OLEPropertyPut,
OLEPropertyGet)
• And many other miscellaneous functions that allow extensive control of an embedded object
Embedded objects or ActiveX controls can be embedded directly onto the model worksheet or
embedded into dialog items built to be embedded object locations.
• When you are trying to control an object that has been embedded onto the model worksheet,
the blockNumber argument is used to determine which object is to be controlled and the dia-
logItem argument is ignored.
• When you are trying to control an object or control that has been embedded into a dialog, the
block number and dialog item arguments are both used.
118 IDE
OLE and ActiveX Automation

ExtendSim as an Automation Client


To use ExtendSim as an Automation Client, start with a call to the function OLECreateObject.
This will return a dispatch Handle to the OLE Automation Server. Once you have the base Dis-
patch Handle for the server, you can then use the functions defined in “OLE/COM (Windows
only)” on page 253 to control the object.
ExtendSim as an Automation Server
ExtendSim also supports a simplified version of Automation as a Server. This is the ability for
another application to control the ExtendSim application from outside via OLE.
The automation supported in ExtendSim as an Automation Server is five methods:
• Poke
• Request
• Execute
• BlockMsg
• GetObjectHandle
IDE

These are used in a fairly simple single object model. Execute, Request, and Poke are the pri-
mary means of controlling ExtendSim via ActiveX/OLE Automation. BlockMsg and GetOb-
jectHandle are slightly more obscure, but can also be useful. See “C++ examples” on page 119
for an example of how these methods are used.
Object
For use with C++ or other related languages, the Object is the ExtendSim application, refer-
enced by the following GUID:
{E167B362-7044-11d2-99DE-00C0230406DF}
In Visual Basic, or other environments where ProgIDs are supported, this GUID can also be
referenced by the ProgID “Extend.application”. ProgIDs are a simplified and easier to remem-
ber way of accessing a GUID.
Even though the application name is ExtendSim, for backward compatibility the ProgID is
Extend.application. In the future, the ProgID ExtendSim.application will be supported as well,
but at the time of this writing the correct ProgID is Extend.application.
Because ModL scripts can be executed with the Execute method, complete control of Extend-
Sim is available through the following methods:

DispatchID Method Name See Page

1 Execute 120
2 Request 120
3 Poke 121
100 BlockMsg 122
101 GetObjectHandle 123

Topic and Item


The Poke and Request methods require two strings (Topic and Item) to identify where the data
should be poked or where it should be requested from.
Programming Techniques 119
OLE and ActiveX Automation

Topic is the name of the worksheet or model (or “system” if you don't need to specify a
model). If you specify system, the data will be poked to or requested from the top model.
The Item string is specified as follows:
"VariableName:#BlockNumber:RowStart:ColStart:RowEnd:ColEnd"
RowStart, ColStart, RowEnd, and ColEnd can all be set to zero if the item specified is neither a
data table object nor an array.
If the item is not a table, RowEnd and ColEnd can be left off. In this case the string would look
as follows:
"VariableName:#BlockNumber:0:0"
Starting in ExtendSim 7.0.2 there are new forms of the Item string which will allow you to
poke directly to, or request directly from, an ExtendSim database table or a global array. These
forms are as follows:
"GA:#GlobalArrayIndex:RowStart:ColStart:RowEnd:ColEnd"

IDE
"DB:#DBIndex:DBTableIndex:RecordStart:FieldStart:RecordEnd:Field-
End"
Note that the database case has an extra argument.
C++ examples
The following examples show how to access an IDispatch interface and use the five methods
(Poke, Request, Execute, BlockMsg, and GetObjectHandle) in C++. Also see the Exam-
ples\Developer Tips\OLE Automation folder.
Retrieving the IDispatch interface
The following C++ sample code shows one possible way you could access an IDispatch inter-
face on an ExtendSim application.
☞ The GetActiveObject code attempts to find a running copy of ExtendSim in the ROT (running
object table). The CoCreateInstance code creates a new instance of ExtendSim if the running
one is not found.
CLSIDFromString ("{E167B362-7044-11d2-99DE-00C0230406DF}", &clsid);
hr = GetActiveObject(clsid, NULL, (IUnknown **) &m_pUnknown);

if (hr == S_OK)
{
// JSL - found an existing instance
hr = m_pUnknown->QueryInterface(IID_IDispatch, &m_pDisp);
hr = m_pUnknown->Release();
}
else
{
theErr = GetLastError();
MessageBox (NULL, TEXT("GetActiveObject Failed, creating a new
Object"), TEXT("OleTest"), MB_OK);
hr = CoCreateInstance(clsid, // class ID of object
NULL, // controlling IUnkown
CLSCTX_LOCAL_SERVER,// context
IID_IDispatch, // interface wanted
(LPVOID *) &m_pDisp) ;// output variable
120 IDE
OLE and ActiveX Automation

if (hr != NOERROR)
{
theErr = GetLastError();
MessageBox (NULL, TEXT("Create Instance Not Successful"),
TEXT("OleTest"), MB_OK);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, theErr,
MAKELANID(LANG_NEUTRAL,SUBLANG_DEFAULT),
buf, sizeof(buf), NULL);
MessageBox (NULL, buf, "Error", MB_OK);
return;
}
}

Execute
The Execute method takes just a single argument that is the code to be executed. The dispID of
Execute is 1.
The Execute method is the most flexible method call, as the command that is passed to Extend-
Sim via this method is just a section of ModL script and can contain anything that can be put
IDE

into ModL script, including scripting functions. This means that by using the execute method
you can build models, run models, or do any of a number of things.
The C++ code you would use to call the execute method would look something like this (note
that this code will cause ExtendSim to display a userError statement with the value in user-
global0):
// Arguments are all passed as variants
bStr = SysAllocString((WCHAR *) L"userError(userglobal0);");
VariantInit(&vString);
vString.vt = VT_BSTR;
vString.bstrVal = bStr;

// Set the DISPPARAMS structure that holds the variant.


dp3.rgvarg = &vString;
dp3.cArgs = 1;
dp3.rgdispidNamedArgs = NULL;
dp3.cNamedArgs = 0;

// Call IDispatch::Invoke()
hr = m_pDisp->Invoke(executeID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dp3, NULL, &ei, &uiErr);

Request
The Request method uses Topic and Item, as specified a in “Topic and Item” on page 118, and
returns a string value. The dispID of Request is 2.
The C++ code you would use to call the Request method would look something like this (this
code will return the value present in userGlobal0):
Programming Techniques 121
OLE and ActiveX Automation

// Arguments are all passed as variants


requestVariant = malloc(sizeof(VARIANTARG) *2);
itemStr = SysAllocString((WCHAR *)
L"userglobal0:#0:0:0:0:0");
VariantInit(&requestVariant[0]);
requestVariant[0].vt = VT_BSTR;
requestVariant[0].bstrVal = itemStr;

topicStr = SysAllocString((WCHAR *) L"system");


VariantInit(&requestVariant[1]);
requestVariant[1].vt = VT_BSTR;
requestVariant[1].bstrVal = topicStr;

// Set the DISPPARAMS structure that holds the variant.


dp2.rgvarg = requestVariant;
dp2.cArgs = 2;
dp2.rgdispidNamedArgs = NULL;

IDE
dp2.cNamedArgs= 0;

var.vt = VT_EMPTY;

// Call IDispatch::Invoke()
hr = m_pDisp->Invoke( requestID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dp2, &var, &ei, &uiErr);

SysFreeString(topicStr);
SysFreeString(itemStr);

Poke
The Poke method takes the three arguments Value, Topic, and Item and sets the value specified
in the Value argument into the item specified in the Item argument. Topic and Item are speci-
fied as in “Topic and Item” on page 118; Value is the string that is going to be poked into the
location specified by Topic and Item. The dispID of poke is 3. Value, Topic, and Item are all
strings.
The C++ code you would use to call the Poke method would look something like this (note that
this code will set the value of Global0 to 34.5):
122 IDE
OLE and ActiveX Automation

pokeVariant = malloc(sizeof(VARIANTARG) *3);


valueStr = SysAllocString((WCHAR *) L"34.5");
VariantInit(&pokeVariant[0]);
pokeVariant[0].vt = VT_BSTR;
pokeVariant[0].bstrVal = valueStr;

itemStr = SysAllocString((WCHAR *)L"Global0:#0:0:0:0:0");


VariantInit(&pokeVariant[1]);
pokeVariant[1].vt = VT_BSTR;
pokeVariant[1].bstrVal = itemStr;

topicStr = SysAllocString((WCHAR *) L"system");


VariantInit(&pokeVariant[2]);
pokeVariant[2].vt = VT_BSTR;
pokeVariant[2].bstrVal = topicStr;

// Set the DISPPARAMS structure that holds the variant.


dp.rgvarg = pokeVariant;
IDE

dp.cArgs = 3;
dp.rgdispidNamedArgs = NULL;
dp.cNamedArgs = 0;

// Call IDispatch::Invoke()
hr = m_pDisp->Invoke( pokeID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dp, NULL, &ei, &uiErr);

SysFreeString(topicStr);
SysFreeString(itemStr);
SysFreeString(valueStr);

BlockMsg
BlockMsg sends a message to a specific block in the active ExtendSim model. The DispID of
BlockMsg is 100. This message will execute a message handler in the block called OLEAuto-
mation.
The BlockMsg method takes two arguments:
• The first is a block number (integer) and specifies the block that is to receive the message.
• The second is a value (integer, real, or string) and can be used to communicate with the
block code.
ExtendSim will set the value of one of three globals to be equal to the value you pass in as the
Value argument. Which global will be set is based on which type of variable passed in. The
example below uses a string variable. The three globals are OLEGlobal, OLEGlobalInt, and
OLEGlobalStr.
As reflected in the code below, the integer values used by the blockMsg method are long inte-
gers. However, by default an integer variable declared in Visual Basic is a short integer. So VB
programmers should take special care to declare the variables as longs in their VB code.
Programming Techniques 123
OLE and ActiveX Automation

msgVariant = malloc(sizeof(VARIANTARG) *2);


VariantInit(&msgVariant[0]);
msgVariant[0].vt = VT_I4;
msgVariant[0].lVal = 23; // blockNumber
argStr = SysAllocString((WCHAR *) L"userText ");
VariantInit(&msgVariant[1]);
msgVariant[1].vt = VT_BSTR;// could be a long, or a real as well
msgVariant[1].bstrVal = argStr;

// Set the DISPPARAMS structure that holds the variant.


dp.rgvarg = msgVariant;
dp.cArgs = 2;
dp.rgdispidNamedArgs = NULL;
dp.cNamedArgs = 0;

// Call IDispatch::Invoke()
hr = m_pDisp->Invoke( msgID, IID_NULL, LOCALE_SYSTEM_DEFAULT,

IDE
DISPATCH_METHOD, &dp, NULL, &ei, &uiErr);
SysFreeString(argStr);

GetObjectHandle
GetObjectHandle returns the Dispatch Handle value for an embedded object within Extend-
Sim. This is useful if your outside code is dealing directly with Dispatch Handles, since it will
allow you to communicate directly with the embedded object inside the ExtendSim application
without going through ExtendSim’s interfaces. The DispID of GetObjectHandle is 101.
getVariant = malloc(sizeof(VARIANTARG)*3);
argStr = SysAllocString((WCHAR *) L"Dialog Item Name");
VariantInit(&getVariant[0]);
getVariant[0].vt = VT_BSTR;// could be a long or a real
getVariant[0].bstrVal = argStr;

VariantInit(&getVariant[1]);
getVariant[1].vt = VT_I4;
getVariant[1].lVal = 23; // blockNumber

argStr2 = SysAllocString((WCHAR *) L"model-1.mox");


VariantInit(&getVariant[2]);
getVariant[2].vt = VT_BSTR;// could be a long or a real
getVariant[2].bstrVal = argStr2;

// Set the DISPPARAMS structure that holds the variant.


dp.rgvarg = getVariant;
dp.cArgs = 3;
dp.rgdispidNamedArgs = NULL;
dp.cNamedArgs = 0;

// Call IDispatch::Invoke()
hr = m_pDisp->Invoke( getID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dp, NULL, &ei, &uiErr);
SysFreeString(argStr);
SysFreeString(argStr2);
124 IDE
OLE and ActiveX Automation

Using VBA for ActiveX/OLE Automation


On page 119 you saw how to control ExtendSim using C++ and the five methods that Extend-
Sim supports. ExtendSim can also be controlled using Excel and VBA.
The workbook “Excel Client-Server Model Workbook.xls” (Documents/ExtendSim/Exam-
ples/How To/Developer Tips/OLE Automation/VBA) contains examples of how to communi-
cate with, send data to, and receive data from an ExtendSim model using Excel VBA and OLE
automation. For these examples, Excel is the Client application and ExtendSim is the Server
application.
☞ This workbook provides a form-based interface to drive communication between Excel and
ExtendSim.
The VBA code in this workbook contains numerous examples that illustrate how to use OLE
Automation to remotely interact with an ExtendSim model to perform the following:
• Start and stop the ExtendSim application
• Open and close a model
IDE

• Make ExtendSim run asynchronously


• Determine if ExtendSim is running or paused
• Change the end time of a simulation model
• Get a database component, (e.g. table or indexes) from an ExtendSim model's database
• Receive the contents of a database table into a range of worksheet cells
• Poke the contents of a range of worksheet cells into an ExtendSim database table
• Get the path and name of an ExtendSim model
• Get the current time of a simulation run
• Set a dialog parameter value in an ExtendSim model's block

Using Visual Basic for ActiveX/OLE Automation


On page 119 you saw how to control ExtendSim using C++ and the five methods that Extend-
Sim supports. ExtendSim can also be controlled using Microsoft Visual Basic (VB).
In VB, the syntax for creating or connecting to instances of ExtendSim and for controlling the
ExtendSim application is identical to Visual Basic for Applications (VBA) discussed above.
The primary difference between VB and VBA is that VB code can be compiled to create exe-
cutable and DLL files.
The executable file “ExtendSim OLE.exe” (/Documents/ExtendSim/Examples/Developer
Tips/OLE Automation/VB/VB Client App) is a VB program that creates an ExtendSim object
and uses ExtendSim’s execute, poke and request OLE methods to communicate with and con-
trol the ExtendSim application. This program starts ExtendSim (if necessary), loads a model,
sets a dialog parameter, executes a command, and gets a dialog parameter.
The VB source code and all of the Visual Studio files required to build “ExtendSim OLE.exe”
are provided in the same folder as the executable file. View the source code to see examples of
how to implement ExtendSim OLE methods and how to create and connect to instances of
ExtendSim using Visual Basic.
Integrated Development
Environment (IDE)

Animation Using ModL


Procedures and suggestions for how to
create and modify ModL code

“In baiting a mousetrap with cheese,


always leave room for the mouse.”
— Hector Hugh Munro
126 IDE
2D animation

This chapter is specific to using ModL functions for performing 2D and 3D animation.
2D animation
The functions listed in “2D Animation” on page 270 make it easy to add 2D animation to
blocks. This section discusses the general procedures in creating 2D animated blocks, then
shows some examples of how you might add 2D animation to the blocks you build.
Overview
☞ Even if Run > Show 2D Animation is not selected, it is still possible to display 2D animation.
The Show 2D Animation command (Run menu) and the Show 2D Animation button in the
Model toolbar only control whether animation is shown during the simulation run. At all other
times, the block will still show animation if the block creator has coded it to do that. For
instance, animation is available when the modeler makes any changes in a block's dialog,
whether Show 2D Animation is selected or not and regardless of whether the simulation is run-
ning. (Of course, when the command Show 2D Animation is selected, animation is available at
all times.)
IDE

Showing animation outside of a simulation run is a powerful feature because it lets you build
blocks which show their initial status or final values without having to turn on 2D animation.
For example, if a check box is clicked, the dialog can send an “on myCheckBox” message to
the block and the block can animate the change on its icon, as seen for the Miles block in
“Adding 2D animation” on page 53.
Steps
As shown in “Adding 2D animation” on page 53 and described in detail below, the basic steps
for adding 2D animation to a block are:
1) Decide how you want the block to animate, including the shape and color that the anima-
tion objects should have.
2) Create the 2D animation objects in the Icon tab of the block’s structure window. Do this
either by placing an animation object on the Icon tab manually or dynamically through
block code.
3) Initialize the animation objects in the CheckData or InitSim handlers.
4) Add code to update the animation object at the correct times, including (if necessary) code
to slow the display so that it isn’t too fast to be seen.
• For continuous blocks, this code will be in the Simulate message handler.
• For discrete event or discrete rate blocks, this code will be in the function or message
handler appropriate for the data that you want animated. (For example, if you are ani-
mating an item entering a block, the code would go in the ItemIn message handler.)

Deciding how to animate the icon


There are several ways to animate a block’s icon. You can show and hide text or a shape (such
as a rectangle, oval, or level), move a shape within or outside of the icon (even along the con-
nection lines), show a changing level, stretch and reduce a shape’s size, show a picture, or
change colors or text.
The AnimationPoly function is especially useful. As shown in the Select Value In and Select
Value Out blocks (Value library), it allows the animation of an arbitrary shape.
Animation Using ModL 127
2D animation

☞ Some animations (such as moving or stretching) will cause simulations to run slower than other
types (for example, changing color or text).
While it is common that icons are animated, it is also possible to animate in the area around
icons. See the Planet Dance model (located in the folder ExtendSim/Examples/Continuous/
Custom Block Models) for an example of a model that shows animation outside of the icon.
Also see the blocks in the Item library for examples of animating from one block to the other,
along connection lines.
Creating 2D animation objects
All 2D animation is done through the use of one or more animation objects that you put in the
Icon tab of the block’s structure. The animation object itself is a resizable rectangle with dotted
sides, identified by a unique number .
☞ Animation objects are always rectangles in the icon pane. As discussed below, the animation
functions in the block’s code determine the characteristics of the object, for example, the shape
and color that will show as the block is animated.

IDE
To create an animation object:
In the Icon toolbar, select the Animation Object button; it is at the bottom or right side of the
toolbar, depending on how the toolbar is oriented
Click in the Icon tab to place the object and resize as desired. Since this
is the first animation object, it will have a “1” in it, as shown at right.
You will use that object number in all of the animation functions that
call this object.
☞ 2D animation objects can also be created “on-the-fly” using the AnimationObjectCreate func-
tion.
Each animation object has a Proper-
ties dialog that can be accessed by
right-clicking on the object. This dis-
plays information such as the Object
ID and allows you to set the exact
position and dimensions of the object
directly in the structure of the block.
If animation objects are layered on top
of each other, the zOrder allows you
to set where in the layer each object
will be.
Initializing animation objects
In the block’s code, initialize the object in the InitSim message handler. If you always want the
animation object visible, even before an animation is run, put the same code in the CreateBlock
handler.
The initialization will generally consist of a call to one of the object definition functions (Ani-
mationOval, AnimationRndRectangle, AnimationPoly, and so forth), a call to AnimationE-
Color (to set the color for the object). It might also include a call to AnimationShow so that the
object is visible at the beginning of the simulation (for example, for showing initial text or
color). Here is an example:
128 IDE
2D animation

on initSim
{
AnimationOval(1); // Set 1 to oval
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
AnimationEColor(1, color); // Set 1 to the EColor value
AnimationShow(1); // Optional
// makes object visible
}
☞ If you define the animation object in the code as an oval, and resize it on the icon as a square, it
will show as a circle. If you define it as an oval and resize it as a rectangle, it will show as an
oval.
The color of an animation object is set with numbers for hue, saturation, and brightness
(value), often called HSV. Use the Fill Color button in the Shapes toolbar to determine the
HSV values of any color.
IDE

If you want a block to see whether or not the Run > Show 2D Animation command is checked
(for example, to hide the animation object if animation is not on), use the AnimationOn system
variable in the CheckData or InitSim message. It is set to TRUE (1) if animation is on and
FALSE (0) if it is not. For example, instead of the preceding initialization, you might have:
on initSim
{
AnimationOval(1); // Set 1 to oval
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
AnimationEColor(1, color); // Set 1 to the EColor value
if (AnimationOn) // Animation is on
AnimationShow(1);// Optional: show 1 now
else // Animation is not on
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}

Updating the animation object


The Show 2D Animation command only affects 2D animation that is specified in the Simulate
message. As mentioned earlier, if Show 2D Animation is not selected, animation is still avail-
able except during the Simulate message. During Simulate, ExtendSim blocks check the state
of the Run > Show 2D Animation command to determine whether or not to perform animation.
In the Simulate message handler (for continuous blocks) or in the function or message handler
appropriate for the data being animated (for discrete event and discrete rate blocks), put the
code that checks whether you want to change the animation object (its position, color, or text).
☞ To speed execution of the block, be sure to only call an animation function when the object has
changed.
If the animation object shows too fast to be seen, you may want to include a call to the WaitN-
Ticks function. Note, however, that this will also slow down the simulation.
Animation Using ModL 129
2D animation

Animating hierarchical blocks


To animate a hierarchical block’s icon, you have to include, in the hierarchical block’s sub-
model, a block that has code to control the animation on the hierarchical block’s icon.
The block in the submodel is used to read the values from other submodel blocks; its code con-
trols the animation of the hierarchical block’s icon based on those values. In order to do this, it
references the hierarchical block’s animation object using the negative of the object number.
For example, if the number of the animation object on the hierarchical block’s icon is 2, the
block in the submodel would reference animation object -2 throughout its ModL code.
Animating hierarchical blocks is the only time when you would use negative values to refer-
ence an animation object. As described in the User Reference, the Animate Value and Animate
Item blocks (Animation 2D-3D library) contain code that allows them to animate hierarchical
blocks.
The block that controls the animating on a hierarchical block’s icon can be deeper than one
level in hierarchy. However, searching from the lowest to the highest level, that block will try

IDE
to animate the first animation object with the correct number that it finds.
☞ If more than one hierarchical block has an animation object with the same number, the lowest
one above the controlling block will be the one that is animated.
Showing and hiding a shape
An animation object could be displayed if an input value met some condition or became true,
or if an item arrived in the block or was being processed. Hiding the animation object would
then indicate the opposite condition. You could have a small object near the connector to indi-
cate item arrivals or meeting a condition, such as the Select blocks (Value library). Or you
could have a larger object indicating a true value or processing, such as the Activity blocks
(Item library).
This example uses the animation object drawn above. You want a solid red circle to appear in
the icon when a value is true (greater than 0.5) and you want to hide it when the value is false.
To do this, initialize the animation object and hide it in InitSim. Then put code in the Simulate
message to indicate when and how the object should change:
on initSim
{
AnimationOval(1); // Set 1 to oval
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
AnimationEColor(1, color); // Set 1 to the EColor value
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
on Simulate // Or appropriate function or message handler
{
...;
if (AnimationOn && ConditionIsTrue) // if both true
AnimationShow(1); // Show object now
else
AnimationHide(1, FALSE); // Else hide object; it is not
// outside of icon
}
130 IDE
2D animation

Moving a shape
Assume that you want the animation object drawn above to move between the original position
and a position 20 pixels higher than the original depending on the values received. The input at
the connector called “con1in” takes in real values from 0 to 1, with 1 indicating the highest
desired input. Since, in screen coordinates, up is considered negative relative to the starting
position, you must call AnimationMoveTo with a negative number to move the object up. Your
code might be:
integer obj1Loc; // Save the object’s location
real clipped;
integer testLoc;
. . .
on initSim
{
AnimationOval(1); // Set 1 to oval
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
IDE

AnimationEColor(1, color); // Set 1 to the EColor value


if (AnimationOn) // Animation is on
AnimationShow(1); // Show object now
else // Animation is off
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
on simulate // Or appropriate function or message handler
{
clipped = Min2(con1in, 1.0); // Highest position is 1
clipped = Max2(clipped, 0.0); // Lowest position is 0

testLoc = int(clipped*-20.0); // Scale to range, upwards


if (testLoc != obj1Loc) // Do nothing if not change
{
obj1Loc = testLoc;
AnimationMoveTo(1, 0, Obj1Loc, FALSE); // Move to new location
}
}

Changing a level
Sometimes you want to display a changing level, such as in a water tank. For this example, use
the animation object drawn above. A simple block that displays a changing level when its input
connector varies between 0.0 (lowest level) and 1.0 (highest level) might look like:
on InitSim
{
// Initialize animation object number 1 as a “level” shape
AnimationLevel(1, 0.0); // Initialize level to low
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
Animation Using ModL 131
2D animation

AnimationEColor(1, color); // Set 1 to the EColor value

if (AnimationOn) // Animation is on
AnimationShow(1); // Show level now
else // Animation is off
AnimationHide(1, FALSE); // Hide level; it is not
// outside of icon
}
on simulate // Or appropriate function or message handler
{
AnimationLevel(1, con1in); // Input connector value (0.0 to 1.0)
// controls the height of the level
}
To have the level reflect values other than 0 to 1, scale the input values to correspond to that
range. See the Holding Tank block (Value library) for an example of changing a level.
Stretching a shape

IDE
You can stretch an animation object horizontally or vertically, or both at
the same time (circular), relative to its original position on the icon. For
example, do this to show the relative size of an item (for instance, based
on an attribute value) or to indicate a direction of flow.
The following code stretches the object vertically inside the icon. This
method uses the exact size of the animation object as it is drawn on the
icon to determine the boundaries for the stretch. The input at the connec- Object for stretching
tor called “con1in” takes in real values from 0 to 1, with 1 indicating the
highest desired input. For this example, draw an animation object like the image shown here.
integer origWidth, origHeight; // Boundaries of the object
integer pixels; // How far to stretch
real clipped; // Amount to change
. . .
on InitSim
{
AnimationRectangle(1); // Set 1 to rectangle
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
AnimationEColor(1, color); // Set 1 to the EColor value
origWidth = AnimationGetWidth(1, TRUE); // Get original width
origHeight = AnimationGetHeight(1, TRUE); // Get original height

if (AnimationOn) // Animation is on
AnimationShow(1); // Show object now
else // Animation is off
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
132 IDE
2D animation

on simulate // Or appropriate function or message handler


{
. . .
clipped = Min2(con1in, 1.0); // Highest position is
1.0
clipped = Max2(clipped, 0.0); // Lowest position is 0.0
pixels = clipped * origHeight; // Calculate stretch
// Subtract the pixels to go upward (negative is up relative to base)
AnimationStretchTo(1, 0, origHeight - pixels, origWidth, pixels,
FALSE);
}
To have the shape stretch outside of the icon, set the last argument in AnimationStretchTo to
TRUE and increase the value for pixels so it will stretch outside the icon. Stretching or moving
outside the icon slows animations considerably and might cause the icon to flash.
☞ See also the AnimationPoly function which can be used for animating an arbitrary shape or for
dynamically changing the shape of an icon. Examples are the Select Item In and Select Item
Out blocks (Item library).
IDE

Showing a picture on an icon


You can also have a picture show on an icon in response to some occurrence in the block. For
example, the code for a picture might look like:
on initSim
{
// Set object 1 to picture, not scaled
AnimationPicture(1, “MyPicture”, FALSE);
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
on simulate // Or appropriate function or message handler
{
. . .
if (ConditionIsTrue)
AnimationShow(1); // Show picture
else
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
☞ In order to use a picture, it must be a resource in the System, in ExtendSim, or in a file in the
ExtendSim/Extensions folder as discussed in “Picture and movie files” on page 89.
Moving a picture along the connection line between two blocks
A picture traveling along the connection line between two blocks is an effective way to ani-
mate individual items as they flow through a model. As shown above, you can assign a picture
to an animation object. By calling AnimationBlockToBlock, the animation picture can move
from one block to the next along the connection line.
☞ In order to use a picture, it must be a resource in the System, in ExtendSim, or in a file in the
ExtendSim/Extensions folder as discussed in “Picture and movie files” on page 89.
Arguments for AnimationBlockToBlock include the animation object number and the block
numbers and appropriate connector numbers of the two blocks you wish to animate the picture
Animation Using ModL 133
2D animation

between. Typically you do not know how blocks will be connected until the model is built.
Therefore you must determine the values of these parameters by using function calls to
MyBlockNumber, GetConNumber, and GetConBlocks. You can call the functions from any
block, provided it knows which block is sending and which is receiving.
The following code example illustrates how to determine the appropriate parameter values and
make a call to AnimationBlockToBlock. In this example, AnimationBlockToBlock is called
from the “sending” block (the block from which the picture will start moving). The picture will
move to the “receiving” block connected to the con1Out connector of the “sending” block.
integer array[][2];
...
on InitSim
{
AnimationPicture(1, “MyPicture”); // Set object 1 to picture
myNumber = MyBlockNumber(); // determine “sending” block #

IDE
// determine “sending” connector #
outCon = getConNumber(myNumber, “con1Out”);
getConBlocks(myNumber, outCon,array); // what blocks are connected
// to con1Out?
rBlock = array[0][0]; // determine “receiving” block #
rConn = array [0][1]; // determine “receiving” connector #
}

on simulate
{
// animate picture between blocks
AnimationBlockToBlock(1,myNumber,outConn, rBlock, rConn, 1.0);
}

Changing a color
To use a change in color instead of motion, include a call to AnimationEColor with a variable
for one of the hue, saturation, or brightness (value) arguments:
on InitSim
{
hueVal = 0;
AnimationOval(1); // Set object 1 to oval
//create an EColor value of red with an opaque alpha channel
Color = EColorFromHSV(0, 255, 255, 255);
AnimationEColor(1, color); // Set 1 to the EColor value
if (AnimationOn) // Animation is on
AnimationShow(1); // Show object now
else // Animation is off
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
134 IDE
2D animation

on simulate // Or appropriate function or message handler


{
. . .
hueVal = hueVal+10; // Different colors
if (hueVal > 255)
hueVal = 0;
Color = EColorFromHSV(hueVal, 255, 255, 255);
AnimationEColor(1, color);
. . .
}

Changing text
You can also animate by changing text in the animation object created at the beginning of this
section.
☞ Using AnimationText() causes a white background around animated text. To not have this,
instead use the function AnimationTextTransparent() as is done below.
IDE

string objText;

on InitSim
{
AnimationTextTransparent(1, ""); // Set object 1 to blank text
//create an EColor value of black with an opaque alpha channel
Color = EColorFromHSV(0, 0, 0, 255);
AnimationEColor(1, color); // Set 1 to the EColor value

if (AnimationOn) // Animation is on
AnimationShow(1); // Show object now
else // Animation is off
AnimationHide(1, FALSE); // Hide object; it is not
// outside of icon
}
on simulate // Or appropriate function or message handler
{
. . .
if (temp < 1000) // Less than 1000
objText = "Cool";
else if (temp < 1500) // Between 1000 and 1500
objText = "Med";
else // Greater than 1500
objText = "Hot";
AnimationTextTransparent(1, objText); // Set the text
. . .
}

Animating pixels
You can generate a rectangle of pixels where each pixel can be a different color based on the
value for that pixel. For example, use this to generate a contour map or give visual display of
temperatures over a two-dimensional space. For an example of this, see the Mandelbrot model
located at Documents/ExtendSim/Examples/Continuous/Custom Block Models.
Animation Using ModL 135
3D animation

3D animation
The ExtendSim 3D (“E3D”) window provides a fully three-dimensional representation of the
world of the model. The objects modeled in the window maintain information about their posi-
tions in three dimensions as well as other physical properties of their representations. The win-
dow is also tightly integrated with the rest of the ExtendSim simulation engine. Every motion
of every object, every aspect of things that happen in the 3D world, can be controlled from the
ModL programming language.
☞ 3D animation is only available in ExtendSim Pro.
☞ This chapter presumes you have read the information about using the E3D window and envi-
ronment in the ExtendSim User Reference.
About the 3D chapter
This chapter provides information for those interested in code development within the E3D
development environment. It is organized into the following sections:

IDE
5) Overview, including a brief discussion of the Torque Game Engine (TGE), upon which the
E3D environment is based
6) Manipulating existing objects, such as adding a mount point or additional skins
7) Building new objects such as people, vehicles, and so forth
The focus of this chapter is on providing a high-level description of the E3D environment, with
explanations where the E3D environment differs from the TGE.
In many cases the E3D environment uses standard TGE constructs, and they will not be
repeated here. Instead, see the GarageGames website at www.GarageGames.com for complete
details about TGE constructs, including DataBlocks and Torque Scripts.
Overview
The Torque Game Engine and the E3D environment
For 3D animation, ExtendSim incorporates its own development environment, a compiled ver-
sion of the Torque Game Engine (“TGE”), Torque Script files, and numerous 3D functions for
communicating with the E3D window. Together this is termed the E3D development environ-
ment. The TGE is a powerful 3D rendering architecture that GarageGames (www.Garage-
Games.com) licenses as a source code development environment.
Since the E3D environment is open-source, you can modify the animation capabilities of exist-
ing blocks, create entirely new 3D-enabled blocks and 3D objects, and modify object behav-
iors for specialized applications. ExtendSim has numerous ModL functions for defining the
custom behavior of 3D objects and events; the Torque Script scripting environment provides
additional control over the animation environment and object behaviors.
Note that the running of a simulation is not necessarily a part of the model’s control of the E3D
window content. The Boids model (located in the \Examples\3D Animation folder), is an
example of a model that uses custom blocks and does not utilize the simulation loop to control
the behavior of the objects in the model.
☞ If you are serious about developing extensive 3D simulations with ExtendSim, and you want
direct access to the TGE API, consider purchasing at least an “indie” license for the TGE.
More information about the TGE can be found at www.GarageGames.com. (Even if you don't
plan to do any development with the engine, this will allow access to the developer forums.)
136 IDE
3D animation

Performance considerations
The E3D window is doing a complete textured rendering of a complex 3D environment, so the
number of objects being rendered and the capability of the hardware on which the software is
run will have an effect on the performance of the E3D window. See the User Reference for
some suggestions for improving performance.
Modes of E3D animation
Each model has a saved 3D animation mode – QuickView, Concurrent, or Buffered, as dis-
cussed below. These modes are selected in the Run > Simulation Setup > 3D Animation dialog
and control aspects of the interaction between the ExtendSim application, the E3D window,
and the blocks’ ModL code.
The 3D animation modes are
discussed fully in the E3D mod-
ule of the User Reference. The
following is meant to be supple-
mental to that information.
IDE

Quickview
Quickview is the default mode
and allows a model to display its
behavior in the E3D window
without being extensively modi-
fied. In this mode most of the
blocks at the top level of the 2D
model will have a representation
in the E3D window and a 3D
object’s position will corre-
spond to the location of the cor-
responding block in the 2D 3D Animation tab in Simulation Setup dialog
model. However, QuickView
mode uses the immediate func-
tions (discussed in “Types of 3D ModL functions” on page 137) so only one object will move
at a time. This mode allows the modeler to get a quick 3D view of the simulation with minimal
customization of the model.
Concurrent
The Concurrent mode is more commonly used for a model that has been designed or modified
to specifically support E3D functionality. In this mode, multiple items can be moving in the
E3D window at one time and the locations of the blocks in the 2D model don't necessarily cor-
respond to the locations of the objects in the E3D window.
In Concurrent mode events are posted internally with the E3DPost functions. This causes cer-
tain events, such as the creation of an object or an object moving, to be put into a queue to be
performed later. (For more information about the E3DPost functions, see “Types of 3D ModL
functions” on page 137)
An additional aspect of Concurrent mode is that the simulation engine will pause with each
E3DPost function call until the currently posted call has begun processing. This assures that
the simulation and the E3D window keep in sync, but it adds the additional requirement that
the 3D events posted by the model need to be posted in time order (earlier before later). Note
that this is handled automatically by the blocks in the Item library.
Animation Using ModL 137
3D animation

Buffered
Buffered mode is a variation on Concurrent mode, where the information about what should
happen in the E3D window is stored in an internal buffer and replayed later.
As is true of the Concurrent mode, the Buffered mode posts events internally using the
E3DPost functions. (For more information about the E3DPost functions, see “Types of 3D
ModL functions” on page 137.) However, one advantage of the Buffered mode, which only
applies to models built with custom blocks as opposed to models that use the Item library
blocks, is that the events posted with the E3DPost functions do not necessarily need to be
posted in order. This is because the events are queued in the buffer and sorted.
Time ratios and 3D event queues for the modes
As discussed in “Distance and time ratios” on page 137, each simulation time unit will by
default take one second to display in the E3D window. In Concurrent and Buffered modes the
simulation time to real world clock time ratio is carefully respected. In these modes, almost all
of the actions the blocks take in the E3D environment are posted using the E3DPost functions
(see “Types of 3D ModL functions” on page 137) which specify simulation time as the first

IDE
argument of the function call. Internally, ExtendSim maintains a list of the posted events and
processes them at the correct time. This means that multiple events can happen at the same
time and multiple objects can be moving at the same time.
☞ The event queue maintained by the E3D window is independent from the event queue main-
tained by the Executive block.
Types of 3D ModL functions
There are two broad categories of functions that manipulate the 3D objects in the E3D win-
dow:
• Post functions. Each of these functions starts with E3DPost and contains as its first argument
the simulation time value when the function should occur. In many cases, such as in the Item
library, this value will be current time. However there is no reason why a custom implemen-
tation could not use more distant future values.
As discussed in “Modes of E3D animation” on page 136, the post functions are used in the
Concurrent and Buffered animation modes and have the effect of putting the E3D commands
into an internal queue. This queue of commands will be executed in time order by the simu-
lation engine. In Concurrent mode the execution will be immediate; in Buffered mode it will
be delayed until the user clicks on the Start button.

• Immediate functions. These functions do not have a time value associated with them and
they take place immediately. Thus they lose the connection between simulation time and
E3D window time that the Post functions have. An example of a model that uses immediate
functions rather than Post functions would be the Boids model (Examples\3D Animation),
which doesn't even run a simulation.

Distance and time ratios


The distance units in the E3D environment are in meters. The default ratio between the pixels
in the 2D model window and the distance units in the E3D window is 20 pixels per meter. This
means that for models that use a direct relationship between the two windows, each 20 pixels
of distance in the 2D window will translate to one meter of distance in the E3D environment.
The ratio can be modified in the Run > Simulation Setup > 3D Animation dialog shown on
page 136.
138 IDE
3D animation

In Concurrent and Buffered modes, time in the E3D window is related to ExtendSim simula-
tion time by the time ratio defined in the Run > Simulation Setup > 3D Animation dialog
shown on page 136. By default this ratio is 1 simulation time unit to 1 second of real time. For
example, if a simulation is set to take 60 time units, it is in Concurrent mode (using E3DPost
calls to establish events in the E3D window), and the E3D window is open, the animation in
the E3D window should display for 60 seconds.
☞ In QuickView mode the time relationship between simulation time and real time is not pre-
served, so the time ratio defined in the Simulation Setup dialog does not have an effect for that
mode.
References
Read the 3D Animation module in the ExtendSim User Reference before doing any 3D devel-
opment work.
The GarageGames web site (www.GarageGames.com) is useful for finding additional
resources when developing in the E3D environment, contacting consultants for custom work,
and asking questions about the Torque engine.
IDE

There are also several books about the TGE. They tend to be focused on game development
but also contain invaluable information about development with the TGE that will in large part
translate directly into working with the E3D window. A couple of books to consider are: “3D
Game Development All In One” and “The Game Programmers Guide to Torque”.
A complete discussion of the TGE is beyond the scope of this document. Instead, there is
extensive information about the Torque scripting environment, as well as the default layout
and behavior of TGE scripts, on the GarageGames website at www.GarageGames.com.
Manipulating object behaviors and appearances
Objects in the E3D environment have many properties that define how they look, behave, and
interact with the 3D window and with the ExtendSim simulation engine. The following sec-
tions define some of these properties, describe how they work within the context of the E3D
environment, and how you can change or adjust them.
E3D object names and labels
There are two object name-type properties that are used and referenced in ExtendSim – the
name field in the World Editor Inspector and the object label that is displayed along with the
object in the E3D window.
Name field
The Name field is at the top of the Inspector pane of the World Editor Inspector. This field is an
optional text identifier for the object that can be set either in the World Editor or through the
E3DSetName function. The name of an object can be used in ModL functions to locate an item
by name, rather than numerically with the objectID value (see “ObjectIDs, userTags and
groupTags” on page 139.) If used, the name of an object will also appear in the Editor in text
drawn on the item following the objectID.
Object label
The other name-like property is the object label. This is set with the E3DSetObjectLabel func-
tion and produces a visual label that is displayed above the object in the E3D window but not
in the World Editor Inspector’s Inspector pane. You can also change the color of the text of the
object label.
Animation Using ModL 139
3D animation

☞ To display text in the E3D window without having a visual object associated with it, create a
waypoint and set its object label. Waypoints are invisible, but the object label will still be
drawn. For instance, this is how the 3D Text block (Animation 2D-3D library) displays text.
ObjectIDs, userTags and groupTags
ObjectIDs, userTags, and groupTags are the numeric properties associated with objects in the
E3D window. Many of the 3D functions have arguments that refer to these numeric properties.
ObjectIDs
The objectID is the main identifier that the E3D window uses to identify the objects it needs to
support. There is a unique objectID value associated with each object in the E3D window. This
includes not just the objects that are created from ModL code, but also all of the objects that
the window uses as the basic building blocks of the 3D world.
☞ Names can also be used by ModL functions to locate objects, as discussed in “E3D object
names and labels” on page 138.
For example, the Camera object (described in the User Reference) has an objectID. This allows

IDE
you to call any of the ModL functions that take an objectID value on the Camera and facilitates
features like setting the position of the camera dynamically to track a moving object. This is
shown in the 3D Animation\Tips\E3D Path model.
For Concurrent and Buffered mode models, which internally call the E3DPost functions
instead of the immediate functions (as discussed in “Modes of E3D animation” on page 136),
the objectID will not be available at the time the function is called. This is because the objec-
tID is created by the E3D window code when the object is instantiated in the 3D world. In
these modes a temporary userTag is created to identify the object, as discussed below.
☞ UserTags should be used for all “post” functions. You should only use the objectID when you
are sure that the object will exist at the time the function is called.
UserTags
As shown in “Modes of E3D animation” on page 136 and “Types of 3D ModL functions” on
page 137, the Concurrent and Buffered modes call the E3DPost functions. At the time the
E3DPost function is called, the simulation time when the object will be created may not yet
have been reached. So operations on the object are put into a queue to be performed later. This
means that a temporary value, a userTag, needs to be created that will be used to identify the
object before it is created. The userTag is the value that will be returned by the E3DPostCreate-
Object that schedules the creation of the object.
The userTag is used to identify the object until it is actually created in the 3D window. How-
ever, once the object is created and an objectID has been established, the userTag is still avail-
able and each object will have both a userTag and an objectID. Thus the object can be referred
to by either its userTag or its objectID; they are distinguishable from each other by the fact that
userTags are negative and objectIDs are positive.
☞ UserTags should be used for all “post” functions. You should only use the objectID when you
are sure that the object will exist at the time the function is called.
There are ModL functions to convert userTags to ObjectIDs (see the function list in “3D Ani-
mation” on page 276).
GroupTags
GroupTags are another numeric tag on the objects in the E3D window that are specified at the
time of object creation and also stay with the object throughout its lifetime. Unlike userTags
140 IDE
3D animation

and objectIDs, groupTag are not unique identifiers but rather are used to define groups of
objects that the developer wants to be able to reference as a whole.
A common example of how groupTag are used is in the Item library, where each of the items
that travels from block to block is tagged as being part of the same group. This allows the
blocks to delete all of these items as a group when one simulation ends and a new one begins,
without deleting other objects that need to remain for the next run.
☞ By default an object created in the World Editor will be supplied with a groupTag value of 0.
The Item library uses the value of 1 for items that travel from block to block.
E3DDeleteAllObjects takes a groupTag argument and will delete all objects in the E3D win-
dow with that groupTag number. If you pass in a negative 1 or lower, the function will ignore
the groupTag and delete all objects in the E3D Window.
E3DGetObjectNames takes an argument for which kind of objects the function should return.
If you pass in a number greater than zero, that number will define a groupTag and the function
will return the names of the objects in that group. See the function list in “3D Animation” on
page 276 for more detailed information about exactly how these functions operate.
IDE

Object classes
ExtendSim defines several classes of objects in addition to the class structure of object types
defined by the TGE.
All ExtendSim 3D objects descend from ExtendBase, which gives them certain common fea-
tures as described in “DataBlocks” on page 151. Which class a new object falls into will be
defined in its DataBlock. The complete class structure of the objects in the E3D window is
beyond the scope of this documentation.
ExtendItems
ExtendItems are intended to represent the items that pass from block to block in an ExtendSim
model. They have several features:
• They do not support physics features like gravity, friction, and momentum. This is to pre-
serve the synchronization between the simulation and the 3D animation. See “Gravity” on
page 145.
• ExtendItems support the DataBlock variable hasFront, which allows the object to continu-
ously turn toward the direction that it is traveling.
• They support mountStacking and therefore should have a mount0 on the top of the object
and a mountPoint on the bottom. See “MountStack” on page 144 for more information.
ExtendPlayers
ExtendPlayer objects (Male and Female) are based on the AIPlayer class in the TGE. Some
information about them includes:
• Unlike Torque AIPlayer objects, ExtendPlayer objects do not attempt any AI calculation
• Like ExtendItems, they avoid momentum and friction calculations
• They do support gravity. If created at a Z height of greater than 100.0 they will drop to the
ground. See “Gravity” on page 145.
ExtendVehicles
ExtendVehicle objects (Car, AGV, and Forklift):
Animation Using ModL 141
3D animation

• Are similar to ExtendPlayer objects in how they differ from standard Torque objects
• Like ExtendPlayer objects, they support gravity but not friction or momentum
• Do not have any AI calculations

Scale and position


The User Reference describes how to visually scale objects in the World Editor and through
block dialogs or by changing the numbers in the Inspector pane. You can also scale objects
through ModL function calls.
Units of scale are relative to 1 and are associated with each axis, so scaling an object from 1, 1,
1 to 2, 2, 2 will make it twice as big along each axis. If you scale an object from 1, 1, 1 to 1, 1,
2 it will stretch along the Z-axis but remain the same along the X and Y-axis. So it will just
look a bit distorted, but taller.
The numbers used in this example are in the same format as those in the Inspector pane of the
World Editor Inspector, although there they are shown without commas. For example you

IDE
might see “1.1 0.5 1.0” in the Inspector pane, which would be scaling to 110% on the X axis,
50% on the Y axis, and 100% on the Z axis.
Object position uses the same format as scale, and the X, Y, and Z values represent the X, Y,
and Z coordinates of the object. Changing the X value from 1 to 2, for example, will move an
object 1 meter along the X axis. The default Z values for objects will be a bit above 100.0 since
the flat terrain in the default E3D window is at height Z = 100. See “Gravity” on page 145 for
more information.
Rotation
The User Reference describes how to visually rotate objects in the World Editor, through block
dialogs. Another method of rotating objects would be by changing the numbers in the Inspec-
tor pane.
The World Editor Inspector has four numbers for rotation – three factors and an angle in
degrees – where each factor represents the x, y, or z axis respectively. Each multiplier deter-
mines the amount by which the object is rotated around its particular axis based on the given
angle.
For example, “0 0 1 90.0” means that the object is rotated 90 degrees around the Z-axis while
“1 0 1 45.0" means that the object is rotated 45 degrees around both the X and the Z-axes. The
most common form of rotation in the ExtendSim modeling world is around the Z-axis, as this
will lead to rotation of the front of the object on the flat plane.
Skins
Skins is the 3D animators term for the texture files that show the surface details of objects in
the 3D world. Many of the 3D objects provided with ExtendSim come with more than one skin
You change which skin is showing on an object either through a block’s Block Animation tab
(Item library) or by using ModL functions calls. You can also define a new DataBlock to spec-
ify a new version of an object that uses a specific skin (see “DataBlocks” on page 151 and
“DataBlock variables” on page 153 for more information about them.)
How skins are defined
ExtendSim supports the naming convention “base.objectName.jpg” which allows developers
to add new skins or modify existing ones. This is specified as follows:
142 IDE
3D animation

• Base is the name of the default skin. To select a new skin, change this part of the name. For
example, the Ball object by default will load using the base.ball.jpg skin. To change the ball
object to blue, create a blue.ball.jpg and then either call the appropriate function or select the
skin on a block dialog.
• ObjectName is usually the same as the name of the object and it must be the same for each
skin of a single skin object. For instance, there are several skins in the folder with the Bed
object; the first is called base.bed.png and the others are called floral.bed.png, hospi-
tal.bed.png, and so on.
• The final part, jpg, is just the extension of the file type.
☞ Skins in ExtendSim will all be either jpg or png files.
Most of the objects that ship with ExtendSim have a single overall skin that can be changed.
The two people objects (Male and Female) however, have two skins each – one for the clothing
of the object and a second for the face and hands.
Two skin objects
IDE

The two skin objects, Male and Female, have the following skin patterns:
• Base.maleclothes.jpg
• Base.maleskin.jpg
• Base.femaleclothes.jpg
• Base.femaleskin.jpg
This allows the different skins to be combined in arbitrary fashions. For example, a given
object in the E3D window could be a Female with these two skin layers: Base.femaleskin.jpg
and Medical.femaleclothes.jpg.
Skin setting functions
The ModL function that sets the skins on an object is E3DSetSkin or E3DPostSetSkin, depend-
ing on the 3D mode. This function takes two string arguments for the skins.
• For single skin objects, just enter an empty string for the second string.
Animation Using ModL 143
3D animation

• In the case of double skin objects, enter both skin names. So, for the exam-
ple above, call E3DSetSkin once with the first string set to Base and the
second set to FemaleSkin, and then a second time with the first string set to
Medical and the second set to femaleClothes. (Note that, unless the object
had already had its femaleSkin changed from the base, the first call would
not be necessary, because the Base skin is already the default.)
Skin DataBlocks
There are four DataBlock variables for specifying skins, as seen in “Data-
Block variables” on page 153:
• SkinBaseName1
• SkinBaseName2
• SkinName1
• SkinName2

IDE
You can use these to cause special effects, such as overriding whether or not
to start with the base skin. For example, setting the skinName1 variable in the Female with
DataBlock will cause the object to be created with the skinName1 value in Medical skin
place of the base part of the skinName.
Mounting
Mounting is the process of attaching one 3D object to another at
certain points. An example would be mounting a Box object
onto a Male object. In this case, the Box object automatically
attaches to the mount0 mount node on the Male object. The
Male object then adjusts its animation to change its hand posi-
tion, so it looks like it is holding the Box. And if the Male is
given a destination, the Box will be carried along. All of the
ModL functions and internal structures are associated with
mounting objects, not images.
☞ See also “Carriable items” on page 154 and the functions for
mounting starting on page 286.
Each object has one mountPoint and at least one mount node.
These are internal structures of the DTS file (discussed on
page 149); if you create custom 3D objects these structures Male carrying a Box
should be added when the DTS file is created.
☞ An object’s mountPoint is the part of the object that can mount onto another object. An object’s
mount nodes are the point or points on the object where other objects can be mounted.
144 IDE
3D animation

For example, the Ball object that ships


with ExtendSim has a mountPoint at
its bottom and a single mount node
(mount0) at the top. These need to be
defined with the names mountPoint,
for the point where the Ball will
mount another object, and mount0, for
the node where other objects can con-
nect to the Ball.
Smart Mounting
The mount functions require you to
specify the node on the mount object
where the object to be mounted will
be placed. This node will usually be
node zero (defined in the DTS object Ball in Milkshape
as mount0, as discussed above).
IDE

If you instead want the internal logic in the ExtendSim application to select the node that the
object will be mounted to, specify that the node should be smart mounted. You do this by pass-
ing in a negative 1 for the node. ExtendSim will then select the best node to be used based on
the type of the mount object and the object to be mounted.
MountStack
One additional type of mounting, specific to ExtendSim, is the mountStack. A mountStack is a
stack of objects where each object is mounted on top of the previous one. The mountStack
functions E3DMountStackInsert, E3DMountStackRemove, E3DMountStackLimit, as well as
their Post versions, allow you to maintain a queue of stacked objects with less ModL code than
if you used the Mount and Unmount functions. The mountStack functions are on page 280.
Unmounting
Unmounting an object disconnects the objects from each other but does not change the position
of the objects. In the case of the Male and the Box above, unmounting the Box will leave it and
the Male n the same position but the Male will drop his hands. And if the Male moves away,
the Box will stay where it is.
The unmount functions also have options that allow you to specify a distance and a direction
for moving the unmounted object. See the function descriptions for more information.
Collision
E3D objects defined through ModL function calls can have collision enabled or disabled:
• Collision enabled causes the objects to respect each other's boundaries and to stop when they
bump into each other
• Collision disabled allows objects to pass through each other
It is a modeling decision whether or not you should enable collision for objects created at loca-
tions in your model. Collisions do allow items to line up as if in a waiting line, but in some
cases you will not want the objects to be stopped in their travel by colliding with another
object.
Animation Using ModL 145
3D animation

Gravity
Gravity is implemented in ExtendSim for certain types of objects and not for others.
• The people and vehicle objects will respect gravity. If created at a height or told to travel to a
Z location higher than 100, people and vehicles drop down to the ground.
• ExtendItem objects will not be effected by gravity and can travel at a fixed height or even to
a different height by simply setting a Z location higher than 100. The Boids example (Exam-
ples\3D Animation) shows this – the Boid objects fly through the air by setting 3D destina-
tion locations.
☞ To maintain the constant speeds associated with having travel times match simulation times,
the concepts of friction and momentum are not implemented in the objects that travel from
location to location in ExtendSim.
Sound
The E3D window supports playing sounds and has a few additions to the Torque Audio sys-
tem. Sounds can be either:

IDE
• Associated with objects in the E3D window. The IdleSound DataBlock variables are an
extension to the Torque Audio system so that sounds can be defined and played at automatic
times during a model execution. (See the list of sound variables in “DataBlock variables” on
page 153.)
• Played by ModL function calls, such as E3DPlaySound.
Sounds are globally enabled or disabled in the Edit > Options > 3D tab.
☞ Sounds played in the E3D window are 3 dimensional. Thus if you move the camera in the E3D
window away from or around a sound source, the volume and direction of the sound will
change.
The audio descriptions used in ExtendSim will commonly be either the AudioCloseLooping3d
description used by the BoidSound (a looping sound) or the AudioClose3d used by the Car-
SquealSound (a non-looping sound).
The other way to play a sound in the E3D window is to use the ModL function E3DplaySound.
This function, which you could use in an equation-based block if you aren't custom-coding
blocks, specifies the name of an audioProfile and an X, Y, Z location and plays that sound at
that location.
An example of an object’s ambient sound that is enabled in the E3D window is an Activity
block (Item library) when it is represented in the E3D window by the Machine object. If
sounds are enabled in the Options tab and the Machine is playing its “running” ambient anima-
tion (discussed on page 147), you will hear an active machine sound.
DataBlock of the Machine object
This DataBlock of the Machine object is from ExtendSim\Extend3D\server\scripts\ExItems.cs.
datablock StaticShapeData(Machine)
{
// Mission editor category, this datablock will show up in the
// specified category under the “shapes” root category.
category = "Block";
146 IDE
3D animation

// Basic Item properties


shapeFile = "~/data/shapes/machine/machine.dts";
mass = 1;
friction = 01;
elasticity = 0.3;
mountPoint = 0;
idleSound[0] = "CarEngineSound";
idleAnimation[0] = "running";
idleSound[1] = "CarSquealSound";
idleAnimation[1] = "blocked";
};
This code is an example of associating sounds with objects and their behaviors. The idleSound
and idleAnimation variables are two of the custom DataBlock variables available in Extend-
Sim; the complete list is on page 153. In this example the variables support associating a spe-
cific sound with an object’s specific ambient animation – the Machine block will play the
CarEngineSound while the running animation plays and the CarSquealSound while the
blocked animation plays.
☞ DataBlocks are discussed on page 151 and ambient animation is discussed on page 147.
IDE

DataBlock of Boid object


Another example in ExtendSim\Extend3D\server\scripts\ExItems.cs is the Boid object, which
has the following code:
// JSL - Boids
datablock AudioProfile(BoidSound)
{
fileName = "~/data/sound/Boid.wav";
description = AudioCloseLooping3d;
preload = true;
};

datablock ExtendItemData(Boid)
{
// Mission editor category
category = "ExtendItem";

// Basic Item properties


shapeFile = "~/data/shapes/Boids/Boid.dts";
mass = 1;
elasticity = 0.2;
friction = 0.0;
mountPoint = 0;
emap = false;

// JSL - mountLook - look to use when mounted.


// (For Extend items, they tell the holder to change his/its look.)
className = "carriableItem"; // class
mountLook[0] = lookbh;
unmountLook[0] = look;
skinname1 = "base";
hasFront = true;
idleSound[0] = "BoidSound";
idleSoundVol[0] = 0.2;
};
Animation Using ModL 147
3D animation

Differences between the sound examples


A few differences between the Machine and Boids examples are worth noting:
• For the Boids, there is no idleAnimation condition. Thus if the sound is a loop, it will be
played continuously; a non-looping sound will play once and quit.
• The ExtendSim idleSoundVol DataBlock defines the volume at which the sound is played.
The default, used for the Machine block, is to play the sound at full volume.
• The audioProfile DataBlock is used for the BoidSound. To play a sound in the E3D window
you need to define an audioProfile DataBlock which is a standard Torque construct. The file
name field defines where the sound file is located and the description field defines how the
sound is to be played. More information can be found on the GarageGames website.

Ambient animation
DTS objects (objects that are not large-scale interiors or buildings, as discussed on page 149)
can have ambient animations – background behavior such as steam coming from a cup or peo-

IDE
ple breathing. These animations are of two types:
• Those used by the object based on the object type and predefined behaviors for that type. An
example is the “run” animation of the people objects. Whenever these objects are moving
they have internal code that plays the “run” animation, automatically adjusting the speed of
the animation based on the speed at which the object is moving.
• Those played by custom code. An example is the Cup object, which has a “Content” anima-
tion. If you start the Content animation running using the E3DAnimationPlay call, the Cup
will appear to be full of coffee and will have a wisp of steam rising from it. (To see this, cre-
ate a Cup object using the 3D Tester model located at \Examples\3D Animation\Tips and
activate the Content animation using the controls in the Animation group.)
Stop one ambient animation before starting another
Once you have started an ambient animation using the E3DAnimationPlay function, you might
think that you could start another animation using the same function and that would replace the
first animation. Due to the nature of the implementation of the animation threads, you should
stop the first animation using the E3DAnimationStop function before starting the second ani-
mation. In the Cup example, this means that you should stop the “Content” animation before
playing the “Empty” animation.
People objects
The people objects have several special ambient animation features:
• An idle animation (Root) that is always playing. This animation shows a small movement
and essentially makes it look like the people are breathing.
• A look animation that is always playing and controls the hand position of the person. See
also “DataBlock variables” on page 153 and “Looks” on page 155.
• An overall body position which includes sitting, sleeping, and so forth.
Both the look animation and the overall body position animation are automatically set by the
3D engine when the person does certain things. So for the most part you will not need to be
specifically setting animation threads on people objects.
148 IDE
3D animation

Paths, markers, and waypoints


A path is a route for an item or other entity that has movement. Each path is a collective object
composed of multiple segments, or markers, in a predefined order.
A waypoint marks a single specific point in the E3D environment; in some ways it is like a
path with just one marker. Waypoints are usually used to identify a destination point for a 3D
object.
There are a number of ModL functions that reference paths (for example E3DSetTargetPath,
which specifies a path for an object to follow). Paths can also be referenced from TorqueScript,
which is discussed on page 150.
Markers have locations in three dimensions. Certain kinds of objects (like people and vehicles)
will just ignore the Z dimension but the most commonly used type of objects (ExtendItems)
does not. Thus you should always set the Z location to the correct value. (See “Object classes”
on page 140 for more information on the differences between ExtendItems, ExtendPlayers,
ExtendWheeledVehicles, and other types of objects.)
☞ The height of the ground in the E3D window is 100 meters and the top of objects like the con-
IDE

veyor belt and the machine is 1 meter from the ground, or 101 meters.
Creating a path
Paths can be created through ModL function calls or through the World Editor Creator. For
more information about creating paths with the World Editor, see the User Reference. The
ModL functions used to create a path are E3DCreatePath, E3DCreateMarker, and
E3DAddMarkerToPath; these functions are described on page 280.
By default paths are not visible. Setting a path to visible with the E3DSetVisibility function
will display the path in the E3D window; this is an extension of the E3D window over standard
Torque. You can also set the color of a path using the E3DpathSetColor function, which
changes how a visible path displays in the E3D window.
Waypoints
A waypoint can be thought of as a path with just one marker; they are often used as destina-
tions for object movement. Like paths and path markers they are invisible in the standard E3D
window but visible in the World Editor. There are a number of functions that refer to way-
points. (See the function reference for descriptions.) Waypoints can also be given object labels
with the SetObjectLabel ModL function, and can therefore be used as a way of displaying text
with no visible object on the viewing area of the E3D Window.
A waypoint can be created through ModL code or through the World Editor Creator in the
same way as other objects. In the World Editor Creator opening the Shapes > Markers category
reveals the WayPointMarker object. Clicking on the WayPointMarker object in the tree will
create a waypoint in the 3D viewing area. See the User Reference for more information about
using the World Editor Creator.
☞ The E3DSetVisibility function cannot be used to make a waypoint visible. Waypoints are never
displayed in the standard E3D window unless you have added an object label to them as
described in the Note on page 139.
Defining new 3D objects
While ExtendSim contains quite a few 3D objects, you might want to add additional ones.
Most of the 3D objects supplied with ExtendSim (such as people, items, vehicles and static
Animation Using ModL 149
3D animation

shapes) are in the DTS format. The following discussion describes how these small-scale 3D
objects are defined.
☞ Buildings or interiors are not usually DTS files. Instead they are DIF files as discussed on
page 155.
The steps involved in building a custom 3D object for use in ExtendSim are:
• Create the object in a 3D graphics program that supports exporting the object as a DTS file
• Export the object as a DTS file
• Create a script file/DataBlock for use in ExtendSim
• Add the script and DTS file to the correct places in the ExtendSim folder structure

DTS file format


ExtendSim requires object files to be in the DTS (Dynamix Three Space) format which is spe-
cific to the Torque engine. This means that you will either need to work with files that were
created specifically for the Torque engine or use one of various conversion utilities (usually a

IDE
plug-in for a 3D art program) to export a DTS file from a file saved in another format.
ExtendSim DTS file
As an example for developing new objects, see the Wall.dts file and the other files associated
with it; those files are located in the Extensions\E3DObjects folder. (The rest of the 3D objects
provided with ExtendSim are located in the ExtendSim\Extend3D\Data\Shapes folder, but new
objects should be put into the Extensions folder.)
Associated with the Wall.dts file are:
• A Wall.cs file. This is a script file that contains the definition of the wall object, mostly in the
form of a DataBlock. Script files run when the E3D window loads. (Script files are discussed
on page 150 and DataBlocks are discussed on page 151.)
The script for the Wall.cs file is discussed in “Example using Wall object” on page 152.

• The Wall folder which contains the Wall.dts file and the skins of the Wall object. As dis-
cussed in “Skins” on page 141, an object’s default skinBaseName1 will be the name of the
DTS file. In this example, because the Wall object is called wall.dts, the default skin-
BaseName1 is base.wall.jpg.
☞ All .cs files must be placed at the top level of the E3DObjects folder within the Extensions
folder, since that is the only place ExtendSim knows to look for them.
Adding a DTS file to ExtendSim
Place new script and DTS files within the Extensions\E3DObjects folder, with the script (.cs)
files at the top level. As noted above, ExtendSim looks for any .cs files only at the top level of
the E3DObjects folder. However, since the .cs file contains information about where the DTS
file is, the location of the DTS file is flexible.
☞ If you place a DTS file into the Extensions folder, but do not include a script file containing a
DataBlock, you will not be able to place the 3D object into the E3D window.
Exporting a 3D object file created in another program
Object files that have been created for other environments can be used in ExtendSim, but they
must first be exported into the DTS format. This is accomplished using DTS exporters.
150 IDE
3D animation

☞ This discussion is about DTS objects. DIF objects, for buildings and interiors, are discussed on
page 155.
DTS exporters are separate pieces of software that are available for several of the popular 3D
modeling packages (3DS Max, MilkShape, Maya, etc.). In most cases these modeling applica-
tions do not ship with an installed DTS exporter. You must obtain the appropriate DTS
exporter from Garage Games and add it to the modeling software package.
The procedure involves opening the object in the 3D modeling application and selecting an
export command. This varies depending on which application your files are in.
Exporting a basic shape that doesn't have any custom behavior can be quite straightforward.
Objects with more complex behavior, such as ambient animation or custom mountpoints, are
more involved. Most of these complex behaviors are defined in different ways for different file
formats, so most likely it will require some custom modifications to the 3D object.
Check for more information on the Garage Games website about which products have export-
ers available and how to install and work with those exporters.
IDE

Scripting and .cs files


The TGE includes a sophisticated scripting environment called Torque Script. This environ-
ment allows extensive control over what happens in the E3D window, and which objects,
sounds, textures and other components are available. The most common use for script files is
to define DataBlocks for new 3D objects. You can also add whatever Torque script code you
wish.
How to use the scripting environment, the syntax of the scripting language, and even the struc-
ture and behavior of the default scripting files is beyond the scope of this documentation.
Instead, there is extensive information about the scripting environment, as well as the default
layout and behavior of TGE scripts, on the GarageGames website (www.GarageGames.com).
Objects and so forth
Script (.cs) files placed in the Extensions\E3DObjects folder are custom scripts that get exe-
cuted when the E3D window is launched. The simplest use for this capability is to just provide
DataBlocks for new E3D objects that are to be used in the E3D window. However, there is no
reason why you cannot do anything that can be done with TorqueScript in a file placed in this
location.
☞ If you are adding multiple 3D objects it is not required that each object have a separate script
file. Instead, you can define multiple DataBlocks in a single script file.
E3D window
The script files that control the behavior of the E3D window are in the Extend3D, Common,
and Creator folders within the ExtendSim folder. Much of the content of these files is the same
as for default TGE projects but with many customizations and custom features.
Unless you are doing some advanced custom 3D work you will not need to either modify or
even look at the contents of the Extend3D, Common, and Creator folders.
Torque script files
Torque script files are text files with a .cs extension that get compiled by the ExtendSim appli-
cation. The compiled version of a Torque file is called a .dso file. These files will not be placed
in the Extensions folder since the script files that are placed in Extensions will be executed
directly, as opposed to being compiled. The .dso files are instead located in the Extend3D,
Common, and Creator folders.
Animation Using ModL 151
3D animation

PathNames in TorqueScript files


Pathnames can have certain special characters in them. There are several standard special char-
acters and ExtendSim defines two new ones.
• The standard characters are “.” and “~”.
• The “.” character specifies that the path starts from the directory location where the
Torque script is executing (the current codeblock\mod path in the Torque environ-
ment).
• The “~” character means the path starts from the root of the Extend3D folder in the
ExtendSim folder (extends from the root of the codeblock/mod path in the Torque envi-
ronment).
• The special characters defined by ExtendSim are “^” and “&”
• The “^” character refers to a path that starts from the application folder. For example, ^/
Extensions refers to the root of the Extensions folder.

IDE
• The “&” character refers to the folder containing the current model.

DataBlocks
A DataBlock is an object definition – the code definition of the initial values of properties of a
3D object as well as a definition of the type/class of the object. You could think of a DataBlock
as being like the definition of an ExtendSim block in a library. A DataBlock defines the com-
mon aspects and behavior of the 3D object, but each instance of the object will have its own
individual parameters associated with it.
The file ExItems contains many of the DataBlocks that have been defined for ExtendSim
objects; it is located at ExtendSim\Extend3D\server\scripts\ExItems.cs.
If you are not doing any extensive 3D scripting or adding custom 3D objects into the Extend-
Sim Extensions folder, you do not need to worry about DataBlocks.
☞ If you are adding multiple 3D objects it is not required that each object have a separate script
file. Instead, you can define multiple DataBlocks in a single script file.
Types of DataBlocks
When a DataBlock is declared, its type is also declared. While you can define your own types,
some typical types of DataBlocks that ExtendSim uses include:
• StaticShapeData
• WheeledVehicleData
• ExtendItemData
• PlayerData
• MissionMarkerData
This definition of the type of the datablock is important, since it will determine what kind of
object ExtendSim creates in the 3D window. For simple cases of placing new objects you will
most likely use ExtendItemData or StaticShapeData. The deciding factor is if the item is going
to be an immobile object (StaticShapeData) or a block-to-block object (ExtendItemData).
152 IDE
3D animation

DataBlock variables
There are many parameters that can be defined in a DataBlock. DataBlock variables are spe-
cific to the type of object that is being defined and can, in fact, be defined dynamically in the
DataBlock itself.
☞ Defining a new variable in a DataBlock will not have an effect on the object unless the variable
is referenced in the script or source code of the object.
Some typical DataBlock variables used by ExtendSim are:
• Category defines groupings that are used both in the Mission Editor and in certain ModL
functions to separate objects into convenient sets. The most common categories that you
would want to use are ExtendItem, Scenery, and Block.
• ShapeFile defines the location of the DTS file. For an example, see the ShapeFile of the Wall
block“Example using Wall object” on page 152.
• Scale defines the default scale of the 3D object. See also “Scale and position” on page 141.
For a list of DataBlock variables that have been specifically defined for ExtendSim or which
IDE

have been modified from how they are used by the Torque engine, see page 153.
ExtendSim-specific DataBlock additions
ExtendSim defines some custom DataBlock variables which can be set to customize the behav-
ior of objects. These are extensions to the 3D functionality defined in the ExtendSim applica-
tion.
As shown on page 145, sounds and ambient animation are examples of additional behaviors
that are enabled through DataBlocks. See also the list of customized DataBlocks on page 153.
Example using Wall object
The script file for the Wall object mentioned earlier only defines one thing – a DataBlock for
the Wall object. The code is:
// datablocks
// JSL - Scenery

datablock StaticShapeData(Wall)
{
// Mission editor category, this datablock will show up in the
// specified category under the “Scenery” root category.
category = "Scenery";

// Basic Item properties


shapeFile = "./Wall/Wall.dts";
scale = "1.0 1.0 1.0";
};
This script defines a single DataBlock that specifies for the 3D engine some aspects of the
behavior of the Wall object and also tells the 3D engine that the Wall object exists.
The first line (datablock StaticShapeData(wall)) is the declaration which has three compo-
nents:
• The keyword “datablock” defines what follows to be a datablock
• StaticShapeData defines the type of datablock
Animation Using ModL 153
3D animation

• Finally, the name of the datablock (Wall) is in parentheses. This is the name that will be used
in ExtendSim dialog boxes and script code.
The remaining lines of the DataBlock script define variables as discussed in “DataBlock vari-
ables” on page 152. For a simple object like the Wall, defining just three variables is sufficient:
• Category. For the Wall object, the Category is Scenery.
• ShapeFile.The path “./Wall/Wall.dts” indicates that the Wall.dts file is located within a folder
named “Wall”. The period (“.”) in the path name signifies that the path starts at the current
location; in this case in the Extensions\3DObjects folder where the .cs (script) file is located.
• Scale. As discussed in “Scale and position” on page 141, “1.0 1.0 1.0” specifies that the
object is scaled to its standard size in each of the three dimensions.

DataBlock variables
As discussed in “DataBlocks” on page 151, there are many variables supported in DataBlocks.
The following tables list a subset of the available variables – those that have been custom

IDE
developed for ExtendSim or which have custom behaviors compared to the standard Torque
DataBlocks.
Custom datablock variables
This table describes variables that have been defined and given custom behaviors for Extend-
Sim.

Variable Description
HasFront This DataBlock flag specifies that the object has a front. When the
item is specified as moving in a direction, the object will turn its front
in the direction it is facing. If this flag is not defined, it defaults to
false.
IdleSound[0-4] As described in “Sound” on page 145, this flag specifies one of up to
five sounds that can be associated with the item idling or with certain
ambient animation states.
IdleSoundAnimation[0- As described in “Sound” on page 145, specifies an animation state to
4] associate with a sound. See above for more information.
IdleSoundVol[0-4] Specifies the volume level for the idleSound. Volumes range from 0.0
to 1.0.
MountLook[n] Part of the ambient animation functionality discussed in “People
objects” on page 147. The mountLook flag specifies what look a per-
son is supposed to use when this kind of object is mounted on them.
The mount functionality is part of the carriableItem functionality
described on page 154.
SkinBaseName1 Defines the baseName for the first skin. An example would be the
Male object, where the SkinBaseName1 is maleClothes.
SkinBaseName2 Defines the baseName for the second skin. An example would be the
Female object, where the SkinBaseName2 is femaleSkin.
154 IDE
3D animation

Variable Description
SkinName1 Specifies what the default skin to be used for the object is. Objects
with multiple skins will obey the base.shapename naming convention,
so this variable tells the object what skin to use if you don't want the
object to start with the base skin.
SkinName2 This DataBlock variable specifies what the default skin for the second
skin should be. This is only relevant for objects with multiple skin
types. Currently only the people objects have more than one skin type.
StackMountPoint The mountPoint that will be used for the mountStack functions. This is
defined as 1 for the people objects so that mountStacking on them will
stack on their arms. However, if people objects stack on each other,
they stack on mountPoint 0.
UnmountLook[n] Part of the ambient animation functionality described on page 147.
The UnmountLook flag specifies what look a person is supposed to
revert to when this kind of object is unmounted from them. The
IDE

unmounting functionality is part of the carriableItem functionality


described on page 154.

Modified datablock variables


Some Torque standard datablock variables have been given additional possible values.

Variable Description

Certain items are defined in their DataBlocks as being CarriableItems;


ClassName
see “Carriable items” on page 154.
Category (Block, Exten- Categories are used in ExtendSim for several of the ModL functions
dItem, Scenery, etc.): that get information about objects. The functions use categories to dis-
tinguish between objects.

Carriable items
Mounting and unmounting objects was discussed on page 143 and page 144, respectively. Cer-
tain types of objects in ExtendSim are carriable items which can be carried by a person. This is
defined in the DataBlock by setting the ClassName variable to CarriableItem.
A carriable item call causes the look of the person to change when an object is mounted on
them. For example, when you mount a Box onto a person, they will move their arms to the
'lookbh' position. (The bh stands for box hold, as discussed on page 155.)
If an object that you expect to be carried by a person is not defined as carriable, people objects
will not change their look animation when mounted with the object and the look and feel of the
animation will suffer.
Animation Using ModL 155
3D animation

Example script
datablock ExtendItemData(Box)
{
// Mission editor category
category = "ExtendItem";

// Basic Item properties


shapeFile = "~/data/shapes/box/box.dts";
mass = 1;
elasticity = 0.2;
friction = 0.0;
mountPoint = 0;
emap = false;

// JSL - mountLook - look to use when mounted.


// (For Extend items, they tell the holder to change his/its look.)
className = "carriableItem"; // class

IDE
mountLook = lookbh;
unmountLook = look;
};

The mounting code will check to see if the object being mounted has a ClassName of Carri-
ableItem and if the object being mounted onto is a person. If both of these are true, it will use
the mountLook defined in the DataBlock as the new look for the person object. The unmount-
Look will be used as the look for the person when the object is unmounted.
Looks
The various looks supported for the carriableItems are:
• Lookbh. This is the “box hold” look associated with carrying a box. The person will spread
their arms low and outside the sides of the box.
• Lookph. The “pallet hold” look is associated with the pallet object. This look is similar to the
box hold, with a small variation in the position of the hands and arms.
• SuitcaseHold. This hold is for holding a suitcase, single-handed on the person’s right-hand
side. This look can be seen in the Airline Security model (Examples\3D Animation).
• SmallHold: This is for holding a small object like a letter or a stack of paper where both
hands are brought together in front of the person. This look can be seen in the Bank line
models (Examples\Tutorials\E3D Animation).

Buildings and interiors


The 3D objects supplied with ExtendSim are primarily DTS objects. The people, items, vehi-
cles and static shapes are all saved and shipped in the DTS format. If you want to add a new
object to ExtendSim and if it is fairly small and self-contained, then you probably want to use
the DTS format process described “Defining new 3D objects” on page 148.
If, on the other hand, you want to include in your model a larger-scale object (such as a build-
ing or anything else that is enterable), you should not use the DTS format as it is not designed
for this use.
156 IDE
3D animation

The DIF format is designed for buildings and objects on large scale. As with the DTS format,
various editors (such as Quark and Cartography Shop) can export DIF files. TGE owners also
get a DIF editor, called Creator, that is specifically designed to develop DIF files.
The creating and exporting process for DIF files can be involved, will be different for each edi-
tor, and is beyond the scope of this manual. Information for how to do this can be found on the
Garage Games website.
Terrain
ExtendSim's default environment file does not make much use of the terrain capabilities built
into the Torque engine. In fact, the blocks in the ExtendSim libraries assume that the terrain
will be flat and will be at a height of 100 units. So if you create models using the standard
ExtendSim environment and use the blocks in the Item library, you should not change from the
flat terrain defined in the default environment file. Changing textures of the terrain in the envi-
ronment file does not affect the behavior of the ExtendSim blocks.
For certain kinds of custom models, however, the ability to manipulate the terrain in the E3D
window might be quite useful. There are several things that can be changed and several mech-
IDE

anisms for how you change them. See the User Reference for information about editing Terrain
and changing Terrain Textures.
Integrated Development
Environment (IDE)

Simulation Architecture
Keep this information in mind as you
create and modify ExtendSim blocks

“In baiting a mousetrap with cheese,


always leave room for the mouse.”
— Hector Hugh Munro
158 IDE
Running a simulation

This chapter describes how the ExtendSim simulation engine works and how discrete event
and discrete rate blocks pass messages and resolve logic issues. This is important information
when you are creating or modifying blocks, since you need to know:
• How the block will work with the ExtendSim simulation engine
• How the block will work with the other blocks that ship with ExtendSim
Running a simulation
It is useful to understand the steps that ExtendSim takes when it runs a simulation so you can
get a feeling for what parts of the process are relevant to models. The following sections give a
step-by-step breakdown of how ExtendSim runs simulations and how it decides what to do
next.
☞ Running continuous simulations starts on this page; running discrete event and discrete rate
simulations is discussed starting on page 162.
How ExtendSim runs continuous simulations
ExtendSim keeps many system variables handy so that it can compute how to run the model.
IDE

Five of the options in the Continuous tab of the Run > Simulation Setup dialog become vari-
ables that are used to determine how the model is run:

Option Variable
End time EndTime
Start time StartTime
Runs NumSims
Time per step (dt) DeltaTime
Number of steps NumSteps

Before anything else happens in the simulation run, these variables are used to calculate an ini-
tial value for the DeltaTime or NumSteps variables. The variable that is calculated depends on
what is selected in the Simulation Setup dialog: if Number of steps is selected, ExtendSim cal-
culates the related variable DeltaTime; if Time per step is selected, ExtendSim calculates Num-
Steps. The formulas used are:
DeltaTime = (EndTime-StartTime)/(NumSteps-1);
NumSteps = Floor (((EndTime - StartTime) / DeltaTime) + 1.5)
This initial value is the value that the blocks see during the PreCheckData, CheckData, and
StepSize simulation messages.
Pseudocode of the simulation loop for continuous simulations
The following is a pseudocode description of ExtendSim’s continuous simulation loop.
Pseudocode is used by developers to describe the controlling logic of a program in a form that
is a cross between English and a programming language.
Simulation Architecture 159
Running a simulation

Calculate simulation order of blocks;

for CurrentSim = 0 to NumSims-1


{
if (continuing saved paused run) // this was saved while paused
{
CurrentTime = SavedCurrentTime;
CurrentStep = SavedCurrentStep;
Send ContinueSim message to blocks
}
else
{
CurrentTime = StartTime;
CurrentStep = 0;
Send PreCheckDataMsg to blocks;// Prepare for validation
Send CheckDataMsg to blocks;// Validate block variables
if (CheckDataMsg aborts)

IDE
Abort Simulation and select bad block;
Send StepSize to blocks;//Continuous models can change
// stepsize
Send InitSimMsg to blocks;// Initialize block variables
Send PostInitSimMsg to blocks;// Check initializations
}

for CurrentStep = 0 to (NumSteps-1) // In discrete event


{ // models, simulation time
Send SimulateMsg to blocks; // is controlled by the Executive
// block, not by this loop.
if (Abort was encountered)
{
Send AbortSim to blocks;
Jump out of loop to ExcecuteEndSims;
}

CurrentTime = CurrentTime+DeltaTime;
}

Send FinalCalc to blocks;// Performs final stat calculations


Send BlockReport to reporting blocks;// Report results
ExecuteEndSims:
Send EndSimMsg to blocks;// Clean up variables, dispose arrays
}
☞ The above comments indicate one purpose of the specific message handler, but each of them
can be used for a variety of purposes, as shown in the table on page 160.
The next several sections discuss the meaning of this pseudocode.
Simulation order
Simulation order defines the sequence in which messages are sent from the ExtendSim appli-
cation to the blocks in a model. The simulation order section of the pseudocode calculates the
simulation order, either flow or left-to-right, as discussed in the User Reference.
Initialization
The pseudocode:
160 IDE
Running a simulation

for CurrentSim = 0 to NumSims-1


instructs ExtendSim to execute the contents of the “for” loop NumSims times. You set Num-
Sims in the Runs entry box in the Continuous tab of the Simulation Setup dialog. The value of
the variable CurrentSim varies from 0 to NumSims-1. This is the logic that defines the number
of simulations that will be run. If an Abort statement is executed during a simulation, it will
halt the current simulation, increment currentSim by 1, and run any remaining simulations.
When messages are sent
Different messages are sent, depending on whether the run is paused or is a new run:
• If the simulation was previously paused and saved before the run was completed, ExtendSim
will send a ContinueSim message to all of the blocks in the model. Since the model was
already initialized and only needs to set up its data structures to continue the previous run,
the ContinueSim message is sent in lieu of the PreCheckData, CheckData, StepSize, InitSim,
and PostInitSim messages that would follow if it were a new run, described below.
• If the run is a new run, the first thing done inside this loop is to send the PreCheckData and
CheckData system message to all the blocks in the simulation. These message handlers in
IDE

the various blocks should check the values of dialog items to see if they are valid. If any of
them abort, ExtendSim recognizes that fact and the simulation aborts with the block
selected. Connection status of the block can be tested during CheckData: Input connectors
that are connected will show a non-zero value, and unconnected input connectors will show
a zero value. This is useful in determining if a block’s inputs are actually connected in the
model.
The StepSize message is then sent to all blocks. In continuous models, StepSize is used to
manipulate the DeltaTime variable. The smallest value of DeltaTime specified by any block is
found and DeltaTime is set to that value. Note that this DeltaTime overrides the value initially
calculated. If AutoStep Slow was selected, the returned value of DeltaTime is then divided by
5 for more accurate simulation results. The Filter blocks (Electronics library) use the StepSize
message in this way because they need a calculated value of DeltaTime to get accurate results.
Finally, a new value of NumSteps is determined based on DeltaTime, StartTime, and EndTime.
The formula is:
NumSteps = Floor(((EndTime - StartTime) / DeltaTime) + 1.5)
This value is used to govern the actual simulation loop.
☞ Because DeltaTime is used to calculate NumSteps and a rounded value is used for the number
of steps, it is possible for the EndTime of the simulation to be exceeded slightly.
The InitSim message is then sent to all blocks. This message handler is used to initialize vari-
ables within each block. After the InitSim message has been sent to all blocks, the PostInitSim
message is sent and gives the developer a chance to initialize any variables that needed all of
the other blocks to be initialized first.
Table of message handler purposes
The following table lists the major purposes of the messages sent during the initialization loop
for Value library blocks. Notice that some purposes only apply if the Value library block is
used in a discrete event, rather than a continuous, model.
☞ While the table lists the major purposes of the message handlers, a purpose can sometimes be
accomplished using a different message handler than the one indicated.
Simulation Architecture 161
Running a simulation

Message Handler Purpose in Value Library Blocks


CheckData Check validity of parameters
Assign position in future events calendar (discrete event models)
Check to see which connectors are connected
Determine parameter links with database
Check for duplicate seeds
Determine if dialog variables are cloned
StepSize Throw and Catch Value blocks create data structures
InitSim Determine if model is discrete event or continuous
Turn off simulate messages in discrete event models
Schedule events in discrete event models
Initialize variables
Calculate local block seed value

IDE
PostInitSim Initialize connector values
Schedule events in discrete event models

☞ For the Data Import Export and Command blocks, initialization message handlers can be
selected using options in the blocks’ dialogs.
Step loop
The inner loop:
for CurrentStep = 0 to (NumSteps-1)
is where Simulate messages are sent to all of the blocks in the order determined by the connec-
tions. In continuous simulations the loop is governed by CurrentStep and NumSteps only.
NumSteps is the variable that is used to end the simulation, and the actual number of Simulate
messages (steps) that occurs is NumSteps. That is, if 2 is entered for the Number of steps
option in the Continuous tab of the Simulation Setup dialog, NumSteps becomes 2, the simula-
tion step loop sends Simulate messages to the blocks for CurrentStep equal to 0, and than 1. (If
you want to run a simulation for only a single step, set Number of steps to 1.)
CurrentTime is incremented by DeltaTime for each step of the loop, but otherwise has no effect
on this loop. This means that you can change CurrentTime and DeltaTime without affecting the
loop. It also means that you can change CurrentStep or NumSteps to keep the loop running lon-
ger or stop it prematurely.
☞ You can set CurrentTime in any block to any value, although you might want to have some
logic in the ModL code to prevent conflicts between blocks setting CurrentTime after other
blocks have already changed it. Use the ExtendSim global variables to help establish some
safeguards against these conflicts. For instance, this is how the Executive block (Item library)
is able to control the progression of time in discrete event models.
Final messages
Upon completion of the simulation, ExtendSim sends out the FinalCalc system message to all
blocks. This message handler is used to perform final calculations for all time-dependent sta-
tistics.
162 IDE
Running a simulation

The Report Manager block (Value library) then sends the BlockReport system message to any
blocks that have been selected for a report. This message handler is responsible for writing all
report data to the appropriate ExtendSim database tables.
Finally, ExtendSim sends the EndSim system message to all blocks. The EndSim message han-
dler is used for any “clean up” activities such as disposing of any dynamic arrays to free up
memory.
Aborting multiple simulations
If the Abort statement is executed during the simulation, it only stops the current simulation. If
you want to abort all simulations (for example, when you have specified in the Simulation
Setup dialog that more than one simulation should be run), use the AbortAllSims() function
instead of the Abort statement.
How ExtendSim runs discrete event or discrete rate simulations
ExtendSim keeps many system variables handy so that it can compute how to run the model.
Three of the options in the Setup tab of the Run > Simulation Setup dialog become variables
that are used to determine how a discrete event or discrete rate model is run:
IDE

Option Variable
End time EndTime
Start time StartTime
Runs NumSims

For discrete event and discrete rate models, the DeltaTime and NumSteps variables (used in
continuous simulations and described on page 158) are ignored, because the Executive block
(Item library) calculates CurrentTime based on the time of the next event.
Pseudocode of the simulation loop in discrete event/rate simulations
The following is a pseudocode description of ExtendSim’s discrete event/discrete rate simula-
tion loop:
for CurrentSim = 0 to NumSims-1
{
if (continuing saved paused run) // this was saved while paused
{
CurrentTime = SavedCurrentTime;
CurrentStep = SavedCurrentStep;
Send ContinueSim message to blocks
}
else
{
CurrentTime = StartTime;
CurrentStep = 0;
Send PreCheckDataMsg to blocks;// Prepare for validation
Send CheckDataMsg to blocks;// Validate block variables
if (CheckDataMsg aborts)
Abort Simulation and select bad block;
Simulation Architecture 163
Running a simulation

Send StepSize to blocks;//Continuous models can change


// stepsize
Send InitSimMsg to blocks;// Initialize block variables
Send PostInitSimMsg to blocks;// Check initializations
}

// simulation Phase is controlled by the Executive block


// Do until simulation end reached
Do While (currentTime < EndTime or number of events)
{
Determine the block(s) with the next event time
Set currentTime to the next event time
Send message to every block whose nextTime == CurrentTime
Send message to every block that has posted a 0 time event
(rescheduled)
}

IDE
Send FinalCalc to all blocks;
Send BlockReport to all reporting blocks;
ExecuteEndSims:
Send EndSimMsg to all blocks;
}
☞ The above comments indicate one purpose of the specific message handler, but each of them
can be used for a variety of purposes, as shown in the table on page 163.
The next several sections discuss the meaning of this pseudocode.
Initialization
The pseudocode:
for CurrentSim = 0 to NumSims-1
instructs ExtendSim to execute the contents of the “for” loop NumSims times. You set Num-
Sims in the Runs field of either the Setup or Continuous tabs of the Simulation Setup dialog.
The value of the variable CurrentSim varies from 0 to NumSims-1. This is the logic that
defines the number of simulations that will be run. If an “abort” statement is executed during a
simulation, the abort will halt the current simulation, increment currentSim by 1, and run any
remaining simulations.
When messages are sent
Different messages are sent depending on whether it is a new run or the run is paused. In addi-
tion, the sequence of sending messages is block dependent. To see the order of messages being
sent, look at the block’s code.
☞ PostInitSim is the only message handler where messages can be passed through block connec-
tors.
Table of message handler purposes
The following table lists the major purposes of the messages sent during the initialization loop
for Item and Rate library blocks, as well as for the Executive block in discrete event and in dis-
crete rate models.
☞ While the following tables list the major purposes of the message handlers, a purpose can
sometimes be accomplished using a different message handler than the one indicated.
164 IDE
Running a simulation

Message Handler Purpose in Item Library Blocks


PreCheckData Initialize Resource Pools
CheckData Check validity of parameters
Assign position in future events calendar
Check to see which connectors are connected
Determine parameter links with database
Check for duplicate seeds
Determine if dialog variables are cloned
Check the version of the Executive
Get Executive block number
Determine if costing is used in the model
Initialize DB Equation variables
Check Animation
Register blocks with ExtendSim database
IDE

StepSize Initialize attribute data structures


Initialize Animation
Initialize Shifts
InitSim Initialize variables
Initialize attribute animation conversion table
Schedule initial events
Set local block seed value
PostInitSim Initialize connector values
Check if a downstream block controls the flow of items (blocker)
Schedule initial events

Message Handler Purpose in Rate Library Blocks


CheckData Update the indexes of the global arrays used for the Rate library system
Update information about the flow and value connections
If the block starts a section, create the section in the appropriate global array
Determine if the type of Shift is On or Off
Assign position in future events calendar
Check parameters in the block
StepSize Initialize animation
Update the unit conversion factors (flow unit and time unit)
Initialize Shifts
Initialize attribute data structures in Interchange block
InitSim Initialize variables (static variables, dialog items)
Initialize next event
Initialize value connectors
Initialize attribute animation conversion table in Interchange block
Simulation Architecture 165
Running a simulation

Message Handler Purpose in Executive Block


PreCheckData Dispose Throw Flow and Catch Flow block information (discrete rate mod-
els)
CheckData Initialize system global variables
Post Executive block number
Send CheckData message through event message connector
Check for duplicate random number seeds
Create the global arrays used for the Rate system (discrete rate models)
Initialize the global variables (discrete rate models)
Rebuild and update Throw Flow and Throw Catch info (discrete rate models)
StepSize Initialize attribute data structures
From the beginning, propagate through each section (discrete rate models)
Create the Unit Groups in the model (discrete rate models)
Create the Lookup List for flow units and time units (discrete rate models)

IDE
Create and update global arrays linked to the sections (discrete rate models)
InitSim Initialize variables
Pass event arrays to other blocks
PostInitSim Launch and perform calculation of all effective rates (discrete rate models)

Simulation phase
The Item and Rate libraries rely on the Executive block rather than ExtendSim to control Cur-
rentTime and NumSteps. As opposed to continuous simulations, which rely on time being
incremented uniformly between each step, discrete event and discrete rate simulations are
event based. In discrete event and discrete rate simulations, NumSteps is modified constantly
and the Executive block monitors and manipulates CurrentTime based on the events the blocks
have posted in the Executive’s event queue.
At each simulation step, the Executive searches through a list of event-scheduling blocks and
finds the nearest future event time. The Executive then sends a message to each of the event-
scheduling blocks whose event time is equal to the nearest event time. This may cause other
blocks to post zero time events (rescheduling themselves). The Executive sends a message to
each one of the blocks on the zero time event list (see “Timing for discrete event models” on
page 166 for a detailed discussion).
☞ The code of the Executive can be seen by opening the block’s structure.
Final messages
Upon completion of the simulation, ExtendSim sends out the FinalCalc system message to all
blocks. This message handler is used to perform final calculations for all time-dependent sta-
tistics.
The Report Manager block (Value library) then sends the BlockReport system message to any
blocks that have been selected for a report. This message handler is responsible for writing all
report data to the appropriate ExtendSim database tables.
Finally, ExtendSim sends the EndSim system message to all blocks. The EndSim message han-
dler is used for any “clean up” activities such as disposing of any dynamic arrays to free up
memory.
166 IDE
How discrete event blocks and models work

Aborting multiple simulations


If the Abort statement is executed during the simulation, it only aborts the current simulation.
If you want to abort all simulations (for example, when you have specified in the Simulation
Setup dialog that more than one simulation should be run), use the AbortAllSims() function
instead of the Abort statement.
How discrete event blocks and models work
Discrete event blocks use some fairly complex code. The following explanation should be use-
ful to anyone trying to program their own discrete event blocks or alter the blocks that come in
the Item library.
☞ Always put copies of blocks from the Item library into your own library and alter the copies
rather than the originals.
The Make Your Own category of blocks in the Example Libraries > ModL Tips library have
sample code and comments that explain how the blocks work. You can use these blocks as
templates for your own discrete event blocks.
The following sections discuss the messaging system used to schedule events, transfer items
IDE

through the model, and resolve logic issues. To understand the details of the different types of
messages, some understanding of the simulation engine, the underlying data structures, and
event handling is necessary.
Timing for discrete event models
To make a model event-based, add the Executive block (Item library) to the model worksheet.
This block does two things:
1) It maintains a data structure of information about the items in the model
2) It takes control of the time clock from the ExtendSim application, scheduling events, send-
ing messages to the blocks that scheduled the event, and moving the clock forward to the
appropriate time for the next event.
In order to provide true discrete event operation, the simulation clock must move to the exact
time of each event. In order to do this, the Executive block uses three dynamic arrays to store
future events in the model.
• The TimeArray contains the event times
• TimeBlocks contains the block numbers of the blocks that post events
• TimeEventMsgType stores the constant for the message handler that is called when the event
time for a block is reached
The Executive block passes the arrays to the system globals with the statements:
SysGlobal0 = passArray(TimeArray);
SysGlobal7 = passArray(TimeBlocks);
SysGlobal13 = passArray(TimeEventMsgType);
☞ An important consequence of the Executive block controlling the time clock in the model is
that the variable numSteps, which in a continuous model represents the number of simulation
steps that will occur in the total run, is updated only by the Executive block and will always
have a value of one greater than the number of simulation steps that have actually occurred.
Simulation Architecture 167
How discrete event blocks and models work

Scheduling events
Each block that needs to post an event at a specific time in the future needs to add itself to the
Executive block's TimeArray, TimeBlocks, and TimeEventMsgType arrays. This is done by
reserving a position in the arrays and then setting that position in TimeArray to the next event
time (this needs to be done each time a new event time is posted) and TimeBlocks to the block
number of the event scheduling block.
The position in the arrays is reserved in the CheckData message handler with the following
code:
on checkdata
{
// SysGlobalInt0 is current number of event posting blocks in model
// Reserves a position in TimeArray & TimeBlocks arrays
myIndex = SysGlobalint0;

IDE
SysGlobalint0 += 1;
}
SysGlobalInt0 has been initialized to 0. By incrementing SysGlobalInt0, each block will get a
unique value for myIndex.
In the InitSim message handler, the two arrays are passed in from the Executive, the block
number is assigned to this block's position in TimeBlocks, and the initial event time is assigned
to TimeArray:
on initsim
{
// get the pointer to the TimeArray and TimeEventMsgType arrays
if(getPassedArray(SysGlobal0, timeArray) > 0)
{
// blocks in de models do not get Simulate messages
GetSimulateMsgs(False);
// set the first event time to the start of the simulation
timeArray[MyIndex] = StartTime;
// get the pointer to the TimeBlocks array
getPassedArray(SysGlobal7,TimeBlocks);
// put this block's # in reserved position in TimeBlocks
TimeBlocks[myindex] = myBlockNumber();
//Get the pointer to the TimeEventMsgType array
getPassedArray(SysGlobal13,TimeEventMsgType);
//reserved position in TimeEventMsgType
TimeEventMsgType[myIndex] = BlockReceive1Msg;
}
else
GetSimulateMsgs(True);
}
168 IDE
How discrete event blocks and models work

If this block is used in a continuous model, the GetPassedArray call will return 0 and the on
Simulate message handler will be called at every simulation step.
When the Executive sends this block a message (at the time specified in TimeArray), the block
will receive the message in TimeEventMsgType. If you do not set a value in TimeEventMs-
gType, the block will receive a BlockReceive0 message.
Put the event code in this message handler and reschedule the block for the next event time:
On BlockReceive1
{
// process event
ShowTime = CurrentTime;
// schedule event in the future
TimeArray[MyIndex] = CurrentTime + EventTime;
}
The Event block (ModL Tips library) illustrates the event scheduling procedure.
IDE

Residence, passing, and decision blocks


There are three types of item-handling discrete event blocks: residence blocks, passing blocks,
and decision blocks:
1) Residence blocks are able to contain or hold items for some duration of simulation time.
Some residence blocks post events and some do not. Examples of residence blocks are the
Queue and Activity blocks.
2) Passing blocks pass items through without holding them. These blocks implement model-
ing operations that are not time based and usually do not post future events. Examples
include setting an attribute or getting information from an item (Set or Information blocks).
Passing blocks may use the CurrentEvents array to reschedule themselves. In this case they
will receive a BlockReceive0 message. Rescheduling is necessary when the passing block
needs to return from a message. However, before the simulation clock advances, it also
needs to perform some additional processing. In this case a message is sent to the Execu-
tive and the block number is posted on the CurrentEvents array. The Executive sends a
BlockReceive0 message to every block entered in the CurrentEvents array.
3) Decision blocks control the flow of items in the model; they do not post future events.
Examples include limiting the number of items (Gate block) or selecting an output (Select
Item Out blocks). Note that some decision blocks can behave as passing or residence
blocks, depending on which options are selected for the particular block.

Blocks that post future events


Each block that posts events places its block number in a slot in the global TimeBlocks during
the initSim message handler. The slot number is an index number assigned in the checkData
message handler, called “myIndex”. Each block also places the time of its next event in a slot
in the global TimeArray. For example:
TimeArray[myIndex] = nexttime;
At the start of a simulation event, TimeArray (the event list) is searched to find the next event
time. A third dynamic array, NextTimes, is used to store all of the block numbers that have
Simulation Architecture 169
How discrete event blocks and models work

posted an event at the next event time. The simulation clock is then advanced to the next event
time and a message is sent to each block in the NextTimes array, one block at a time.
After receiving its event message, each block processes its own unique code based on that
event type. For example, a Convey Item block will attempt to pull in an additional item when
the event for an open input occurs, or the Activity block will attempt to push an item out when
that item’s processing duration has completed. Some blocks will conditionally post an event
based on the options selected. An example of this is the Queue, which will post an event if
reneging is selected. Blocks do not have to process items for an event to occur – the Clear Sta-
tistics block (Value library) generates an event at the clear time when used in a discrete event
model.
Residence blocks that do not post future events:
Some of the residence blocks that do not post future events, such as the Queue Matching and
Resource Item blocks, also attempt to move items at event times.
If a residence block needs to return from a message but also needs to attempt to pull in or push

IDE
out items with the same time step, it will send a message to the Executive posting itself on the
CurrentEvents array. The Executive sends a BlockReceive0 to all of the blocks listed in the
CurrentEvents array. This “zero time event” (discussed below) ensures that the residence block
will receive an additional message before the next time step so that additional items can be pro-
cessed.
Zero time events
Sometimes a block needs to post two events at the same simulation time yet have those events
be sequential. In addition, the other blocks in the model need to be given a chance to complete
the posting of their own events after the second event.
An example of this is an Activity block that has just released its item after the specified time
delay. The Activity will need to do two things at the same event time: send the item out to the
next block (if that path is not blocked) and pull another item in (if an item is available). To do
this, it sends the item to the next block and then posts a “current” event to the Executive.
Before the simulation clock advances, the Activity will receive a BlockReceive0 message and
will then try to pull another item in.
To post a zero time event, the block assigns SysGlobalInt8 to its block number and sends a
BlockReceive3 message to the Executive. The Executive maintains a list of all the blocks that
have sent a BlockReceive3 message and before it advances the simulation clock sends a Block-
Receive0 message to each of these blocks in turn. In the example below, the “rescheduled” flag
is used to prevent the block from posting more than one zero time event at a time:
if ( ! rescheduled)
{
// remember block is scheduled as a zero time event
rescheduled = TRUE;
// set the block number for this block
SysGlobalInt8 = MyBlockNumber();
// send message to Executive for a zero time event
SendMsgToBlock(Exec,BLOCKRECEIVE3MSG);
}
170 IDE
How discrete event blocks and models work

Item data structures and indexes


The Executive block stores information about each item in a discrete event model in a set of
dynamic arrays that it passes into the reserved global variables SysGlobal3, SysGlobal4, Sys-
Global6, SysGlobal9, and SysGlobal12 (see “Global variables” on page 211), as well as a set
of two global arrays (see “Global arrays” on page 378). The information in all of the arrays is
available to every block that needs to access it.
Each item in the model is identified by a unique number that is the index number used to look
up the item’s information in the dynamic arrays. This is the item’s index. The arrays contain
information about the items, such as values, priorities, attribute information, and so on. When
an item is passed through an item connector, it is really the index of the item that is passed.
Items are indexed from 1 to n-1, where n is the number of slots in the array. Index 0 is not used
as an item index, since a connector value of 0 indicates that no item is present.
Passing the index numbers through item connectors allows the blocks to pass a great deal of
information with a single number. It also means that all blocks in the model can access any
item. Each of the global variables is received into a local array within each block and, after
being received, is available in exactly the same way that data in any local array is available.
IDE

For example, if there are currently ten items in a simulation, the index number 5 might be
passed from one block in the model to the next. When a block receives index number 5, it
accesses the information in the Executive block’s arrays for item number 5. For instance, ite-
mArrayC[5][0] would tell if the item could accumulate a cost while itemArrayR[5][1] would
tell the item’s priority. When a block is done with an item, it passes the index value of that item
to the next block.
The Executive block maintains two arrays of real information (itemArrayR[][3] and itemAr-
rayC[][10]) and three arrays of integer information (itemArrayI[][5], itemArrayI2[][5], and ite-
mArray3D[][10]). These arrays are described below:
Real array
The real array itemArrayR[][3], passed through SysGlobal3, contains the following informa-
tion:

Slot # Description
0 Quantity: The number of items that the current item represents. This is used, for exam-
ple, by the Set block (Item Library). Item quantities are used to copy items in queues and
resource blocks. They are also used by certain input connectors (such as on the Activity
block) to convey additional information to a block.
1 Priority: Used by the Set, Get, and Queue blocks. Note that in ExtendSim the lower the
number (including negatives), the higher the priority.
2 Reserved for future use.

Cost array
The real array itemArrayC[][10], passed through SysGlobal9, contains information concerning
cost resources that are batched with the item. This information is used by residence blocks to
calculate the accumulated cost based on the cost rates and the amount of time the item spent in
the block.
Simulation Architecture 171
How discrete event blocks and models work

Slot # Description
0 Item type: When considering cost, all items can be classified as an item that can accumu-
late costs (1) or a resource (2).
1 Resource Rate 1: The cost per time unit of a resource batched to the item using the batch
block.
2 Batch Number 1: Stores the amount of resource 1 batched to the item.
3 Resource Rate 2: The cost per time unit of a resource batched to the item using the batch
block.
4 Batch Number 2: Stores the amount of resource 2 batched to the item.
5 Resource Pool Rate: The accumulated cost per time unit of resources batched to the item
using the Queue block.

IDE
6 Unused
7 Original Cost: Used in calculating cost when unbatching items using the Unbatch block
(Item library).
8 Unused
9 Unused

Integer arrays
There are two integer arrays: itemArrayI and itemArrayI2.
The integer array itemArrayI[][5], passed through SysGlobal4, contains the following informa-
tion:

Slot # Description
0 Free row flag. This is used by the Executive block for memory management. It has a
value of 1 if the row is free (that is, has no existing item associated with it), and a value
of 0 if the row is in use. See the Exit block (Item library) for an example of how to use
this to delete an item.
1 Batch ID. This is used by the batching and unbatching blocks to keep track of which
items are part of what batch.
2 User-defined integer value. This value is left untouched by the blocks in the Item library.
3 Unused except where needed to provide backwards compatibility with Extend 5 or ear-
lier.
4 Block number where item is.

ItemArrayI2[][5] is passed through SysGlobal18 and has 5 columns:


172 IDE
How discrete event blocks and models work

Slot # Description
0 Resource Order ID. If an item has requested at least one advanced resource requirement,
the integer held in slot 0 represents the record associated with the last requested require-
ment in the “Resource Orders” database table. Resource Order ID is used with Advanced
Resource Management (ARM).
1 Unique item ID used by the Report Manager block
2 Report Manager block’s log record index
3 RBD. Event item’s record index into “RBD event registry”
4 RBD. Event item’s record index into “RBD event occurrence log”

3D array
The integer array itemArray3D[][10] stores information for the ExtendSim 3D animation and
is passed through SysGlobal12.
IDE

☞ Some of the values are scaled by 100,000 so that they can be stored in an integer, saving space.
Slot # Description
0 3D objectID. Used to reference the 3D object that represents the item in the E3D win-
dow.
1 ID for the first skin of an item.
2 ID for the second skin of an item.
3 Scale of an object. This is based on a factor of 100,000. (An object with a scale of
100000 will be normal sized; a scale of 50,000 will be half sized.)
4 Object rotation in degrees times 100,000.
5 Object Z location times 100,000. The Z locations are based on a ground level of 100, so
a Z location in itemArray3D of 10,000,000 would be at ground level.
6 Object type. This is the type of 3D object as returned by the E3DGetObjectType func-
tion.
7 Temporary level times 100,000. This stores the Z level for an object before it is placed
on a Conveyor or other object that temporarily raises its position.
8 Restore Z level. If true, the temporary Z level will be used to restore the original Z posi-
tion of the 3D object.
9 Reserved for future use.

Item attribute global arrays


There are three global arrays that are responsible for item attributes:
• The first (_AttributeList) stores attribute names
• The second (_AttribType) stores the attribute type (value, string, or db address)
• The third (_AttribValues) stores attribute values
Simulation Architecture 173
How discrete event blocks and models work

The attribute names are stored in a String15 type global array called “_AttributeList”. This
array is created whenever a block that uses attributes is placed in the model. Its single column
contains an alphabetized list of the attribute names entered into the blocks. All blocks that ref-
erence attributes use a popup menu to allow the modeler to select from a list of attributes that
have already been defined for the model or to create a new attribute. When the popup menu is
clicked, these blocks reference the AttribList global array to ensure that all of the attributes
defined in the model are available for selection in the popup menus. Each time a new attribute
is added, this global array is increased in size by one, the attribute name is appended to the list,
and the list is sorted.
The “_AttribType” global array is used to store the attribute’s type at the time the user defines
a new attribute. There are 3 types of attributes: value, string, and db address.
While building a model, it is possible to define attributes that end up not being used or refer-
enced in the model. Cleanup of unused attribute names is done at the start of the simulation.
The Executive clears the AttribList global array in its StepSize message handler. Each block in
the model that references an attribute name then adds all of its referenced attributes to the

IDE
AttribList global array in their StepSize message handlers.
In the InitSim message handler, the Executive sorts the new AttribList global array (which now
includes only attributes which are used in the model). In doing this, each attribute name is
assigned a sequential index (the row index) in alphabetical order. Each block then calls the
Attrib_GetColumnIndex procedure which searches the AttribList global array for the attribute
that is referenced by the calling block. This index is used when referencing the attribute value
during the simulation.
In addition, if either of the two costing attributes (“_cost” or “_rate”, as discussed in the User
Reference) are used in the model, they are assigned the index values at the end of the list of
user-defined attributes.
The attribute with index 0 stores the animation object for the item.
The third global array used for attributes stores the attribute values for each item. In the Exec-
utive’s InitSim message handler, the two-dimensional global array “_AttribValues” is created
to store the values of the attributes during the simulation. The number of columns is calculated
as the “number of user-defined attributes plus one” for the animation attribute and plus two for
the costing attributes (if costing is used in the model). The number of rows corresponds to the
number of items in the model and is increased if additional items are allocated. The attributes’
values can be referenced by using the attribute index as the column and the item index as the
row. For example: the following is pseudocode for setting an attribute:
AttribValueIndex = GaGetIndex("_AttribValues");
GaSetReal(Value1,attribValueIndex,itemIndex,AttribIndex);
where:
Value1 = the value of the attribute
AttribValueIndex = The index to the "_AttribValues" global array
ItemIndex = The index of the item
AttribIndex = The index of the attribute

Flow attribute global arrays.


The blocks in the Rate library use flow attributes which are implemented using the same logic
as discussed above for item attributes. The global arrays responsible for flow attributes are:
174 IDE
How discrete event blocks and models work

• The first (_FlowAttList) stores attribute names


• The second (_FlowAttType) stores the attribute type (value or string)
• The third (_FlowAttValues) stores attribute values

Basic item messaging


The actual moving of items between blocks is done through a messaging communication struc-
ture using item connectors and connections. This messaging system allows modelers to place
blocks in a more intuitive sequence.
Discrete event blocks send messages to each other during the course of a simulation run. These
messages are used for communication regarding whether items are available, whether they
have been taken, and whether a block is free to receive items.
For single connectors, messages are sent using the functions SendMsgToInputs(connector-
name) and SendMsgToOutputs(connectorname). For variable connectors, messages are sent
using SendMsgToInputs(connectorname, whichConnector) and ConArraySendMsgToOut-
puts(connectorname, whichConnector). Messages are received in message handlers that have
IDE

the name of the connector that received the message. For example the “On ItemIn” message
handler is called when a message is sent to the “ItemIn” connector.
Discrete event blocks have a function in their code called SendMsg. This function is just
included for clarity. It calls the two ModL functions mentioned above.
The SendMsgToInputs and SendMsgToOutputs functions only send messages. In discrete event
models, so that more information can be sent with each message, the global SysGlobalInt3 is
used as an argument to the messages, and the global SysGlobalInt0 is used as a return code
value. Note that some globals are used to perform different functions during the initialization
(CheckData and InitSim) phases of the simulation run.
During the Simulate phase of the run, the meanings of the various values of SysGlobalInt0 and
SysGlobalInt3 are as follows:

Value Sending (SysGlobalInt3) Returning (SysGlobalInt0)


0 (rejects) (Not sent) Block rejects item
1 (wants) Does block want item? (Not returned)
2 (taken) Item has been taken (Not returned)
3 (needs) Item needs to be taken Block needs item
4 (query) What is the index of the next item? Item index for the next item (0 if no item is
found)
5 (notify) Item has been sent (Not returned)
6 (blocked) Is the downstream block blocking (Not returned)
us?
7 (init) Used during initialization (Not returned)

Depending on how the message sequence is initiated, items can be either pushed or pulled
through the model. It is easiest to illustrate this with a series of simple examples. The following
figures show a Queue block connected to an Activity block with a single item capacity.
Simulation Architecture 175
How discrete event blocks and models work

Push mechanism
When an item is pushed through the model, the upstream blocks (in this case, a Queue) try to
push their items out into any downstream blocks.
For example, assume that an item has just arrived at the
Queue and the Queue is attempting to pass that item along to
the Activity. The first action is for the Queue to send a wants
message through its item output connector to the Activity.
This is accomplished by setting SysGlobalInt3 to a value of 1
(wants) and calling the function SendMsgToInputs. This indi-
Wants message sent to Activity
cates that the Queue wants to send an item to the Activity.
The Activity receives the message in its “on itemIn” message
handler. If the Activity in the above example is not currently
processing an item and thus is idle, it will return a needs
value to the Queue by setting SysGlobalInt0 to 3 (needs),
indicating that the item can be accepted.

IDE
Needs value returned from Activity
If a needs value has been returned from the Activity, the
Queue then sends a needs message back to the Activity by
setting SysGlobalInt3 to 3 (needs) and calling the function
SendMsgToInputs. At this point the item would be commit-
ted to moving from the Queue to the Activity.
Needs message sent to Activity
If the Activity is currently busy processing another item,
instead of a needs value it will return a rejects value . This is
accomplished by setting SysGlobalInt0 to 0 (rejects). If the item is rejected, the message
sequence will be terminated.
The item is logically moved from one block to the next by
transferring its item index over the connection between the
blocks. To do this, the Queue sets its output connector value
to the item index.
When a block sets its connector value to the item index, the
connector value of any connected blocks will automatically Taken message sent back to Queue
be set to that same item index value.
Since the output connector of the Queue is connected to the input connector of the Activity, the
two connectors will share the item index value. The Activity then sets its input connector to a
negative number and sends a taken message back to the queue to indicate that the item has suc-
cessfully moved. This is done by setting SysGlobalInt3 to 2 (taken) and calling the function
SendMsgToOutputs. In response to the taken message, the queue will update any internal sta-
tistics related to the departure of the item.
Pull mechanism
In addition to being pushed, as in the preceding example,
items can also be pulled through the model. If they have
remaining capacity, downstream blocks try to pull items
into their inputs. For example, when the Activity finishes
processing the item, it will attempt to pull in another item.
To do this, the Activity first sends a wants message to the Wants message sent from Activity
176 IDE
How discrete event blocks and models work

Queue indicating that it is requesting an item. The wants message is sent by setting SysGlo-
balInt3 to 1 (wants) and calling the SendMsgToOutputs function.
If an item is available in the Queue, its output connector will be assigned to that item’s index
value. The Activity will pull in the item and then send a taken message back to the Queue by
setting SysGlobalInt3 to 2 (taken) and calling the SendMsgToOutputs function. If an item is not
available in the Queue, a rejects value (0) will be returned and the message chain will be termi-
nated.
Passing blocks
Both of the blocks in the above examples are residence blocks and can hold items for some
period of time. Passing blocks do not have this ability and must pass the item through in 0
time.
The following example shows an Equation(I) block
reading multiple attribute and other property values to
calculate the delay needed for the Activity. The Equa-
tion(I) block does not affect the messaging communica-
IDE

tion between the Queue and the Activity. Since it is a


passing block, it transfers the initial wants and needs Passing block between Queue and Activity
messages between the Queue and Activity. Thus, any
number of passing blocks can be between any blocks that can hold items. Once the item moves
into a passing block, it will send a taken message to the upstream block.
Blocked and query messages
One of the more complex message communication subsystems in this architecture is the com-
munication between blocks when a block needs information about an item that has not yet
arrived. This occurs when an item needs to know if it can move downstream before it starts to
move, or when it needs to determine which path it will take before it gets to the block that con-
tains the different paths.
If Predict the path of the item before it enters this block is selected in its dialog, the Select Item
Out block will use a special sequence of messages to determine which direction the item will
go before the item leaves any upstream residence blocks.
Traditional discrete event architectures would require dummy resources to overcome these
problems. The ExtendSim discrete event architecture, however, is able to determine the path of
an item before it moves into the decision logic and is able to block through decision points
without any additional modeling components.
In the example at right, the Equation(I) block reads mul-
tiple attribute and other property values to calculate the
one of three paths for that item to follow (Select Item
Out) based on the value of the properties for that item.
Without the ability to send a Query message, the Equa-
tion(I) block would read the value of the properties on Select Item Out controlled by Equation(I)
the item, but only after the item has already entered the
block. In this case, this could cause a problem as the Select Item Out block may be blocked
down the path that the item will need to travel. If the Select Item Out is blocked, and the item
has to move into the Equation(I) block to present its property values, then the item will be
Simulation Architecture 177
How discrete event blocks and models work

stuck in the Equation(I) block. And since property-manipulating blocks are only meant to pass
items, not hold them, the Queue will understate the number of items available.
The solution to this problem is to use the Equation(I) block which can then look upstream to
see what the next item coming along will be, and not pull in the item until the downstream path
is free.
Blocked messages
The first part of this process involves sending a
blocked message downstream from the Equation(I)
to see if there are any blocks that could cause this
situation. This is accomplished by setting SysGlo-
balInt3 to 6 (blocked) and calling the SendMs-
gToInputs function. The Equation(I) does this the
first time it gets an incoming message (i.e. the first Blocked message sent to Select Item Out
time the Select Item Out block requests a calculated
value from the value out connector.) The Equation(I) sends a blocked message from its item

IDE
output connector in its on AttribOut message handler. (The on AttribOut message handler is
called when the value out connector on the Equation(I) block gets a message.) If the block
downstream is a potential blocker, it will return a TRUE value by setting SysGlobalInt6 to 1
(TRUE). If a TRUE value is returned in response to the message, then the Equation(I) block
sets a flag that records that it is blocked.
Query messages
If it has been determined that blocking can occur,
each time there is a request for a calculated value,
the Equation(I) block sends a query message
upstream by setting SysGlobalInt3 to 4 (query) and
calling the SendMsgToOutputs function. This mes-
sage is essentially a request for information about Query message sent to Queue
the next item that is available. The message will be
propagated upstream by the blocks until it reaches
a block that can contain items, such as a queue.
The block responding to the query message will check to see what the item index of the next
item to be released will be and will return that value to the querying block by setting the global
SysGlobalInt0 to the item’s index value. The Equation(I) block will then access the property
values for that item. From this point on, each time that a property value is requested from the
Equation(I) block, it will send out the query message and check the property values of the next
item. It will not need to re-send the blocked message again.
ExtendSim will notify modelers if there are any logical ambiguities that will not allow the
model to operate properly. When this occurs, an error message is issued that recommends a
course of action that will resolve the ambiguity.
The Notify message
The final message used by this system is the notify message. This message is used to notify
other blocks that an item has just passed by a specified point in the model. A special sensor
connector receives this message. Sensor connectors do not pass items, they monitor the mes-
sage stream, processing only the notify message. Only a few blocks have sensor connectors,
although all of the blocks that process items will send the notify message through their item
178 IDE
How discrete event blocks and models work

output connector by setting SysGlobalInt3 to 5 (notify) and calling the SendMsgToInputs func-
tion.
In this example, the Gate block limits the num-
ber of items in the section of the model between
its output connector and the activity’s output
connector. It uses its sensor connector to deter-
mine when an item has passed the activity’s
output connector.
Situation that requires a notify message
As an item travels from the Activity to the Set
block, a taken message will be sent to the Activity. In response to this message, the Activity
will send out the notify message. The normal item input connectors in the blocks will ignore
the notify message, but sensor connectors will respond to it and start processing information
about the item. In the above example, when a notify message is received by the sensor connec-
tor, the Gate block knows that another item has passed by and can allow an additional item into
the model section.
IDE

Value connector messages


In addition to item connectors, value connectors are used to relay model information. Value
connectors pass a single number from one block to another. Examples include a value output
such as length of a queue or an input such as a delay time. The use of these connectors allows
the combining of blocks that perform numerical calculations to provide a control structure and
logical information for the discrete event blocks. This provides additional modeling flexibility
without requiring user programming or complicated interfaces.
In the example that follows, two Random Number
blocks are added together to specify the delay for an
activity. Whenever an item arrives to the activity, the
Random Number and Math blocks will need to be recal-
culated. Whenever a discrete event block detects a con-
dition where an update to the input value of a connector
is needed (in this case, an item arriving to the activity),
it sends a message out its input value connector (in this
case, value input connector “D”) using the ConArray-
SendMsgToOutputs() function. This message propagates
The sum of two random variables
backwards via the Math block and causes the Random specifying an activity’s delay
Number blocks to recalculate their output values so that
the Math block can add them and update its output con-
nector value for the Activity block to use.
Message emulation
A default feature (“message emulation”) for continuous blocks in a discrete event or discrete
rate model causes the messages to be propagated throughout all of the continuous blocks used
in the calculation. Message emulation is used whenever the block contains no message han-
dlers for any of its connectors. In that case, the “on simulate” message handler is used as a
default message handler for all connectors.
How message emulation works:
• If a message is received on an output connector:

• Echo to ALL input connectors to get their latest values.


Simulation Architecture 179
How discrete event blocks and models work

• Send a SIMULATE message to the block to recalculate values to its output connectors.

• If a message is received on an input connector:

• Echo to all other inputs THAT HAVE NEVER RECEIVED A MESSAGE to get their
latest values.

• Send a SIMULATE message to the block to recalculate values to its output connectors.

• Echo message out the outputs.

• If Additional messages are received on any connector while processing current message:

• DON'T echo these additional messages.

• Send a SIMULATE message to the block to recalculate its latest values.

IDE
This message emulation capability improves performance and reduces redundancy.
The example code below illustrates an On Simulate message handler adding one to its input by
assigning the output connector (Con1Out) to the input connector (Con1In) plus one. There are
two cases:
• The block received a message from its input connector to recalculate, so it calls its Simulate
message handler and then propagates that input connector message by then sending a mes-
sage via its output connector to any connected block’s inputs so they can act on that mes-
sage.

• The block received a message on its output connector from a downstream block that needs a
new value. It first propagates the message backwards through its inputs so upstream blocks
can recalculate, then calls its Simulate message handler to recalculate its outputs for the
downstream block to use.

Whenever either connector receives a message, the Simulate message handler will be executed
and a message will be sent out the other connector through message emulation. This will prop-
agate messages where appropriate.
On Simulate
{
Con1out = Con1In + 1; // calculate the output value
}

Explicit connector messages


Overriding message emulation gives you, as a block developer, more flexibility in the behavior
of the block. If a generic block has one or more connector message handlers, message emula-
tion is automatically disabled and the connector message handlers are used to perform the cal-
culation instead. In this case, the generic block must send out messages to other value input
and output connectors explicitly. For example, a message must be sent out of the output con-
nector whenever a message is received on the input connector, and a message must be sent out
of the input connector whenever a message is received on the output connector.
180 IDE
Globals in discrete event blocks

The code below uses message handlers to make a block behave similarly to the message emu-
lation used in the above example. Both examples will perform identically in model operation.
Because message handlers have been explicitly specified for the connectors in the example
below, message emulation has been automatically disabled.
On Con1In
{
Con1Out = Con1In + 1;
SendMsgToInputs(Con1Out);
}

On Con1Out
{
SendMsgToOutputs(Con1In);
Con1Out = Con1In + 1;
}
IDE

On Simulate
{
}

Functions in discrete event blocks


The following are some, not all, of the functions to be found in discrete event blocks. They are
the ones found in most of the blocks and help give an understanding of how the code is orga-
nized.

Function Description
SendItem Attempts to pass an item out of the block. First it checks certain block variables to
see if an item is available, then it will output the index value of the item and send a
message to the receiving block (it calls SendMsg).
GetItem Attempts to get an item once a block determines that it is ready to get an item.
First it checks to see if an item is available, then it gets the index value, negates the
connector, and sends a message to the sending block.
PassItem Performs the actions of both the GetItem and SendItem functions. It is used in
blocks that pass items through without delaying them (passing blocks).
SendMsg Sends the messages out through the connectors. It sends out messages based on
the values of its arguments.

Globals in discrete event blocks


Several reserved global variables (sysGlobals) are used in discrete event blocks. This table lists
the reserved global variables with a brief description of their use during the Simulate message
(most have undefined values during the CheckData message). For more information, examine
the code of the blocks in the Make Your Own category of the Example Libraries > ModL Tips
library or the Executive block and other blocks in the Item library.
In addition to the global variables reserved by ITI, there are general use global variables. To
see the complete list of global variables, go to “Global variables” on page 211
Simulation Architecture 181
Globals in discrete event blocks

☞ Global variables are integers if they contain the “Int” designation (SysGlobalIntX) and are
strings if they contain the “Str” designation (SysGlobalStrX). Otherwise, they are reals.
Use of system globals during Simulate message

Global Used In Definition during Simulate message


SysGlobal0 DE blocks Used to access the TimeArray of posted events.
SysGlobal1 Blocks with Report file number.
reports
SysGlobal2 Blocks with Trace file number.
traces
SysGlobal3 DE blocks Used to access the real item array of discrete event item data.
SysGlobal4 DE blocks Used to access the integer item array of discrete event item

IDE
data.
SysGlobal5 Do Not Use DO NOT USE. (Was used in versions prior to 7.0.3 to pass the
TimeEventMsgType array between the Executive and event
scheduling blocks. Use SysGlobal13 instead.)
SysGlobal6 DE blocks Used to access the string item array of discrete event timer data.
SysGlobal7 DE blocks Used to access the TimeBlocks array of event posting blocks.
SysGlobal8 Resource Used in communication between the Resource Pool, Queue (in
pools Resource Pool mode), and Resource Pool Release blocks.
SysGlobal9 Costing Used to access the cost item array for discrete event item data.
blocks
SysGlobal10 Global arrays Communicates the value, row, and column to other global array
blocks when a value in a global array has changed.
SysGlobal11 Throw and Passes a value between blocks.
Catch blocks
(Value
library)
SysGlobal12 DE blocks Used to access the integer item array of discrete event itemAr-
rayI2 data.
SysGlobal13 DE blocks Passes the time event message type array between Executive
and event scheduling blocks.
SysGlobal14 Not used
SysGlobal15 Not used
SysGlobal16 Blocks with Passes array containing names of attribute arrays.
attributes
SysGlobal17 Catch Item Passes Throw block nums array.
SysGlobal18 Not used
182 IDE
Globals in discrete event blocks

Global Used In Definition during Simulate message


SysGlobal19 Proof Anima- Passes ProofString as an array.
tion blocks
SysGlobal20 Executive Used in BlockReceive5 as a DB Address argument for the call-
ing block and used by the Executive as the return value.
SysGlobal21 Passes Resource Orders from Batch block to Resource Man-
ager
SysGlobal22 Item Log Used to pass arrays from Item Log Manager to satellite blocks
Mngr (e.g., the History block).
SysGlobal29 Not used
SysGlobalStr0 Blocking Name of attribute being checked upstream.
blocks
SysGlobalStr1 Any block Used as an argument for the block table info (BlockReceive4)
IDE

message handler.
SysGlobalStr2 Blocks with Name of new string attribute passed to Executive.
attributes
SysGlobalStr4-9 Not used
SysGlobalInt0 DE blocks Return code from the messages that discrete event blocks send
to each other.
SysGlobalInt1 DE blocks Index value for the first free row in the item arrays maintained
that create by the Executive block.
items
SysGlobalInt2 DE blocks Total number of rows of data that have been allocated to the
item arrays. This will always be rounded up to the next alloca-
tion level.
SysGlobalInt3 DE blocks Argument to the messages that discrete event blocks send to
each other.
SysGlobalInt4 Blocking Tells whether the priority is being checked.
blocks and
priority
SysGlobalInt5 Used for v6 Global batch count.
compatibility
SysGlobalInt6 Blocking Specifies whether or not there is a blocked block (see the Get
blocks block).
SysGlobalInt7 DE blocks ID of the item currently being disposed.
SysGlobalInt8 DE blocks Used to pass the block number to the Executive when the block
is rescheduling itself in the CurrentEvents array.
Simulation Architecture 183
Globals in discrete event blocks

Global Used In Definition during Simulate message


SysGlobalInt9 Random Flag when the graph is sending a message. (See the code of the
Number, Line Chart, Scatter Chart, and Random Number blocks for
Holding Tank more information.)
(Value
library)
SysGlobalInt10 Resource Used in communication between the Resource Pool, Queue (in
pools Resource Pool mode), and Resource Pool Release blocks.
SysGlobalInt11 Select Item Used to control whether or not a new random value is generated
Out in a connected Random Number block.
SysGlobalInt12 Throw and Passes item index in Throw Item and Catch Item blocks.
Catch (Item
library)

IDE
SysGlobalInt13 Random Set to TRUE if a new random number should be generated for a
Number, select block.
Equation, and
Select blocks
SysGlobalInt14 Throw and Used by Throw Item and Catch Item blocks to determine which
Catch (Item Throw block is sending the message.
library)
SysGlobalInt15 Resource Used in communication between the Resource Pool, Queue (in
pools Resource Pool mode), and Resource Pool Release blocks.
SysGlobalInt16 Blocks with Set to TRUE during CheckData message if discrete event
costing model is calculating item costs.
SysGlobalInt17 Blocks with Holds the number of attributes in a discrete event model.
attributes
SysGlobalInt18 Blocks with Argument to BlockTableInfo message handler that chooses the
tables type of information to return.
SysGlobalInt19 DE blocks Used as an argument for blockreceive4 (on queueFunction
message handler).
SysGlobalInt20 Queues, Used in direct communication with queues and resource pools.
Resource
pools
SysGlobalInt21 Queues, Used in direct communication with queues and resource pools.
Resource
pools
SysGlobalInt22 Set, Get, Executive and attribute blocks.
Executive
SysGlobalInt23 DE blocks Block number of the Executive.
SysGlobalInt24 Create, Set, Attribute info command number.
Get, Execu-
tive
184 IDE
Globals in discrete event blocks

Global Used In Definition during Simulate message


SysGlobalInt25 Set, Create, Number of attribute name arrays in a block.
Executive
SysGlobalInt26 Any block Block number of item tracing block.
SysGlobalInt27 DE blocks Item index sent to tracing block.
SysGlobalInt28 Resource List number when resource pool tries to send item. Used in
Pool, Queues BlockReceive1 message.
SysGlobalInt29 Resource Set in Queue in PreCheckData to tell Pools the Historical Log
Pool, Queues has been turned on.
SysGlobalInt30 Resource Resource Requirement record.
Mngr
SysGlobalInt31 Resource Item Index.
Mngr
IDE

SysGlobalInt32 Resource Pointer to Resource method.


Mngr
SysGlobalInt33 Item library Block number for Resource Manager.
SysGlobalInt36 Resource Number of selected resources.
Mngr
SysGlobalInt37 Unique Keeps a count of how many items have been created. Used to
ItemID assign a unique ID to items in ItemArrayI2.
SysGlobalInt38 Item blocks Msg type. Tells the remote satellite block what to do in Block-
Receive6 for item logging.
SysGlobalInt39 Item blocks The table index of the Item Log block's central log table.
SysGlobalInt40 Global setting for whether or not to track string attribute values.
SysGlobalInt42 Mean & Vari- Track the number of blocks that have relative error turned on.
ance block This makes sure that the simulation runs continue until the all
of the relative error conditions have been met.
SysGlobalInt43 Item & Rate True when the addition of a block is being scripted. Prevents
the automatic redrawing of connection lines.

Use of Global variables during CheckData or InitSim messages


Some of the variables in the above table are also used in the CheckData and InitSim message
handlers and have a different meaning than when used in the Simulate message handler.

Global Different definitions during CheckData/InitSim messages


SysGlobalInt0 Number of blocks posting events for the time array.
SysGlobalInt1 Block number of the Executive block.
SysGlobalInt8 Used by the Executive block during CheckData to check for duplicate Execu-
tive blocks.
Simulation Architecture 185
Creating blocks for discrete event models

Global Different definitions during CheckData/InitSim messages


SysGlobalInt11 Used to control random seed initialization.
SysGlobalStr1 Used by equation to send a value to Proof Animation.

Creating blocks for discrete event models


A Make Your Own block (Example Libraries > ModL Tips library > Make Your Own cate-
gory) is useful for creating blocks that will be used in discrete event models that have item
inputs and outputs. However, you may want to create blocks that have value inputs and out-
puts, but are meant to be used in discrete event models. In that case, do not use the Make Your
Own block as a template. Instead, you only need to follow these two rules:
• Add SendMsgToInputs(connName) and SendMsgToOutputs(connName) functions to your
Simulate message handler for all input and output connectors on your block. Remember that
the argument to SendMsgToInputs is the name of the output connector on the block you are

IDE
creating; likewise, the argument to SendMsgToOutputs is the name of the input connector.

• To control how the block receives and sends messages, add at least one message handler
(which can be empty) with the name of one of your connectors. Otherwise, the block will
emulate connector messages. Thus, if the name of one of the output connectors is “G1Out”,
you would add a message handler such as:
on G1Out
{
...
}
☞ Using options in the Run > Debugging command, you can cause models to display block mes-
sages as they run. This gives an idea of how messaging works in discrete event models.
How discrete rate blocks and models work
The blocks in the Rate library are for creating discrete rate models. LP technology, which has
global oversight over discrete rate models, as well as messaging in discrete rate models, is dis-
cussed in the User Reference.
Globals in discrete rate blocks
Several reserved global variables (SysFlowGlobals and others) are used in the Rate library
blocks. The table below lists those global variables with a brief description of their use in Rate
library blocks during the Simulate message (most have undefined values during the CheckData
message).

Global Definition during Simulate message


SysGlobalInt41 Rate library
SysFlowGlobal0 To store the maximum rate defined in the Executive
SysFlowGlobal1 To store the rate precision to be considerate as 0
SysFlowGlobalStr0 Used for the propagation of the name of the flow unit in a section
186 IDE
Globals in discrete rate blocks

Global Definition during Simulate message


SysFlowGlobalInt0 Used to propagate the section# (= corresponding to the row# in _FlowSec-
tion global array)
SysFlowGlobalInt1 Used to propagate the row# in the _FlowAttValues global array for each
outflow connector that can change attributes
SysFlowGlobalInt2 Used to stop the propagation when the message is received twice in the
same block => count the LP calculations made in the Executive
SysFlowGlobalInt3 {1/2/3} Option defined in the Executive block to show or not the bias
order above the Merge and Distribute icons using a mode with bias order
SysFlowGlobalInt4 Used to get the type of propagation which is made in FlowBlockReceive0
and FlowBlockReceive3 messages
SysFlowGlobalInt5 Count the number of constraints in an LP calculation
SysFlowGlobalInt6 Row # in siListTCConnection_GA global array. Used to update when
IDE

change occurs in Throw Catch connections.


SysFlowGlobalInt7 {0/1} True if the Rate blocks have to update the state starved or blocked
after each new calculation of the rates
SysFlowGlobalInt8 Used to inform the block on the number of the section which is concerned
by the message handler (FlowBlockReceive0_1_3_4_6_7
SysFlowGlobalInt9 Used to inform which is the sense of the propagation when a message is
sent from a block
SysFlowGlobalInt10 Unused
SysFlowGlobalInt11 Used to inform from which connector number the message has been sent
(in FlowBlockReceive0 msg)
SysFlowGlobalInt12 Value of the popup menu in the Executive
SysFlowGlobalInt13 Used to inform on the option taken in the Executive for the merge percent
option
SysFlowGlobalInt14 Used to inform on the option taken in the Executive for the merge/diverge
bias order
SysFlowGlobalInt15 {0/1} True if the definition of the LP area is in process
SysFlowGlobalInt16 Unused
SysFlowGlobalInt17 Unused
SysFlowGlobalInt18 To stop the propagation of the FlowBlockReceive5 message in the block.
Each block has to express its constraints only once per LP resolution
SysFlowGlobalInt19 To know if there is a block in the area which requires the extra calculation
of an LP with downstream and upstream differentiation
SysFlowGlobalInt20 To count the number of slacks in the LP
SysFlowGlobalInt21 To inform from which type of connector (Flow or Throw/Catch) number
the message has been sent (in FlowBlockReceive0 message)
Simulation Architecture 187
Globals for ARM (Advanced Resource Management)

Globals for ARM (Advanced Resource Management)


Advanced Resource Management (ARM) is a complete system for organizing resources, dis-
tinguishing between them, and allocating them throughout the model. It provides a convenient
and straightforward method for defining complex resource requirements for items as well as a
flexible set of rules for how resources get allocated to them. ARM is discussed in the User Ref-
erence and in the separate document Advanced Resource Management Tutorial and Reference.

Global Definition during Simulate message


SysGlobalStr3 dB table name used to query if table fields can be expanded
SysGlobal23 Used to pass array pointers to the Resource Manager block
SysGlobal25 To enable updating of locked resource properties
SysGlobal26 To enable remote deletion of resources

IDE
SysARMGlobal0-19 Unused

Other reserved global variables


Mainly used for event monitoring and reliability.

Global Definition during Simulate message


SysGlobal24 To pass array pointers to the Event Monitor block
SysGlobal27 To pass optional argument 1 to the Item Event Monitor block
SysGlobal28 Return value
SysGlobalInt44-52 Reserved for reliability
SysGlobalInt53 Event Monitor block number
SysGlobalInt54-56 Reserved for reliability
SysGlobalInt57 Argument used for passing “EventType” to the Event Monitor block
SysGlobalInt58 Argument used for passing “itemIndex” to the Event Monitor block
SysGlobalInt59 Argument used for passing “blockNumber” to the Event Monitor block
SysGlobalInt60-79 Reserved for reliability
SysDBNGlobalInt0-19 Unused
188 IDE
Other reserved global variables
IDE
Integrated Development
Environment (IDE)

Debugging
A guide to debugging models and blocks

“We have gone beyond the absurd...


our position is ridiculous.”
— John Vacarro
190 IDE
Debugging models

Debugging models
This section discusses ways to debug models and the code necessary to add Trace features to
blocks you build. These methods are also useful when you debug block code.
Features that are discussed in the User Reference
The Debugging Tools chapter of the User Reference has a list of blocks that are useful for
debugging models. These blocks display values, help validate item flow, and speed debugging
of a model. That User Reference chapter also contains other information for debugging models
such as showing simulation order.
Adding Trace code
The ExtendSim Trace feature can be useful in debugging a model. If you create your own
blocks, those blocks can take advantage of the ExtendSim tracing features. When building a
new block, you could include code similar to the following.
For the code that follows:
• For continuous blocks, such as those in the Value library, put the code in the Simulate mes-
IDE

sage handler
• For discrete event blocks, such as those in the Item library, put the code in the departure pro-
cedure
// SysGlobal2 is the file reference number for the Debug Trace
// template for trace: BLOCK NAME BLOCK NUMBER CURRENTTIME
if( SysGlobal2 != 0.0 ) // check for open file for TRACE
{
fileWrite(SysGlobal2,"myBlockName block number "+(myBlockNum-
ber()) + ". CurrentTime:"+currentTime+".","",True);
if(getBlockLabel(myBlockNumber()) != "")
fileWrite(SysGlobal1,"Block Label: "+
getBlockLabel(myBlockNumber()),"",True);
....
....
}
☞ The blocks that ship with ExtendSim contain all the necessary Tracing code.
Profiling
Use profiling to determine the amount of time that each block in a model is used, then use that
information to optimize the block’s code. Profiling a model generates a text file showing the
percentage of time individual blocks execute during a simulation. This helps developers who
want to determine if they should optimize custom blocks, although non-developers might also
use it to find the areas of their models that are most heavily used.
To generate a profile text file, choose the Run > Model Debugging > Profile Block Code com-
mand, then run the model. Be sure to run the model long enough (at least 5 seconds for each
block in the model) to compensate for extraneous events and get a good sample. It is also
Debugging 191
Debugging block code without the Source Code Debugger

important to not move blocks in the model between runs if you repeatedly run the profile. For
example, the profile of a Bank Line model might look like:

Block Name Block Number Time (seconds) Percent


Create 0 2.42 9.30
Queue 2 7.65 29.50
Activity 3 2.27 8.80
Activity 5 1.15 4.40
Activity 6 1.82 7.00
Exit 7 4.15 16.00
Line Chart 8 5.83 22.50
Executive 10 0.62 2.40

You can use the information in this profile to look for anomalous results. For example, if one

IDE
of the three Activity blocks used a much higher percentage of the time than the other two, but
you had expected them to be about the same, you could use that information to see what it was
about that block that was different.
Note that only blocks that use 1% or more of the simulation time are shown in the profile. And
the percentages are approximate, so the sum of the percentages might not equal 100%.
Profile text files are opened, closed, and edited just like any other text file.
Debugging block code without the Source Code Debugger
The ExtendSim Source Code Debugger, discussed beginning on page 192, has a lot of advan-
tages in block debugging, offering conditional breakpoints, stack crawl, and viewing variable
values in specified blocks. The following methods may also be useful for debugging code.
Using DebugMsg functions
If you don’t want to use the Source Code Debugger, you can use the DebugMsg function to
insert a breakpoint and monitor variable values as the simulation runs. You specify a message
and variable values as this function’s string argument. When the function gets called, it dis-
plays the argument in an alert.
DebugWrite is the same as the DebugMsg function except that the data is written to a file so
the simulation run isn’t interrupted. The advantage of using DebugMsg or DebugWrite rather
than UserError is that ExtendSim warns if the Debug functions are present when the library is
loaded. See the functions in “Debugging” on page 402.
Viewing intermediate results
When developing a block’s code, there is an easy way to view intermediate results of calcula-
tions without any interruption of the model. Just add an assignment statement:
comments = myVar; // myVar will be visible as it changes
or add some more information and variables:
comments = “myVar = ” +myVar+ “, myVar2 = ” +myVar2; // more info
in your code after some calculations. Then open the block’s dialog, tab to the Comments field,
and run the model. Since “comments” is the comments box (editable text) item in the dialog,
any number assigned to it will be immediately visible in the dialog. This is different than using
192 IDE
Source Code Debugger

the DebugMsg() function (discussed on page 191) to display data, as it doesn’t interrupt the
model for each new number displayed.
Source Code Debugger
No matter what the language, code often does not work the first time. This section shows how
the ModL Source Code debugger can save you time when locating the source of an error in one
of your blocks or the equations in equation-based blocks. It provides a tutorial that shows how
to step through lines of source code, examine values of variables, create breakpoints with con-
ditions, and analyze block problems. It also discusses the various Debugger windows and dia-
logs.
In addition to being useful when creating or editing the source code of blocks, the Source Code
Debugger is available when using equations in equation-based blocks. See the How To:
Debugging Tools section of the ExtendSim User Reference for more information.
Overview of the debugger
A source code debugger makes it much easier to determine the causes of block malfunctions.
You can watch the execution of the ModL code and see its path and the effects it has on any of
IDE

the variables used in the block.


Definition of terms
A breakpoint is where the debugger will initially stop execution of the block’s code and open
the Debugger window. You can then manually step through lines of code to trace its execution,
and examine the effects on the variables defined in that code and in the block’s dialog and con-
nectors.
The breakpoint condition is the TRUE or FALSE boolean decision that causes the breakpoint
to break execution only under certain circumstances. This is valuable if there could be too
many breaks and an important break only occurs rarely, with certain values of variables.
☞ See also the descriptions of the Debugger windows and dialogs in “Source code debugger ref-
erence” on page 203.
Steps for debugging
As illustrated in the examples that follow, the steps to debug code are:
1) Use a menu command to recompile a block, a library, or several libraries in debugging
mode.
2) Add breakpoints (indicated by red circles) by clicking on the code markers in the left mar-
gin of the Set Breakpoints window. (To remove a breakpoint, click it again.)
3) Add a condition to the breakpoint in the Set Breakpoints window so that it will occur at the
appropriate time and model state. Conditional breakpoints display as blue circles.
4) Run the simulation. Or click an item in the block’s dialog to execute the code.
5) When the breakpoint is reached, step through the code and examine the variables.
6) After you have resolved the problem, use the menu command to remove the breakpoints
and any debugging code from the libraries.
Debugger tutorial
This tutorial shows how to add debugging code to a block and to an entire library as well as
how to use the Source Code Debugger to track down and fix an error in a block’s code.
Debugging 193
Debugger tutorial

The Debug Tutorial model


Open the Debug Tutorial model located in the Documents/
ExtendSim/Examples/How To/Developer Tips folder. As
shown to the right, the model consists of three connected
blocks which generate data, process the data, and plot the
Debug Tutorial model
result.
Run the model. You
should see the error mes-
sage at the right, fol-
lowed by a second
message that stops the simulation.
Click OK to close those error messages.
Debugging one block
The error message indicates the offending code is in the Start block, so start with setting the

IDE
block to be in debugging mode.
On the model worksheet, right-click the Start block and choose Set Breakpoints and Add
Debugging Code (or select the block and choose that command from the Develop menu).
This recompiles the
block in debugging
mode and opens two
windows:
• The Breakpoints
window shows
the breakpoints
for all the blocks
in the model
• The Set Break-
points window is
for setting break-
points in the
selected block; in
this case, the
Start block
These windows are
described more in
“Source code debugger
reference” on page 203.
For now, since the debugger automatically stops at an error message, you don’t need to set
breakpoints. Close the Set Breakpoints window
Notice that on the model worksheet and in the Tutorial library window, the Start
block’s icon is now surrounded by a red border, indicating that the block is in debug-
ging mode. Blocks in debugging mode will execute more slowly—the red markings
are a reminder that you should remove debugging code when finished.
194 IDE
Debugger tutorial

Going to the Debugger


Run the model again. You’ll get the same error message but it now
has an Go to Debugger button.
Click the Go to Debugger button. This opens the Debugger window shown below.
IDE

Debugger window after error message

• The title bar indicates that the error occurred at currentTime: 8


• In the Source pane at the left:
• A green location arrow in the Breakpoint margin on the left points at line 16 (“b =
array[timeIndex];”).
• The variable Array is declared at the top of the script and has 10 members (Real
array[10]).
• In the Variables pane at top right, the index variable timeIndex has a value of 10. If you dou-
ble-click the Value for the Array variable, you will see that the number of members is
indexed from 0 to 9.
• The point where the error occurred ([0]Start MYFUNCTION, line 16) is selected in the bot-
tom right pane, known as the Call Chain pane.
In order to debug this, you need to find out how MyFunction got called and see the chain of
events that led to this error message.
Debugging 195
Debugger tutorial

Going up the call chain


In the Call Chain pane, select the “DATAOUT, line 32” entry (the top entry above the origi-
nally selected entry), as shown below.

IDE
Debugger window after clicking top entry in Call Chain

Notice that the location arrow in the Breakpoint margin is now yellow for this entry, indicating
it is the previous entry in the Call Chain. The selected message handler is called DataOut,
which is the name of one of the connectors on the block. It indicates that a connector message
was received from a block that is connected to the Start block.
To see the code of the block that sent this message, you need to compile it in debugging mode
too. Then it can be seen in the Call Chain and you can click its entry to see the code that caused
the chain of events. But rather than setting individual blocks to debugging mode, it is often eas-
ier to set the entire library.
Debugging an entire library
If the Debugger window is open, stop debugging or close the Debugger window. That way
you won’t be in the middle of debugging code when the library is changed.
Choose the menu command Library > Library Tools > Add Debug Code to Libraries
In the window that appears, choose the libraries the model uses (in this case, only the Tuto-
rial library) and click Add Debugging Code
After ExtendSim finishes compiling all of the blocks in the Tutorial library, the three blocks on
the Debug Tutorial model will be outlined in red, indicating that they are in debugging mode.
Run the model again.
When the error occurs, click the Go To Debugger button to access the Debugger window.
196 IDE
Debugger tutorial

Following the Call Chain


The Source Code Debugger allows you to follow the chain of events that caused the error.
Click on the top Call Chain entry (Process SIMULATE, line 14); this is one that started this
whole chain of events.
IDE

Debugger window with top Call Chain entry selected

In the Source pane’s Breakpoint margin, the yellow location arrow points to line 14, as indi-
cated in the Call Chain. There was a SendMsgToOutputs function call from the Process block
because its input (ProcessIn) was greater than 7.0. (The actual value can be seen in the Vari-
ables pane as 10.6046.)
Debugging 197
Debugger tutorial

Click on the second Call Chain entry (DATAOUT, line 32):

IDE
Debugger window with message handler selected

The Variables pane indicates that CurrentTime is 8. Line 32 of the Source pane shows that the
code called MyFunction with an argument equal to10.0 (CurrentTime+2.0).
198 IDE
Debugger tutorial

Click on the bottom Call Chain item where the error occurred (MyFunction, line 16):
IDE

Debugger window with error point selected

Since the error message indicated that Array was


indexed beyond its bounds, inspect Array by double-
clicking its value in the Variables pane.
In the Array window, shown at right, notice that the array
is indexed from 0 to 9. However, the code tried to index it
with a 10, which is outside its bounds, resulting in an error
message.
Fixing the block’s code #1
The model is being run from a CurrentTime of 0 to a Cur-
rentTime of 10, and the code could be adding 2.0 to the
CurrentTime in some cases. The way to fix the problem is Array window
to increase the size of Array so that it can be indexed from
0 to at least 12.
Click the Stop Debugging and Edit Code button at the top of the Debugger window.
This takes you to the location of the error in the Start block’s structure window
Change the declaration of Array[10] to Array[13]
Close the block’s structure window and compile the block
Debugging 199
Debugger tutorial

Run the model again and note that this


time there is no error message. How-
ever, the plotter shows a drop off in val-
ues around time 7 and you know from
experience that the Smedley function is
supposed to be increasing.
To see what the problem is you need to set
breakpoints.
Setting breakpoints
To open its Set Breakpoints window,
right-click the Start block on the model
worksheet and select Set Breakpoints
and Add Debugging Code.
(Since the entire library already has its code set for debugging, this just reopens the Start

IDE
block’s Set Breakpoints window.)
To set a breakpoint, go to the Breakpoints margin on the left side of the Set Breakpoints
window and click on the code marker for line 16—the location of the B = array[timeIndex]
statement.

Start block debugging window

A red circle appears where you clicked. Running the model will now cause the simulation to
break (pause) at that point, opening the Debugger window.
Run the model
200 IDE
Debugger tutorial

The Debugger window opens and the breakpoints margin has a green arrow on top of a red
circle. The green arrow indicates that this is the part of the code that will be executed next;
the red circle indicates that there is also a breakpoint there.
IDE

Breakpoint reached

In the Variables pane, timeIndex is 0, which means the simulation is stopped at the beginning.
You can either:
Click the Continue button in the Debugger’s toolbar 10 times until the breakpoint
occurs at timeIndex 10
Or, set conditions as described below
Setting conditions
Clicking until a timeIndex of 10 is reached can get tedious. Instead, set a condition on the
breakpoint so the code only breaks when timeIndex is greater than or equal to 10.
Close the Debugger window or click the Stop Debugging button in the Debugger window’s
toolbar (this also stops the run)
Debugging 201
Debugger tutorial

Choose Develop > Open Breakpoints Window (or bring the Breakpoints window forward
if it is open)

Breakpoints window showing the breakpoint

The Breakpoints window has two columns: Breakpoint and Condition. Double-click in the
Condition column that relates to the breakpoint (in this case, there is only one breakpoint).
A new window appears for setting conditions:

IDE

Condition window

In this window, do the following:


In the Variable A column, select timeIndex (long)
For the comparison, choose the radio button A>=B
202 IDE
Debugger tutorial

Below the Variable B column, check the checkbox Use constant for B and enter 10 as
the constant
Click OK to save your changes and close the Breakpoint Conditions window
Run the model again
When the breakpoint occurs, click the Step over button in the Debugger window’s toolbar to
see the value of b over time. (Note that, in this case, the Step over and Step into buttons do
the same thing, because there is no function call to step into.)
The calculated value of b at timeIndex 10 is zero. This should not happen because, as noted
earlier, we know that the value of the Smedley function should increase over time, not
decrease.
Fixing the block’s code #2
Double click the Array variable to look at its values – the result is
shown at the right.
In the array, elements 10-12 are zero, indicating that the Smedley
IDE

values for the new larger array have not been calculated. The code
should be changed so that no matter what the size of the array is, it
will be filled.
Changing the block’s code
Click the Stop Debugging and Edit Code button in the Debugger’s
toolbar. This closes the Debugger and opens the Script tab of the
Start block’s structure.
In the Start block’s code, change the Initsim message handler (line
43 to line 50) to read:
on initsim
{
integer i, length;
length = GetDimension(array); // get length of array
// initialize the array so we don’t have to recalculate it
for (i=0; i<length; i++)// use length to limit loop
array[i] = Log(GammaFunction(i+1));
}

Instead of hard coding i <10, this code calls a function to return the array length into a new
variable called length which is used to limit the calculation loop. Then any time the size of the
array is changed the entire array will be filled.
Close the block’s structure and Save and Compile the block.
Disabling and removing breakpoints
To temporarily disable a breakpoint, click once on the red circle in the margin of the Break-
points window. This turns the red circle into an empty circle.
To remove a breakpoint, select the breakpoint’s name in the in the Breakpoints window and
delete it. Or click once on the red circle in the left margin of the Debugger window.
Since the Debugger window has closed:
Debugging 203
Source code debugger reference

Remove the breakpoint by selecting the breakpoint information (MYFUNCTION, line 16,
[0]Start) in the Breakpoints window and clicking the Delete key
Run the model again to see the correct output:

IDE
The well-behaved Smedley function

☞ Making Array a dynamic array and then resizing it in InitSim would allow the model to be run
for any EndTime value without overrunning Array.
Source code debugger reference
The following sections discuss the Debugger and its windows and dialogs.
Setting a block or library to be in debugger mode
In order for you to use the Source Code Debugger, ExtendSim has to generate debugging code
for a block or blocks.
• To add debugging code to one or a few blocks, select the block or blocks on the model work-
sheet and choose the command Develop > Set Breakpoints and Add Debugging Code (or
right-click the block). This automatically generates debugging code for the selected blocks
and opens a Set Breakpoints window for each block selected.

• To add debugging code to an entire library, choose the command Library > Library Tools >
Add Debug Code to Libraries. (This takes longer than setting a block to debugging mode.
But it is especially useful if you are trying to debug blocks in a discrete event model, since
the messages will be traceable back to their originators via the Call Chain in the Debugger
window.) After the library is in debugging mode, right-click the blocks on the model work-
sheet that you want to add breakpoints to, or select them and choose the Develop > Set
Breakpoints and Add Debugging Code command.
204 IDE
Source code debugger reference

Debugger window
IDE

When the model is run and execution reaches the breakpoint, the Debugger window opens and
shows the ModL code, values of variables, the Call Chain, and (in the title bar) the current-
Time.
☞ The only way to access the Debugger window is to run a model with one or more blocks in
debugging mode, where there is also either an error message or breakpoints that have been set.
You can set a breakpoint in a block’s Debugger or Set Breakpoint window. However, since the
Debugger window is only open during the model run, it is more common to set breakpoints in
the Set Breakpoint window.
Toolbar
There are six tools at the top of the Debugger
toolbar. From left to right, they are:
• Continue continues execution until the next
breakpoint is reached. Debugger toolbar
• Step Over executes a function call without
stepping into the function code. It is used when you want the debugger to execute the line of
code with a function call, but not to trace the code of the function.
• Step Into steps into the function call. It is used when you want the debugger to trace the
actual function call, including the code of the function.
• Step Out continues execution until it gets to the caller of the function. It is used when you
want to complete the function or message handler that is currently executing and step back
to the calling function.
• Stop Debugging stops the debugging session and returns to the ExtendSim program.
• Stop Debugging and Edit Code stops the execution of the block, opens the block’s structure
window, and positions the cursor at the point where execution stopped. This is particularly
useful when you have found the error and want to edit the code to make a correction.
Debugging 205
Source code debugger reference

Popup menus
• The Functions popup menu can scroll to any function and shows which function you are in.
• The Includes popup menu shows which include files are used in the block. It allows you to
set breakpoints in an include by displaying its contents in the source pane.

Margin indicators in the Debugger window


At the left of the Debugger window, the Breakpoints margin provides the following indicators:
• Active, unconditional breakpoints are shown as a red circle
• A blue circle indicates an active breakpoint that has a condition
• An empty white circle indicates the breakpoint is temporarily disabled
• A green location arrow indicates where the code is going to execute next
• A yellow location arrow indicates where the previous entry in the call chain is going to exe-
cute

IDE
To add breakpoints, click on one of the code markers in the Breakpoints margin. To remove a
breakpoint, click it again. To add a condition to a breakpoint, use the Breakpoints window,
shown on page 206.
Set Breakpoints window

This window shows the ModL code and the breakpoints for the indicated block. The Break-
points margin, with code markers and any breakpoints, is on the left. The popup menus at the
top of this window are the same as for the Debugger window on page 204.
To add a breakpoint, click on a code marker in the Breakpoints margin. This places a red circle
on the code marker, as seen above. To remove the breakpoint, click its red circle in this win-
dow once so it returns to a code marker, or delete the breakpoint from the Breakpoints window,
discussed below.
206 IDE
Source code debugger reference

Breakpoints window

The Breakpoints window shows breakpoints for the entire model as well as any conditions for
those breakpoints. It is used for enabling, disabling, and deleting breakpoints and for adding
conditions to breakpoints. For a model with blocks in debugging mode, the Breakpoints win-
dow is opened by the command Develop > Open Breakpoints Window.
• A red circle indicates an enabled breakpoint.
• To temporarily disable a breakpoint, click the red circle once– it becomes an empty white
circle. To return the breakpoint to active status, click the empty circle once.
IDE

• To delete a breakpoint, select its name from the Breakpoint column and click the Delete key.
• To enable a condition for a breakpoint, double-click in its Condition column, opening the
Breakpoint Conditions dialog.
Debugging 207
Source code debugger reference

Breakpoint Conditions dialog

IDE
Conditions allow a breakpoint to be ignored unless the condition is TRUE. This is useful when
you get too many breakpoints and you are only interested in a breakpoint that occurs at a spe-
cific time or when a variable reaches a specific value.
The Breakpoint Conditions dialog makes it easy to construct a conditional breakpoint with no
coding. You can enter a currentTime value and/or any other comparison that might be helpful
in narrowing down the problem.
Accessing the dialog
To access the Conditions dialog, double-click in the Condition column of the Breakpoints win-
dow shown on page 206.
To enter a comparison:
Select a variable from column A
Click the desired comparison operator radio button
Choose a variable from column B or check the Use constant for B check box and enter a
constant in that field
Optionally you can enter a currentTime value and/or click the Ignore comparison and always
break check box so that your entered condition will be saved but ignored for the present.
208 IDE
Source code debugger reference

WatchPoints
A WatchPoint condition detects when the variable A changes value and will break to the
Debugger whenever that occurs. To use this, select Watch(A) from the comparison operator list
between the Variable A and Variable B columns. This is most useful in finding a statement in a
different block that is changing a variable incorrectly, and the statement cannot be found easily
by normal means.
In order for watchpoints to work correctly, all blocks in a library should be compiled with
debugging code turned on. WatchPoints slow model execution as they have to be checked con-
tinuously while code is executed.
Arrays
If a variable used in a condition is an array, you need to specify which cell is being referenced.
Do this by filling out the Array Indexes section below the Variable A and/or Variable B col-
umns, as appropriate. For example, to watch the 2nd row and 3rd column of MyArray, you
would enter [1][2] in the Array Indexes field.
Ignore conditions checkbox
IDE

Check Ignore conditions and always break when you’ve met the condition once and may not
meet it again, but you want to keep exploring that breakpoint. This saves the conditions so you
can use them later.
Debugging tips
• To quickly debug a block, select the block and choose Develop > Set Breakpoints and Add
Debugging Code. This checks the block structure, recompiles the block for debugging, and
opens the Set Breakpoint window.
• To debug the sending of interblock messages, compile the entire library for debugging using
the Library > Library Tools menu. That way the Call Chain will contain the entire chain of
messages and it will be obvious which block sent what to whom.
• When a breakpoint occurs, click the Step over button in the Debugger toolbar to see how the
values of the variables change. To jump to a later CurrentTime, go to the Break Point Condi-
tions dialog.
• When finished debugging, you should remove all of the debugging code as it slows execu-
tion considerably. To do this, choose Library > Library Tools > Remove Debug Code from
Libraries.

• Be proactive and use the Debugger to step through code even when you think it is working
properly. Try different cases just to make sure that the block is working as you have
intended. This will give you confidence in what you have written.
Variables, Messages, & Functions

ModL Variables
A detailed description of the ModL variables
that can be used in your block code

“Knowledge is of two kinds. We know a subject ourselves,


or we know where we can find information upon it.”
— Samuel Johnson
210 Reference
System variables

This chapter includes a complete list and description of the system and global variables.
• System variables provide information about the state of the simulation
• Global variables are used to pass information between blocks
System variables
System variables give you information about the state of the simulation. They are declared by
ExtendSim and can be viewed or modified by any block in a model.
☞ You can read or write to these variables, but you should be careful when writing to any of them.
Table of system variables

Name Description
AnimationOn Tells the state of the Run > Show 2D Animation command. If it is checked,
AnimationOn is TRUE (1), otherwise it is FALSE (0). (Note that closed hierar-
chical blocks always see a value of FALSE until they are opened. This speeds
simulations by preventing needless animation when the modeler can’t see it
anyway.)
AntitheticRan- If TRUE, ExtendSim's random number functions generate antithetic random
domVariates numbers.
CurrentScenario In models where the Scenario Manager is running a series of scenarios, this is
Variables

the current scenario number. This will be equal to the row in the Scenarios
table that is currently providing the factors to the model.
CurrentSense Used by the sensitivity analysis feature to determine the number of the simula-
tion run for changing sensitivity variables. It is initially set to 0 and is incre-
mented by 1 during each simulation, after ENDSIM. However, you may
choose to change CurrentSense to any value you want for whatever reason
during ENDSIM –ExtendSim will simply increment it after ENDSIM and use
that for its variable calculations. You should not change CurrentSim, and you
can always refer to that variable to find the actual simulation number.
CurrentSim Current simulation number. Its value starts at 0 and increments each step up to
NumSims-1. It only has a positive value if you set the Number of runs option
in the Simulation Setup or Sensitivity Setup dialogs to a value greater than 1.
CurrentSim has a value of -1 when there is no simulation running.
CurrentStep Current step number. In a continuous simulation, its value starts at 0 and incre-
ments each step up to NumSteps. In a discrete event simulation, the value starts
at 0 and increments with each event.
CurrentTime Current time during the simulation. In a continuous simulation, its value starts
at StartTime and increments at DeltaTime for each step in the simulation. In a
discrete event simulation, the Executive block (Item library) changes the Cur-
rentTime system variable only when processing an event.
DeltaTime Time increment per step. This value is initialized by the Simulation Setup dia-
log and represents the basic increment of time used in the simulation. Delta-
Time has no meaning in a discrete event or discrete rate simulation.
ModL Variables 211
Global variables

Name Description
EndTime Ending time for the simulation specified in the Simulation Setup dialog. This is
the time at which the simulation ends, unless a block stops the simulation with
an abort statement or a discrete event or discrete rate simulation runs out of
items or events.
GlobalProofStr Set by the Proof Animation code of a block.
ModernRandom Tells the state of the random number. If the current random number generator
is being used, ModernRandom is 1. If the previous version of the random num-
ber generator is being used (for backwards compatibility), ModernRandom is
0. (See “Random numbers” in the ExtendSim User Reference for a discussion
about the random number generator.)
MovieOn This legacy variable is currently unused.
NumScenarios In models where the Scenario Manager is running a series of scenarios, this is
the total number of scenarios that will be run.
NumSims Number of times the simulation will be repeated, as specified in the Simulation
Setup or Sensitivity Setup dialogs.
NumSteps The total number of steps that will be executed during a continuous simulation.
NumSteps is the number of steps entered in the Simulation Setup dialog. Num-

Variables
Steps has no meaning in a discrete event or discrete rate simulation.
OleGlobal, Ole- These variables are set by the external application sending an OLEAutomation
GlobalInt, OleG- message to a block. They act as arguments that the block can access when it
lobalStr gets the message.
RandomSeed Sequence number used to initialize the random number generator; it is set in
the Simulation Setup or Sensitivity Setup dialogs. When debugging a simula-
tion, it is sometimes necessary to force the random number generator to pro-
duce a repeatable sequence of pseudo-random numbers.
SimDelay Tells the method of simulation order: 0 for Left to right, 2 for Flow order, 3 for
Custom order.
SimMode 0 for manual mode (deltaTime or numSteps values as entered in the Simulation
Setup dialog), 1 for autostep fast (use entered values unless model calculates
smaller deltaTime), and 2 for autostep slow (divide calculated deltaTime by 5),
as specified in the Simulation Setup dialog.
StartTime Starting time of the simulation at step 0. It is initialized in the Simulation Setup
dialog.

Global variables
Global variables are useful for passing information between blocks. They are predefined by
ExtendSim and stored within the model. They can be used by any block anywhere in a model.
The ExtendSim application never changes the values of global variables except to initialize
them when a new model is created.
Types
There are two types of global variables
212 Reference
Global variables

• General use global variables have a name that starts with “Global”. They can be used any
way you want.
• Reserved global variables start with “SysGlobal”. These System Globals are controlled by
the libraries and features that are included with ExtendSim and their use is reserved.
Never use the SysGlobal variables for your own purposes; always use the general use globals
(Global, GlobalInit, and GlobalStr) instead.
General use global variables
The following global variables are available for your use in equations or when creating blocks.

Name Type Use


Global0 through Global19 Real General
GlobalInt0 through GlobalInt9 Integer General
GlobalStr0 through GlobalStr9 String General

Reserved global variables


The system globals, which start with “Sys”, are reserved by Imagine That Inc. for our internal
purposes.
Variables

You can use the SysGlobal variables (for example, when creating discrete event or discrete rate
blocks), but you should only use them in the same way they are used by the ExtendSim appli-
cation.
☞ See “Globals in discrete event blocks” on page 181, “Globals in discrete rate blocks” on
page 185, and “Globals for ARM (Advanced Resource Management)” on page 187 for tables
that describe how ExtendSim uses the reserved globals during the Simulate, CheckData, and
InitSim messages.

Name Type Use


SysGlobal0 through SysGlobal29 Real Reserved for ITI
SysGlobalInt0 through SysGlobalInt79 Integer Reserved for ITI
SysGlobalStr0 through SysGlobalStr9 String Reserved for ITI
SysFlowGlobal0 through SysFlowGlobal4 Real Reserved for ITI
SysFlowGlobalInt0 through SysFlowGlobalInt29 Integer Reserved for ITI
SysFlowGlobalStr0 through SysFlowGlobalStr4 String Reserved for ITI
SysDBNGlobalInt0 through SysDBNGlobalInt19 Integer Reserved for ITI
SysARMGlobalInt0 through SysARMGlobalInt19 Integer Reserved for ITI
Variables, Messages, & Functions

Messages and Message Handlers


A detailed description of the ModL messages

“Knowledge is of two kinds. We know a subject ourselves,


or we know where we can find information upon it.”
— Samuel Johnson
214 Reference
Summary of messages

Messages and message handlers were introduced on page 33 and discussed more in “Message
handlers” on page 75 and “Using message handlers” on page 109.
The following table summarizes each category and type of ModL message. The three catego-
ries of messages (application, user interaction with the dialog, and block-to-block) are dis-
cussed on page 109. Note that while messages can originate either from the ExtendSim
application or from blocks, it is always a block that is on the receiving end of a message.
Summary of messages

Category Type Purpose Page


Application Simulation Sent to blocks in simulation order during a simu- 214
lation run
Application Model Status Sent to all blocks in a model when the model 216
changes state
Application Block Status Sent when clicking on a block or connector, when 217
placing, deleting, moving, or pasting a block, or
when a model is opened on a different computing
platform.
Dialog activity Dialog Sent when the modeler interacts with a block’s 219
dialog
Block to Block Connector Sent via the Connector Message functions, or by 221
the system when a modeler manually changes the
number of variable connectors, or when the mod-
eler connects or disconnects a block
Block to Block Block to block System and user-defined messages sent from a 222
block’s ModL code when communicating infor-
Messages

mation to other blocks


Application Dynamic Link Sent to subscribed blocks when there is a change 223
to the ExtendSim database or global array part
that they are linked to
Application OLE Sent in response to OLE conditions 223
Application 3D Animation Sent in response to 3D animation events 223

Simulation messages
These messages are sent to all blocks during the simulation run in the following order:

Message When sent


ModifyRunPa- Sent before the simulation run begins to allow changing the Simulation Setup
rameter parameters via the SetRunParameter() function (see page 336). Note that this is
sent only once even for multiple simulation runs.
SimStart Sent after ModifyRunParameter and before all other simulation message han-
dlers. See the BlockSimStartPriority() function on page 328 for details.
Messages and Message Handlers 215
Simulation messages

Message When sent


PreCheckData Sent to prepare blocks for CheckData, below. Most blocks can ignore this mes-
sage.
CheckData This is the best place to check whether all data that is to be used in the block is
valid. If the data is bad, you should execute an “abort” statement, so that
ExtendSim will select the block and alert you that the data is missing or bad.
During this message, connectors that are connected to something else in the
model always have a true (any non-zero) value and unconnected ones have a
false (zero) value. This makes it easy to check whether a block is connected
properly before running a simulation.
StepSize After all CheckData messages. If the code needs a particular StepSize, set it
here. In continuous models, set the DeltaTime system variable to the maximum
step size. ExtendSim queries all blocks and uses the smallest DeltaTime value
returned. This message is also used to set up the attribute global arrays in a dis-
crete event model.
InitSim Just before the simulation starts. If your block’s code uses DeltaTime (continu-
ous model only), check it here. Also, allocate any arrays that are dependent on
DeltaTime, NumSteps, or any other system variable. This is also a good time to
set any static variables, dialog items, or connectors that change when the simula-
tion starts. (Note that ContinueSim, below, is sent instead of InitSim when con-
tinuing a saved model’s run.)
ContinueSim This message is sent instead of InitSim if you are continuing a saved model’s
run. Set up any variables for continuing a saved model run.
PostInitSim Sent to give blocks another chance to initialize variables that could not be ini-
tialized until after the InitSim was sent to all blocks. Most blocks can ignore this
message.

Messages
Simulate Every step of the simulation. Note that this message gets sent over and over, not
just once. This is where most of the “action” in a block takes place. For instance,
you check and change the value of connectors in this message handler.
In continuous simulations, the first Simulate message gets sent with Current-
Time=StartTime and CurrentStep=0. For subsequent Simulate messages,
ExtendSim adds 1 to CurrentStep and adds DeltaTime to CurrentTime. The last
Simulate message occurs when CurrentStep=NumSteps-1 and Current-
Time=EndTime, so each block gets NumSteps Simulate messages.
In discrete event and discrete rate simulations, the first Simulate message gets
sent with CurrentTime = StartTime and CurrentStep = 0. For subsequent Simu-
late messages, the Executive block (Item library) controls how CurrentTime is
advanced. See the GetSimulateMsgs() function for how to turn off simulate
messages in a block under certain conditions.
AbortSim Sent only if an Abort occurred during the Simulate messages. This notifies the
blocks to clean up and lets them know that an abort occurred.
FinalCalc Sent after the Simulate messages are over and before the BlockReport messages.
Used for any final calculations that the block might need before the BlockReport
and EndSim messages.
216 Reference
Model Status messages

Message When sent


BlockReport Sent after the FinalCalc messages. If a block receives this message, it has been
selected for a report. To organize the reports by block category (see “Block cate-
gories” on page 55), ExtendSim cycles through each block category and sends
this message to any block selected for a report.
EndSim At the end of the simulation. Use this to clean up any memory that you used or
to reset values. This message gets sent even if the modeler or the block’s code
aborts the simulation.
SimFinish Sent after all other simulation message handlers. See BlockSimFinishPriority()
function at page 328 for details.

Model Status messages


When the status of the model changes, these messages are sent to all blocks:

Message When sent


ActivateModel Sent to all blocks in a model when that model is brought in front of a different
model. This allows blocks to modify their data or appearance if the model is
activated.
AnimationSta- Sent to all blocks in a model when the 2D Animation command changes state.
tus This is useful to change a block's appearance according to the value of the Ani-
mationOn variable.
CloseModel Right before the model closes, this message is sent to all blocks in the model to
let them know that the model is closing.
ModelSave This message is sent to each block at the beginning of a save. You might use this
Messages

message handler to dispose of unneeded data before it gets saved.


OldFileUpdate Before the openModel message, if the file version is older than the application
version.
OpenModel Sent when a model is opened, or to a new hierarchical block that has just been
placed on the model worksheet. Use this message handler to set some block
variables to values that you only want to reset when a model is opened, not at
the beginning of a simulation.
OpenModel2 Sent after all of the blocks have received the OpenModel message, or after the
OpenModel message to a new hierarchical block that has just been placed on the
model worksheet. Use this message handler to set some block variables to val-
ues that you only want to reset when a model is opened, not at the beginning of a
simulation.
PauseSimula- Sent to ALL blocks when the modeler pauses the simulation. Contrast this to
tion ResumeSim which is sent only to the block that the modeler has changed, and
ResumeSimAllBlocks sent to all of the blocks in the model.
Messages and Message Handlers 217
Block Status messages

Message When sent


ResumeSim This message allows the ModL code to respond to changes before continuing
the simulation. It is sent when the modeler:
• Either clicks dialog buttons during the simulation
• Or, edits a parameter and chooses Run > Resume (or clicks the Resume button
in the simulation status bar).
Note: This message is sent only to the blocks that have had dialog values edited.
ResumeSi- This message allows the ModL code to respond to changes before continuing
mAllBlocks the simulation. It is sent when the modeler:
• Either clicks dialog buttons during the simulation
• Or, edits a parameter and chooses Run > Resume (or clicks the Resume button
in the simulation status bar).
Note: This message is sent to all of the blocks in the model, as opposed to
ResumeSim, above, that is sent only to the blocks edited.
SimOrder- Sent when the modeler changes connections, connects a new block, deletes con-
Changed nections or blocks, or does anything that changes the simulation order.
SimSetup Sent when the modeler changes anything in the Simulation Setup dialog.

Block Status messages


These messages are sent to individual blocks:
• When the block is clicked
• When a block is placed, deleted moved, or pasted
• When a block needs to communicate information to the model

Messages
Message When sent
BlockClick Sent when the modeler clicks on a block. Use GetMouseX(), GetMouseY(), and
GetBlockTypePosition() to find out what portion of the block was clicked. See
the Mandelbrot model (Documents/ExtendSim/Examples/Continuous/Custom
Block Models) for an example.
BlockIdentify Reserved for use by Imagine That Inc.
BlockLabel Sent to the block that just had its Block Label changed, when the label becomes
deactivated. The block can then use the new value of the label.
BlockMove Upon completion of a move, sent to all blocks that moved. (See “Scripting” on
page 337.)
BlockRead This message must be used only with extreme caution – it can cause a crash if
used improperly. It is used to convert version 3.x block data tables to version 4.0
dynamic data tables. See the Information block (Value library) for an example.
Call only the GetFileReadVersion() and ResizeDTDuringRead() functions in
this message handler.
BlockRight- Sent when a block is right-clicked. Usually used to create a custom popup menu.
Click See the Math block (Value library).
218 Reference
Block Status messages

Message When sent


BlockSelect Sent when a block becomes selected. See also BlockUnselect.
BlockUndelete Sent to a block when its deletion is undone using the Edit menu Undo command.
BlockUnselect Sent to a block when it becomes unselected. See also BlockSelect.
Connection- Sent to all newly connected blocks when the modeler makes a connection on the
Make model worksheet. For hierarchical blocks, this is sent to all internal blocks. To
prevent the connection from being completed, you can call the Abort statement.
CloneInit When a clone is placed on the model, sent to the block that owns the clone so
that it can be re-initialized. This is useful for static text that needs to be re-ini-
tialized when cloned.
EquationCom- When an equation tries to execute and it is compiled on the wrong platform, this
pilePlatform message handler should just recompile the equation to fix it.
ConnectorRi- Sent when the modeler right-clicks a connector. Used, for example, in the Item
ghtClick library to create a popup menu that is used to add History blocks to a connection
when that connection is right-clicked.
Connector- Sent when the modeler hides or shows the connectors, either from the toolbar or
ShowHide the Model menu command.
CopyBlock Sent to all blocks selected before a Copy operation. Useful to dispose of a
dynamic array, create a dynamic array, or add a Global Array to the clipboard
using the GAClipboard() function, before the copy.
CreateBlock When the block is added to a model. This is the place to set initial values for the
dialog. Note that this message is only sent to the block when you add it to a
model. If you change the CreateBlock code for a block that already is in a
Messages

model, the changes won’t affect the existing blocks, only new blocks added to
the model.
DeleteBlock Sent when the modeler deletes a block from the model. For hierarchical blocks,
this is sent to all internal blocks.
DeleteBlock2 Sent to blocks after their connection lines to other blocks have been deleted,
right before the block deletion occurs.
DragCloneTo- This message gets sent when a modeler drags a clone onto a block and releases
Block the mouse button when the block is highlighted. If you want to get information
about the clones, call the GetDraggedCloneList() function. Used in the Opti-
mizer, Statistics (Report library) and the Scenario Manager and Find & Replace
blocks (Value library).
HBlockClose When a hierarchical block’s submodel or structure is closed. For hierarchical
blocks, this is sent to all internal blocks.
HBlockFrom- Sent to all enclosed blocks when the H-block from a library is placed on the
Library model. The OpenModel and OpenModel2 messages are then sent to the H-
block.
Messages and Message Handlers 219
Dialog messages

Message When sent


HBlockHelp- This message is sent to all the blocks inside a hierarchical block when the H-
Button block Help button is clicked. This can be used to intercept the Help button mes-
sage for the H-block, and do something of your own implementation instead.
Aborting this message will prevent the message from getting to the rest of the
blocks in the H-block, and prevent the Help text from opening up.
HBlockMove Sent to all enclosed blocks when the enclosing H-block is moved.
HBlockOpen When a hierarchical block is opened, this message is sent to all blocks in its sub-
model.You can use this to correct animation in a hierarchical block that is open-
ing. If you don’t want the hierarchical layout or structure windows to open,
execute an Abort statement in the on HBlockOpen message handler in one of the
blocks in the submodel.
HBlockSave- Sent to all enclosed blocks when the H-block structure is saved to a library.
ToLibrary
HBlockUpdate Sent to all enclosed blocks when the H-block structure is edited and closed.
HelpButton Sent when the modeler clicks the Help button in the block’s dialog. Executing
an Abort statement during this message handler will prevent the ExtendSim
Help from opening.
IconView- Sent when the modeler changes the icon view or when a ModL function call
Change from a block changes the icon view. If this message is stopped with an abort
statement, the change is not made to that view.
MakeSelec- Sent after a selection of blocks is made into a hierarchical block using the menu
tionHierarchi- command.
cal

Messages
MailSlotRe- Sent repeatedly when there are mailslot messages waiting to be picked up. See
ceive the mailslot functions for more information.
PasteBlock When the modeler pastes a block onto the model. For hierarchical blocks, this is
sent to all blocks within the hierarchical block.
PasteBlock2 Sent after the PasteBlock message has been received by all the blocks pasted.
PasteBlock3 Sent after the PasteBlock2 message has been received by all the blocks pasted.
Plotter0Close, Sent when the modeler closes a plotter window.
Plotter1Close,
Plotter2Close,
Plotter3Close
PlotterProper- Sent to the plotter block when a user makes a change to a plot’s properties.
tyChange
TimerTick Sent by the Timer chore started by the StartTimer function. (See the scripting
functions.)

Dialog messages
Dialog messages are the names of dialog items and are sent to the block whenever the dialog is
used. When a button in a dialog is clicked or a parameter is unselected (for example, after it has
220 Reference
Dialog messages

been changed), ExtendSim sends a message with the same name as the dialog item to the
ModL code.
For example, assume a block has a “Count” button in its dialog. When that button is clicked,
ExtendSim sends the “Count” message to the block. If the block has an “on Count” message
handler, it will be executed; if not, nothing happens.
Names for all the named dialog items in a block are listed in the Variables pane at the lower left
of the structure window. If a dialog item (such as static text) does not have a dialog item name,
it will not be listed in the Variables pane.

Message When sent


AbortDialog- If the modeler stops the execution of one of your own dialog message handlers
Message or that message handler executes an Abort statement, this message gets sent to
the block. Use this as an “exception handler” to clean up after an error occurs.
Cancel When the Cancel button is clicked. This restores the block to the state it was in
the last time it was opened, discarding changes to the dialog To keep this behav-
ior, do not change the name of the dialog item from “Cancel”.
CellAccept Sent to a block when the modeler finishes editing any cell in any of the block’s
data tables. You can use this to check the data entered in cells in a data table.
DataTable- Sent to the block when the cursor is hovering over a data table.
Hover
DataTableRe- Sent when the datatable resize button is clicked. Use this so the block can be
size alerted to the new size and inform the modeler if the new size is not acceptable.
Use the function WhichDialogItemClicked to determine which datatable resize
button has been clicked. Use an Abort statement to prevent the resize.
DataTable- Sent to the owning block when one of its data tables is scrolled.
Messages

Scrolled
DialogClick Sent when the modeler clicks on a dialog item, before the actual dialog item
message is sent to the block. Call WhichDialogItemClicked() to find the name
of the item that was clicked. This message is used, for example, to modify the
items in a popup menu at the time it is clicked on but before it opens to the mod-
eler.
DialogClose When the OK or Cancel buttons or the close box are clicked.
DialogItemRe- Sent when a dialog item becomes visible, if it was set up by calling the
fresh SetVisibilityMonitoring() function.
DialogItem- Sent when the cursor hovers over a dialog item so that the block can customize
ToolTip the tool tip (e.g format a value in a special way) that the modeler sees.
DialogOpen When the block’s dialog is opened. To display any static text labels that can
change based on what is happening in the simulation, set them here. If you don’t
want the dialog to open, execute an Abort statement – see also Plotter I/O block
code.
OK When the modeler clicks the OK button. No need to do any special handling in
this section unless you want to check input data. Use an Abort statement to pre-
vent the dialog from closing if data is not acceptable.
Messages and Message Handlers 221
Connector messages

Message When sent


TabSwitch This message is sent to a block when the block’s dialog is switched from one tab
to another. This will also be sent when the dialog is first opened, as that is basi-
cally treated as a click on the last tab that was previously opened. Use an Abort
statement to prevent the tab switch.
YourButton If you have created a button, radio button, or check box named “YourButton,”
this message handler is activated when the button is clicked. Use an Abort state-
ment to prevent the action if necessary.
YourItem Whenever the selection in a dialog is in a parameter or editable text dialog item
and you click another item or press the Tab key (taking the selection out of the
item), the message handler with that dialog item’s name is invoked. This is use-
ful if you want to check the value of the item after it might have been changed.
Use an Abort statement to prevent the value from changing.

Connector messages
These messages are sent to individual blocks:
• Via the Connector Message functions
• By the system when a modeler manually changes the number of variable connectors
• When the modeler connects or disconnects a block
☞ The connector functions start on page 299.
Message When sent
ConArray- Sent continuously when a modeler drags a variable connector to increase or
Changed decrease the number of connectors in its array. Call ConArrayChangedWhich-

Messages
Con() to return the name of the connector, and then call ConArrayGetNum-
Cons() to find out how many connectors there are in the dragged connector.
Abort this message handler to prevent the modeler from adding too many or too
few connectors.
ConArray- Sent when the modeler finishes dragging a variable connector, to allow the
ChangedCom- block to see the final number of connectors chosen.
plete
ConArrayCol- Sent when the modeler collapses or expands the variable connectors.
lapseChanged
Connection- Sent to all connected blocks when a connection is deleted. Note that a block can
Break receive multiple ConnectionBreak messages when blocks or right angle connec-
tions are deleted.
Connection- When a connection line is clicked, sent to all blocks connected so that they can
Click react (e.g. report a value). The function ConnectorToolTipWhich() returns the
connector number for that connection.
222 Reference
Block to block messages

Message When sent


Connection- Sent to all newly connected blocks when the modeler makes a connection on the
Make model. For hierarchical blocks, this is sent to all internal blocks. The function
ConnectorToolTipWhich() returns the connector number for that connection. To
prevent the connection from being completed, you can call the Abort statement
in this message handler.
Connector- Connector message. When the connector on a connected block receives a mes-
Name sage from another block using the connector message functions.
ConnectorRi- Sent when the modeler right-clicks a connector. Used, for example, in the Item
ghtClick library to create a popup menu that is used to add History blocks to a connection
when that connection is right-clicked.
ConnectorTool- Sent when the cursor hovers over a connector so that the block can customize
Tip the tool tip (e.g format a value in a special way) that the modeler sees.

Block to block messages


Model type dependent and user-defined messages sent from a block’s ModL code to communi-
cate information to other blocks:

Message When sent


AttribInfo Sent by the Executive block when attribute information has been changed.
BlockReceive0 Used by the Discrete Event library as system messages.
through 9
ClearStatistics When a block’s statistical variables need to be reset. This message is typically
sent by a Statistics block (Report Library). See the Activity block (Item library)
Messages

for an example of receiving this message.


DEExecutive- Sent by the Executive block to notify Item or Flow blocks that item arrays have
ArrayResize been resized.
BlockTableInfo Sent by some of the blocks to query data table size. Not sent by ExtendSim.
ProofAnima- This message is used by the blocks that are interacting with Proof Animation to
tion produce proof animation functionality.
QueueFunction Sent by the QueueTools block (Utilities library) and the Queue blocks (Item
library) to communicate with each other.
ShiftSchedule Sent by a block to all the blocks in the model when a shift schedule has been
changed.
UpdateStatis- When a block’s statistical variables need to be recalculated and updated. This
tics message is typically sent by a Statistics block (Report library). See the Activity
block (Item library) for an example of receiving this message.
UserMsg0 User-defined message that is not used by any ExtendSim libraries. Use the
through 19 SendMsgToBlock function to send these messages from another block.
Messages and Message Handlers 223
Dynamic Link messages

Message When sent


FlowBlock- Used by the Rate library to communicate information between blocks.
Receive0-
FlowBlock-
Receive19

Dynamic Link messages


When the part they are linked to changes, these messages are sent to individual blocks that are
subscribed to an ExtendSim Database or global array.
☞ Database functions start on page 354; global array functions start on page 378.
Message When sent
LinkContent If linked or subscribed to part of an ExtendSim Database or global array, this is
sent when the data changes within that part. This facilitates recalculation only
when the data changes.
LinkStructure If linked or subscribed to part of an ExtendSim Database or global array, this is
sent when the structure (e.g. number of fields, records, names, etc.) changes
within that part. Use the DILinkUpdateInfo() and DILinkUpdateString() func-
tions to find out what changed.

OLE messages
These messages that are sent to an individual block on particular events.

Message When sent

Messages
AdviseReceive Sent to the block when it receives updated data from an advise conversation (see
the functions for “Interprocess Communication (IPC)” on page 250).
OLEAutoma- Sent to a block when the BlockMsg automation method is invoked. See
tion “BlockMsg” on page 122.

3D messages
Sent to an individual block during 3D events.
☞ The 3D animation functions start on page 276.
224 Reference
3D messages

Message When sent


E3DCollision Sent when two objects are about to collide in the E3D window. Used to control
whether or not a collision occurs or otherwise to respond to a collision. (Be
aware that this message can occur multiple times for each potential collision.)
If a collision is about to happen, the block associated with the 3D object that is
about to collide with another 3D object receives an E3DCollision message. The
new function E3DMessageInfo() discussed on page 294 allows the programmer
to request the 3D object ID of the object that is about to collide and/or the object
that is about to be collided with.
The E3DCollision message has been defined such that aborting the message will
tell the E3D engine that the collision should not happen. This makes the objects
noncollidable for the purposes of that collision. The result is that they will visu-
ally pass right through each other or, in the event that the collision would have
just been the two objects brushing edges, they will just pass right by each other.
This functionality is implemented in the Item library to reduce unintentional col-
lisions that could cause objects to move incorrectly in E3D models.
E3DInit Sent to all blocks in the active model when the 3D window is opened.
E3DStart Sent to all blocks in the active model when the first 3D post event in a simula-
tion is processed.
E3DFinish Sent to all blocks in the active model when the last 3D post event in a simulation
is processed.
E3DClose Sent to all the blocks in the active model when the 3D window is closed.
E3DObject- Sent to the block associated with a 3D object when that object is clicked in the
Click 3D window. This can be used in conjunction with the E3DObjectClicked func-
Messages

tion to respond to clicks on 3D objects.


E3D- Sent to all blocks when the 3D mode (QuickStart, Concurrent, or Buffered) is
ModeSwitch changed.
E3DReachDes- Sent to the block that is associated with a 3D object when the object reaches its
tination destination.
E3DCollision Sent to the block that is associated with a 3D object when the object collides
with another object.
E3DObject- Sent to the block that is associated with a 3D object when that object is moved/
Moved resized in the E3D editor.
E3DTick Sent to the block periodically when the E3DTimer has been started with
E3DStartTick.
Variables, Messages, & Functions

ModL Functions
A detailed description of the ModL functions
that can be used in your block code

“Knowledge is of two kinds. We know a subject ourselves,


or we know where we can find information upon it.”
— Samuel Johnson
226 Reference
ModL function overview

This chapter includes a complete list of the ModL functions. These functions can be called in
the blocks that use equations (Equation, Equation(I), Queue Equation, and Optimizer) and
when creating new blocks.
ModL function overview
The rest of this chapter is a description of all the functions in ModL, listed by type. Within
types, the functions are grouped by category. Within categories, the functions are listed alpha-
betically.

Function Type Page Categories


Math 227 Basic math, Trigonometry, Complex numbers, Statistical and
random distributions, Financial, Integration, Matrices, Bit
handling, Equations
I/O 242 File I/O (formatted), File I/O (unformatted), Internet Access,
Interprocess Communication, OLE/COM, Mailslot, ODBC,
Serial I/O, Other drivers, DLLs, Alerts and prompts, User
inputs
Animation 270 2D Animation visible on the model worksheet and 3D Anima-
tion visible in the E3D window.
Blocks and inter-block 295 Block numbers/labels/names/type/position, Block connectors
communication and connection information, Variable connectors, Connector
tool tips, Dialog items and dialog items from other blocks,
Block data tables, Dynamic linking, Dynamic text items, Dia-
log item tool tips, Block dialogs (opening and closing), Mes-
sages to blocks (sending and receiving), Icon views.
Also see Scripting, below
Models and notebooks 331 Models and notebook information, simulation parameters, DE
Modeling Using Equation Blocks.
Scripting 337 Building and running a model remotely. Also see “Blocks and
inter-block communication” and “Models and notebooks”
above
Reporting 345 Block reporting
Functions

Plotting/Charts 345 Functions for displaying graphs and data


Arrays, Queues, Delays, 376 Dynamic arrays, Passing arrays, Global arrays, Queues, Delay
Linked lists, and String lines, Linked list data structures, and String lookup tables
lookup tables
Database 354 Manipulating databases and database data with the ExtendSim
database
Miscellaneous 394 Strings, Attributes, Calendar Date and time, Time units, Col-
ors, EColors, Timer functions, Debugging, ADO, Help, Plat-
forms and versions

☞ ModL functions are also listed in the ExtendSim Help command alphabetically and by type,
including their arguments. You can copy a function from there to use in your code.
ModL Functions 227
Math functions

Code completion
When you start to type a function or message handler name in the structure window or include
file of a block, it will come up with a list of possibilities. Click the one you want.
Once the function has been placed in the script,
type an open parenthesis “(” immediately follow-
ing it. This causes the parenthesis to turn red and
causes call tips to display the function’s argu-
ments as shown here. The first argument will be
bolded. When you enter it, the parenthesis will turn black. As you enter each argument, subse-
quent arguments get bolded until all are entered.
Overriding
Functions can be overridden by being re-declared any number of times below the first declara-
tion. This is useful in that include files can have basic forms of functions which can be re-
declared and overridden in the main block code.
Type conversion of arguments
All ModL functions expect their arguments to be the data type specified in the function defini-
tion. If you use another type, ModL will automatically convert the argument to the expected
type before the function is called. For the functions that take no arguments, the parentheses are
still required.
Static data limits
Each function has a limit of 32,560 bytes of data for locally defined static data. Dynamic
arrays, global arrays, and database tables are not part of the count and are the more common
and usually more useful method used to allocate large data structures.
Function returns
Except for void functions, which do not return values, all functions return values that are real,
integer, or string. The type of value returned is indicated in the third column of the function
tables as:

Return Meaning

Functions
R Real or Double (8 byte double)
I Integer or Long (4 byte long integer)
S String (up to 255 characters)
V Void function (no value returned)

Math functions
Basic math
These functions perform numerical operations on their arguments.
228 Reference
Math functions

Basic Math Description Return


Ceil(real x) Nearest integral real with a value greater than or equal to x. For R
example: Ceil(1.3) returns 2.0, and Ceil(-1.3) returns -1.0
Erf(real x) Returns the erf value of the variable x. Erf is the Error function, R
which is a special case of the incomplete gamma function. See
Numerical recipes in C.
Exp(real x) ex R
FFT(real Replaces the array with the real and imaginary parts of the fast V
array[n][2], inverse) Fourier transform (see below).
FixDecimal (real Sets the number of figures after the decimal point to fixFigs and R
value, integer returns the result.
fixFigs)
Floor(real x) Nearest integral real with a value less than or equal to x. For R
example: Floor(1.3) returns 1, and floor(-1.3) returns -2.
GammaFunc- Gamma function for x. Do not confuse this with the Gamma dis- R
tion(real x) tribution function.
Int(real x) Nearest integer after rounding toward 0. For example: Int(1.3) I
returns 1, and Int(-1.3) returns -1.
Integerabs(i) Non-negative integer containing the absolute value of the integer I
i.
Log(real x) Natural (base e) log of x. R
Log10(real x) Base 10 log of x. R
Log2(real x) Returns the log base 2 value of the variable x. R
Max2(real x, real y) Maximum of the two arguments. R
Min2(real x, real y) Minimum of the two arguments. R
NearlyEqual(real x, Returns true if the x and y arguments are close enough to equal I
real y, integer preci- each other. The precision argument specifies the number of sig-
Functions

sion) nificant figures to compare the two numbers.


NearlyGreaterT- Returns true if x is greater than y. If equal is TRUE, Nearly- I
han(real x, real y, Equal() is used, with the precision argument, to give an equal or
integer precision, greater result. If equal is FALSE, x has to be greater than y by the
integer equal) precision number of significant figures. See the NearlyEqual()
function.
Nearly- Returns true if x is less than y. If equal is TRUE, NearlyEqual() I
LessThan(real x, is used, with the precision argument, to give an equal or less than
real y, integer preci- result. If equal is FALSE, x has to be less than y by the precision
sion, integer equal) number of significant figures. See the NearlyEqual() function.
NoValue(real x) 1 (True) if x has no value (is blank) or 0 (False) if a value has I
been assigned to x.
ModL Functions 229
Math functions

Basic Math Description Return


Pow(real x, real y) xy. The same results may be achieved with the ^ operator, as in R
x^y. Note that Pow(0,0) is undefined.
Realabs(real x) Non-negative real number containing the absolute value of x. R
Realmod(real x, real x modulo y (that is, the remainder of x divided by y). R
y)
Round(real x, inte- Rounds x to the significant figures specified in the sigFigs argu- R
ger sigFigs) ment.
Sqrt(real x) Square root of x. R

The FFT function replaces the real array argument with the real and imaginary parts of the
FFT. n must be a power of 2. If inverse is TRUE, the inverse FFT is calculated. The real values
are contained in array[n][0], and the imaginary values are contained in array[n][1] (these two
are denoted together as “array[n][i]”). array[0][i] is zero frequency. array [(n/2)-1][i] is the
most positive and most negative frequency. array[n-1][i] is the negative frequency just below
0. See the “four1” routine in Press, Numerical Recipes in C, for more information on this algo-
rithm.
Trigonometry
These functions assume that the argument represents an angle in radians.

Trig Description Return


Acos(real x) Arccosine of x, where x is any real number between -1 and +1 R
inclusive.
Asin(real x) Arcsine of x, where x is any real number between -1 and +1 inclu- R
sive.
Atan(real x) Arctangent of x, where x is a real number. The value returned is R
between -/2 and /2 radians.
Atan2(real y, real x) Arctangent of y/x, where x is non-zero. The value returned is R

Functions
between - and  radians.
Cos(real x) Cosine of angle x. R
Cosh(real x) Hyperbolic cosine of angle x. R
Sin(real x) Sine of angle x. R
Sinh(real x) Hyperbolic sine of angle x. R
Tan(real x) Tangent of angle x. R
Tanh(real x) Hyperbolic tangent of angle x. R
230 Reference
Math functions

Complex numbers
These functions operate on complex numbers composed of two-element real arrays (U, Z, and
result), where U[0] is the real part and U[1] is the imaginary part. All arguments and results are
complex numbers expressed as two-element real arrays:
real U[2], Z[2], result[2];

Complex numbers Description Return


AddC(result, U, Z) result = U+Z V
DivC(result, U, Z) result = U/Z V
MultC(result, U, Z) result = U*Z V
SubC(result, U, Z) result = U-Z V

Statistics and random distributions


These functions can be used both to generate random inputs and to gather statistical informa-
tion from the results of simulations. In the following functions, the following are used as argu-
ments:
real prob, rate, mean, stdDev;
integer nTrials, kthEvent, kthSuccess;

Statistics/
Description Return
distributions
DBinomial(real Number of successes out of nTrials, each with a probability of R
prob, integer success of prob.
nTrials)
DExponential(real Interval between events. rate is the expected (mean) number of R
rate) events per period.
DGamma(integer Waiting time to the kthEvent in a Poisson process of mean equal R
kthEvent) to 1.
Functions

DLogNormal(real Positively skewed distribution. R


mean, real stdDev)
DPascal(real prob, Geometric distribution if kthSuccess equals 1. This returns the R
integer kthSuccess) number of trials needed for the kthSuccess of an event with proba-
bility of prob.
DPoisson(real rate) Number of times an event occurs within a given period. rate is the R
expected (mean) number of events per period.
Gaussian(real Real random member of a Gaussian (normal) distribution with the R
mean, real stdDev) specified mean and standard deviation.
Mean(real array[], Arithmetic mean of the first i members of the single-dimensional R
integer i) array.
ModL Functions 231
Math functions

Statistics/
Description Return
distributions
Random(real i) Uniform pseudo-random integer in the range 0 to i-1 using the I
random seed specified in the Simulation Setup dialog. For exam-
ple, Random(6) returns an integer in the range 0 through 5, inclu-
sive. Random(i) assumes that i is an integer. For the Integer
(uniform) function.
RandomCalculate Returns a random number given a distribution and up to three R
(integer distribu- arguments. If a given distribution does not use all three argu-
tion, real arg1, real ments, a zero should be entered for the unused argument(s). The
arg2, real arg3) following numbers are used to define the distribution:
Beta 1
Binomial 2
Erlang 3
Exponential 4
Gamma 5
Geometric 6
Hyperexponential 7
Integer Uniform 8
Loglogistic 9
Lognormal 10
Negative Binomial 11
Normal 12
Pearsonv 13
Pearsonvi 14
Poisson 15
Real Uniform 16
Triangular 17
Weibull 18
ExtremeValue1A20
ExtremeValue1B 21
JohnsonSB 22
JohnsonSU23
Laplace24
Rayleigh25

Functions
InverseWeibull26
Logarithmic27
Hypergeometric28
Chisquared29
PowerFunction30
Cauchy31
Logistic32
InverseGaussian33
Pareto34
232 Reference
Math functions

Statistics/
Description Return
distributions
RandomCheck- Checks that the arguments passed in are valid for the given distri- I
Param (integer dis- bution. The distribution argument is defined using the numbers
tribution, real arg1, above. Displays an error message if reportError is TRUE and the
real arg2, real arg3, arguments are not valid. If reportError is FALSE, the function
integer reportError) returns the following:
0 Successful
-1 Mean must be greater than 0
-2 Probability must be between 0 and 1
-3 Argument must be between 0 and 1
-4 Shape must be greater than 0
-5 Shape2 must be greater than 0
-6 Most likely value must be between Max and Min values
-7 Min must be less than Max
-8 Arg1 is negative or less than 1.0e-15
-9 Arg2 is negative or less than 1.0e-15
-10 Arg3 is negative or less than 1.0e-15
-11 Arg1 >= Arg2
-12 Arg1 > 1.0
-13 Arg2 > 1.0
-14 Arg3 > 1.0
RandomGetModel- The actual seed used for the model. If the Simulation Setup dialog I
SeedUsed() had 0 entered for the seed, this will return the actual randomized
seed used, not 0. If a non-zero number was entered, this will
return that number. This is different than reading the RANDOM-
SEED global variable, which just shows the actual number
entered in the Simulation Setup dialog, including 0, and doesn’t
show the actual randomized seed used for running the model.
RandomGetSeed() Current seed value or current state of the random number genera- I
tor. Used for saving and restoring the random state when using
different seeds. See RandomSetSeed() below.
RandomReal() Uniform pseudo-random real number x, in the range {0.0 <= x R
<1.0} using the random seed specified in the Simulation Setup
Functions

dialog.
RandomSet- Sets the seed value or saved state of the random number genera- V
Seed(integer i) tor. Used for saving and restoring the random state when using
different seeds. See RandomGetSeed() above.
SeedListClear() Clears the list of the seed values. V
SeedListRegis- Keeps a list of the seed values. Returns a BLANK for success, R
ter(real blockNum- meaning the item was entered in the list, or returns the blockNum-
ber, integer seed) ber of the block that already posted the seed value.
Note: Block number is a real so we can register DB cells that gen-
erate random numbers using a DB attribute. DB attributes will
appear as negative numbers.
StdDevPop(real Population standard deviation of the first i members of the single- R
array[], integer i) dimensional array.
ModL Functions 233
Math functions

Statistics/
distributions Description Return

StdDevSam- Sample standard deviation of the first i members of the single- R


ple(real array, inte- dimensional array.
ger i)
TStatis- Returns an accurate approximation of the point on the students t- R
ticValue(real prob- distribution for a given single tail probability and number of
ability, integer degreesOfFreedom
degreesOfFree-
dom)
UseRandomized- Forces a randomized seed for the current simulation run, overrid- V
Seed() ing any fixed seed entered into the Simulation Setup dialog. Must
be called in CHECKDATA message handler.

See “Random numbers” in the main ExtendSim User Reference for information about how
ExtendSim generates random numbers.
Financial
These functions calculate the unknown parameter in loan and annuity calculations given four
known parameters. The financial functions use standard financial arguments:

Argument Meaning
pv Present value of a cash-flow (real)
fv Future value of a cash-flow (real)
pmt Amount of one payment (real)
ratePer Interest rate per period (real)
nPer Number of periods (integer)

pv, fv, and pmt treat cash received as a positive value and cash paid out as a negative value.
Note that ratePer must match the length of the periods indicated by nPer. For example, if nPer

Functions
is the number of months, ratePer is the interest per month.
payAtBegin is a flag variable. If payAtBegin is TRUE (non-zero), payments occur at the
beginning of the period. If FALSE (0), payments occur at the end of the period.

Financials Description Return


CalcFV(ratePer, Future value R
nPer, pmt, pv,
payAtBegin)
CalcNPER(rate- Number of periods R
Per, pmt, pv, fv,
payAtBegin)
234 Reference
Math functions

Financials Description Return


CalcPMT(ratePer, Payment R
nPer, pv, fv,
payAtBegin)
CalcPV(ratePer, Present value R
nPer, pmt, fv,
payAtBegin)
CalcRate(nPer, Interest rate. If the rate cannot be calculated using the values of R
pmt, pv, fv, the arguments, the function returns a noValue (BLANK) result.
payAtBegin)

Integration
These functions integrate a stream of values. For instance, you may want to integrate values
coming from inputs during a simulation. In the integration functions, the array used in the inte-
gration calculations must be declared a static array of four real values:
real array[4];
real initConditions, inputValue, deltaTime;

Integration Description Return


IntegrateEuler(real Value of a Euler integration in progress. The array must be initial- R
array[4], real input- ized with the IntegrateInit function. The algorithm is a backward
Value, real delta- Euler: out = out + inputValue * DeltaTime.
Time)
IntegrateInit(real Initializes the array for integration. Call this function in the Init- V
array[4], real Sim message handler if you are going to use the integration func-
tions during a simulation. initConditions specifies the starting real
initConditions) value for the integration.
IntegrateTrap(real Value of a Trapezoidal integration in progress. The array must be R
array[4], real input- initialized with the IntegrateInit function. The algorithm is a first-
Functions

Value, real delta- order trapezoid: out = out + DeltaTime * (previousInputValue +


Time) inputValue) / 2.

Matrices
Many intricate tasks can be written in just a few matrix operations. For example, solving
simultaneous equations, curve fitting data, finding the roots of a polynomial, and coordinate
transformations may all be done with matrices. For further information about matrices, see
Matrix Methods and Applications by Groetsch and King, (Prentice Hall, 1988).
The matrices used by these functions are in the form matrix[m][n], where m is the number
of rows and n is the number of columns. Vectors are of the form vector[n], where n is the
number of elements in the vector. Matrices are supported up to 1500x1500.
The complex numbers returned by the Roots and EigenValues functions are in an array that is
declared as array[n][2]. This makes array[k][0] the real part, and array[k][1] the imaginary
part.
ModL Functions 235
Math functions

Complex versions of the matrix functions end in the letter C. All arguments to these complex
functions are complex.
Declarations for matrices are as follows:
real matrix[rows][columns]; // real matrix;
// also matrixA, matrixB, ma-
trixR
real vector[rows]; // real vector; also values
real matrixC[rows][columns][2]; // complex;
// also matrixAC, matrixBC, ma-
trixRC
real vectorC[rows][2]; // complex; also valuesC
real resultC[2]; // a complex number
integer n, m; // dimensions

Rows and columns can be bigger than needed. Just specify desired rows and columns when
calling functions.

Matrices Description Return


Conju- Returns the conjugate values of matrixAC in matrixRC. Both V
gateC(matrixRC, matrixAC and matrixRC are m by n by 2 (complex) matrices.
matrixAC, integer
m, integer n)
Determi- Value of the determinant of matrixA, which is an m by m matrix. R
nant(matrixA, inte- If the matrix is singular, the function returns a
ger m) NoValue.
Determi- Complex version of Determinant which returns its complex result V
nantC(resultC, in resultC. If the matrix is singular, the function returns a NoValue
matrixAC, integer in resultC.
m)
EigenValues(Val- Eigenvalues of matrixA (m by m) are placed into the complex I
uesC, matrixA, array ValuesC. ValuesC is of length m by 2 (complex). matrixA
integer m) may be nonsymmetric. (This routine is based on the EISPACK
method of creating a Hessenberg matrix and iterating that matrix

Functions
into a diagonal matrix through similarity transformations). If the
matrix is singular, the function returns TRUE.
Identity(matrixR, Creates an m by m matrixR with 1s along the diagonal and 0s V
integer m) above and below the matrix diagonal.
Identi- Complex version of Identity. V
tyC(matrixRC,
integer m)
Inner(vectorA, vec- Value of the inner or dot product of vectorA and vectorB of length R
torB, integer m) m.
InnerC(resultC, Complex version of Inner which returns its complex result in V
vectorAC, vec- resultC.
torBC, integer m)
236 Reference
Math functions

Matrices Description Return


LUde- Returns the LU decomposition of input matrixA in matrixR. If the I
comp(matrixR, matrix is singular, the function returns TRUE. Since LU factoriza-
matrixA, integer m) tion in LUdecomp permutes rows to obtain the best pivots, the LU
matrix returned is only directly applicable to diagonally dominant
matrices. The result of LUdecomp can be used in general once the
permutation is accounted for.
LUde- Complex version of LUdecomp. If the matrix is singular, the I
compC(matrixRC, function returns TRUE.
matrixAC, integer
m)
MatAdd(matrixR, Returns in matrixR the addition of matrixA to matrixB. m is the V
matrixA, matrixB, number of rows, n is the number of columns.
integer m, integer
n)
MatAddC(matrixR Complex version of MatAdd. V
C, matrixAC,
matrixBC, integer
m, integer n)
MatCopy(matrixR, Copies matrixA (of dimension m by n) into matrixR. V
matrixA, integer m,
integer n)
Mat- Complex version of MatCopy. V
CopyC(matrixRC,
matrixAC, integer
m, integer n)
MatIn- MatrixR is the inverse of matrixA, which is an m by m square I
vert(matrixR, matrix. If the matrix is singular, the function returns TRUE.
matrixA, integer m)
MatIn- Complex version of MatInvert. If the matrix is singular, the func- I
vertC(matrixRC, tion returns TRUE.
matrixAC, integer
Functions

m)
MatMat- MatrixR (mA by nB) is created from the product of matrixA (mA V
Prod(matrixR, by nA) and matrixB (mB by nB). Note that nA must equal mB.
matrixA, integer
mA, integer nA,
matrixB, integer
mB, integer nB)
MatMat- Complex version of MatMatProd. V
ProdC(matrixRC,
matrixAC, integer
mA, integer nA,
matrixBC, integer
mB, integer nB)
ModL Functions 237
Math functions

Matrices Description Return


MatScalar- This matrix scalar product creates matrixR by multiplying V
Prod(matrixR, matrixA by B. MatrixA is m by n, and B is a scalar (single num-
matrixA, integer m, ber).
integer n, B)
MatScalar- Complex version of MatScalarProd. V
ProdC(matrixRC,
matrixAC, integer
m, integer n, BC)
MatSub(matrixR, Returns in matrixR the difference of matrixB from matrixA. m is V
matrixA, matrixB, the number of rows, n is the number of columns.
integer m, integer
n)
Mat- Complex version of MatSub. V
SubC(matrixRC,
matrixAC,
matrixBC, integer
m, integer n)
MatVectorProd( Creates an m length vector (vectorR) by multiplying matrixA (m V
by n) by vectorB (n).
vectorR, matrixA,
integer m, integer
n, vectorB)
MatVector- Complex version of MatVectorProd. V
ProdC(vectorRC,
matrixAC, integer
m, integer n, vec-
torBC)
Outer(matrixR, Creates an m by n matrix (matrixR) from the product of vectorA V
vectorA, integer m, and vectorB. vectorA is of length m and vectorB is of length n.
vectorB, integer n)
OuterC(matrixRC, Complex version of Outer. V

Functions
vectorAC, integer
m, vectorBC, inte-
ger n)
Roots(real val- Calculates the roots of polynomial p of order n. These roots are I
ues[][2], real p[], returned in the complex array values. The coefficients of the poly-
integer n) nomial p are in an array beginning with the coefficient of the sec-
ond highest power. The coefficient of the highest power is
assumed to be 1. For example:
p[] -> x^n + p[0]*x^(n-1)+ p[1]*x^(n-2) ...+p[n-1]
Note that both values and p can be length n or greater. If the
matrix of the polynomial is singular, the function returns TRUE.
238 Reference
Math functions

Matrices Description Return


Trans- Creates the transpose of matrixA in matrixR. The input matrix is V
pose(matrixR, m by n and the result matrix is n by m.
matrixA, integer m,
integer n)
Trans- Complex version of Transpose. V
poseC(matrixRC,
matrixAC, integer
m, integer n)

Bit handling
The bit-handling functions return the integer value result of the operation. In these functions,
bit 0 is the most significant bit and bit 31 is the least significant bit of ModL’s 32-bit integers.
Declarations for bit handling are as follows:
integer bitNum, Count;

Bit handling Description Return


BitAnd(integer i, Bitwise AND of the two integers. I
integer j)
BitClr(integer i, Sets the bit numbered bitNum in i to 0 and returns the result. I
integer bitNum)
BitNot(integer i) Bitwise NOT of the integer. I
BitOr(integer i, Bitwise OR of the two integers. I
integer j)
BitSet(integer i, Sets the bit numbered bitNum in i to 1 and returns the result. I
integer bitNum)
BitShift(integer i, Shifts i by Count bits. If Count is positive, this shifts to the left I
integer Count) (multiply i by 2^Count); if Count is negative, it shifts to the right
(divide i by 2^Count). 0s are shifted in.
Functions

BitTst(integer i, TRUE if the bit numbered bitNum is set to 1, FALSE if bitNum is I


integer bitNum) 0.
BitXor(integer i, Bitwise Exclusive OR of the two integers. I
integer j)

Equations
These functions let you create a block in which the user can enter equations built on ModL
code and the ExtendSim built-in functions. (Note that user-defined functions must be defined
in include files in order to be used in an equation block.) See “Dynamic text items” on
page 320 if you want to implement much larger (text edit boxes are initially limited to 255
characters) user-entered equations (up to 32000 characters). See the Equation block (Value
library) for an example of using these and the dynamic text item functions in building your
own equation block.
ModL Functions 239
Math functions

See the EquationSetStatic() and EquationGetStatic() functions to use “remembered” values in


your equations.
☞ For cross-platform compatibility, if you build blocks that use the equation functions your code
needs to detect if the model is being opened on a different platform. Therefore, in addition to
your own specific tests, you should test dynArrayName in the CheckData message handler of
any block that uses the equation functions:
On CheckData
{
if (getDimension(dynArrayName) == 0)
EquationCompile(...);
...
}

☞ Because ExtendSim will detect a change of platform and will therefore dispose of dynArray-
Name, the code must check and recompile the equation again when the simulation is run. For a
detailed example, see the Equation block (Value library).

Equations Description Return


EquationCalcu- Calculates an equation compiled by the EquationCompile func- R
late(real input1, ..., tion. The arguments can be integer or real values (such as input
real input 10, inte- connectors). This function returns the real value assigned to the
ger dynArray- output variable. This function should be called whenever you
Name[]) need a new value from the equation, and is usually placed in the
Simulate message handler. Also see “Dynamic text items” on
page 320 for larger equations than 255 characters. If you need
unlimited input and output variables, see EquationCalculateDy-
namicVariables, below.
EquationCalcu- This works the same as the EquationCalculate function, except it R
late20 (real input1, allows 20 inputs. Also see “Dynamic text items” on page 320 for
real input2, ... real equations larger than 255 characters. If you need unlimited input
input19, real and output variables, see EquationCalculateDynamicVariables,
input20, integer below.
dynArrayName[])

Functions
EquationCalculate- Calculates a dynamic text equation using the input arguments I
Dynamic(real from the array arrayValues. Up to 20 input arguments are allowed.
arrayValues[], inte-
ger equationAr-
ray[])
EquationCalculate- This function allows unlimited input and output variables. Input- I
DynamicVari- DynArray values and outputDynArray real array are used in the
ables(real equation like this example: outputsName[i] = inputsName[i];
inputDynArray, Make sure that you have enough elements allocated in the input
real outputDynAr- and output dynamic arrays. See the Equation block in the Values
ray, integer code- library to see how to use this function.
DynArray)
240 Reference
Math functions

Equations Description Return


EquationCompile ( Compiles an equation that is entered into an editable text item or I
string inputVar- string variable in a dialog. The variables inputVarName1 through
Name1, ..., string inputVarName10, outputVarName, and equation are all strings;
inputVarName10, tabOrder is an integer and dynArrayName is an integer dynamic
string output array. The user’s equation can use any valid ModL function or
VarName, string statement, including defining new variables. The compiler outputs
equation, integer error messages and puts the insertion point at the error in the dia-
tabOrder, integer log item identified by tabOrder if it is a dialog editable text item.
dynArrayName[]) The compiler stores the machine code for the compiled equation
in dynArrayName. This function should be called only when the
equation or variable names are changed. Returns TRUE if there
was an error in the equation. Also see “Dynamic text items” on
page 320 for larger equations than 255 characters. If you need
unlimited input and output variables, see EquationCompileDy-
namicVariables, below.
EquationCom- This works the same as the EquationCompile function, except it I
pile20 (string allows 20 inputs and two equation strings. Also see “Dynamic
inputVarName1, ..., text items” on page 320 for larger equations than 255 characters.
string inputVar- If you need unlimited input and output variables, see Equation-
Name20, string CompileDynamicVariables, below.
output
VarName, string
equation, string
equation2, integer
tabOrder, integer
tabOrder2, integer
dynArrayName[])
EquationCompile- Compiles a dynamic text equation. See EquationCompile20(), as I
Dynamic (str31 this is similar except that the input variable names are supplied in
varNames[], string the array VarNames. VarNames can be up to 20 arguments.
dynamicTextAr-
ray, integer out-
putEquation[],
string labelOutput,
integer tabOrder)
Functions

EquationCompile- This function allows unlimited input and output variables. I


DynamicVariables InputsName and outputsName are used in the equation like this
(string inputsName, example: outputsName[i] = inputsName[i]; where i will be the
string out- index of that input or output variable. TabOrder is used to select
putsName, string the correct text item when there is an error in the equation. You
equationDynArray, can do a string substitution in the user’s raw equation to put it in
integer codeDy- this indexed form. See the Equation block in the Values library to
nArray, integer see how to use this function. See also EquationCompileDynamic-
tabOrder) VariablesSilent.
ModL Functions 241
Math functions

Equations Description Return


EquationCompile- Similar to the EquationCompileDynamicVariables function, I
DynamicVariables- except this function doesn't show the lines compiled progress dia-
Silent (string log
inputsName, string
outputsName,
string equationDy-
nArray, integer
codeDynArray,
integer tabOrder)
EquationCompile- See the Equation block for use. The dynArray argument can be V
SetStaticArray any type as the equation compile functions set up the array to hold
(integer dynArray) any declared static variables.
EquationDebug- Calculates the equation using specified input values. The output I
Calculate(integer values for the result will be put into outputVarValuesArray.
debugEquationIn- Returns a TRUE value if an error occurs.
dex, real inputVar-
ValuesArray[], real
outputVarValue-
sArray[])
EquationDebug- Converts the equation code and variable names into block form so I
Compile(integer it can be debugged. DebugEquationIndex is the previously
debugEquationIn- returned value from a previous call to this function for this equa-
dex, string equa- tion, or -1 (minus one) when this function is called for the first
tionCodeArray[], time with this equation. Returns a debug equation index to be
string varsInputAr- used in the other equation debugging functions. TabOrder is the
ray[], string var- tab order of the text item with the equation. See the equation-
sOutputArray[], based blocks for how to use this function.
integer tabOrder)
NOTE: DebugEquationIndex should be set to -1 if EquationDe-
bugDispose() (below) is called for that index OR this function is
called for the first time for this block.
EquationDebug- Disposes and releases the memory used by the hidden block spec- V
Dispose(integer ified by debugEquationIndex used to debug a particular equation.

Functions
debugEquationIn- This does not affect the visible equation block.
dex)
NOTE: The variable used for DebugEquationIndex should be set
to
-1 (minus one) after this function is called so it works correctly if
EquationDebugCompile(), above, is called after this call.
EquationDebugSet- Opens a “Set Breakpoints” window so the user can click to create I
Breakpoints(inte- debugger breakpoints. Returns a True value if an error occurs.
ger
debugEquationIn-
dex)
242 Reference
I/O functions

Equations Description Return


EquationGetStatic Used in an Equation type block to allow static values to be R
(integer index) "remembered" and used in the equation. Need to define:
Real EquationStaticValues[100];
as a static variable at the top of the ModL script for the Equation
block (Value library). A shorter name for this function is EqGet().
The user calls this function with an index from 0 to 99 to get the
correct static value from this array to use in their equation. Used
with EquationSetStatic(), below.
EquationInclude- Called right before one of the equationCompile functions, this V
Set(string theIn- puts the contents of the specified include file into the compiled
cludeName) equation. Call this for each include desired.
EquationSetStatic Used in an Equation type block to allow static values to be V
(integer index, real "remembered" and used in the equation. Need to define:
value)
Real EquationStaticValues[100];
as a static variable at the top of the ModL script for this Equation
block. A shorter name for this function is EqSet().
The user calls this function with an index from 0 to 99 to set the
value in the static array. Then the user can call EquationGet-
Static(index), above, to use that value in their equation.
IncludeFileEdi- Tags the specified include file to do the following: If you click the I
tor(string include- close box, it will not close, but instead will send a message to the
FileName, integer block specified by blockNumber. Equation-based blocks use this
blockNumber) for their external code editor functionality; see the equation
blocks for examples. Returns 0 for success or a negative value to
indicate failure.
ShowFunction- Brings up ExtendSim’s Help with a list of the functions and argu- V
Help(integer alpha) ments available for the equation functions. If alpha is TRUE,
brings up the alphabetical list of functions. If alpha is FALSE,
brings up the “Functions by type” list.
Functions

I/O functions
File I/O, formatted
Use these functions to manipulate formatted text files. Text files produced with the output
functions must be read in an application that reads text files such as a word processing or
spreadsheet program.
In these functions, if the pathname used is the empty string (""), ExtendSim prompts you with
a standard open or save dialog. This allows you to determine the correct file name at the time
of the simulation. File pathnames for specific files are specified as “driveLetter:\direc-
tory\directory\fileName” (Windows) or “volumeName : folder : folder : fileName” (Mac OS)
with each level separated by backslashes or colons, as appropriate. If the volumeName and
folder names are left off of the pathname, the file name will come from the current folder. Note
that names of files can only be 31 characters long (Windows and Mac OS).
ModL Functions 243
I/O functions

The Import and Export functions let you define the column delimiter (separator) character in
the file to be read or written. In ExtendSim, Excel, Word, and most other tabular data applica-
tions, tabs normally delimit columns, and CRLFs (Windows: carriage returns, line feeds) or
CRs (Mac OS: carriage returns) always delimit rows.
The colDelim argument to these functions is a string which specifies the separator character:

"" The empty string (two quotation marks with nothing between them)
indicates a tab character
"," A comma character
"" A space character (multiple spaces are read as one space)
"(any character)" The character specified will be used as a column separator

☞ There are two sets of functions. The Import and Export functions are used with files that have
numerical data; the ImportText and ExportText functions are used with files that have string
data.
The functions are:

File I/O (formatted) Description Return


Export(string path- Writes the contents of a one- or two-dimensional real array or data I
Name, string user- table to the file. Rows and columns specify the portion of the array
Prompt, string to be written and are integers. The function assumes that columns
colDelim, real are delimited by the colDelim string character. Single dimension
array[][], integer arrays must be read as one column by n rows. The function
rows, integer col- returns the number of rows written to the file, or 0 if there is an
umns) error.
ExportText(string Writes the contents of a one- or two-dimensional string array or I
pathName, string text table to the file. Rows and columns specify the portion of the
userPrompt, string array to be written and are integers. The function assumes that
colDelim, string columns are delimited by the colDelim string character. Single
array[][], integer dimension arrays are treated as one column by n rows. The func-
rows, integer col- tion returns the number of rows written to the file or 0 if there is

Functions
umns) an error.
Import(string path- Reads the numerical data from the file into a one- or two-dimen- I
Name, string user- sional real array or data table, then returns the number of rows
Prompt, string read (if an error occurs, it returns 0). The function assumes that
colDelim, real columns are delimited by the colDelim string character. Single
array[][]) dimension arrays are read as one column by n rows. Note that you
should initialize the array before using this function. Otherwise,
any values beyond what was read from the file will have the old
values of the array.
244 Reference
I/O functions

File I/O (formatted) Description Return


ImportText(string Reads the string data from the file into a one- or two-dimensional I
pathName, string string array or text table, then returns the number of rows read (if
userPrompt, string an error occurs, it returns 0). The function assumes that columns
colDelim, string are delimited by the colDelim string character. Single dimension
array[][]) arrays are treated as one column by n rows. Note that you should
initialize the array before using this function to prevent any values
beyond what was read from the file from having the old values of
the array.

File I/O, unformatted


These are lower level file I/O functions. You can have up to 200 text (.txt) or HTML (.htm)
files open for general reading and writing. The files are specified in the functions with the inte-
ger fileNumber that is returned from the FileOpen and FileNew functions. The functions are:

File I/O
Description Return
(unformatted)
Create- Creates a new folder from the pathName. For Windows, the path- I
Folder(string path- Name must use backslashes (\) to separate folder names,
Name) “myDrive:\ExtendSimX\myNewFolder”. For Mac OS, colons (:)
should be used, “myDrive:ExtendSimX:myNewFolder”. (In both
cases “X” is the ExtendSim version.) Returns FALSE if success-
ful, TRUE if there was an error.
DirPathFromPath- Returns the folder pathname part of a complete pathname. Also S
Name(string path- see FileNameFromPathName(), below. For example:
Name) “C:\myfolder\”
FileChoose(string Pops up the standard file selection dialog, with the prompt and the S
defaultFilename, default file name specified, and returns the file name of the file
string Prompt) the user selects. This differs from the fileOpen function, which it
otherwise resembles, in that it just returns the file name/path name
of the selected file without opening it. This allows the developer
to use that name however she chooses.
FileClose(integer Closes the file when you are finished writing or reading data to or V
Functions

fileNumber) from the file. Files must be closed before they can be used as data
in other applications. Call FileClose in the EndSim message han-
dler to close files when the simulation is finished.
FileDelete(string Deletes the file. Use this with caution because deleted files are not V
pathname) recoverable.
FileEnd- TRUE if the end of file has been reached during the most recent I
OfFile(integer file- FileRead.
Number)
FileExists(string Returns TRUE if the file exists I
pathname)
ModL Functions 245
I/O functions

File I/O
Description Return
(unformatted)
FileGetDelimiter Type of delimiter found after the most recent FileRead. Returns I
(integer fileNum- FALSE if a column delimiter (such as a tab character) was found
ber) after the data, or TRUE if a CRLF (Windows) or CR (Mac OS)
row delimiter was found. Call this immediately after FileRead to
find out whether a column delimiter, CRLF, or CR followed the
data.
FileGetPathName Returns the file’s path name. S
(integer fileNum-
ber)
FileInfo(string Returns information about the file specified in the filePathName R
filePathName, inte- argument. The which argument specifies what information will be
ger which) returned:
1: created date
2: modified date
Dates are returned as ExtendSim date values.
FileIsOpen(string Returns TRUE if the file described by the pathName is open. I
pathName)
FileNameFrom- Returns the filename part of a complete pathname.Also see Dir- S
PathName (string PathFromPathName(), above, to get the path name part of a com-
pathName) plete path name.
FileNew(string Opens a new or existing text (.txt) or HTML (.htm) file for writ- I
pathname, string ing and returns a fileNumber. If the pathName is an empty string
userPrompt) (""), ExtendSim prompts for a file name, displaying the user-
Prompt string. If the pathname cannot be found, or the Cancel
button has been clicked, FileNew returns FALSE (0). If the file is
already open, it returns the file’s fileNumber. Note that the File-
New function erases all information from an existing file. To
append data to an existing file, use FileOpen. Call FileNew in the
InitSim message handler to create files at the beginning of a simu-
lation.

Functions
246 Reference
I/O functions

File I/O
Description Return
(unformatted)
FileOpen(string Opens an existing text (.txt) or HTML (.htm) file for reading or I
pathname, string writing, and returns a fileNumber for reference. If the pathname
userPrompt) cannot be found, or the file is unreadable, or the Cancel button has
been clicked, FileOpen returns FALSE. If the file is already open,
it returns the file’s fileNumber. If the file is written to after using
FileOpen, the new data is appended to the end of the file. Call Fil-
eOpen in the InitSim message handler to open files at the begin-
ning of a simulation.
NOTES: If you call this function with the following strings (e.g.
*.TXT) as the pathname, it will change the types of files that the
Standard File Dialog will be looking for:
*.TXT - text files, *.DAT - data files, *.ATF - Proof trace file,
*.LAY - Proof layout file.
Note that if pathname is an empty string (““), the user will be
prompted for a filename at run time.
FileRead(integer Reads and returns a string read from the file, up to colDelim (a S
fileNumber, string column delimiter character) or to a CRLF (Windows) or CR (Mac
colDelim) OS) delimiter. To ignore the column delimiter, set colDelim to an
unused character (i.e. “@”). Reading past the end of file causes an
error message. You should test with FileEndOfFile before calling
FileRead. See FileGetDelimiter(), above.
FileRewind(inte- Resets the file to its beginning so that it can be reread. V
ger fileNumber)
FileWrite(integer Writes the string or value into the file. If a number is used for s, V
fileNumber, string ModL will automatically convert the number to a string. If tabCR
s, string colDelim, is FALSE, a column delimiter character is written to the file after
tabCR) s; if TRUE, a CRLF (Windows) or CR (Mac OS) delimiter is writ-
ten after s. If the column delimiter is a plus sign (“+”), no delim-
iter is written between the strings.
GetDirectoryCon- This function takes two dynamic arrays as arguments, calls Make- I
Functions

tents (string path, Array() for them, and fills them with the names of all the files and
stringArray string- subdirectories in the specified folder. The first array will contain
data, longarray the names of all the files/directories, and the second will contain
longdata) an integer value that will be zero for a file, and one for a folder. It
returns the number of row entries in the array. The pathname sep-
arator on a mac is a ":", on windows a "/".
GetFileReadMa- Returns the type of machine the currently active model was saved I
chineType() on. (This is only useful if models have been moved from one plat-
form to another. Otherwise, it will be the same as the machine the
model is running on.) Type 2 is Windows, 1 is models built on
68k Macs, and 4 is models built on PPC Macs.
ModL Functions 247
I/O functions

File I/O
Description Return
(unformatted)
StripLFs (integer Sets a flag in ExtendSim that determines if the fileread functions V
strip) will strip LF characters. This flag defaults to TRUE, so you
should call StripLFs(FALSE) if you find that meaningful LF char-
acters are missing from your data.
StripPathIfLocal Strips off the pathname if the file is in the same folder as the cur- S
(string pathName) rent model. For example, this can remove non-portable path
names from a filename returned from FileOpen() function. If the
file is in the same folder as the model, no pathname is needed.

Internet access
These functions allow data and file access and manipulation using Internet protocols. The FTP
block (Libraries/Example Libraries/ModL Tips) is an example of the use of these functions in
FTP access.
The connection type handles used in these functions are:

SessionHandle The handle to this entire Internet communication session.


FTPHandle The handle to a specific FTP session. You must use this handle to
access and manipulate files on a Server.
SearchHandle The handle to a specific search operation.
InetHandle Any one of the above handle types.

Internet access Description Return


INetCloseHan- Closes an InetHandle. This function will close a handle created by V
dle(Integer inetH- InetOpenSession(), InetFTPFileFirstFile(), or InetConnect().
andle)
INetConnect(inte- Creates an Internet connection type. The connectionType integer I
ger sessionHandle, can be
string serverName,
Functions
string userName, 1:FTP (The only connectionType that allows you to access or
string passWord, manipulate files.)
integer connection- 2:HTTP (Allows you to open a connection to a website location.
Type) Cannot be used for accessing or manipulating of files.)
3:Secure HTTP
Returns a connection handle that needs to be closed with INet-
Closehandle when the connection is complete.
INetFileImport- Given an INet handle (most likely created by INetOpenURL) this I
Text(integer hFile, function will import data from the file represented by that handle
string format, into the specified array.
stringArray array)
INetFindNext- Continues an Internet file search by moving the searchHandle on I
File(integer search- to the next file. Returns a searchHandle.
Handle)
248 Reference
I/O functions

Internet access Description Return


INetFTPCreateDi- Creates a folder named targetName in the current folder. I
rectory(integer
FTPHandle, string
targetName)
INetFTPDelete- Deletes the path\file targetName if it is found. I
File(integer
FTPHandle, string
targetName)
INetFTPEx- Operates much like the Export function (see page 242) with the I
port(integer exception that it writes to a path\file accessed via FTP.
FTPHandle, string
fileName, string
delim, real
array[][], integer
rows, integer cols)
INetFTPEx- Writes out the contents of a Global Array to the FTP path\file. I
portGA(integer
FTPHandle, string
fileName, string
delim, integer
GAIndex, integer
rows, integer cols)
INetFTPExport- Operates much like the ExportText function (see page 242) with I
Text(integer the exception that it writes to a path\file accessed via FTP.
FTPHandle, string
fileName, string
delim, string
array[][], integer
rows, integer cols)
INetFTPFindFirst- Starts a search for files in the default folder. An empty string will I
File(integer find the first file in the current folder with any filename. Returns a
FTPHandle, string search handle that needs to be closed with INetClosehandle when
searchFile, inte- the search is complete. Currently, flags should be set to zero.
Functions

gerflags)
INetFTPGetCur- Returns the path to the current FTP directory as a string. S
rentDirectory(inte-
ger FTPHandle)
INetFTPGet- Copies a file from the remote site to the local machine. The I
File(integer path\targetname specifies the name of the file to be retrieved. The
FTPHandle, string path\filename specifies the local name where the file should be
targetName, string put. FailIfExists determines what happens if the local file already
fileName, integer exists. Currently, flags and file attributes should be set to zero.
failIfExists, integer
fileAttributes, inte-
ger flags)
ModL Functions 249
I/O functions

Internet access Description Return


INetFTPIm- This operates much like the Import function (see page 242) with I
port(integer the exception that it reads a path\file accessed via FTP.
FTPHandle, string
fileName, string
delim, real
array[][])
INetFTPIm- Reads the contents of an FTP path\file into the Global Array. I
portGA(integer
FTPHandle, string
targetName, integer
format, integer
GAIndex)
INetFTPImport- This operates much like the ImportText function (see page 242) I
Text(integer with the exception that it reads a path\file accessed via FTP.
FTPHandle, string
fileName, string
delim, string
array[][])
INetFTPPut- Copies a local file to the Internet. Path\fileName specifies the I
File(integer name of the local file. Path\targetName specifies the desired name
FTPHandle, string of the file on the Internet. Currently, flags should be set to zero.
fileName, string
targetName, integer
flags)
INetFTPRemove- Deletes the specified directory path\targetName from the site. I
Directory(integer
FTPHandle, string
targetName)
INetFTPRename- Renames the file path\targetName to newName. I
File(integer
FTPHandle, string
targetName, string

Functions
newName)
INetFTPSetCur- Sets the current directory to path\targetName. I
rentDirectory(inte-
ger FTPHandle,
string targetName)
INetGetFindFile- Returns info about the current file in the FTP search. The only I
Info(which) allowed input is connectionType which=1 (FTP); it returns TRUE
if a directory, FALSE if a file.
INetGetFindFile- Returns the name of the current file in the FTP search. S
Name()
INetOpenSession() Starts an Internet session. Returns a session handle that needs to
be closed with INetClosehandle when the session is complete.
250 Reference
I/O functions

Internet access Description Return


INetOpenURL Given a session handle (created by the INetOpenSession function) I
(integer session, and a URL, this function will open a connection to the site corre-
string url) sponding to that URL

Interprocess Communication (IPC)


Interprocess communication (IPC) provides a standard way in which one application can
directly communicate with another. These functions allow ExtendSim to act as a client applica-
tion by connecting to and requesting data and services from a server application. The server
application must support dynamic data exchange (DDE, Windows) or AppleEvents (Mac OS).
The IPC functions start with “IPC”. If you are trying to develop on both Windows and Mac OS
using IPC, see “IPC or multi-server considerations” on page 423.
DDE is no longer supported as of release 10 of ExtendSim. Use OLE/COM instead.
The functions that are no longer available in ES10 are noted below.

IPC & Publish/


Subscribe Description Return

IPCAdvise(integer OBSOLETE AS OF ES10 I


conversation, string
item, integer block- (Windows only) Starts a DDE Advise loop with the application
Number, string dia- that is the other side of the specified conversation. This function
logItem, integer will return an advise loop id, which needs to be used in the IPCS-
rowStart, integer topAdvise Function when the advise loop is to be terminated.
colStart, integer
rowEnd, integer
colEnd)
IPCCheckConver- OBSOLETE AS OF ES10 I
sation(integer con-
versation) Checks the validity of an IPC conversation on Windows. (It
always returns TRUE on the Mac.) A TRUE value is returned if
the conversation is valid.
IPCConnect(string OBSOLETE AS OF ES10 I
serverName, string
Functions

topic) Initiates an IPC conversation between ExtendSim and a server.


The serverName argument is the DDE or AppleEvents name of
the server you are trying to connect to. (This name needs to be in
the format that is appropriate for the platform. For example, Excel
on Windows expects “Excel”, on the Mac OS it expects
“XCEL”.) The topic argument is typically the keyword “SYS-
TEM.” You can also use the name of the document you want to
communicate with, if you want the conversation to target a spe-
cific model. If successfully connected, this function returns an
integer value that is used in the other IPC functions as the conver-
sation identifier. If unsuccessful, it returns a zero. Note: the IPC-
Disconnect function must be used with IPCConnect so that
communication is terminated as soon as it is no longer required.
ModL Functions 251
I/O functions

IPC & Publish/


Description Return
Subscribe
IPCDisconnect OBSOLETE AS OF ES10 I
(integer
Disconnects the specified conversation. This function is neces-
conversation) sary when using IPCConnect, and should be called immediately
when communication is no longer required. Returns a zero if the
disconnection was successful.
IPCExecute(inte- OBSOLETE AS OF ES10 I
ger conversation,
string execute- Sends a command to be executed by the server in the specified
Data, string item) conversation. The executeData argument is the command to be
sent. The item argument is currently not used and should be set to
a blank string (""). This function returns a zero if successful, a -1
for a general error, a -2 for a time-out error, a -3 for an invalid
connection, and a -4 for an event not handled by the server.
IPCGetDocName() Returns a string that contains the name of the last file opened with S
the IPCOpenfile() function. This is mostly used to return the
name of a file that the user selected when an empty string ("") was
passed into the IPCOpenfile function.
IPCLaunch(string Launches the application appName and minimizes it if minimized I
appName, integer is TRUE.
minimized)
IPCOpenFile Opens the file (for example, a spreadsheet) in the Finder using I
(string fileName) DDE (Windows) or AppleEvents (Mac OS). This function is
equivalent to the user double-clicking a file’s icon: it causes both
the file and the file’s application to open. The single argument is a
string which is the file name. Note that this function tells the Sys-
tem to open the file (that is, to launch the named application or
document) and is not at all related to ExtendSim’s FileOpen func-
tion. This function will accept a blank string ("") in the fileName
argument which will cause a File Open dialog to appear. The user
is then prompted to select the file which is to be opened. The
function returns zero if successful.

Functions
IPCPoke(integer OBSOLETE AS OF ES10 I
conversation, string
pokeData, string Sends data to the server in the specified conversation. The poke-
item) Data argument is the data to be sent. The item argument indicates
where the data is to be put. For example, in Excel the item argu-
ment could be “R1C1” indicating that the data is to be sent to the
cell at row 1 column 1. Note that the syntax of the item argument
is dependent on the server. This function returns a zero if success-
ful.
IPCPokeAr- OBSOLETE AS OF ES10 I
ray(integer conver-
sation, string item, (Windows only) Pokes an array of data. The data from the
string delim, string dynamic array data will be poked to the target application. The
array data) return value will be zero for success, and nonzero for failure.
252 Reference
I/O functions

IPC & Publish/


Description Return
Subscribe
IPCRequest(inte- OBSOLETE AS OF ES10 S
ger conversation,
string item) Returns data from the server in the specified conversation. The
item argument indicates where the data is to be taken from. For
example, in Excel the item argument could be “R1C1” indicating
that the data is to be retrieved from the cell at row 1 column 1.
Note that the syntax of the item argument is dependent on the
server.
IPCRequestArray OBSOLETE AS OF ES10 I
(integer conversa-
tion, string item, (Windows only) Requests an array of data. The dynamic array
string delim, string data will be filled with the results from the request. The return
array data) value will be the number of rows of data that were returned.

IPCSendCalcRe- OBSOLETE AS OF ES10 R


ceive(integer prod-
uct, real sendValue, Sends sendValue to the sendRow, sendCol of a spreadsheet file
integer sendRow, that is already open. It then executes the macro called funcName,
integer sendCol, or just recalculates if funcName is an empty string. The function
string funcName, returns the value at receiveRow, receiveCol. Product specifies the
integer receive- spreadsheet you are communicating with: use 1 for Microsoft
Row, integer Excel or 2 for Lotus 123. See also the function IPCSpreadSheet-
receiveCol) Name.

IPCSetTimeOut( OBSOLETE AS OF ES10 V


integer timeOut)
Sets the Timeout value for the various IPC functions. This deter-
mines how long ExtendSim will wait for the other application to
respond to IPC requests. Values are in milliseconds. The default
value is 10000. Putting a –1 into this parameter will request
Async behavior.
IPCServerAsync If async is TRUE, sets a flag in ExtendSim so that ExtendSim will V
(integer async) return from further Execute messages immediately instead of
waiting for the Execute messages to complete. Useful when used
in an Execute message from another application so that the other
Functions

application can continue to do other tasks while ExtendSim calcu-


lates.
IPCSpreadSheet- OBSOLETE AS OF ES10 V
Name(string
spreadSheetName) Used to establish a default spreadSheetName, and is only used in
conjunction with the IPCSendCalcReceive function. The
IPCSendCalcReceive function does not take a spreadsheet name
as an argument, and Lotus 1-2-3 requires a specific spreadsheet
name for DDE communication on Windows.
IPCStopAdvise OBSOLETE AS OF ES10 I
(integer conversa-
tion, integer (Windows only) Stops the specified advise loop within the speci-
adviseLoopID, fied block.
integer block)
ModL Functions 253
I/O functions

IPC & Publish/


Description Return
Subscribe
UpdatePublishers() OBSOLETE AS OF ES10 V
(Mac OS only) Forces an update of publisher information, for all
publishers in the model. Note that this departs from Apple’s stan-
dard interface, where publishers are only updated when the model
is saved.

OLE/COM (Windows only)


These functions apply to the two variations of interface objects that are supported in Extend-
Sim, as described below. They also control or communicate with other applications via OLE
Automation. Both are types of OLE embedded objects, (and/or ActiveX controls,) that can be
inserted into the ExtendSim user interface in different ways. The two variations are:
• Inserting an OLE object at the worksheet level with the Insert Object command in the edit
menu. This command will create a new block-like object that represents an instance of the
embedded object.
• Inserting an object into a new type of dialog item called an embedded object. This gives the
embedded object a dialog variable name that can be used in these functions.

The ModL functions below will allow you to access and communicate with either type of
object. The OLE function calls that contain a blockNumber and dialogItem refer to an embed-
ded object on either the worksheet or in a dialog. In the dialog case, both arguments need to be
used. In the worksheet case, just the blockNumber is sufficient, and the dialogItem should be
an empty string (e.g. ““). OLE functions support SafeArray functionality where appropriate.
When these functions are used for OLE Automation, you need to start with the
OLECreateObject function. This function will create an OLE object of the type you specify,
and return an IDispatch interface on that object. From then on you can use the OLEDispatch
functions described below to call methods, or set and get properties on the objects.
Please note that what these functions return, and what effects they have is largely dependent on
the implementation of the OLE object/ActiveX Control that you are embedding.
☞ There are sample blocks in the ModL Tips library in the OLE category that show the syntax of
Functions
these commands. The blocks are called Excel and Embed, and can be used as OLE scripting
tutorials. Embed is a good tool for looking at the methods and properties of a given embedded
object.

OLE (Windows
Description Return
only)
OLEGetHelpCon- Returns the Help context value of the specified dispID. I
text
(integer blockNum-
ber, string dialog-
Item, integer
dispID)
254 Reference
I/O functions

OLE (Windows
Description Return
only)
OLEActivate(inte- Activates the specified embedded object. DialogItem is the dialog I
ger blockNumber, variable name in quotes. Returns FALSE if successful.
string dialogItem)
OLEAddRef(inte- Addrefs the interface specified. Returns the refcount. I
ger interfacePtr)
OLEArrayParam Puts the data in the array 'data' into a safeArray, packaged as a I
(array data, integer parameter for an Invoke call. The variants argument determines
variants) whether each data element will be packaged in a separate variant
or not.
OLEArrayParam- Specifies that the datatable array passed in will be used as an I
VariableCol- argument for the next OLEInvoke call. The numCols argument
umns(short hNum, will define how many columns the function defines the data as
array datatable- containing.
Name, integer
numCols, integer
variants)
OLEArrayResult Retrieves the SafeArrray result data from an Invoke call, putting I
(array data) the data into the array 'data'.
OLEArrayResult- Specifies that the datatable array passed in will be filled with the I
VariableCol- result of the last OLEInvoke call. The numCols argument will
umns(array define how many columns the function defines the data as con-
datatableName, taining.
integer numCols)
OLECreateObject This function is the starting point for OLE Automation. It will I
(string objectRefer- create an OLE object, or provide an interface to an application if
ence) it is already running, and return an Idispatch interface to that
object that can be used with the OLEDispatch calls listed below to
allow the user to control other applications via OLE Automation.
The object reference string is the registry key associated with the
object you wish to embed. (As an example, Excel would be
excel.application.)
Functions

OLEDB- Passes the contents of the specified DB table as a safe array I


Param(integer parameter.
DBIndex, integer
tableIndex, integer
variants)
OLEDBRe- Fills the specified database table with the results of an Invoke or I
sult(integer DBIn- ParameterGet call that was just made.
dex, integer
tableIndex)
OLEDeactivate Deactivates the specified embedded object. DialogItem is the dia- I
(integer blockNum- log variable name in quotes. Returns FALSE if successful.
ber, string dialog-
Item)
ModL Functions 255
I/O functions

OLE (Windows
only) Description Return

OLEDispatchGet- Returns the CLSID as a string. ProgID is FALSE to return the S


CLSID(integer dis- CLSID, or TRUE to return the program ID.
pHandle, integer
progID)
OLEDispatchGet- Same as the function OLEGetDispatchName below, except it S
DispatchName takes a dispatchHandle instead of a blocknumber and a dialog
(integer dispHan- item name.
dle, integer which)
OLEDispatchGet- Given a function/variable name, returns the DispID. Same as the I
DispID(integer dis- function OLEGetDispID below, except it is expecting a dispatch-
pHandle, string Handle instead of a block number and dialog item name.
theName)
OLEDispatchGet- This function is a Dispatch handle version of the OLEGetDoc() I
Doc (integer IDis- function. For a description of the IDispatchHandle argument, see
patchHandle, string the OLEDispatchGetHelpContext() function.
returnDoc[], inte-
ger dispID, integer
which)
OLEDispatchGet- Same as the function OLEGetFuncIndex, except it takes a dis- I
FuncIndex(integer patchHandle instead of a blocknumber and a dialog item name.
dispHandle, inte-
ger dispID)
OLEDispatchGet- Same as the function OLEGetFuncInfo, except it takes a dispatch- I
FuncInfo(integer Handle instead of a blocknumber and a dialog item name.
dispHandle, inte-
ger funcIndex, inte-
ger which)
OLEDispatch- This uses an Idispatch handle, usually returned by the OLEDis- I
GetHelpContext patchResult, or OLECreateObject functions defined above. This
(integer IDispatch- handle will be the Dispatch interface to an object that is either
Handle, integer associated with an embedded object on the worksheet, or in the
Functions
dispID) block dialog, or has been created via OLE Automation in an
remote application. Many embedded objects are simple objects
that will not have methods that return Idispatch handles on other
objects, but some, like an embedded Excel worksheet, for exam-
ple, contain ‘Subobjects’ that will need to be referenced in this
way. See OLEDispatchResult() and OLECreateObject().
Same as OLEGetHelpContext(), except uses a handle.
OLEDispatchGet- See OLEDispatchGetHelpContext(). Same as OLEGetNames(), I
Names (integer except uses a handle.
IDispatchHandle,
Str31 names[], inte-
ger dispID)
256 Reference
I/O functions

OLE (Windows
Description Return
only)
OLEDispatchIn- See OLEDispatchGetHelpContext(). Same as OLEInvoke(), I
voke (integer Idis- except uses a handle.
patchHandle,
integer dispID)
OLEDispatch- Adds a DispatchHandle to the argument list for the next Invoke I
Param (integer dis- call. Note: arguments are listed in back to front order. Returns
patchHandle) FALSE if successful.
OLEDispatchProp- See OLEDispatchGetHelpContext(). Same as OLEProperty- I
ertyGet (integer Get(), except uses a handle.
IdispatchHandle,
integer dispID)
OLEDispatchProp- See OLEDispatchGetHelpContext(). Same as OLEPropertyPut(), I
ertyPut (integer except uses a handle.
IdispatchHandle,
integer dispID)
OLEDispatchRe- Returns an IdispatchHandle from the last Invoke call. (If a return I
sult() value is available.) This handle can be used in the other OLEDis-
patch calls listed above. This handle will be the Dispatch interface
to an object that is associated with an embedded object on the
worksheet, or in the block dialog. Many embedded objects are
simple objects that will not have methods that return dispatch
handles on other objects, but some, like an embedded Excel work-
sheet, for example, contain ‘Subobjects’ that will need to be refer-
enced in this way.
OLEGAParam Copies the data in the global array defined by arrayindex into a I
(integer arrayIndex, SafeArray, packaged as a paramaeter for an Invoke call. The vari-
integer variants) ants argument determines whether each data element will be
packaged in a separate variant or not.
OLEGAResult Retrieves the SafeArrray result data from an Invoke call, putting
(arrayIndex) the data into the global array referred to be arrayIndex.
Functions

OLEGetCLSID Returns the CLSID as a string. ProgID is false to return the


(integer blockNum- CLSID, or TRUE to return the program ID.
ber, string dialog-
Item, integer
progID)
OLEGetDis- DialogItem is the dialog variable name in quotes. Returns the S
patchName (integer name associated with the specified dispID.
blockNumber,
string dialogItem,
integer dispID)
ModL Functions 257
I/O functions

OLE (Windows
Description Return
only)
OLEGetDispID DialogItem is the dialog variable name in quotes. Returns the Dis- I
(integer blockNum- patch ID for the function/variable theName.
ber, string dialog-
Item, string
theName)
OLEGetDoc (inte- DialogItem is the dialog variable name in quotes. Returns the I
ger blockNumber, internal documentation from the type library in string array
string dialogItem, returnDoc. returnDoc will be resized as needed if the text is larger
string returnDoc[], than a single string. This function accesses text that is in the
integer dispID, objects Type Library. What information is available, and whether
integer which) any is available, is object dependent.
Which takes the following values.
0: name (DispID property/Method name)
1: doc (Any available Documentation on the DispID.)
2: file name (FileName of the help file associated with the
dispID.)
OLEGetFuncIndex Returns the function Index used in OLEGetFuncInfo that corre- I
(integer blockNum- sponds to the dispID.
ber, string dialog-
Item, integer
dispID)
OLEGetFuncInfo DialogItem is the dialog variable name in quotes. Returns func- I
(integer blockNum- tion information for the function specified by index. Implementa-
ber, string dialog- tion of this function is object specific, so your results will vary
Item, integer index, dependent on how the developers of the object have implemented
integer which) it.
if which is 0: INVOKEKIND
returns 1 for INVOKE_FUNC
returns 2 for INVOKE_PROPERTYGET

Functions
returns 4 for INVOKE_PROPERTYPUT
returns 8 for INVOKE_PROPERTYPUTREF
if which is 1: cParams
returns Count of total number of parameters
if which is 2 : cParamsOpt
returns Count of optional parameters
if which is 3 : returns DispID (sometimes called memberID).
Note that index is not the same as the dispID. It is just a sequential
index value from 0 to n-1 where n is the number of functions sup-
ported by the object.
OLEGetGUID() Pops up the standard insert item dialog, and returns the GUID of S
the object you select as a string. The objects that appear on the
standard insert item dialog are just those objects that have been
defined as ‘Insertable’ in the registry, and will not necessarily
include all of the objects that you can use with ExtendSim.
258 Reference
I/O functions

OLE (Windows Description Return


only)
OLEGetInterface DialogItem is the dialog variable name in quotes. Returns a I
(integer blockNum- pointer to an interface on the object. The whichInterface argument
ber, string dialog- currently only supports a zero value for the IDispatchInterface.
Item, integer
whichInterface)
OLEGetNames DialogItem is the dialog variable name in quotes. Puts the name I
(integer blockNum- of the function/variable into the first row of the dynamic array
ber, string dialog- names. The later rows contain the names of any arguments to the
Item, Str31 function. The return value is the number of names returned.
names[], integer
dispID)
OLEGetRefCount Returns the RefCount on the Specified interfacePtr. Note that this
(integer inter- does nothing more than an AddRef and a Release, so there is no
facePtr) reason to call this routine if you are already using addref and
release.
OLEInsertLicense- Same as the OLEInsertObject function, below, with the exception I
dObject (integer of the last argument, which allows you to pass a license string to
blockNumber, the object to be inserted. This is used for activeX objects that
string dialogItem, allow licensed execution as runtimes. See the function OLEReq-
strng guid, integer uestLicKey for additional information.
xPixel, integer
yPixel, string lic-
String)
OLEInsertObject DialogItem is the dialog variable name in quotes. Inserts an object I
(integer blockNum- into the indicated location. If you specify the dialog item, and the
ber, string dialog- block number, it will be inserted into that dialog item, ignoring
Item, string guid, xPos and yPos. If the dialog item name is an empty string, the
integer xPos, inte- object will be inserted onto the active worksheet at pixel location
ger yPos) xPos and yPos. If xPos and yPos are both 1, the item will be
inserted at the "current" position on the worksheet (i.e. the last
mouse click or the last created block position).
OLEInsertObject- This function inserts an Object into an embedded object dialog I
Functions

FromFile(integer item, or onto the worksheet, like OLEInsertObject. It takes the


blockNumber, additional Argument licString, the usage of which is defined in
string dialogItem, OLEInsertLicensedObject. It also takes a filepath Argument,
string guid, integer which allows the coder to define an object based on a file, as is
xPixel, integer done in the standard Object insertion dialog.
yPixel, string lic-
String, string file-
Path)
OLEInvoke(inte- DialogItem is the dialog variable name in quotes. Invokes (calls) I
ger blockNumber, the method/variable specified by dispID. You must call Param
string dialogItem, functions to set up the arguments to the method. Returns a WIN
integer dispID) API error code if it fails, zero if success.
ModL Functions 259
I/O functions

OLE (Windows
only) Description Return

OLELongParam Adds an integer value to the argument list for the next Invoke call. I
(integer value) Note: Arguments are listed in back to front order. Returns FALSE
if successful.
OLELongResult() Returns an integer value from the last Invoke call, if a return I
value is available.
OLEObjectIsReg- Checks to see if a specific CLSID is already registered. Returns
istered(string clsid) TRUE if the CLSID is already in the registry and FALSE if it is
not.
OLEProperty- DialogItem is the dialog variable name in quotes. Gets the prop- I
Get(integer block- erty specified by dispID. You must call Result functions to
Number, string retrieve the value.
dialogItem, integer
dispID)
OLEProperty- DialogItem is the dialog variable name in quotes. Sets the prop- I
Put(integer block- erty specified by dispID. You must call Param functions to set up
Number, string the arguments to the method.
dialogItem, integer
dispID)
OLERealParam Adds a real value to the argument list for the next Invoke call. I
(Real value) Note: Arguments are listed in back to front order. Returns FALSE
if successful.
OLERealResult() Returns a real value from the last Invoke call, if a return value is R
available.
OLERelease(inte- Releases the interface pointer specified. Returns the refCount. I
ger interfacePtr)
OLEReleaseInter- Releases the interface pointer returned by OLEGetInterface. I
face (integer inter- Returns FALSE if successful.
facePtr, integer
whichInterface)

Functions
OLERemoveOb- Removes the OLE object from the dialog item. I
ject(integer block-
Number, string
dialogItem)
OLEReq- This function requests a license key from a licensed activeX con- S
uestLicKey(string trol on your machine. This can be used with OLEInsertLicensed-
guid) Object, above, to allow the user to retrieve the license key to be
used when inserting a licensed runtime activeX Control.
260 Reference
I/O functions

OLE (Windows
Description Return
only)
OLESetNamed- Specifies that the first named parameter is the parameter Para- I
Param (integer par- mID. If the Idispatch interface you are using specifies named
amID) parameters, then they are the first parameters by definition. All
this function does is specify which named parameters you are
using. The first time you call it, it specifies what the paramID of
the first named parameter is, the second time the second, and so
on.
OLEStringParam Adds a string value to the argument list for the next Invoke call. I
(string value) Note: Arguments are listed in back to front order. Returns FALSE
if successful.
OLEStringResult() Returns a string value from the last Invoke call, if a return value is S
available.
OLESupressIn- Used to stop those pesky error messages from appearing during V
vokeErrors(integer an invoke of an OLE object.
supressErrors)
OLEVariant- Adds a variant pointer value to the argument list for the next I
Param(string value) invoke call. Note: Arguments are listed in back to front order.
OLEVari- Returns a string value from the specified variant pointer argument S
antResult(integer of the last Invoke call. Which specifies which of the arguments of
which) the invoke call you are referring to, it would be one for the first
one entered, two for the second, and so on (If the specified argu-
ment was a variant pointer argument.)
WinRegSvr32(inte- This function runs the RegSvr32 command line tool used is used I
ger registerObject, to register .dll files as components in the windows registry. The
string fileName, registerObject integer is a flag that determines if you want to reg-
string dir) ister (true) or unregister (false) the object. FileName is the name
of the dll file. Dir is the path name to the directory containing the
dll.

Mailslot (Windows only)


Functions

Mailslots are a messaging functionality supported by the windows API. They are unidirec-
tional messages that are sent from a given machine to a specified mailslot.
The MailSlotReceive message handler will be called periodically when there is a waiting mes-
sage available in one of the mailslots created by these functions.
☞ Because mailslot technology is a “polling” system, there will be a time delay between when a
message is sent to when a message is actually received.
☞ If you send out a single message to a mailslot, the mailslot may receive multiple copies of that
message depending on your network configuration. This is a expected behavior of the Micro-
soft implementation of mailslots. If you need to uniquely identify messages, the simplest way
would be to concatenate a unique identifier onto the beginning or the ending of the message
and then ignore the duplicates.
See the Windows API documentation for more information about mailslots.
ModL Functions 261
I/O functions

Mailslot (Windows
Description Return
only)
MailSlot- Closes the specifed mailslot. Returns FALSE if successful. I
Close(integer
index)
MailSlotCreate Creates a mailslot with the specified name. Returns the index I
(string theSlot- number of the mailslot, or a zero if the call failed.
Name)
MailSlotRead(inte- Reads the next message from the specified mailslot. This function S
ger index) will return an empty string if there are no messages waiting.
MailSlotSend Sends a message to the specified mailslot(s). TheComputerName I
(string theComput- field specifies exactly which machine to send the message to. If
erName, string this field is a star "*", this message will be broadcast to all
theSlotName, mailslots with the specified mailslot name in the primary domain
string message) of the sending computer. If this field is a domain name, the mes-
sage will be sent to all mailslots with the specified name in that
domain. The SlotName field must contain the name of the speci-
fied mailslot, and cannot be wildcarded. Returns FALSE if suc-
cessful.

ODBC
ODBC stands for Open Database Connectivity. This Microsoft API allows data connectivity
between applications that support it, and databases that support it. The following functions
allow MODL access to the ODBC API. The following diagram shows the basic sequence of
commands that you would use to connect to a database, and retrieve data.

Functions

ODBC sequence of operations

If you are trying to change data in the database, or add data, you could substitute the ODB-
CInsertRows, and/or ODBCSetRows calls for the ODBCExecuteQuery,
262 Reference
I/O functions

ODBCBindColumn, and ODBCFetchRows combination. The information listed here is about


the MODL implementation of functions that allow access to the ODBC API.
To use these functions effectively, you will need documentation on ODBC, SQL, and the data-
base you are targeting as well as this documentation. The Microsoft documentation on ODBC
can easily be found by doing an Exact Phrase search for "ODBC API Reference" on the
MSDN Online Search site.
☞ There is a sample block in the ModL Tips library) in the Input/Output category that shows the
syntax of these commands. The block is called ODBC, and can be used as an ODBC scripting
tutorial, or as a test of the ODBC functionality.

ODBC Description Return


ODBCBindCol- Associates an array with a column in the specific dataset. Which- I
umn (integer state- Col defines which column of the dataset you wish to bind the
ment, integer array data with. The contents of that column will be different
whichCol, string dependent on dataset, and how it was derived. This does not actu-
data[]) ally retrieve the data, just specifies where the data will go when it
is retrieved. Returns FALSE (0) if unsuccessful. (See ODB-
CFetchRows below.)
ODBCColAttri- Returns the value of the specified attribute of the specified col- I
bute (integer state- umn. This function just filters directly through to SQLColAttri-
ment, integer bute, check the ODBC documentation for additional information.
column, integer This function can be called as soon as there is a defined dataset.
which)
ODBCColumns Executes a standard query that returns a dataset containing the I
(integer connec- names of all the valid columns in the data source. Returns a State-
tion) ment Handle. (Note: it is important to free all statements before
disconnecting the connection, otherwise, the disconnection may
fail.) Returns FALSE (0) if the query fails. See your ODBC docu-
mentation (SQLColumns) for a list of the meanings of the col-
umns of the resulting dataset.
ODBCCol- This function works the same as the ODBCColumns function I
umns2(integer except that it adds four string arguments. See your ODBC docu-
hdbc, string cata- mentation (SQLColumns) for additional information about the
Functions

log, string schema, meaning and use of these arguments. Please note that the argu-
string table, string ments are strings, so you cannot pass in the NULL values that are
column) defined in the SQLColumns specification. For this function,
we've defined an empty string "" to be interpreted as a NULL, so
just use empty strings for unused arguments where NULL is nor-
mally used.
ODBCConfigData- Calls the Windows API SQLConfigDataSource() function with
Source(integer fRe- the entered arguments
quest, string
szDriver, string
szAttributes)
ModL Functions 263
I/O functions

ODBC Description Return


ODBCConnect Connects to an ODBC source. Returns a connection Handle. I
(string szDB- (Note: It is very important to disconnect this connection before
Name, string szUs- quitting ExtendSim, otherwise a crash may result.) Returns
erName, string FALSE (0) if the connection fails. You need to have created a
szPassword) valid ODBC Data Source to connect with before using this call.
ODBCConnect- Returns the string name of the current connection. S
Name ()
ODBCCountRows Uses the SQL COUNT statement to return the number of rows in I
(integer connec- the specified column of the specified table. The statement exe-
tion, string table- cuted will be SELECT COUNT (ColumnName) FROM "table-
Name, string Name" WHERE whichCondition. ColumnName will default to
columnName, ‘*’ if it is blank. WhichCondition will specify a selection condi-
string whichCondi- tion, if it is blank, all rows will be counted. See your SQL docu-
tion) mentation for additional information about this query.
ODBCCreateTable This function will create a table in the specified database with col- I
(Integer connec- umns named as the values in the columnnames array, and types as
tion, string table- specified in the columntypes array. Returns FALSE (0) if unsuc-
Name, stringarray cessful.
columnNames,
string column-
Types[])
ODBCDriverCon- Connects to an ODBC source, putting up a system source selec- I
nect(string szCon- tion dialog. Returns a connection Handle. (Note: it is important to
nectString) disconnect this connection before quitting ExtendSim, otherwise
a crash may result.) Returns FALSE (0) if the connection fails.
You need to have created a valid ODBC Data Source to connect
with before using this call.
ODBCDisconnect Disconnects the specified connection. Returns FALSE (0) if I
(integer connec- unsuccessful.
tion)
ODBCExecuteAr- See the description for ODBCExecuteQuery() below. This func- I
ray(integer hdbc, tion allows a query that contains more than 255 characters by
Functions
string array[]) allowing you to pass in an array of strings instead of just one
string.
ODBCExecute- Executes the specified SQL query string. Returns a Statement I
Query (integer con- Handle. (Note: it is very important to free all statements before
nection, string disconnecting the connection, otherwise the disconnection may
theQuery) fail.) Returns FALSE (0) if the query fails.
ODBCFetchRows Fetches the data from the dataset, and stores it in the variables that I
(integer statement) have been bound by ODBCBindColumn. Returns the number of
rows. (See ODBCBindColumn above.)
ODBCFreeState- Frees the specified Statement Handle. Returns FALSE if success- I
ment (integer state- ful.
ment)
264 Reference
I/O functions

ODBC Description Return


ODBCInsertRow This Function add a row of data with the specified values to the I
(Integer connec- indicated table. Returns FALSE (0) if unsuccessful.
tion, string table-
Name, string
columnNames[],
string values[])
ODBCKey- Returns a TRUE value if the string word is an ODBC reserved I
word(string word) keyword. Otherwise returns a FALSE value.
ODBCNumResult- Returns the number of resulting columns in the specified dataset. I
Cols (integer state- This function will only return useful information after an ODB-
ment) CExecuteQuery, ODBCTables, or ODBCColumns call has estab-
lished a dataset.
ODBCSetRows Copies the data from the data array into the columnName array, I
(integer connec- using the IDArray values to determine which cell each item goes
tion, string table- into. That is, the variable named in the IDName field will be com-
Name, string pared to the values in the IDArray array, and each row of the
columnName, columnName variable will be updated based on the database row
string IDName, selected by the values in the IDArray array. Returns FALSE (0) if
string dataArray[], unsuccessful.
string IDArray[])
ODBCSetRows- See the description for the ODBCSetRows function. Whereas the I
Type(linteger hdbc, SetRows function defaults the types of the values of both string
string tableName, arrays to SQL_CHAR, the SetRowsType function allows you to
string colName, specify the types of the variables in the y and x arrays. Type val-
string IDName, ues are:
string y[], string
x[], SQL_UNKNOWN_TYPE 0, SQL_CHAR 1, SQL_NUMERIC 2,
SQL_DECIMAL 3, SQL_INTEGER 4, SQL_SMALLINT 5,
integer varTypeX, SQL_FLOAT 6, SQL_REAL 7, SQL_DOUBLE 8, SQL_DATE-
integer varTypeY) TIME 9, SQL_VARCHAR 12, SQL_TYPE_DATE 91, SQL_-
TYPE_TIME 92, SQL_TYPE_TIMESTAMP 93
ODBCSuccessInfo Sets a flag that determines if warning error messages are shown, V
(integer ShowSuc- or not.
Functions

cessInfo)
ODBCTables (inte- Executes a standard query that returns a dataset containing the I
ger connection) names of all the valid tables in the data source. Returns a State-
ment Handle. (Note: it is very important to free all statements
before disconnecting the connection, otherwise the disconnection
may fail.) Returns FALSE (0) if the query is unsuccessful. See
your ODBC documentation (SQLTables) for a list of the mean-
ings of the columns of the resulting dataset.

Serial I/O
These functions allow ExtendSim to interact with serial ports. You can, for example, set up a
simulation that will cause a modem attached to a computer to dial up a remote database, collect
data, run a simulation, and send the results to another location over the modem. Likewise, an
ExtendSim simulation can be controlled by a modem from a remote location.
ModL Functions 265
I/O functions

• Windows: The port arguments are from 1 through 4 for COM1 through COM4, respectively.
• Mac OS: The port arguments are 0 for serial port A (modem port) or 1 for port B (printer
port).

☞ If you use serial functions in your ModL code, and there is any possibility that your blocks will
be used cross-platform (e.g. on both Windows and Mac OS systems), your code should include
checks to allow for the differences between platforms. For more information, see “Cross-Plat-
form Considerations” on page 419.
The SerialRead and SerialWrite functions are asynchronous, meaning that they return immedi-
ately without waiting for a response from the modem. SerialRead reads from the input buffer,
not from the modem, and SerialWrite writes to the output buffer.

Serial I/O Description Return


SerialRead(integer Returns a string if there is any read data, or an empty string if data S
port) is not available. If there are more than 255 characters in the serial
port buffer, it returns the first 255 characters. Successive Serial-
Read calls will return the rest of the characters in the buffer.
SerialReset(integer Sets up one of the serial ports for communications. baud can be V
port, integer baud, 300, 600, 1200, 2400, 4800, 9600, 19200, or 57600; stop can be 1,
real stop, integer 1.5, or 2; parity is 0 for no parity, 1 for odd parity, or 2 for even
parity, integer data, parity; data can be 5, 6, 7, or 8 data bits. Set xonXoff to TRUE for
integer xonXoff) XON/XOFF handshaking or FALSE for CTS handshaking.
SerialWrite(integer Writes the string s to the serial port buffer. V
port, string s)

DLLs and Shared Libraries


ExtendSim can interact with DLLs (Windows only) and Shared Libraries (Macintosh only)
through the following functions.
Working with DLLs and Shared Libraries
Working with DLLs and Shared Libraries will be a lot easier if you make note of the following:
• DLLs or Shared Libraries called by ExtendSim must be built for 64-bit execution.

Functions
• Variables passed from the ModL code to a DLL/Shared Library are passed by value unless
the variables are strings or arrays, in which case they are passed as pointers. Pointertype (64
bit) variables can also be passed as arguments. Strings are passed to DLLs/Shared Libraries
from ModL as Pascal strings, not C strings. See “DLLs” on page 86, for more information.
• If you use DLL functions in your ModL code, and it is possible that your blocks will be used
cross-platform (for example, on both Windows and Mac OS systems), your code should
include checks to allow for the differences between platforms. For more information, see
“Extensions” on page 423.
• The DLLs and Shared Libraries are stored in the ExtendSim/Extensions/DLLs folder.
☞ See “DLLs” on page 86 for more information about using DLLs. At some point the Extend-
Sim/Examples/How To/Developer Tips/DLLs folder will have some DLL examples.
266 Reference
I/O functions

About the functions


These function calls are called with variable argument lists. The first argument in each case is
the Proc-Address for the procedure, which is a 4-byte integer (not a 64-bit Pointertype). This is
returned by the function DLLMakeProcInstance. It is recommended that you call DLLMake-
ProcInstance once (in On OpenModel or in On InitSim), and save the return value in a vari-
able, rather than call it each time you call the specific function.
It is critical that you match the argument list and the calling convention in the ModL code with
the argument list and calling convention in the DLL/Shared Library, otherwise a crash could
result.
ProcAddress is not a 64-bit Pointertype variable. Instead, it is a 4-byte integer index that
points to a pointer internal to ExtendSim. This makes the 32 bit block code used in previous
releases compatible with the 64 bit code of ExtendSim 10.
All of the DLL calls below are translated into 64-bit fastcalls, which is the only call allowed in
64-bit systems.

DLL/Shared
Description Return
Libraries
DLLBoolCFunc- Calls a DLL routine referenced by procAddress and returns a I
tion(integer pro- Boolean (translated into an integer by ExtendSim). Accepts a
cAddress, .....) variable argument list. Assumes a C calling convention.
DLLBoolPascal- Calls a DLL routine referenced by procAddress and returns a I
Function(integer Boolean (translated into an integer by ExtendSim). Accepts a
procAddress, .....) variable argument list. Assumes a Pascal calling convention.
DLLBoolStdcall- Calls a DLL routine referenced by procAddress and returns a I
Function(integer Boolean (translated into an integer by ExtendSim). This function
procAddress, ...) is the same as the other DLL functions except it assumes a Std-
Call calling convention.
DLLCtoPString Converts a C string to a V string that is usable by ModL, as V
(string theString) ExtendSim/ModL internally can use only V (Pascal) strings. In
some cases pre-established DLLs will expect and return C format
strings in the passed parameter string pointer, and this function
can convert the string type safely within the pointer space. See
Functions

DLLPtoCString below to convert back to C strings.


DLLDoubleCFunc- Calls a DLL routine referenced by procAddress and returns a real. R
tion(integer pro- Accepts a variable argument list. Assumes a C calling convention.
cAddress, .....)
DLLDoublePascal- Calls a DLL routine referenced by procAddress and returns a real. R
Function(integer Accepts a variable argument list. Assumes a Pascal calling con-
procAddress, .....) vention.
DLLDoubleStd- Calls a DLL routine referenced by procAddress and returns a real. R
callFunction(inte- This function assumes a StdCall calling convention.
ger procAddress,
...)
ModL Functions 267
I/O functions

DLL/Shared
Description Return
Libraries
DLLLoadLibrary Loads the specified library. This is for people who need to access I
(string pathName) routines in a DLL that is not present in the Extensions folder.
After loading the library, attempts to access DLL routines that are
in that library should succeed. See also DLLUnloadLibrary.
DLLLongCFunc- Calls a DLL routine referenced by procAddress. Returns a 64 bit I
tion(integer pro- integer that can be saved as a ModL integer (32 bit) or, if needed,
cAddress, .....) as a pointertype (64 bit integer/pointer). Accepts a variable argu-
ment list. Assumes a C calling convention.
DLLLongPascal- Calls a DLL routine referenced by procAddress. Returns a 64 bit I
Function(integer integer that can be saved as a ModL integer (32 bit) or, if needed,
procAddress, .....) as a pointertype (64 bit integer/pointer). Accepts a variable argu-
ment list. Assumes a Pascal calling convention.
DLLPtoCString Converts a V string to a C string that is usable by a DLL, as V
(string theString) ExtendSim/ModL internally can use only V (Pascal) strings. In
some cases pre-established DLLs will expect and return C format
strings in the passed parameter string pointer, and this function
can convert the string type safely within the pointer space. See
DLLCtoPString above to convert back to V strings.
DLLLongStdCall- Calls a DLL routine referenced by procAddress. Returns a 64 bit I
Function (integer integer that can be saved as a ModL integer (32 bit) or, if needed,
procAddress, ...) as a pointertype (64 bit integer/pointer). This function assumes a
StdCall calling convention.
DLLMakeProcIn- Returns the ProcAddress expected by the other calls as an argu- I
stance (string proc- ment. Requires a procedure name. This function will search all
Name) open libraries for the named procedure, so it is advisable to call it
once, and save the returned value. Function will return a zero if
procName was not found.
DLLMakeProcIn- Similar to DLLMakeProcInstance except it has a libraryName I
stanceLibrary argument so you can specify which library should be opened and
(string searched for the procedure.
libraryName, string
Functions
procName)
DLLUnloadLi- Unloads the DLL from memory. See also DLLLoadLibrary. I
brary (string name)
DLLVoidCFunc- Calls a DLL routine referenced by procAddress and returns noth- V
tion(integer pro- ing. Accepts a variable argument list. Assumes a Pascal calling
cAddress, .....) convention.
DLLVoidPascal- Calls a DLL routine referenced by procAddress and returns noth- V
Function (integer ing. Accepts a variable argument list. Assumes a Pascal calling
procAddress, .....) convention.
DLLVoidStdcall- Calls a DLL routine referenced by procAddress and returns noth- V
Function (integer ing. This function assumes a StdCall calling convention.
procAddress, ...)
268 Reference
I/O functions

Alerts and prompts


These functions can be used to display results and diagnostics as well as to prompt for input
data.

Alerts & Prompts Description Return


Beep() Causes the computer to beep using the beep sound selected in the V
Control Panel.
IntegerParameter Similar to NumericParameter, except it returns an integer value I
(label, default) and displays the parameter to the user as an integer.
IntegerParameter2 Similar to NumericParameter2, except it returns integer values I
(label1, default1, and displays the parameters to the user as integers.
label2, default2,
resultArray)
NumericParame- Similar to the userParameter function, except that this returns a R
ter(string message, real value. This function will return a NOVALUE if the user
real default) clicks on the cancel button. See also NumericParameter.
NumericParame- Similar to the numericParameter function, except that this func- R
ter2 (string mes- tion returns two values in a real array declared as real array[2];
sage1, real default,
strng message2, The return value of the function itself will be a zero if the user
real default2, real successfully input one or more numbers, or a –1 if they canceled.
array[]) See also NumericParameter2.

PlaySound(string Plays the sound named in the argument. Returns FALSE if no I


soundName) error, TRUE if the sound is not found. See “Sounds” on page 89
for important details.
Speak(string s) (Mac OS only) Speaks the string if the speech manager is present. V
UserError(string s) Opens a dialog with an OK button displaying the string s. V
UserParameter( Opens a dialog to get a value. Displays the prompt string and S
string prompt, default string, then returns either the entry typed, or the default
string default) string if there was no user entry, or the empty string (““) if Cancel
was clicked. After getting a string with UserParameter, you can
Functions

convert the string to a real with the StrToReal function described


later in the section on strings.
UserPrompt(string Opens a dialog with an OK and a CANCEL button displaying the I
s) string s. The function returns TRUE if the OK button is clicked
and FALSE if the Cancel button is clicked.
userPromptCus- User prompt with the ability to customize the text of the buttons. I
tomButtons(string Returns a 1 (one) if the first button is clicked or 2 (two) if the sec-
str, string button1, ond button is clicked.
string button2)

Because of the automatic type conversion provided in ModL, and because they provide an easy
way to display the contents of variables, these functions are also useful for debugging block
code. For example:
ModL Functions 269
I/O functions

UserError("X = "+x+", Y = "+y);

will display a dialog with something like:


X = 5.23, Y = .007

This is also an example of using the + operator for concatenating strings.


Also see other useful functions in “Debugging” on page 402.
User inputs
Use these functions to determine the location of mouse clicks and the status of modifier keys
during the on blockClick and on dialogClick message handlers.

User inputs Description Return


GetModifierKey Returns a 1 if the key is depressed, a 0 if the key is not depressed. I
(integer whichKey) Can be used in the on blockClick and on dialogClick message
handlers.
whichKey 1 = Shift key
whichKey 2 = Option (Mac OS) or Alt (Windows) key
GetMouseX() Returns the mouse X position in pixels relative to the model I
worksheet. Use the GetBlockTypePosition() function to get the
coordinates of the block. Can be used in the on blockClick mes-
sage handler.
GetMouseXActive- Returns the mouse X position in pixels relative to the active win- I
Window() dow, for example, a hierarchical submodel window. Use the Get-
BlockTypePosition() function to get the coordinates of a block in
that window. Can be used in the on blockClick message handler.
GetMouseY() Returns the mouse Y position in pixels relative to the model I
worksheet. Use the GetBlockTypePosition() function to get the
coordinates of the block. Can be used in the on BlockClick mes-
sage handler.
GetMouseYActive- Returns the mouse Y position in pixels relative to the active win- I

Functions
Window() dow, for example, a hierarchical submodel window. Use the Get-
BlockTypePosition() function to get the coordinates of a block in
that window. Can be used in the on blockClick message handler.
HBlockClicked() This function returns the block number of the Hblock that was last V
double clicked. This is intended to be called during a On Hblock-
Open message handler, and will always return a negative one at
other times.
isKeyDown(inte- Returns a True/False value for whether or not the specified key is I
ger keyCode) pressed. The constants for keyCode are the constants for the API
call GetKeyState (Windows) or the GetKeys functionality (Mac-
intosh).
270 Reference
Animation

User inputs Description Return


Lastkeypressed() The value returned will be the ASCII value of the character I
entered for keys that have ASCII equivalents. For keys that don’t
have ASCII equivalents, the value returned is the keycode. This is
useful for monitoring what keys the user hits on the keyboard.
Used in conjunction with startTimer (See “Timer functions” on
page 400) or during a simulation, it will allow live keyboard
input.
WhichDialogItem- Used in the dialogClick message handler to find the name of the S
Clicked() item that received the click. This is used, for example, to modify
the items in a popup menu at the time it is clicked on but before it
opens to the user.
WhichDTCell- Returns the row or column of the cell in the data table that was I
Clicked(integer clicked on. This function should only be used in the on dialog-
rowCol) Click message handler, and usually after the whichDialogItemC-
licked function has determined that a specific data table was
clicked on.
rowCol 0 = row
rowCol 1 = col

Animation
2D Animation
Use these functions to implement the ExtendSim 2D animation. Examples of using these func-
tions are shown in “2D animation” on page 126.
The Show 2D Animation command (Run menu) only controls whether animation is shown
during the simulation run. At all other times, the block will still show animation if the block
creator has coded it to do that. For instance, animation is available when the modeler makes
any changes in a block's dialog, whether Show 2D Animation is selected or not and regardless
of whether the simulation is running. When the command Show 2D Animation is selected, ani-
mation is available at all times.
In the functions:
Functions

• “obj” is the integer object number of the animation object on the icon.
• As discussed in “Animating hierarchical blocks” on page 129, hierarchical blocks are ani-
mated indirectly (by blocks in the submodel) by referencing the negative of the hierarchical
block’s object number. If a negative number is used and ExtendSim doesn’t find that object
in the current enclosing H-block, ExtendSim will search the H-block enclosing that one and
so on, until it finds the object or reaches the top level.
• The outsideIcon value is a value that is set to FALSE unless you want to move or stretch out-
side the original size of the icon (setting this to TRUE slows down the animation). All mea-
surements are in pixels.
• Some functions have the option of selecting a pattern in addition to a color. Starting with
ExtendSim 10, patterns remain as arguments for those functions but are no longer supported.
ModL Functions 271
Animation

• AnimationEColor specifies the color of animated objects. See the “Select Color window” on
page 401.
There is a limit of 256 animation objects that can be manually placed on a block’s icon when
the block is created. However, the AnimationObjectCreate function supports thousands of ani-
mation objects. This function can be used to create new animation objects during the run; use
AnimationObjectDelete() to delete the objects during the run.

Animation Description Return


AnimationAntial- Determines whether or not the specified animation object uses V
ias (integer obj- anti-aliasing when it draws. Defaults to on (True) for most anima-
Num, integer tion object types.
antialias) Call this function with a false (0) if you don't want the specified
animation object to be drawn with anti-aliasing.
AnimationBlock- This function moves an animation object across the connection V
ToBlock (integer lines from one block to another. You specify the sending block
animationObj- and connector, and the receiving block and connector, as well as
Num, integer the number of the animation object. The speed value is a relative
blockNumFrom, speed factor. Use a value of 1.0 for normal speed.
integer conNum-
From, integer
blockNumTo, inte-
ger conNumTo,
real speed)
AnimationBorder Changes the border size of an animation object. Pixels can be 0, V
(integer obj, integer for no border, and up to 20 for a 20 pixel border.
pixels)
AnimationBorder- Allows you to specify the color of the border on an animation V
Color (integer obj- object. Only effects objects that have a visible border around
Num, integer hue, them.
integer saturation,
integer value) As of ExtendSim 10, see instead AnimationBorderEColor

AnimationBor- Allows you to specify the EColor of the border on an animation V


derEColor (integer object. Only effects objects that have a visible border around

Functions
objectNum, inte- them. See “EColors” on page 401 for more information.
ger EColorValue
AnimationColor Sets the color of the object using the pattern number, hue, satura- V
(integer obj, integer tion, and brightness.
hue, integer sat,
integer bright, inte- Patterns are not supported as of release 10, so use 1 for a solid
ger pattern) pattern. Also, for ExtendSim 10 or later, use the AnimationE-
Color function instead.
AnimationEColor Set the color of an animation object using an EColor value. See V
(long objNum, long “EColors” on page 401 for more information.
EColorValue)
272 Reference
Animation

Animation Description Return


AnimationGetH- Returns the offset of the height of the object. If originalValue is I
eight (integer obj, true, gets the original height.
integer original-
Value) See also AnimationGetHeightR, below.

AnimationGetH- The same as the animationGetHeight function above, except it R


eightR (integer obj, returns a real number for the height instead of an integer.
integer getOrig)
AnimationGetLeft Returns the offset of the left side of the object relative to its origi- I
(integer obj) nal position in the icon.
AnimationGetLef- Gets the left of the animation object relative to the upper left hand I
tRelative (integer corner of the block icon. See AnimationGetTopRelative and Ani-
blockNumber, inte- mationGetTopRelativeR for more info.
ger objNum, inte-
ger original)
AnimationGetLef- Exactly the same as AnimationGetLeftRelative except this func- R
tRelativeR (integer tion returns a real for the left number.
blockNumber, inte-
ger objNum, inte-
ger original)
AnimationGet- Returns the speed setting, with 1 being slowest and 5 being fast- I
Speed() est. See AnimationSetSpeed(), below.
AnimationGetTop Returns the offset of the top side of the object relative to its origi- I
(integer obj) nal position in the icon.
AnimationGetTo- Gets the top of the animation object relative to the upper left hand I
pRelative(integer corner of the block icon. Compare to AnimationGetTop, which
blockNumber, inte- returns the location relative to just the Animation Object location,
ger objNum, inte- and will always return zero unless the animation object has been
ger original) moved with an AnimationMove call. Original specifies if the
moved rect (0), or the original unmoved rect (1) should be used.
AnimationGetTo- Exactly the same as AnimationGetTopRelative except this func- R
Functions

pRelativeR(integer tion returns a real for the top.


blockNumber, inte-
ger objNum, inte-
ger original)
Animation- Returns the width of the object. If getOrig is true, gets the original I
GetWidth(integer width before any stretching.
obj, integer get-
Orig) See also AnimationGetWidthR, below.

AnimationGetWid- Same as AnimationGetWidth, above, except it returns a real num- R


thR(integer obj, ber for the width instead of an integer.
integer getOrig)
AnimationHide Immediately hides the object. V
(integer obj, integer
outsideIcon) NOTE: as of ExtendSim 10, the outsideIcon argument is unused.
ModL Functions 273
Animation

Animation Description Return


AnimationLevel Defines the object as a level whose height varies from 0.0 to 1.0 V
(integer obj, real (based on the level argument).
level)
AnimationMoveTo Moves the object relative to its original position in the icon. Note: V
(integer obj, integer pixel coordinates start at the top/left corner of the animation
leftOffset, integer object and go down and to the right. TopOffset of 0 is the top of
TopOffset, integer the animation object.
outsideIcon)
AnimationMovie (Mac OS only) Defines the object as a QuickTime movie, played V
integer obj, string at the specified speed (relative to 1.0, the normal speed). If play-
movieName, real SoundTrack is true, the soundtrack is played. If async is true, the
speed, integer play- movie starts and the function returns immediately; if it is false,
SoundTrack, inte- the function will not return until the movie is finished. The movie
ger async) must be a file in the ExtendSim\Extensions folder. Unlike other
resources, the “movieName” is its file name, not a resource name.
AnimationMovieF- (Mac OS only) Returns TRUE if the QuickTime movie is finished I
inish(integer obj) or not currently playing; returns FALSE if the movie is still play-
ing. This is useful if you want to wait for a QuickTime movie to
finish playing before you restart it. If you call AnimationMovie
with async TRUE, use this function to check the status of the
movie at any time.
AnimationObject- This function copies the animation object data, (like type of I
CopyData(integer object, poly points, color, size, etc.) from one object to another
objNum, integer one.
objNum2)
AnimationObject- Creates an animation object on the fly. The animation object I
Create(integer number for the created object will be returned. If the enclosingH-
enclosingHblockIf- blockIfTRUE argument is set to one, or TRUE, the function will
TRUE) create the animation object in the enclosing Hblock of the current
block. In this case, the returned value will be the negative value
of the animation object number. Animation objects create on the
fly with this function are not part of the block structure, and will

Functions
need to be recreated in openModel, or InitSim, or whenever they
are used. They will persist until the model window (Including
Hblock model windows,) is closed, or AnimationObjectDelete is
called.
AnimationObject- This function will delete an animation object. This will not affect I
Delete(integer obj- animation objects that are defined in the block structure, just
Num) those created on the fly with AnimationObjectCreate. Use nega-
tive objNum if in enclosing Hblock.
AnimationObject- Returns TRUE if an animation object with the specified objNum I
Exists(integer obj- exists, and FALSE if it doesn’t. For example, you could test if the
Num) enclosing hierarchical block has a specified animation object.
(i.e. if animationObjectExists(-3) returns a TRUE value, then
there is an animation object in the enclosing Hblock, or any num-
ber of levels above, with the objNum 3.)
274 Reference
Animation

Animation Description Return


AnimationObject- Similar to the AnimationObjectExists function, except that this I
Exists2(integer function includes a block number argument, allowing you to
blockNumber, inte- check for the existence of an animation object in a remote block.
ger objNum)
AnimationOval Defines the object as an oval. V
(integer obj)
AnimationPicture Defines the object as a picture. If TRUE, the scaleToObj argu- V
(integer obj, string ment scales the picture to the animation object size; if FALSE, the
picName, integer picture will not be scaled. See “Picture and movie files” on
scaleToObj) page 89 for important information about pictures.
AnimationPixel- Defines the object as a rectangular pixel map of rows height and V
Rect(integer obj, cols width, where each pixel can have a specified color. Extend-
integer rows, inte- Sim normalizes the size of the pixels to conform to the animation
ger cols, integer object size. IntArray is declared as a dynamic array:
intArray[]) integer intArray[];
AnimationPixel- Initializes or sets the color value of all the pixels in an Animation V
RectEColor- Pixel Rectangle to the specified color. (This is quicker then loop-
Init(integer ing through each pixel.)
objNum, integer
EColorValue)
AnimationPixelSet See AnimationPixelRect, above. Sets a specific pixel to an HSV V
(integer objNum, color (see notes on color, above). Row values start from 0 to rows-
integer row, inte- 1. Col values start from 0 to cols-1.
ger col, integer h,
integer s, integer v, Note: As of ExtendSim 10, see instead AnimationPixelRectECol-
integer drawNow) orInit

AnimationPixelSe- Same as AnimationPixelSet, above, except it takes an EColor V


tEColor (integer value for the color instead of H/S/V values.
objNum, integer
row, integer col,
integer EColor,
integer drawNow)
Functions

Animation- Animates a polygon. PointCount is the number of points to be V


Poly(integer obj- drawn, point array is a two dimensional array of points that con-
Num, integer tains the points to be animated. The points are defined in pixels
pointCount, inte- from the upper left hand corner of the animation object location.
ger pointArray[])
AnimationRectan- Defines the object as a rectangle. V
gle(integer obj)
AnimationRn- Defines the object as a rounded rectangle. V
dRectangle(integer
obj)
ModL Functions 275
Animation

Animation Description Return


AnimationSetDe- If trueIsDelay is TRUE (default), then ExtendSim uses its normal V
layMode(integer delay, corresponding to the animation speed that the user chose.
trueIsDelay) FALSE removes any animation delay, no matter what speed the
user chooses. Use this function to set your own delay for anima-
tion and have ExtendSim ignore the animation speed set by the
user. See AnimationGetSpeed(), above, to see what speed the user
chose.
AnimationSet- Sets the animation speed, with 1 being slowest and 5 being fast- V
Speed(integer new- est. See AnimationGetSpeed(), above.
Speed)
AnimationShow Shows a hidden object. V
(integer obj)
Animation- Stretches the object relative to its original position in the icon. V
StretchTo(integer
obj, integer leftOff-
set, integer topOff-
set, integer width,
integer height, inte-
ger outsideIcon)
AnimationText Defines the object as text with the string msg. Also see the V
(integer obj, string TextWidth function in Strings, below, that is useful in applying
msg) the AnimationStretchTo function to the object so that the text
width is accommodated.
AnimationTex- This function specifies the text alignment for the specified anima- V
tAlign (integer obj- tion object. Justification takes the following values:
Num, integer
justification) Left: 0
Right: -1
Center: 1
AnimationText- Allows you to modify the size of animation text. The size argu- V
Size(integer obj- ment is a font point size.
Num, integer size)
AnimationText- Exactly the same as the animationText function, except the back- V Functions
Transparent(inte- ground behind the text will be transparent. It’s normally white for
ger objNum, string the regular function.
text)
AnimationZOrder- Gets the zOrder value of the specified animation object. R
Get(integer obj-
Num) Note: zOrders for animation objects only control the zOrder
relative to the other animation objects from the block that
controls the animation. Animation objects are children of the
block that they are associated with, and are all ordered rela-
tive to that block's zOrder.
AnimationZOrder- Sets the zOrder value of the specified animation object. See note V
Set(integer obj- about zOrders above.
Num, real zOrder)
276 Reference
Animation

Animation Description Return


DialogPicture This function displays the picture pictureName over the static text I
(string variable- item variableName. This is used to display a picture on a dialog
Name, string pic- box. Normally you would create an empty static text item, and use
tureName, integer that as the location for displaying this picture. ScalePicture will
scalePicture) take a TRUE or FALSE, and determines if the picture is scaled to
the space, or not. Returns FALSE if that picture is not available.
PictureList Resizes, and fills the dynamic array arrayname with the names of I
(String15 array- the pictures from the extension folder or the application to be used
Name[], integer with the AnimationBlockToBlock() function. Return value is the
type) number of pictures.
type:
0 - All pictures in the Extensions folder.
1 - Only AnimationBlockToBlock pictures in the application.
2 - Only AnimationBlockToBlock pictures in the Extensions
folder. Pictures with names that start with a “@” character are not
AnimationBlockToBlock pictures and are not returned. The @
character prevents pictures from showing up in the block’s anima-
tion tab popup menu.
3 - All non-AnimationBlockToBlock pictures (pictures that start
with an @ character.
ProofEncode The version of the Proof Animation DLL that works with Extend- I
(string command- Sim requires a numeric value calculated by this function to be
Line) passed to it periodically. See the Proof Animation blocks in the
Animation 2D-3D library to see how to use this function.
ProofEncodeRe- Resets counters for Proof copy protection. V
set()

3D Animation
For the 3D functions, all distances are in meters, speeds are in meters per second, and time
units are in real time seconds, which correspond to a single simulation time unit.
3D block functions
Functions

3D block Description Return


E3DBlockToB- Using the 3D Block locations set below by E3DSetBlockLoca- V
lock(integer sBlock, tion, this function creates an object and moves it from the loca-
integer eBlock, string tion of the sBlock to the location of the eBlock. This function is
objectName, integer intended to allow a more complex path between two blocks
objectType, integer compared to a straight line – a one step method to emulate 2D
pathID, real AnimationBlockToBlock in the 3D world. ObjectName and
speed,integer SelfDe- ObjectType specify the object to be created, as in E3DCreateO-
leting) bject. See the description of that function for more information.
If PathID is nonzero, the function will move the object along the
path specified by that ID. If selfDeleting is set to True, the
object will be deleted when the animation is completed. If self-
Deleting is False, the function will return the ID of the created
object.
ModL Functions 277
Animation

3D block Description Return


E3DBlockToBlock- Specifies a height for the next object to be moved with an V
Height(real Z) E3DblockToBlock call. This is primarily for ExtendItems, as
they have a traveling height. People and vehicles will drop to
the ground, so this call will not effect them. This procedure
should be called before the E3DblockToBlock call.
E3DBlockToBlockO- Specifies an object label for the next E3DBlockToBlock call. V
bjectLabel(label) This procedure should be called before the E3DblockToBlock
call.
E3DBlockToBlock- Specifies the rotation values for the next E3DblockToBlock V
Rotation(real x, real y, call. This procedure should be called before the E3DblockToB-
real z) lock call.
E3DBlockToBlock- Specifies the scale values for the next E3DblockToBlock call. V
Scale(real x, real y, This procedure should be called before the E3DblockToBlock
real z) call.
E3DBlockToBlock- Specifies the string skin names to be used by the next V
Skin(string skin- E3DblockToBlock call. This procedure should be called before
Name, string the E3DblockToBlock call.
skinTypeName)
E3DBlockToBlock- Specifies the indexes of the string names to be used by the next V
SkinByIndex(integer E3DblockToBlock call. This procedure should be called before
skinIndex1, integer the E3DblockToBlock call. See E3DsetSkinByIndex for more
skinIndex2) information about the skinIndex values.
E3DGetBlockLoca- Retrieves the x, y, or z value for the Block location set by R
tion(integer blockN, E3DsetBlockLocation. The which argument takes the follow-
integer which) ing values:
0: x
1: y
2: z
E3DGetObjectBlock- Gets the block number field on the specified 3D Object. I
Number(integer objec-
tID)
E3DSetBlockLoca- Sets an x, y, and z location for a block. This information is V Functions
tion(integer blockN, saved in the model.
real x, real y, real z)
E3DSetObjectBlock- Sets the blocknumber field on the specified 3d object. V
Number(integer objec-
tID, integer
blockNumber)

3D time functions

3D time Description Return


E3DCurrentTime() Returns currentTime in the 3D windows playback of the model R
events.
278 Reference
Animation

3D time Description Return


E3DMode() Returns the mode set by E3DsetMode. I
E3DPauseAllOb- Pauses all objects. Pausing an object stops it from moving I
jects() towards its destination, but records the destination within the
object, so it can be resumed later if desired. This is used in the
executive to pause all items in a model when the simulation is
paused.
E3DResumeAllOb- Resumes all objects that have been paused, and have a saved I
jects() resume destination. See E3DPauseAllObjects above.
E3DSetMode(integer This function sets the mode in which the 3D window, and block V
mode) code, will expect to function. Takes the following values:
0: E3DQUICKVIEWMODE
1: E3DBUFFEREDMODE
2: E3DCONCURRENTMODE
E3DSetTimeRa- Sets the 3DtimeRatio. See the description of E3DtimeRatio for V
tio(real ratio) more information.
E3Dsleep(integer mil- Delays for milliseconds. Stops processing MODL code for that V
liseconds) integer while the 3D window keeps processing.
E3DTimeRatio() Retrieves the 3D Time ratio. This number sets the correspon- R
dence between real-time and simulation time in the 3D window.
The default value is 1000. Changing this will speed up, or slow
down the Playback of 3D events in the 3D Window. For exam-
ple, setting the Time Ratio to 2000, will make the 3D window
run twice as slow as the default value of 1000. Basically this
number is the number of milliseconds in a 3D window time
unit.

3D rotation, position, and scale functions

3D time Description Return


E3DdistanceRatio() Returns the ratio between pixels and meters set in the Simula- R
Functions

tion setup dialog.


E3DGetPosition(inte- Returns the X, y, or z position value of the object. Coord takes R
ger theObject, integer the following values:
coord) 0: x
1: y
2: z
E3DGetRotation(inte- Returns the rotation information for the specified object. Which R
ger objectID, integer can take the following values:
which) 0: x
1: y
2: z
ModL Functions 279
Animation

3D time Description Return


E3DSetPosition(inte- Sets the position of the specified object to the specified location. I
ger theObject, real x, If dropToGround is true, the object will drop until it touches the
real y, real z, dro- ground.
pToGround)
E3DSetRotation(inte- Sets the X, Y, and Z rotation values of the object. Currently I
ger theObject, real x, only z values are meaningful, they will rotate around the z axis.
real y, real z) Values are in radians. (I.e. 2? will be 100% rotation.)
E3DSetScale(integer Sets the scale of the object to the specified scale. X, y, and z I
theObject, real x, real refer to three different dimensions of the object. By default x, y,
y, real z) and z are 1.0. If you set x, y, or z to values that are different
from each other there will be some distortion in the appearance
of the object.

3D window functions

3D window Description Return


E3DNotEnabled() Checks if the 3D is enabled, or not, and returns why. Return I
value:
0: E3D enabled
1: Pro not enabled
2: machine not capable
3: 3D files missing
E3DOpenWindow() Opens the 3D Window. I
E3DUpdate() Forces an update or redraw of the E3D window. This is not usu- V
ally necessary.
E3DWindow() Returns TRUE if the 3D Window is open. I
E3DWindowCon- This function returns a TRUE (1) value if the current model (the I
nected(void) one the function is being called from,) is the model connected to
the E3D window. It returns a FALSE (0) value otherwise.

Functions
3D mountStack functions
A mountStack is a stack of objects mounted onto a mount node on some object. These func-
tion just simplify stacking multiple objects onto a single mount point.

3D mountStack Description Return


E3DMountStack- Add an object to a MountStack. Object will be mounted onto I
Insert(integer objec- target, at the index specified by index. Index starts at zero for
tID, integer targetID, the first object to be mounted on the target. The items in the
integer index, integer stack will mount on each other based on the internal stack-
baseNode) MountNode of the objects, with the exception of the base of the
mountStack, which will use the Node specified by baseNode. If
you pass in a –1 for baseNode, the object will use its stack-
MountNode. If you do not know which node you want to spec-
ify, just pass in a negative one for the baseNode.
280 Reference
Animation

3D mountStack Description Return


E3DMountStack- Determines the limit for mountStacks created by a specified I
Limit(integer block- block. The purpose is to reduce the number of objects displayed
Number, integer limit) in the E3D window, enhancing performance. The mountStack
limit only renders up to limit objects; after that it indicates the
total count of objects as a number on the top of the stack. If not
overridden by block code, the default mountStack limit is 10.
E3DMountStack- Remove an object from a mountStack. Direction and distance I
Remove(integer are as defined in the Unmount functions. Rule determines how
objectID, integer the index value is used. A rule value of zero, means that index
index, integer base- is just a zero based index of which object is to be removed. A
Node, integer rule, rule value of one means that index is the Object ID of the object
integer direction, real to be removed. BaseNode specifies which node on the base
distance) object the mountStack is stacked on. If you pass in a –1 for
baseNode, the object will use its stackMountNode. If you do
not know which node you want to specify, just pass in a nega-
tive one for the baseNode.

3D path functions

3D path Description Return


E3DAddMarkerTo- Adds the specified Marker to the specified path. I
Path(integer path,
integer marker)
E3DCreate- Creates a Marker for addition to a path. X, Y and Z specify the I
Marker(real x, real y, location of the marker. Spline specifies how the path will ren-
real z, integer spline, der when viewed in the Editor. If spline is true, the marker will
integer seqNum, inte- be represented as connected to the other markers, by a curved
ger GroupTag) line, otherwise it will be connected with a straight line. The
seqNum argument should be 1 for the first point on the path,
and should count up incrementally. If the markers are not
sequential, the behavior of the path will be unpredictable. See
the creation functions section for more information about the
GroupTag.
Functions

E3DCreatePath(string Creates a path with the specified name. Looping determines I


name, integer loop- whether the path is looping, or not. If the path is looping, an
ing, integer Group- item that is traveling on the path will go back to the beginning
Tag) of the path when it leaves the last marker on the path. See the
creation functions section for more information about the
GroupTag.
E3DGetPathBy- Returns the ObjectID number for the path with the specified I
Name(string name) name.
ModL Functions 281
Animation

3D path Description Return


E3DPathMarkerLoca- Returns the x, y, or z position value of the nth marker on the R
tion(integer path, inte- specified path. Index specifies which marker you want the
ger index, integer coordinate value for, starting at one for the first one, and coord
coord) specifies whieh coordinate value you want. This function
returns a –10000 when it fails. Coord takes the following val-
ues:
0: x
1: y
2: z
E3DPathSetCo- Sets the color of the specified path. Paths are invisible by I
lor(integer objectID, default, so this function will seem to have no effect until the
integer firstColor, E3DSetVisibility function is also called on the path. ObjectID
integer secondColor, specifies which path is to have its color set. FirstColor, second-
integer thirdColor, Color, and thirdColor have different meanings depending on the
integer RGB) value of the RGB argument. If the RGB argument is set to
TRUE, firstColor is red, secondColor is green, and thirdColor is
blue. If RGB is FALSE, first Color is hue, second is saturation,
and third color is value. (See separate discussion of RGB and
HSV colors.)

3D object selection functions

3D object selection Description Return


E3DGetSelectedOb- Returns the ObjectID for the object currently selected in the 3D I
ject() window.
E3DObjectClicked() Returns the objectID of the last E3D object clicked. I
E3DSetSelectedOb- Sets the selection in the 3D window to be the object specified. I
ject(integer object)
E3DUnselectOb- Unselects the specified object. This will have no effect if the I
ject(integer objectID) specified object is not the selected object in the E3D window.

Functions
3D environment functions

3D environment Description Return


E3DBounding- Sets a flag which decides if objects drawn in the 3d Window I
Boxes(integer bound- should try to draw their bounding boxes. This will only affect
ingBoxes) ExtendItems, ExtendPlayers, and ExtendVehicles.
E3DChooseEnviron- Sets the Environment file name that is associated with the I
ment(string Environ- model.
mentName)
E3DSetDetail(real Sets the level of detail for the objects in the E3D window. This V
detailValue) controls the same variable as the LOD control in the options
dialog.
282 Reference
Animation

3D environment Description Return


E3DSetTerrain(string Sets the Terrain texture file to be associated with the terrain. V
terrain, integer which) Which takes a value of 1-6, which corresponds to which one of
the 6 textures the terrain editor defines is to be changed. (By
default the terrain is all drawn in texture one (1), so if you just
want to change the texture of the default environment file, just
use 1 for the which value.
E3DSky(integer sky- Red/Green/Blue : 0-255, skySetting: V
Setting, integer red, 0: default (Clouds and Skybox)
integer green, integer 1: no Clouds (just Skybox)
blue) 2: no skybox
3: ceiling (uses color, no clouds or fog)
E3DSun(integer sun- Red/Green/Blue : 0-255, sunSetting: I
Setting) 0: No visible sun (sunFlare is disabled)
1: Sun is visible, (Sun flare is enabled)

3D creation and deletion functions


GroupTag is user-defined identifer to group types of objects. For example you could use 1 to
be the type of all block-to-block items that you want to delete at the end of the simulation.

3D creation/deletion Description Return


E3DChangeOb- Changes the specified object into another type of object. I
ject(integer objectID, ObjectName specifies which type of object to change the
unsigned char choosen object into. Please note that you should only attempt to
*ObjectName) change objects of a like type into other objects. For example,
changing a ‘Male’ object into a ‘Female’ object should be fine,
because both objects are ExtendPlayer Objects, but changing a
‘Male’ object into a ‘Boid’ object is not allowed, and will not
work.
E3DCopyObject(inte- Creates a copy of the object referenced by objectID at location I
ger objectID, real x, x, y, z. This copy will have all the information associated with
real y, real z) the object being copied, with the exception of location, and any
other objects mounted on it.) If the X, Y and/or Z values are
Functions

blanks or novalues, then the existing position of the object will


be used for that coordinate.
E3DCreateOb- Creates an object at location x, y, z. ObjectName specifies what I
ject(string object- kind of object to create. ObjectType specifies what type of
Name, integer object is to be created. Zero is a special type that tries to create
objectType, real x, real the appropriate type for that particular object. This is almost
y, real z, integer col- always what you will want to use from MODL, unless you are
lideable, integer custom coding using custom 3D objects.
GroupTag)
ModL Functions 283
Animation

3D creation/deletion Description Return


E3DCreateObjectAt- Creates an object at waypointID. I
WayPoint(string
objectName, integer
objectType, integer
wayPointID, string
name, integer collide-
able, integer Group-
Tag)
E3DCreateWay- Creates and returns a waypointID at the specified location. I
Point(real x, real y,
real z, string name,
integer GroupTag)
E3DDeleteAllOb- If tag is <= –1, all objects will be cleared. If tag is greater than – I
jects(integer Group- 1, only objects that have that GroupTag will be cleared. Clears
Tag) all objects and events created from MODL from the 3D Win-
dow.
E3DDeleteOb- Deletes the specified object. If deleteMount is true, objects I
ject(integer theOb- mounted to the specified object will be delete.
ject, integer
deleteMount)

3D movement functions

3D movement Description Return


E3DGetDestina- Returns on of the destination coordinants of the specified R
tion(integer objectID, object.
integer coord) coord
0: x
1: y
2: z
E3DGetSpeed(integer Returns the speed of the specified object. R

Functions
objectID)
E3DResume- Resumes the previous speed value of the object. Each object I
Speed(integer objec- internally saves its old speed when a new speed value is set.
tID) This function resets the speed to the last value used.
284 Reference
Animation

3D movement Description Return


E3DSetDestina- Sets a destination for the specified E3D object. The types of I
tion(integer objectID, objects that can have a destination set are ExtendItems, Extend-
real speed, real x, real Players, and ExtendVehicles. This excludes scenery and block
y, real z, integer sync, objects, which do not normally move. The speed argument will
integer selfDeleting) be used by to the object as it travels to its destination. X, Y, and
Z are the coordinates of the destination. The sync argument
determines if the motion of the object will be synchronous, or
asynchronous. Synchronous means that the call will wait to
return until the specified object reaches its destination. This has
a potential danger, in that if the object is blocked, and does not
reach its destination, the call will not return, and the code will
hang. If selfdeleting is set to true, then the object will delete
itself when it reaches its destination.
E3DSetSpeed(integer Sets the speed of the specified object. I
objectID, real speed)
E3DSetTargetOb- Sets a target object for the object. The types of objects that can I
ject(integer objectID, have a path set are ExtendItems, ExtendPlayers, and ExtendVe-
integer targetID, string hicles. This excludes scenery and block objects, which do not
name, real speed, inte- normally move. The speed argument will be used by to the
ger sync, integer self- object as it travels to its destination. TargetID is the ID of the
Deleting) target object. The sync argument determines if the motion of
the object will be synchronous, or asynchronous. Synchronous
means that the call will wait to return until the specified object
reaches the target. This has a potential danger, in that if the
object is blocked, and does not reach its destination, the call will
not return, and the code will hang. If selfdeleting is set to true,
then the object will delete itself when it reaches the target
object.
E3DSetTarget- Sets a target path for the object. The types of objects that can I
Path(integer objectID, have a path set are ExtendItems, ExtendPlayers, and ExtendVe-
integer targetID, string hicles. This excludes scenery and block objects, which do not
name, real speed, inte- normally move. The speed argument will be used by to the
ger sync, integer self- object as it travels to its destination. TargetID is the ID of the
Deleting, integer target path. The sync argument determines if the motion of the
Functions

startingMarker) object will be synchronous, or asynchronous. Synchronous


means that the call will wait to return until the specified object
reaches the end of the path. This has a potential danger, in that
if the object is blocked, and does not reach its destination, the
call will not return, and the code will hang. If selfdeleting is set
to true, then the object will delete itself when it reaches the end
of the path. The startingMarker defines which marker starts the
path, usually one.
ModL Functions 285
Animation

3D movement Description Return


E3DSetTargetWay- Sets a target waypoint for the object. The types of objects that I
Point(integer objec- can have a path set are ExtendItems, ExtendPlayers, and
tID, integer targetID, ExtendVehicles. This excludes scenery and block objects,
string name, real which do not normally move. The speed argument will be used
speed, integer sync, by to the object as it travels to its destination. TargetID is the ID
integer selfDeleting) of the target waypoint. The sync argument determines if the
motion of the object will be synchronous, or asynchronous.
Synchronous means that the call will wait to return until the
specified object reaches the target. This has a potential danger,
in that if the object is blocked, and does not reach its destina-
tion, the call will not return, and the code will hang. If selfdelet-
ing is set to true, then the object will delete itself when it
reaches the target waypoint.
E3DStopAllObjects() This function stops all objects that have a destination. This I
would usually be called when the E3D animation is complete,
as it will clear destinations, and there will not be a way of
resuming the motion.

3D post function
Post functions are the equivalent of the similarly named regular E3D function, with the addi-
tion of a time argument specifying when the E3D action will occur. See the appropriate E3D
function for more information about the meaning of the arguments of the functions. Times are
specified in simulation time units, and the most common value of this argument will be to
place the system variable currentTime into it.

3D post
E3DPostAnimationPlay(real time, integer objectID, string which, integer forward, integer threa-
dID)
E3DPostAnimationSetPosition(real time, integer objectID, string which, real pos)
E3DPostAnimationStop(real time, integer objectID, string which)
E3DPostChangeObject(real time, integer objectID, string ObjectName)
E3DPostCopyObject(real time, integer objectID, real x, real y, real z) Functions
E3DPostCreateObject(real time, string objectName, integer objectType, real x, real y, real z, inte-
ger collideable, integer GroupTag)
E3DPostCreateObjectAtWayPoint(real time, string objectName, integer objectType, integer way-
PointID, string wayPointName, integer collideable, integer GroupTag)
E3DPostDeleteAllObjects(real time, integer groupTag)
E3DPostDeleteObject(real time, integer ObjectID, integer deleteMounted)
E3DPostMountObject(real time, integer objectID, integer targetID, integer node)
E3DPostMountStackInsert(real time, integer ObjectID, integer targetID, integer index, integer
baseNode)
286 Reference
Animation

3D post
E3DPostMountStackRemove(real time, integer ObjectID, integer index, integer baseNode, inte-
ger rule, integer direction, real distance)
E3DPostObjectPropertySet(real time, integer objectID, integer which, real value)
E3DPostResumeSpeed(real time, integer objectID)
E3DPostRotateTimed(real startTime, real endTime, integer objectID, real startZ, real endZ, inte-
ger ticks)
E3DPostSetDestination(real time, integer objectID, real duration, real speed, real x, real y, real z,
integer selfDeleting)
E3DPostSetObjectBlockNumber(real time, integer objectID, integer blockNumber)
E3DPostSetObjectLabel(real time, integer objectID, string objectLabel)
E3DPostSetPosition(real time, integer objectID, real x, real y, real z, integer drop)
E3DPostSetRotation(real time, integer objectID, real x, real y, real z)
E3DPostSetScale(real time, integer objectID, real x, real y, real z)
E3DPostSetSkin(real time, integer objectID, string skinName, string skinBaseName)
E3DPostSetSkinByIndex(real time, integer objectID, integer skinIndex1, integer skinIndex2)
E3DPostSetSpeed(real time, integer objectID, real speed)
E3DPostSetTargetObject(real time, integer objectID, real duration, real speed, integer targetID,
string name, integer selfDeleting)
E3DPostSetTargetPath(real time, integer objectID, real duration, real speed, integer targetID,
string name, integer selfDeleting)
E3DPostSetTargetWayPoint(real time, integer objectID, real duration, real speed, integer tar-
getID, string name, integer selfDeleting)
E3DPostSetVisibility(real time, integer objectID, integer visible)
E3DPostStopAllObjects(real time, integer sync)
Functions

E3DPostUnmountObject(real time, integer objectID, integer targetID, integer direction, real dis-
tance)
E3DSetObjectLabel(integer objectID, string name)

3D mounting functions

3D mounting Description Return


E3DGetMount(inte- Returns the objectID for the object that the specified object is I
ger objectID) mounted to.
E3DGetMountedOb- Returns the ObjectID for the object that is mounted to the speci- I
ject(integer objectID, fied object at the specified node.
integer node)
ModL Functions 287
Animation

3D mounting Description Return


E3DMountOb- Mounts the object referred by riderID onto the object referred to I
ject(integer mountID, by mountID. Node specifies the mountNode to use on the object
integer riderID, inte- to be mounted. Node would be set to 0, for objects that have
ger node) only one mount point. Pass in a –1 if you want Extend to do a
smart mount, i.e. to mount a person object to the seat, and a box
object to the fork of a forklift, for example.
E3DUnmountOb- Unmounts the rider from the mount. Direction specifies which I
ject(integer mountID, way to use the optional offset distance. This will move the
integer riderID, inte- object a certain distance when the unmount is completed. Dis-
ger direction, real dis- tance is in 3D units. (Meters.)
tance) Direction: 1: north, 2: west, 3: east, 4: south, 5: up
If you pass in a zero for the mountID, the function will unmount
the rider from whatever mount it happens to be mounted on.

3D animation functions

3D animation Description Return


E3DAnimation- Returns the name of the animation on the specified object that S
Name(integer objec- corresponds to the ‘which’ parameter.
tID, integer which)
E3DAnimation- Plays the animation specified by the ‘which’ parameter on the I
Play(integer objectID, object specified by the ObjectID parameter. Backward should
string which, integer be set to true of you want the animation to play backward.
backward)
E3DAnimationSetPo- Sets the specified animation to the specified position. I
sition(integer objec-
tID, which which, real
pos)
E3DAnimation- Stops the animation thread specified by the string which. Note I
Stop(integer objectID, that this also stops the Torque animation thread from running.
string which) In most cases this doesn’t matter, as ExtendSim manages the

Functions
Torque threads for you. Examples of where it does matter are
animations where two sequences use the same parts of the
object, or if you have more than eight different animations that
you want to run. In either case, you need to stop one thread to
successfully run the next.
E3DDialogPic- Shows the object picture within a dialog’s static text item. I
ture(string variable-
Name, string
objectName, real rota-
tion, real rotation2)
E3DGetObjectAnima- Gets the object’s animation names into theArray. I
tionNames(integer
ObjectID, string the-
Array[])
288 Reference
Animation

3D animation Description Return


E3DObjectSnap- Saves a .png file with the object’s picture. I
shot(string fileName,
integer objectID, real
rotation, real rota-
tion2)

3D name functions

3D name Description Return


E3DGetName(integer Returns the name of the specified object. Useful for uniquely S
objectID) naming 3d objects, this is the name used in the E3DgetPathBy-
Name, and E3DgetObjectByName functions
E3DGetObjectBy- Returns the objectID for the object with the specified name. I
Name(string name)
E3DGetObjectLabel Gets the ObjectLabel of the specified object. (This is the name/ S
(integer objectID) label that displays above the object in the 3D Window.) Note for
E3D Developers, in the 3D engine this is the ShapeName.
E3DGetObject- This function returns a list of object type names of all the I
List(integer which, objects of the type specified by the ‘which’ argument. Please
string31 nameArray[]) note that these are not the object names defined by E3DSetOb-
jectName, or the object labels defined by E3DsetObjectLabel,
but rather the object type names. I.e.:“Male”, “Female”, “Ball”,
and so on. This function is used to identify all the possible
types of objects that can be created. NameArray need to be a
string31 dynamic array. It will be resized by the function.
Which values:
-1: all possible objects
0: ExtendItem + ExtendPlayer + ExtendVehicle
1: block
2: scenery
3: ExtendSim
4: ExtendPlayer
Functions

5: ExtendVehicle
E3DGetObject- Fills the passed in string31 array with the names of the E3D I
Names(integer which, Objects in the 3D world. The array should be a string31
string31 nameArray[]) dynamic array, which the function will resize based on the num-
ber of names to be returned. Which values:
0 or greater: groupTag
-1: everything
-2: Paths
-3: WayPoints
-4: ExtendItems
-5: Players
-6: wheeled vehicles
ModL Functions 289
Animation

3D name Description Return


E3DObjectLabelCol- Sets the color of the object label on the specified object. Noth- I
orSet(integer objec- ing will be drawn if the objectLabel is empty, so this function
tID, integer firstColor, will need to be used in conjunction with E3DSetObjectLabel.
integer secondColor, FirstColor, secondColor, and thirdColor have different mean-
integer thirdColor, ings depending on the value of the RGB argument. If the RGB
integer RGB) argument is set to TRUE, firstColor is red, secondColor is
green, and thirdColor is blue. If RGB is FALSE, first Color is
hue, second is saturation, and third color is value. (See separate
discussion of RGB and HSV colors.)
E3DSetName(integer Sets the name of the specified object. This is the name by I
objectID, string name) which the object is referred to in the 3D window. This name
will be visible in the editor. Useful for uniquely naming 3d
objects, this is the name used in the E3DgetPathByName, and
E3DgetObjectByName functions.
E3DSetObjectLabel Sets the ObjectLabel of the specified object. (This is the name/ I
(integer objectID, label that displays above the object in the 3D Window.) Note for
string shapeName) E3D Developers, internally in the 3D engine this is the
ShapeName.

3D screenshot functions

3D screenshot Description Return


E3DPanoram- Creates three screenshot files in the Extend directory. Put V
icScreenShot(string together, the screen shots will create a panoramic view of the
fileName) contents of the 3D window.
E3DScreen- Creates a screenshot file in the Extend directory. Currently the V
Shot(string fileName) file type of the screen shot file is PNG. So the file name will be
filename.png.

3D distance functions

Functions
3D distance Description Return
E3DDistance(integer Returns the distance from the location of the specified object to R
objectID, real x, real y, the specified location.
real z)
E3DDistan- Returns the total distance of the path. R
cePath(integer pathID)
E3DDistanceToOb- Returns the distance between the two objects. R
ject(integer objectID,
integer targetID)
290 Reference
Animation

3D skin functions

3D skin Description Return


E3DGetObjectSkin- Returns the SkinBaseNames for the object type specified by S
Base(string object- objectName. Which specifies if you want base name 1, or base
Name, integer which) name 2. Currently the only objects that have meaningful base
names are the Male and Female object, as discussed under
E3DgetObjectSkinNames above. I.e. for the female object,
calling this function with a which value of 2, will return the
string “femaleSkin”.
E3DGetObjectSkin- Returns the names of the skins for the object. For most objects, I
Names(integer objec- you can leave the basename field blank (“”). For objects with
tID, string baseName, multiple skins, it specifies which skin you want to set. Specifi-
str32 theArray[]) cally, at the moment, there are two objects that support more
than one skin, the female and male figures. For the female,
specify “femaleClothes” for her clothes, and “femaleskin” for
her skin. For the male, its “MaleClothes” and “maleSkin”.
E3DSetSkin(integer Allows you to set the skin of a 3D object. For most objects, you I
objectID, string skin- can leave the basename field blank (“”). For object with multi-
Name, string ple skins, it specifies which skin you want to set. Specifically,
baseName) at the moment, there are two objects that support more than one
skin, the female and male figures. For the female, specify
“femaleClothes” for her clothes, and “femaleskin” for her skin.
For the male, its “MaleClothes” and “maleSkin”. Returns an
error code number (Non-zero) if it fails.
E3DSetSkinByIn- This function lets you set the skin values of an object by I
dex(integer objectID, numeric index values. The first skinIndex number modifies the
integer skinIndex1, first object skin, and the second modifies the second skin. Note
integer skinIndex2) that most objects (currently, all object except the people,) only
have one skin, so the second number will be ignored. skinIndex
values:
-1: make the skin value a random choice
0: keep the skin value the same
1-n: use a specific skin
>n: use n
Functions
ModL Functions 291
Animation

3D vector functions
3D vector Description Return
E3DForwardAn- This function returns the forward angle for the Object. Where R
gle(integer objectID, zero means directly in front, PI means directly behind.
integer targetID)
E3DForwardVec- This function returns the forward vector for the Object. The R
tor(integer objectID, forward vector is the vector forward from the Object. The
integer which) which argument specifies which part of the vector is to be
returned. Which values are:
0: X
1: Y
2:Z
E3DGetAngleFrom- This function returns the yaw and pitch angles. The range of R
Vector(real vectorX, yaw is 0 - 2PI. The range of pitch is -PI/2 - PI/2. Which values:
real vectorY, real vec- 0: yaw
torZ, integer which) 1: pitch
E3DGetObjectVec- This function returns a vector for the object, depending on the I
tor(integer objectID, value of the which argument. Vector needs to be a predefined
integer which, real single row real array with at least three elements. Which takes
vector[]) the following values:
0: position
1: forward Vector
E3DGetVectorFro- This function returns the vector from the specified angles. The R
mAngles(real yaw, range of yaw is 0 - 2PI. The range of pitch is -PI/2 - PI/2. Which
real pitch, integer values are:
which) 0: X
1: Y
2: Z
E3DNormalizeVec- Takes the vector passed in, and normalizes the array. Vector I
tor(real vector[]) needs to be a predefined single row real array with at least three
elements.

3D user tag functions


Functions
ObjectIDs are unique identifiers defined by the E3D engine to identify each object in the E3D
world. Normally functions that create an object, will return a resulting ObjectID. In the case
of the Post functions, this is not possible, because the post functions are called before they are
executed. A userTag is a value returned by a E3DpostCreate function, as it does not immedi-
ately create an object, instead creates it at the specified simulation time.
UserTag values are negative numbers, and objectID values are positive numbers. Objects cre-
ated from Extend retain their userTags even after the objectID value is created when the object
is actually created in the 3D window, and all Extend functions can recognize either.
292 Reference
Animation

3D user tag Description Return


E3DObjectIDToUs- Returns an UserTag value from a ObjectID. This function is the I
erTag(integer objec- reverse of the E3DuserTagToObjectID function. See that func-
tID) tions description for more information. UserTag values are neg-
ative numbers, and objectID values are positive numbers. All
Extend functions can recognize either.
E3DUserTagToObjec- Returns an objectID value from a userTag. An ObjectID value I
tID(integer userTag) is the reference ID of a 3D object, as used by the 3D engine. A
userTag is a value returned by E3DPostCreateObject, as it does
not immediately create an object, instead creates it at the speci-
fied simulation time. UserTag values are negative numbers, and
objectID values are positive numbers. This function does not
usually need to be called, as objects created from Extend retain
their userTags even after the objectID value is created when the
object is actually created in the 3D window, and all Extend
functions can recognize either.

3D tick functions
These functions start a timer specifically for the use of the 3D window. The E3DTICK mes-
sage will be sent to the block periodically once the E3DTimer has been started with E3DStart-
Tick. Unlike the ExtendSim timers, described separately, the E3Dtimer is controlled by the
E3D engine. It will be sent on each tick of the E3D engine, which will be frequently enough to
update something that needs to move smoothly in the E3D window. If you want a timer that is
based on simulation time, you should use the regular ExtendSim Timers.

3D tick Description Return


E3DStartTick(integer blockNumber specifies which block should get the E3DTICK V
blockNumber) message. If you specify a negative one (-1) for the block num-
ber, all the blocks in the model will receive the E3DTICK mes-
sage.
E3DStopTick(integer Stops the E3D timer for the specific block. V
blockNumber)
Functions

3D object property functions

3D object properties Description Return


E3DCollision- Shows the collision rect for the specified object. This will cur- V
Show(integer objec- rently only show up once the object has moved.
tID, integer show)
ModL Functions 293
Animation

3D object properties Description Return


E3DGetObject- Returns the bounds of the specified object in the 3D world. R
Bounds(integer objec- Which specifies what part of the bounds information is to be
tID, integer which) returned. Zero through eight return values that are in World
Coordinates. World Coordinates are based on the objects posi-
tion in the E3D World. 10 through 18 return values that are in
Object Coordinates. Object Coordinates are based on the object
position as if the object were located at the origin. Which:
0: min X, 1: min Y, 2: min Z, 3: max X, 4: max Y, 5: max Z, 6:
X length, 7: Y length, 8: Z length, 10: min X (obj Bounds), 11:
min Y, 12: min Z, 13: max X, 14: max Y, 15: max Z, 16: X
length (obj Bounds), 17: Y length (obj Bounds), 18: Z length
(obj Bounds)
E3DGetObjec- This function fills the passed in array of longs with the object I
tIDs(integer which, ids of all the 3D objects in the 3D window. The ‘which’ param-
integer theArray) eter can be used to specify which objects you want to list.
Which:
> 0: groupTag, -1: everything, -2: Paths, -3: WayPoints, -4:
ExtendItems, -5: Players, -6: wheeled vehicles
E3DGetObject- Returns the specified information about the object. ‘Which’ I
Info(integer objectID, takes the following arguments: 0: userTag, 1: objectID, 2:
integer which) groupTag, 3: savedInEnvironmentFile Flag
E3DGetObject- This function returns the type of a 3D object, based on the I
Type(unsigned char name. The possible type values are: 1: block, 2: scenery, 3:
*ObjectName) item, 4: person, 5: vehicle.
If the object doesn’t fall into any of these categories, a zero will
be returned.
E3DObjectProperty- which: 1: collidable. (true/false) I
Set(integer objectID,
integer which, real
value)
E3DSetVisibility(inte- Sets the visibility flag on the item specified by objectID. A vis I
ger objectID, integer value of TRUE means the item is visible. (The default.)

Functions
vis)

3D script functions

3D script Description Return


E3DExec(string Executes the contents of the string script through the Torque I
script) compiler.
E3DExecFile(string Executes a .cs file through the Torque compiler. I
path)
294 Reference
Animation

3D miscellaneous functions

3D miscellaneous Description Return


E3DCollision- Collision optimization. Used by the Transport and Convey Item V
Blocker(integer objec- blocks to inform a 3D object that it is in a queuing situation and
tID, integer blocker) can optimize its collision calculations by only looking at the
object specified in the blocker argument. Blocker should be the
object ID of the object that is in front of the specified object in
the queue.
E3DGetCamera() Returns the ObjectID for the camera object. I
E3DLogEvents(inte- Turns on (or off) logging of the Events in the E3D window.
ger logFlag) Logging will write messages to the Console.log file in the
ExtendSim folder when events occur in the E3D window. Log-
ging is off by default. If logFlag is true (1), it will be turned on.
E3DMessage- Returns information about a message sent by the E3D window I
Info(integer which) to ExtendSim. This function is used in the E3DCollision mes-
sage handler to request the 3D object ID of the object that is
about to collide (which=1) or the object that is about to be col-
lided with (which=2).
E3DNeighborDetec- This function acts like ‘vision’ for objects in the E3D world. It I
tion(integer objectID, detects all the objects within a certain range of a specified item,
integer which, real and returns the number of objects ‘seen’, as well as filling an
distance, real angle, array with the Object Ids of the objects. Which is used to spec-
integer sort, integer ify which types of items are to be detected, see below for possi-
neighbors[]) ble values. Distance determines how far to detect other objects.
Angle determines how broadly to detect the objects, and the
angle starts straight ahead and goes both right and left, so 3.14
(Pi radians) will detect everything on both sides, front to back.
Sort determines if the object Ids should be sorted on return, and
neighbors is the array of objects Ids that are returned. An angle
value of zero is special cased to mean don’t check the angle.
This should have the same affect as an angle value of 3.14.
Which:
0: everything
Functions

1: ExtendItems
E3DObjectExists(inte- Returns a true (1) if the specified object exists, and a false (0) if I
ger objectID) it doesn’t.
E3DPlaySound(string Plays the sound specified by soundProfileName. At the location I
soundProfileName, specified by x,y,z.
real volume, real x,
real y, real z)
E3DUses3D() Returns the value of the uses3D flag from the sim setup dialog I
for the active model.
ModL Functions 295
Blocks and inter-block communications

Blocks and inter-block communications


Block numbers, labels, names, categories, position
As seen in their Properties, all objects in a model (blocks, text, shapes, connection lines, and so
forth) are numbered uniquely and sequentially from 0 to n-1 as they are added to the model
worksheet. In most cases, the numbers assigned to each object do not change. However:
• If a model has
• f a block or text is deleted, its number becomes an “unused slot” which is available when
another object is added to the model.

Numbers
There are two numbers associated with blocks. Global numbers access all blocks, including
blocks inside of hierarchical blocks. Local numbers access a hierarchical block’s internal
blocks and are the same for all instances of that hierarchical block, whereas the global numbers
are different for each instance. Blocks are numbered from 0 to NumBlocks-1. Block numbers
show in a dialog’s title bar.
Names and labels
• Block names are the names you give a block when you create it. For example, “Data Import
Export” is the name of a block in the Value library. Names appear in the dialog’s title bar.
• Block labels are user-definable names given to a particular block in the model. Block labels
are entered in the area to the right of the Help button at the bottom of a block’s dialog. Labels
appear at the bottom of the block’s icon.

Categories and types


• Categories are used to group blocks in the library menu based on some commonality. Exam-
ples of categories include Math or Holding from the Value library. Categories are set using
the Develop > Set Block Category menu command.
• Block types are a way to delineate Item library blocks as residence, passing, or decision.

Block numbers, Description Return


labels, etc.

Functions
BlockName(inte- Looks in global slot i and returns either the name of the block, the S
ger i) first 255 characters of text, or an empty string if it is an unused
slot. For example, you can use this function to read text informa-
tion that you have added or modified in a model.
BlockRect (integer Virtually the same as the getBlockTypePosition function, except I
blockNumber, inte- for the useAnimation argument. This argument specifies (with a
ger or real array[4], true/false, 1/0 value) whether or not the animation objects are to
integer useAnima- be included in the returned rectangle. If useAnimation is true, the
tion) rectangle will include the positions of the animation objects that
are off the icon in the rectangle, otherwise it will not.
296 Reference
Blocks and inter-block communications

Block numbers,
Description Return
labels, etc.
FindInHierarchy This function is used by several blocks, including the Catch Item I
(string FindBlock- and Throw Item blocks in the Item library, to locate the corre-
Name, string Find- sponding block associated with the current block. (For example,
BlockLabel, string to find a Catch corresponding to a Throw, and vice versa.) Please
FindDialogName, see the Catch and Throw blocks for an example of how to use this
integer FindDialog) function. The function returns the block number of the resulting
block found; it returns a –1 if no matching block is found. Find-
BlockName is the name of the block to be found (e.g. ‘Catch’, or
‘Throw’). FindBlockLabel is the block label of the block to be
found. FindDialogName is the name of the dialog item you wish
to search for. The FindDialogName field should be filled with the
dialog item name, a colon, and then the value of the dialog item
that you wish to search for. For example Item:54 will search for
the presence of a dialog item with the name “item”, and the value
“54”. FindDialog takes the following values: 0: just check the
block name, and the block label. 1: just check the block name and
the dialog item name and value. 2: check the name, label, and dia-
log item.
FindInHierar- The same as the FindInHierarchy function except it takes a block I
chy2(integer block- number argument.
Number, string
findBlockName,
string findBlockLa-
bel, integer findDi-
alog)
GetBlockLa- Returns the label string for the global block i. S
bel(integer i)
GetBlockMem- Returns the number of bytes of memory used by the block. I
Size(blockNumber)
GetBlock- Returns the string that represents the category (e.g. Math or Hold- S
Type(integer i) ing) for the global block i. Block categories are set in the Develop
> Set Block Category menu.
Functions

GetBlockTypeNu- Like GetBlockTypePosition() this function returns the block type I


meric(objectID) but since it doesn't have to calculate the block position, it is faster.
ModL Functions 297
Blocks and inter-block communications

Block numbers, Description Return


labels, etc.
GetBlockTypePosi- In versions prior to 10, many objects (anchor points, blocks, text, I
tion(integer i, inte- etc.) were referred to as “blocks”. This function returns a speci-
ger or real fied Type for the global block i. Types are as follows:
Array[4]) 0: empty slot
1: anchor point
2: text
3: block
4: hierarchical block
5: embedded object
6: Slider, Switch, or Meter (from the Model > Controls command
prior to ExtendSim 10)
The function puts an integer or a real in the array depending on
whether the array is defined as integer or real. On return, array[0]
will contain the top, array[1] the left, array[2] the bottom, and
array[3] the right position’s pixel values.
To include animation objects, see the blockRect function.
☞ See also the GetBlockTypeNumeric and ObjectIDNext func-
tions, which are faster for certain situations.
GetEnclosingH- Returns the global block number for the enclosing hierarchical I
blockNum() block. Returns -1 if there is no enclosing hierarchical block.
GetEnclosingH- This is the same as GetEnclosingHblockNum(), except it refers to I
blockNum2 (inte- a global block number.
ger block)
GetStaticNames Fills the names and types arrays with the names and types of all I
(integer blockNum- the static variables defined in the block structure. Names should
ber, array names, be an array of strings, and types should be an array of longs. The
array types) value of the cells of the types array will be from the following list:
3: LONGTYPE
6: DOUBLETYPE
7: STRING255TYPE

Functions
8: STRING15TYPE
9: STRING31TYPE
10: STRING63TYPE
11: STRING127TYPE
GlobalToLocal Returns the local block number for the specified block if it is con- I
(integer blockNum- tained in an H-block. Returns a -1 if the block is not contained in
ber) an H-block.
IconBody (block- Similar to the BlockRect function. Returns the rect for the body of I
Num, real array[4], the icon, allowing (via the useAnimation and useConnectors argu-
useAnimation, use- ments) control over whether the animation objects and/or connec-
Connectors) tors are included in the rect.
Returns a zero for success or a non zero value for an error.
298 Reference
Blocks and inter-block communications

Block numbers,
Description Return
labels, etc.
LocalNumBlocks() Number of internal blocks in the hierarchical block from which I
this function is called. Blocks are numbered from 0 to Local-
NumBlocks()-1.
LocalNumBlocks2 This is same as LocalNumBlock(), except it refers to a global I
(integer block) block number.
LocalToGlobal Converts a local number in the hierarchical block from which this I
(integer i) function is called to a global number.
LocalToGlobal2 Similar to LocalToGlobal, this function will return the global I
(integer Hblock- blocknumber for a local one. The difference is that this function
Num, integer local- allows you to specify which Hblock in the model is used as the
BlockNum) context for the local block number via the first parameter Hblock-
Num.
MakeOptimizer- This function tags the block as an optimizer block so that the V
Block (integer true- Run > Run Optimization command will send a RUN message to
False) that block, assuming there is a “Run" button in the block that will
run the optimization and has an "ON RUN" message handler. Call
this function in "CREATEBLOCK." See the Optimizer block
(Value library).
MyBlockNumber() Global number of the block in which the function is called. Note I
that this number is the first number shown in parentheses in the
block dialog’s title.
MyLocalBlock- Local number of the block in which the function is called. Note I
Number() that this number is the second number shown in parentheses in the
block dialog’s title.
NumBlocks() Global number of blocks in the model, including text blocks and I
unused slots. Blocks are numbered from 0 to NumBlocks()-1.
ObjectIDNext(Inte- Returns the objectID of the next object of the type requested, as I
ger fromBlock, controlled by the which variable. You can step through all the
integer which) blocks in the model quite a bit faster than in V9 since, depending
Functions

on the which value, you can just jump to the next block.
FromBlock specifies where in the list to begin, so it will normally
be started at -1. Which currently takes the arguments:
0: blocks
1: Hblocks
2: both regular and Hblocks
The pseudo code for using the function:
objectID = objectIDNext(-1, 0);
while (objectID > -1)
{
objectID = objectIDNext(objectID, 0);
}
This will loop through all the blocks in the model without needing
to call numblocks or getBlockTypePosition.
ModL Functions 299
Blocks and inter-block communications

Block numbers,
Description Return
labels, etc.
SetBlockLabel Sets the label for the global block i to str. Blocks are numbered V
(integer i, string from 0 to NumBlocks()-1.
str)
ShowBlockLabel Labels are shown by default. To hide a block’s label, use this V
(integer i, integer function with the global block number i and FALSE for show.
show)

Block connectors and connection information


The following functions give you information about connectors and connected blocks in a
model. This helps you manipulate connectors and determine what is connected to a block or to
create network lists of your models.
In these functions, “block” is the global block number (see “Block numbers, labels, names, cat-
egories, position” on page 295), “connName” is the connector’s name (without quotes, not a
string), “connString” is the connector’s name (with quotes), and “conn” is the ith connector (0
to n-1) in the list of connectors in the structure window’s connector pane. To determine the
connector number for a given connector name, look in the block’s connector pane, counting
from the top of the list (which is connector 0). “block” and “conn” are integers.
Also see “Variable connectors” on page 303, below, to see their use and to see the connector
labeling functions.

Block connection Description Return


AlignConnection Adjusts the position of the second block (blockTo) to make the I
(long blockFrom, connection line between the two connectors specified straight.
long conFrom, long
blockTo, long
conTo, long verti-
cal)
GetConBlocks Returns the number of blocks attached to the connector. On I
(integer block, inte- return, the rows of intArray are used to index the connected
ger conn, integer blocks (if there are three blocks connected, there are three rows).

Functions
intArray[][2]) The first column of intArray contains the global block number of
a connected block, the second column contains the connector
number of that connected block. Rows and columns are indexed 0
to n-1. IntArray is declared as a dynamic array:
integer intArray[][2];
GetConHblocks Similar to the GetConBlocks() function, above, but returns a list I
(integer blockNum- of connected Hblocks. You can also start from a textblock or
ber, integer iConn, anchor point if you know the block number (connector numbers
array y[]) are zero for textblocks or anchor points).
GetConName (inte- Name of the connector. S
ger block, integer
conn)
300 Reference
Blocks and inter-block communications

Block connection Description Return


GetConnectedText- If block is positive, returns the block number of the named con- I
Block (integer nection (bypasses connector text blocks inside an Hblock and
block, integer goes out Hblock connector) connected to the connector conn of
conn) block number block. If block is negative, stay inside the Hblock
(can return the connector text block inside of an Hblock). Use the
BlockName() function to retrieve the text of the named connec-
tion.
GetConnected- Tells the type of connector connected to this connector. This is I
Type (name conn- useful for determining what is connected to a universal connector.
Name) You can read the result by number or their associated ExtendSim
constants:
13 value connector
14 discrete connector
15 universal connector
16 diamond connector
25 flow connector
GetConnected- This is similar to GetConnectedType(), except it refers to a global I
Type2(integer block number and conn is the ith connector (0 to n-1).
block, integer
conn)
GetConnection- Fills the color array (three integer element) with the hue, satura- I
Color (integer tion, and brightness (HSV) values for the color of the connection
blockFrom, integer line. The color selector is on page 401.
conFrom, integer
blockTo, integer Returns 0 for success or a negative value to indicate failure.
conTo, integer col- Note: As of ExtendSim 10, see instead GetConnectionEColor.
orArray[])
GetConnectionE- Returns the value for the EColor of the specified connection line. I
Color (integer The EColor selector is on page 401.
blockFrom, integer
conFrom, integer
blockTo, integer
conTo)
Functions

GetConnectorPosi- Returns the position of the specified connector in pixels. Array I


tion(integer block- should be defined as a four-row integer or real array (integer
Number, integer array[4]; or real array[4];), which on return from the
con, integer or real function call will be filled with the four values:
Array[4]) array[0] = top
array[1] = left
array[2] = bottom
array[3] = right
GetConnector- Returns the connector type of the specified connector. I
Type(integer block- 13 value connector
Number, integer 14 discrete connector
con) 15 universal connector
16 diamond connector
25 flow connector
ModL Functions 301
Blocks and inter-block communications

Block connection Description Return


GetConNumber Returns the Connector number of the connector of the specified I
(integer blockNum- name.
ber, string con-
NameStr)
GetEnclosingH- Used to find the connector index of the outer connector, given a I
blockCon(integer blockNumber and connector index inside the Hblock that is con-
blockNumber, inte- nected to the Hblock’s internal connector text. Returns connector
ger conNum) number of the enclosing Hblock’s outer conector or -1 if not an
Hblock.
GetIndexedCon- Gets the connector’s current value. For blocks with many similar R
Value(integer conn) connectors, use this in a loop instead of lots of statements like
“value[22]=con23In”. The connectors are indexed from 0; the
indexes are the same as the order of the connector names in the
connectors pane.
GetIndexedCon- This is same as GetIndexedConValue(), except it refers to a global R
Value2(integer block number.
block, integer
conn)
GetIntermediate- Returns number of connected dot blocks, text blocks, and connec- I
Blocks(integer tors between two blocks. Fills the array with information about
blockNum1, inte- the blocks. See GetConBlocks function for definition of the array.
ger conn1, integer If blockNum2 is negative, returns above information between a
blockNum2, inte- block (blockNum1) and the text block or connector text block
ger conn2, array) specified by blockNum2 (can be inside a hierarchical block).
GetNumCons(inte- Number of connectors on the block. I
ger block)
GetRightClicked- This function returns the conn number of the last connector that I
Con() was right clicked on. This function should be called in the CON-
NECTORRIGHTCLICK message.
IsConVisible(inte- Tests the specified connector for visibility. Returns TRUE if the I
ger blockNumber, connector is visible, FALSE otherwise

Functions
integer conn)
MakeFeedback- If feedBack is TRUE, this function causes ExtendSim to terminate V
Block(feedBack) the flow order search for this block. For multiple feedback cases,
this function prevents feedback from unexpectedly changing the
main flow simulation order. For an example, see the Feedback
block (Utilities library).
NodeGetCurrent- Returns the currently set value of the connected block connectors. R
Value(nodeIDIn- See NodeGetIDIndex(), below.
dex)
NodeGetIDIn- Returns the nodeID for a connected network of block connectors. I
dex(blockNumber, Each connected network has a unique nodeID, which can change
conNum) when additional block connectors are connected or the model is
reopened. The nodeID is equivalent to an index of a real value
that holds the set value of the connected connectors.
302 Reference
Blocks and inter-block communications

Block connection Description Return


SetConnection- Sets the color value of the specified connection line. See “Select I
Color (integer Color window” on page 401 for a description of the hue, satura-
blockFrom, integer tion, and value arguments. This function returns a TRUE if it suc-
conFrom, integer ceeds and a FALSE if it fails.
blockTo, integer
conTo, integer hue, Note: as of ExtendSim 10, see instead SetConnectionEColor
integer saturation,
integer value)
SetConnectionE- Sets the EColor value of the specified connection line. See I
Color (integer “Select Color window” on page 401. This function returns a
blockFrom, integer TRUE if it succeeds and a FALSE if it fails.
conFrom, integer
blockTo, integer
conTo, integer
EColorValue)
SetConnection- Sets the connection line thickness of the specified connection I
Thickness (long line.
blockFrom, long
conFrom, long Returns a zero for success or a non zero value for an error.
blockTo, long
conTo, long value)
SetConVisibil- Sets the visibility flag on an individual connector. This function V
ity(integer block- can be used by block developers to hide and show connectors
Number, integer based on choices the user has made in the dialog.
conn, integer visi-
ble)
SetIndexedCon- Sets the connector’s numerical value. For blocks with many simi- V
Value(integer conn, lar connectors, use this in a loop instead of lots of statements like
real value) “con23Out=value[22]”. The connectors are indexed from 0; the
indexes are the same as the order of the connector names in the
connectors pane.
SetIndexedConVal- This is same as SetIndexedConValue(), except it refers to a global V
ue2(integer block, block number.
Functions

integer conn, real


value)
SetSelectedCon- Sets the color value of all selected connections. See “Select Color I
nectionColor (inte- window” on page 401 for a description of the hue, saturation and
ger hue, integer value arguments. This function returns a TRUE if it succeeds, and
saturation, integer a FALSE if it fails.
value)
SetSelectedCon- Sets the color value of all selected connections. See “Select Color I
nectionEColor window” on page 401. This function returns a TRUE if it suc-
(integer EColor- ceeds and a FALSE if it fails.
Value)
ModL Functions 303
Blocks and inter-block communications

Variable connectors
These functions are used with a block’s variable connectors, and to interface them with the
standard connector functions. Note that all of the single connector functions, above, also work.
Where conn is specified in the argument list, use ConArrayGetConNumber() to find the actual
connector number on the block from the array owner and nth connector in the array. For exam-
ple, to send a message out of a variable connector, call ConArrayGetConNumber() to get the
actual number of the connector (its index). Then call SendMsgTo…() and instead of using the
actual connector name (e.g. FlowIn), use V7’s new feature and use the connector number you
got from ConArrayGetConNumber().
These connector functions use a block number and the connector name as a string so you can
use them to control other blocks.

Variable connectors Description Return


ConArrayChanged- When the user drags to get more or less variable connectors, the
WhichCon() block gets a CONARRAYCHANGED message. This function
returns the owning connector name, as a string, that is being
dragged. Use this string in the ConArrayGetNumCons() function
to get the actual number of connectors during the dragging opera-
tion.
ConArrayGetCol- Returns True if the specified connector is collapsed, or false if it is I
lapsed(integer not.
blockNumber, string
origConName)
ConArrayGetCon- Returns the connector number of the nth connector in this array. I
Number(blockNum- OrigConNameStr is the owning connector name as a string. Nth-
ber, Conn is the index of the array connector, starting from 0 for the
origConNameStr, owning connector, to the number of connectors in this array
nthConn) minus 1 for the last connector. The returned connector number
can be used in the other connector functions.
ConArrayGetDirec- Returns the array direction as: 0 top, 1 right, 2 bottom, 3 left. If I
tion(blockNumber, not an array connector or an error, returns -1.
origConNameStr)

Functions
ConArrayGetNth- Given a block connector number, returns the member index of its I
Con(conn) connector array (e.g. Given the block connector number of
ConIn[3] (could be 253), returns 3 meaning ConIn[3]). A -1
returned is an error.
ConArrayGetNth- Same as ConArrayGetNthCon except it has an additional argu- I
Con2(blocknum, ment to specify the connector on a different block.
conn)
ConArrayGetNum- Returns the number of connectors in this array. If there are no I
Cons(blockNumber, added array connectors, returns 1 for the original connector. Orig-
origConNameStr) ConNameStr is the owning connector name as a string.
304 Reference
Blocks and inter-block communications

Variable connectors Description Return


ConArrayGetOwn- Given a block connector number, returns the block connector I
erCon(conn) number of the owning (originating) connector of a connector
array (e.g. Given the block connector number of ConIn[3] (could
be 253), returns the block connector number of ConIn[0]). A -1
returned is an error.
ConArrayGetTotal- Returns the total number of connectors in this block, including I
Cons(blockNumber) array connectors. Used to prevent a dragged connector array from
adding too many connectors, causing the block to have more than
its limit of 255 connectors.
ConArrayGet- Returns the value of the nth connector of the array owned by Con- R
Value(ConName, Name. ConName can be the name of the connector without
nthConn) quotes or, new for V7, the index from 0 to numCons-1 as a con-
stant or variable (If the compiler detects a connector name, it
turns it into an index rather than evaluating its value).
ConArrayMsgFrom- Returns the index of the connector that received the message in an I
Con() array. For example, if the Con1In message handler received a
message, calling this function at the beginning of the message
handler would return which connector in this array (from 0 to
num-1) received the message.
ConArraySendMs- Sends a connector message to all connectors connected to the V
gToAllCons(integer specified Connector. See SendMsgToAllCons.
origConName, inte-
ger nthConn)
ConArraySendMs- Sends a connector message to input connectors connected to the V
gToInputs(integer specified Connector. See SendMsgToInputs.
origConName, inte-
ger nthConn)
ConArraySendMs- Sends a connector message to output connectors connected to the V
gToOutputs(integer specified Connector. See SendMsgToOutputs.
origConName, inte-
ger nthConn)
Functions

ConArraySetCol- Sets the collapsed state on the specified connector. True will col- V
lapsed(integer lapse the connector, and False will uncollapse it.
blockNumber, string
origConName, inte-
ger trueOrFalse)
ConArraySetNum- Call this to set the number of connectors in a variable connector (a V
Cons(blockNumber, 1 for NewNumCons means to only keep the original connector).
origConNameStr, If trueToIgnoreConnections is TRUE, the user can delete connec-
newNumCons, true- tors that have connections on them. If trueToIgnoreConnections is
ToIgnoreConnec- FALSE, connectors that have connections on them will not be
tions) deleted. This means that connections may prevent all of the
desired connectors from being deleted.
ModL Functions 305
Blocks and inter-block communications

Variable connectors Description Return


ConArraySet- Sets the value of the nth connector of the array owned by Con- V
Value(ConName, Name. ConName can be the name of the connector without
nthConn, value) quotes or, new for V7, the index from 0 to numCons-1 as a con-
stant or variable (If the compiler detects a connector name (not a
string), it turns it into an index rather than evaluating its value).
ConnectorLabels- Call this to get the connector labels for single connectors or con- I
Get(blockNumber, nector arrays. labelsStrArray is any kind of string array (local,
origConNum, static, or dynamic) that will contains all the labels used, one per
labelsStrArray[]) array element, which will allow up to n labels to be retrieved.
Each label is the ith connector in that connector array (0th for sin-
gle connectors). Returns the number of labels retrieved.
ConnectorLabels- Call this to set the connector labels for single connectors or con- V
Set(blockNumber, nector arrays. labelsStrArray is any kind of string array (local,
origConNum, num- static, or dynamic) containing all the labels needed, one per array
Labels, labelsStrAr- element. The labels can contain combinations of style information
ray[], position, hue, such as <biur> for bold, italics, underlined, right adjusted. Posi-
saturation, value) tions are: 0 top, 1 right, 2 bottom, 3 left.

Connector tool tips


The System message ConnectorToolTip is sent to the block when the cursor hovers over a con-
nector. In that message handler, the connector tool tip functions (below) will allow you to cus-
tomize and access the tooltip that will appear.

Connector tool tips Description Return


ConnectorToolTip- Gets the current string value of a connector tool tip from a block S
Get(integer block- and connector. This is useful if you want to show what block your
Number, integer block is connected to, like the batch and select blocks.
connectorIndex)
ConnectorToolTi- Allows you to set the string that will be displayed. If the replace V
pSet(stringstring, flag is true, the default string generated by ExtendSim will be
integer replace) replaced, if it is false, this string will be appended to the default

Functions
string.
ConnectorToolTip- When the ConnectorToolTip message is received, this function I
Which() returns the connector index of the connector the cursor is over.
This function is also used in the ConnectionMake message to
return the connector being connected.

Dialog items
These functions work with a block’s dialog items and can be used to get and set values from
dialog items in other blocks, as well as change dialog item colors, create popup menus, hide
and show items, etc.
The functions in this list that include a global block number in their argument list can affect
any block in the model, including the calling block if its own block number (from the
MyBlockNumber() function) is used.
306 Reference
Blocks and inter-block communications

☞ Block controls (switch, slider, and meter) can be set or changed via the Get/SetDialogVariable
functions or poke/request functionality just the same way other types of blocks can. In the case
of the block meter, this is easy to recognize, as this control has a dialog, and therefore all the
pieces that you need for setting and getting the values are available. (Block number, and dialog
item name.) In the case of the slider and the switch it’s not so obvious, as these controls don’t
have dialogs, and therefore the dialog item name is not readily available. The names for these
dialog items follow the pattern of the meter, and therefore are as follows:
• Switch: value – This is whether the switch is on, or off, and just takes a value of 0, or 1.
• Slider: value – The current value of the slider. (The position of the thumb.)
• lower – The value of the lower bound of the slider.
• upper – The value of the upper bound of the slider.
☞ For additional formatting options, see “Formatting/interactivity using column and parameter
tags” on page 321. These facilitate both specialized formatting and mouse-interactivity with
parameters and data tables. Also see “Block data tables” on page 312, “Dynamic text items” on
page 320, and “Dynamic linking” on page 317.

Block dialog items Description Return


AppendPopupLa- This function appends the specified string onto the labels associ- I
bels(string vari- ated with the named popup menu. Popup menu labels can total up
ableNameStr, string to 5100 characters. This function is the method for adding menu
theLabels) labels. VariableNameStr is the dialog item name as a string or in
quotes. See SetPopupLabels() below.
CreatePopupMenu Creates a Popup at the last location the user clicked. This function I
(string string1, can be used in conjunction with the on dialogClick message han-
string string2, inte- dler, the whichDialogItemClicked function, and the whichDT-
ger initialSelection) CellClicked function to create a popup menu that appears on a
dialog item, or data table cell in response to a user’s click. See the
code of the on dialogClick messagehandler of the Activity block
(Item library) for an example of how to use this function. Also see
PopupMenuArray(), below.
DialogHasEmbed- Returns the dialog item name if the specified block contains any S
dedObject (integer embedded object dialog items in its dialog. This function will
Functions

blockNumber) return an empty string "" if there are no dialog items of this type
in the dialog.
DialogItemVisible Returns a true value if the specified dialog item is visible. If the I
(integer blockNum- Clones value is a one (TRUE) this function checks to see if any
ber, string variable- clones of the specified item are visible; otherwise it checks to see
NameStr, integer if the primary item is visible.
clones)
DIGetID(integer Returns a dialog item ID number. This is used in the LINKCON- I
blockNumber, TENT and LINKSTRUCTURE message handlers to help identify
string name) which dialog item is getting the message.
DIMoveBy(integer Offsets the dialog item by the values of the y and x parameters. I
blockNumber,
string name, inte-
ger y, integer x)
ModL Functions 307
Blocks and inter-block communications

Block dialog items Description Return


DIMoveTo(integer Moves the specified dialog item to the y and x location specified I
blockNumber, by the top and left variables.
string name, inte-
ger top, integer
left)
DIMsgNum- Returns the message number associated with a dialog item. Used I
ber(integer block- to send a dialog item message to a block.
Number, string
name)
DIPopupBut- Changes the behavior of the specified popup menu so that it will I
ton(integer block- not show the typical popup behavior when it is clicked, but will
Number, string instead behave like a button (Sending a message to the MODL
name, integer code, but not displaying a popup menu). This is used when the
behavesAsButton) block developer wants something that looks like a popup menu,
but has a button’s behavior.
DIPosition- Gets the position of a dialog item specified by blockNumber, and I
Get(integer block- dialogItemName. The coordinates of the dialog items location
Number, string will be placed into the integer array position. Position needs to be
name, integer array declared as:
position) integer array[4];
DIPosition- Resets the location of the dialog item back to the position and size I
Home(integer defined in the structure.
blockNumber,
string name)
DIPositionSet(inte- Sets the position of the specified dialog item. This function also I
ger blockNumber, includes the bottom and right arguments so you can change the
string name, inte- displayed size of the dialog item as well.
ger top, integer left,
integer bottom,
integer right)
DisableDialogItem Disables, or enables the specified dialog item. V
(string variable-
Functions
NameStr, Integer
TRUEFALSE)
DisableDialog- Disables the specified Dialog Item. This function differs from the I
Item2(integer DisableDialogItem() function in that it takes a block number
blockNumber, argument so you can disable a dialog item from a remote block.
string name, inte-
ger disableEnable)
DISetFocus(inte- Sets the focus on the specified dialog item. Returns 0 for success I
ger blockNumber, or a negative value to indicate failure.
string dialogItem-
Name)
308 Reference
Blocks and inter-block communications

Block dialog items Description Return


DISetParent
(blockNum, dialog-
ItemName, dialog-
ItemName)
DITitleGet(integer Returns the string title of the dialog item. For dialog items like S
blockNumber, radio buttons and check boxes, the title is the text that appears on
string dialogItem- the dialog. Use this function to retrieve the string if it has been set
Name) by the function DITitleSet.
DITitleSet(integer Sets the title of a dialog item. Useful for Dialog items like radio I
blockNumber, buttons and checkboxes where there is no other way to change the
string name, string title of the dialog item on the fly.
title)
GetDialogColors Copies all the color information from the dialog colors into the I
(integer blockNum- color array. Used to save all the colors in a dialog in on dialog
ber, integer HSV- close. The HSVColorArray is declared as a dynamic array:
ColorArray[][3]) integer HSVColorArray[][3];
GetDialogItem- Gets a color value associated with the dialog item. I
Color (integer
blockNumber, For ExtendSim 10 or later, use the GetDialogItemEColor func-
string variable- tion.
NameStr, integer
HSVColorAr-
ray[3])
GetDialogItemE- Returns the EColor value of the color of the dialog item. I
Color (long block-
Name, string See “EColors” on page 401 for more information.
dialogItemName)
GetDialog- Returns TRUE if which qualities are true for the dialog item: I
ItemInfo(integer 0: exist, 1: hidden, 2: enabled, 3: display only.
blockNumber, Returns the values for: 4: dialog item type, 5: rows, 6: columns, 7:
string variable- width, 8: height.
NameStr, integer Dialog item types are: 1: button, 2: checkbox, 3: radiobutton, 4:
Functions

which) meter, 5: parameter, 6: slider, 7: datatable, 8: edittext, 9: stattext,


12: switch, 13: stringtable, 14: plotpane, 16: popupmenu, 17:
embedobject, 18: dynamic text, 19: textframe, 20: calendar, 21:
edittext31
GetDialogItemLa- Returns the nth item label. For example, the nth item on a popup S
bel (integer block- menu or the nth column header in a data table. Returns an empty
Number, string string "" if the wrong type of item or no label is found.
variableNameStr,
integer n)
ModL Functions 309
Blocks and inter-block communications

Block dialog items Description Return


GetDialo- Returns a list of the dialog variables in the specified block. Both
gNames(integer nameArray and typeArray are dynamic arrays. This function
block, string name- returns the number of items in the target block’s dialog. For each
Array[], integer item in the block’s dialog, the string array will contain the name
typeArray[]) of the dialog item and typeArray will contain the type of dialog
item. Values for typeArray are:
1:Button, 2:Check Box, 3:Radio Button, 4:Meter,
5:Parameter, 6:Slider, 7:Data Table, 8:Editable Text, 9:Static
Text, 12:Switch, 13:Text Table, 16:Popup Menu, 17:Embed-
ded Object, 18:Dynamic Text, 19:Text Frame, 20:Calen-
dar, and 21:Editable Text31 (31 characters)
GetDialogVariable Returns the string value of the named variable (variableNameStr S
(integer blockNum- in quotes or string). If the variable is a numeric parameter or a
ber, string variable- control (such as a checkbox, slider, and so on), you would call
NameStr, integer StringToReal to convert the returned string to a numeric value.
row, integer col) The variable can be any dialog item, static variable, global vari-
able, or dynamic array. Row and col apply to the cells of a data
table or text table. For Sliders or Meters, row must be zero and col
is 0 for the minimum, 1 for the maximum, and 2 for the value.
Row and col are ignored for other types of items.
☞ See also the GetStaticVariable function and the GetVariable-
Numeric function which should be faster for querying non-
string values.
GetDraggedClone- If you put this function call in a DRAGCLONETOBLOCK mes- I
List (integer block- sage handler, it returns the number of clones dragged onto a
Nums[], string block. It also fills the dynamic array parameters with the block
variableNames[]) numbers and variable names of the clones so you can get and set
their values with GetDialogVariable() and SetDialogVariable()
functions. This function is used in the Optimizer block (Value
library).
getStaticVari- Similar to GetDialogVariable, this function allows the user to S
able(integer block- explicitly retrieve the value of a static variable.
Functions
Num, string
staticVariable- GetDialogVariable will already do this, but GetDialogVariable
Name, long row, looks for any dialog variable with the specified name first.
col) The advantage of this function is speed. If you know whether you
are looking for a dialog variable or a static variable, you can call
the appropriate function and the function will not have to look for
the other kind of variable.
GetSystemColor Gets the system colors so that they can be matched in a dialog. I
(integer whichPart, Returns whichPart:
integer which- 1:R, 2:G, 3:B, 4:H, 5:S, 6:V, 7:xxBBGGRR
Color) whichColor:
0:Dialog BackGround, 1:ToolTipColor, 3:ScrollBar color
310 Reference
Blocks and inter-block communications

Block dialog items Description Return


GetVariableNu- Similar to GetDialogVariable, but returns a numeric (real) value. R
meric (integer Should be faster for querying non-string variables.
blockNum, string
name, integer row,
integer col)
HideDialogItem Hides the named dialog item if hideShow is TRUE. I
(string variable- DialogNameStr is the dialog item name as a string or in quotes.
NameStr, integer Returns 0 if it succeeds.
hideShow)
HideDialogItem2 Set the hidden/shown status of the item. See the HideDialog- I
(integer blockNum- Item() function, with the addition of the block number argument,
ber, string name, which allows you to call the function from outside a block.
integer hideShow) Returns 0 if it succeeds.
LastSetDialogVari- Returns the last string value that was set by SetDialogVariable. S
ableString() This is useful if one is setting the value of a dialog item like a
popup menu, where the stored value is not the value that the
popup menu contains, but rather an additional string variable. In
this case, using the WhoInvoked() function, below, and this func-
tion you can have the code of the block change the correct string
for the dialog item, so the SetDialogVariable function will react as
the user expects, even though the data is not directly contained in
the dialog item.
OpenAndSelectDi- Obsolete. Please see OpenAndSelectDialogItem2(), just below V
alogItem (integer this function. This version of the function did not have the row
blockNumber, and column indexes to select a cell in a data table.
string variable-
NameStr)
OpenAndSelectDi- Opens the block's dialog, highlighting (selecting) the dialog item V
alogItem2 (integer corresponding to varName. If the item is a data table, row and col
blockNumber, are the indexes. Row and col are ignored if the item is not a data
string variable- table. If row and col are -1, selects the entire data table.
NameStr, integer
row, integer col)
Functions

PopupCanceled() Returns whether or not the last popup menu was canceled. This I
can be called immediately after a ‘flying’ popup menu has been
created, to determine if the user canceled the popup menu action
or not. Canceling would be clicking off the popup menu, without
making a selection.
PopupItem- This function parses the string that is passed in, and removes the S
Parse(itemString) special characters that are used in certain dialog item contexts.
Specifically, it removes the formatting notation (e.g. <RB> for
right adjusted, bold), characters that are user for formatting, and
returns the stripped string.
ModL Functions 311
Blocks and inter-block communications

Block dialog items Description Return


PopupMenu- Appends the contents of the string array array to the popup menu I
AppendAr- specified by dialogItemName.
ray(string
dialogItemName,
stringArray array)
PopupMenuArray This function creates a flying popup menu based on the strings in I
(string theArray[], theArray, maximum 20 strings (5100 characters total). Other than
integer initial- the fact that an array of strings is passed in instead of separate
Value) strings, it’s exactly the same as the CreatePopupMenu function.
SetDialogColors Sets all the colors of the dialog items at once. Usually used with I
(integer blockNum- the array from GetDialogColors(), above.
ber, integer HSV-
ColorArray[][3])
SetDialogItem- Sets a color value associated with the dialog item. Some items V
Color (integer will not redraw with this color, but instead have their color
blockNumber, defined by the operating system settings.
string variable-
NameStr, longAr- Note: For ExtendSim 10 or later, use the SetDialogItemEColor
ray HSVValues) function.

SetDialogItemE- Sets the color of the dialog item based on the passed in EColor I
Color (long block- value.
Name, string
dialogItemName, See “EColors” on page 401 for more information.
long value)
SetDialogVariable Sets the value of the named variable to the given numeric or string V
(integer blockNum- value. The variable can be any dialog item, static variable, global
ber, string variable- variable, or dynamic array. Row and col apply to the cells of a
NameStr, string data table or text table. For Sliders or Meters, row must be zero
value, integer row, and col is 0 for the minimum, 1 for the maximum, and 2 for the
integer col) value. Row and col are ignored for other types of items.
☞ See also SetVariableNumeric, which should be faster when

Functions
setting non-string values.
SetDialogVariable- Same as SetDialogVariable function, but doesn’t send a dialog V
NoMsg(integer item message to the block.
blockNumber,
string variable-
NameStr, string
value, integer row,
integer col)
SetPopupLa- Sets the named popup menu items to theLabels string. The menu V
bels(string vari- items should be separated by semicolons (;). This function is sim-
ableNameStr, string ilar to SetDataTableLabels in that the changes made by this call
theLabels) are not permanent within a block's dialog. Changes made by this
call are permanent, however, for cloned copies of popup labels.
VariableNameStr is the dialog item name as a string or in quotes.
See AppendPopupLablels() above to add more labels.
312 Reference
Blocks and inter-block communications

Block dialog items Description Return


SetVariableNu- Similar to SetDialogVariable, except it takes a numeric (real) V
meric (integer value. Should be faster when setting non-string values
blockNum, string
name, real value,
integer row, inte-
ger col, integer
msg)
SetVisibilityMoni- Turns on monitoring of the visibility of a dialog item. This sets a I
toring (integer flag on a dialog item that makes it send a message to the block
blockNumber, code (DIALOGITEMREFRESH) when the dialog item (Or one
string variable- of its clones) becomes visible. This is useful if you have a dialog
NameStr, integer item whose redraw includes some time-consuming calculation
monitor) and you want to be able to turn off the calculation unless the dia-
log item is visible.
WhichDialogItem() Returns the name of the current dialog item in certain contexts. I
This function can be used in the CELLACCEPT, DATATA-
BLERESIZE, DATATABLESCROLLED, DIALOGITEMTOOL-
TIP, DIALOGCLICK, or dialog item name message handlers.
WhoInvoked() Determines the source of the invocation of the current message I
handler. Currently implemented in two cases:
1) Called in a dialog item message handler, this function will
return a 1 if the message handler was invoked from SetDialog-
Variable, or a 0 if the handler was invoked through user interac-
tion.
2) Called in OpenModel, this function will return a 2 if the Open-
Model handler is being executed from the placement of an
Hblock, or a 0 if it's being called because the model containing
the block is being opened.

Block data tables


These functions allow ModL code to control the display of data in block dialog data tables. In
the following functions, DataTableName is the name of the dialog data table from which you
want to retrieve the selection; this name needs to be either a string variable or a string in
Functions

quotes.
☞ Starting in ExtendSim 7, you must access all data tables using their dialog item variable name.
Even dynamic data tables need to be accessed using the dialog variable name. This was not the
case in Extend 6 or earlier, but is a ModL compiler change that is necessary to allow data tables
to transparently access linked database or global array data, and to be variable column. Using
the dynamic array name will not allow linked or variable column data tables to work.
☞ If you need large data tables, see the Dynamic data table functions below.
Variable column data tables
The DynamicDatatableVariableColumns function, and the supporting functions that have been
built for it, allow the creation and use of a data table with both variable rows and variable col-
umns. The starting point is a call to the DynamicDatatableVariableColumns function which
will link a dynamic array to a data table, in much the same way as the DynamicDatatable func-
ModL Functions 313
Blocks and inter-block communications

tion, with the addition of allowing the user to define the number of columns that the table sup-
ports.
Each time you want to change the number of columns in the data table, you call Dynamic-
DataTableVariableColumns again with the new number of columns. The internal implementa-
tion of this construct is basically that the link between the data table and the dynamic array
contains the information about the number of columns. This means that you cannot use the
dynamic array variable name to refer to the data, as the dynamic array still has the original
definition of how many columns it has. To reference your data with the variable number of col-
umns, you need to refer to it using the data table variable name, as the data table will use the
information in the link to determine how many columns it has. See “OLE/COM (Windows
only)” on page 253 for OLE functions that fill variable column data tables.
Dynamic data table resizing
The following functions are designed to be support functions for dynamic data table resize
functionality. This functionality is implemented partially through block code, and partially
through the ExtendSim Application. The basic functionality, as seen on dialog boxes in both
the Item and Value libraries, is a button on the lower right hand corner of the data table that can
be clicked popping up a dialog that allows the user to specify the resizing options for the data
table. The application level implementation is the drawing and behavior of the button on the
data table. The presence or absence of the button can be controlled from the block code via the
DTGrowButton function described below. When the button is clicked, the block will receive a
DATATABLERESIZE message. The code of this message handler is where the majority of the
block code controlling the resizing will be executed. Normally the code in this message han-
dler will first be a call to NumericParameter, or NumericParameter2 to determine the desired
resizing of the table, followed by the necessary code to implement the resizing. See the Vari-
able Columns data table section above. See the blocks in the Value and Item libraries for
examples of this code.
Data table linking
Data tables can be linked to global arrays or an ExtendSim database by the user clicking the
Link button at the lower left corner, or using the linking functions below. When the data or
structure that they are linked to changes, LINKCONTENT or LINKSTRUCTURE messages
are sent to individual blocks that are subscribed to an ExtendSim database or global array. See
“Dynamic linking” on page 317.
☞ Starting in ExtendSim V, you must access all data tables using their dialog item variable name.
Even dynamic data tables need to be accessed using the dialog variable name. This was not the
Functions
case in Extend 6 or earlier, but is a ModL compiler change that is necessary to allow data tables
to transparently access linked database or global array data, and to be variable column. Using
the dynamic array name will not allow linked or variable column data tables to work.
Formatting individual columns
For additional formatting options, see “Formatting/interactivity using column and parameter
tags” on page 321. These facilitate both specialized formatting and mouse-interactivity with
data tables.
314 Reference
Blocks and inter-block communications

Block data tables Description Return


AppendDataTable- Appends another string of labels to the data table labels list of the I
Labels (string data table DTname.
DTname, string
theLabels)
DisableDTTabbing Disables or enables the tab key functionality for the specified data I
(integer blockNum- table.
ber, string
DTname, integer
disableDT)
DTGrowButton Shows/hides the resize/grow button on the specified data table. I
(integer blockNum- This button is hidden by default, as block code is necessary for the
ber, string resizing functionality.
DTname, integer
showButton)
DTHasDDELink Returns true if the specified data table has an IPC advise link, or a I
(integer blockNum- Paste link, associated with it.
ber, string
DTname)
DTPaneFixed Changes the behavior of the specified data table, setting or unset- I
(integer blockNum- ting its internal ‘fixed’ flag. By default this flag is off, but if it is
ber, string name, turned on, the data table will retain its width when the number of
integer fixed) columns in the data is reduced, rather than resizing smaller, as it
can do in the default case.
DTResizeToCols Forces the data table to resize to the width of the resized columns. I
(integer block- This function will not resize the columns, but instead will resize
Num, string the data table object to the width of the current column size.
DTName) Returns a zero for success or a non zero value for an error.
DTRowFontSize Returns the size used for the font within the data table. This will R
(integer block- change if the height is modified either within the structure of the
Num, string block or via the DTRowHeightSet function.
DTName)
Functions

DTRowHeightSet Sets the height of the rows for a data table object. This function I
(integer block- overrides the row height value set in the structure for a data table.
Num, string
DTName, integer All the rows of the data table will be set to the same height.
height) Returns a zero for success, or a non zero value for an error.
DTToolTi- In conjunction with the DataTableHover message handler dis- V
pSet(string caption- cussed on page 219, this function allows you to show custom tool
String) tips when the cursor hovers over a data table.
DynamicDataT- This function attaches a dynamic array to a dialog data table. This I
able(integer block- allows dynamically resizable data tables, and the ability to change
Number, string what data is displayed in a data table without recopying the data.
dataTableName, You can attach the array to the data table at any time, but it will
array dynamicAr- need to be reattached (dynamicDataTable will need to be called)
rayName) each time that the dynamic array is resized.
ModL Functions 315
Blocks and inter-block communications

Block data tables Description Return


DynamicDataT- Has the same behavior as the dynamicDataTable function, with I
able2(integer the exception that it can be called from an outside block, and
blockNumber, doesn't have to be called from within the block that contains the
string dataTable- array. Note that the arrayName argument is the name of the array
Name, string array- as a string, not the array name itself.
Name)
DynamicDataT- Similar to DynamicDatatable, with the addition of adding the I
ableVariableCol- specification of how many rows and columns the resulting data
umns(integer table will have. It will correct the data to work with a new number
blockNumber, of columns. You must use the variable name of the data table, not
string dataTable- the dynamic array, to access the data.
Name, array y, inte-
ger rows, integer
columns)
DynamicDataT- Has the same behavior as the dynamicDataTableVariableColumns I
ableVariableCol- function, with the exception that it can be called from an outside
umns2 (integer block, and doesn't have to be called from within the block that
blockNumber, contains the array. Note that the arrayName argument is the name
string dataTable- of the array as a string, not the array name itself.
Name, string array-
Name, integer
rows, integer col-
umns)
GetDataTableSe- IntegerArray is a four element array declared as integer inte- I
lection(string gerArray[4]. On return from the function, integerArray will
DataTableName, contain the selection information in the following format:
integer integerAr- integerArray[0] -- top row
ray) integerArray[1] -- bottom row
integerArray[2] -- left column
integerArray[3] -- right column
The integer value returned from the function will be the same as
integerArray[0] if there is a valid selection. The value will be a -2
if there is no correct selection, and a -1 if an error of some other
type occurred (usually an invalid DataTableName.)
GetDTOffset (inte- Returns the offset (How many rows or columns the table has been I Functions
ger blockNumber, scrolled) for a data table. If row is true, it returns the row offset,
string DTname, otherwise the column offset. If clone is true, it returns the value
integer clone, inte- for the first clone of the item found.
ger row)
RefreshDatatable- This function will redraw the specific cells of the named data I
Cells(integer table. This needs to be used in conjunction with the dynamic data
blockNumber, tables defined by the function above, as they will not automati-
string dataTable- cally update the data displayed during a simulation run when the
Name, integer star- dynamic array is modified
tRow, integer
startCol, integer
endRow, integer
endCol)
316 Reference
Blocks and inter-block communications

Block data tables Description Return


ResizeDTDur- This function will allow you to inform ExtendSim that a data I
ingRead(string table is now a different size than it was in an earlier version. This
name, integer old- should only be called in the BlockRead message handler, and is
Rows, integer old- most useful when used with the GetFileReadVersion function to
Cols) inform ExtendSim when a Data Table has been redefined. (See
GetFileReadVersion for more information.) OldRows and Old-
Cols will contain the original size of the data table.
ScrollDTTo(inte- Scrolls the named data table to the indicated row and column. (0 I
ger blockNumber, successful, 1 failed)
string name, integer
row, integer col)
SetDataTable- Sets a label to be displayed in the upper left-hand corner of the I
CornerLabel (string data table. This area of the table is blank by default. The function
datatablename, will return a zero if the call succeeded, and a value of one if there
string15 label) was an error (most likely an incorrect DataTableName).
SetDataTableLa- The LabelString variable will be used as a replacement string for I
bels (string DataT- the column header string of the specified data table. The format
ableName, string for this string is the same as that used in the dialog editor when
LabelString) creating or modifying a data table dialog item. The function will
return a zero if the call succeeded, and a value of one if there was
an error (most likely an incorrect DataTableName). Note: The
change made by this call is not a permanent change within the
block’s dialog, you will need to retain the new string in a variable
in the block, and call this function multiple times. See the code of
the Information block (Item library) as an example of using this
function. The change made by this call is permanent for clones of
data tables.
SetDataTableSelec- This function selects the cells in the named data table or text table. V
tion(name, star- If editCell is TRUE, this function sets up the first cell for entering
tRow, startCol, data.
endRow, endCol,
editCell)
SetDTColumn- Sets the specified column in the named data table to the specified I
Functions

Width(integer width. Please note that column number for this function is zero
blockNumber, based starting from the title column, to allow reference to the title
string name, integer column. This means that the first column with data in it is column
column, integer one, unlike most other functions that reference data table col-
width, integer umns.
doClones)
SetDTRowStart Sets the named data table to have its row numbers start at the indi- I
(integer blockNum- cated value. (i.e the first row number, normally zero, will be row-
ber, string name, Start) (0 successful, 1 failed)
integer rowStart)
ModL Functions 317
Blocks and inter-block communications

Block data tables Description Return


SortArrayVariable- Sorts the specified array, using the numCols argument to define I
Columns(short how many columns the array to be sorted contains.
hNum, array datat-
ableName, integer
numCols, integer
numRowsToSort,
integer keyColumn,
integer increase,
integer sortStrin-
gAsNumbers)
StopDataTableEdit- Immediately stops the currently selected data table from being V
ing() edited. A common use would be to call this function in response
to a click on the data table, preventing the user from editing the
cell but allowing selection to occur.
WhichDTCell(inte- Returns the Row or Column that is currently active. If rowCol is I
ger rowCol) TRUE this function returns the Column, otherwise it returns the
row. This function can be called in the CELLACCEPT, DIALOG-
ITEMTOOLTIP, DIALOGCLICK, or dialog item name message
handlers.

Dynamic linking
Dynamic linking creates a link between a dialog item (data table or parameter) and a data
source (ExtendSim database or global array). This is a very powerful feature because the links
are live and dynamic—they update instantly when there is a change in the data source.
The ExtendSim user interface allows the modeler to create dynamic links just by right-clicking
on a parameter or clicking the Link button at the lower left of a data table. In addition, Extend-
Sim provides functions, described below, that allow control over how the links are to be cre-
ated and controlled.
For database linking using scripting see the DBDatatable function on page 375 and the DBPa-
rameter function on page 376. For global array linking using scripting, see the GADatatable
function on page 380 and the GAParameter function on page 383. Also see “Database func-
tions” on page 354 and “Global arrays” on page 378.
To simply register a block so that it will be notified if there was a database change, see “Regis-
Functions
tered blocks” on page 111 and “Linking and notification” on page 374.
☞ Starting in ExtendSim 7, you must access all data tables using their dialog item variable name.
Even dynamic data tables need to be accessed using the dialog variable name. This was not the
case in Extend 6 or earlier, but is a ModL compiler change that is necessary to allow data tables
to transparently access linked database or global array data, and to be variable column. Using
the dynamic array name will not allow linked or variable column data tables to work.
318 Reference
Blocks and inter-block communications

Dynamic linking Description Return


DBDatatable(integer Link a data table with an ExtendSim database table. I
blockNumber, string
datatableName, inte- NOTE: This is the same function as listed on “Linking and noti-
ger databaseIndex, fication” on page 374; we just copied it here for your conve-
integer tableIndex, nience DK.
integer showField-
Names)
DBParameter(integer Link a parameter with an ExtendSim database cell. I
blockNumber, string
dialogItemName, inte- NOTE: This is the same function as listed on “Linking and noti-
ger databaseIndex, fication” on page 374; we just copied it here for your conve-
integer tableIndex, nience DK.
integer fieldIndex,
integer recordIndex)
DILinkClear(integer Clears a link from the specified link if it has one. I
blockNumber, string
dialogItemName)
DILinkInfo(integer Returns linking information about the specified dialog item. I
blockN, string dialog- Values for which:
ItemName, integer 0 : Link type returns 0: no link, 1: global array, 2: Database, 3:
which) dynamic array
1: DB Index returns the index of the database for the link (if it's
a DB link)
2: table/array index returns the value of the index
3: returns column index
4: returns row index
5: user link: if the link was created by a user vs. a function
7: returns dialogItemID to identify a dialog item. See DIGetID
function description.
10: ReadOnly: return value is true/false
DILinkingDis- This function controls if the specified data table or parameter I
abled(integer blockN, will allow linking. By default each data table has a link button
string dialogItem- in its lower left-hand corner and calling this function will allow
Functions

Name, integer dis- the block developer to hide this button. This should have the
ableIfTrue) added effect of disabling the link menu command. Return a neg-
ative error number or zero if no error.
ModL Functions 319
Blocks and inter-block communications

Dynamic linking Description Return


DILinkModify(inte- This function is used to modify flags associated with a specific I
ger blockNumber, dialog item link. The ‘which’ argument specifies which flag will
string dialogItem, be set; value specifies what the value should be set to.
integer which, integer which:
value) 0: ReadOnly. Set value to TRUE to make a link ‘read-only’
1: InitMsgs. Set value TRUE so link will get messages during
INITSIM.
2: SimMsgs. Set value TRUE so link will get messages during
SIMULATE.
3:FinalMsgs. Set value TRUE so link will get messages during
FINALCALC.
4: AnyMsgs. By default it is set to False, so you get messages
when the linked data changes. If set to True, the block will not
get any messages at all. There is no corresponding checkbox in
the dialog; this is only available by code.
5: UserLink. Set value TRUE so link was created by the user
interface (TRUE), or a MODL function call (FALSE).
11: ShowFieldNames Set value TRUE so link uses the field
names for the header rows in the data table.
DILinkMsgs(integer Turns on and off the sending of messages associated with link- V
sendMsgs) ing. This function should be used carefully, and should always
be turned back on when the code has completed. This will dis-
able all messages sent to any blocks that have dialog items
linked to any data source, and many blocks will function incor-
rectly if these messages are disabled. The primary reason to use
this function would be if you are making many changes to a data
source, and don’t want things to be overwhelmed with too many
messages.
DILink- Sends update messages to all the dialog items linked to this data I
SendMsgs(integer source. In the Global Array case, the DBIndex is ignored. If
dataSourceType, inte- you want to send messages to all dialog items linked to a whole
ger DBIndex, integer table, pass in –1 for the fieldIndex, and –1 for the rowIndex.
tableIndex, integer dataSourceType:
fieldIndex, integer 1: Global Array

Functions
recordIndex) 2: Database
320 Reference
Blocks and inter-block communications

Dynamic linking Description Return


DILinkUp- Should be called in the LinkStructure, LinkContent, or dialog I
dateInfo(integer item name message handlers. Returns information about which
which) link changed and what the change was. Values for which:
0:Link type (returns 0:no link, 1:global array, 2:database, 3:
dynamic array)
1:DB Index returns the index of the database for the link (if it's a
DB link)
2:table/array index returns the value of the index
3:returns column index
4:returns row index
5:what changed (see below for values)
6:number of rows or columns changed
7:dialog item ID
8: the block number of the block that changed the data
9: Returns True (1) if link messages are enabled; otherwise
returns False (0).
10:returns the index of the database being imported or 0 if
no database is being imported.
A which value of 5 (what changed) returns 1:data changed,
2:field inserted, 3:field deleted, 4:field renamed, 5:record
inserted, 6:record deleted, 7:table or GA deleted, 8:table or GA
renamed, 9:DB deleted, 10:DB renamed, 11:link created,
12:link modified, 13:link cleared, 14:DB replaced via DBData-
baseImport(), 15:GA resized, 16:table inserted, 17:field proper-
ties modified, 18:field moved, 19:table sorted, 20:Table
Properties modified, 21:record ID modified.
DILinkUpdat- This companion function to DILinkUpdateInfo returns a string S
eString(integer which) containing information about a change to the link status. This
can be called in the same message handlers as DILinkUp-
dateInfo.
which values:
0 : DialogItemName The name of the dialog item associated
with the link.
1 : Changed Name. If whatChanged is field or table renamed,
for example, the changed name string will be the old name of
Functions

the field or table.


DTHideLinkBut- This function is still available however, there is one that is more I
ton(integer blockN, complete. See DILinkingDisabled(), above, that works for both
string DTname, inte- data tables and parameters. See that function for a description.
ger hideButton)

Dynamic text items


Dynamic Text items are a new type of dialog item that supports up to 32000 characters of text.
They are useful where the 255 character limitation of editable text items is a hindrance. The
text is stored in a string dynamic array, declared:
string dynTextArray[];
ModL Functions 321
Blocks and inter-block communications

For an example of how to use dynamic text items, look at the Equation block (Value library).

Dynamic Text Description Return


DynamicTextAr- Returns the dynamic array index. Used to link the Dynamic Text I
rayNumber (string Item to the correct dynamic array. For example:
dynamicTextAr-
ray[]) myDTextItem = DynamicTextArrayNumber(dyn-
TextArray);
where dynTextArray is declared as above.
DynamicTextIs- Returns a true if the text item is dirty (the user has typed text into I
Dirty (integer the dynamic text item or changed its contents in some way).
blockNumber,
string name)
DynamicTextSet- Sets the dirty flag to ‘dirty’ (TRUE or FALSE) on the specified I
Dirty (integer dynamic text item. Useful to set dirty if the block performs a text
blockNumber, changing operation outside of the user editing the text.
string variable-
NameStr, integer
dirty)
StrFindDynamic Similar to the StrFind() function, except it searches a dynamic I
(string dynamic- text array.
TextArray[], string
findStr, integer cas-
eSens, integer diac-
Sens, integer
wholeWords)
StrFindDynamic- Similar to the StrFind() function, except it searches a dynamic I
StartPoint (string text array. startPoint is the starting character index to search from,
dynamicTextAr- starting at zero.
ray[], string findStr,
integer caseSens,
integer diacSens,
integer whole-
Words, integer
Functions
startPoint)
StrReplaceDy- Similar to the StrReplace function, except it replaces text in a
namic (string dynamic text array.
dynamicTextAr-
ray[], integer start,
integer numChars,
string replaceStr)

Formatting/interactivity using column and parameter tags


Column tag and Parameter tag functions provide a great amount of control over the display and
formatting of certain dialog items. Column and parameter tags allow you to put strings, check-
boxes, buttons, dates, popup menus, the infinity character, and so forth into a parameter field or
the cell of a data table. They can also be used to hide or disable a column or parameter.
322 Reference
Blocks and inter-block communications

The data table and parameter dialog items check which column tags have been set, and draw
their data, or respond to clicks appropriately.
☞ The Data Init block (Value library) is an example of using column tags.
The basic mechanism for setting a param tag, or column tag, is to call either the DIParam-
TagSet or the DTColumnTagSet function. Column and param tags are not saved when the
model is closed, so the tags are commonly reset in the OpenDialog and CloneInit message han-
dlers.
If you set a column tag that has a value higher than 99, it will be stored as a HeaderTag. Head-
erTags are stored independently from column tags, and will store a behavior for the header for
that column, not for the individual cells in the table. (See Header tags below for more informa-
tion.)
In the data table case, column values start at zero, with zero referring to the first column after
the row column. Each column has four pieces of information that can be associated with it:
Two integer values, the tag itself, a tagOption value, and two string values, the TagString1 and
TagString2. ParamTags for parameters have just one number, the paramTag, and the same two
strings.
The primary tag sets the default behavior for the column/parameter. The TagOption value is
used for specific purposes by some of the tags below, and can also be used to disable the col-
umn using the TAGDISABLE value.
The TagString1 value is the lookup name in the case of string Lookup table columns, for other
tags it’s used as needed. TagString2 is used by some tags. For any tag that displays a string,
except the SL tags and the DBFIELD tag, putting a string into the string1, or string2 field will
prepend the string from string1, and/or append the string from string2.
The column/parameter tags are listed below. The symbol name definitions can be found in the
include file “\Extensions\Includes\ColumnTags v10.h”.

Tag name Value Description


Tag_Block_Label 60 Tags the column/parameter as containing block labels.
Tag_Block_La- 62 If the block has a block label it will show that, but if there is no block
bel_Name label, shows the block name (e.g. Activity)
Functions

Tag_Block_Name 61 Tags the column/parameter as containing block names.


Tag_Button 21 Tags the column/parameter as containing push buttons. To hide the
button in a specific cell, set that data table cell to BLANK.
Tag_CheckBox 20 Tags the column/parameter as containing checkboxes. BLANK is
equivalent to FALSE (unchecked).
Tag_Color 24 Tags the column as containing colored cells. The value in the row of
the column will be used as an eColor value to set the color of the each
cell. (Alpha channel will be ignored and set to 255.)
ModL Functions 323
Blocks and inter-block communications

Tag name Value Description


Tag_Condition- 42 Tags the column as containing popups conditionally. This functional-
al_Popup ity is very specific. Each cell/row in the column will show a popup tri-
angle under the following condition: The cell in the column to the left
of the column specified must contain a string value that matches the
stringTag that was passed in when the coltag was set. If the string
value in the cell to the left of a given cell does not contain the string
value, that cell will default to a normal editable cell. This functionality
is used in the Item Equation block.
Tag_Condition- 43 Tags the column as containing popups conditionally. This functional-
al_Popup_Array ity is very specific. Each cell/row in the column will show a popup tri-
angle under the following condition: The cell in the dynamic array
specified by the tagOption parameter must contain a string value that
matches the stringTag that was passed in when the coltag was set. If
the string value in the dynamic array cell does not match the string
value, that cell will default to a normal editable cell. This functionality
is used in the Item Equation block. This functionality is the same as
the TAG_Conditional_Popup function except that the comparison
strings are kept in a dynamic Array instead of in the adjacent column.
Tag_Date 50 Tags the column/parameter as containing date values.
Tag_Date_Con- 51 Tags the column as containing simulation time values that should be
vert represented as date values. The conversion is done in the application.
Tag_DB_Address 32 Tags the column as containing DB Addresses, but with no popup menu
so the block designer can customize the DB part selection process.
Tag_DB_Ad- 31 Tags the column as containing DB Addresses. A popup menu appears
dress_Pop when the user clicks the data table cell, enabling selection of the DB
parts.
Tag_DB_Field 30 Tags the column as containing data from a specified database table
field. TagOption should contain the DBIndex, String1, the tablename,
and string2 the fieldname.
Tag_Disable 99 Tags the column/parameter as being disabled. Note that this tag can be
used in Tag Option to mark a tagged column as disabled as well as the

Functions
other meaning of the tag in the column tag.
Tag_- 100 Tags the column/parameter header as being a popup menu. Note: this
Head_Tag_Popup does not change the behavior of clicking on the cell, just the appear-
ance of the cell. The popup behavior needs to be implemented in block
code.
Tag_Hide 98 Tags the column/parameter as being hidden.
324 Reference
Blocks and inter-block communications

Tag name Value Description


Tag_Infinity 26 Tags the parameter as containing a checkbox that changes the value to
a novalue to represent infinity. If ParamStr and paramStr2 are empty,
the behavior is that the dialog item will display the word infinite, and
an infinity symbol will be drawn near the checkbox. If there is a string
in paramStr, it will be displayed instead of the word infinity, if there is
a string in paramStr2, it toggles whether or not the infinity symbol is
drawn, so if you want to change the meaning of novalue to something
else, just put the meaning in paramStr, and an ‘x’. or some thing like
that in paramStr2.
Tag_No_- 101 Reverts the header tag back to zero, meaning no defined behavior.
Head_Tag
Tag_Nothing 0 Tags the column/Parameter as not having a tag. (Note that you can use
this with the TagOption or the TagStrings to disable the column, or
append/prepend text to the column.)
Tag_Number 71 Used in a string table to format numbers correctly to fit the cell.
Tag_Percent 70 Tags the column/parameter as containing percents. Only numerical
parameters support this tag.
Tag_Popup 40 Tags the column/parameter as containing popupMenus. Note: this does
not change the behavior of clicking on the cells, just the appearance of
the cells. The popup behavior needs to be implemented in block code.
Tag_Precision 72 Specifies the precision of the numbers displayed in the column. The
coltag2 value specified will determine how many characters of preci-
sion with which to display the numbers in the cells.
Tag_Progress 23 Tags the column as containing progress bars. The value of the progress
bar will show using the content of the row to display a range from 0 to
100. If column tag 2 contains a valid eColor value, that color will be
used to render the progress bars.
Tag_Radio 22 Tags the column/parameter as containing radio buttons.
Tag_SL 10 Tags the column/parameter as containing string lookup values.
Functions

Tag_SL_Append 17 Tags the column as containing string lookup values, appended with the
string in tagSstring2.
Tag_SL_Pop 11 Tags the column/parameter as containing string lookup values that
function as popup menus when clicked.
Tag_SL_Prepend 16 Tags the column as containing string lookup values, prepended with
the string in tagString2.
Tag_Str_Flag 80 Tags the column as a numeric column where the colstring will be dis-
played when the value in a cell is a negative one. Otherwise, the col-
umn will be treated as a standard numeric data column.
Tag_Str_Flag_- 81 The same as Tag_Str_Flag, except it doesn’t allow editing.
Noed
ModL Functions 325
Blocks and inter-block communications

Column/parameter tag functions


Here is a list of the functions used to implement column/parameter tags. The tag values are
listed in the table above:

Column/parameter tags Description Return


DIParamTagGet(inte- Returns the ParamTag for the specified parameter. I
ger blockNumber, string
dialogItemName)
DIParamTagSet(integer Sets the specified Parameter tag to the specified value. Values I
blockNumber, string for the tag value are from the ColTag/ParamTag Values table
dialogItemName, inte- above. The tagString value is currently only used for the string
ger tag, integer tag2, lookup tags, in which case it is the lookup name.
string tagString, string
tagString2)
DIParamTagString- Returns a TagString for the specified parameter. Which should S
Get(integer blockNum- be 0 for the first string and 1 for the second string.
ber, string
dialogItemName, inte-
ger which)
DTColumnTagGet(inte- Returns the column tag for the specified column. Which value I
ger blockNumber, string is:
DTname, integer col, 0: columnTag 1
integer which) 1: columnTag 2
2: the header tag
DTColumnTagSet(inte- Sets the specified column tag to the specified value. Col val- I
ger blockNumber, string ues start at zero, with zero referring to the first column after
DTname, integer col, the row column. Values for the tag value are from the ColTag/
integer tag, integer ParamTag Values table above. The tagString value is the
tagOption, string tag- lookup table name in the case of string Lookup table columns,
String, string tag- for other tags it’s used as needed. For many types of tags it’s
String2) not used. TagString2 is used by some tags as well, for many
it’s not used, and can just be set to “” the empty string. TagOp-
tion specifies an option for the tag. Some tags use this option
for specific purposes. Using the flag for TAGDISABLE in
Functions
this argument will disable most column tags. For any tag that
displays a string, except the SL tags and the DBFIELD tag,
putting a string into the string1, or string2 field will prepend
the string from string1, and/or append the string from string2.
DTColumnTagString- Returns a tagString value for the specified column. Which S
Get(integer blockNum- should be 0 for the first string and 1 for the second string.
ber, string DTname,
integer col, integer
which)

Dialog item tool tips


The System message DialogItemToolTip is sent to the block when the cursor hovers over a dia-
log item. In that message handler, the dialog item tool tip functions (below) will allow you to
customize and accesss the tooltip that will appear.
326 Reference
Blocks and inter-block communications

The functions WhichDialogItem(), and whichDTCell() can be used with this functionality to
find which dialog item the cursor is currently hovering over.

Dialog item tool tips Description Return


DIToolTipSet(string- Allows you to set the string that will be displayed. If the replace V
string, integer replace) flag is true, the default tool tip string will be replaced, if it is
false, the default string will be appended to.

Block dialogs (opening and closing)


These functions allow the ModL code to control the opening and closing of the block’s dialog.

Block dialogs Description Return


BlockDialogIsO- Returns TRUE if the block dialog it open. Returns FALSE other- I
pen(integer block- wise.
Number)
CloseBlockDialog- Closes the dialog for any block, where i is the global block num- V
Box(i) ber. See OpenBlockDialogBox, below.
CloseDialogBox() Closes this block’s dialog from within the ModL code. Put this in V
the EndSim message handler if you want an open dialog to close
at the end of the simulation. See OpenDialogBox, below.
NOTE: to prevent the dialog from closing conditionally, use an
Abort statement in the DIALOGCLOSE message handler.
CloseEnclosing- Closes the hierarchical block in which this block resides, if any. V
Hblock()
CloseEnclosing- This is same as CloseEnclosingHblock(), except it refers to a V
Hblock2(integer global block number.
blockNumber)
DialogGet- Gets the width or Height of an open dialog. (Returns the width or I
Size(integer the- height of the Hblock model window if the block number refers to
BlockNumber, an Hblock.) The ‘which’ argument takes the following values:
Functions

integer which) 0: width


1: height.
Dialog- Moves the dialog box to the specified x and y pixel location. If the I
MoveTo(integer block is an Hblock, this will move the Hblock submodel window.
blockNumber, inte-
ger x, integer y)
DialogSetSize(inte- Resizes the dialog box of the block. Only works if the dialog is I
ger blockNumber, open. If the block is an Hblock, this will resize the Hblock sub-
integer w, integer model window. W and H are width and height in pixels.
h)
MakeDialogModal Makes a block's dialog modal and should be called when the dia- V
(integer theBlock- log is open. During the dialogOpen message is OK. Calling this
Number, integer function with the TrueFalse flag set to false will turn the dialog
TrueFalse) back to non-modal behavior.
ModL Functions 327
Blocks and inter-block communications

Block dialogs Description Return


OpenBlockDialog- Opens the dialog for any block, where i is the global block num- V
Box(i) ber. You may want to do this if you are telling the user to change a
value in a block’s dialog. For instance, if you have just put up an
alert saying “The value in the ‘Height’ field of the ‘Attic’ dialog
is negative,” you can then open the offending dialog to make the
change easier.
OpenDialogBox() Opens this block’s dialog to show something visually important to V
the user. If you want a dialog to always appear in front of any
open plotting windows, call this function at the beginning of the
Simulate message handler.
OpenEnclosing- Opens the hierarchical block in which this block resides, if any. V
Hblock()
OpenEnclosingH- This is same as OpenEnclosingHblock(), except it refers to a V
block2 (integer global block number that is within the Hblock.
blockNumber)

Block dialog tabs


These functions allow ModL code to manipulate block dialog tabs.

Block dialog tabs Description Return


DisableTabName Disables or enables the specified tab. V
(string tabName,
integer trueOr-
False)
GetCurrentTab- Returns the currently selected tab name. S
Name(integer
blockNumber)
OpenDialogBox- Opens a dialog box to a specified tab. V
ToTabName(string
tabName, integer

Functions
blockNumber)
SetDefaultTab- Sets the block so that the dialog will open at a specific tab name. V
Name (string tab-
Name, integer
blockNumber)
VariableNameTo- Returns the name of the tab of a dialog that the indicated dialog S
TabName(string item is on.
varName, integer
blockNumber)

Messages to blocks (sending and receiving)


These functions make it easy to communicate information back and forth between blocks and
to execute and modify processes between blocks. They can be used to set up different types of
simulations that override ExtendSim’s simulation engine (i.e. Item library blocks). Sending
328 Reference
Blocks and inter-block communications

messages to blocks can be used to enable global functions. You can put many functions in a
custom function block, then use the SendMsgToBlock function to send one of the user-defined
messages. Use global variables to select a function and pass parameters to and from the func-
tion. Blocks can also send and receive connector messages and propagate them correctly, as
discussed in “Basic item messaging” on page 174.
In the functions, connName is the name of the connector in the calling block and block is the
global block number of the receiving block. (See “Block numbers, labels, names, categories,
position” on page 295 .)

Block messaging Description Return


BlockSimStartPri- Sets the priority value for receiving the SimStart message dis- I
ority(integer block- cussed on “Simulation messages” on page 214. Returns 0 for suc-
Number, integer cess or a negative value for failure. The default value is -1 and any
priority) block with a priority value of less than 0 will not receive the mes-
sage. Blocks that have a priority value greater than -1 will receive
the message in priority order (lowest to highest).
BlockSimFinish- Sets the priority value for receiving the SimFinish message dis- I
Priority(integer cussed on “Simulation messages” on page 214. Returns 0 for suc-
blockNumber, inte- cess or a negative value for failure. The default value is -1 and any
ger priority) block with a priority value of less than 0 will not receive the mes-
sage. Blocks that have a priority value greater than -1 will receive
the message in priority order (lowest to highest).
Connec- Called from a block currently receiving a connector message. It V
torMsgBreak() prevents any additional connected blocks from receiving that
message. This function does not affect the current message han-
dler and it should be called right before returning from the current
message handler.
DuringHblockUp- During an Hblock update, some connections are temporarily bro- I
date() ken and then reconnected. Returns True if called during an
Hblock update so you can determine if ConnectionMake or Con-
nectionBreak messages can be safely ignored.
GetConnec- Makes the specified connector the first in netlist messages. This is V
torMsgsFirst (con- used in blocks where it is critical that the messages be received by
Functions

nName) a specific block first, no matter what the order of connections. Use
this function in INITSIM or CHECKDATA. For example, the Sta-
tus block uses this function.
GetMsgSending- Returns the blocknumber of the block that sends the currently I
Block () executing message to the current block.
ModL Functions 329
Blocks and inter-block communications

Block messaging Description Return


GetSimulateMsgs( In some cases, you may not want a block to get Simulate mes- V
integer ifTrue) sages. (See “Residence blocks that do not post future events:” on
page 169.) This may be true in some discrete event blocks and in
continuous blocks that are used in discrete event simulations. This
function prevents blocks from getting Simulate messages and thus
speeds up the simulation. The function would usually be called in
the InitSim or checkData message handlers. Call this function
with FALSE if you do not want the block to get Simulate mes-
sages. This is initially set to TRUE for new and existing models,
and is always reset to TRUE before a simulation starts.
MsgEmulationOp- See “Value connector messages” on page 178. This specialized V
timize(integer function is used in the Executive block (Item library) to optimize
ifTrue) the operation of Value blocks in discrete event models. It prevents
the propagation of redundant messages that are produced by Value
blocks emulating and propagating connector messages from Item
blocks. It does this by not back-propagating (step 1) connector
messages to blocks that have ever sent a connector message to
that input of this block. This can speed the simulation by reducing
the number of messages sent between Itemand Value blocks. This
behavior is not a default because other types of modeling will fail
if not all messages are propagated. This is initially set to FALSE
for new and existing models, and is always reset to FALSE before
a simulation starts.
RestrictConnec- This function enables/disables a flag that restricts the use of con- V
torMsgs (integer nector messages in InitSim, checkdata, and endsim. This is used
restrictMessages) in the Executive block (Item library), as sending connector mes-
sages at the wrong times can cause problems in these libraries.
SendConnectorMs- Sends a connector message to a block number that is not necessar- V
gToBlock (integer ily connected to the block sending the message. Conn is the index
blockNumber, inte- for the receiving connector in the connector pane (the index starts
ger conn) at 0).
SendMsgToAll- Sends a message to all connectors on other blocks that are con- V
Cons( connName) nected to connName on the sending block. The connected blocks

Functions
will get an “on xxx” message where xxx is the connected receiv-
ing block’s connector name.
SendMsgToBlock Sends a message to the specified global block. The message is an V
(integer block, inte- ExtendSim constant that corresponds to the message to be sent.
ger messageCon- The messageConstant is not a string. It is derived by taking the
stant) message name and adding MSG after the message name. For
example, to send a USERMSG0 to a block, messageConstant
would be USERMSG0MSG (not a string). See the chapter “Mes-
sages and Message Handlers” on page 213 for all the messages
that can be sent. Note: If the block is a hierarchical block, the sub-
model blocks will not receive the message. Instead, use the
SendMsgToHblock function discussed in this section.
330 Reference
Blocks and inter-block communications

Block messaging Description Return


SendMs- Sends the message to all internal blocks within the hierarchical V
gToHblock(integer block. This function will do nothing if globalBlockNum is not a
globalBlockNum, hierarchical block.
integer message)
SendMsgToInputs( Sends a message to all input connectors on other blocks that are V
connName) connected to connName on the sending block. The connected
blocks will get an “on xxxIn” message where xxxIn is the con-
nected receiving block’s input connector name.
SendMsgToOut- Sends a message to the output connector on the block that is con- V
puts(connName) nected to connName on the sending block. The connected block
will get an “on xxxOut” message where xxxOut is the connected
receiving block’s output connector name.
SimulateConnec- This is used to disable the “simulation” of connector messages by V
torMsgs(integer Value blocks that have no connector message handlers, as
trueFalse) described in “Value connector messages” on page 178. “Simula-
tion” of connector messages is enabled by default for new and
existing models, and is always re-enabled before a simulation
starts. This is a special-purpose function that will probably only
be of interest to users who are creating their own libraries that are
not being used with the Item library. Use this function in INIT-
SIM or CHECKDATA.

Icon views
These functions are used to interrogate and control block icon classes and views. Classes are
global (e.g. Flowchart class) and always set by the modeler, but views (e.g. Flow down) can be
set by the modeler or the block.
The default class (ExtendSim classic) and view are both zero.
☞ As of ExtendSim 10, icon classes were eliminated.
Classes and views Description Return
Functions

IconGetClass (inte- Gets the current class (0 to 7) of the block, but classes are cur- I
ger blockNumber) rently global, so the entire model will have this class.
IconGetView (inte- Gets the current view (0 to n) of the block. See IconGet- I
ger blockNumber) ViewName(), below.
IconGet- Returns the name of the view specified. S
ViewName (inte-
ger blockNumber,
integer view)
IconSetViewByIn- Sets the block’s view by index (0 to n). V
dex (integer block-
Number, integer
index)
ModL Functions 331
Models and notebook

Classes and views Description Return


IconSetViewBy- Sets the block’s view by the partial name entered. For example, I
PartialName (inte- “right” will set the icon view to “Right Angle.” This is useful
ger blockNumber, when the view names are slightly different for different classes
string partialName) and you want to set the view to a type of view rather tban a spe-
cific one.

Models and notebook

Models, notebook Description Return


DuringContinue() Returns true if the model is being continued from a previous I
saved run.
GetBlockInfo(inte- Returns misc information about a block which can take the fol- R
ger theBlockNum- lowing values:
ber, integer which) 1: invisible --- returns if the block is invisible.
2: scriptedBlock – returns if the block was created via scripting.
3: dialog box is open
GetGlobalSimula- Returns the actual simulation order index of a block. I
tionOrder(integer
blockNumber)
GetLibraryCon- Fills the passed-in Dynamic Arrays with the names and types of I
tents (string lib- the blocks in the named library. Returns the number of blocks in
Name, Str31 the library.
blockNames[],
Str31 block-
Types[])
GetLibraryInfo Returns whether a library is of a certain type. I
(integer blockNum-
ber, integer spec- specify takes the following values:
ify) 1: RunTime

Functions
(others will be defined in the future)
GetLibraryPath- Function to return the pathname of a library file, given a block in S
Name (integer that library.
blockNumber, inte-
ger specify) specify takes the following values:
1: pathname without library name
2: just library name
GetLibraryString- Returns string information about the library that the block comes S
Info (integer block- from. Specify takes the following values:
Number, integer
specify) 1: Name
(others will be defined in the future)
332 Reference
Models and notebook

Models, notebook Description Return


GetLibraryVer- This function returns the short version string for the library that S
sion(integer block- includes the block specified by blockNumber.
Number)
GetLibraryVersion- Returns the library version string. S
ByName(string lib-
Name)
GetModelName() Returns the string that is the model’s file name. This is useful S
when writing out debugging information or in certain user alerts.
GetModelPath Returns the pathname to the specified model, but does not include S
(string model- the model name. The model needs to be open.
Name)
GetRunParame- Similar to GetRunParameterLong except it returns a real. Which R
ter(integer which) specifies a parameter in the Simulation Setup dialog. In addition
to the parameters for GetRunParameterLong, this function
returns values for:
1 - endTime
2 - startTime
10 - startDate
12 - endDate
GetRunParameter- Gets the specified parameter from the Simulation Setup dialog I
Long(integer using the value of which:
which) 3 - numSims
4 - numSteps
5 - random seed
6 - seedControl (value, from 1-3, of the seed popup from the Ran-
dom Numbers tab)
7 - checkRandomSeeds (value of the duplicate seeds check box
from the Random Numbers tab)
8 - timeUnits
9 - calendarDates
11 - “__seed” table database index
GetSerialNumber() Returns the serial number of the unit as a string. S
Functions
ModL Functions 333
Models and notebook

Models, notebook Description Return


GetSimulation- Returns the phase of the simulation. I
Phase()
0 - Not currently running a simulation
1 - CheckData
2 - StepSize
3 - InitSim
4 - Simulate (main simulation loop)
5 - FinalCalc
6 - BlockReport
7 - EndSim
8 - AbortSim
9 - PreCheckData
10 - PostInitSim
11 - SimStart
12 - SimFinish
13 - ModifyRunParameter
14 - OpenModelPhase
Note: If a hierarchical block is updated, ExtendSim sends an
openModel message handler but the function will return a 0,
rather than a 14.
GetWindowsHndl (Windows Only) Returns the Windows API handle of the main I
(integer which) window in the ExtendSim application. Currently the which
parameter is unused. It should be set to 0 for the Main window
handle. This handle is used to pass to a Windows DLL. It is not
used in ModL functions.
IsSimulation- Returns TRUE if the simulation run is paused or is about to pause. I
Paused()
ModelLock(inte- The function allows you to lock and unlock the model from I
ger lock, integer MODL code. The Lock argument takes a value of one if the
HblocksLocked, model is to be locked, a value of zero for unlocking. Hblocks-
string password) Locked is a flag that sets whether you want the Hblocks to be
locked when locking a model. The password is the password to be
set in the locking case, and the password to be compared with in

Functions
the unlocking case. This function returns a zero if is succeeds, and
the following error codes for specific error conditions:
-1: Unlock password didn’t match.
-2: Model is already locked, it cannot be locked again without
being unlocked first.
-3: lock value out of range.
NotebookClose() Closes the notebook if it is open. I
334 Reference
Models and notebook

Models, notebook Description Return


NotebookItem- Fills the 4 element array rectArray with the position values for the I
Rect(blockNum, specified notebook item. Specification of whichNotebook works
whichNotebook, the same way as for OpenNotebook2.
iobjectID, rectAr-
ray) Coordinates are:
0: top
1: left
2: bottom
3: right
Return value is the type of the object.
Notebook- Fills the idArray and typeArray with information about objects in I
Items(blockNum, the specified notebook. IdArray is filled with a list of the id num-
whichNotebook, bers of objects in the notebook. typeArray is filled with type spec-
idArray, typeArray) ifiers for those same items. Specification of whichNotebook
works the same way as for OpenNotebook2.
The return value is the count of the number of items found (there-
fore also the number of rows filled in the arrays.)
Notebook- Returns information about the specified notebook object. Specifi- R
ItemInfo(block- cation of whichNotebook works the same way as for OpenNote-
Num, book2.
whichNotebook,
itemId, which) Which values are:
0: type
1: isClone
2: blockNumber
NotebookItemIn- Returns string information about the specified notebook S
foString(block- object.Specification of whichNotebook works the same way as
Num, for OpenNotebook2.
whichNotebook,
itemId, which) Which values are:
1: object name
NotebookIsOpen() Returns a true value if the notebook is currently open. I
Functions

OpenNotebook() Opens the model notebook. Since this is from v9, which only had V
one notebook per model, see also OpenNotebook2.
OpenNote- Opens the specified notebook, either for the model worksheet or V
book2(integer for an Hblock. BlockNumber controls which set of Hblock note-
blockNumber, inte- books is referenced by the Index. Pass in the number of a block at
ger Index, integer the top level of the main worksheet or a -1 for blockNumber to get
ripOff) to the top level notebooks. Otherwise, the blockNumber will be
used to identify which Hblock's set of notebooks will be refer-
enced by the Index. If the blockNumber is for a block inside an
Hblock, that Hblock's notebooks will be referenced, otherwise the
blockNumber will identify the hblock itself. If ripOff is true, the
notebook will be opened in the ripped-off state. If false, the note-
book’s tab will be selected.
ModL Functions 335
Models and notebook

Models, notebook Description Return


PauseSimFor- Pauses the currently running active model for saving. This allows V
Save() the user to save the model while paused. The model can be saved
by the Save menu command or the SaveModel() function below.
NOTE: The PauseSim() function (located elsewhere) does a pause
immediate which is useful for debugging, but will not allow sav-
ing the model.
ResumeSimula- Resumes the simulation and returns immediately. V
tion()
RunSetup(true- Opens Setup Simulation dialog and sets up a default OK button I
False) instead of Run Now button. Returns TRUE if OK is clicked. If
trueFalse is TRUE, show RunNow button. If trueFalse is FALSE,
hide RunNow button.
RunSimula- Runs the model. If the argument is TRUE, the function puts up the I
tion(trueFalse) Simulation Setup dialog, then runs the simulation if the user
chooses OK; if the argument is FALSE, the model is run directly.
This function returns TRUE if the simulation ran to completion
with no errors and was not stopped, otherwise returns FALSE. See
the SetRunParameters() function below.
NOTE: If called from a block, runs the model until it completes or
is aborted, and then returns. If you use the ExecuteMenuCom-
mand() function to call RunSimulation() (e.g. from scripting or
OLE automation), it returns immediately after starting the model
run.
SaveModel() Saves the model and updates any publishers. V
SaveMod- Saves the active model under the name and path defined in file- I
elAs(string file- Name. Returns a zero if successful, a negative number otherwise.
Name) Saves after the current block is executed.
SaveTopDo- Saves the top document under the file name and path name I
cAs(string file- defined by filePath. If aSync is TRUE, saves after the current
Path, integer block is executed. Similar to SaveModelAs except it will work on
aSync) whichever the top ExtendSim document is. (Specifically used by

Functions
the Equation block to save and close Include files.) Returns 0 for
success or a negative value to indicate failure.
SetBlockSimula- Sets the simulation order value of the specified block. This is only I
tionOrder (integer useful, or allowed if the model simulation order has been set to
blockNumber, inte- custom simulation order. This function returns a zero if success-
ger newOrder) ful, and the following error codes if it fails:
-1: can’t be set during a simulation.
-2: newOrder must be greater than zero.
-3: no active model document.
-4: sim order is not set to custom.
-5: no such block.
336 Reference
Models and notebook

Models, notebook Description Return


SetModelSimula- Sets the type of simulation order to be used in the model. Types I
tionOrder (integer are:
neworder)
0: left to right
1: not used
2: flow
3: custom
This function returns a zero if successful, and –1, -2, and –3, as
described under SetBlockSimulationOrder.
SetRunParame- Sets a single parameter in the Simulation Setup dialog. As an enu- I
ter(real param- merated list, this function is more expandable than SetRunParam-
Value, integer eters(). The values for which are:
which)
1:endTime, 2:startTime, 3:numSims, 4:numSteps, 5:random
seed), 6:seedControl (value, from 1-3, for the seed popup from
the Random Numbers tab), 7:checkRandomSeeds (value for
the duplicate seeds check box for the Random Numbers tab),
8:timeUnits, 9:calendarDates, 10:startDate, 11: “__seed”
table database index.
SetRunParame- Sets the parameters in the Simulation Setup dialog. This function I
ters(real SetEnd- returns the following:
Time, real
SetStartTime, real 0 Successful
SetNumSims, real -1 End time must be greater than start time
SetNumStep)
-2 Number of steps must be at least one
-3 Number of steps must be less than 2000000000
-4 Number of simulations must be at least 1 and less than 32768
SpinCursor() Spins the beachball cursor. Used to alert the user that a time con- V
suming calculation is taking place.
SpinCur- Starts a spinCursor that will continue until spinCursorStop is V
sorStart(integer called.
Functions

showDuringRun)
showDuringRun determines if the cursor is shown during a simu-
lation or not.
SpinCursorStop() Stops a spinCursor started by spinCursorStart. V

DE Modeling Using Equation Blocks


The following function are convenience functions intended to be called from Equation blocks.
They have the effect of querying a resource pool block for the number of available resource, or
reuesting that the Resourcd Pool block allocate a resource. They are implemented through the
sending of messages, and the use of globals. See the code of the resource pool block for more
information if desired.
ModL Functions 337
Scripting

DE Modeling Description Return


ResourcePoolAllo- Requests the specified Resource Pool block to allocate the speci-
cate(integer fied number of resources.
ResourcePool-
BlockNum, real
NumToAllocate)
ResourcePoolA- Queries the specified resource pool block for the number of
vailable(integer resources that are available.
ResourcePool-
BlockNumber)

Scripting
These functions are useful in building or changing models when called from blocks or from
other applications. See also the GetDialogVariable() and SetDialogVariable functions under
“Dialog items” on page 305.
See the Scripting blocks in the ModL Tips library for examples of scripting.

Scripting Description Return


ActivateApplica- Brings the ExtendSim application to the foreground. This is pri- V
tion() marily used for interapplication/scripting
ActivateWorksheet Activates, (selects and brings to the front), the named worksheet. I
(string sheetName)
AddBlockToClip- Adds the indicated block to the clipboard contents without other- I
board (integer wise changing the contents. Returns FALSE if successful.
blockNumber)
AddBlockToSelec- Adds the indicated block/worksheet object to the selection. This I
tion (integer block- is in contrast to SelectBlock(), which makes the indicated block
Number) the entire selection. Returns FALSE if successful.
Application- Returns the application frame in global coordinates. The Inside I
Frame(integer argument specifies if the returned frame should be inside
Functions
frame[], integer (includes the menubar and window frame) of the application
inside) frame window, or the outside.
Declare frame as: Integer frame[4];
When the function returns, frame will contain: frame [0] - Top,
frame[1] - Left, frame[2] - Bottom, frame[3] - Right
BlockAdjustPosi- Adjusts the position of the specific block relative to the location V
tion(integer block- of the icon positioner, which is turned on or off in the Icon tab of
Num) a block’s structure. See “Icon positioner” on page 10 for more
information.
338 Reference
Scripting

Scripting Description Return


ChangePreference Allows you to change preference values using ModL code. The V
(integer prefer- value argument takes a zero for FALSE or a one for TRUE. The
ence, integer value) preference argument takes the following values:
12: simulation sound
14: connection type (0=free, 1=right, 2= smart, 3=straight)
21: show worksheet tool tips
22: show dialog tool tips
27: metric units
30: show library warnings
31: check application version
32: bump connectors and auto-connect
33: show dialog editor tool tips

Note: XCMDs and patterns are not supported as of release 10.


See GetPreference(), below.
ChangePreferen- Change the string-based preferences using this function. The pref- V
ceString (integer erences that can be changed with this function are:
preference, string
theString) Default Library Path: 1
Library 1: 2
Library 2: 3
Library 3: 4
Library 4: 5
Library 5: 6
Library 6: 7
Library 7: 8
Default Model Path: 9
ClearBlock(integer Clears the specified block from the worksheet. V
blockNumber)
ClearBlockUndo Clears the block and adds it to the delete task list to allow undo- I
(integer theBlock- ing. Returns FALSE if successful.
Number)
Functions

ClearConnec- Removes the connection between the specified blocks and con- I
tion(integer block- nector numbers. Returns TRUE if successful.
From, integer
conFrom, integer
blockTo, integer
conTo)
ClearUndo(void) Clears the Undo list and removes any existing undo tasks from V
the Edit menu. After executing this function, the Undo command
will be disabled.
ModL Functions 339
Scripting

Scripting Description Return


CloneCreate(inte- Returns a cloneID for the new clone, used in the other clone I
ger blockNumber, scripting functions. VariableName is the dialog item variable
string variable- name. Destination is -1 for the top worksheet, -2 for the notebook
Name, integer des- or the block number of an H-block to put it into its submodel. Left
tination, integer and Top are the pixel coordinates of the left-top corner of the
left, integer top) clone.
CloneDelete(inte- Deletes the specified clone. Get the cloneID from the CloneCre- I
ger cloneID) ate() or CloneFind() functions.
CloneFind(integer Returns a cloneID for the found clone, used in the other clone I
blockNumber, scripting functions. VariableName is the dialog item variable
string variable- name. N is the nth instance of the clone specified, in order of cre-
Name, integer n) ation. If variableName is blank, the nth clone from the block is
returned.
CloneGetDialog- Returns the variable name of the dialog item that the specified S
Item(integer clone is from.
cloneID)
CloneGetDialog- Returns the Nth label on a cloned dialog item that has labels. This S
ItemLabel(integer would be either a Popup menu, or a data table.
cloneID, integer n)
CloneGetInfo(inte- For whatInfo, 1:returns the type of the clone, 2:returns the block I
ger cloneID, inte- number of the clone, 3:returns True if the clone is selected and
ger whatInfo) False if it is not.
Values for the type of clone (whatInfo:1) are:
1:Button, 2:Check Box, 3:Radio Button, 4:Meter, 5:Parameter,
6:Slider, 7:data table, 8:EditText, 9:StaticText, 12:Switch,
13:String Table, 14:Plotter pane, 15:Plotter data table, 16:Popup
Menu, 17:EmbeddedObject, 18:DynamicText, 19:Text frame,
20:Calendar, 21:EditText(31).
CloneGetList(inte- Returns the number of clones in the cloneIDArray array. Fills the I
ger blockNumber, dynamic array cloneIDArray with all of the cloneIDs for the vari-

Functions
string variable- ableName. If variableName is blank, all of the clone IDs for that
Name, integer block are returned in the array.
cloneIDArray[])
CloneGetPosi- PositionArray is declared as an array of 4 integers. It returns the I
tion(integer following information: positionArray[0] = cloneRect.top, posi-
cloneID, integer tionArray[1] = cloneRect.left, positionArray[2] =
positionArray) cloneRect.bottom, positionArray[3] = cloneRect.right.
CloneHideDis- Disables/enables or hides/shows the specified clone. I
able(integer If disable is True and disableIFtrue is True, the clone is disabled.
cloneID, integer If disable is True and disableIFtrue is False, the clone is enabled.
disable, integer dis- If disable is False and disableIFtrue is True, the function hides
ableIFtrue) the clone; the clone appears if disable is False and disableIFtrue
is False.
Returns zero if successful; otherwise returns an error code (nega-
tive number).
340 Reference
Scripting

Scripting Description Return


CloneResize(inte- Resizes the clone to the specified rectangle (position and size). I
ger cloneID, inte-
ger top, integer left,
integer bottom,
integer right)
CodeExe- Executes the ModL code in the string modlCodeString. Local V
cute(string modl- variables may be defined. Global variables can be used to input
CodeString) and return values.
CreateHblock Makes the current selection into an H-block with the specified I
(string theName) name.
DialogRe- Forces the dialog box of the specified block to refresh (redraw.) I
fresh(integer block- Does nothing if the dialog box is not open or the block doesn't
Number) exist. Returns true (1) if it succeeds, zero otherwise.
DialogFixed- Specifies that the dialog box for blockNumber should be fixed to I
Size(integer block- the specified height and width. User resizing of the block dialog
Number, integer will be restricted.
height, integer
width)
DuplicateBlock Makes a copy of the indicated block, and returns the block num- I
(integer theBlock- ber of the new block. Returns FALSE if successful.
Number)
ExecuteMenuCom- Executes the specified command. This is functionally the same as V
mand(integer com- selecting the command from the menus. ExtendSim will attempt
mandNumber) to perform the command on the active window. If there are multi-
ple windows open (including dialog boxes), you may need to call
ActivateWorksheet() to ensure that the correct model is in the
active window. See Appendix C for a list of menu command num-
bers.
ExtendMaximize() Maximizes the ExtendSim Application. V
ExtendMinimize() Minimizes the ExtendSim Application. V
Functions

FindBlock (string Finds the first block that matches the string searchStr and returns I
searchStr, integer its block number, optionally opening the dialog or selecting the
which, integer block. Which specifies what string in the block you want to com-
openDialogs, inte- pare your searchstring to. It takes the following values:
ger wholeWords,
integer justBlock- BlockLabel:1, BlockName:2, BlockType:3, TextBlockText:4
Num) openDialogs specifies if the block should be just selected, or if
the dialog should be opened. It is overridden by the justBlock-
Num parameter, if it is TRUE. WholeWords specifies if you want
the text to try for an exact match, or to match a partial string. The
final argument justBlockNum if set to true will set the function to
just return a block number, and neither select the block nor open
the dialog.
ModL Functions 341
Scripting

Scripting Description Return


FindNext() Finds the next block that matches the search string specified. I
Only useful if called immediately after the findBlock function.
(Returns a –1 if no matching block is found.)
GetAppPath() Returns a string containing the full path name for the ExtendSim S
application file. This function is useful for determining the loca-
tion of files for which only the file’s relative location to the
ExtendSim application is known.
GetPreference Allows you to get preference values using ModL code. The return I
(integer preference) value is 1 for TRUE and 0 for FALSE. The preference argument
takes the following values:
12: simulation sound
14: connection type (0=free, 1=right, 2= smart, 3=straight)
21: show worksheet tool tips
22: show dialog tool tips
27: metric units
30: show library warnings
31: check application version
32: bump connectors and auto-connect
33: show dialog editor tool tips
See also ChangePreference
Note: XCMDs and patterns are not supported as of release 10.
GetRecentFile- Returns the full path to the specified recent file from the list of 5 S
Path(integer which) recent files at the bottom of the File menu. The specified file
(which) will be a number from 1 to 5.
GetUserPath() Returns the path to the user documents directory. Similar to S
GetAppPath.
GetWorksheet- Returns the frame of the worksheet in the array arrayName, I
Frame(integer which must be declared integer arrayName[4]. Coordinates are in
blockNumber, screen pixels and correspond to the information returned by the
array arrayName) GetMouseX(), GetMouseY(), and GetBlockTypePosition() func-
tions.
ArrayName[0]:top, ArrayName[1]:left, ArrayName[2]:bottom, Functions
ArrayName[3]:right.
HBlockTopGet() Returns the block number of the topmost open Hblock’s sub- I
model, or a negative number if there are no Hblocks open above
the model worksheet.
HBlockUnlink- Disconnects the specified Hblock from the library it has a link to. V
FromLibrary(inte- This will make the Hblock into a standalone Hblock without a
ger blockNumber) library connection.
IsBlockSelected Returns a TRUE if the indicated block is selected, returns false I
(integer blockNum- otherwise. This function will return a –1 if the indicated block-
ber) number is not a valid block.
342 Reference
Scripting

Scripting Description Return


IsLibEnabled(inte- Returns TRUE if the running version of ExtendSim will open a I
ger type) specific type of library. Type values are: 17: OR library, 18: AT
library, 19: Suite library
IsMenuIte- Returns TRUE if the given menu command is currently checked. I
mOn(integer The whichItem argument uses the same numbers as defined in
whichItem) Appendix C for the ExecuteMenuCommand() function.
IsMetric() Returns TRUE if metric is set in the options dialog. I
LastBlockPlaced() Returns the block number of the last block placed on the active I
worksheet.
LibraryGetInfoBy- Function to return information about a library, and blocks in that I
Name(unsigned library. Specify takes the following values;
string libName, 1: Hblock - TRUE/FALSE
string blockName,
integer specify)
MakeBlockInvisi- Makes the indicated block invisible. (Turns it visible if it was I
ble (integer global- already invisible, and the invisible flag is set to false.) Invisible
BlockNum, integer blocks will not display on the worksheet at all, and cannot be
invisible) selected by the user. Returns FALSE if successful.
MakeConnection Makes a connection line from the From block to the To block. I
(integer block-
From, integer con-
From, integer
blockTo, integer
conTo)
ModelSettings- Returns the model setting value specified by the which argument. R
Get(string model- If modelName is an empty string, this function will access the
Name, integer active model. which values:
which)
0: Model exists (returns a true or a false)
1: Animation on
2: Model is dirty (has unsaved changes)
Functions

3: Run Mode (0 means multithreaded; 1 means single threaded)


4: Sim Running
ModelSettings- Sets the value of a model Setting to the real value specified by the I
Set(string model- which argument. Returns a 0 for success and a non zero integer
Name, integer for failure. which values:
which, real value)
1: Animation on
2: Dirty (needs to be saved)
3: Run Mode (0 means multithreaded; 1 means single threaded)
MoveBlock(inte- Moves the specified block the specified number of pixels. Coordi- I
ger blockNumber, nates refer to the upper left corner of the block.
integer xPixel, inte-
ger yPixel)
ModL Functions 343
Scripting

Scripting Description Return


Move- Moves the specified block to the specified location. Coordinates I
BlockTo(integer refer to the upper left corner of the block.
blockNumber, inte-
ger xLoc, integer
yLoc)
OpenExtendFile Opens the ExtendSim model, library, or text file, using the full- I
(string fullPath) path name on the disk. This creates a new front window if open-
ing a model or text file. Returns a zero if successful.
PlaceBlock(string Places the named block from the named library onto the active I
blockName, string worksheet at the specified location. If the neighbor field is filled
libName, integer in with a block number of a block already on the worksheet, then
xPixel, integer the xPixel, yPixel values are relative to the location of the neigh-
yPixel, integer bor, otherwise if neighbor is -1 (no neighbor) they are absolute
neighbor, integer worksheet coordinates.
side)
The side argument determines how the new block will be placed
relative to the old block:
0: Left, 1: top, 2: right, 3: bottom
PlaceBlockIn- Places a copy of the named block from the named library in the I
Hblock (string H-block that is specified by the HblockNum argument. See Place-
blockName, string Block in your manual for more information. Returns FALSE if
libName, integer successful.
xPixel, integer
yPixel, integer
HblockNum)
PlaceDot- Places a dot block into the worksheet. Arguments are similar to I
Block(integer PlaceBlock, and PlaceTextBlock.
xPixel, integer
yPixel, integer
neighbor, integer
side, integer width,
integer Hblock-
Name)
PlaceTextBlock Places a Text Block with the string text as its content onto the I Functions
(string text, integer active worksheet at the specified location. The width argument
xPixel, integer specifies the final width of the text block in pixels. See the
yPixel, integer description of PlaceBlock above for descriptions of the other
neighbor, integer arguments.
side, integer width)
PlaceTextBlockIn- This function places a TextBlock in the Specified HBLock. See I
Hblock(string text, the description of PlaceTextBlock for more information.
integer xPixel, inte-
ger yPixel, integer
neighbor, integer
side, integer width,
integer Hblock-
Num)
344 Reference
Scripting

Scripting Description Return


QuickTimeAvail- Returns whether or not quicktime is available on the current I
able() machine.
SelectConnection Selects the connection line associated with the connection I
(integer block- between the specified blocks. This function returns a TRUE if it
From, integer con- succeeds, and a FALSE if it fails.
From, integer
blockTo, integer
conTo)
SetDirty(integer Sets/Unsets the “dirty” flag on the active worksheet. A common V
dirty) use for this functionality would be to set the dirty flag to
“FALSE’”before issuing the ExecutemenuCommand function to
close a worksheet. This has the effect of closing the worksheet
without querying the user if they want to save, or not.
SuppressWork- If supress is TRUE, stops any update drawing of the worksheet V
sheetRedraw(inte- until a call to SuppressWorksheetRedraw(FALSE), whereupon
ger suppress) the worksheet will be redrawn.
UnselectAll() Unselects all blocks, connections, etc. V
WinSetFore- Sets the application associated with the passed in handle to be the V
groundWin- foreground window. Passing in a zero, sets ExtendSim as the
dow(integer foreground window. Windows handles for other applications then
handle) ExtendSim will need to be acquired through some means. One
example would be querying the Excel object model through OLE/
COM to return the object handle for Excel. See the code of the
Command block in the Value library for an example of doing this.
WinShellExe- This calls the Windows ShellExecute() function. This specifies all I
cute(string opera- arguments in the ShellExecute() function call but the first
tion, string (HWND), as ExtendSim supplies that argument internally.
fileName, string
params, string dir,
integer show)
WorksheetRe- Forces a worksheet refresh (redraw) of the worksheet window I
Functions

fresh(integer block- containing the specified block.


Number)
worksheetSetting- Gets a setting on the worksheet associated with the specified I
Get(integer block- block. (Blocks on the top level will affect the main worksheet,
Num, integer blocks inside an Hblock will affect that Hblock worksheet, if it's
which) open.) Which takes the following values:
1: left
2: top
3: width
4: height
5: scroll X
6: scroll Y
ModL Functions 345
Reporting

Scripting Description Return


worksheetSet- Sets a setting on the worksheet associated with the specified I
tingSet(integer block. Also works on Hblocks. Uses “which” values the same
blockNum, integer way as WorkSheetSettingGet.
which, integer
value)

Reporting
These functions are used in the BlockReport message handler to organize reports written by
blocks.

Reporting Description Return


GetReportType() Used in BlockReport message handler to get the current report I
type. Returns 0 for Dialog report, 1 for Statistical report.
IsFirstReport() Returns TRUE if this is the first block of a type getting a Block- I
Report message. Useful to set up column headers for that block
type.

Plotting/Charts
These functions allow you to provide graphs and data in any block you create.
Each trace can be assigned one of two Y axes, Y and Y2, so that traces of different magnitudes
can appear in the same plot.
Some of these functions only apply to the blocks in the Plotter library which is a Legacy library
that was replaced by the Chart library as of ExtendSim 10.
The following arguments are used in the plotting functions:

Plot argument Definition


Color Color of the plot traces. You can use the numbers or their associated Extend-
Sim constants. Note that these are different than the animation colors.

Functions
33: BlackColor
205: RedColor
341: GreenColor
409: BlueColor
273: CyanColor
137: MagentaColor
EndTime X-axis value that corresponds with the last point of the array.
FunctionName Name of a real, single argument function. For example, cos(x) should be
entered as cos.
IsXLog If TRUE, the X axis is logarithmic.
IsY2Log If TRUE, the Y2 axis is logarithmic.
IsYLog If TRUE, the Y axis is logarithmic.
346 Reference
Plotting/Charts

Plot argument Definition


LineFormat Format for traces.
0: connected points
1: rectangular connected points (no interpolation between points)
2: dots
MaxLines Initial number of rows in the plot’s data pane.
NumFormat Format for the numbers in the data pane.
0: General
1: decimal (2 places)
2: integer
3: scientific (exponential)
Pattern Pattern of the plot line. You can use the numbers or their associated Extend-
Sim constants. Note that these are different than the animation patterns.
0: BlackPattern
1: DkgrayPattern
2: GrayPattern
3: LtgrayPattern
Note: patterns are not supported as of release 10.
Plot Number (0 to 3) specifying one of the four possible plot pages. See the
blocks in the Plotter library for an example. As of ExtendSim 10, the Plotter
library is a Legacy library.
PlotPts Number of points in the array ready to plot, which does not need to be the
number of points actually declared in the array. If there are no points ready
to plot (because they have not yet been calculated), use 0 for this value.
SigName Name for the trace
StartTime X-axis value that corresponds with the first point (y[0]) of the array.
SymFormat Symbols used on traces.
0– ;1– ;2– ;3– ;4– ;5– ;6– ;7–
8– (displays the trace’s number); 9 –
UseY2Axis If TRUE, the trace is plotted to the limits of the Y2 axis instead of the main
Functions

Y axis.
WhichSig Number (0, 1, 2 ...) specifying one of the plot traces
Y Name of the dynamic array used in the plot. Use MakeArray to allocate Y
before using it in a function.

General plotting
☞ See Pie Chart, Bar Chart, and Scatter Chart functions starting on page 353.
General plotting Description Return
AutoScaleX(inte- Finds the minimum and maximum X axis values of all installed V
ger plot) arrays or installed scatter arrays and adjusts the X axis limits
accordingly. See also the PlotterAutoScaleLimits function.
ModL Functions 347
Plotting/Charts

General plotting Description Return


AutoScaleY(inte- Finds the minimum and maximum Y values of all installed arrays V
ger plot) or installed scatter arrays and adjusts both the Y and Y2 axis lim-
its accordingly.
BarGraph(integer Sets the number of bins, the minimum value, and maximum value V
plot, integer aBins, for a bar graph.
real aMin, real
aMax)
ChangeAxisValues Sets or changes the axis values of the specified plotter to the value I
(integer plot, real specified. Specifying a BLANK for a given value will use the
xLo, real xHi, real existing value. Returns a TRUE if the function executed success-
yLo, real yHi, real fully.
y2Lo, real y2Hi)
ChangePlotType Changes the defined plot type of a plotter. This is used when cre- V
(integer plot, inte- ating custom plotters. The call to change the plotter should be
ger plotType) done right after the call to install an axis and before any other of
the plotter calls.
1 – linear plot; 2 – scatter plot; 3 – error bars; 4 – strip chart;
5 – worm plot; 6 – bar plot
ChangeSignal- Specifies the color for the trace. V
Color (integer plot,
integer whichSig,
integer color)
ChangeSignalSym- Specifies the symbol for the trace. V
bol(integer plot,
integer whichSig,
integer symFormat)
ChangeSignal- Specifies the width (in pixels) for the trace. V
Width(integer plot,
integer whichSig,
integer width)

Functions
ClosePlotter(inte- Closes the plot window, if open. V
ger plot)
ClosePlotter2 (inte- This function just closes the specified plotter window, if it is open. V
ger blockNumber,
integer plot)
DisposePlot(inte- Disposes of a plot window and all its saved plots. This does not V
ger plot) dispose of any installed data arrays.
GetAxis(integer Fills the first nine elements of the axisValues array (declared as V
plot, real axisVal- real axisValues [9]) with the current values of isXLog, xLow, xHi,
ues[9]) isYLog, yLow, yHi, isy2Log, y2Low and y2Hi.
348 Reference
Plotting/Charts

General plotting Description Return


GetAxisName(inte- Returns the name of the specified axis. S
ger plot, integer
whichAxis) whichAxis:
1-x
2 - y1
3 - y2
GetPlotter- Returns information about the specified plotter or chart. Values R
Value(integer plot, for Which:
integer which)
1: X precision places
2: Y precision places
3: Y2 precision places
GetSignalName Returns the name of the signal whichSig. S
(integer plot, inte-
ger whichSig)
GetSignalValue Finds the value of the installed trace at xAxisValue. If the trace is R
(integer plot, inte- an installed array, the value is interpolated between adjacent
ger whichSig, real points. If the trace is an installed function, the function is evalu-
xAxisValue) ated at xAxisValue. This does not work for scatter plots because
there may be many Y values for a single xAxisValue.
GetTickCount(inte- Returns the number of ticks on the plotter axis. WhichCount is 0 I
ger plot, integer for the X axis, 1 for the Y axis, and 2 for the Y2 axis.
whichCount)
GetY1Y2Axis(inte Returns an integer specifying which Y axis the signal is plotted I
ger plot, integer against and whether or not the signal is hidden.
whichSig)
1: y1
2: y2
-1: y1, hidden
-2: y2, hidden
Note: If you are not concerned whether the signal is hidden, take
the absolute value of the result.
Functions

InstallArray(inte- Allows the automatic plotting of arrays. The plot window will V
ger plot, integer plot all the points of this array up to plotPts-1. It should be pre-
whichSig, string ceded by InstallAxis and eventually be followed by showPlot.
sigName, real y, The first time arrays are installed they need to be installed in
real StartTime, real sequential order. The Install Array call is used in two ways in
EndTime, integer plotter blocks. The first time it is called, it installs the array and
plotPts, integer sets parameters such as the color of the line. The second and sub-
useY2Axis, integer sequent times, the formatting options are ignored, and the only
pattern, integer action a call to installArray takes is to reinstall the array itself. If
color) you precede a call to InstallArray with a call to RemoveSignal,
the formatting information will be used.
Note: patterns are not supported as of release 10.
ModL Functions 349
Plotting/Charts

General plotting Description Return


InstallAxis(integer Installs both the X and Y axes. If both the y2Low and y2Hi argu- V
plot, string title, ments are 0, the Y2 axis is not shown.
string xName, inte-
ger isXLog, real
xLow, real xHi,
string yName, inte-
ger isYLog, real
yLow, real yHi,
string y2name,
integer isY2Log,
real y2Low, real
y2Hi, integer
y2Pattern, integer
y2Color, integer
maxLines)
InstallFunction Allows the automatic plotting of functions. The plot window will V
(integer plot, inte- plot all the points of this function corresponding to the x axis val-
ger whichSig, ues, even if you changed them. It should be preceded by Instal-
string sigName, lAxis and eventually followed by ShowPlot. Call InstallFunction
functionName, every time the plot window is shown (before ShowPlot).
integer useY2Axis,
integer pattern, Note: patterns are not supported as of release 10.
integer color)
NumPlotPoints Specifies the number of points to be stored for worm and strip V
(integer plot, inte- plots.
ger points)
PlotNewBarPoint This function allows you to set the value of one of the bins in a V
histogram/barchart chart, rather than adding 1 to it as the Plot-
(integer plot, inte- NewPoint function will do.
ger whichSig, inte-
ger whichBin, real
Value)
PlotNewPoint(inte- Adds and plots a new yValue point to the installed array. It is use- V

Functions
ger plot, integer ful when you want to see points plotted as they are calculated
whichSig, integer within a loop (such as during simulations). To use this effectively,
index, real yValue) first use InstallArray with a value of 0 for the plotPts argument.
PlotNewPoint increments the plotPts of the installed array when
the point is plotted, and the equation “y[index] = yValue” is inter-
nally executed, putting the new yValue into the installed array.
Note that the first value of index must be 0 when calling PlotNew-
Point for a newly installed array.
PlotSignalFormat Specifies the line format and number format for the trace. V
(integer plot, inte-
ger whichSig, inte-
ger lineFormat,
integer numFor-
mat)
350 Reference
Plotting/Charts

General plotting Description Return


PlotterAuto- Sets the limits for the autoscaling functionality in the specified
scaleLimits (inte- plot. Autoscaling will force the max and min values to these val-
ger plot, real minX, ues if they are set.
real maxX, real
minY, real maxY,
real minY2, real
maxY2)
PlotterBackground Specifies that the named picture should be used as the background I
(integer plot, string for the specified plotter. The picture file must be in the extensions
backName) folder. See “Picture and movie files” on page 89 for more infor-
mation on how external pictures are used in ExtendSim.
PlotterNameGet Returns the name of the specified plotter. S
(integer plot)
PlotterNam- Sets the name of the specified plotter. I
eSet(integer plot,
string newName)
PlotterSignalColor- Sets the color of the specified signal. This function will automati- V
Set(integer plot, cally set the color value of the signal to custom and will then
integer whichSig, define the custom color values to be the values you pass in.
integer Hue, integer
Sat, integer Value) As of ExtendSim 10, use PlotterSignalEColorSet instead.

PlotterSignalECol- Sets the color of the specified signal. See “EColors” on page 401. V
orSet (integer plot,
integer whichSig,
integer EColor-
Value)
PlotterSignalVal- Returns a value associate with the specified signal. The which- I
ueGet (integer plot, Value argument specifies the number of the signal:
integer whichSig, 0: Color (prior to ExtendSim 10)
integer which- 1: Hue (prior to ExtendSim 10)
Value) 2: Sat (prior to ExtendSim 10)
3: Value (prior to ExtendSim 10)
Functions

4: Signal visibility
5: use Y2Axis
6: Line format
7: Line symbol
8: Line thickness
10: EColor Value to set the signal line color
PlotterSignalValue- Sets the value of a specified aspect of a plotter signal. Which val- I
Set (integer plot, ues are the same as for PlotterSignalValueGet.
integer whichSig,
integer which-
Value, integer
value)
ModL Functions 351
Plotting/Charts

General plotting Description Return


PlotterSquare(inte- If true, forces the window to be square. If false, it removes the V
ger plot, integer squaring restriction.
trueFalse)
PlotterVal- Gets a setting value on the specified plotter or chart. “which” R
ueGet(integer plot, takes the following values:
integer which) 1: X axis decimal places
2: Y axis decimal places
3: Y2 axis decimal places
4: number of active traces (just get)
5: label angle for Bar Chart or pieSize for Pie Chart
PlotterValue- Sets a setting value on the specified chart or plotter. “which” takes I
Set(integer plot, the following values:
integer which, real 1: X axis decimal places
value) 2: Y axis decimal places
3: Y2 axis decimal places
5: label angle for Bar Chart or pieSize for Pie Chart
PlotterXAxisCal- Turns on or off Calendar date behavior on the x axis of the speci- V
endar(integer plot, fied plotter. The xAxisCalendar flag set to a true value will set the
integer xAxisCal- plotter to redraw with Calendar date values on the x Axis. The
endar, integer for- format parameter takes the following values:
mat) 0: everything
1: Just date, (ignore time)
2: Just time, (ignore date)
3: tight format. (Two digit year, and don't show time value if
zero.)
PlotterXAxisIs- This function sets a true/false flag in the specified plotter that tells V
Time(integer plot, the plotter if the X axis is defined as a time value or not. The pri-
integer xAxisTime) mary purpose for which the plotter uses this is for optimization. If
the X axis of the plotter is scaled to a certain max value, and the
next X value is beyond that value, the plotter knows that it is done
drawing because all subsequent X value will be higher than the
current values. Without this optimization, the DE plotter, which
is based on a scatter plotter, not a continuous plotter, will continue

Functions
to attempt to draw the rest of the points in the data unnecessarily.
PushPlotPic(inte- Pushes the top plot picture, page 1, down to page 2 of the plot V
ger plot) window. The oldest plot (page 4) is discarded. This function only
works if the plot is showing when the function is called.
RefreshPlot- Function that will redraw the plotter without opening the plotter V
ter(integer plot, window if it is closed. Used for redrawing the clones of a plotter
integer whole- when a change has occurred.
frame, integer
openPlotterWin-
dow)
RemoveSig- Removes the last installed array or function from the plot. V
nal(integer plot,
integer unused) For unused, enter any integer; 0 is suggested.
352 Reference
Plotting/Charts

General plotting Description Return


RenamePlot- Renames the plotter. V
ter(integer plot,
string newname)
RetimeAxis(inte- Sets the X axis values to the simulation start and end times. This V
ger plot) is useful for plotting simulation results without having to reset the
x axis values before a simulation is run.
RetimeAxisNStep This function is used to correct axis values when “Plot every nth V
(integer plot, inte- Point” is selected in the plotter’s dialog. As an example, see the
ger nStep) Plotter I/O block in the Plotter library.
SetAxisName(inte- Sets the Axis name of the specified Axis. whichAxis: I
ger plot, integer 1-x
whichAxis, string 2-y1
theName) 3-y2
SetSignalName Sets the name of signal whichSig. V
(integer plot, inte-
ger whichSig,
string theName)
SetTickCounts Specifies the number of ticks on the plotter axes in the plot. Spec- V
(integer plot, inte- ifying -1 as the parameter will use the current value.
ger xCount, integer
yCount, integer
y2Count)
ShowPlot(integer Opens and names the plot window. If the plot has never been V
plot, string plot- used, an empty plot is shown. Additional calls bring the window
Name) to the front. plotName is a string that contains the name of the
plot. Note that ShowPlot will not change the name of a plot that
was entered the plot dialog.
ShowPlot2(integer Shows the specified plotter. The only difference between this V
blockNumber, inte- function and ShowPlot is the block number argument, which
ger plot) allows you to show a plotter in a remote block.
Functions

SwitchPlotterRe- Specifies the direction in which the plot will be redrawn. A direc- V
draw(integer plot, tion of 0 specifies left to right, a direction of 1 specifies right to
integer direction) left. This only affects the way that the plot lines are redrawn when
the plot is complete.

Remember to call the ShowPlot function to replot any changes made by these functions. Be
sure to call ShowPlot after all calls that change the plot axis limits or formats.
The structure and contents of plots are saved with the model file, whether they were open or
not.
ModL Functions 353
Plotting/Charts

Pie and Bar chart functions

Pie charts Description Return


PieChart(integer Sets the specified plotter to be a Pie Chart. PieSize and holeSize V
plot, real pieSize, range from 0.0 to 1.0. PieSize specifies how big the Pie Chart is,
real holeSize relative to the size of the graph area. HoleSize specifies the same
for the hole in the middle of the Pie Chart. A hole size of greater
than 0.0 makes the Pie Chart a Donut Chart.
PieChartSlice(inte- Specifies the size and color of a slice of a Pie Chart. V
ger plot, integer
whichSlice, string Explode should be set to TRUE if the pie slice should be dis-
sliceLabel, long played separated from the rest of the Pie Chart.
color, long explode, Value is the relative size of the section.
real explodePer-
cent, real value)

Bar charts Description Return


BarChart(integer Sets the specified plotter to be a Bar Chart. When there are multi- V
plot, integer ple Series (i.e. a grouped bar chart), Stacked allows the bars to be
stacked) stacked on top of each other rather than next to each other.
BarChartCategory- Returns the specified value for the specified bar chart set. I
CountGet(integer
plot)
BarChartCategory- Sets the number of categories in the specified bar chart. New cate- V
CountSet(integer gories will be defined with empty strings. Will not change exist-
plot, integer num- ing categories.
Categories)
BarChartCategory- Returns the specified category name. Returns an empty string if S
Get(integer plot, the which value is out of range.
integer which)
BarChartCategory- Sets the specified category to the specified string. Has no effect if V

Functions
Set(integer plot, the which value is out of range.
integer which,
string catego-
ryName)
BarChartSet(inte- Creates a new set, or modifies an existing set in the specified Bar V
ger plot, integer set, Chart. Set is the index value of the set.
string setLabel,
integer color)
BarChartVal- Gets the value for a specified Bar Chart. R
ueGet(integer plot,
integer whichSet,
integer which-
Value)
354 Reference
Database functions

Bar charts Description Return


BarChartValue- Sets the values within a specific set in the Bar Chart. V
Set(integer plot,
integer whichSet,
integer which-
Value, real value)

Scatter plot functions


To plot scatter plots (XY plots), you need two additional functions. Scatter plot windows com-
bine two traces previously installed into a plot. The traces are combined into an XY trace,
where the first trace supplies the X values, and the second trace supplies the Y values. The val-
ues of the whichSig argument for the Scatter Plot functions must range from 0 to an even num-
ber minus one specifying the highest numbered scatter trace.

Scatter plots Description Return


MakeScatter (inte- Combines the two traces (the first specified by whichSig) into a V
ger plot, integer scatter trace. Both whichSig and whichSig+1 traces must be the
whichSig) same length and must have been installed by InstallArray before
MakeScatter is called.
PlotNewScatter Similar to plotNewPoint but for scatter plots. xValue is put into V
(integer plot, inte- whichSig and yValue is put into whichSig+1.
ger whichSig, inte-
ger index, real
xValue, real
yValue)

To see how the plotting functions can be used in your own blocks, examine the plotter func-
tions that are used in the code of the various blocks in the Chart library.
Database functions
These are used to create, read, write, import, export, and delete databases and their compo-
nents. They are used by blocks to create and manipulate databases during a run. All database
indexes are 1 based, so they start at 1 and end at N. Databases and tables maintain their
Functions

indexes, even when other databases or tables are deleted. Fields and record indexes can change
if earlier fields or records are deleted.
☞ Reserved databases use specially named functions to manipulate them so they don’t inadver-
tently get changed by the user or developer. These functions have the word “Reserved” in their
name.
Blocks can be linked to parts of the database, so if the database structure or data changes, they
will be notified and can take action. See “Dynamic linking” on page 317 and the LINK-
STRUCTURE and LINKCONTENT messages.
Error codes
For database read/write functions, the Database menu command “Read/Write Index Checking“
can enable error messages if a read/write function call has illegal indexes. This is a good tool to
find illegal indexes and leaving this check on does not impact the speed of a simulation run.
ModL Functions 355
Database functions

Leave it off if it is preventing a legacy model from running. New models have this check on by
default.
In most cases, functions return zero if no error, or non-zero error codes when an error occurs:

Error code Value Description


no such record -1 One of the indexes are incorrect.
no such parent -2 Trying to set a child field to a value that is not a parent value.
not unique error -3 Trying to set a cell to a non-unique value in a field with the “Unique”
property set.
not unique index >0 DBSetDataAs... functions will return the record index of the currently
existing unique value if you try to set a cell to a non-unique value.
not linked error -4 Returned by DBDataGetAsNumber() on a list of tables field if a table
name found in a database cell doesn’t exist and doesn’t have an index
in the database.

Creating and deleting database components

DB creating/deleting Description Return


DBDatabaseCreate Creates database databaseName and returns its index. Error: I
(string databaseName) returns negative error code if existing name already used.
DBDatabaseDe- Deletes entire database. Returns negative error code if DB I
lete(string data- doesn't exist.
baseName)
DBDatabaseDelete- Deletes entire database using index, returns error code. See I
ByIndex(integer data- also DBDatabaseDelete() in the Technical Reference.
baseIndex)
DBDatabaseTabDe- Deletes existingTabName tab in databaseIndex database I
lete(integer databa- viewer. Returns -1 if error.
seIndex, Str255

Functions
existingTabName)
DBFieldCreate(string Creates field fieldName with specified attributes tableName I
databaseName, string and returns its index. Error: returns negative error code if
tableName, string existing name already used.
fieldName, integer Field format constants defined:
fieldFormat, integer DB_FIELDTYPE_INTEGER_VALUE, DB_FIELD-
decimals, integer TYPE_INTEGER_BOOLEAN (checkbox), DB_FIELD-
unique, integer TYPE_REAL_GENERAL,
readOnly, integer DB_FIELDTYPE_REAL_SCIENTIFIC, DB_FIELDTYPE_-
invisible) REAL_PERCENT, DB_FIELDTYPE_REAL_CURRENCY,
DB_FIELDTYPE_REAL_DATE_TIME, DB_FIELDTYPE_-
REAL_DB_ADDRESS, DB_FIELD-
TYPE_STRING_VALUE, DB_FIELDTYPE_TABLELIST
356 Reference
Database functions

DB creating/deleting Description Return


DBFieldCreateByIn- Creates field fieldName using specified indexes, returns error I
dex(integer databa- code. See also DBFieldCreate() in the Technical Reference.
seIndex, integer
tableIndex, string field-
Name, integer field-
Format, integer
decimals, integer
unique, integer
readOnly, integer
invisible)
DBFieldDelete(string Delete field. Returns negative error code if field doesn't exist. I
databaseName, string
tableName, string
fieldName)
DBFieldDeleteByIn- Deletes field using index, returns error code. See also I
dex(integer databa- DBFieldDelete() in the Technical Reference.
seIndex, integer
tableIndex, integer
fieldIndex)
DBRecordsDe- Delete records from a table. Returns negative error code if I
lete(integer databa- table doesn't exist.
seIndex, integer
tableIndex, integer
startRecord, integer
endRecord)
DBRecordsInsert(inte- Insert at record index or append (insertAtRecord is zero) new I
ger databaseIndex, records to a table, returns tableIndex if ok. Returns negative
integer tableIndex, error code if table doesn't exist.
integer insertAtRecord,
integer numberRe-
cords)
DBRelationCre- Create relation, returns negative error code if anything doesn't I
ate(string data- exist.
Functions

baseName, string
tableChildName, string
fieldChildName, string
tableParentName,
string fieldParent-
Name)
DBRelationDe- Delete relation. Returns negative error code if relation doesn't I
lete(string data- exist.
baseName, string
tableChildName, string
fieldChildName, string
tableParentName,
string fieldParent-
Name)
ModL Functions 357
Database functions

DB creating/deleting Description Return


DBTableCloneTo- Creates the tabName if not there, and clones the table to the V
Tab(integer databa- tab.
seIndex, integer
tableIndex, string tab-
Name)
DBTableCreate (string Creates table tableName and returns its index. Error: returns I
databaseName, string negative error code if existing name already used.
tableName)
DBTableCreateByIn- Creates table tableName in current database using indexes, I
dex(integer databa- returns negative error code. See also DBTableCreate() in the
seIndex, string Technical Reference.
tableName)
DBTableDelete(string Delete table. Returns negative error code if Table doesn't exist. I
databaseName, string
tableName);
DBTableDeleteByIn- Deletes table using index, returns error code. See also DBTa- I
dex(integer databa- bleDelete() in the Technical Reference.
seIndex, integer
tableIndex)
DBToolTipsGet(inte- Gets the string value of the tooltip. S
ger databaseIndex, 1) All indexes good, gets field tooltip.
integer tableIndex, 2) FieldIndex is zero, gets table tooltip.
integer fieldIndex) 3) Field and Table index zero, gets database tooltip.
DBToolTipsSet(inte- Sets the tooltip to value. I
ger databaseIndex, 1) All indexes good, sets field tooltip.
integer tableIndex, 2) FieldIndex is zero, sets table tooltip.
integer fieldIndex, 3) Field and Table index zero, sets database tooltip.
string value)

Selecting parts of a database


These functions open a database component selection dialog so the user can select a desired

Functions
component.

DB selecting Description Return


DBChildPopupSelec- Opens a child field parent value selector similar to clicking on I
tor(integer databaseIn- a child field popup arrow, and changes the child value accord-
dex, integer ing to which parent value the user selects. If trueForSelector-
tableIndex, integer Dialog is TRUE, a selector dialog is shown with a scroll bar,
fieldIndex, integer good for a large numbers of parent values. If FALSE, a popup
recordNum, integer menu is shown, which is good for a small number of parent
trueForSelectorDialog) values.
Returns the selected parent record index or zero if cancelled.
358 Reference
Database functions

DB selecting Description Return


DBDatabasePopupSe- Opens a database selector dialog and selects the currentDBIn- I
lector(real currentD- dex if not BLANK or zero. If BLANK or zero, doesn’t select
BIndex) any entries in the list.
Returns the selected database index or zero if cancelled.
DBFieldPopupSelec- Opens a field selector dialog and selects the currentFieldIndex I
tor(integer databaseIn- if not BLANK or zero. If BLANK or zero, doesn’t select any
dex, integer entries in the list.
tableIndex, real cur-
rentFieldIndex) Returns the selected field index or zero if cancelled.

DBRecordPopupSelec- Opens a record selector dialog and selects the currentRe- I


tor(integer databaseIn- cordIndex if not BLANK or zero. If BLANK or zero, doesn’t
dex, integer select any entries in the list.
tableIndex, integer
fieldIndex, real curren- Returns the selected record index or zero if cancelled.
tRecordIndex)
DBTablePopupSelec- Opens a table selector dialog and selects the currentTableIn-
tor(integer databaseIn- dex if not BLANK or zero. If BLANK or zero, doesn’t select
dex, integer any entries in the list.
tableIndex)
Returns the selected table index or zero if cancelled.

Copying parts of a database

DB copy Description Return


DBDatabaseC- Copies entire database to a new database. Returns index of the I
opy(integer fromData- new database or -1 if error (bad index or same name as exist-
baseIndex, string ing database).
newDatabaseName)
DBTableCopy(integer Copies and optionally renames an existing table into its cur- I
fromDatabaseIndex, rent database (must use newTableName) or another database
integer fromTableIn- (If newTableName is blank, keeps the existing table name).
Functions

dex, integer toDataba- Returns index of the new table or -1 if error (bad index or
seIndex, string same table name as existing table in that database).
newTableName)

Import and export a database

DB import/export Description Return


DBDatabaseEx- Export database to DB text file pathName. If pathName is a I
port(string data- blank string, let the user select a text file. Returns -1 if error.
baseName, string
pathName)
ModL Functions 359
Database functions

DB import/export Description Return


DBDatabaseIm- Import database from text file pathName, replacing the data- I
port(string data- base named databaseName or creating it if it didn’t exist. If
baseName, string the database name is in the form “databaseName<delete>”, it
pathName) deletes any left over tables that were not imported in this file.
If pathName is a blank string, let the user select a text file.
Returns the database index or -1 if it fails. Sends both a Link-
Structure message (what changed: DB replaced) and a Link-
Content message (what changed: data changed) to linked
blocks. See DILinkUpdateInfo() for an explanation of what
changed.
DBTableExport- Exports the table data to a delimited text file. If pathName is a I
Data(string pathName, blank string, lets the user select a text file. If format is a blank
string userPrompt, string, uses a tab as delimiter (see Import() functions). If the
string format, integer databaseIndex is negative, it outputs the field names (sepa-
databaseIndex, integer rated by delimiters) as the first line of the text file. Returns -1
tableIndex, integer if error.
rows, integer columns)
DBTableImport- Imports a delimited text file into a database table and returns I
Data(string pathName, the number of rows imported. If format is a blank string, uses
string userPrompt, a tab as delimiter (see Import() functions). If databaseIndex is
string format, integer negative, it assumes that the first line of the text file contains
databaseIndex, integer the field names and skips that line.
tableIndex)
This function maintains existing relations in the table but will
discard relations that violate parent/child data requirements:
all child data in a relation must be blank or exist in the parent
data set.
NOTE: This function automatically resizes the table to the
number of rows imported, so you do not need to allocate any
records in the table before calling this function.

Database properties

Functions
DB properties Description Return
DBDatabaseExists Passing in a database index, returns TRUE if the database I
(integer databaseIn- exists, FALSE if it doesn’t exist. Also see DBTableExists(),
dex) DBFieldExists(), and DBRecordExists().
DBDatabaseGetIn- Returns database index or negative error if not found. I
dex(string data-
baseName)
DBDatabaseGet- Gets the name of the database or blank string if bad index. S
Name(integer databa-
seIndex)
360 Reference
Database functions

DB properties Description Return


DBDatabaseRe- Renames a database. Returns a negative error code if newDa- I
name(integer databa- tabaseName already exists or the old database doesn't exist.
seIndex, string
newDatabaseName)
DBDatabasesGet- Because database indexes remain constant even if some data- I
Num() bases are deleted, this returns number of database slots of
which some could be empty. To count how many actual data-
bases there are, use a loop and count the databases that have a
non-blank name.
DBDatabaseShowHid- Use this to hide or show reserved databases without using the V
eReserved(integer menu command. Reserved databases are discussed on
showIfTrueHideIf- page 112.
False)
Note: When the model closes, the reserved databases return to
being hidden. So this command must be called again when-
ever the model is opened.
DBDatabaseTabChan- Changes the name of existingTabName to newTabName in I
geName(integer data- databaseIndex database viewer. Returns -1 if error.
baseIndex, Str255
existingTabName,
Str255 newTabName)
DBFieldExists(integer Passing in a database index, table index, field index, returns I
databaseIndex, integer TRUE if the field exists, FALSE if it doesn’t exist. Also see
tableIndex, integer DBDatabaseExists(), DBTableExists(), and DBRecordEx-
fieldIndex) ists().
DBFieldGetIndex(inte- Returns field index or negative error if not found. I
ger databaseIndex,
integer tableIndex,
string fieldName)
DBFieldGet- Gets the name of the field or blank string if bad index. S
Name(integer databa-
seIndex, integer
Functions

tableIndex, integer
fieldIndex)
DBFieldGetProper- which: I
ties(integer databaseIn- 1: fieldType
dex, integer 2: fieldDecimals
tableIndex, integer 3: fieldUnique
fieldIndex, integer 4: fieldReadOnly
which) 5: fieldInvisible
6: IfFieldID
7: isParentField (note: use judiciously; this is very slow)
8: isChildField, (note: use judiciously; this is very slow)
-1 if error
Also see the DBFieldCreate() function on page 355.
ModL Functions 361
Database functions

DB properties Description Return


DBFieldGetPropertie- This uses a DBAddress (see the DBAddress functions). I
sUsingAddress(real
dbAddress, integer For the values of which, see the DBFieldGetProperties func-
which) tion, above.
Also see the DBFieldCreate() function on page 355.
DBFieldMove(integer Moves field fieldName to newFieldIndex, moving other fields I
databaseIndex, integer in the process. Returns a negative when indexes are incorrect.
tableIndex, integer
fieldIndex, integer
newFieldIndex)
DBFieldRename(inte- Renames a field. Returns a negative error code if the field I
ger databaseIndex, already exists or the old field doesn't exist.
integer tableIndex,
integer fieldIndex,
string newFieldName)
DBFieldSetInitial- Set the field's initialization parameters. I
ize(integer databaseIn- initFlag: 0 no init (default), 1 init to initDataValue.
dex, integer initSimFlag: 0 init each run (default), 1 init first run of multi-
tableIndex, integer sim.
fieldIndex, integer init- value: what value to init the field, real or string for string
Flag, integer initSim- fields.
Flag, string value) Returns an error code if bad indexes.
DBFieldSetProper- which: 1: fieldType, 2: fieldDecimals, 3: fieldUnique, 4: fiel- I
ties(integer databaseIn- dReadOnly, 5: fieldInvisible, 6: IfFieldID. Returns -1 if index
dex, integer error. See the DBFieldCreate() function, above.
tableIndex, integer
fieldIndex, integer
which, integer
newValue)
DBFieldsGet- Returns number of fields. Returns negative error code if no I
Num(integer databa- fields or no such table index.
seIndex, integer

Functions
tableIndex)
DBRecordExists(inte- Passing in a database index, table index, field index, record I
ger databaseIndex, index, returns TRUE if the record (database cell) exists,
integer tableIndex, FALSE if it doesn’t exist. Also see DBDatabaseExists(),
integer fieldIndex, DBTableExists(), and DBFieldExists().
integer recordIndex)
362 Reference
Database functions

DB properties Description Return


DBGetSize(integer Used to find the amount of memory used by the DB. Returns R
databaseIndex, integer the size in bytes of the selected database, table, or field by
tableIndex, integer specifying its indexes. If the index is -1, all of the sizes of the
fieldIndex) databases, tables, or fields are added up. For example, if data-
baseIndex is -1, the size of all of the databases are totaled and
returned. If any of the indexes are -1, the next indexes are
ignored, so if the databaseIndex is 1, tableIndex is -1, and
fieldIndex is 2, the function ignores the fieldIndex and returns
the sum of sizes of all of the tables in databaseIndex 1.
DBRecordID- Returns field index of the recordID field, if any. Returns neg- I
FieldGetIndex(integer ative error if no fieldID found.
databaseIndex, string
tableName)
DBRecordsGet- Returns number of records in a table. Returns negative if no I
Num(integer databa- such table index.
seIndex, integer
tableIndex)
DBRelationsGet- Returns zero error code and tableChild, fieldChild, tablePar- I
Names(integer databa- ent, fieldParent in string relationNames[4]
seIndex, integer
relationIndex, string
relationNames[])
DBRelationsGet- Returns number of relations in the DB. Returns negative error I
Num(integer databa- code if no DB.
seIndex)
DBTableExists (inte- Passing in a database and table index, returns TRUE if the I
ger databaseIndex, table exists, FALSE if it doesn’t exist. Also see DBDatabase-
integer tableIndex) Exists(), DBFieldExists(), and DBRecordExists().
DBTabGetTableIndex- Puts database table indexes in integerArray, where indexes I
List(integer databa- represent the tables in the tab named tabName. IntegerArray is
seIndex, string a dynamic array declared as integer integerArray[]. Returns an
tabName, integer inte- integer that specifies how many table indexes are in integerAr-
Functions

gerArray) ray. Returns -1 if the either or both of the databaseIndex or the


tabName don't exist.
DBTableGetIn- Returns table index or negative error if not found. I
dex(integer databa-
seIndex, string
tableName)
DBTableGetProper- Returns the initialization method: 0 is no initialization, 1 is I
ties(integer databaseIn- delete all records for all runs, 2 is delete all records for only
dex, integer the first run. Returns -1 if error.
tableIndex)
ModL Functions 363
Database functions

DB properties Description Return


DBTableGet- Gets the name of the table or blank string if bad index. S
Name(integer databa-
seIndex, integer
tableIndex)
DBTableSetProper- Sets the initialization method: 0 is no initialization, 1 is delete I
ties(integer databaseIn- all records for all runs, 2 is delete all records for only the first
dex, integer run. Returns -1 if error.
tableIndex, integer ini-
tializeMethod)
DBTableRename(inte- Renames a table. Returns a negative error code if the table I
ger databaseIndex, already exists or old table doesn't exist.
integer tableIndex,
string newTableName)
DBTablesGet- Because table indexes remain constant even if some tables are I
Num(integer databa- deleted, returns number of table slots of which some could be
seIndex) empty. To count how many actual databases there are, use a
loop and count the tables that have a non-blank name.

Read and write to a database


☞ Note that reading a “List of Tables” field returns the table index if read as a number, and the
name of the table if read as a string.

DB read/write Description Return


DBDataGetAsNum- Reads the value as a number without any formatting. Note that R
ber(integer databaseIn- random distributions in cells will return a different random
dex, integer number each time that this function is called.
tableIndex, integer
fieldIndex, integer Note: Using this function to read a “List of Tables” field
recordIndex) returns the index of the table read.

DBDataGetAsNum- This function, when called with a child DBAddress, allows R


berParentAltField(real returning the value from a different field of the parent record.

Functions
childDBAddress, inte- Reads the value as a number without any formatting. Note that
ger altFieldIndex) random distributions in cells will return a different random
number each time that this function is called.
Note: Using this function to read a “List of Tables” field
returns the index of the table read.
DBDataGetAsNumbe- Using a DBAddress, read the value as a number without any R
rUsingAddress(real formatting. Note that random distributions in cells will return
dbAddress) a different random number each time that this function is
called.
Note: Using this function to read a “List of Tables” field
returns the index of the table read.
364 Reference
Database functions

DB read/write Description Return


DBDataGe- Reads the value as a string at full precision. Percentage format S
tAsString(integer data- returns the normalized value as “1.00” for database cells that
baseIndex, integer read 100%. NOTE that if the table is a table of tables, this
tableIndex, integer returns the table name (see DBGetDataAsNumber() below.
fieldIndex, integer Note that random distributions in cells will return a different
recordIndex) random number each time that this function is called.
Note: Using this function to read a “List of Tables” field
returns the name of the table read.
DBDataGetAsString- This function, when called with a child DBAddress, allows S
ParentAltField(real returning the value from a different field of the parent record.
childDBAddress, inte- Reads the value as a string at full precision. Percentage format
ger altFieldIndex) returns the normalized value as “1.00” for database cells that
read 100%. NOTE that if the table is a table of tables, this
returns the table name (see DBGetDataAsNumber() below.
Note that random distributions in cells will return a different
random number each time that this function is called.
Note: Using this function to read a “List of Tables” field
returns the name of the table read.
DBDataGetAsStrin- Using a DBAddress, read the value as a string at full precision. S
gUsingAddress(real Percentage format returns the normalized value as “1.00” for
dbAddress) database cells that read 100%. NOTE that if the table is a table
of tables, this returns the table name (see DBGetDataAsNum-
ber() below. Note that random distributions in cells will return
a different random number each time that this function is
called.
Note: Using this function to read a “List of Tables” field
returns the name of the table read.
DBDataGetDateAs- Reads a database cell as a date, and converts it to a simulation R
SimTime(integer dbIn- time value. This allows the user to read a date value directly
dex, integer as a simulation time value, avoiding the conversion process.
tableIndex, integer
fieldIndex, integer
Functions

recordIndex, integer
timeUnits)
DBDataGetDateAs- Using a dbAddress, reads a database cell as a date, and con- R
SimTimeUsingAd- verts it to a simulation time value. This allows the user to read
dress(real a date value directly as a simulation time value, avoiding the
addressValue, integer conversion process.
timeUnits)
ModL Functions 365
Database functions

DB read/write Description Return


DBDataGetPar- Gets the parent information from a child field. Use it to either I
ent(integer databaseIn- return these database indexes of the parent:
dex, integer parentArray[0] returns parent Table index
tableIndex, integer parentArray[1] returns parent Field index
fieldIndex, integer parentArray[2] returns parent Record index (or zero if no child
recordIndex, integer value has been set)
parentArray[3]) Or, as with parentArray[2], to return the parent record index
(or zero if no child value has been set).
Returns a negative error code.
DBDataGetParentUs- Using a DBAddress, gets the parent information from a child I
ingAddress(real dbAd- field address. Use it to either return these database indexes of
dress, parentArray[3]) the parent:
parentArray[0] returns parent Table index
parentArray[1] returns parent Field index
parentArray[2] returns parent Record index (or zero if no child
value has been set)
Or, as with parentArray[2], to return the parent record index
(or zero if no child value has been set).
Returns a negative error code.
DBDataSetAsNum- Write value of field as number to a record. Returns a negative I
ber(integer databaseIn- error code. Only sends LINKCONTENT message to block if
dex, integer value has changed. If setting a unique field cell to a non-
tableIndex, integer unique value, returns the record index of the original unique
fieldIndex, integer value. This function does not work with reserved databases.
recordIndex, real val- See DBDataSetAsNumberReserved(), which works only with
ueDouble) reserved databases.
DBDataSetAsNumber- This function works only with reserved databases. Otherwise, I
Reserved(integer data- it is the same as DBDataSetAsNumber(), which works only
baseIndex, integer with non-reserved databases.
tableIndex, integer
fieldIndex, integer
recordIndex, real val-
ueDouble)

Functions
DBDataSetAsNumbe- Using a DBAddress, write value of field as number to a I
rUsingAddress(real record. Returns a negative error code. Only sends LINKCON-
dbAddress, real val- TENT message to block if value has changed.If setting a
ueDouble) unique field cell to a non-unique value, returns the record
index of the original unique value. See DBDataSetAsNumbe-
rUsingAddressReserved(), which works only with reserved
databases.
DBDataSetAsNumbe- This function works only with reserved databases. Otherwise, I
rUsingAddressRe- it is the same as DBDataSetAsNumberUsingAddress(), which
served(real dbAddress, works only with non-reserved databases.
real valueDouble)
366 Reference
Database functions

DB read/write Description Return


DBDataSetAsPar- For a child field, sets the parent index directly rather than with I
entIndex(integer data- DBPutDataAs... functions trying to set the parent index by
baseIndex, integer finding the data value in the parent. Only sends LINKCON-
tableIndex, integer TENT msg to block if value changed. Note that you can set
fieldIndex, integer the parentIndex to zero if you want to set the child value to
recordIndex, integer <no value yet>. See DBDataSetAsParentIndexReserved(),
parentIndex) which works only with reserved databases.
DBDataSetAsPar- This function works only with reserved databases. Otherwise, I
entIndexRe- it is the same as DBDataSetAsParentIndex(), which works
served(integer only with non-reserved databases.
databaseIndex, integer
tableIndex, integer
fieldIndex, integer
recordIndex, integer
parentIndex)
DBDataSetAsPar- Using a DBAddress for a child field, sets the parent index I
entIndexUsingAd- directly rather than with DBPutDataAs... functions trying to
dress(real dbAddress, set the parent index by finding the data value in the parent.
integer parentIndex) Only sends LINKCONTENT msg to block if value changed.
Note that you can set the parentIndex to zero if you want to set
the child value to <no value yet>. See DBDataSetAsParentIn-
dexUsingAddressReserved(), which works only with reserved
databases.
DBDataSetAsPar- This function works only with reserved databases. Otherwise, I
entIndexUsingAd- it is the same as DBDataSetAsParentIndexUsingAddress(),
dressReserved(real which works only with non-reserved databases.
dbAddress, integer par-
entIndex)
DBDataSe- Write value of field as string to a record. Percentage format I
tAsString(integer data- expects the normalized value as “1.00” for database cells that
baseIndex, integer read 100%. Returns a negative error code. Only sends LINK-
tableIndex, integer CONTENT message to block if value has changed.If setting a
fieldIndex, integer unique field cell to a non-unique value, returns the record
Functions

recordIndex, string val- index of the original unique value. See DBDataSetAsStrin-
ueString) gReserved(), which works only with reserved databases.
DBDataSetAsStrin- This function works only with reserved databases. Otherwise, I
gReserved(integer it is the same as DBDataSetAsString(), which works only with
databaseIndex, integer non-reserved databases.
tableIndex, integer
fieldIndex, integer
recordIndex, string val-
ueString)
ModL Functions 367
Database functions

DB read/write Description Return


DBDataSetAsStrin- Using a DBAddress, write value of field as string to a record. I
gUsingAddress(real Percentage format expects the normalized value as “1.00” for
dbAddress, string val- database cells that read 100%. Returns a negative error code.
ueString) Only sends LINKCONTENT message to block if value has
changed.If setting a unique field cell to a non-unique value,
returns the record index of the original unique value. See
DBDataSetAsStringUsingAddressReserved(), which works
only with reserved databases.
DBDataSetAsStrin- This function works only with reserved databases. Otherwise, I
gUsingAddressRe- it is the same as DBDataSetAsStringUsingAddress(), which
served(real dbAddress, works only with non-reserved databases.
string valueString)
DBDataSetDateAs- Takes a simulation time value, converts it to a date, and sets a I
SimTime(integer dbIn- DB cell with that date value. See DBDataSetDateAsSimTim-
dex, integer eReserved(), which works only with reserved databases.
tableIndex, integer
fieldIndex, integer
recordIndex, real sim-
TimeVal, integer
timeUnits)
DBDataSetDateAs- This function works only with reserved databases. Otherwise, I
SimTimeRe- it is the same as DBDataSetDateAsSimTime(), which works
served(integer only with non-reserved databases.
dbIndex, integer
tableIndex, integer
fieldIndex, integer
recordIndex, real sim-
TimeVal, integer
timeUnits)
DBDataSetDateAs- Using a dbAddress, takes a simulation time value, converts it I
SimTimeUsingAd- to a date, and sets a DB cell with that date value. See DBData-
dress(real SetDateAsSimTimeUsingAddressReserved(), which works
addressValue, real sim- only with reserved databases.

Functions
TimeVal, integer
timeUnits)
DBDataSetDateAs- This function works only with reserved databases. Otherwise, I
SimTimeUsingAd- it is the same as DBDataSetDateAsSimTimeUsingAddress()
dressReserved(real which works only with non-reserved databases.
addressValue, real sim-
TimeVal, integer
timeUnits)
368 Reference
Database functions

Random data in a database

DB random data Description Return


DBDataGetCurrent- Returns current running seed value from a random cell speci- I
Seed(integer databa- fied by indexes. Returns zero if bad cell.
seIndex, integer
tableIndex, integer
fieldIndex, integer
recordIndex)
DBDataSetCurrent- Sets current running seed value for a random cell specified by I
Seed(integer databa- indexes. Returns 0 if bad cell.
seIndex, integer
tableIndex, integer
fieldIndex, integer
recordIndex, integer
seedValue)
Functions
ModL Functions 369
Database functions

DB random data Description Return


DBRandomDistribu- Gets the cell's distribution, if any assigned. Returns the info on S
tionGet(integer databa- the distribution in the returnParams array. Can use locally or
seIndex, integer statically declared returnParams (Real returnParams[10]) and
tableIndex, integer empTable (Real empTable[maxEmpiricalrows][2]) or dynamic
fieldIndex, integer arrays for returnParams[], empTable[][2]; If using dynamic
recordIndex, string arrays, no Makearray() needed. You can dispose dynamic
distName, real arrays after the call if not needed (Local arrays allow use in an
params[],real empT- Equation block).
able[][2])
Case: All database indexes good (ignores distName), return
info for a DB cell:
1) Return all info in arrays. Function returns name of distribu-
tion or blank if not named.
2) Return distributionIndex of 0 in array if not a random cell.

Case: Only databaseIndex is good, rest are zero. Return info


for distName named distribution, if it exists:
1) If distName is good name: Return all info for that distribu-
tion (useSeed and seedInit will be zero as it is defined for each
DB cell).
2) distName doesn’t exist: Return string “-1”
Note that the returned distributionIndex values are the same
as used in the RandomCalculate() function, with these addi-
tions:
EmpiricalDiscrete 200
EmpiricalStepped 201
EmpiricalInterpolated 202

returnParams[0] = distributionIndex;
returnParams[1] = meanDistParam1;
returnParams[2] = argDistParam2;
returnParams[3] = modeParam3;
returnParams[4] = locationParam4;
returnParams[5] = lowerLimit;
returnParams[6] = upperLimit;

Functions
returnParams[7] = useSeed;
returnParams[8] = seedInit;
returnParams[9] = empiricNumRows;
empTable contains the empirical distribution array, if any.
370 Reference
Database functions

DB random data Description Return


DBRandomDistribu- This can be used in several cases: I
tionSet(integer databa-
seIndex, integer 1) Define or modify a named random distribution without set-
tableIndex, integer ting a DB cell to it (must use this for empirical distributions):
fieldIndex, integer a) Set databaseIndex, other DB indexes should be zero:
recordIndex, string b) Use distributionIndex to set the distribution type.
distName, integer dis- c) Set remaining params for this distribution.
tributionIndex, real d) Fill empTable if this is an empirical distribution.
param1, real param2, 2) Set a DB cell to a named random distribution (must use this
real param3, real loca- for empirical distributions):
tionParam4, real low- a) Set all DB indexes to point to a DB cell.
erLimit, real b) Set distribution name as it is defined in database or via case
upperLimit, integer 1 above.
useSeed, integer seedI- c) Set useSeed and seedInit for this DB cell. Other parameters
nit, real empTable[][2]) are ignored as name defines distribution to use.
3) Set a DB cell to an unnamed non-empirical random distri-
bution:
a) Set all DB indexes to point to a DB cell.
b) Set distribution name to ““ (blank string).
c) Set distribution index and parameters as in case 1 above.
4) Remove the random distribution from a cell and make it a
constant:
a) Set all DB indexes to point to a DB cell.
b) Set distribution name to ““ (blank string).
c) Set distribution index to zero.
Note that the distributionIndex values are the same as used in
the RandomCalculate() function, with these additions:
EmpiricalDiscrete 200
EmpiricalStepped 201
EmpiricalInterpolated 202

Returns -1 as error.
Functions
ModL Functions 371
Database functions

Sort and search in a database

DB sort/search Description Return


DBRecordFind(inte- Finds a record and returns index of record found. If fieldIndex I
ger databaseIndex, is zero, uses RecordID field for search. startingRecordIndex
integer tableIndex, can be zero or one to start at the first record. To keep searching
integer notRecordID- for more matches, increment the returned record index by one
FieldIndex, integer for startingRecordIndex. If exactMatch is FALSE, finds
startingRecordIndex, record containing findValue without having to match entire
integer exactMatch, field value.
string findValue)
Returns 0 if record not found. Returns negative error if index
error.
NOTE: Different find functions return different error codes
because of legacy concerns.
DBRecordFindMulti- Finds a record and returns index of record found. Up to 3 I
pleFields(integer data- fields can be searched. If only one is searched, make both
baseIndex, integer fieldIndex2, fieldIndex3 zero. If only two are searched, make
tableIndex, integer fieldIndex3 zero. StartingRecordIndex can be zero or one to
startingRecordIndex, start at the first record. To keep searching for more matches,
integer fieldIndex1, increment the returned record index by one for startingRe-
string findValue1, inte- cordIndex. If exactMatch is FALSE, finds record containing
ger exactMatch1, inte- findValue without having to match the entire field value.
ger fieldIndex2, string
findValue2, integer Returns -1 if record not found or index error.
exactMatch2, integer NOTE: Different find functions return different error codes
fieldIndex3, string because of legacy concerns.
findValue3, integer
exactMatch3)
DBRecordFindMulti- Finds a record and returns index of record found. Any number I
pleFieldsArray(integer of fields can be searched. Create three arrays that can be local,
databaseIndex, integer static or dynamic. For example, to declare local arrays in an
tableIndex, integer Equation block to search 4 fields:
startingRecordIndex,
integer fieldIndexAr- integer fieldIndexArray[4], exactMatchArray[4];

Functions
ray[], string findValue- string findValueArray[4];
Array[], integer The arrays can be larger than you need as only nonzero
exactMatchArray[]) fieldIndexArray members will be searched. The first zero
fieldIndex will end the fields searched. StartingRecordIndex
can be zero or one to start at the first record. To keep searching
for more matches, increment the returned record index by one
for startingRecordIndex. If exactMatch is FALSE, finds
record containing findValue without having to match the
entire field value.
Returns -1 if record not found or index error.
NOTE: Different find functions return different error codes
because of legacy concerns.
372 Reference
Database functions

DB sort/search Description Return


DBRecordFindNumer- Finds a record and returns index of record found where num- I
icalRange(integer data- ber >= lowerDouble and <= upperDouble. To find exactly,
baseIndex, integer make lowerDouble and upperDouble the same. If fieldIndex is
tableIndex, integer zero, uses RecordID field for search. StartingRecordIndex can
notRecordIDFieldIn- be zero or one to start at the first record. To keep searching for
dex, integer startingRe- more matches, increment the returned record index by one for
cordIndex, real startingRecordIndex.
lowerDouble, real
upperDouble) Returns 0 if record not found or index error.
NOTE: Different find functions return different error codes
because of legacy concerns.
DBRecordFindParen- Returns the index of the child record found pointing to start- I
tRecordIndex(integer ingParentIndex. StartingRecordIndex can be 0 or 1 to start at
databaseIndex, integer the first record. To keep searching for more matches, incre-
tableIndex, integer ment the returned record index by 1 for startingRecordIndex.
childFieldIndex, inte- Returns index of found record or 0 for record not found, -1 for
ger startingRecordIn- indexing error.
dex, integer
findParentIndexValue)
DBTableSort(integer Sorts the table using up to three fields and directions. Set the I
databaseIndex, integer fieldIndexes of the fields you need sorted, and set the other
tableIndex, integer fieldIndexes to zero. For example, if you want to sort only one
fieldIndex1, integer field, set fieldIndex1 to that field index and set fieldIndex2
direction1, integer and 3 to zero. The direction arguments are TRUE for ascend-
fieldIndex2, integer ing and FALSE for descending. Returns -1 if there is an error.
direction2, integer
fieldIndex3, integer
direction3)

DB address functions
These functions stuff the database or global array component indexes into a real number. For
databases, it includes the database index, table index, field index, and record index. The result-
ing real number is very useful as an attribute value that can completely describe a database or
Functions

global array address.


Depending on whether there are more than 1 million records, the top index limits for DB
Addresses are:

Component Algorithm 1 Algorithm 2


Databases 500 500
Tables 10,000 1,000
Fields 1,000 1,000
Records 1,000,000 10,000,000

Depending on the number of records needed, ExtendSim automatically switches to the correct
algorithm. For example, Algorithm #2 is used if more than 1 million records are needed.
ModL Functions 373
Database functions

DB address Description Return


DBAddressCre- Returns a DBAddress value from the indexes. R
ate(integer databaseIn-
dex, integer
tableIndex, integer
fieldIndex, integer
recordIndex)
DBAddress- Return the indexes from a DBAddress value. ReturnIndexe-
GetAllIndexes(real sArray can be declared as a local variable array (can be
addressValue, integer declared in equation blocks):
returnIndexesArray[4]) integer returnIndexesArray[4];
returnIndexesArray[0] returns Database index
returnIndexesArray[1] returns Table index
returnIndexesArray[2] returns Field index
returnIndexesArray[3] returns Record index
DBAddress- Returns the string representation of a DBAddress value. S
GetAsString(real
addressValue)
DBAddressGet- Puts up a dialog for the user to specify the coords of a DBAd- R
Dlg(real theInitVal) dress. theInitVal is a starting value. BLANK leaves all blank.
DBAddressGet- Similar to DBAddressGetDlg. Displays a dialog so the user R
Dlg2(integer DBIn- can enter a database address. Note that in addition to entering
dex, integer the DB coordinates as separate values, you can also pass -2 for
tableIndex, integer a DB coordinate, and this will hide that coordinate on the dia-
fieldIndex, integer log. This allows you to enter just a DB index, for example, or
recordIndex) just a DB and table index. Returns a database address.
DBAddressGetFrom- Returns the real database address when the string argument is R
String(string dbAd- of the form “D:T:F:R” where D, T, F, and R are the numerical
dressStr) indexes of the address.
DBAddressIncre- Increments or decrements (negative incrementValue) a DBAd- R
mentIndex(real dress. whichElement: 1: database, 2: table, 2: field, 4: record

Functions
addressValue, integer
whichElement, integer
incrementValue)
DBAddressReplaceIn- Replaces part of a DBAddress with newValue. whichElement: R
dex(real addressValue, 1: database, 2: table, 3: field, 4: record
integer whichElement,
integer newValue)
DBDatabaseGetIndex- Returns a dabase index from the DBAddress value. I
FromAddress(real
addressValue)
DBFieldGetIndexFro- Returns a field index from the DBAddress value. I
mAddress(real
addressValue)
374 Reference
Database functions

DB address Description Return


DBRecordGetIndex- Returns a record index from the DBAddress value. I
FromAddress(real
addressValue)
DBTableGetIndexFro- Returns a table index from the DBAddress value. I
mAddress(real
addressValue)

Viewing a database

DB viewing Description Return


DBDatabaseOpen- Opens the desired database table and scrolls to and selects the I
Cell(integer databa- cell specified by fieldIndex and recordIndex. Returns a -1 if
seIndex, integer indexes are bad.
tableIndex, integer
fieldIndex, integer
recordIndex)
DBDatabaseOpen- Open the table data viewer. If tableName is blank or doesn't I
Viewer(integer databa- exist, open the default database viewer. Returns table index if
seIndex, string successful or -1 if error.
tableName)
DBDatabaseOpen- Opens the table data viewer. If tableName is blank or doesn't I
ViewerToTab(integer exist, open the default database viewer. If openTabName
databaseIndex, Str255 exists, opens to that tab. If it is blank or doesn't exist, opens
tableName, Str255 the last clicked tab. Returns table index if successful or -1 if
openTabName) error.
DBDatabaseClose- Close the table data viewer. If tableName is blank or doesn't I
Viewer(integer databa- exist, close the database viewer. Returns table index if suc-
seIndex, string cessful or -1 if error.
tableName)

Linking and notification


Functions

These functions register and unregister blocks from databases, independent of dialog items and
their links, so linked blocks can be notified if the data that they are depending on changes in
structure or content. This type of linking is different than user linking of parameters and data
tables to a database because you don’t specify anything to link. If the database changes content
(e.g. the value in a cell that you registered changes) you will get a LINKCONTENT message.
If the database table that you are linked to changes name or number of fields or rows, you will
get a LINKSTRUCTURE message. Please see “Dynamic linking” on page 317, for informa-
tion on finding out what changed when you get the LINKCONTENT, or LINKSTRUCTURE
messages.
☞ All registration set up by DBBlockRegisterContent() or DBBlockRegisterStructure() is good
only for this model session. This disposal of links is done to prevent obsolete links sending
unneeded messages that could slow down a simulation.
ModL Functions 375
Database functions

When the model is closed and reopened, you will have to call these functions again (usually in
the OPENMODEL message handler) for all links that you want.
For an overview, see “Registered blocks” on page 111.

DB linking/notify Description Return


DBBlockRegisterCon- This will register the block with the selected part of the data- I
tent(integer block- base so it will get LINKCONTENT messages when that data
Number, integer is changed. Returns negative code if block not found. Note
databaseIndex, integer that for content registration, individual cells as well as whole
tableIndex, integer databases, tables, fields, and records can be registered.
fieldIndex, integer If databaseIndex is negative, register all databases.
recordIndex) If tableIndex is negative, register all tables.
If fieldIndex is negative and recordIndex is negative, register
all cells in table.
If fieldIndex is negative and recordIndex is good, register
whole record.
If fieldIndex is good and recordIndex is negative, register
whole field.
DBBlockRegister- This will register the block with the selected part of the data- I
Structure(integer base so it will get a LINKSTRUCTURE message when the
blockNumber, integer database or table structure is changed. Returns negative code
databaseIndex, integer if block not found. Note for structure registration, only whole
tableIndex) databases or whole tables can be registered.
If databaseIndex is negative, register all databases for struc-
ture changes.
If tableIndex is negative, register all tables for structure
changes.
DBBlockUnregister- For non-user-linked data, take it out of the registered block I
Content(integer block- list. Return negative code if block not found.
Number, integer If databaseIndex is negative, unregister all databases.
databaseIndex, integer If tableIndex is negative, unregister all tables.
tableIndex, integer If fieldIndex is negative and recordIndex is negative, unregis-
fieldIndex, integer ter all cells in table.
recordIndex) If fieldIndex is negative and recordIndex is good, unregister
whole record.
Functions
If fieldIndex is good and recordIndex is negative, unregister
whole field.
DBBlockUnregister- For non-user-linked data, take it out of the registered block I
Structure(integer list. Return negative code if block not found.
blockNumber, integer If databaseIndex is negative, unregister all databases.
databaseIndex) If tableIndex is negative, unregister all tables.
DBDatatable(integer Link a data table with an ExtendSim database table. I
blockNumber, string
datatableName, inte-
ger databaseIndex,
integer tableIndex,
integer showField-
Names)
376 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

DB linking/notify Description Return


DBParameter(integer Link a parameter with an ExtendSim database cell. I
blockNumber, string
dialogItemName, inte-
ger databaseIndex,
integer tableIndex,
integer fieldIndex,
integer recordIndex)

Arrays, pointers, queues, delay, linked list, and string lookup table functions
Dynamic and non-dynamic arrays
The following functions manipulate arrays.
Dynamic arrays are declared as static arrays with their first dimension missing, such as:
real, integer, or string array[], array2Dim[][5];

☞ If you pass a dynamic array as an argument to a user-defined function, you cannot use this local
argument name as the argument to the MakeArray or DisposeArray functions, but must instead
use the original static declared name.

Dynamic arrays Description Return


ArrayDataMove This function moves a specified number of rows of data I
(array y[], integer (rowsToMove) from a specified location (startIndex) in the array
StartIndex, integer to another specified location in the array (targetIndex). If the
rowsToMove, inte- clearData flag is set to TRUE (1), it will clear out the old data
ger targetIndex, locations in the array. Returns 0 if successful.
integer clearData)
DisposeAr- Dynamic arrays only. Releases the memory used by a dynamic V
ray(array) array. Use this when you have finished using a dynamic array to
save memory and model file space. Call this function with the
original static declared name of the array (see notes above).
DynamicArrayIn- Returns the index number of the named dynamic Array. I
Functions

dexByName (long
blockNum, string
arrayName)
FindMinimum(real Accepts two dynamic arrays; one real, one integer. It searches the R
RealArray, integer RealArray for the minimum values and returns the minimum
ResultArray) value. The ResultArray is filled with the position numbers of the
elements that contain the minimum value.
FindMinimum- This function is identical to the FindMinimum function defined in R
WithThreshhold the above, with the addition of the threshhold argument. This
(realArray y, inte- argument specifies a threshhold below which the real values will
gerArray y2, real be ignored. I.e. the minimum value found will always be at the
threshhold) threshhold, or above.
ModL Functions 377
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Dynamic arrays Description Return


GetDimension The size of the first dimension (rows). If array is a dynamic array, I
(array) this function will return the size of the dynamic dimension. This is
useful for determining the maximum subscript (the returned value
minus 1) of an array when it is passed to a user-defined function.
GetDimensionBy- This function is a variation of the GetDimension function that has I
Name(integer two differences. The first is that it takes a block number argu-
blockNumber, ment, which specifies which block contains the array, and the sec-
string arrayName) ond is that it takes the arrayname of the array as an argument
rather than the array itself. The combination of these two differ-
ences mean that you can call the function from a remote block,
query the number of rows in a array, and also pass in a string vari-
able for the arrayname if desired.
GetDimensionCol- Returns the number of columns (second dimension in a two I
umns(array) dimensional array) in the specified array.
GetDimensionCol- Has the same behavior as the getDimensionColumns function, I
umnsByName(inte- with the exception that it can be called from an outside block, and
ger blockNumber, doesn't have to be called from within the block that contains the
string arrayName) array. Note that the arrayName argument is the name of the array
as a string, not the array name itself. This also means that the
function can be called with a string variable as the second argu-
ment, and not a hard coded array name.
MakeArray(array, Dynamic arrays only. Allocates a dynamic array. i is the desired V
integer i) value of the first (blank) dimension. MakeArray does not clear or
disturb data already in the array and can be used to make an array
larger or smaller. If you need to initialize an array to 0 or BLANK,
this must be done by the block’s code. Call this function with the
original static declared name of the array (see notes above).
MakeArray2(inte- Has the same behavior as the MakeArray function, with the V
ger blockNumber, exception that it can be called from an outside block, and doesn't
string arrayName, have to be called from within the block that contains the array.
integer dim) Note that the arrayName argument is the name of the array as a
string, not the array name itself. This allows resizing of dynamic

Functions
arrays passed in to functions as a string name.
SortArray(array, Sorts the array up to numRows. Uses the keyColumn as the sorting V
integer numRows, column. If increase is TRUE, sorts in ascending order (note that,
integer keyColumn, for purposes of sorting, NoValues are considered larger than any
integer increase, number). If this is a string array and
integer sortStrin- sortStringAsNumbers is TRUE, sorts strings as numbers in key-
gAsNumbers) Column. This function works with any kind of array, including
data tables and text tables.

Passing arrays
These functions let you pass dynamic arrays through connectors or global variables. This is
discussed in more detail in “Passing arrays” on page 102. Also see the “Passing Arrays” exam-
ple (Windows: PassArry.mox in the ModLTips folder; Mac OS: Passing Arrays in the ModL
Tips folder).
378 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Passing arrays Description Return


GetPassedAr- Gives access to array values from the input connector or real num- I
ray(real ber realVar that holds the location of a passed array. array must be
declared in this block as a dynamic array of the same type as the
realVar, array) passed array. After this function is called, array can be used to
access and change the values in the passed array. This function
returns TRUE if realVar is a passed array from another block and
returns FALSE if it is not a passed array.
PassArray(array) Returns the real value that represents the location of a dynamic R
array declared in this block. This is used to pass the array to an
output connector or real variable (such as a global variable). Do
not call PassArray to pass an array that has been received by Get-
PassedArray; see “Passing arrays” on page 102, for more infor-
mation.

Pointer functions
Dynamic array pointer functions allow you to copy the contents of dynamic arrays into an
independent data structure that can be created, used by other blocks if desired, and disposed of
by any block. You can create a very large number of independent pointers, if desired. They are
also useful for creating complex structures of pointers.
Using a disposed pointer will cause a crash (uses malloc() and free()).

Pointers Description Return


PointerFromDynamicAr- Copies data from any type of dynamic array to a new pointer I
ray(dynamicArray) created by “malloc()” and returns the pointer.
If you pass the pointer to an external DLL, the first integer in
the pointer's data is the size of the pointer's data in bytes.
Including the size data, the pointer is actually that size plus 4.
PointerDispose(integer Frees the memory used by the pointer using “free()”. The V
pointer) pointer is now invalid and can cause a crash if used.
PointerToDynamicAr- Takes a pointer created by PointerFromDynamicArray() and V
Functions

ray(integer pointer, copies it to a dynamic array, so ModL code can access it. This
dynamicArray) action writes over any old data in that dynamic array. The
dynamic array must be the same type as the array in the
pointer. The pointer must still be disposed of by PointerDis-
pose().

Global arrays
The Global Array functions define and manage global arrays (see “ModL function overview”
on page 226). All of the functions except the ones that start with “GAGet” will return a nega-
tive number if they fail. The following numbers have standard meanings:
ModL Functions 379
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Value Meaning
-1 No arrays defined, or array not found
-2 Array index invalid, or array not defined
-3 Row or column reference out of range
-4 Incorrect array type
-5 Name is blank, or too long (> 15 characters)
-7 Wrong type of array
-8 Array length doesn’t match global array length

The type of a global array can be defined by the following constants:

Constant Value
GAReal 1
GAInteger 2
GAString 3
GAString15 4
GAString31 5
GAString63 6
GAString127 7

Global Arrays Description Return


DBTable- Copies data from the specified Database table to the specified I
toGA(integer data- Global Array. The function makes its best attempt to copy the
baseIndex, integer data over. If the DB table defines multiple fields in different for-
Functions
tableIndex, integer mats, not all the data may be copyable.
GAIndex)
GABlockRegister- This function is used in conjunction with the Dynamic Linking I
Content(integer functionality in version 7. This function will set up a registration
blockNumber, inte- entry for the specified Global Array, such that whenever there is a
ger GAIndex, inte- change in the Global Array, the block will receive Conten-
ger row, integer tChanged messages informing it of the change. This works simi-
col) larly to the way a dialog item linked to the Global Array would
work, except that by calling this function you can establish this
kind of link through code without a specific dialog item involved.
If you specify the row and column, then the message will only be
sent when the specific cell is affected by the change. (Specify -1 if
you want the entire array.) See the GABlockRegisterStructure()
function below to register to receive structure changes.
380 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GABlockRegister- This function is similar to the GABlockRegisterContent function, I
Structure(integer except that it registers to receive StructureChanged messages
blockNumber, inte- when the structure of the GA changes, not when the content
ger GAIndex, inte- changes.
ger row, integer
col)
GABlockUnregis- Unregisters the specified GA from the Block’s dynamic link reg- I
terContent(integer istry. See GABlockRegister above for information about what it
blockNumber, inte- means for a Global Array to be listed in the registry.
ger GAIndex, inte-
ger row, integer
col)
GABlockUnregis- Unregisters the specified GA from the Block’s dynamic link reg- I
terStructure(inte- istry. See GABlockRegister above for information about what it
ger blockNumber, means for a Global Array to be listed in the registry.
integer GAIndex,
integer row, inte-
ger col)
GAClipboard (inte- Copies the array with the specified index into the clipboard, V
ger arrayIndex) where it will be inserted into the selected model with the next
paste.
GACopyAr- Creates a new Global Array that is a duplicate of the array speci- I
ray(integer arrayIn- fied by arrayIndex, with the name newName. The return value of
dex, string the function is the arrayindex of the new Global Array.
newName)
GACreate(string This function creates an array with the specified name, and type. I
name, integer type, Arrays are created with zero rows. Returns the index number.
integer columns)
GACreateQuick This function behaves the same way as the GACreate function, I
(string name, inte- with the exception that it will not check the name to see if a global
ger type, integer array already exists with that name. The only case where you
columns) would want to use this function is where you are creating a large
Functions

number of GA’s, speed is of the essence, and you are sure that
there will be no duplication of names. If you do create an array
with the same name as an existing array, referencing that array by
name will only access the older array.
GACreateRandom Creates a Global Array with a random name. Useful for quick cre- I
(integer type, inte- ation of global arrays in cases where you need to create many
ger columns) arrays quickly.
GADataTable (inte- Associates a Global Array with a dialog data table in the same I
ger blockNumber, way the DynamicDatatable function associates a dynamic array
string DTname, with one. See the DynamicDatatable() function description for
integer arrayIndex) more information.
ModL Functions 381
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GADelete- Deletes a row in the specified Global Array. This will move down I
Row(integer array- the data on rows after the specified row.
Index, integer row)
GADispose(string Disposes the named Array. I
name)
GADisposeByIn- Disposes the Global Array referenced by arrayIndex. I
dex (integer array-
Index)
GAExport(string Exports data from the Global Array specified by GAIndex I
pathName, string directly into a text file. See the Export() function for information
userPrompt, string about the other arguments.
format, integer
GAIndex, integer
rows, integer col-
umns)
GAFindStringAny This function searches a specific string Global Array, referrenced I
(integer arrayIndex, by arrayIndex, for the first string that matches the findString. The
string findString, return value is the index of the array element that contains the first
integer column, string found. A -1 will be returned if the string is not found.
integer numRows,
integer numChars,
integer caseSensi-
tivity)
GAGetArray(inte- Sets the contents of the array y to the values in the Global Array I
ger arrayIndex, with the specified index. This will copy the contents of the speci-
integer row, array fied row of the Global Array into the array y. (You need to make
y) sure that the number of elements in the dynamic array match the
number of columns in the row of the global array.)
GAGetColumns Returns the number of columns defined for the named array. I
(string name)
GAGetColumns- Returns the number of columns defined for the Global Array I

Functions
ByIndex (integer referrenced by arrayIndex.
arrayIndex)
GAGetIn- Returns the Index value of the named array. I
dex(string name)
GAGetInfo(integer This Global Array function returns the value of some of the I
ArrayIndex, inte- Global Array flags for the specified array. Values for Which are:
ger Which) 0:non saving, 1:initializing.
GAGetInit- Gets the initialization value for the global array. This value is set R
Value(integer by GASetInitValue(), and is used during array initialization.
arrayIndex)
382 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GAGetInteger(inte- Returns the integer value stored at the specific row and column of I
ger arrayIndex, the array with the specified index.
integer row, inte-
ger column)
GAGetLong(inte- This function is also known as GAGetInteger. See I
ger arrayIndex, GAGetInteger for description.
integer row, inte-
ger column)
GAGetName(inte- Returns the Name of the array with the specified index. S
ger arrayIndex)
GAGetReal(inte- Returns the real value stored at the specific row and column of the R
ger arrayIndex, array with the specified index.
integer row, inte-
ger column)
GAGet- Returns the number of rows defined for the named array. I
Rows(string name)
GAGetRowsByIn- Returns the number of rows defined for the Global Array refer- I
dex (integer array- renced by arrayIndex.
Index)
GAGetString (inte- Returns the string value stored at the specific row and column of S
ger arrayIndex, the array with the specified index.
integer row, inte-
ger column)
GAGet- Returns the string value stored at the specific row and column of S
String15(integer the array with the specified index.
arrayIndex, integer
row, integer col-
umn)
GAGet- Returns the string value stored at the specific row and column of S
String31(integer the array with the specified index.
Functions

arrayIndex, integer
row, integer col-
umn)
GAGet- Supports the string 63 type, otherwise the same as the GAGet- S
String63(integer String() function.
arrayIndex, integer
row, integer col-
umn)
GAGetType(string Returns the type of the named Array. See table above for type val- I
name) ues.
GAGetTypeByIn- Returns the type of the Global Array referrenced by I
dex (integer array- arrayIndex.
Index)
ModL Functions 383
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GAImport(string Imports data from a text file directly into the Global Array speci- I
pathName, string fied by GAIndex. See the Import() function for information about
userPrompt, string the other arguments.
format, integer
GAIndex)
GAInitializ- Sets the initializing flag for the specified global array. The flag I
ing(integer Array- determines if the array is automatically initialized during initsim
Index, integer of a model run or not. The Initializing flag takes the following
Initializing) values: 0: don't initialize (default), 1: initialize to 0, 2: initialize to
blank (real numbers only.), 3: initialize to specified value. See
GASetInitValue(), below.
GAInsertRow(inte- Inserts a row in the specified Global Array. This will cause all the I
ger arrayIndex, data on rows after the specified row to be moved up a row.
integer row)
GALastUsedIn- Returns the GAIndex of the last defined Global Array. This can I
dex() be used to loop through all the Global Arrays in a model.
GAMultisim(inte- Sets a flag on the Global Array that determines how the initializa- I
ger arrayIndex, tion deals with multiple simulation runs. 0: initialize at beginning
integer multisim) of each run, 1: initialize at beginning of first run of a multiple run
only.
GANonSav- This function flags the specific array as a non saving array. The I
ing(integer arrayIn- array will not be written out to the model file when the file is
dex, integer closed. (By default Global arrays are “saving” arrays.)
nonSavingArray)
GAParameter(inte- Link a parameter with a Global Array cell. I
ger blockNumber,
StringdialogItem-
Name, integer
arrayIndex, integer
colIndex, integer
rowIndex)

Functions
GAPopupMenu This function copies the strings in the specified Global array into I
(integer arrayIndex, the named Popup menu. This is a utility that allows quick con-
string name, integer struction of a popup menu. The flying argument is true if the
rows, integer init, menu is being created “on the fly,” as opposed to adding the array
integer flying) to the existing menu. See the code that controls the Animation tab
of any Item library block as an example.
GAPtr (integer Returns the memory pointer to the data associated with a particu- I
arrayIndex) lar global array. (For passing data to dll's only, and it should be
called only immediately before the DLL call, as memory can
move, making the pointer invalid.)
GAResize(string Changes the number of rows defined for a global array. I
name, integer rows)
384 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GAResizeByIndex Changes the number of rows defined for the Global Array refer- I
(integer arrayIndex, renced by arrayIndex.
integer size)
GASearch(integer Searches a Global array for the occurrence of the specified value I
GAIndex, integer and returns the first index where found. This function can be used
lValue, real rValue, to search any type of Global Array. It will search for the value
string sValue, inte- lValue, rValue, or sValue, as appropriate, based on the type of the
ger whichCol, inte- Global Array and will search in the column specified by the
ger startIndex) whichCol parameter. The startIndex parameter specifies which
row to begin searching on. For second and subsequent searches,
just pass the last value returned by the function plus one as the
startIndex parameter. You should end the search when the func-
tion returns a negative 1, as this will mean that the desired ele-
ment was not found.
GASearch- Returns the number of occurrences in a Global array of the speci- I
Count(integer fied value. This function can be used to search any type of Global
GAIndex, integer Array. It will search for the value lValue, rValue, or sValue, as
lValue, real rValue, appropriate, based on the type of the Global Array and will search
string sValue, inte- in the column specified by the whichCol parameter. The startIn-
ger whichCol, inte- dex parameter specifies which row to begin searching on. You
ger startIndex) should end the search when the function returns a negative 1, as
this will mean that the desired element was not found.
GASetArray(inte- Sets the contents of the Global Array with the specified index to I
ger arrayIndex, the values in the array y. This will copy the contents of the array y
integer row, array into the specified row of the Global Array. (You need to make
y) sure that the number of elements in the dynamic array match the
number of columns in the row of the global array.)
GASetInit- Sets the initialization value for the specified global array. This I
Value(integer value is used during array initialization.
arrayIndex, real
value)
GASetInteger(inte- Sets the integer value at the specific row and column of the array I
ger value, integer with the specified index.
Functions

arrayIndex, integer
row, integer col-
umn)
GASetLong(inte- This function is alos known as GASetInteger. See GASetInteger I
ger value, integer for description.
arrayIndex, integer
row, integer col-
umn)
GASetReal(real Sets the real value at the specific row and column of the array I
value, integer with the specified index.
arrayIndex, integer
row, integer col-
umn)
ModL Functions 385
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Global Arrays Description Return


GASet- Sets the string value at the specific row and column of the array I
String(string value, with the specified index.
integer arrayIndex,
integer row, inte-
ger column)
GASet- Sets the str15 value at the specific row and column of the array I
string15(string with the specified index.
value, integer
arrayIndex, integer
row, integer col-
umn)
GASet- Sets the str31 value at the specific row and column of the array I
string31(string with the specified index.
value, integer
arrayIndex, integer
row, integer col-
umn)
GASet- Supports the string 63 type, otherwise the same as the GASet- I
String63(string String() function.
value, integer
arrayIndex, integer
row, integer col-
umn)
GASort(integer Sorts the Array with the specified index. Sorts the array up to I
arrayIndex, integer numRows. Uses the keyColumn as the sorting column. If increase
numRows, integer is TRUE, sorts in ascending order (note that, for purposes of sort-
keyColumn, integer ing, NoValues are considered larger than any number). If this is a
increase, integer string array and sortStringAsNumbers is TRUE, sorts strings as
sortstringAsNum- numbers in keyColumn.
bers)
GAtoDBT- Copies data from the specified GA to the specified Database I
able(integer GAIn- table. The function makes its best attempt to copy the data over.

Functions
dex, integer If the DB table defines multiple fields in different formats, not all
databaseIndex, the data may be copyable.
integer tableIndex)

Linked lists
Linked lists are queue-like, multiple type structures that maintain internal pointers between the
different elements. This speeds the moving around of elements (sorting) within the list. Each
structure element can simultaneously contain any number of integer, real, Str15, Str31, and
Str255 data types, so complex sorted structures can be created. They will be slightly slower to
access than their linear equivalent if used as a simple queue (FIFO, or LIFO) and faster than
their linear equivalent if their internal sorting functionality is taken advantage of, as in a Queue
block (Item library). See that block’s code for a good example of using linked lists to sort.
These functions create and manipulate linked lists which are referred to by an index and are
associated and stored with a block. Because these functions have a global block number as an
386 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

argument, linked lists associated with a specific block can also be accessed globally, from any
other block in the model.
The normal sequence for working with linked lists is:
ListCreate(...); // create the list structures

ListCreateElement(…); // creates a new empty element

ListSetxxx(…); // sets a field in the element

ListSetxxx(…); // sets another field in the element

… // set the rest of the fields in the element

ListAddElement(…); // adds the new element to the list

... // manipulate the list, adding and deleting elements

... // get elements from the list to use in a calculation

ListDispose(...); // we are done with the list

Linked lists Description Return


ListAddEle- Adds an element previously created with ListCreateElement to I
ment(integer block- the specified queue.
Number, integer
listIndex, integer where:-2 sorted by preset sortType and field index value
where) where:-1 the front of the list
Otherwise, where is an index value and the item will be added
after the specified index item. Returns zero for success.
Lis- This function should be called right after ListCreate, if you wish I
tAddString63s(inte your linked list to contain String63s. It has the same effect as
ger blockN, integer specifying, for example, n String15s in the ListCreate function, it
listIndex, integer defines the number of string63s that will be present in each ele-
string63Count) ment of the Linked List.
Functions

ListCopyEle- Copies an element from one linked list to another. The first three I
ment(integer parameters specify the element in the first list, the next two spec-
blockN, integer ify the target list, and the last one specifies where in the new list to
listIndex, integer copy the element. As with any linked list function that adds an
fromIndex, integer element, you can specify a -2 to mean that the new element should
targetBlockN, inte- be added in its sorted order.
ger targetListIn-
dex, integer
targetIndex)
ModL Functions 387
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Linked lists Description Return


ListCreate(integer Creates a new list with the specified attributes. LongCount, real- I
blockNumber, inte- Count, etc are counts of the number of fields of each of the speci-
ger longCount, fied types each list element contains. SortType and fieldIndex
integer realCount, determine which field is to be used as the sorting field for the list.
integer str15Count,
integer str31Count, sortType:0 don’t sort
integer strCount, sortType:1 real field is key
integer sortType, sortType:2 integer field is key
integer fieldIndex) sortType:3 str255 field is key
sortType:4 str15 field is key
sortType:5 str31 field is key
FieldIndex is used to determine which index of the specified type
is the key field. Zero is the first field.
ListCreateEle- Creates a new empty element for a list. The normal sequence is I
ment(integer block-
Number, integer ListCreateElement(…); // creates a new empty element
listIndex) ListSetxxx(…); // sets a field in the element
ListSetxxx(…); // sets another field in the element
… // set the rest of the fields in the element
ListAddElement(…); // adds the new element to the list
ListDeleteEle- Deletes the specified element. Zero is the first element. I
ment(integer block-
Number, integer
listIndex, integer
indexToDelete)
ListDispose(inte- Disposes of the specified list and recovers its memory. I
ger blockNumber,
integer listIndex)
ListDispo- Disposes all linked lists in a block. Returns TRUE if the block I
seAll(integer doesn’t exist or the lists have already been disposed.
blockNumber)
ListElementMin- This function searches the list for the maximum or minimum I

Functions
Max(integer block- value of the specified value. If the Max flag is true, it will return
Number, integer the index of the element that contains the maximum value of that
listIndex, integer entry, otherwise it will return the minimum. (Currently just inte-
compareType, inte- ger and real are implemented. string comparisons are not yet
ger compareIndex, implemented.)
integer max)
388 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Linked lists Description Return


ListGetCount(inte- Returns the count of the number of linked lists the block has I
ger blockN) defined. Please note that in a similar way to the way GetNumB-
locks works for the model worksheet, the number returned by this
function can contain 'empty slots'. An 'empty slot' is defined as a
list index that specifies a list that has been disposed, or is other-
wise not defined. This function can be used to execute a loop that
looks at all the linked lists in a block, but you should check each
list to confirm that it exists. Because of this aspect of how this
functions, you should not call ListGetCount, and assume that the
returned value is exactly the number of lists the block supports.
ListGetDou- Returns the real (double) value at that element and field index. If R
ble(integer block- elementIndex is passed in as a value less than zero, it refers to the
Number, integer current newly created, but not yet added, item. If
listIndex, integer elementIndex is zero or greater it is used as an index value into
elementIndex, inte- the specified list.
ger fieldIndex)
ListGetEle- Returns the number of elements in the specified list. I
ments(integer
blockNumber, inte-
ger listIndex)
ListGetIndex(inte- Gets the index of a linked list by its name. Linked lists do not I
ger blockN, string automatically have names. If the name specified is not found, the
name) function will return a negative value as an error code.
ListGetInfo(inte- Returns the specified info about the specified Linked List. Info- I
ger blockNumber, Type takes the following values:
integer listIndex,
integer infoType) 1: returns the number of real values in the specified list
2: returns the number of integer values in the specified list
3: returns the number of string values in the specified list
4: returns the number of string15 values in the specified list
5: returns the number of string31 values in the specified list
6: returns the number of string63 values in the specified list
10: returns TRUE if this list exists, FALSE if it doesn’t
Functions

ListGetLong(inte- Returns the integer (integer) value at that element and field index. I
ger blockNumber, If elementIndex is passed in as a value less than zero, it refers to
integer listIndex, the current newly created, but not yet added, item. If elementIn-
integer elementIn- dex is zero or greater it is used as an index value into the specified
dex, integer fieldIn- list.
dex)
ListGetName(inte- Returns the name of the linked list. List names are new in version S
ger blockN, integer 7. Lists do not have a name by default, and will not have a name,
listIndex) until one has been set with the ListSetName function.
ModL Functions 389
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Linked lists Description Return


ListGetString(inte- Returns the string value at that element and field index. If ele- S
ger blockNumber, mentIndex is passed in as a value less than zero, it refers to the
integer listIndex, current newly created, but not yet added, item. If
integer elementIn- elementIndex is zero or greater it is used as an index value into
dex, integer string- the specified list.
Type, integer
fieldIndex) StringType takes the following values:
3: string (str255) field
4: str15 field
5: str31 field
ListLastElementIn- Return the index value of the last item added to the specified list I
dex(integer (not the end of the list, the last item actually added).
blockN, integer
listIndex)
ListLocked (integer If Locked is true, this function call marks the specified Linked I
blockN, integer List as locked. This has the effect of making that List not be dis-
listIndex, integer posed if ListDisposeAll is called. If the function ListDispose is
locked) called explicitly on this list, it will still be disposed, this function
only prevents accidental disposal of the list through the ListDis-
poseAll call. Returns a zero of the call succeeds. Returns a nega-
tive error code value if the function fails.
ListSearch(integer Searches the list for the specified value. Search type determines I
blockN, integer which type to search for, and also which value string is used.
listIndex, integer StartIndex specifies where in the list to start searching. This func-
searchType, inte- tion returns the index number of the first list element that matches
ger searchIndex, the search criteria. If you want to search for multiple elements in
integer lVal, real the same list, just call the function multiple times, using the last
rVal, string sVal, index found plus one as the ‘startIndex’ parameter of the next
integer startIndex) search. You should end the search when the function returns a
negative 1, as this will mean that the desired element was not
found.
ListSearch- Similar to the ListSearch function, except that this function I
Count(integer returns the number of occurrences of the specified value in the

Functions
blockN, integer list.
listIndex, integer
searchType, inte-
ger searchIndex,
integer lVal, real
rVal, string sVal,
integer startIndex)
ListSearchCount- Functions similarly to the ListSearchCount function, except that I
Longs(integer the integer Array Y argument is similar to the ListSearchLongs
blockN, integer function, below. (I.e. this function will count the number of ele-
listIndex, integer ments in the list that contain matches for all the integer elements
Array y, integer in the integer Array.)
startIndex)
390 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Linked lists Description Return


ListSearchLo- Similar to the ListSearch function, except that the type to be I
ngs(integer blockN, searched for is longs, and the function will search for more than
integer listIndex, one integer at a time within a single element of the list. The inte-
integer Array y, ger Array Y argument is a two column array by any number of
integer startIndex) rows long. These longs are in pair of index followed by search
value. This allows you to search a linked list for more than one
integer condition at a time. The search will match only list ele-
ments where all the longs in the array match.
ListSetDou- Sets the real (double) value at that element and field index. If ele- I
ble(integer block- mentIndex is passed in as a value less than zero, it refers to the
Number, integer current newly created, but not yet added, item.
listIndex, integer If elementIndex is zero or greater it is used as an index value into
elementIndex, inte- the specified list.
ger fieldIndex, real
value)
ListSetLong(inte- Sets the integer (long) value at that element and field index. If ele- I
ger blockNumber, mentIndex is passed in as a value less than zero, it refers to the
integer listIndex, current newly created, but not yet added, item. If elementIndex is
integer elementIn- zero or greater it is used as an index value into the specified list.
dex, integer longIn-
dex, integer value)
ListSetName(inte- Sets the name of the specified linked list to the name defined by I
ger blockN, integer the ‘name’ parameter.
listIndex, string
name)
ListSetSort(integer ListSetSort allows you to change the sort criteria for the list. Sort- I
blockNumber, inte- Type and fieldIndex are defined as described above in the List-
ger listIndex, inte- Create function. The list will be resorted by this call.
ger sortType,
integer fieldIndex)
ListSetSort2(inte- Sets the sorting criteria for the specified list. This function I
ger blockN, integer enhances the existing ListSetSort() function in that there are now
listIndex, integer multiple sorting criteria. I.e. there is a secondary, and tertiary
Functions

sortType, integer sort.


sortIndex, integer
sortType2, integer
sortIndex2, integer
sortType3, integer
sortIndex3)
ListSetString(inte- Sets the string newString at that element and field index. If ele- V
ger blockNumber, mentIndex is passed in as a value less than zero, it refers to the
integer listIndex, current newly created, but not yet added, item.
integer elementIn- If elementIndex is zero or greater it is used as an index value into
dex, integer string- the specified list. StringType takes the following values:
Type, integer 3: string (str255) field
stringIndex, string 4: str15 field
newString) 5: str31 field
ModL Functions 391
Arrays, pointers, queues, delay, linked list, and string lookup table functions

String lookup table functions


String lookup tables are data structures that allow you to associate a string with an integer
value. This is used to lookup a string value in the table whenever needed. An example might
be associating the strings “Red”, “Green” and “Blue” with the values 1, 2 and 3. This allows
you to display the string values in a dialog box or popup menu when internally you are storing
a numeric value. Because the String Lookup blocks use hash tables internally they will access
and convert the integer values to the strings quickly.
These functions are used to implement the string attribute behavior in the Item library.
Note that string lookup table information is stored in the model, but it is not saved when the
model is closed. This has a couple of implications. First, if you copy a block that has informa-
tion that is based on a string lookup from one model to another one where the string lookup is
not defined, the results will be unpredictable. The correct work around for this issue would be
to make sure that the string lookup is defined in the target model before the block is copied.
The second implication is that, as the string lookup information is not saved when the model is
closed, you will need to recreate any necessary string lookups in the model when it is opened.
(In the case of the String Attributes, this is done in the executive block during the OpenModel
message handler.) Also, see “Strings” on page 394

String lookup Description Return


SLClear(string Clears the specified lookup of all strings, and sets it to not be a I
slName) string lookup, until SLSet is called on it again.
SLCreate(string Creates a string lookup table with the specified name. I
slName)
SLDelete(string Deletes a string lookup table with the specified name. I
slName)
SLFlagGet(string Returns one of the twenty user defined flag values for the speci- I
slName, integer fied string lookup. Each string lookup has twenty flags associ-
which) ated with it. ‘Which’ should take a value from 0 to 19.
SLFlagReal- Returns one of the twenty real user defined flag values for the R
Get(string slName, specified string lookup. Each string lookup has twenty real flags
integer which) associated with it. ‘Which’ should take a value from 0 to 19.

Functions
SLFlagReal- Sets one of the twenty real user defined flag values for the speci- I
Set(string slName, fied string lookup. Each string lookup has twenty real flags asso-
integer which, inte- ciated with it. ‘Which’ should take a value from 0 to 19.
ger tableAttribute)
SLFlagSet(string Sets one of the twenty user defined flag values for the specified I
slName, integer string lookup. Each string lookup has twenty flags associated
which, integer with it. ‘Which’ should take a value from 0 to 19. Note that these
tableAttribute) flags are stored internally as a single byte of data, which means
that you can only store values from zero to 127 in the flag. This is
normally intended to store Boolean (True/False) values, but you
can store values up to 127 if you wish. (Negative values will not
be stored.)
SLGetCount() Returns the count of the number of string Lookups defined in a I
model.
392 Reference
Arrays, pointers, queues, delay, linked list, and string lookup table functions

String lookup Description Return


SLGetCount- Returns the count of the number of strings that are associated with I
Strings(string the specified lookup.
slName)
SLIs(string Returns a true value if the specified name is a string lookup. I
slName)
SLPopup- Either fills a popup menu with the lookup string values, or creates I
Menu(string a flying popup menu at the location of the last click, based on
slName, dialog- whether or not the flying flag is set.
Item, init, flying)
SLSort(string Sorts the strings for the specified lookup alphabetically. I
slName)
SLStringAp- Sets a string value for the specified lookup. By default the first I
pend(string string will have value one, the second one value two, and so on.
slName, string This can be revised by changing the order of the list by either call-
stringVal) ing SLSort, to sort the list alphabetically, or calling SLRemove to
remove a string from the list. The first time this function is called,
It will create a string lookup table with the name slName if that
string lookup table does not already exist. This is an alternative
to calling SLCreate.
SLStringGet(string Returns the string value of the specified index on a string lookup. S
slName, integer
index)
SLStringGetIn- This function is the inverse of the SLStringGet, it returns the I
dex(string slName, index value of a string on a string lookup.
string string)
SLStringInsert(stri Inserts the specified string at the specified index. I
ng slName, string-
stringVal, integer
index)
SLStringRe- Removes the specified string from the list of strings associated I
Functions

move(string with the specified lookup.


slName, string
string)

Queues
These functions store queues in a single-dimensional real, dynamic array, that is, an array that
is declared with no dimension, such as real a[] (see the section above on dynamic arrays).
You do not need to use the MakeArray function before calling QueInit. When you have fin-
ished with a queue, you should recover the memory it occupies with the
DisposeArray function; this is often done in the EndSim message handler.
In queues, the first member is numbered “0”, the next member “1”, and so on. This means that
in an array of n members, the last member is numbered “n-1”. n and i are integers, and x is a
real value.
ModL Functions 393
Arrays, pointers, queues, delay, linked list, and string lookup table functions

Queues cannot be directly accessed via the array and an index. You must use the following
functions to access elements within the queue. Also, see “Linked lists” on page 385.

Queues Description Return


GetFront(real Removes and returns item 0 from the front of the queue. If the R
array[]) queue is empty, NoValue is returned.
GetRear(real Removes and returns item n-1 from the rear of the queue. If the R
array[]) queue is empty, NoValue is returned.
PutFront(real Adds x to the front of the queue. V
array[], real x)
PutRear(real Adds x to the rear of the queue. V
array[], real x)
QueGetN(real Removes and returns the ith member of a queue. If the ith member R
array[], integer i) does not exist, noValue is returned. This compacts the queue after
the ith member is removed so that the i+1st member becomes the
new ith member.
QueInit(real Allocates and initializes the array for the queuing functions. Call V
array[]) this procedure in the InitSim message handler for each queue.
QueLength(real Length of the queue. If the queue is empty, the function returns 0. I
array[])
QueSetAlloc (inte- Specifies the allocation and reallocation constants for the queue- V
ger alloc, integer ing functions. This function allows the user to control how much
realloc) memory is allocated by the queueing functions to initially allocate
memory for item storage, and how much additional to add each
time they need to be resized bigger. The default values are 200
for alloc, and 500 for realloc.
QueLookN(real Value of the ith member of a queue without changing the queue R
array[], integer i) order. If the ith member does not exist, noValue is returned.
QueSetN(real Sets the value of the ith member of a queue to x without changing V
array[], integer i, the queue order. If i is greater than the length of the queue, an

Functions
real x) error message informs you and aborts the operation.

Delay lines
These functions store delay lines in a single-dimensional real, dynamic array, that is, an array
that is declared with no dimension, such as real a[] (see the section above on dynamic
arrays). Delay lines are used in continuous simulations to delay values by a constant amount of
time. They are like a pipe with values flowing in one end and out the other; the delay time is
analogous to the length of the pipe.
Although the delay line functions store delay lines in dynamic arrays, you must not use the
MakeArray function to allocate these arrays. Array allocation is handled automatically by the
delay line functions. When you have finished with a delay line, you should recover the mem-
ory it occupies with the DisposeArray function.
394 Reference
Miscellaneous functions

Delay lines Description Return


Delay(real array[], Inserts a new value x, and returns a delayed value from a delay R
real x) line. The returned value will be the value inserted DelayTime ago.
DelayInit(real Initializes a dynamic array delay line to DelayTime. Call this pro- V
array[], real Delay- cedure in the InitSim message handler for each delay line.
Time)

Miscellaneous functions
Strings
These functions allow you to change and parse a string into whatever component parts you
want. Note that, in ModL, the “+” operator acts as a string concatenation operator. The func-
tions that require a character position indicate the first character in a string as position 0. In
these functions, the arguments s, findString, and replaceString are strings.
Please see “String lookup table functions” on page 391

Strings Description Return


ArrayLabel- Parses an array of semicolon delimited strings and treats it as a S
Parse(integer item, single long string so you can get the nth label. This is the same
string array) parsing that ExtendSim does internally with both the data table
labels, and the popup menu strings.
DIFontSize(inte- Returns the point size of the font used by the named dialog item. R
ger blockNum,
string DIName)
FormatString(inte- This function creates formatted strings using string value argu- S
ger numArgs, ments. The formatString argument is used to define the format of
string format- the returned output string. The definition of the format string is
String, string val- based on the C function sprintf. Please refer to a standard C refer-
ue1, string value2, ence for more information on how to define the format string.
string value3, string NumArgs defines the number of value arguments that contain
value4, string val- meaningful values.
Functions

ue5, string value6,


string value7, string
value8)
FormatStringReal This function creates formatted strings using real value argu- S
(integer numArgs, ments. The formatString argument is used to define the format of
string format- the returned output string. The definition of the format string is
String, real value1, based on the C function sprintf. Please refer to a standard C refer-
real value2, real ence for more information on how to define the format string.
value3, real val-
ue4, real value5,
real value6, real
value7, real value8)
ModL Functions 395
Miscellaneous functions

Strings Description Return


NumToFor- Returns the number formatted as a string. X is the input number, S
mat(real x, integer maxchar is the maximum number of characters in the returned
maxchar, integer string, sigFigs is the number of significant figures desired. For-
sigFigs, integer for- mat is 0 for general, 1 for currency, 2 for integer, 3 for scientific
mat) notation.
NOTE: if -1 is used for maxchar, format is ignored and no scien-
tific notation is used even if the value is very small or large. This
special output format is needed to be compatible with Proof Ani-
mation.
Random- Returns a randomly generated string of n upper case alphabetic S
String(integer n) characters.
RealToStr(real Converts the value, rounded to sigFigs significant figures, to a S
value, integer sig- string.
Figs)
RealToStrShort- Converts a double or real variable to a string value, like the Real- S
est(real value, inte- ToStr function. The alwaysPadZeros argument specifies if you
ger sigFigs, integer want the zero trimming behavior. What this does is to remove any
alwaysPadZeroes) trailing zeros that may have appeared in the string from the sigfigs
being higher than the number of actual digits in the resulting
value. If you call this function with alwaysPadZeros TRUE, it
will behave exactly the same as RealToString.
StrFind(string s, Character position of findString within string s. The first position I
string findString, of a string is 0, so if the findString is not found, StrFind returns -1.
integer caseSens, If caseSens is TRUE, case is considered in the search. If diacSens
integer diacSens) is TRUE, diacritical marks are considered in the search.
StrGetAscii(string First character of s as an integer value corresponding to the ASCII I
s) value.
StringCase(string Returns str converted to lower case if lowerCase is TRUE, upper S
str, integer lower- case if lowerCase is FALSE.
Case)

Functions
StringCompare Returns -1 if s1 < s2, 0 if s1 == s2, 1 if s1 > s2. If caseSens is I
(string s1, string s2, TRUE, uses case. If diacritical is TRUE, uses diacritical marks (ä,
integer caseSens, é, ö, etc.).
integer diacritical)
StringTrim (string This function is used to trim blank spaces (including CR, LF, and S
input, integer TAB characters) off the input string. The resulting string is
which) returned.
The argument “which,” takes the following values:
0-both leading and trailing blanks are trimmed.
1-leading blanks trimmed.
2-trailing blanks trimmed.
3-both leading and trailing blanks are trimmed plus blanks any-
where else in the string
396 Reference
Miscellaneous functions

Strings Description Return


StrLen(string s) Number of characters in the string s. I
StrPart(string s, Substring of string s, starting at character position start, i charac- S
integer start, inte- ters long. Note that string length is 255 character maximum.
ger i)
StrPutAscii(integer String of length 1 corresponding to the ASCII value of i. This is S
i) useful for putting non-printing control characters into a string.
StrReplace(string s, The substring of string s starting at start of length i is replaced S
integer start, inte- with replaceString.
ger i, string
replaceString)
StrToReal(string s) Real value converted from string s, ending with the first space or R
letter found that is not part of the number. If s does not represent a
number, the function returns a NoValue.
TextWidth(string This function returns the width the specified string would draw at I
theString, integer in pixels. If font, face, and size are all zero the function will use
font, integer face, the default values for the animation text functions.
real size)
StrPartDy- Same as the strPart function, on a dynamicText dialog item. See S
namic(stringarray, “Dynamic text items” on page 320.
integer start, inte-
ger numChars)

Attributes
Use these functions in discrete event blocks to work with attribute strings. Attribute strings are
formatted as: AttrName1=val1;AttrName2=val2;...
Obsolete. These function are provided for backwards compatibility with version 3.x. New
blocks built in version 4.0+ should not use these functions.

Attributes Description Return


Functions

GetAttributeValue( Returns the value of the attribute attrName or NoValue if attr- R


string attrString, Name isn’t found. If you pass in a blank (empty) string for the
string attrName) attrName variable, function returns the value of the first attribute
in the attribute string.
RemoveAttribute( Returns the attribute string after removing attribute attrName. S
string attrString,
string attrName)
SetAttribute( Adds attrName and value or, if it already exists, changes the attr- S
string attrString, Name to value. Returns the attribute string after adding or chang-
string attrName, ing the attribute value.
real value)
ModL Functions 397
Miscellaneous functions

Time units
These functions convert local time units defined within blocks to the global time unit defined
in the Simulation Setup (see “Units of time” in the main ExtendSim User Reference). Get-
TimeUnits and ConvertTimeUnits use the following values for Time Units.

Time Unit Value


Generic Time Units 1
Milliseconds 2
Seconds 3
Minutes 4
Hours 5
Days 6
Weeks 7
Months 8
Years 9

Time Units Description Return


ConvertTimeUnits Converts a value from one type of time unit to another. R
(real value, integer
fromType, integer
toType)
GetTimeUnits() Returns the currently selected Time Units from the Simulation I
Setup dialog.
SetTimeConstants Sets the time unit conversion values. These are specified in the V
Simulation Setup dialog.
(real hInADay, real
dInAWeek, real

Functions
dInAMonth, real
dInAYear)
SetTimeUnits(inte- Sets the Time Unit parameter in the Simulation Setup dialog. I
ger value)

Calendar Date functions


ExtendSim Calendar Date values are numeric representations of a date value that is the same as
is used by Microsoft Excel, and is based on the number of days since January 1, 1900 and the
fraction of the current date for the time value. The integer part of the number is the number of
days since 1900, and the decimal part of the number is the fraction of the current day. For
example, the number 37256.5 would be twelve noon, on January first, 2006. There is a Macin-
tosh version of this date calculation, (also implemented based on the same numbers as Excel,)
which bases the first part of the date number on January first, 1904. Make sure that if you are
398 Reference
Miscellaneous functions

communicating with an outside application, you have selected the same version of these date
choices in both applications.
If you have a model saved in ExtendSim, and it has saved date values in one of these formats,
running it in the other date setting will give unexpected results. This legacy Macintosh date
setting is selectable in the Simulation Setup Dialog. Calendar Dates can only be selected in the
simulation setup dialog if the time units for the model are set to seconds or longer, and not to
generic time units, or milliseconds.
☞ Prior to ExtendSim 7, a different time and date format was used, as discussed on page 399.
Date and time Description Return
EDCalcDate(inte- Construct a date value from its individual components. R
ger year, integer
month, integer day,
integer hour, inte-
ger minute, integer
second)
EDCalendarDate- Opens the calendar input dialog for the user to input a date value R
Get(real startDate) and returns that date value. The input dialog will show the value
of the parameter startDate as a starting point.
EDCalendarDates() Returns the value of the CalendarDates checkbox in the simula- I
tion setup dialog box: FALSE is unchecked, TRUE is checked.
EDCalendar- This function opens or closes the calendar window. I
Show(true/false)
EDConvert- Modifies a date value by adding additional time. The additional R
Date(real value, time added to the date value will be in the value parameter, and
integer fromType, what time units it is in will be in the fromType parameter. Note
real startDate) that this function returns a date value, not a number of time units.
EDDateToSim- Converts from a date value to a simulation time value (e.g. a pos- R
Time(real current- sible value of currentTime). Putting in a zero for the timeUnits
Date, integer argument will make the function use the currently specified model
timeUnits) time units. (see Time Units)
Functions

EDDateTo- Converts an ExtendSim date value to a string according to format: S


String(real dateV-
alue, integer 0: Date and Time, 1: Just date (ignore Time), 2: Just Time (ignore
format) Date), 3: Tight format (two digit year, don’t show time value if
zero). 4: Looser format (two digit year but show time value even
if zero)
The following query the operating system to see if it uses the
European format where day comes before month: 10: Date and
Time, 11: Just date (ignore Time), 12: Just Time (ignore Date), 13:
Tight format (two digit year, don’t show time value if zero). 14:
Looser format (two digit year but show time value even if zero)
EDDateValue(real Gets one part of a date value. Which is the time unit value (see I
value, integer “Time units” on page 397, above). NOTE: Week information is
which) not available in this function.
ModL Functions 399
Miscellaneous functions

Date and time Description Return


EDDayOfThe- Converts from an ExtendSim Date value to an integer value repre- I
Week(real current- senting the day of the week. Returns a zero for Sunday.
Date)
EDGetCurrent- Returns the current date equivalent for the CurrentTime simula- R
Date() tion variable during a simulation run.
EDGetStartDate() Returns the date value of start time in the Simulation Setup Dia- R
log.
EDNow() Returns the real time current date and time like the Now() func-
tion, but as an ExtendSim date.
EDSimTimeTo- Converts a simulation time value to a date value. A simTime R
Date(real sim- value is a time number in simulation time format. Putting in a zero
Time, integer for the timeUnits argument will make the function use the current
timeUnits) model time units. For example in most models, the simTime value
for startTime is zero. Calling with a zero value of simTime will
return the ExtendSim Date value for the StartDate value of the
model.
EDStringTo- Parses a string to retrieve an ExtendSim Date value. R
Date(string dat-
eString)

Date and time, legacy format


☞ The following date and time functions were used in releases prior to ExtendSim 7. See “Calen-
dar Date functions” on page 397 for the functions used in ExtendSim 7.
The legacy format stored dates and times in an integer that is the number of seconds since mid-
night, January 1, 1904.
• The Now function returns the current date and time. To determine the amount of time that
has elapsed since the beginning of the simulation, subtract Start Time from Now.

Date and time Description Return

Functions
DiffDate(integer Returns the difference between two date values as a real number R
firstDate, integer which represents the number of days between the two dates.
secondDate)
GetBlock- Returns the modified and created dates of the block. The where- I
Dates(integer From argument takes a zero for the block or a one for the library.
blockNumber, inte- The whichDate argument takes a zero for created or a one for
ger whereFrom, modified. Use the EDdateToString function to get the string val-
integer whichDate) ues of the date & time.
ModifyDate(inte- Returns the old date value plus the date modifier value. The old- I
ger oldDate, real Date value is an ExtendSim integer date value, similar to that
dateModifier) returned from the GetBlockDates function, and the dateModifier
value is a real number representing a number of days.
Now() Number of the current date and time. I
400 Reference
Miscellaneous functions

Date and time Description Return


WaitNTicks(inte- Waits for the number of ticks (60ths of a second) before returning. V
ger numTicks) This is useful for slowing simulations down and for synchronizing
communication protocols with real time.

Timer functions
These allow real time measurements to be set up. The TimerID functions are an extension of
the timer functions that allow multiple (Up to 200) timers to run simultaneously. Each timer is
referenced by an ID number from 0 to 199. The StartTimer() and StopTimer() functions (with-
out a timerID argument) always refer to timer zero.

Timers Description Return


PrecisionTimer() Returns the current timer count of the highest resolution timer R
found on the system. Used in conjunction with PrecisionTim-
erScale(), below.
PrecisionTim- Returns the numbers of counts per second of the timer made avail- I
erScale () able in the PrecisionTimer function.
StartTimer (integer Starts a timer chore that will periodically send messages to either V
blockNumber, inte- the specified block, or every block in the active model if the
ger waitTicks) blockNumber is zero. This chore is performed when the CPU is
idle, so you cannot count on it happening exactly every period,
unless the CPU is idle. (e.g. other user/program actions will
potentially interrupt the execution of the chore.) If the CPU is
idle, the chore will be performed every waitTicks time intervals.
Ticks are 60ths of a second, so if you enter 60 the chore will
attempt to send out its message every second. The message sent
is TIMERTICK. See the Breakout.mox model for an example of
timer events.
StartTimerID (inte- Starts a timer with an ID tag, which can range from 0 to 199. As V
ger blockNumber, with the StartTimer() function, blockNumber specifies which
integer waitTicks, block should receive the TIMERTICK message, and waitTicks
integer index) specifies how often it should be sent.
Functions

Stoptimer() This procedure stops the idle timer chore started by startTimer V
above.
StopTimerID (inte- Stops a timer with an ID tag, which can range from 0 to 199. V
ger index)
TickCount() Clock count (in 60ths of a second) since the computer was pow- I
ered up. This is useful for timing operations.
TimerID() This function is to be used in the TimerTick message handler to I
find which timer is responsible for triggering the message.
Returns the ID number of the timer that is currently activating the
message.
ModL Functions 401
Miscellaneous functions

EColors
The following color functions are new in ExtendSim 10. They support a new color information
variable type called an EColor, which is stored in long (integer) variables. EColors contain the
previously supported RGB/HSV color information as well the alpha channel information that
allows color transparency and is new in ExtendSim 10.
Select Color window
You can see any color’s RGB (red, green, blue), HSV (hue, saturation, and value or bright-
ness), and HTML values as well as other settings by selecting the Fill Color tool in the Shapes
toolbar:

Color selector

Pick a basic color from the matrix of colors. Or use your cursor and the button labeled Pick
Screen Color to choose a color from the color swatch at the right. Adding any selected color to
the custom colors section saves the color for other models. Use the slider at the far right to
increase or decrease the value (brightness) of a selected color.
The alpha channel is for the level of transparency; the lower the number, the more transparent

Functions
the color is.
Some functions in ExtendSim releases prior to 10 had the option of selecting a pattern in addi-
tion to a color. Patterns remain as arguments for those functions but are no longer supported.

EColors Description Return


EColorFromHSV Converts HSV values to EColor values. H (Hue) should be in the I
(h, s, v, alpha) range from 0 to 359. All other values must be in the range 0 to 255
EColorFromOl- Converts a color value from ExtendSim 9 or earlier to an EColor I
dExtendColor (old) value.
EColorFromRGB Converts RGB values to EColor values. All values must be in the I
(r, g, b, alpha) range 0 to 255.
402 Reference
Miscellaneous functions

EColors Description Return


EColorIsValid (col- Returns a true value if the EColor is a valid color, and a false (0) I
orValue) value if it is not.
EColorPart (color, Returns an integer value for the specified part of the EColor I
which) value. which can take on the following values:
1: red (0-255)
2: green (0-255)
3: blue (0-255)
4: hue (0-359)
5: saturation (0-255)
6: value (0-255)
7: alpha (0-255)
EColorPicker (col- Displays a color picker and returns an EColor value from the user I
orValue) selected result.
EColorUpdateV- Converts an ExtendSim 9 or earlier color component value to a I
alue (old, isHue) part of an EColor value. (For example, if you have a number from
some v9 code that supports v9 RGB values, calling this function
on each one of those separate values will convert them to an
EColor component value.)

Debugging
Also see the Abort statement in “Control statements and loops” on page 70 and UserError in
“Alerts and prompts” on page 268.
Note: To stop a simulation such that it neither puts up an error message nor opens windows to
indicate in which process the simulation was stopped, put the following code in the SIMU-
LATE message handler of an equation-based or custom block:
• currentStep = numSteps;
• currentSim = numSims;
• //don’t use the Abort statement or call any abort functions

Debugging Description Return


Functions

AbortAllSims() Aborts the simulation and all multiple simulations. Note that the V
Abort statement only aborts the current simulation.
AbortAllSimsSi- Aborts a multiSim run without an error message. I
lent()
AbortSilent() Aborts the simulation run without giving any error messages. V
DebuggerBreak- If called with a true value will act as if a source debugger break- V
point(integer true- point has been set at the line of code where the function is called.
False) This function is useful in debugging the CreatBlock message and
in putting a global breakpoint for all blocks of a type.
ModL Functions 403
Miscellaneous functions

Debugging Description Return


DebugMsg(string Operates like the UserError function. The difference is that this V
errorString) function flags the block as having debugging code – the next time
a library is opened that contains any blocks having this function,
ExtendSim will issue a warning message. This function automati-
cally displays the simulation time and the block number of the
block from which the function was called.
DebugWrite(inte- Operates like the FileWrite function. The difference is that this V
ger fileNum, string function flags the block as having debugging code – the next time
errorString, delim- a library is opened that contains any blocks having this function,
Str, integer tabCR) ExtendSim will issue a warning message.
FreeMemory(inte- Returns the amount of memory available to ExtendSim. The I
ger memoryType) memoryType argument determines what type of memory will be
checked. Windows:
1 - Total memory
2 - Resources (only for Windows 3.1 and Windows 95)
Mac OS:
1 - Total memory
2 - Contiguous memory
heapCheck() Posts an error message, and returns a true value for an error condi- I
tion if memory has been corrupted.
Don’t call this function unless you are in a debugging situation, as
heap checking is slow.
PauseSim() Pauses the simulation until you choose Run > Resume or click the V
Resume button.
ProfileBlock- Returns the block profile results for the specified block. This will R
Get(integer block- only return a meaningful number if the command Profile Block
Number) Code is selected. Can be called in finalCalc to get the total profile
results for that block or during the simulation to get partial results.
SelectBlock(inte- Selects the block and scrolls to it if the argument is TRUE, unse- V
ger trueFalse) lects it if the argument is FALSE.

Functions
SelectBlock2(inte- This is same as SelectBlock(), except it refers to a global block V
ger block, integer number.
trueFalse)
TraceModeEnable- Call to enable or disable the current trace when desired. Trace V
Disable(integer mode must be on for this function to work. It returns zero if no
enableIfTRUE) error and -1 if trace mode is not on.

Web and Help connectivity


See also the ShowFunctionHelp function which brings up a list of ExtendSim’s functions and
arguments. This function is listed with “Equations” on page 238.
404 Reference
Miscellaneous functions

Help Description Return


CallHelp(string Used to load a WinHelp file, an HTML Help file, or a pdf file. V
fileName, integer
command, integer (For the WinHelp and HTMLHelp Windows API calls, see the
data, integer file- Microsoft documentation for more information.)
Type) The fileType flag takes the following values:
0: Calls the WinHelp function (Windows only. Opens compiled
Help files. Typically have an extension of .hlp.)
1: Calls HTMLHelp. (Opens compiled Html help files. Typically
have an extension of .chm.)
2: Opens a file with a .pdf extension.
This function is used to bypass the standard ExtendSim Help sys-
tem via the following code in the “on helpbutton” message han-
dler:
On helpbutton
{
CallHelp("C:\helpfile.chm", 1,1,1);
Abort;
}
OpenURL(string Access the specified URL using your computer’s default browser. I
theURL) Returns non-zero error code if it fails.
ShowBlockHelp Opens the Help dialog, showing the online Help for any global V
(integer block) block. For example, use the function GetEnclosingHblockNum to
get the global block number of an enclosing hierarchical block to
show its Help under ModL code control.
ShowHelp() Opens the Help dialog, showing the online Help for the block. V

Platforms and versions


These functions allow you to determine the version number of ExtendSim and the platform on
which it is running.
Functions

Platforms and
Description Return
versions
GetCurrentPlat- Determines the operating system under which ExtendSim is cur- I
form() rently running. This function returns 0 for 68K Mac OS, 1 for
Power Mac OS or Mac OSX, 2 for Windows 3.1/Win32s, 3 for
Windows NT or XP, and 4 for Windows 95, 98, and ME.
ModL Functions 405
User-defined functions for ADO

Platforms and
versions Description Return

GetExtendVer- Returns a real number in the format 701.1 where 7 is the major R
sion(integer which) version, 1 is the minor version, and 0 is the middle. The value
after the point is 1 for an a, 2 for a b, and so on. This final value
is always zero for a file read version.
Which:
0 : application version
1 : file version
GetExtendVersion- Returns the version number of ExtendSim as a string. S
String()
GetExtendType() Returns the type of the ExtendSim application. I
Normal: 0
LT/RunTime: 2
Demo/Player: 4
GetFileReadVer- Returns the version of the file being read, or previously read. It R
sion() can be used in the On BlockRead message handler to determine
the version of the file that is currently in the process of being read.
In conjunction with the ResizeDTDuringRead function, it will
allow you to inform ExtendSim that a data table has changed size
from the size it was in an older version. (This is useful for using
the Dynamic data table function without breaking existing mod-
els.)
GetFileReadVer- Returns the version of the file being read, or previously read, as a
sionString() string. This is similar to the GetFileReadVersion function, with
the difference that the result is a version string, not a real number.
NOTE: This function returns the complete version string, in the
form ‘major version. minor version.bug fix version', unlike the
GetFileReadVersion function which just returns the major ver-
sion. This function will return an empty string for files earlier than
version 4.0.

User-defined functions for ADO

Functions
User-defined functions are custom functions, coded in ModL, that can be declared in a block
for local use or declared in an include file for use by multiple blocks. For how to create, use,
and override them, see “User-defined functions” on page 72 and “Include files” on page 81.
The following ActiveX Data Object (ADO) functions are used to implement ADO features in
the Data Import Export block (Value library). These ModL-coded functions are stored in an
include file named ADO_DBFunctions.h. To reference that include file in your block’s code,
use a format discussed on page 81, such as #include “ADO_DBFunctions.h”.
406 Reference
User-defined functions for ADO

ADO Function Description Return


ADO_AddRe- Inserts an ExtendSim table into an ADO database table. V
cords(integer ADO_TableName - name of the table in the ADO database
ADOApp, string EX_DBIndex - ExtendSim Database index
ADO_TableName, EX_TableIndex - ExtendSim table index
integer EX_DBIn-
dex, integer Note 1: The tables must have exactly the same structure.
EX_TableIndex Note 2: This is the fastest way to transfer information.

ADO_CheckCom- Returns True (1) if the ADO field type is compatible with the I
patibleField- ExtendSim field type.
Type(string
ADODataType,
integer ExtendSim-
Type)
ADO_Close(inte- Closes the connection to the ADO DLL. Call when done access- I
ger ADOAppHan- ing the DLL.
dle, integer Force)
ADO_Cre- Creates a table in an ADO database. V
ateTable(integer ADO_TableName - name of the table
ADOApp, string ADO_FieldArray contains the table names, their type, “Is nul-
ADO_TableName, lable”, and the number of characters
string63 ADO_-
FieldArray[][4])
ADO_DeleteRe- Deletes records from an ADO database table. V
cords(integer ADO_TableName - name of the table in the ADO database.
ADOApp, string Criteria - SQL statement indicating which rows to delete. To
ADO_TableName, delete all rows, leave blank.
string Criteria)
ADO_Execu- Executes a Non-query SQL statement. V
teNonQuery(inte- SQLStr - SQL statement
ger ADOApp,
string SQLStr)
Functions

ADO_Execute- Executes a Query SQL statement. V


Query(integer SQLStr - SQL statement
ADOApp, string
SQLStr)
ADO_Get- Gets a list of fields in the database. V
Fields(integer ADO_TableName - name of the table
ADOApp, String ADO_FieldArray contains the table names, their type, “Is nul-
ADO_TableName, lable”, and the number of characters. This is returned by the func-
string63 ADO_- tion
FieldArray[][4])
ADO_GetNum- Gets the number of fields in table ADO_TableName. I
Fields(integer ADO_Tablename - name of the table in the ADO database
ADOApp, string63
ADO_TableName)
ModL Functions 407
User-defined functions for ADO

ADO Function Description Return


ADO_GetNum- Gets the number of records in table ADO_TableName. I
Rows(integer ADO_Tablename - name of the table in the ADO database
ADOApp, string63
ADO_TableName)
ADO_GetNum- Returns the number of tables in an ADO Database I
Tables(integer
ADOApp)
ADO_GetTable- Transfers a set of columns to an ExtendSim database table. V
Columns(integer EX_DBIndex - ExtendSim Database index
ADOApp, integer EX_TableIndex - ExtendSim table index
EX_DBIndex, inte- ADO_TableName - name of the table in the ADO database
ger EX_TableIn- ADO_Columns - array containing the column (field names) to
dex, string import into the ExtendSim data table
ADO_TableName,
string63 ADO_- Note 1: Allocate records in the ExtendSim table before calling
Columns[]) this function.
Note 2: The data types for the fields in the ExtendSim table and
the ADO table must be compatible.
ADO_GetTa- Gets the list of tables in the ADO database. ADO_FieldArray V
bles(integer ADO- contains the table names, their type, “Is nullable”, and the number
App, string63 of characters.
ADO_FieldAr-
ray[])
ADO_OpenCon- Opens a connection with an ADO database. This is where data- I
nection(string base information is specified:
DatabaseType, DatabaseType - Access, SQLServer, MYSql, or XML
string FileName, Filename - name of the database
string UserName, UserName
string Password, Password
String Server) Server - name of the database server (not used in Access or XML)
ADO_SetTable- Transfers a set of columns to an ADO database table. V
Columns(integer ADO_TableName - name of the table in the ADO database
ADOApp, string ADO_Columns - array containing the column (field names) to
Functions
ADO_TableName, import into the ExtendSim data table
string63 ADO_- EX_DBIndex - ExtendSim Database index
Columns[], integer EX_TableIndex - ExtendSim table index
EX_DBIndex, inte-
ger EX_TableIn- Note: The data types for the fields in the ExtendSim table and the
dex) ADO table must be compatible.

ADO_Setup() Sets up the connection to the ADO DLL. Call before accessing I
the DLL Returns the ADO Application Handle - referred to in
other functions as ADOApp.
ADO_SQLServer- Returns a list of SQL Server Servers. V
GetServ- ServerInfo - array containing the list of the servers. Allocate this
ers(string63 array before calling the function.
ServerInfo[][4])
408 Reference
User-defined functions for ADO

ADO Function Description Return


ADO_SQLSserver- Returns a list of SQLServer databases. V
GetData- Server - name of the SQL Server
bases(string63 DBArray - returns name, size, description of the SQL Server data-
Server, string63 base. The forth column is unused.
DBArray[][4])
ConvertADOData- Converts an ADO field type to an ExtendSim Constant. I
Type(string ADO- ADODataType - string containing the type for the ADO type
DataType) (float, string, int ...)

ConvertExtend- Converts an ExtendSim constant for data type to SQL string for S
SimDataType(inte- data type.
ger
ExtendSimType)
DB_FieldGetTyp- Returns the string description given an ExtendSim field type. S
eString(integer
ExtendSimType)
Functions
Appendix

Menu Command Numbers


A list of the menu command numbers to be used with
the ExecuteMenuCommand function

“Obedience alone gives the right to command.”


— Ralph Waldo Emerson
410 Appendix

The ExecuteMenuCommand(commandNumber) function executes a specified menu command


(see “Scripting” on page 337). This is functionally the same as selecting the command from the
menu. Below is a list of the command numbers that are used with that function.
☞ As of ExtendSim 10 the menu commands have changed such that there are some new menu
commands while others have been deleted.

Command
File Menu
Number
New Model 2
New Text File 1601
Open 3
Recent Files (1-5) 1555-1559
Close 4
Save Model 5
Save Model As 6
Print 9
Update Launch Control 1410
Properties 2001
Exit or Quit 1

Edit menu Command


Number
Cut 18
Copy 19
Paste 20
Clear 21

Command
Model > Connection Line Style Sub menu
Number
Appendices

Smart 5004
Right-Angle 5001
Straight 5002
Free Form 5003
Menu Command Numbers 411

Command
Database Menu
Number
Read/Write Index Checking 1931

Command
Run Menu
Number
Run Simulation 6000
Show 2D Animation 2020
Stop 30000
Pause 30001

Command
Run > Model Debugging Menu Number
Generate Trace 2040
Add Selected Blocks To Trace 2041
Add All Blocks To Trace 2045
Remove Selected Blocks From Trace 2042
Remove All Blocks From Trace 2043
Show Tracing Blocks 2044

Command
Simulation Status Bar
Number
Slower Animation 30004
Faster Animation 30005

Command
Text Fonts (sets the default font)
Number
Appendices

Courier 6100
Helvetica 6101
Times 6102
Arial 6103
412 Appendix
Appendices
Appendix

Upper Limits
A list of the maximum numbers of things
that you can do at one time

“The thing I am most aware of is my limits.”


— André Gide
414 Appendix

Note: Some limits depend on available memory.

Total model data size 2.8E14 bytes


Steps in a simulation run 2 billion
Number of simulations in a multiple run 2 billion
Block name or label length, characters 31
Blocks in a model 2 billion
Blocks in a library 200
Libraries open at one time 40
Text files open at one time 200
Databases per model 2 billion
Tables per database/fields per table/records per table 2 billion/1,000/2 billion
Output connectors in a model (nodes) 2 billion
Connectors per block 255
Length of a block’s ModL code (characters) 1 gigabyte
Dialog items in a block 1024
2D animation objects per block 255
Dynamic arrays (each array) 2 billion elements
Number of array dimensions 5
Maximum index for array dimensions 2 billion elements total
Dynamic arrays per block 255
Columns in a table 255 (data table); 255 (text table)
Total table size (cells) per block for static data tables 3260 (data table); 2030 (text table)
Total table size (cells) each, for dynamic data tables 2 billion
Variable name length: dialog item msgs, connector 63
names
Variable name length: ModL local, static variables 127
Maximum popup menu length 5100 characters or 20 strings
Appendices

User defined function arguments 127


Nested loops 32
Maximum, minimum of real numbers ±1E±308
Maximum, minimum of integer numbers ±2,147,483,647
Significant figures in real calculations 16 (double)
Upper Limits 415

Number of attributes for discrete event item 500


Static and local variable declaration limit (See page 62) 32,767 bytes

Appendices
416 Appendix
Appendices
Appendix

ASCII Table
To help you determine the values of
the ASCII characters

“I would sooner read a timetable or catalogue than


nothing at all. They are much more entertaining
than half the novels that are written.”
— W. Somerset Maugham
418 Appendix

This table shows the ASCII values from 00 to 127, which are the same for Windows and Mac
OS. Values above 127 are not part of the standard ASCII set and vary depending on the font.
00 NUL 32 space 64 @ 96 `
01 SOH 33 ! 65 A 97 a
02 STX 34 " 66 B 98 b
03 ETX 35 # 67 C 99 c
04 EOT 36 $ 68 D 100 d
05 ENQ 37 % 69 E 101 e
06 ACK 38 & 70 F 102 f
07 BEL 39 ' 71 G 103 g
08 BS 40 ( 72 H 104 h
09 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DC1 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 ETB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
Appendices

27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 \ 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 ~
31 US 63 ? 95 _ 127 DEL
Appendix

Cross-Platform Considerations
File conversion, file name comparisons, and keyboard shortcuts
for the Windows and Macintosh operating systems

“There never were, since the creation of the world,


two cases exactly parallel.”
— Lord Chesterfield
420 Appendix
Libraries

Libraries
In most cases, libraries should be placed in the ExtendSim\Libraries folder; they can be placed
in subfolders within that folder. Optionally, libraries needed by a model can also be at the
model file location.
Libraries should never be placed anywhere outside of either the Libraries folder or the folder
that contains the model file that uses the library.
ExtendSim supports library file names up to 256 characters. Library names must end in the
“.LBR” extension. (Libraries developed in ExtendSim releases earlier than 10 used the LIX
extension; they are automatically converted to LBR when opened in newer releases.)
Models
Model file names can be any length. All models must end in the “.MOX” extension.
Menu and keyboard equivalents
The following table lists some common actions and keyboard shortcuts under the Windows
and Mac OS systems. Appendix A of the User Reference contains pictures of the ExtendSim
menus, including keyboard equivalents for the menu commands.

Menu > Command or


Action Windows keyboard Mac OS keyboard
Right-Click menu
Open a model File > Open CTRL+O CMND+O
Open a library Library > Open Library CTRL+L CMND+L
Save a model File > Save Model CTRL+S CMND+S
Close the active File > Close CTRL+W CMND+W
window
Run a simulation Run > Run CTRL+R CMND+R
Stop a simulation Run > Stop CTRL+period (.) CMND+period (.)
Stop a library CTRL+period (.) CMND+period (.)
search
Open a hierarchi- Develop (or right- Hold down the Alt key Hold down the Option
cal block’s struc- click) > Open Hierarchi- while double-clicking key while double-clicking
ture window. cal Block Structure the block’s icon on the block’s icon
(Select block icon first)
Open a library Develop (or right- Hold down the Alt key Hold down the Option
block’s structure click) > Open Block while double-clicking key while double-clicking
Appendices

window Structure the block’s icon on the block’s icon


(Select block icon first)
Proportionately Hold down the Shift Hold down the Shift key
scale drawing key while resizing the while resizing the object
object object
Cross-Platform Considerations 421
Menu and keyboard equivalents for developers

Menu and keyboard equivalents for developers


Develop menu

Command Windows Macintosh


Compile Block Ctrl+K Cmnd+K
Shift Selected Code Left Ctrl+[ Cmnd+[
Shift Selected Code Right Ctrl+] Cmnd+]
Go To Line Ctrl+‘ Cmnd+‘

Run menu

Command Windows Macintosh


Run Simulation Ctrl+R Cmnd+R
Simulation Setup Ctrl+J Cmnd+J
Stop Ctrl+. Cmnd+.
Pause Ctrl+/ Cmnd+/
Resume Ctrl+\ Cmnd+\
Model Debugging > Add Selected Blocks To Ctrl+8 Cmnd+8
Trace
Model Debugging > Remove Selected Blocks Ctrl+9 Cmnd+9
From Trace

Transferring files between operating systems


The Windows and Mac OS versions of ExtendSim are cross-platform compatible. For exam-
ple, if you build a model or a library on your Windows computer, you can move it to a Mac OS
computer and ExtendSim will read it, and vice versa.
There are three considerations when transferring ExtendSim files between Windows and Mac
OS systems: file name adjustments, physical transfer, and file conversion.
Models and libraries developed in an older version and different platform may not transfer suc-
cessfully. It is strongly recommended that you upgrade to the latest version on the source plat-
form, re-save the structure of any hierarchical blocks stored in libraries, and recompile any
libraries that you have created. Then re-save your models before transferring your files.
File name adjustments
Appendices

• Windows to Mac OS: When you transfer files from a Windows computer to a computer run-
ning Mac OS, it is important that you do not delete the MOX extension. The MOX extension
is required so ExtendSim can identify the file as a Windows model. After ExtendSim has
converted the Windows model to Mac OS format, save the model under the same name or a
new name.

• Mac OS to Windows: If you transfer files from a Mac OS to a Windows computer, you may
need to change the name of your file before you transfer it. File names must end in a three-
422 Appendix
Transferring files between operating systems

character extension (the extensions are “.MOX” for ExtendSim model names, “.LBR” for
library names, and “.TXT” for text file names). To change your Mac file names to Windows
format, change the name of the file on the Mac OS computer using the Save As command (if
the file is open) or using the Finder (if the file is not open).

Physically transferring files


Once you have made any necessary file name adjustments, physically transfer the files
between Windows and Mac OS computers. This process depends on your system resources
and is independent of ExtendSim. For example, you might copy the file onto a memory stick.
Or you could send the files directly from one computer to the other if the computers are net-
worked.
☞ Extensions created on a Mac OS computer need to be converted before being physically trans-
ferred to the Windows system, as discussed below.
File conversion
In most cases file conversion are handled automatically by ExtendSim. However, extensions
that you build, such as DLLs and Shared Libraries, require conversion. Include files are, of
course, already cross-platform compatible.
Converting model files
The Windows version of ExtendSim can read ExtendSim model files created on the Mac OS as
long as the name format is correct, as discussed above. The Mac OS version of ExtendSim can
read ExtendSim model files created under Windows without file name modification (in fact, as
discussed above, the MOX extension should not be removed).
If your models (including hierarchical blocks) use libraries that you have created, and you have
changed the name of those libraries, ExtendSim will not be able to locate the library. In this
case, ExtendSim will ask you to find and select the correct library as described in the User Ref-
erence. Keeping all your libraries in the Libraries folder will make this search process easier.
Saving the model will cause the renamed libraries to be used from then on.
For model files that have blocks that access text files (such as the Read block from the Value
library), you may need to change the name of the text file that is being read to conform to plat-
form requirements, as discussed above. Be sure to also change the name of the file in the Read
block’s dialog to correspond to the new file name.
☞ The first time you run a model that has been transferred from one operating system to another,
any Equation blocks in the model will recompile to the format of the new system at the begin-
ning of the simulation run. Messages that report this process may appear too quickly for you to
read.
Converting hierarchical blocks in libraries
If you have a hierarchical block saved in a library and you have renamed any of the libraries of
Appendices

the blocks inside the hierarchical block (for example, to comply with Windows format), you
need to update the hierarchical block’s information so that it can locate the renamed libraries.
The easiest way to do this is to drag hierarchical blocks from their libraries, place them on a
worksheet, and update their structure, as discussed below.
☞ This is only required for hierarchical blocks saved in libraries; hierarchical blocks saved only
in a model get updated with the model.
Cross-Platform Considerations 423
IPC or multi-server considerations

When you add a hierarchical block from a library to a model worksheet, the hierarchical block
causes ExtendSim to open the libraries of the blocks inside it. Since you have renamed those
libraries, ExtendSim will not be able to locate them. In this case, ExtendSim will ask you to
find and open the correct libraries. Note: keeping all your libraries in the Libraries folder will
make this search process easier.
If you save the model worksheet that contains the hierarchical block, the location of the
renamed libraries is saved for the model only. Before you close the model worksheet, you also
need to update the hierarchical block’s library information. To do this, open the hierarchical
block’s structure window and then close it, causing the hierarchical block’s Save dialog to
appear. In the dialog, choose Also save to library. This process is described in the User Refer-
ence.
☞ It is strongly recommended that you keep library names the same on either operating system.
Libraries
Physically transfer libraries to the target computer. Then recompile the libraries under the tar-
get computer’s operating system using the Library > Library Tools > Compile Libraries com-
mand.
Blocks that use the equation functions
If you build blocks that use the equation functions, your code needs to detect if the model is
being opened on a different platform. See the “Equations” on page 238 for more information.
Extensions
Extensions are files (such as pictures and DLLs) that can be accessed by ExtendSim to fulfill
specialized tasks. Like libraries, the extensions that come with your ExtendSim package are
formatted correctly for your operating system. However, if you build your own extensions, and
you want to transfer your extensions (or blocks that use them) to a computer running a differ-
ent operating system, you will need to do some conversion:
• Pictures: As discussed“Picture and movie files” on page 89, ExtendSim accepts most types
of picture files.

• Sounds: WAV files are supported on both platforms and shareware utilities are available to
convert Mac OS sound resources (SNDs) to Windows sound files (.WAV) and vice versa.

• DLLs and Shared Libraries: On Windows the DLL functions will search the ExtendSim
Extensions folder for a DLL file. For the Mac OS those same calls will search for a Shared
Library file.

IPC or multi-server considerations


The ModL language can only be compiled by ExtendSim. ExtendSim will execute ModL code
Appendices

in the same way regardless of the platform (Windows or Macintosh) on which it runs.
However, ExtendSim is capable of communicating with other applications through ModL
code, and some of these applications may not have a consistent interface across platforms. The
following is a discussion of some of the things to consider when writing ModL code that is
intended to be cross-platform compatible.
The interprocess communication (IPC) functions allow ExtendSim to act as a client application
and request data and services from server applications. When using the IPC functions, it is
important to remember that the syntax of some of the function arguments are dependent both
424 Appendix
Cross-platform code

on the server application that ExtendSim is communicating with and the platform that Extend-
Sim is running on. For example, the serverName argument of the IPCConnect function (which
defines the application you want to connect ExtendSim to) must be in the format appropriate
for that application and platform. The serverName for Microsoft Excel on the Windows operat-
ing system would be “Excel,” while on the Mac OS operating system it would be
“XCEL.”.This type of information can be found in the documentation of the server application.
When writing ModL code that utilizes IPC functions and is meant to be cross-platform com-
patible or capable of operating with multiple server applications, it is necessary to define the
function arguments according to the platform application prior to calling the function. This can
be accomplished by using the platform variables PLATFORMMACINTOSH, and PLAT-
FORMWINDOWS) and using dialog items to define the server application (see blocks in the
IPC library for examples).
For instance, the following code establishes a conversation between ExtendSim (the client)
and Excel (the server) on either the Windows or Mac OS operating system:
if (PlatformMacintosh)
serverName = “XCEL”;
if (PlatformWindows)
serverName = “Excel”;
IPCConnect (serverName, theSpreadsheet);
The following is a list of functions that contain arguments where the syntax of the argument
depends on the server application (the dependent argument is shown in italics):
• IPCConnect(serverName, topic)
• IPCExecute(conversation, executeData, item)
• IPCPoke(conversation, pokeData, item)
• IPCRequest(conversation, item)

Cross-platform code
The following ModL constants return TRUE or FALSE depending on the platform: PLAT-
FORMMACINTOSH; PLATFORMWINDOWS; PLATFORMPOWERPC. You can use these
constants in an If statement to make code be cross-platform capable. For example:
if (PLATFORMWINDOWS)
Windows specific code

else if (PLATFORMMACINTOSH)

Macintosh specific code


Appendices
Index 425

Symbols E3D environment 135


event queue 137
207 ExtendItems 140
_(underscore) character 112 ExtendPlayers 140
_leftClickDB 98, 100 ExtendVehicles 140
.cs files 149 functions 276
** 33 gravity 145
*/ 33 ground height 148
GroupTags 139
/* 33
idleSoundVol 147
// 33
immediate functions 137
#define 83 interiors 155
#else 78, 83 markers 148
#endif 78, 83 messages 223
#ifdef 78, 82 modes 136
#ifndef 83 mount nodes 143
% operator 69 mounting 143
mountPoint 143
Numerics mountStack 144
Name field 138
2D animation new objects 149
adding to a block 53 object classes 140
between blocks 132 object label 138
changing a level 130 object tops 148
color 128, 133 objectID 139
functions 270 overview 135
hiding a shape 129 paths 148
hierarchical blocks 129 performance considerations 136
moving a shape 130 pixels to distance ratio 137
objects 10, 53 position of object 141
overview 10 post functions 137
pictures 132 QuickView mode 136
pixels 134 rotation of objects 141
programming 126 scale of objects 141
shapes 127 script file 149
showing a shape 129 scripting environment 150
stretching a shape 131 skins of objects 141
text 134 sound 145
3D animation terrain 156
3D window 135 time ratio 138
ambient animation 147 time ratios 137
Buffered mode 137 Torque Game Engine 135
buildings 155 units 141
clock 137 unmounting 144
collision 144 userTag 139
Concurrent mode 136 Wall.cs file 149
creating a new object 149 waypoint 148
DataBlocks 151 3D animation functions 287
DIF format 156 3D array 172
distance ratio 137
3D block functions 277
DTS 149
426

3D creation, deletion functions 282 Visual Basic 124


3D distance functions 289 Visual Basic examples 124
3D environment functions 282 ActiveX Automation 118
3D event queue 137 ActiveX Data Objects functions 405
3D messages 223 Add External Code to Libraries command 84
3D miscellaneous functions 294 Add to Custom Colors button 401
3D mounting functions 286 add to right click menu 19
3D mountStack functions 280 AddBlockToClipboard 337
3D movement functions 283 AddBlockToSelection 337
3D name functions 288 AddC 230
3D object functions 281 ADO functions 405
3D path functions 280 ADO_AddRecords 406
3D post functions 137, 285 ADO_CheckCompatibleFieldType 406
3D properties functions 292 ADO_Close 406
3D screenshot functions 289 ADO_CreateTable 406
3D script functions 293 ADO_DeleteRecords 406
3D skin functions 290 ADO_ExecuteNonQuery 406
3D tick functions 292 ADO_ExecuteQuery 406
3D time functions 278 ADO_GetFields 406
3D user tag functions 291 ADO_GetNumFields 406
3D vector functions 291 ADO_GetNumRows 407
3D window functions 279 ADO_GetNumTables 407
ADO_GetTableColumns 407
A ADO_GetTables 407
ADO_OpenConnection 407
Abort statement 70, 166
ADO_SetTableColumns 407
in CheckData 72
in Simulate 72 ADO_Setup 407
AbortAllSims 166, 402 ADO_SQLServerGetServers 407
AbortAllSimsSilent 402 ADO_SQLSserverGetDatabases 408
AbortDialogMessage 220 AdviseReceive 223
aborting multiple simulations 162, 166 alert functions 268
AbortSilent 402 AlignConnection 299
absolute value 228 alignment of dialog item labels 19
Acos 229 alpha channel 401
ActivateApplication 337 Alt key 269
ActivateModel 216 alternate views 9
ActivateWorksheet 337 ambient animations 147
ActiveX animation
Automation 118 2D 126
BlockMsg 122 2D functions 270
C++ examples 119 3D 135
client 118 3D functions 276
controls 253 animation object (2D) 127
Execute 120 animation object (3D) 138
GetObjectHandle 123 ambient animation 147
Poke 121 buildings 155
Request 120 classes 140
427

collision 144 AnimationMovieFinish 273


creating a new 149 AnimationObjectCopyData 273
creating new 149 AnimationObjectCreate 127, 273
exporting 149 AnimationObjectDelete 273
ExtendBase 140
AnimationObjectExists 274
ExtendItems 140
AnimationObjectExists2 274
ExtendPlayers 140
ExtendVehicles 140 AnimationOn 128, 210
gravity 145 AnimationOval 127, 274
GroupTags 139 AnimationPicture 274
interiors 155 AnimationPixelRect 274
mounting 143 AnimationPixelRectEColorInit 274
mountStack 144 AnimationPixelSet 274
objectID 139 AnimationPixelSetEColor 274
people 147 AnimationPoly 126, 127, 274
rotation 141 AnimationRectangle 274
scale 141
AnimationRndRectangle 127, 275
skins 141
AnimationSetDelayMode 275
sound 145
unmounting 144 AnimationSetSpeed 275
userTag 139 AnimationShow 127, 129, 275
Animation Object button 10 AnimationStatus 216
animation object tool 21 AnimationStretchTo 131, 275
animation objects 10 AnimationText 134, 275
Properties dialog 127 AnimationTextAlign 275
zOrder 54 AnimationTextSize 275
AnimationAntialias 271 AnimationTextTransparent 134, 275
AnimationBlockToBlock 132, 271, 276 AnimationZOrderGet 275
AnimationBorder 271 AnimationZOrderSet 276
AnimationBorderColor 271 AntitheticRandomVariates 210
AnimationBorderEColor 271 API 2
AnimationColor 271 AppendDataTableLabels 314
AnimationEColor 127, 133, 271 AppendPopupLabels 306
AnimationGetHeight 272 AppleEvents 250
AnimationGetHeightR 272 application.ini file 79
AnimationGetLeft 272 ApplicationFrame 337
AnimationGetLeftRelative 272 arguments
AnimationGetLeftRelativeR 272 arrays as 67, 74
AnimationGetSpeed 272 call tips 79, 227
AnimationGetTop 272 data type expectations 227
of function calls (converting) 64
AnimationGetTopRelative 272
pass by value or reference 102
AnimationGetTopRelativeR 272
array segment 67
AnimationGetWidth 272
ArrayDataMove 376
AnimationGetWidthR 272
ArrayLabelParse 394
AnimationHide 129, 272
arrays 65
AnimationLevel 130, 273
array segment 67
AnimationMoveTo 130, 273 as arguments 67, 74
AnimationMovie 273 copying using FOR loops 108
428

definition 30 BarChartCategorySet 353


dimensions 65 BarChartSet 353
disposing 104 BarChartValueGet 353
disposing of global 107 BarChartValueSet 354
dynamic 26, 66
BarGraph 347
fixed 26, 66
basic math functions 227
fixed or dynamic 30
functions 376 Beep 268
global arrays 67, 107 bidirectional connectors 101
import function 108 Bidirectional Flows model 101
in discrete event modeling 166 Binomial distribution function 230
memory usage 101 BitAnd 238
passing 103, 377 BitClr 238
passing (precautions) 104 bit-handling functions 238
subscripts 65 bitmap pictures 423
working with 101 BitNot 238
ASCII value table 418 BitOr 238
Asin 229 BitSet 238
ASP license BitShift 238
form-based interface 124
BitTst 238
assignment operators 68 BitXor 238
Atan 229 BLANK 63
Atan2 229 block
AttribInfo 222 compile command 421
AttribType array 173 block number 299
AttributeList array 173 block parts
attributes accessing from code 35
arrays for items 172 animation 8
flow 173 code 7
functions 396 connector types 20
AttribValues array 173 connectors 8
AudioClose3d 145 Connectors pane 8
AudioCloseLooping3d 145 Dialog Item Names pane 9
audioProfile 147 dialog items 8, 14
auto indentation 79 Help tab 8
automation icon 8
methods 118 icon views 8
automation, OLE ModL code 7
client 118 script 7
server 118 Script tab 12
tabs 8
AutoScaleX 346
AutoScaleY 347 block status messages 217
block to block messages 222
B BlockAdjustPosition 337
blockAdjustPosition 10
BarChart 353 BlockClick 217, 269
BarChartCategoryCountGet 353 BlockDialogIsOpen 326
BarChartCategoryCountSet 353 blocked message 176
BarChartCategoryGet 353 BlockIdentify 217
429

blocking the flow 177 submenus in library 55


BlockLabel 217 that don’t post future events 169
BlockMove 217 that post events 168
BlockMsg 118, 122 types of discrete event 168
uncompiled 45
BlockName 113, 295
BlockRead 217, 316 BlockSelect 218
BlockSimFinishPriority 328
BlockReceive 222
BlockSimStartPriority 328
BlockReceive0 169
BlockTableInfo 222
BlockReceive3 169
BlockUndelete 218
BlockRect 295
BlockUnselect 218
BlockReport 162, 165, 216, 345
blue circle 205
BlockRightClick 217
Boid object DataBlock 146
blocks
2D animation between 132 Boolean operators 69
adding connectors 46 Border Color tool for dialog items 17
animating in 2D 53 brace matching 78
categories 55, 295 Break statement 70, 72
communicating with each other 97 Breakpoint Conditions dialog 207
communication 97, 295, 299, 305, 328 breakpoints
compiling 47 condition 192
data table functions 312 definition 192
dialog items when creating 35 disabling 202
dialog tab functions 327 margin 194
dialogs 6, 326 removing 202
dynamic text functions 320 setting 199
equation-based 92 setting conditions 200
Executive 162 window 206
for debugging 190 Breakpoints window 206
hierarchical (animating) 129 Breakpoint and Condition columns 201
icon view functions 330 Buffered mode 136, 137
icons 9 button
intermediate results 51 creating 52
labels 295 dialog item 14
labels (length) 414 message 221
Make Your Own 166 titles (changing) 38, 96
messaging functions 328
Buttons block 92
names 295
names (length) 414
new 44 C
numbers 295, 299 C to Pascal string function 61
parts of a block 7 CalcDate
popup menus 48 see EDCalcDate 398
programming discrete event 166 CalcFV 233
programming discrete rate 185 CalcNPER 233
protecting 89
CalcPMT 234
red border for debugging mode 193
CalcPV 234
registered 111
remote communication 97 CalcRate 234
structure 7 calendar 15
430

calendar date CloneInit 218


functions 397 CloneResize 340
call chain CloseBlockDialogBox 326
yellow location arrow 196, 205 CloseDialogBox 326
Call Chain pane 194 CloseEnclosingHBlock 326
Call Tips 79, 227 CloseEnclosingHBlock2 326
CallHelp 404 CloseModel 216
Cancel 220 ClosePlotter 347
case sensitivity 60 ClosePlotter2 347
CASE statement 72 CM 84
categories of blocks 55 cm extension 84
Category 153, 154 code
Ceil 228, 229 colorization 78
CellAccept 220 conventions 49
ChangeAxisValues 347 example 47
ChangePlotType 347 language overview 27
ChangePreference 338 layout 32
ChangePreferenceString 338 management 84
script editor 78
ChangeSignalColor 347
type declarations 33, 60
ChangeSignalSymbol 347
code completion 33, 79
ChangeSignalWidth 347
customizing 79
changing parameters globally 96 for functions 227
chart functions 345 code folding 79
checkbox code management 84
programming for 37
code marker 199
titles (changing) 96
CodeExecute 340
checkboxes 14
coding conventions 49
CheckData 158, 160, 215
color 128, 133
classes of 3D objects 140
HSV 128
ClassName 154
color selector window 401
ClearBlock 338
colored code 78
ClearBlockUndo 338
column index 92
ClearConnection 338
column separators 243
ClearStatistics 222
column tag functions 321
ClearUndo 338
COM DLL example 117
client application 423
comments 12
CloneCreate 339 multi-line 33
CloneDelete 339 single line 33
clone-drop 97 compile
code for a custom stand-alone block 98 conditionally 29, 76, 82
CloneFind 339 Compile Block command 421
CloneGetDialogItem 339 Compiled_Debug 83
CloneGetDialogItemLabel 339 complex number function 230
CloneGetInfo 339 ConArrayChanged 221
CloneGetList 339 ConArrayChangedComplete 221
CloneGetPosition 339 ConArrayChangedWhichCon 303
CloneHideDisable 339
431

ConArrayCollapseChanged 221 initializing 100


ConArrayGetCollapsed 303 labels 22
ConArrayGetConNumber 303 messages 174, 180
ConArrayGetDirection 303 naming 21, 34
no resize bar 21
ConArrayGetNthCon 303
normal 22, 35
ConArrayGetNthCon2 303
normal vs variable 21
ConArrayGetNumCons 303 renaming 46
ConArrayGetOwnerCon 304 tools 20
ConArrayGetTotalCons 304 tooltips 23
ConArrayGetValue 304 types 20
ConArrayMsgFromCon 304 User Defined 20
ConArraySendMsgToAllCons 304 variable 21, 22, 35, 100
ConArraySendMsgToInputs 304 Connectors pane 8, 21
ConArraySendMsgToOutputs 304 ConnectorShowHide 218
ConArraySetCollapsed 304 ConnectorToolTip 222
ConArraySetNumCons 304 ConnectorToolTipGet 305
ConArraySetValue 305 ConnectorToolTipSet 305
concatenation 68, 69, 269 ConnectorToolTipWhich 305
Concurrent mode 136 constant definitions 32
conditional breakpoints 207 constants 61, 63
conditional compilation 29, 76, 82 definition 30, 33, 63
ConjugateC 235 in equation-based blocks 63
ConnectionBreak 221 names 60
ConnectionClick 221 Continue statement 70, 72
ConnectionMake 218, 222 Continue tool 204
connector labels ContinueSim 160, 215
defined 22 control 41
formatting 22 control statements 70, 72
connector messages 174, 221 conversion
connector names of numeric types 64
used as variables in ModL 34 convert a variable connector 21
connector tool tips 305 ConvertADODataType 408
ConnectorLabelsGet 305 ConvertExtendSimDataType 408
ConnectorLabelsSet 305 ConvertTimeUnits 397
ConnectorMsgBreak 328 CopyBlock 218
ConnectorName 222 copying
ConnectorRightClick 218, 222 dialog items 95
connectors 34 Cos 229
adding 22, 46 Cosh 229
bidirectional 101 cost array 170
changing 100 costing attributes 173
changing an input to an output 46 Create New Library button 44
changing from normal to variable 21 CreateBlock 50, 218
changing the type of 22 CreateFolder 244
checking in CheckData 215 CreateHBlock 340
deleting 100
CreatePopupMenu 306
functions 299
cross-platform compatibility 421
432

cross-platform development 423 no such record error 355


CurrentScenario 210 not linked error 355
CurrentSense 210 not unique error 355
CurrentSim 160, 163, 210 not unique index error 355
number of databases per model 414
CurrentStep 161, 210
properties functions 359
CurrentTime
random data functions 368
changed by Executive block 210
read/write functions 363
currentTime registering blocks 55, 317
in Debugger window 194 reserved 112
custom colors 401 selecting functions 357
sort/search functions 371
D viewng functions 374
data working with 111
checking in CheckData 215 DataBlock
consumption by type of variable 61 audioProfile 147
linking to databases 55 definition 151
linking to global arrays 55 types 151
managing data in complex models 111 variables 152, 153
repository 111 DataTableHover 220
source (organizing) 92 DataTableResize 220
source indexing 92 DataTableScrolled 220
data consumption 61 date functions (legacy) 399
data tables 15, 38 DateToString
functions 312 see EDdateToString 398
row and column 18 DB_FieldGetTypeString 408
data type declarations 32 DBAddressCreate 373
data types 33, 60 DBAddressGetAllIndexes 373
definition 30 DBAddressGetAsString 373
Database DBAddressGetDlg 373
Read/Write Index Checking 354 DBAddressGetDlg2 373
database errors DBAddressGetFromString 373
no such parent 355 DBAddressIncrementIndex 373
no such record 355
DBAddressReplaceIndex 373
not linked error 355
DBBlockRegister 111
not unique error 355
not unique index 355 DBBlockRegisterContent 375
database functions 354 DBBlockRegisterContents 111
databases (ExtendSim) DBBlockRegisterStructure 111, 375
_character at beginning of name 112 DBBlockUnregisterContent 375
accessing 111 DBBlockUnregisterStructure 375
copying functions 358 DBChildPopupSelector 357
creating 111 DBDatabaseCloseViewer 374
creating/deleting functions 355 DBDatabaseCopy 358
DB address functions 372 DBDatabaseCreate 355
functions 354 DBDatabaseDelete 355
import/export functions 358 DBDatabaseDeleteByIndex 355
linking/notify functions 374
DBDatabaseExists 359
no such parent error 355
DBDatabaseExport 358
433

DBDatabaseGetIndex 359 DBFieldCreateByIndex 356


DBDatabaseGetIndexFromAddress 373 DBFieldDelete 356
DBDatabaseGetName 359 DBFieldDeleteByIndex 356
DBDatabaseImport 359 DBFieldExists 360
DBDatabaseOpenCell 374 DBFieldGetIndex 360
DBDatabaseOpenViewer 374 DBFieldGetIndexFromAddress 373
DBDatabaseOpenViewerToTab 374 DBFieldGetName 360
DBDatabasePopupSelector 358 DBFieldGetProperties 360
DBDatabaseRename 360 DBFieldGetPropertiesUsingAddress 361
DBDatabasesGetNum 360 DBFieldMove 361
DBDatabaseShowHideReserved 360 DBFieldPopupSelector 358
DBDatabaseTabChangeName 360 DBFieldRename 361
DBDatabaseTabDelete 355 DBFieldSetInitialize 361
DBDataGetAsNumber 363 DBFieldSetProperties 361
DBDataGetAsNumberParentAltField 363 DBFieldsGetNum 361
DBDataGetAsNumberUsingAddress 363 DBGetSize 362
DBDataGetAsString 364 DBinomial 230
DBDataGetAsStringParentAltField 364 DBParameter 318, 376
DBDataGetAsStringUsingAddress 364 DBRandomDistributionGet 369
DBDataGetCurrentSeed 368 DBRandomDistributionSet 370
DBDataGetDateAsSimTime 364 DBRecordExists 361
DBDataGetDateAsSimTimeUsingAddress 364 DBRecordFind 371
DBDataGetParent 365 DBRecordFindMultipleFields 371
DBDataGetParentUsingAddress 365 DBRecordFindMultipleFieldsArray 371
DBDataSetAsNumber 365 DBRecordFindNumericalRange 372
DBDataSetAsNumberReserved 365 DBRecordFindParentRecordIndex 372
DBDataSetAsNumberUsingAddress 365 DBRecordGetIndexFromAddress 374
DBDataSetAsNumberUsingAddressReserved DBRecordIDFieldGetIndex 362
365 DBRecordPopupSelector 358
DBDataSetAsParentIndex 366 DBRecordsDelete 356
DBDataSetAsParentIndexReserved 366 DBRecordsGetNum 362
DBDataSetAsParentIndexUsingAddress 366 DBRecordsInsert 356
DBDataSetAsParentIndexUsingAddressRe- DBRelationCreate 356
served 366 DBRelationDelete 356
DBDataSetAsString 366 DBRelationsGetNames 362
DBDataSetAsStringReserved 366 DBRelationsGetNum 362
DBDataSetAsStringUsingAddress 367 DBTabGetTableIndexList 362
DBDataSetAsStringUsingAddressReserved 367 DBTableCloneToTab 357
DBDataSetCurrentSeed 368 DBTableCopy 358
DBDataSetDateAsSimTime 367 DBTableCreate 357
DBDataSetDateAsSimTimeReserved 367 DBTableCreateByIndex 357
DBDataSetDateAsSimTimeUsingAddress 367 DBTableDelete 357
DBDataSetDateAsSimTimeUsingAddressRe- DBTableDeleteByIndex 357
served 367 DBTableExists 362
DBDatatable 318, 375 DBTableExportData 359
DBFieldCreate 355 DBTableGetIndex 362
434

DBTableGetIndexFromAddress 374 DebugWrite 191, 403


DBTableGetName 363 decision blocks 168
DBTableGetProperties 362 DEExecutiveArrayResize 222
DBTableImportData 359 Delay 394
DBTablePopupSelector 358 delay line functions 393
DBTableRename 363 DelayInit 337, 394
DBTableSetProperties 363 DeleteBlock 218
DBTablesGetNum 363 DeleteBlock2 218
DBTableSort 372 delimiters 243
DBTabletoGA 379 DeltaTime 158, 160, 161, 210
DBToolTipsGet 357 Determinant 235
DBToolTipsSet 357 DeterminantC 235
DDE (dynamic data exchange) 250 Develop command 44
DE Modeling Using Equation Blocks 336 Develop menu keyboard equivalents 421
Debug Tutorial model 193 DExponential 230
debugger 192 DGamma 230
arrays 208 DI ID 18
breakpoint margin 194 diagnostic functions 268
breakpoints 192 dialog functions 312, 320, 326
call chain pane 194 Dialog Item Names pane 9
Debugger window 194
dialog items 6, 15, 35
indicators in the margin 205
add to right click menu option 19
location arrow 194, 195
alignment of labels 19
red border around blocks 193
Border Color for labels 17
removing breakpoints 202
buttons 14, 38
setting breakpoints 199
buttons (creating) 52
setting conditions 200, 207
calendar 15
source pane 194
changing text and titles 94
toolbar 204
checkbox 14
tutorial 193
checkboxes 37
variables pane 194
color for labels 17
WatchPoint conditions 208
copying 95
window 204
data tables 38
Debugger window 194 display only option 19, 50
empty circle 202 dynamic text 15, 36
indicators 205 editable text 15, 36
toolbar 204 editable text 31 character limit 15
DebuggerBreakpoint 402 embedded objects 16, 41
debugging 191 Fill Color option 17
block code using UserError 268 format text 19
blocks for 190 frame 15, 40, 49
functions 402 functions 305
functions using alerts and prompts 268 hidden 18
models 190 ID 18
source code (see "debugger") 192 labels 17
tips 208 linking to ExtendSim databases 55
tracing 190 linking to global arrays 55
using DebugMsg function 191 list 14
DebugMsg 191, 403 messages 36, 219
435

meter 15, 41 DialogMoveTo 326


move manually 95 DialogOpen 220
move to another tab 95 DialogPicture 276
move using code 95 DialogRefresh 340
names 17, 35
dialogs
new 44
Dialog Item Names pane 9
numeric formats for 17
exploring 6
parameter 14, 36, 49
functions for opening and closing 326
parameter fields 14
Help tab 14
popup menus 14, 39, 48
programming tips 93
radio button 15, 37, 48
tab for dialog editing 13
show and hide 95
tabs 8, 13
slider 15, 41
text (changing) 93
static text label 15, 39
DialogSetSize 326
style 19
switch 41 DIF format 156
switch control 15 DiffDate 399
tab order 18 DIFontSize 394
tabs 8, 13 DIGetID 306
text frame 40 DILinkClear 318
text tables 15, 38 DILinkInfo 318
tool tips 20, 326 DILinkingDisabled 318
types (definition) 17 DILinkModify 319
types of 14 DILinkMsgs 319
visible 18
DILinkSendMsgs 319
visible in all tabs option 18
DILinkUpdateInfo 320
W and H coordinates 17, 96
X and Y coordinates 17, 95 DILinkUpdateString 320
zOrder 17 dimensions of an array 65
Dialog Items 2 toolbar 44 DIMoveBy 306
dialog messages 219 DIMoveTo 307
dialog names DIMsgNumber 307
used as message names 36 DIParamTagGet 325
used as variable names 36 DIParamTagSet 325
Dialog Resizer 13 DIParamTagStringGet 325
Dialog tab 8, 13, 44 DIPopupButton 307
dialog tab functions 327 DIPositionGet 307
dialog variables DIPositionHome 307
getting and/or setting remotely 97 DIPositionSet 307
remote interface with 97 DirPathFromPathName 244
DialogClick 220, 269, 306 DisableDialogItem 307
DialogClose 220 DisableDialogItem2 307
DialogFixedSize 340 DisableDTTabbing 314
DialogGetSize 326 DisableTabName 327
DialogHasEmbeddedObject 306 discrete event programming
DialogItem 221 arrays 166
DialogItemRefresh 220 blocked and query messages 176
DialogItemToolTip 220 continuous blocks 178
DialogItemVisible 306 explicit connector messages 180
436

functions 180 DLLDoublePascalFunction 266


how ExtendSim runs DE models 162 DLLDoubleStdcallFunction 266
item data structures 170 DLLLoadLibrary 267
item messaging 174 DLLLongCFunction 267
Make Your Own blocks 166
DLLLongPascalFunction 267
message emulation 179
DLLLongStdCallFunction 267
notify message 178
overview 166 DLLMakeProcInstance 267
pseudocode of the simulation loop 162 DLLMakeProcInstanceLibrary 267
pulling 176 DLLPtoCString 61, 87, 267
pushing 175 DLLs 86, 265, 423
scheduling events 167 example code 87
SysGlobal variables 181 interface 86
system variables 162 DLLUnloadLibrary 267
types of blocks 168 DLLVoidCFunction 267
zero time events 169 DLLVoidPascalFunction 267
discrete rate programming 185 DLLVoidStdcallFunction 267
DISetFocus 307 DLogNormal 230
DISetParent 308 dlopen 88
display only option 19, 36, 50 dlsym 88
DisposeArray 66, 376 Donut Chart 353
DisposePlot 347 double (data type) 33, 227
distributions definition 60
Binomial function 230 Do-While 70, 71
Exponential function 230 DPascal 230
Gamma function 230 DPoisson 230
Gaussian function 230
DragCloneToBlock 98, 218
LogNormal function 230
drawing tools 9
Mean distribution function 230
Pascal function 230 drivers (cross-platform) 423
Poisson function 230 DTColumnTagGet 325
Random function 231 DTColumnTagSet 325
RandomCalculate function 231 DTColumnTagStringGet 325
RandomCheckParam function 232 DTGrowButton 314
RandomGetModelSeedUsed function 232 DTHasDDELink 314
RandomRead function 232 DTHideLinkButton 320
students t 233 DTPaneFixed 314
TStatisticValue function 233 DTResizeToCols 314
DITitleGet 308 DTRowFontSize 314
DITitleSet 308 DTRowHeightSet 314
DIToolTipSet 326 DTS (Dynamix Three Space) format 149
DivC 230 DTS exporters 150
division by integer 69 DTS format 149
DLL functions 265 DTToolTipSet 314
DLLBoolCFunction 266 DuplicateBlock 340
DLLBoolPascalFunction 266 DuringContinue 331
DLLBoolStdcallFunction 266 DuringHBlockUpdate 328
DLLCtoPString 61, 87, 266 dylib extension 89
DLLDoubleCFunction 266
437

dynamic arrays 26, 30, 66, 376 E3DCollisionBlocker 294


functions 376 E3DCollisionShow 292
number per block 414 E3DCopyObject 282
dynamic data exchange (DDE) 250 E3DCreateMarker 280
dynamic data link functions 317 E3DCreateObject 283
dynamic data link messages 223 E3DCreateObjectAtWayPoint 283
dynamic data linking 55 E3DCreatePath 281
Dynamic Link Libraries (DLLs) 86, 265, 423 E3DCreateWayPoint 283
dynamic text 15, 36 E3DCurrentTime 278
add to right click menu 19 E3DDeleteAllObjects 140, 283
display only 19 E3DDeleteObject 283
display only option 19
E3DDialogPicture 287
functions 320
E3DDistance 289
visible in all tabs 18
E3DDistancePath 289
DynamicArrayIndexByName 376
E3DdistanceRatio 279
DynamicDataTable 314
E3DDistanceToObject 289
DynamicDataTable2 315
E3DExec 293
DynamicDataTableVariableColumns 66, 312, 315
E3DExecFile 293
DynamicDataTableVariableColumns2 315
E3DFinish 224
DynamicTextArray 321
E3DForwardAngle 291
DynamicTextIsDirty 321
E3DForwardVector 291
DynamicTextSetDirty 321
E3DGetAngleFromVector 291
Dynamix Three Space format 149
E3DGetBlockLocation 277
E E3DGetCamera 294
E3DGetDestination 283
E (scientific) notation E3DGetMount 286
definition 30 E3DGetMountedObject 286
E3D environment 135 E3DGetName 288
definition 135
E3DGetObjectAnimationNames 287
E3D window 135, 150 E3DGetObjectBlockNumber 277
E3DAddMarkerToPath 280 E3DGetObjectBounds 293
E3DAnimationName 287 E3DGetObjectByName 288
E3DAnimationPlay 147, 287 E3DGetObjectIDs 293
E3DAnimationSetPosition 287 E3DGetObjectInfo 293
E3DAnimationStop 147, 287
E3DGetObjectLabel 288
E3DBlockToBlock 277
E3DGetObjectList 288
E3DBlockToBlockHeight 277
E3DGetObjectNames 140, 288
E3DBlockToBlockObjectLabel 277
E3DGetObjectSkinBase 290
E3DBlockToBlockRotation 277
E3DGetObjectSkinNames 290
E3DBlockToBlockScale 277
E3DGetObjectType 293
E3DBlockToBlockSkin 277
E3DGetObjectVector 291
E3DBlockToBlockSkinByIndex 277
E3DGetPathByName 281
E3DBoundingBoxes 282
E3DGetPosition 279
E3DChangeObject 282
E3DGetRotation 279
E3DChooseEnvironment 282
E3DGetSelectedObject 281
E3DClose 224
E3DGetSpeed 283
E3DCollision 224
438

E3DGetVectorFromAngles 291 E3DPostSetRotation 286


E3DInit 224 E3DPostSetScale 286
E3DLogEvents 294 E3DPostSetSkin 142, 286
E3DMode 278 E3DPostSetSkinByIndex 286
E3DModeSwitch 224 E3DPostSetSpeed 286
E3DMountObject 287 E3DPostSetTargetObject 286
E3DMountStackInsert 144, 280 E3DPostSetTargetPath 286
E3DMountStackLimit 144, 280 E3DPostSetTargetWayPoint 286
E3DMountStackRemove 144, 280 E3DPostSetVisibility 286
E3DNeighborDetection 294 E3DPostStopAllObjects 286
E3DNormalizeVector 291 E3DPostUnmountObject 286
E3DNotEnabled 279 E3DReachDestination 224
E3DObjectClick 224 E3DResumeAllObjects 278
E3DObjectClicked 281 E3DResumeSpeed 283
E3DObjectExists 294 E3DScreenShot 289
E3DObjectIDToUserTag 292 E3DSetBlockLocation 278
E3DObjectLabelColorSet 289 E3DSetDestination 284
E3DObjectMoved 224 E3DSetDetail 282
E3DObjectPropertySet 293 E3DSetMode 278
E3DObjectSnapshot 288 E3DSetName 289
E3DOpenWindow 279 E3DSetObjectBlockNumber 278
E3DPanoramicScreenShot 289 E3DSetObjectLabel 138, 286, 289
E3DPathMarkerLocation 281 E3DSetPosition 279
E3DPathSetColor 281 E3DSetRotation 279
E3DPauseAllObjects 278 E3DSetScale 279
E3DPlaySound 294 E3DSetSelectedObject 281
E3DplaySound 145 E3DSetSkin 142, 290
E3DPostAnimationPlay 285 E3DSetSkinByIndex 290
E3DPostAnimationSetPosition 285 E3DSetSpeed 284
E3DPostAnimationStop 285 E3DSetTargetObject 284
E3DPostChangeObject 285 E3DSetTargetPath 284
E3DPostCopyObject 285 E3DSetTargetWayPoint 285
E3DPostCreateObject 139, 285 E3DSetTerrain 282
E3DPostCreateObjectAtWayPoint 285 E3DSetTimeRatio 278
E3DPostDeleteAllObjects 285 E3DSetVisibility 293
E3DPostDeleteObject 285 E3DSky 282
E3DPostMountObject 285 E3Dsleep 278
E3DPostMountStackInsert 285 E3DStart 224
E3DPostMountStackRemove 286 E3DStartTick 292
E3DPostObjectPropertySet 286 E3DStopAllObjects 285
E3DPostResumeSpeed 286 E3DStopTick 292
E3DPostRotateTimed 286 E3DSun 282
E3DPostSetDestination 286 E3DTick 224
E3DPostSetObjectBlockNumber 286 E3DTimeRatio 278
E3DPostSetObjectLabel 286 E3DUnmountObject 287
E3DPostSetPosition 286 E3DUnselectObject 281
439

E3DUpdate 279 equation-based blocks 2, 27, 92


E3DUserTagToObjectID 292 differences from custom block code 31
E3DUses3D 294 user-defined functions 92
E3DWindow 279 EquationCalculate 239
E3DWindowConnected 279 EquationCalculate20 239
EColorFromHSV 401 EquationCalculateDynamic 239
EColorFromOldExtendColor 401 EquationCalculateDynamicVariables 239
EColorFromRGB 401 EquationCompile 240
EColorIsValid 402 EquationCompile20 240
EColorPart 402 EquationCompileDynamic 240
EColorPicker 402 EquationCompileDynamicVariables 240
EColors 401 EquationCompileDynamicVariablesSilent 241
EColorUpdateValue 402 EquationCompilePlatform 218
EDCalcDate 398 EquationCompileSetStaticArray 241
EDCalendarDateGet 398 EquationDebugCalculate( 241
EDCalendarDates 398 EquationDebugCompile 241
EDCalendarShow 398 EquationDebugDispose 241
EDConvertDate 398 EquationDebugSetBreakpoints 241
EDDateToSimTime 398 EquationGetStatic 242
EDDateToString 398 EquationIncludeSet 242
EDDateValue 398 equations 92
EDDayOfTheWeek 399 differ from custom block code 31
EDGetCurrentDate 399 EquationSetStatic 242
EDGetStartDate 399 Erf 228
editable text 36 Euler integration 234
31 character limit 15 evaluating expressions 69
add to right click menu 19 event
dialog item 15 list 168
display only 19, 36 posting 168
visible in all tabs 18 scheduling 166, 167
editable text 31 character 15 event clock 167
EDNow 399 Example block 6
EDSimTimeToDate 399 Excel block 253
EDStringToDate 399 Excel Client-Server Model Workbook.xls 124
EigenValues 235 Excel interface 124
Embed block 253 Execute 118, 120
embedded objects 16, 41, 117, 253 ExecuteMenuCommand 340
empty circle 202, 205 Executive block 162, 329
end of line 78 controlling simulation 165
endif 83 controlling timing 166
EndSim 162, 165, 216 relationship to 3D animation 137
EndTime 158, 160, 162, 211 Exp 228
Enter Selection command 80 Exponential distribution function 230
entry boxes 14 exponential number 30
Equation block 92, 238, 422 Export 243
equation functions 238 ExportText 243
Equation(I) block 92 expressions
440

evaluating 69 FileRewind 246


ExtendBase 140 files
ExtendIPlayers 140 transferring 421
ExtendItems 140 FileWrite 246
ExtendMaximize 340 Fill Color for dialog items 17
ExtendMinimize 340 FinalCalc 161, 165, 215
ExtendSim financial functions 233
databases 111 Find command 80
upper limits 414 Find in Files tab (Find String dialog) 80
ExtendSim IDE 2 Find String dialog 80
ExtendSim OLE.exe 124 FindBlock 340
ExtendSim_10 83 FindInHierarchy 296
ExtendVehicles 140 FindInHierarchy2 296
extensions 85 FindMinimum 376
converting 423 FindMinimumWithThreshhold 376
DLLs 86 FindNext 341
folder 85
FixDecimal 228
pictures 89
fixed arrays 26, 30, 66
Shared Libraries 88
sounds 89 Floor 228
external source code 42, 83 flow attributes 173
source folder 84 flow order 211
External Source Code command 84 FlowAttList array 174
FlowAttType array 174
F FlowAttValues array 174
FlowBlockReceiveN 223
FALSE 63 For construct 70, 71
fast Fourier transform 228
format of numbers 17
FFT 228
formats
file conversion 421, 422 data sources 92
file format DIF 156
pictures 423 DTS 149
file I/O functions 242, 244 number formats 17
file names 420 of 3D files 149
file types for extensions 85 FormatString 394
FileChoose 244 FormatStringReal 394
FileClose 244 form-based interface 124
FileDelete 244 Fortran 29
FileEndOfFile 244 forward declaration 73
FileExists 244 frame 15, 40, 49
FileGetDelimiter 245 free() 378
FileGetPathName 245 FreeMemory 403
FileInfo 245 friction 145
FileIsOpen 245 functions 225
FileNameFromPathName 245 2D 270
FileNew 245 3D animation 276, 287
FileOpen 246 3D block 277
FileRead 246 3D creation, deletion 282
441

3D distance 289 delay line 393


3D environment 282 diagnostic 268
3D miscellaneous 294 dialog 326
3D mounting 286 dialog items 305
3D mountStack 280 dialog tabs 327
3D movement 283 distributions 230
3D name 288 DLLs 265
3D object 281 dynamic arrays 376
3D path 280 dynamic data linking 317
3D post 285 dynamic text 320
3D properties 292 equation 238
3D rotation, position, scale 279 file I/O, formatted 242
3D screenshot 289 file I/O, unformatted 244
3D script 293 financial 233
3D skin 290 global 110
3D tick 292 help 403
3D time 278 icon view 330
3D user tag 291 integration 234
3D vector 291 internet access 247
3D window 279 Interprocess communication (IPC) 250
alerts, prompts 268 labels 295
animation 2D 270 linked list 385
animation 3D 276 Mailslots 260
AppleEvents 250 math 227
arrays as arguments to 67 matrix 234
attributes 396 messaging blocks 328
bit-handling 238 models 331
block categories 295 names 60, 295
block numbers 295 netlist 299
calendar date 397 notebook 331
charts 345 ODBC 261
column tag 321 OLE 253
connections 299 overriding 34
data tables 312 parameter tags 321
database 354 passing arrays 377
database copying 358 plotting 345
database creating/deleting 355 pointers 378
database DB address 372 queue 392
database import/export 358 recursive 73
database linking/notify 374 returns 227
database properties 359 scripting 337
database random data 368 serial I/O 264
database read/write 363 Shared Libraries 265
database selecting 357 statistical 230
database sort/search 371 string 394
database viewing 374 text files 242, 244
date (egacy) 399 time (legacy) 399
DDE 250 time units 397
debugging 402 timer 400
definition 30, 33 trigonometric 229
442

types 226 GALastUsedIndex 383


user-defined 72, 102 Gamma distribution function 230
web 403 GammaFunction 228
Functions popup in Script tab 12 GAMultisim 383
Functions popup menu 205 GANonSaving 383
future value 233 GAParameter 383
GAPopupMenu 383
G GAPtr 383
GABlockRegister 111 GAResize 383
GABlockRegisterContent 379 GAResizeByIndex 384
GABlockRegisterContents 111 GASearch 384
GABlockRegisterStructure 111, 380 GASearchCount 384
GABlockUnregisterContent 380 GASetArray 384
GABlockUnregisterStructure 380 GASetInitValue 384
GAClipboard 380 GASetInteger 384
GACopyArray 380 GASetReal 384
GACreate 380 GASetString 385
GACreateQuick 380 GASetstring15 385
GACreateRandom 380 GASetstring31 385
GADataTable 380 GASetString63 385
GADeleteRow 381 GASort 385
GADispose 381 GAtoDBTable 385
GADisposeByIndex 381 Gaussian 230
GAExport 381 Gaussian distribution function 230
GAFindStringAny 381 GetAppPath 341
GAGetArray 381 GetAttributeValue 396
GAGetColumnsByIndex 381 GetAxis 347
GAGetColums 381 GetAxisName 348
GAGetIndex 381 GetBlockDates 399
GAGetInfo 381 GetBlockInfo 331
GAGetInitValue 381 GetBlockLabel 296
GAGetInteger 382, 384 GetBlockMemSize 296
GAGetLong 382 GetBlockType 296
GAGetName 382 GetBlockTypeNumeric 296
GAGetReal 382 GetBlockTypePosition 217, 297, 341
GAGetRows 382 GetConBlocks 133, 299
GAGetRowsByIndex 382 GetConHBlocks 299
GAGetString 382 GetConName 299
GAGetString15 382 GetConnectedTextBlock 300
GAGetString31 382 GetConnectedType 300
GAGetString63 382 GetConnectedType2 300
GAGetType 382 GetConnectionColor 300
GAGetTypeByIndex 382 GetConnectionEColor 300
GAImport 383 GetConnectorMsgsFirst 328
GAInitializing 383 GetConnectorPosition 300
GAInsertRow 383 GetConnectorType 300
443

GetConNumber 133, 301 GetNumCons 301


GetCurrentPlatform 404 GetObjectHandle 118, 123
GetCurrentTabName 327 GetPassedArray 102, 104, 378
GetDataTableSelection 315 GetPlotterValue 348
GetDialogColors 308 GetPreference 341
GetDialogItemColor 308 GetRear 393
GetDialogItemEColor 308 GetRecentFilePath 341
GetDialogItemInfo 308 GetReportType 345
GetDialogItemLabel 308 GetRightClickedCon 301
GetDialogNames 309 GetRunParameter 332
GetDialogVariable 96, 309 GetRunParameterLong 332
GetDimension 66, 377 GetSerialNumber 332
GetDimensionByName 66, 377 Get-Set Dialog Variable model 96
GetDimensionColumns 66, 377 GetSignalName 348
GetDimensionColumnsByName 66, 377 GetSignalValue 348
GetDraggedCloneList 98, 309 GetSimulateMsgs 329
GetDTOffset 315 GetSimulationPhase 333
GetEnclosingHBlockCon 301 GetStaticNames 297
GetEnclosingHBlockNum 297 getStaticVariable 309
GetEnclosingHBlockNum2 297 GetSystemColor 309
GetExtendType 405 GetTickCount 348
GetExtendVersion 405 GetTimeUnits 397
GetExtendVersionString 405 GetUserPath 341
GetFileReadMachineType 246 GetVariableNumeric 310
GetFileReadVersion 217, 316, 405 GetWindowsHndl 333
GetFileReadVersionString 405 GetWorksheetFrame 341
GetFront 393 GetY1Y2Axis 348
GetGlobalSimulationOrder 331 global arrays 67
GetIndexedConValue 301 AttribType 173
GetIndexedConValue2 301 AttributeList 173
GetIntermediateBlocks 301 AttribValues 173
GetItem 180 functions 378
working with 107
GetLibraryContents 331
GetLibraryInfo 331 global numbers 295
global variables 76
GetLibraryPathName 331
definition 30
GetLibraryStringInfo 331
for passing messages 110
GetLibraryVersion 332 lists 211
GetLibraryVersionByName 332 reserved 212
GetModelName 332 scope 62
GetModelPath 332 SysGlobals 181
GetModifierKey 269 use during CheckData or InitSim 184
GetMouseX 217, 269, 341 use during Simulate 181
GetMouseXActiveWindow 269 GlobalProofStr 211
GetMouseY 217, 269, 341 GlobalToLocal 297
GetMouseYActiveWindow 269 Go To Function/Message Handler command 81
GetMsgSendingBlock 328 Go To Line button 79, 81
444

Go To Line command 81 exploring 9


goal seeking 116 Icon toolbar 20, 46
GOTO statement 70, 72 description 20
green location arrow 194, 200, 205 icon view
groups functions 330
for radio buttons 15 Icon views popup 9, 10
GroupTags 139 IconBody 297
IconGetClass 330
H IconGetView 330
IconGetViewName 330
HasFront 153
IconSetViewByIndex 330
HBlockClicked 269
IconSetViewByPartialName 331
HBlockClose 218
IconViewChange 219
HBlockFromLibrary 218
IDE 2
HBlockHelpButton 219
identifier
HBlockMove 219
definition 30
HBlockOpen 219
Identity 235
HBlockSaveToLibrary 219
IdentityC 235
HBlockUnlinkFromLibrary 341
IdleSound 153
HBlockUpdate 219
IdleSoundAnimation 153
header files 81
IdleSoundVol 153
heapCheck 403
idleSoundVol 147
help 404
IEEE floating point numbers 60
functions 403
IF statement 70, 71
getting technical support 4
ifdef 82
Help tab 14
If-Else statement 70, 71
HelpButton 219
ifndef 83
HideDialogItem 310
Ignore comparison and always break 207
HideDialogItem2 310
Ignore conditions and always break 208
hiding dialog items 95
Imagine That, Inc. 4
hierarchical blocks
animation 129 immediate functions 137
library (converting) 422 Import 243
HSV 128, 401 Import function 108
ImportText 244
I Include additional block information option 14
include files
icon definition 12
alternate views 9 MouseClick 98
animating in 2D 53 New Include File command 82
block part 8 referencing 81
creating 9 Save Include File command 82
functions for view 330
IncludeFileEditor 242
red border around block 193
Includes popup menu 205
showing a picture on 132
tools 20 indentation guides 79
views 9 index of items 170
icon positioner 337 indexing
Icon tab 7 table by data source type 92
445

indexing (data source) 92 IntegrateInit 234


indicators 205 IntegrateTrap 234
INetCloseHandle 247 integration functions 234
INetConnect 247 interface 124
INetFileImportText 247 internet access functions 247
INetFindNextFile 247 Interprocess communication (IPC)
INetFTPCreateDirectory 248 cross-platform development 423
INetFTPDeleteFile 248 functions 250
INetFTPExport 248 IPCAdvise 250
INetFTPExportGA 248 IPCCheckConversation 250
INetFTPExportText 248 IPCConnect 250, 424
INetFTPFindFirstFile 248 IPCDisconnect 251
INetFTPGetCurrentDirectory 248 IPCExecute 251, 424
INetFTPGetFile 248 IPCGetDocName 251
INetFTPImport 249 IPCLaunch 251
INetFTPImportGA 249 IPCOpenFile 251
INetFTPImportText 249 IPCPoke 251, 424
INetFTPPutFile 249 IPCPokeArray 251
INetFTPRemoveDirectory 249 IPCRequest 252, 424
INetFTPRenameFile 249 IPCRequestArray 252
INetFTPSetCurrentDirectory 249 IPCSendCalcReceive 252
INetGetFindFileInfo 249 IPCServerAsync 252
INetGetFindFileName 249 IPCSetTimeOut 252
INetOpenSession 249 IPCSpreadSheetName 252
INetOpenURL 250 IPCStopAdvise 252
initializing connectors 100 IsBlockSelected 341
InitSim 160, 215 IsConVisible 301
Inner 235 IsFirstReport 345
InnerC 235 isKeyDown 269
InstallArray 348 IsLibEnabled 342
InstallAxis 349 IsMenuItemOn 342
InstallFunction 349 IsMetric 342
Int 228 IsSimulationPaused 333
integer item
division of an 69 array 170
function return 227 priority 170
maximum value 60 quantity 170
to real 64 item attributes 172
to string 65 item index 170
integer (data type) 33 Item library
definition 60 programming 166
integer array for SysGlobal 171 itemArray arrays 170
Integerabs 228 itemArray3D
IntegerParameter 268 passed by SysGlobal12 172
IntegerParameter2 268 itemArrayC
integrated development environment (IDE) 2 passed by SysGlobal9 170
IntegrateEuler 234 itemArrayI
446

passed by SysGlobal4 171 ListAddString63s 386


itemArrayI2 171 ListCopyElement 386
itemArrayR ListCreate 387
passed by SysGlobal3 170 ListCreateElement 387
items ListDeleteElement 387
flow is blocked 177 ListDispose 387
pulling 176 ListDisposeAll 387
pushing 175
ListElementMinMax 387
ListGetCount 388
J ListGetDouble 388
Java 29 ListGetElements 388
ListGetIndex 388
K ListGetInfo 388
keyboard shortcuts 420 ListGetLong 388
for developers 421 ListGetName 388
ListGetString 389
L ListLastElementIndex 389
ListLocked 389
label 15
ListSearch 389
label functions 295
ListSearchCount 389
labels for dialog items 17
ListSearchCountLongs 389
labels on connectors 22
ListSearchLongs 390
LastBlockPlaced 342
ListSetDouble 390
Lastkeypressed 270
ListSetLong 390
LastSetDialogVariableString 310
ListSetName 390
LBR extension 420
ListSetSort 390
left to right order 211
ListSetSort2 390
libraries
ListSetString 390
converting 423
file name size 420 literal
number of blocks per 414 definition 31
protecting 89 LIX extension 420
size 414 local numbers 295
source folder 84 local variables 34, 62, 76
LibraryGetInfoByName 342 definition 31
limits of ExtendSim 414 LocalNumBlocks 298
line numbers 79 LocalToGlobal 298
Link Alerts 112 LocalToGlobal2 298
Link Contents 112 location arrow 194, 195
Link Structure 112 Log 228
LinkContent 223 Log10 228
linked list functions 385 Log2 228
linked lists logical operators 69
sorting 67 LogNormal distribution function 230
LinkStructure 223 long 227
list of tables 355, 363, 364 long (data type) 33
ListAddElement 386 definition 60
447

LUdecomp 236 MatScalarProdC 237


LUdecompC 236 MatSub 237
MatSubC 237
M MatVectorProd 237
Machine object DataBlock 145 MatVectorProdC 237
Macintosh Max2 228
file conversion 422 Mean 230
keyboard shortcuts 420 memory usage when programming 101
Macintosh to Windows 421 menu command shortcuts 420
magnitude operators 69 for developers 421
Mailslot functions 260 message emulation 179
MailSlotClose 261 message handlers
MailSlotCreate 261 3D 223
block status 217
MailSlotRead 261
block to block 222
MailSlotReceive 219, 260
categories 109
MailSlotSend 261 categories and types 214
Make Your Own block 181, 185 connector messages 221
Make Your Own blocks 166 constants 329
MakeArray 66, 109, 377 CreateBlock 50
MakeArray2 66, 377 definition 31, 33
MakeBlockInvisible 342 dialog messages 36, 219
MakeConnection 342 dynamic data link 223
MakeDialogModal 327 example 33, 75
MakeFeedbackBlock 301 format 75
model status 216
MakeOptimizerBlock 298
OLE 223
MakeScatter 354
overriding 34, 75
MakeSelectionHierarchical 219 purpose during DE initialization loop 163
malloc() 378 purpose during initialization loop 160
Mandelbrot model 134 Simulation Messages 214
markers 148 types 109
MatAdd 236 use during DE initialization loop 163
MatAddC 236 use during initialization loop 160
matching message name 36
#ifdef, #endif, and #else 78 messages 110
braces 78 3D 223
strings 78 AbortDialogMessage 220
MatCopy 236 ActivateModel 216
MatCopyC 236 AdviseReceive 223
math functions 227 AnimationStatus 216
math operators 68 AttribInfo 222
block status 217
MatInvert 236
block to block 222
MatInvertC 236
BlockClick 217
MatMatProd 236 BlockIdentify 217
MatMatProdC 236 BlockLabel 217
matrix functions 234 BlockMove 217
MatScalarProd 237 BlockRead 217
448

BlockReceive 222 E3DStart 224


BlockReport 216 E3DTick 224
BlockRightClick 217 EndSim 216
BlockSelect 218 EquationCompilePlatform 218
BlockTableInfo 222 FinalCalc 215
BlockUndelete 218 FlowBlockReceiveN 223
BlockUnselect 218 functions for communicating 328
Button 221 GetDraggedCloneList 98
Cancel 220 HBlockClose 218
CellAccept 220 HBlockFromLibrary 218
CheckData 215 HBlockHelpButton 219
ClearStatistics 222 HBlockMove 219
CloneInit 218 HBlockOpen 219
CloseModel 216 HBlockSaveToLibrary 219
ConArrayChanged 221 HBlockUpdate 219
ConArrayChangedComplete 221 HelpButton 219
ConArrayCollapseChanged 221 IconViewChange 219
ConnectionBreak 221 InitSim 215
ConnectionClick 221 LinkContent 223
ConnectionMake 218, 222 LinkStructure 223
connector messages 221 list 214
ConnectorName 222 MailSlotReceive 219
ConnectorRightClick 218, 222 MakeSelectionHierarchical 219
ConnectorShowHide 218 model status 216
ConnectorToolTip 222 ModelSave 216
ContinueSim 215 ModifyRunParameter 214
CopyBlock 218 netlist 328
CreateBlock 218 OK 220
DataTableHover 220 OldFileUpdate 216
DataTableResize 220 OLE 223
DataTableScrolled 220 OLEAutomation 223
DEExecutiveArrayResize 222 OpenModel 216
DeleteBlock 218 OpenModel2 216
DeleteBlock2 218 PasteBlock 219
DialogClick 220 PasteBlock2 219
DialogClose 220 PauseSimulation 216
DialogItem 221 PlotterClose 219
DialogItemRefresh 220 PreCheckData 215
DialogItemToolTip 220 ProofAnimation 222
DialogOpen 220 QueueFunction 222
DragCloneToBlock 98, 218 ResumeSim 217
dynamic data link 223 ResumeSimAllBlocks 217
E3DClose 224 sent by application 110
E3DCollision 224 sent during user interaction 110
E3DFinish 224 ShiftSchedule 222
E3DInit 224 SimFinish 216
E3DModeSwitch 224 SimOrderChanged 217
E3DObjectClick 224 SimSetup 217
E3DObjectMoved 224 SimStart 214
E3DReachDestination 224 Simulate 215
449

simulation 214 constant definitions 33, 60


StepSize 215 data types 33, 60
TabSwitch 221 external source code 42, 83
TimerTick 219 functions and message handlers 33
types of 109 language terminology 30
UpdateStatistics 222 layout 32
UserMsg0-9 222 overview of the language structure 27
meter 15, 41 preprocessor directives 76, 82
methods type declarations 33, 60
for automation 118 ModL feature overview 30
Miles block 44 modulo 229
Min2 228 momentum 145
MOD operator 69 mount nodes 143
model MountLook 153
artificial intelligence 116 mountPoint 143
converting for cross platform use 422 MouseClick.h 98
cross-platform 420 MoveBlock 342
debugging a 190 MoveBlockTo 343
discrete event (running) 162 MovieOn 211
functions 331
movies 273
goal-seeking 116
MOX extension 420
how discrete event models work 166
Macintosh file name 420 MsgEmulationOptimize 329
profiling 190 MultC 230
programming 331 multiple simulations 211
self-modifying 116 multiple statements 70
size 414 MyBlockNumber 133, 298
status messages 216 MyLocalBlockNumber 298
text blocks as commands 113
timing for discrete event 166
Windows file name 420
N
ModelLock 333 name
dialog items 17
ModelSave 216
Name field for 3D animation 138
ModelSettingsGet 342
name functions 295
ModelSettingsSet 342
names
ModernRandom 211
constants 60
modes for 3D animation 136
functions 60
ModifyDate 399 reserved 60
ModifyRunParameter 214 variables 60
ModL names of blocks
case sensitivity 60 length of name 414
code conventions 49 NearlyEqual 228
code example 47
NearlyGreaterThan 228
code part of block 7
NearlyLessThan 228
compared to C++ 27
compared to Java, Visual Basic, FORTRAN 29 netlist messages 328
compiled to machine code 12 New Include File command 82
conditional compilation 76, 82 NextTimes 168
connector names as variables 34 No resize bar 21
450

no such parent 355 ODBCConfigDataSource 262


no such record 355 ODBCConnect 263
NodeGetCurrentValue 301 ODBCConnectName 263
NodeGetIDIndex 301 ODBCCountRows 263
normal connectors 22, 35 ODBCCreateTable 263
not linked error 355 ODBCDisconnect 263
not unique error 355 ODBCDriverConnect 263
not unique index 355 ODBCExecuteArray 263
notebook functions 331 ODBCExecuteQuery 263
NotebookClose 333 ODBCFetchRows 263
NotebookIsOpen 334 ODBCFreeStatement 263
NotebookItemInfo 334 ODBCInsertRow 264
NotebookItemInfoString 334 ODBCKeyword 264
NotebookItemRect 334 ODBCNumResultCols 264
NotebookItems 334 ODBCSetRows 264
notebooks ODBCSetRowsType 264
functions 331 ODBCSuccessInfo 264
notify message 178 ODBCTables 264
NoValue 63, 69, 228 OK 220
converted to integer 64 OldFileUpdate 216
Now 399 OLE
number of periods 233 automation client 118
numbers 60 automation server 118
NumBlocks 298 BlockMsg 122
numeric conversion 64 C++ examples 119
NumericParameter 268 Execute 120
NumericParameter2 268 GetObjectHandle 123
IDispatch interface 119
NumPlotPoints 349
messages 223
NumScenarios 211
methods 118
NumSims 158, 160, 162, 163, 211 Poke 121
NumSteps 158, 161, 211 Request 120
NumToFormat 395 VB.net DLL example 117
Visual Basic 124
O Visual Basic examples 124
object OLE functions 253
for Automation 118 OLEActivate 254
object label for 3D animation 138 OLEAddRef 254
objectID 139 OLEArrayParam 254
ObjectIDNext 298 OLEArrayParamVariableColumns 254
objects OLEArrayResult 254
animation 126 OLEArrayResultVariableColumns 254
ODBC functions 261 OLEAutomation 223
ODBCBindColumn 262 OLECreateObject 254
ODBCColAttribute 262 OLEDBParam 254
ODBCColumns 262 OLEDBResult 254
ODBCColumns2 262 OLEDeactivate 254
451

OLEDispatchGetCLSID 255 OLEStringResult 260


OLEDispatchGetDispatchName 255 OLESupressInvokeErrors 260
OLEDispatchGetDispID 255 OLEVariantParam 260
OLEDispatchGetDoc 255 OLEVariantResult 260
OLEDispatchGetFuncIndex 255 Open a library command 420
OLEDispatchGetFuncInfo 255 Open a model command 420
OLEDispatchGetHelpContext 255 Open Block Structure command 7
OLEDispatchGetNames 255 Open structure command 420
OLEDispatchInvoke 256 OpenAndSelectDialogItem 310
OLEDispatchParam 256 OpenAndSelectDialogItem2 310
OLEDispatchPropertyGet 256 OpenBlockDialogBox 327
OLEDispatchPropertyPut 256 OpenDialogBox 327
OLEDispatchresult 256 OpenDialogBoxToTabName 327
OLEGAParam 256 OpenEnclosingHBlock 327
OLEGAResult 256 OpenEnclosingHBlock2 327
OLEGetCLSID 256 OpenExtendFile 343
OLEGetDispatchName 256 OpenModel 216
OLEGetDispID 257 OpenModel2 216
OLEGetDoc 257 OpenNotebook 334
OLEGetFuncIndex 257 OpenNotebook2 334
OLEGetFuncInfo 257 OpenURL 404
OLEGetGUID 257 operations
OLEGetHelpContext 253 between any type and a string 65
OLEGetInterface 258 between reals and integers 64
OLEGetNames 258 operators 68
OLEGetRefCount 258 Optimizer block 92
OleGlobal 211 Option key 269
OleGlobalInt 211 Outer 237
OleGlobalStr 211 OuterC 237
OLEInsertLicensedObject 258 overridin
OLEInsertObject 258 message handlers 34
OLEInsertObjectFromFile 258 overriding
OLEInvoke 258 functions 34
message handlers 75
OLELongParam 259
user-defined functions 74
OLELongResult 259
OLEObjectIsRegistered 259
OLEPropertyGet 259 P
OLEPropertyPut 259 panes
OLERealParam 259 connectors 8
OLERealResult 259 parameter
OLERelease 259 add to right click menu 19
adding to a dialog 49
OLEReleaseInterface 259
changing globally from a block 96
OLERemoveObject 259
changing through text on the model 113
OLERequestLicKey 259 dialog item 14, 36
OLESetNamedParam 260 display only 19, 36
OLEStringParam 260 format 17
452

formats for numbers 17 Platform_Macintosh_Defined_Symbol 83


tags 321 Platform_Windows_Defined_Symbol 83
visible in all tabs 18 PLATFORMMACINTOSH 424
parameter fields 14 PLATFORMWINDOWS 424
parameter tag functionss 321 PlaySound 268
Pascal distribution function 230 PlotNewBarPoint 349
Pascal to C string function 61 PlotNewPoint 349
pass by value or reference 102 PlotNewScatter 354
PassArray 102, 378 PlotSignalFormat 349
passing array functions 377 plotter functions 345
passing arrays 103, 377 PlotterAutoscaleLimits 350
connectors 103 PlotterBackground 350
precautions 104
PlotterClose 219
using globals 104
PlotterNameGet 350
Passing Arrays model 102
PlotterNameSet 350
passing blocks 168
PlotterPropertyChange 219
passing messages 110
PlotterSignalColorSet 350
PassItem 180
PlotterSignalEColorSet 350
PasteBlock 219
PlotterSignalValueGet 350
PasteBlock2 219
PlotterSignalValueSet 350
PasteBlock3 219
PlotterSquare 351
paths
PlotterValueGet 351
creating in 3D 148
PlotterValueSet 351
paths for 3D animation 148
PlotterXAxisCalendar 351
PauseSim() 403
PlotterXAxisTime 351
PauseSimForSave 335
pointer functions 378
PauseSimulation 216
PointerDispose 378
payment 233
PointerFromDynamicArray 378
PI 63
pointers 102
Pick Screen Color button 401
PointerToDynamicArray 378
PictureList 276
pointertype (data type) 33, 265
pictures 89, 132, 274, 423
definition 60
bitmap 423
naming conventions 89 Poisson distribution function 230
Windows MetaFiles 423 Poke 118, 121
PieChart 353 popup menus
PieChartSlice 353 creating 48
dialog item 14, 39
pixels
in block dialogs 48
animating 134
coordinates 273 PopupCanceled 310
measurement 270 PopupItemParse 310
PlaceBlock 343 PopupMenuAppendArray 311
PlaceBlockInHBlock 343 PopupMenuArray 311
PlaceDotBlock 343 position of 3D object 141
PlaceTextBlock 343 Post functions 137
PlaceTextBlockInHBlock 343 posting events 168
Planet Dance model 127 PostInitSim 160
Pow 229
453

PreCheckData 160, 215 pseudocode 158, 162


PrecisionTimer 400 pulling items 176
PrecisionTimerScale 400 pushing items 175
pre-defined constants 63 PushPlotPic 351
preprocessor directives 29, 76, 82 PutFront 393
preprocessor symbols 83 PutRear 393
present value 233
procedures 72 Q
Profile Block Code command 190 QueGetN 393
ProfileBlockGet 403 QueInit 393
profiling 190 QueLength 393
programming QueLookN 393
2D animation 126
Query Equation block 92
arrays 101
Query Equation(I) block 92
changing parameters globally 96
code search and replace 80 query message 176
debugging 191 QueSetAlloc 393
dialogs 93 QueSetN 393
discrete event blocks 166 Queue Equation block 92
discrete rate blocks 185 queue functions 392
DLLs 86, 265 QueueFunction 222
extensions 85 QuickTime 273
include files 81 QuickTimeAvailable 344
profiling 190 QuickView mode 136
scripting 116
Shared Libraries 265
sounds 89 R
techniques 78 radians 229
text as commands 113 radio button
Trace 190 defining in a dialog 48
viewing debugging data 191 dialog item 15
viewing intermediate results 191 groups 15
programming languages programming for 37
C++ 27 radio group ID 37
C++ example for Automation 119 radio control 37
Fortran 29 Radio Group ID 37
Java 29 Random 231
used for OLE and ActiveX 117 Random distribution function 231
VBA for Automation 124
random number generator 211
Visual Basic 29
RandomCalculate 231
Visual Basic for Automation 124
RandomCheckParam 232
prompts 268, 337
RandomGetModelSeedUsed 232
Proof Animation
numerical format 395 RandomGetSeed 232
ProofAnimation 222 RandomReal 232
ProofEncode 276 RandomSeed 211
ProofEncodeReset 276 RandomSetSeed 232
Properties dialog for animation objects 127 RandomString 395
protecting libraries 89 rate 233
454

Rate library returns


programming 185 function 227
Read/Write Index Checking 354 RGB 401
real Roots 237
function return 227 rotation of 3D animation objects 141
to integer 64 Round 229
to string 65 row index 92
real (data type) 33 rows and columns
definition 60 setting for text tables and data tables 18
Real (uniform) function 232 Run a simulation command 420
real array 170 Run menu keyboard equivalents 421
Realabs 229 runs
Realmod 229 multiple 210, 211
RealToStr 395 RunSetup 335
RealToStrShortest 395 RunSimulation 335
recursive functions 73
red border 193
red circle 199, 205
S
Save a model command 420
red name of a block 45
Save Block command 49
RefreshDatatableCells 315
Save Include File As command 82
RefreshPlotter 351
SaveModel 335
RegisterBlockInLeftClickDB 99
SaveModelAs 335
registered blocks 111
SaveTopDocAs 335
registering blocks 55, 317
scale for 3D animation objects 141, 153
regular expression (searching) 80
scatter plots 354
RemoveAttribute 396
scientific notation
RemoveSignal 351
definition 30
RenamePlotter 352
scope 62
reporting script editor
programming 190
miscellaneous features 81
Request 118, 120 syntax styling 78
reserved database 112 script file 149
_character 112
Script tab 7, 12
blocks that use 112
syntax highlighting 78
residence blocks 168 syntax styling 78
ResizeDTDuringRead 217, 316 scripting 116
resizing a tab 13 scripting environment 150
Resource Order ID 172 scripting functions 337
ResourcePoolAllocate 337 ScrollDTTo 316
ResourcePoolAvailable 337 searching and replacing 80
RestrictConnectorMsgs 329 searching text 80
ResumeSim 115, 217 SeedListClear 232
ResumeSimAllBlocks 115, 217 SeedListRegister 232
ResumeSimulation 335 Select Color window 401
RetimeAxis 352 SelectBlock 403
RetimeAxisNStep 352 SelectBlock2 403
Return statement 70, 72 SelectConnection 344
455

self-modifying 116 SetSelectedConnectionColor 302


SendConnectorMsgToBlock 329 SetSelectedConnectionEColor 302
SendItem 180 SetSignalName 352
SendMsg 174, 180 SetTickCounts 352
SendMsgToAllCons 329 SetTimeConstants 397
SendMsgToBlock 329 SetTimeUnits 397
SendMsgToHBlock 330 SetVariableNumeric 312
SendMsgToInputs 174, 175, 178, 185, 330 SetVisibilityMonitoring 312
SendMsgToOutputs 174, 175, 185, 330 ShapeFile 153
sensitivity analysis Shared Libraries 88, 265
CurrentSense variable 210 Shift key 269
sensor connector 178 Shift Selected Code Left command 81
serial I/O functions 264 Shift Selected Code Right command 81
serial ports 264 Shift-click 97
SerialRead 265 _leftClickDB 100
SerialReset 265 code for a custom stand-alone block 98
SerialWrite 265 code in blocks used remotely 98
server application 423 ShiftSchedule 222
Set Block Category command 56 shortcuts 420
Set Breakpoints window 205 Show 2D Animation button 126
SetAttribute 396 Show 2D Animation command 126
SetAxisName 352 Show Animation command 270
SetBlockLabel 299 AnimationOn variable 210
SetBlockSimulationOrder 335 Show Reserved Databases command 112
SetConnectionColor 302 ShowBlockLabel 299
SetConnectionEColor 302 ShowFunctionHelp 242
SetConnectionThickness 302 ShowHelp 404
SetConVisibility 302 showing dialog items 95
SetDataTableCornerLabel 316 ShowPlot 352
SetDataTableLabels 316 ShowPlot2 352
SetDataTableSelection 316 SimDelay 211
SetDefaultTabName 327 SimFinish 216
SetDialogColors 311 SimMode 211
SetDialogItemColor 311 SimOrderChanged 217
SetDialogItemEColor 311 SimSetup 217
SetDialogVariable 96, 311 SimStart 214
SetDialogVariableNoMsg 311 Simulate 161, 215
SetDirty 344 SimulateConnectorMsgs 330
SetDTColumnWidth 316 simulation
SetDTRowStart 316 stop command 420
SetIndexedConValue 302 simulation messages 214
SetIndexedConValue2 302 simulation order 211
SetModelSimulationOrder 336 simulation pseudocode 162
SetPopupLabels 311 Simulation Setup command 158
SetRunParameter 336 simulations
automating 116
SetRunParameters 336
changing data while running 115
456

internals 158 source code editor 78


messages 214 source connectors 101
methods 158 source folder 84
multiple 210, 211 Source pane 194
number of runs (maximum) 414
Speak 268
order when running 211
Speech Manager 268
paused 160
pseudocode 158, 162 SpinCursor 336
running 158 SpinCursorStart 336
running with Equation/Equation(I) block 422 SpinCursorStop() 336
stopping multiple 162, 166 Sqrt 229
time 166, 210 StackMountPoint 154
Sin 229 StartTime 158, 160, 162, 211
Sinh 229 StartTimer 400
sink connectors 101 StartTimerID 400
sizes 101 statements
SkinBaseName1 143, 153 control 70
SkinBaseName2 143, 153 definition 31
SkinName1 143, 154 multiple 70
SkinName2 143, 154 static data limits 62
skins of 3D objects 141 static text 15, 39
SLClear 391 static variables 32, 34, 62, 76
SLCreate 391 definition 31
limits on data size 62
SLDelete 391
scope 62
SLFlagGet 391
uninitialized 62
SLFlagRealGet 391
statistics functions 230
SLFlagRealSet 391
Status block 328
SLFlagSet 391
StdDevPop 232
SLGetCount 391
StdDevSample 233
SLGetCountStrings 392
Step Into tool 204
slider 15, 41
step loop 161
SLIs 392
Step Out tool 204
SLPopupMenu 392
Step Over tool 204
SLSort 392
steps
SLStringAppend 392 number of 210
SLStringGet 392 number of (maximum) 414
SLStringGetIndex 392 StepSize 158, 160, 215
SLStringInsert 392 Stop a simulation command 420
SLStringRemove 392 Stop and Go To tool 204
smart highlighting 78 Stop Debugging and Edit Code 202
smart mounted 144 Stop tool 204
SortArray 377 StopDataTableEditing 317
SortArrayVariableColumns 317 Stoptimer 400
sorting StopTimerID 400
linked lists 67 Str127 33, 60
sounds 89, 268, 423 Str15 33, 60
source code debugger (see "debugger") 192 Str255 33, 60
457

Str31 33, 60 Platform_Macintosh_Defined_Symbol 83


Str63 33, 60 Platform_Windows_Defined_Symbol 83
StrFind 395 pre-defined preprocessor 83
StrFindDynamic 321 syntax colorization 78
StrFindDynamicStartPoint 321 syntax styling 78
StrGetAscii 395 SysDBNGlobalInt0-19 187
string 227 SysFlowGlobal0 186
concatenation 68, 69, 269 SysFlowGlobal1 186
declaring 61 SysFlowGlobalInt0-21 186
function return 227 SysFlowGlobalStr0 186
functions 394 SysGlobal 76
literals 61 SysGlobal variables 181, 212
to integer 65 during CheckData or InitSim 184
to real 65 during Simulate message 181
String data type 33 SysGlobal0 166, 167
definition 60 SysGlobal0-22 181
string functions 394 SysGlobal1 190
StringCase 395 SysGlobal12 170
StringCompare 395 passing itemArray3D 172
StringTrim 395 SysGlobal13 166, 167
StripLFs 247 SysGlobal2 190
StripPathIfLocal 247 SysGlobal23 187
StrLen 396 SysGlobal24 187
StrPart 396 SysGlobal25 187
StrPartDynamic 396 SysGlobal26 187
StrPutAscii 396 SysGlobal27 187
StrReplace 396 SysGlobal28 187
StrReplaceDynamic 321 SysGlobal3 170
StrToReal 39, 396 passing itemArrayR 170
structure SysGlobal4 170
open command 7, 420 passing itemArrayI 171
structure of a block 7 SysGlobal6 170
structures 67, 101 SysGlobal7 166, 167
using passed arrays 105 SysGlobal9 170
structures (pointers) 378 passing itemArrayC 170
style of text for dialog items 19 SysGlobalInt0 167, 174, 175, 177, 185
SubC 230 SysGlobalInt0-40 182
submenus for blocks 55 SysGlobalInt1 185
subscripts of an array 65 SysGlobalInt11 185
SuppressWorksheetRedraw 344 SysGlobalInt3 174, 175, 177
Switch 72 SysGlobalInt41 185
switch 15, 41 SysGlobalInt42 184
Switch statement 70 SysGlobalInt43 184
SwitchPlotterRedraw 352 SysGlobalInt44-52 187
symbols 82 SysGlobalInt53 187
Compiled_Debug 83 SysGlobalInt54-56 187
ExtendSim_10 83 SysGlobalInt57 187
458

SysGlobalInt58 187 time units


SysGlobalInt59 187 functions 397
SysGlobalInt6 177 TimeArray 166, 168
SysGlobalInt60-79 187 TimeBlocks 166
SysGlobalInt8 169, 185 TimeEventMsgType 166
SysGlobalStr0-2 182 timer functions 400
SysGlobalStr1 185 TimerID 400
SysGlobalStr3 187 TimerTick 219
SysGlobalStr4-9 182 TimeToString
system variables see EDdateToString 398
definition 31 tool tips
list 210 connector 305
dialog item 326
T on block dialogs 20
on dialog tab 20
tab character 243 tools
tab delimited files 243 animation 20
tab number 18 connectors 20
tab resizing 13 in the Debugger window 204
table list 355, 363, 364 tooltips 23
tabs 8, 13 topic and item 118
TabSwitch 221 Torque Game Engine 135
Tan 229 Torque Script 150
Tanh 229 TraceModeEnableDisable 403
technical support transparency 401
information to provide 4 transparent text 134
terminology 30 Transpose 238
text 113 TransposeC 238
changing programmatically 93 Trapezoidal integration 234
tables 15, 38 trigonometry functions 229
text as commands 113 TRUE 63
text files TStatisticValue 233
functions 242, 244
tutorial
include files 81
source code debugger 193
numerical data 243
type conversion 64
programming 243
function arguments 227
string data 243
type declarations 32
text frame 15, 40
definition 31
text tables 15, 38
type of dialog item 17
row and column 18
TextWidth 396
TGE 135 U
TickCount 400 uninitialized static variables 62
time UnmountLook 154
current time 210 UnRegisterBlockInLeftClickDB 99
time functions 399 UnselectAll 344
time functions (legacy) 399 UpdatePublishers 253
time in simulation 210 UpdateStatistics 222
459

upper limits 414


Use 396
W
UseRandomizedSeed 233 W (width) and H (height) coordinates 96
user-defined functions 72 WaitNTicks 128, 400
ADO functions 405 Wall.cs file 149
exiting 73 Watch(A) 208
include files 81 WatchPoint condition 208
overriding 74 waypoint 148
recursive 73 web functions 403
user-defined procedures 72 WhichDialogItem 312
UserError 191, 268 WhichDialogItemClicked 220, 270, 306
UserMsg0-9 222 WhichDTCell 317
UserParameter 268 WhichDTCellClicked 270
UserPrompt 268 While loop 71
userPromptCustomButtons 268 While statement 70
userTag 139 white circle 205
white space 78
V WhoInvoked 312
value connector messages 178 Windows
variable connectors 21, 22, 35, 100 file conversion 422
convert to normal 21 keyboard shortcuts 420
no resize bar 21 MetaFiles 423
variable name 36 Windows to Macintosh 421
VariableNameToTabName 327 WinRegSvr32 260
variables WinSetForegroundWindow 344
data consumption 61 WinShellExecute 344
global 212 wizards 116
list 210 WorksheetRefresh 344
local 31, 62 worksheetSettingGet 344
memory usage 101 worksheetSettingSet 345
names 60
pane 194
scope 62
X
static 31, 62 X and Y coordinates 17, 95
SysGlobal 212
system 210 Y
Variables pane 194 yellow location arrow 195, 196, 205
VB.net 117
VB.net COM DLL example 117
VBA example 124
Z
version control 42, 83 zero time event list 165
Zoom In button 81
Visible checkbox 18, 95
zOrder 17, 54
visible in all tabs 18
zOrderanimation objects
Visible option for dialog items 18
zOrder 127
Visual Basic 29, 124
void 227
void functions (procedures) 30

You might also like