In addition to the inspectors embedded in the main window, Tkenv also lets you open floating inspector windows for objects. The screenshow below shows Tkenv with several inspectors open.
The following screenshots show various inspectors available in Tkenv.
Registered components (NED Types, classes, functions, enums) can be displayed with the Inspect | Available components menu item. If an error message reports missing types or classes, you can check here whether the missing item is in fact available, i.e. registered correctly.
The Find/Inspect Objects dialog lets you search the simulation for objects that meet certain criteria. The criteria may be the object name, class name, the value of a field of the object, or the combination of those. The results are presented in a table which you can sort by columns, and double-click items in it to inspect them.
Some possible use cases:
WATCH()
macro), you can get a list of them.
The dialog lets you specify the search root, and the name and class name of the objects to find. The latter two accept wildcard patterns.
The checkboxes in the dialog can be used to select the object category that interests you. If you select a category, all objects with that type (and any type derived from it) will be included in the search. Alternatively, if you specify object class as a class filter expression, the search dialog will try to match the object's class name with the given string, meaning that objects of derived types will not be included.
You can also provide a generic filter expression, which matches the object's full path by default.
Wildcards ("?"
, "*"
) are allowed. "{a-exz}"
matches any character in the range "a".."e"
plus "x"
and
"z"
. You can match numbers: "*.job{128..191}"
will match objects named "job128"
, "job129"
, ...,
"job191"
. "job{128..}"
and "job{..191}"
are also understood.
You can combine patterns with AND
, OR
and NOT
and parentheses
(lowercase and
, or
, not
are also accepted). You can match other object fields such
as queue length, message kind, etc., with the syntax "fieldname(pattern)"
. If the pattern
contains parentheses or space, you need to enclose in in quotes.
(HINT: You will want to start the pattern with "*."
in most cases to
match objects anywhere in the network!).
Examples:
*.subnet2.*.destAddr
"destAddr"
"subnet2"
*.destAddr
: Matches all objects with the name "destAddr"
(likely module parameters).
*.node[8..10].*
: Matches anything inside module node[8], node[9]
and node[10]
.
className(cQueue) and not length(0)
: Matches non-empty queue objects.
className(cQueue) and length({10..})
: Matches queue objects with length>=10.
kind(3) or kind({7..9})
: Matches messages with message kind equal to 3, 7, 8 or 9 (only messages have
a "kind"
attribute).
className(IP*) and *.data-*
: Matches objects whose class name begins with "IP"
and name begins with
"data-."
not className(cMessage) and byteLength({1500..})
: Matches messages whose class is not cMessage and
byteLength is at least 1500 (only messages have a "byteLength"
attribute).
"*(*" or "*.msg(ACK)"
: Quotation marks needed when pattern is a reserved word or contains
parentheses (note: *.msg(ACK) without parentheses would be interpreted as some object having a "*.msg"
attribute with the value "ACK"!).
cObject::forEachChild
method to collect all objects from a tree recursively. If you
have your own objects derived from cObject
, you should redefine the cObject::forEachChild
to
function correctly with an object search.