This section describes which C++ API functions various parts of Tkenv employ
to display data and otherwse perform their functions. Most functions are member
functions of the cObject
class.
Inspectors display the hierarchical name (i.e. full path) and class name
of the inspected object in the title using the getFullPath()
and getClassName()
cObject
member functions. The Go to parent feature in inspectors uses the
getOwner()
method of cObject
.
The Object Navigator displays the full name and class name of each object
(getFullName()
and getClassName()
), and also the ID for classes that have one
(getId()
on cMessage
and cModule
). When you hover with the mouse, the tooltip
displays the info string (str()
method). The roots of the tree are the network module
(simulation.getSystemModule()
) and the FES (simulation.getFES()
.
Child objects are enumerated with the help of the forEachChild()
method.
In the Object Inspector, the Contents page displays the full name,
class name and info string (getFullName()
, getClassName()
, str()
)
of child objects enumerated using forEachChild()
. forEachChild()
can only
enumerate objects that are subclassed from cObject
. If you want your
non-cObject
variables (e.g. primitive types or STL containers) to appear
in the Contents list, you need to wrap them into cObject
. The WATCH()
macro does exactly that: it creates an object wrapper that displays the
variable's value via the wrapper's str()
method. There are watch macros
for STL contains as well, they present the wrapped object to Tkenv in a more
structured way, via custom class descriptors (cClassDescriptor, see below).
One might ask how the forEachChild()
method of modules can enumerate
messages, queues, and other objects that are owned by the module. The answer is
that the module class maintains a list of owned objects, and cObject
automatically joins that list.
The Object Inspector's Fields page display an object's fields by
making use of the class descriptor (cClassDescriptor
) for that class.
Class descriptors are automatically generated for new classes by the message compiler.
Class descriptors for the OMNeT++ library classes are also generated by the
message compiler, see src/sim/sim_std.msg
in the source tree.
The Network Display uses cSubmoduleIterator
to enumerate submodules,
and its Go to parent module function uses getParentModule()
. Background and
submodule rendering is based on display strings (getDisplayString()
method of
cComponent
).
The module log page of Log Viewer displays the output to EV
streams
from modules and channels.
The message/packet traffic page of Log Viewer shows information based
on stored copies of sent messages (the copy is created using dup()
), and stored
sendhop information. The Name column displays the message name (getFullName()
).
However, the Info column does not display the string returned from str()
,
but rather, strings produced by a cMessagePrinter
object. Message printers
can be dynamically registered.
Tkenv sets up a network by calling simulation.setupNetwork()
, then
immediately proceeds to invoke callInitialize()
on the root module.
During simulation, simulation.takeNextEvent()
and simulation.executeEvent()
are called iteratively. When the simulation ends, Tkenv invokes callFinish()
on the root module; the same happens when you select the Conclude Simulation
menu item. The purpose of callFinish()
is to record summary statistics
at the end of a successful simulation run, so it will be skipped if an error occurs
during simulation. On exit, and before a new network is set up,
simulation.deleteNetwork()
is called.
The Debug Next Event menu item issues the int3
x86 assembly instruction
on Windows, and raises a SIGTRAP
signal on other systems.