The SnowProcessor is an example class that could be added to a module. It extends the Processor class and modifies its onDraw() method to draw falling Snowflakes (small white triangles) in the surrounding volume. The user can adjust the rate at which the snow falls. The exact position of every Snowflake can be saved as part of the tree.
While this example is more fun than practical, it demonstrates several key module concepts.
Before creating this example, be sure to read Flexsim Module Development; it demonstrates how to create a working module. You will need to have a working module in order to use this example. Once you have a working module, follow these steps:
getClassFactory()
) with the name of your moduleFollow the steps for adding Snowflake.h, but call the file "SnowProcessor.h" and use the SnowProcessor.h source code. Also, you won't need to replace any text in this file.
Follow the steps for adding Snowflake.cpp, but call the file "SnowProcessor.cpp" and use the SnowProcessor.cpp source code.
#include "SnowProcessor.h"
createodtderivative
(not createsdtderivative
) function (before the return
statement):
if (strcmp(classname, "SnowProcessor") == 0)
return new SnowProcessor();
createsdtderivative
function (before the return
statement):
if (strcmp(classname, "Snowflake") == 0)
return new Snowflake();
When a SnowProcessor is first created, it won't have any snowflakes. Press reset, and the flakes should appear at the top of the processor. To see the flakes fall, run the model (you may need to add other objects to the model to get it to run).
The Snowflake class extends the SimpleDataType class. The SimpleDataType class is simplest object that can be used in FlexSim's tree. It is perfect for representing simple objects, or for situations where you require an object, but you don't need all the overhead of a regular FlexSim object. The TrackedVariable object, for example, extends the SimpleDataType class.
Since the Snowflake class stores relatively few member variables, it can be represented with a SimpleDataType.
In order for SimpleDataType objects to be stored in the tree, they must implement the
bind()
method, and they must call the parent bind()
as
part of the implementation.
The Snowflake class binds six doubles. The second parameter in the bindDouble()
function indicates that the class should store the value as a sub node. Usually, if you need
to bind the variable at all, you should make sure that the variable is bound as a subnode.
In general, you should bind member variables with subnodes. However, if the object's state can be saved and loaded without a value, then you don't need to bind it.
Each SimpleDataType or CouplingDataType class you create must be registered in
createsdtderivative
in order to be properly loaded.
The NodeListArray provides a convenient way to manage a list of objects in FlexSim.
The SnowProcessor uses a NodeListArray to store a list of Snowflake objects. The NodeListArray
can be bound as if it is a treenode. It provides std::vector-like methods and 0-based index access
for objects store on subnodes. For more types of NodeListArrays, see datatypes.h, and search for NodeListArray
.
The Mesh class allows you to create a geometric mesh, for graphics purposes. The SnowProcessor uses a single mesh to draw each Snowflake object. Notice that the mesh is not bound. Instead, the SnowProcessor uses a boolean member variable (constructed with a false value) to indicate whether the mesh has been built. In general, you shouldn't build the mesh each time you need to draw. Each SnowProcess object only builds the mesh once, and only if it is needed. While it is possible to bind a mesh, many FlexSim objects use the pattern described here.
You can extend regular library objects. The SnowProcessor, while functionally identical to the regular Processor, demonstrates some of the important points about extending a FlexSim object.
Like the SimpleDataType bind() method, bindVariables() allows you to bind nodes in the tree to your object's variables. Also, you should call the parent class' bindVariables() method. However, you cannot use bindDouble() or bindObjRef or any typed bind function. Instead, variables are bound using bindVariable().
You can also use bindStateVariable(). This second function is identical to the first, except that variables bound this way will be placed in the stats node in the object, rather than in the variables node. The variables node, then, can be used for input or configuration values. Any other state data can be stored in stats.
For more information on bindVariables(), see the FlexsimObject class.