Qtenv and C⁠+⁠+

This section describes which C⁠+⁠+ API functions various parts of Qtenv employ to display data and otherwse perform their functions. Most functions are member functions of the cObject class.

Inspectors

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.

The Object Inspector in Children mode 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 Children tree, 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 Qtenv 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 displays 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.

During Simulation

Qtenv 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, Qtenv 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.