diff --git a/.hgignore b/.hgignore
index 6754560cf..8bbd0a32f 100644
--- a/.hgignore
+++ b/.hgignore
@@ -6,5 +6,6 @@ build
.*\.sconsign
doc/html.*
doc/latex.*
+doc/trace-source-list.h
.lock-wscript
.waf*
diff --git a/doc/doxygen.conf b/doc/doxygen.conf
index fc6fd25fa..ac0f72a0e 100644
--- a/doc/doxygen.conf
+++ b/doc/doxygen.conf
@@ -450,7 +450,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = src doc/main.txt
+INPUT = src doc/main.txt doc/trace-source-list.h doc/tracing.h
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@@ -514,7 +514,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH = doc
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/doc/main.txt b/doc/main.txt
index 3fc144687..37e1ed92d 100644
--- a/doc/main.txt
+++ b/doc/main.txt
@@ -23,6 +23,7 @@
* - \ref config
* - a base class for objects which need to support reference counting
* and QueryInterface: ns3::Object and ns3::InterfaceId
+ * - a set of low-level trace facilities integrated in the ns3::Object system: \ref tracing
* - a ns3::ComponentManager which can be used to manage the creation
* of any object which derives from ns3::Object through an ns3::ClassId
* - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
@@ -33,11 +34,10 @@
* ns3::Scheduler and ns3::SchedulerFactory
* - a simulator class used to create, schedule and cancel events: ns3::Simulator
*
- * The "common" module contains:
+ * The "core" module contains:
* - a packet class to create and manipulate simulation packets: ns3::Packet, ns3::Header,
* and ns3::Trailer. This packet class also supports per-packet ns3::Tag which are
* globs of data which can be attached to any packet.
- * - a set of low-level trace facilities: \ref lowleveltracing
*
* The "node" module contains:
* - a ns3::Node base class which should be subclassed by any new type of
diff --git a/doc/namespace-2.dia b/doc/namespace-2.dia
new file mode 100644
index 000000000..5cd5ed59e
--- /dev/null
+++ b/doc/namespace-2.dia
@@ -0,0 +1,1658 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ #A4#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/devices/[0-n]#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #NodeList#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Node#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/queue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/nodes/[0-n]#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/udp#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/rx#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/netdevice#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/ipv4#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/interfaces/[0-n]#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/rx#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/queue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/rx#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/enqueue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/dequeue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/drop#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #InternetNode#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #PointToPointNetDevice#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Queue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Ipv4L3Protocol#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Ipv4Interface#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #CsmaNetDevice#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/enqueue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/dequeue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #/drop#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Queue#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/namespace-2.png b/doc/namespace-2.png
new file mode 100644
index 000000000..7ea379c82
Binary files /dev/null and b/doc/namespace-2.png differ
diff --git a/doc/trace-source-list.h b/doc/trace-source-list.h
new file mode 100644
index 000000000..c23d06ece
--- /dev/null
+++ b/doc/trace-source-list.h
@@ -0,0 +1,204 @@
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/tx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback0 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback1 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback2 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief store packet in queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet queued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/enqueue.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback3 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief remove packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dequeued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/dequeue.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback4 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback5 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::PointToPointTraceType
+void TraceSinkCallback6 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::CsmaTraceType
+void TraceSinkCallback7 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::CsmaTraceType
+void TraceSinkCallback8 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief The value of the speed vector changed
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 the mobility model whose course changed.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$MobilityModelNotifier/course-change.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+void TraceSinkCallback9 (const TraceContext & arg1, Ptr arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/tx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback10 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback11 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback12 (const TraceContext & arg1, const Packet & arg2);
+
diff --git a/doc/tracing.h b/doc/tracing.h
new file mode 100644
index 000000000..45e7d9db5
--- /dev/null
+++ b/doc/tracing.h
@@ -0,0 +1,576 @@
+/**
+ * \defgroup TraceSourceList List of trace sources
+ */
+
+/**
+ * \defgroup tracing Tracing
+ *
+ * The flexibility of the ns-3 tracing system comes at the cost of quite
+ * a bit of complexity so, before trying to use the low-level aspects
+ * of the tracing API, it is important to focus on some basic definitions:
+ *
+ * - A trace source is an object instance which can report trace events
+ * to a set of listening trace sinks.
+ *
+ * - A trace sink is a user-provided callback (a function) which can
+ * be connected to a set of trace sources to receive the events generated
+ * by each trace source.
+ *
+ * - A trace resolver is an object which allows users to establish
+ * connections between a set of trace sources and a set of trace sinks.
+ *
+ * \section TraceSource Generating Trace Events
+ *
+ * So, what does it look like in practice ? First, let's look at trace
+ * sources. We have two types of trace sources: numeric, and, normal
+ * trace sources. Numeric trace sources behave as normal c++ integers
+ * or c++ floating point numbers except that they report as trace events
+ * each change of their value. For example:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (void)
+ * {
+ * // use the "int" trace source just
+ * // like any other "int" variable.
+ * m_cwnd *= 2;
+ * m_cwnd += 4;
+ * if (m_cwnd > 100)
+ * {
+ * // do something.
+ * }
+ * }
+ * private:
+ * // declare an instance of a "int" trace source
+ * SVTraceSource m_cwnd;
+ * };
+ * \endcode
+ * Normal trace sources, on the other hand, allow you to trace the
+ * call of arbitrary functions and methods, as shown below. They are
+ * typically used to track "rx", "tx", or "drop" events but could
+ * also be used to track route change events, or position change
+ * events:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource m_doSomething;
+ * };
+ * \endcode
+ * Every type of trace source derives from the ns3::TraceSource base class.
+ * As of today, the set of concrete subclasses is relatively short:
+ * ns3::CallbackTraceSource, ns3::SvTraceSource, ns3::UvTraceSource, and,
+ * ns3::FvTraceSource.
+ *
+ * \section TraceSink Receiving Trace Events
+ *
+ * To receive these trace events, a user should specify a set of trace sinks.
+ * For example, to receive the "int" and the "something" events shown in the
+ * examples above, a user would declare the following functions:
+ * \code
+ * // oldValue and newValue contain the previous and new values of
+ * // the connected SVTraceSource trace source.
+ * void
+ * CwndTraceSink (const TraceContext &context, int64_t oldValue, int64_t newValue)
+ * {
+ * // for example, print the new value:
+ * std::cout << "cwnd=" << newValue << std::endl;
+ * }
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "packet " << packet << std::endl;
+ * }
+ * \endcode
+ * Each of these sink function takes, as a first argument, a reference to a
+ * const TraceContext object. This context object contains information which
+ * describes the instance of the connected trace source: that information is
+ * setup during the connection process and does not change afterwards
+ * The type and the number of the other arguments to each trace sink depends
+ * on the type of the connected trace source: it conveys per-event information
+ * from the trace source to the trace sink. For example, UVTraceSource and
+ * SVTraceSource trace sources require two extra arguments. The former requires
+ * two unsigned 64 bit integers while the latter requires two signed 64 bit
+ * integers. More generally, users can consult the \ref TraceSourceList
+ * to figure out the arguments which a trace sink is required to receive
+ * for each trace source: a signature of the user trace sink must match
+ * _exactly_ the signature documented in the \ref TraceSourceList.
+ *
+ *
+ * \section TraceSourceSimpleExport A simple way to connect Trace Sources with Trace Sinks
+ *
+ * The crux of the complexity of the ns-3 tracing system comes from its
+ * flexible system used to connect trace sources to trace sinks but what is really
+ * nice about it is that it is not necessary to use it to setup simple traces.
+ *
+ * The simplest way to export a set of trace sources to a user, for example,
+ * during the early prototyping phases of a system, is to add a set of public methods
+ * to give to your users access to the trace source object instances you use to generate
+ * trace events:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * CallbackTraceSource *PeekSomethingTraceSource (void) const
+ * {
+ * return &m_doSomething
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource m_doSomething;
+ * };
+ * \endcode
+ * If your users hold a pointer to an instance of MyModel, and if they want to connect
+ * a MySomethingSink, they can simply do the following which invokes the
+ * TraceSource::AddCallback method and creates a Callback object from the user's
+ * sink with the MakeCallback function.
+ * \code
+ * void
+ * MySomethingSink (const TraceContext &context, Packet packet)
+ * {
+ * // do whatever you want.
+ * }
+ * MyModel *model = ...;
+ * CallbackTraceSource *source = model->PeekSomethingTraceSource ();
+ * source->AddCallback (MakeCallback (&MySomethingSink));
+ * \endcode
+ *
+ * The full power of the tracing system comes however from its ns3::NodeList::Connect
+ * method which is described in the following sections.
+ *
+ * \section TraceConnection Connecting Trace Sources to Trace Sinks
+ *
+ * If a trace source is integrated in the ns-3 trace connection facility, a user
+ * should call the ns3::NodeList::Connect method to establish a connection between
+ * a trace sink and a set of matching trace sources. The second argument to that
+ * method is a callback to the user's trace sink.
+ * That callback is easy to construct: call ns3::MakeCallback and you are done. The
+ * first argument is a string whose format is similar to a unix path and which is
+ * used to uniquely identify the set of trace sources you want to connect to.
+ * The set of acceptable path strings is also documented in the \ref TraceSourceList.
+ *
+ * So, what does this look like from the perspective of a user ? If we wanted to
+ * connect to a trace source defined somewhere deep into the a set of NetDevice objects
+ * located in some nodes of the system, we could write the following:
+ * \code
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "packet: " << packet << std::endl;
+ * }
+ * // connect the above sink to a matching trace source
+ * NodeList::Connect ("/nodes/* /devices/* /rx", MakeCallback &DoSomethingTraceSink);
+ * \endcode
+ *
+ * The connection path string "/nodes/* /devices/* /rx" matches the "rx" trace source
+ * located in every netdevice located in every node. The syntax of that path string
+ * is loosely based on regular expressions so, a user could conceivably connect
+ * to the trace sources present in only one node identified by node index:
+ * "/nodex/3/devices/* /rx".
+ *
+ * The matching algorithm used here is very useful since it allows you to connect
+ * at once a large set of trace sources to a single sink but it introduces another
+ * problem: it becomes impossible when you receive an event in your trace sink to
+ * know from _which_ trace source the event is coming from. In our example, the
+ * trace source might be coming from the NetDevice number 2 of Node 10 or Netdevice
+ * number 0 of Node 5. In both cases, you might need to know which of these NetDevice
+ * is generating this event, if only to generate some ascii trace dump. Another
+ * similar use-case is that you might have connected the same trace sink to
+ * multiple types of events which have the same signature: it is quite common
+ * to receive all tx, rx, and drop events in the same trace sink and that would be
+ * quite trivial to achieve with a string such as: "/nodes/* /devices/* /*"
+ *
+ * The source of a trace event can be retrieved from a trace sink using
+ * different means: the simplest
+ * way to get this information is to use the builtin printing facility of
+ * the TraceContext object:
+ * \code
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * The above code is going to generate output which looks like the following:
+ * \code
+ * context="nodeid=2 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * context="nodeid=1 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * ...
+ * \endcode
+ *
+ * Another more advanced way to get information out of a TraceContext is to call its
+ * ns3::TraceContext::GetElement method. This method takes as its first and only
+ * argument an instance of the object we want to read and the list of available
+ * object instances we can read from a TraceContext is documented, once again,
+ * in the \ref TraceSourceList. For example, we could write the following to
+ * generate adhoc trace output:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ * NodeListIndex nodeIndex;
+ * NodeNetDeviceIndex deviceIndex;
+ * context.GetElement (nodeIndex);
+ * context.GetElement (deviceIndex);
+ * std::cout << "node-index=" << nodeIndex.Get ();
+ * std::cout << ", device-index=" << deviceIndex.Get ();
+ * std::cout << ", packet: " << packet;
+ * std::cout << std::endl;
+ * }
+ * \endcode
+ *
+ * \section ExportingTraceSources Exporting new Trace Sources
+ *
+ * Using existing trace sources to connect them to a set of adhoc trace sinks
+ * is not really complicated but, setting up new trace sources which can hook
+ * in this automatic connection system is a bit more complicated.
+ *
+ * So far, we know that a model author can generate trace events really easily:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet with value
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource m_doSomething;
+ * };
+ * \endcode
+ *
+ * To make these new trace sources available to the rest of the connection system,
+ * the first step is to make sure that your model object derives from the ns3::Object
+ * base class either directly (as shown below) or indirectly through another base class:
+ * \code
+ * class MyModel : public Object {...};
+ * // or:
+ * class SomeOtherObject : public Object {...};
+ * class MyModel : public SomeOtherObject {...};
+ * \endcode
+ *
+ * This is pretty trivial and lays the ground for the second step: overriding the
+ * ns3::Object::GetTraceResolver method:
+ * \code
+ * class MyModel : public MyParent
+ * {
+ * public:
+ * // declare overriden method
+ * virtual Ptr GetTraceResolver (void) const;
+ * private:
+ * // the new trace source to export.
+ * CallbackTraceSource m_rxSource;
+ * };
+ * \endcode
+ *
+ * To implement this method, you could attempt to implement a new subclass of
+ * the ns3::TraceResolver base class and return an instance from this method but
+ * this would be very hard. Instead, you should use the helper class
+ * ns3::CompositeTraceResolver to register your trace sources and chain up to
+ * your parent:
+ * \code
+ * Ptr
+ * MyModel::GetTraceResolver (void) const
+ * {
+ * // create an empty trace resolver
+ * Ptr resolver = Create ();
+ * // register m_rxSource
+ * resolver->AddSource ("rx", // the name of the trace source in the path string
+ * TraceDoc ("some help text to explain the purpose of this trace source",
+ * "Packet", // the type of the first argument to the trace source
+ * "the purpose of the first argument",
+ * "type-of-second-argument", "purpose-of-second-argument"),
+ * m_rxSource // the trace source itself is registered
+ * );
+ * // make sure we include the trace sources implemented in the parent.
+ * resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ *
+ * Once you have written that code, you must make sure that this new method GetTraceResolver
+ * is going to be called at some point by the tracing system. If your model is located somewhere
+ * deep in MAC or PHY layer, that is, it is part of a NetDevice implementation, all you
+ * have to do is to make sure that your model is registered as a "composite" of your NetDevice
+ * subclass:
+ * \code
+ * class MyNetDevice : public NetDevice
+ * {
+ * public:
+ * Ptr GetTraceResolver (void) const;
+ * private:
+ * Ptr m_model;
+ * };
+ *
+ * Ptr
+ * MyNetDevice::GetTraceResolver (void) const
+ * {
+ * Ptr resolver = ...;
+ * // register other trace source
+ * ...
+ * // register now your model as a "composite"
+ * resolver->AddComposite ("my-model", m_model);
+ * // chain up to parent.
+ * resolver->SetParentResolver (NetDevice::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ *
+ * The code above will make your "rx" trace source appear under the
+ * /nodes/xx/devices/xx/my-model/rx namespace path.
+ *
+ * If you have implemented a new layer 3 or 4 protocol object, the process to
+ * export your trace sources is quite similar. You need to subclass from
+ * ns3::Object, override the ns3::Object::GetTraceResolver method, make
+ * sure you chain up to your parent's GetTraceResolver method, and, finally,
+ * make sure that someone calls your new GetTraceResolver method. How to accomplish
+ * the latter should be documented in the node's API documentation which describes
+ * how to implement a new layer 3 or 4 protocol object.
+ *
+ * \section AdvancedTraceContext Creating new Trace Context Elements
+ *
+ * The last important feature which model developers need to understand
+ * is how to provide extra context information to trace sinks. For example,
+ * if your model exports both rx and tx trace sources which share the same
+ * signature, it is quite natural for a user to connect to a single trace sink
+ * to both of them with a trace path string such as "/nodes/* /devices/* /(rx|tx)".
+ * In this case, it becomes necessary to be able, from the trace sink function,
+ * to tell which event triggered the call to the trace sink: a rx or a tx event.
+ *
+ * That example is detailed below with a TX, a RX, and a DROP source:
+ * \code
+ * class MyModel
+ * {
+ * private:
+ * CallbackTraceSource m_rxSource;
+ * CallbackTraceSource m_txSource;
+ * CallbackTraceSource m_dropSource;
+ * };
+ * \endcode
+ * When a single sink is connected to all 3 sources here, one might want
+ * to write code like the following:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ * switch (type) {
+ * case RX:
+ * std::cout << "rx" << std::endl;
+ * break;
+ * case TX:
+ * std::cout << "tx" << std::endl;
+ * break;
+ * case DROP:
+ * std::cout << "drop" << std::endl;
+ * break;
+ * }
+ * \endcode
+ *
+ * \subsection AdvancedTraceContextSimpleSolution The simple solution
+ *
+ * The simplest way to do achieve the result shown above is to include
+ * in the trace source an extra explicit argument which describes the source event:
+ * - define a small enum with 3 values
+ * - change the signature of m_rxSource, m_txSource, and m_dropSource to include
+ * the enum
+ * - pass the enum value in each event
+ *
+ * The resulting code is shown below:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * // define the trace type enum.
+ * enum TraceType {
+ * RX,
+ * TX,
+ * DROP
+ * };
+ * private:
+ * // generate events
+ * void NotifyRxPacket (Packet p) {
+ * m_rxSource (p, MyModel::RX);
+ * }
+ * void NotifyTxPacket (Packet p) {
+ * m_rxSource (p, MyModel::TX);
+ * }
+ * void NotifyDropPacket (Packet p) {
+ * m_rxSource (p, MyModel::DROP);
+ * }
+ * CallbackTraceSource m_rxSource;
+ * CallbackTraceSource m_txSource;
+ * CallbackTraceSource m_dropSource;
+ * };
+ * \endcode
+ * These 3 new sources can be connected easily to a new trace sink:
+ * \code
+ * void ASimpleTraceSink (const TraceContext &context, const Packet &packet, enum MyModel::TraceType type)
+ * {
+ * // here, read the "type" argument
+ * }
+ * \endcode
+ *
+ * This solution works but it makes it impossible to connect a single trace sink to a set
+ * of trace sources which represent "rx" events in different NetDevice objects since
+ * each of them will define a different enum type with different values: since the
+ * trace sink signature must match exactly the trace source signature, it is impossible
+ * to connect at the same time to all "rx" events of different NetDevice.
+ *
+ * \subsection AdvancedTraceContextFancySolution The more complex and generic solution
+ *
+ * There is, hopefully, a way to get the best of both worlds, that is, to allow a
+ * user to connect to a lot of trace source events of the same kind but coming from different
+ * implementations and to allow the user to differentiate between these different
+ * implementations.
+ *
+ * Rather than define an adhoc enum type with a list of trace sources, you can also
+ * define a new ns3::TraceContextElement for your source sources. For example, if you
+ * define a new MyModelTraceType class which contains the type of trace, your users can
+ * then write trace sink code which looks like this:
+ * \code
+ * void AFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ * MyModelTraceType type;
+ * if (context.GetElement (type))
+ * {
+ * switch (type.Get ())
+ * {
+ * case MyModelTraceType::RX:
+ * std::cout << "rx" << std::endl;
+ * break;
+ * case MyModelTraceType::TX:
+ * std::cout << "tx" << std::endl;
+ * break;
+ * case MyModelTraceType::DROP:
+ * std::cout << "drop" << std::endl;
+ * break;
+ * }
+ * }
+ * }
+ * \endcode
+ *
+ * Of course, since the type of trace is stored in the TraceContext, your users can
+ * also take the shortcut which uses the printing functionality of the TraceContext:
+ * \code
+ * void ALessFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ * std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * which will generate something like the following when the trace source comes
+ * from MyModel:
+ * \code
+ * context="my-model-rx" packet: ...
+ * \endcode
+ *
+ * The first step to achieve this is to define and implement a new
+ * subclass of the ns3::TraceContextElement base class. The exact list of
+ * public methods which must be implemented is described in the API
+ * documentation of the ns3::TraceContextElement class.
+ * \code
+ * class MyModelTraceType : public TraceContextElement
+ * {
+ * public:
+ * enum Type {
+ * RX,
+ * TX,
+ * DROP
+ * };
+ * // called from MyModel::GetTraceResolver
+ * MyModelTraceType (enum Type type);
+ * // called from trace sink
+ * enum Type Get (void) const;
+ * // needed by the tracing subsystem
+ * static uint16_t GetUid (void);
+ * // needed by the tracing subsystem to
+ * // print the content of a TraceContext
+ * void Print (std::ostream &os) const;
+ * // needed by the tracing subsystem to
+ * // generate the doxygen documentation.
+ * std::string GetTypeName (void) const;
+ * private:
+ * enum Type m_type;
+ * };
+ * \endcode
+ * The implementation does not require much thinking:
+ * \code
+ * MyModelTraceType::MyModelTraceType (enum Type type)
+ * : m_type (type)
+ * {}
+ * enum Type
+ * MyModelTraceType::Get (void) const
+ * {
+ * return m_type;
+ * }
+ * uint16_t
+ * MyModelTraceType::GetUid (void)
+ * {
+ * // use protected TraceContextElement::AllocateUid method
+ * // the input string is used to uniquely identify this new subclass
+ * static uint16_t uid = AllocateUid ("ns3::MyModelTraceType");
+ * return uid;
+ * }
+ * void
+ * MyModelTraceType::Print (std::ostream &os) const
+ * (
+ * // this method is invoked by the print function of a TraceContext
+ * // if it contains an instance of this TraceContextElement.
+ * switch (m_type) {
+ * case RX: os << "rx"; break;
+ * // ...
+ * }
+ * )
+ * std::string
+ * MyModelTraceType::GetTypeName (void) const
+ * {
+ * // This method should return a fully-qualified c++ typename
+ * // This method is used only for documentation purposes to
+ * // generate the content of the Trace Source List.
+ * return "ns3::MyModelTraceType";
+ * }
+ * \endcode
+ *
+ * Once this subclass is implemented, the work is almost completed: you
+ * just need to pass an instance of that class as the last argument of
+ * the ns3::CompositeTraceResolver::AddSource method as shown below:
+ * \code
+ * Ptr
+ * MyModel::GetTraceResolver (void) const
+ * {
+ * // create an empty trace resolver
+ * Ptr resolver = Create ();
+ * // register m_rxSource
+ * resolver->AddSource ("rx", // the name of the trace source in the path string
+ * TraceDoc ("some help text to explain the purpose of this trace source",
+ * "Packet", // the type of the first argument to the trace source
+ * "the purpose of the first argument",
+ * "type-of-second-argument", "purpose-of-second-argument"),
+ * m_rxSource, // the trace source itself is registered
+ * // the TraceContextElement associated to this trace source.
+ * MyModelTraceType (MyModelTraceType::RX)
+ * );
+ * // make sure we include the trace sources implemented in the parent.
+ * resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ */
diff --git a/samples/main-random-topology.cc b/samples/main-random-topology.cc
index 3fb52a0d9..3021ed3fb 100644
--- a/samples/main-random-topology.cc
+++ b/samples/main-random-topology.cc
@@ -15,7 +15,7 @@
using namespace ns3;
static void
-CourseChange (Ptr position)
+CourseChange (const TraceContext &context, Ptr position)
{
Position pos = position->Get ();
std::cout << Simulator::Now () << ", pos=" << position << ", x=" << pos.x << ", y=" << pos.y
@@ -39,7 +39,7 @@ int main (int argc, char *argv[])
for (uint32_t i = 0; i < 10000; i++)
{
Ptr notifier = Create ();
- notifier->RegisterListener (MakeCallback (&CourseChange));
+ notifier->TraceConnect ("/course-change", MakeCallback (&CourseChange));
objects.push_back (notifier);
}
diff --git a/src/common/array-trace-resolver.h b/src/common/array-trace-resolver.h
deleted file mode 100644
index e4507d4af..000000000
--- a/src/common/array-trace-resolver.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef ARRAY_TRACE_RESOLVER_H
-#define ARRAY_TRACE_RESOLVER_H
-
-#include
-#include
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to offer trace resolution for an array of objects.
- * \ingroup lowleveltracing
- */
-template
-class ArrayTraceResolver : public TraceResolver
-{
-public:
- /**
- * \param context trace context associated to this trace resolver
- * \param getSize callback which returns dynamically the size of underlying array
- * \param get callback which returns any element in the underlying array
- *
- * Construct a trace resolver which can match any input integer
- * against an element in an array. The array is accessed using a
- * pair of callbacks. It is the responsability of the user to
- * provide two such callbacks whose job is to adapt the array
- * API to the resolver needs. Each element of the array is expected
- * to provide a method named CreateTraceResolver which takes as
- * only argument a reference to a const TraceContext and returns
- * a pointer to a TraceResolver. i.e. the signature is:
- * TraceResolver * (*) (TraceContext const &)
- */
- ArrayTraceResolver (TraceContext const &context,
- Callback getSize,
- Callback get);
-private:
- virtual TraceResolverList DoLookup (std::string id) const;
- Callback m_getSize;
- Callback m_get;
-};
-}//namespace ns3
-
-namespace ns3 {
-
-template
-ArrayTraceResolver::ArrayTraceResolver (TraceContext const &context,
- Callback getSize,
- Callback get)
- : TraceResolver (context),
- m_getSize (getSize),
- m_get (get)
-{}
-template
-TraceResolver::TraceResolverList
-ArrayTraceResolver::DoLookup (std::string id) const
-{
- TraceResolverList list;
- if (id == "*")
- {
- for (uint32_t i = 0; i < m_getSize (); i++)
- {
- TraceContext context = GetContext ();
- INDEX index = i;
- context.Add (index);
- list.push_back (m_get (i)->CreateTraceResolver (context));
- }
- }
- return list;
-}
-
-
-}//namespace ns3
-
-#endif /* ARRAY_TRACE_RESOLVER_H */
diff --git a/src/common/callback-trace-source.h b/src/common/callback-trace-source.h
deleted file mode 100644
index a1e13df9d..000000000
--- a/src/common/callback-trace-source.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-
-#ifndef CALLBACK_TRACE_H
-#define CALLBACK_TRACE_H
-
-#include
-#include "ns3/callback.h"
-#include "ns3/fatal-error.h"
-#include "trace-context.h"
-
-namespace ns3 {
-
-
-/**
- * \brief log arbitrary number of parameters to a matching ns3::Callback
- * \ingroup lowleveltracing
- *
- * Whenever operator () is invoked on this class, the call and its arguments
- * are forwarded to the internal matching ns3::Callback.
- */
-template
-class CallbackTraceSource {
-public:
- CallbackTraceSource ();
- void AddCallback (CallbackBase const & callback, TraceContext const & context);
- void RemoveCallback (CallbackBase const & callback);
- void operator() (void);
- void operator() (T1 a1);
- void operator() (T1 a1, T2 a2);
- void operator() (T1 a1, T2 a2, T3 a3);
- void operator() (T1 a1, T2 a2, T3 a3, T4 a4);
-
-private:
- typedef std::list > CallbackList;
- TraceContext m_context;
- CallbackList m_callbackList;
-};
-
-}; // namespace ns3
-
-// implementation below.
-
-namespace ns3 {
-
-template
-CallbackTraceSource::CallbackTraceSource ()
- : m_callbackList ()
-{}
-template
-void
-CallbackTraceSource::AddCallback (CallbackBase const & callback,
- TraceContext const &context)
-{
- Callback cb;
- cb.Assign (callback);
- m_context.Add (context);
- m_callbackList.push_back (cb);
-}
-template
-void
-CallbackTraceSource::RemoveCallback (CallbackBase const & callback)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); /* empty */)
- {
- if ((*i).IsEqual (callback))
- {
- i = m_callbackList.erase (i);
- }
- else
- {
- i++;
- }
- }
-}
-template
-void
-CallbackTraceSource::operator() (void)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context);
- }
-}
-template
-void
-CallbackTraceSource::operator() (T1 a1)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1);
- }
-}
-template
-void
-CallbackTraceSource::operator() (T1 a1, T2 a2)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2);
- }
-}
-template
-void
-CallbackTraceSource::operator() (T1 a1, T2 a2, T3 a3)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2, a3);
- }
-}
-template
-void
-CallbackTraceSource::operator() (T1 a1, T2 a2, T3 a3, T4 a4)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2, a3, a4);
- }
-}
-
-}//namespace ns3
-
-#endif /* CALLBACK_TRACE_H */
diff --git a/src/common/composite-trace-resolver.cc b/src/common/composite-trace-resolver.cc
deleted file mode 100644
index bf60aa81e..000000000
--- a/src/common/composite-trace-resolver.cc
+++ /dev/null
@@ -1,375 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#include "composite-trace-resolver.h"
-
-namespace ns3 {
-
-CompositeTraceResolver::CompositeTraceResolver (TraceContext const &context)
- : TraceResolver (context)
-{}
-
-CompositeTraceResolver::~CompositeTraceResolver ()
-{}
-
-void
-CompositeTraceResolver::Add (std::string name,
- Callback createResolver)
-{
- TraceContext traceContext = GetContext ();
- DoAdd (name, createResolver, traceContext);
-}
-
-void
-CompositeTraceResolver::DoAdd (std::string name,
- Callback createResolver,
- TraceContext const &context)
-{
- struct CallbackTraceSourceItem item;
- item.name = name;
- item.createResolver = createResolver;
- item.context = context;
- m_items.push_back (item);
-}
-
-TraceResolver::TraceResolverList
-CompositeTraceResolver::DoLookup (std::string id) const
-{
- if (id == "*")
- {
- TraceResolver::TraceResolverList list;
- for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
- {
- list.push_back (i->createResolver (i->context));
- }
- return list;
- }
- std::string::size_type start, end;
- start = id.find_first_of ("(", 0);
- end = id.find_first_of (")", 0);
- if (start != 0 || end != (id.size ()-1))
- {
- for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
- {
- if (i->name == id)
- {
- TraceResolver::TraceResolverList list;
- list.push_back (i->createResolver (i->context));
- return list;
- }
- }
- }
- std::list names;
- std::string alternatives = std::string (id, start+1, end-1);
- std::string::size_type next, cur;
- next = 0;
- cur = 0;
- while (true)
- {
- std::string element;
- next = alternatives.find ("|", cur);
- if (next == std::string::npos)
- {
- element = std::string (alternatives, cur, alternatives.size ());
- names.push_back (element);
- break;
- }
- element = std::string (alternatives, cur, next);
- names.push_back (element);
- cur = next + 1;
- }
- TraceResolver::TraceResolverList list;
- for (std::list::const_iterator i = names.begin (); i != names.end (); i++)
- {
- for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
- {
- if (j->name == *i)
- {
- list.push_back (j->createResolver (j->context));
- break;
- }
- }
- }
- return list;
-}
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "ns3/test.h"
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-class TraceSourceTest : public TraceContextElement
-{
-public:
- enum Sources {
- DOUBLEA,
- DOUBLEB,
- SUBRESOLVER,
- };
- static uint16_t GetUid (void)
- {static uint16_t uid = AllocateUid ("TraceSourceTest"); return uid;}
- void Print (std::ostream &os)
- {os << "tracesource=";
- if (m_sources == DOUBLEA) {os << "doubleA";}
- else if (m_sources == DOUBLEB) {os << "doubleB";}
- else if (m_sources == SUBRESOLVER) {os << "subresolver";}
- }
- TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
- TraceSourceTest (enum Sources sources) :m_sources (sources) {}
- bool IsDoubleA (void) {return m_sources == TraceSourceTest::DOUBLEA;}
- bool IsDoubleB (void) {return m_sources == TraceSourceTest::DOUBLEB;}
-private:
- enum TraceSourceTest::Sources m_sources;
-};
-
-class SubTraceSourceTest : public TraceContextElement
-{
-public:
- enum Sources {
- INT,
- };
- static uint16_t GetUid (void)
- {static uint16_t uid = AllocateUid ("SubTraceSourceTest"); return uid;}
- void Print (std::ostream &os)
- {os << "subtracesource=int";}
- SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
- SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
-private:
- enum Sources m_sources;
-};
-
-class CompositeTraceResolverTest : public Test
-{
-public:
- CompositeTraceResolverTest ();
- virtual ~CompositeTraceResolverTest ();
- virtual bool RunTests (void);
-private:
- void TraceDouble (TraceContext const &context, double v);
- void TraceInt (TraceContext const &context, int v);
- TraceResolver *CreateSubResolver (TraceContext const &context);
-
-
- bool m_gotDoubleA;
- bool m_gotDoubleB;
- CallbackTraceSource m_traceInt;
- bool m_gotInt;
-};
-
-CompositeTraceResolverTest::CompositeTraceResolverTest ()
- : Test ("CompositeTraceResolver")
-{}
-CompositeTraceResolverTest::~CompositeTraceResolverTest ()
-{}
-void
-CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
-{
- TraceSourceTest source;
- context.Get (source);
- if (source.IsDoubleA ())
- {
- m_gotDoubleA = true;
- }
- else if (source.IsDoubleB ())
- {
- m_gotDoubleB = true;
- }
- else
- {
- NS_FATAL_ERROR ("should not get any other trace source in this sink");
- }
-
-}
-
-void
-CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
-{
- m_gotInt = true;
-}
-
-TraceResolver *
-CompositeTraceResolverTest::CreateSubResolver (TraceContext const &context)
-{
- CompositeTraceResolver *subresolver = new CompositeTraceResolver (context);
- subresolver->Add ("trace-int", m_traceInt,
- SubTraceSourceTest (SubTraceSourceTest::INT));
- return subresolver;
-}
-bool
-CompositeTraceResolverTest::RunTests (void)
-{
- bool ok = true;
-
- CallbackTraceSource traceDoubleA;
- CallbackTraceSource traceDoubleB;
- TraceContext context;
-
- CompositeTraceResolver resolver (context) ;
-
- resolver.Add ("trace-double-a", traceDoubleA,
- TraceSourceTest (TraceSourceTest::DOUBLEA));
- resolver.Add ("trace-double-b", traceDoubleB,
- TraceSourceTest (TraceSourceTest::DOUBLEB));
-
- resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- m_gotDoubleA = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
- m_gotDoubleA = false;
- m_gotDoubleB = false;
-
- resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
-
- resolver.Connect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- resolver.Connect ("/(trace-double-a)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- resolver.Connect ("/(trace-double-a|trace-double-b)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
-
-
- resolver.Disconnect ("/(trace-double-a|trace-double-b)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
-
- resolver.Add ("subresolver",
- MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this),
- TraceSourceTest (TraceSourceTest::SUBRESOLVER));
-
- resolver.Connect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (!m_gotInt)
- {
- ok = false;
- }
-
- resolver.Disconnect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (m_gotInt)
- {
- ok = false;
- }
-
- resolver.Connect ("/*/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (!m_gotInt)
- {
- ok = false;
- }
-
- resolver.Disconnect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (m_gotInt)
- {
- ok = false;
- }
-
-
-
-
- return ok;
-}
-
-static CompositeTraceResolverTest g_compositeTraceResolverTest;
-
-}//namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
diff --git a/src/common/composite-trace-resolver.h b/src/common/composite-trace-resolver.h
deleted file mode 100644
index cadf9da2d..000000000
--- a/src/common/composite-trace-resolver.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef COMPOSITE_TRACE_RESOLVER_H
-#define COMPOSITE_TRACE_RESOLVER_H
-
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-#include "callback-trace-source.h"
-#include "uv-trace-source.h"
-#include "sv-trace-source.h"
-#include "fv-trace-source.h"
-#include "terminal-trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to aggregate contained TraceResolver and other trace sources.
- * \ingroup lowleveltracing
- */
-class CompositeTraceResolver : public TraceResolver
-{
-public:
- CompositeTraceResolver (TraceContext const &context);
- virtual ~CompositeTraceResolver ();
- /**
- * \param name name of trace source
- * \param trace a callback trace source
- * \param context the context associated to this trace source
- *
- * Add a callback trace source in this resolver. This trace
- * source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template
- void Add (std::string name,
- CallbackTraceSource &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace a signed variable trace source
- * \param context the context associated to this trace source
- *
- * Add a signed variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template
- void Add (std::string name,
- SVTraceSource &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace an unsigned variable trace source
- * \param context the context associated to this trace source
- *
- * Add an unsigned variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template
- void Add (std::string name,
- UVTraceSource &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace a floating-point variable trace source
- * \param context the context associated to this trace source
- *
- * Add a floating-point variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template
- void Add (std::string name,
- FVTraceSource &trace, T const &context);
-
- /**
- * \param name name of child trace resolver
- * \param createResolver a trace resolver constructor
- * \param context the context associated to this entry
- *
- * Add a child trace resolver to this resolver. This child
- * trace resolver will match the name specified during
- * namespace resolution. When this happens, the constructor
- * will be invoked to create the child trace resolver and
- * the associated TraceContext will be automatically extended
- * to contain the input context.
- */
- template
- void Add (std::string name,
- Callback createResolver,
- T const &context);
-
- /**
- * \param name name of child trace resolver
- * \param createResolver a trace resolver constructor
- *
- * Add a child trace resolver to this resolver. This child
- * trace resolver will match the name specified during
- * namespace resolution. When this happens, the constructor
- * will be invoked to create the child trace resolver.
- */
- void Add (std::string name,
- Callback createResolver);
-private:
- template
- void DoAddTraceSource (std::string name,
- SOURCE &traceSource, CONTEXT const &context);
- template
- static TraceResolver *CreateTerminalTraceResolver (SOURCE *trace,
- TraceContext const &context);
- void DoAdd (std::string name,
- Callback createResolver,
- TraceContext const &context);
- virtual TraceResolverList DoLookup (std::string id) const;
-
- struct CallbackTraceSourceItem
- {
- std::string name;
- Callback createResolver;
- TraceContext context;
- };
-
- typedef std::list TraceItems;
- TraceItems m_items;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template
-void
-CompositeTraceResolver::DoAddTraceSource (std::string name,
- SOURCE &traceSource, CONTEXT const &context)
-{
- TraceContext traceContext = GetContext ();
- traceContext.Add (context);
- TraceResolver *(*create) (SOURCE *trace, TraceContext const &context);
- create = &CompositeTraceResolver::CreateTerminalTraceResolver;
- Callback createResolver =
- MakeBoundCallback (create, &traceSource);
- DoAdd (name, createResolver, traceContext);
-}
-
-template
-TraceResolver *
-CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource,
- TraceContext const &context)
-{
- return new TerminalTraceResolver (*traceSource, context);
-}
-
-
-
-
-template
-void
-CompositeTraceResolver::Add (std::string name,
- CallbackTraceSource &trace,
- T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template
-void
-CompositeTraceResolver::Add (std::string name,
- SVTraceSource &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template
-void
-CompositeTraceResolver::Add (std::string name,
- UVTraceSource &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template
-void
-CompositeTraceResolver::Add (std::string name,
- FVTraceSource &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template
-void
-CompositeTraceResolver::Add (std::string name,
- Callback createResolver,
- T const &context)
-{
- TraceContext traceContext = GetContext ();
- traceContext.Add (context);
- DoAdd (name, createResolver, traceContext);
-}
-
-}//namespace ns3
-
-#endif /* COMPOSITE_TRACE_RESOLVER_H */
diff --git a/src/common/empty-trace-resolver.h b/src/common/empty-trace-resolver.h
deleted file mode 100644
index 04f1c1bc4..000000000
--- a/src/common/empty-trace-resolver.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef EMPTY_TRACE_RESOLVER_H
-#define EMPTY_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-/**
- * \brief a TraceResolver instance which does not resolve anything.
- * \ingroup tracing
- *
- * Trying to resolve against this class will yield no matches and no
- * connections. Returning an instance of this class from a
- * CreateTraceResolver method is a hand way of not implementing
- * any Tracing code.
- */
-class EmptyTraceResolver : public TraceResolver
-{
-public:
- /**
- * \param o necessary context for this class.
- *
- * The only constructor exported by this class.
- */
- EmptyTraceResolver (TraceContext const &o);
-};
-
-}//namespace ns3
-
-#endif /* EMPTY_TRACE_RESOLVER_H */
diff --git a/src/common/packet.cc b/src/common/packet.cc
index 5159f3e2c..0de766dba 100644
--- a/src/common/packet.cc
+++ b/src/common/packet.cc
@@ -199,6 +199,12 @@ Packet::Deserialize (Buffer buffer)
buffer.RemoveAtStart (metadataDeserialized);
}
+std::ostream& operator<< (std::ostream& os, const Packet &packet)
+{
+ packet.Print (os);
+ return os;
+}
+
} // namespace ns3
diff --git a/src/common/packet.h b/src/common/packet.h
index 00c540600..f1e14cf02 100644
--- a/src/common/packet.h
+++ b/src/common/packet.h
@@ -328,6 +328,8 @@ private:
static uint32_t m_globalUid;
};
+std::ostream& operator<< (std::ostream& os, const Packet &packet);
+
/**
* \defgroup packetperf Packet Performance
* The current implementation of the byte buffers and tag list is based
diff --git a/src/common/terminal-trace-resolver.h b/src/common/terminal-trace-resolver.h
deleted file mode 100644
index e026d07cb..000000000
--- a/src/common/terminal-trace-resolver.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef TERMINAL_TRACE_RESOLVER_H
-#define TERMINAL_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-template
-class TerminalTraceResolver : public TraceResolver
-{
- public:
- TerminalTraceResolver (T &traceSource, TraceContext const &context);
- private:
- virtual void DoConnect (CallbackBase const &cb);
- virtual void DoDisconnect (CallbackBase const &cb);
- T &m_traceSource;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template
-TerminalTraceResolver::TerminalTraceResolver (T &traceSource,
- TraceContext const &context)
- : TraceResolver (context),
- m_traceSource (traceSource)
-{}
-template
-void
-TerminalTraceResolver::DoConnect (CallbackBase const &cb)
-{
- m_traceSource.AddCallback (cb, GetContext ());
-}
-template
-void
-TerminalTraceResolver::DoDisconnect (CallbackBase const &cb)
-{
- m_traceSource.RemoveCallback (cb);
-}
-
-}//namespace ns3
-
-#endif /* TERMINAL_TRACE_RESOLVER_H */
diff --git a/src/common/trace-resolver.cc b/src/common/trace-resolver.cc
deleted file mode 100644
index 251e7cc87..000000000
--- a/src/common/trace-resolver.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-TraceResolver::TraceResolver (TraceContext const &context)
- : m_context (context)
-{}
-
-TraceResolver::~TraceResolver ()
-{}
-
-TraceContext const &
-TraceResolver::GetContext (void) const
-{
- return m_context;
-}
-
-void
-TraceResolver::Connect (std::string path, CallbackBase const &cb)
-{
- std::string::size_type cur = 1;
- // check that first char is "/"
- std::string::size_type next = path.find ("/", cur);
- std::string element = std::string (path, cur, next-1);
- TraceResolverList resolverList = DoLookup (element);
- for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
- {
- TraceResolver *resolver = *i;
- if (next == std::string::npos)
- {
- // we really break the recursion here.
- resolver->DoConnect (cb);
- }
- else
- {
- std::string subpath = std::string (path, next, std::string::npos);
- resolver->Connect (subpath, cb);
- }
- delete resolver;
- }
- resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-void
-TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
-{
- std::string::size_type cur = 1;
- // check that first char is "/"
- std::string::size_type next = path.find ("/", cur);
- std::string element = std::string (path, cur, next-1);
- TraceResolverList resolverList = DoLookup (element);
- for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
- {
- TraceResolver *resolver = *i;
- if (next == std::string::npos)
- {
- // we really break the recursion here.
- resolver->DoDisconnect (cb);
- }
- else
- {
- std::string subpath = std::string (path, next, std::string::npos);
- resolver->Disconnect (subpath, cb);
- }
- delete resolver;
- }
- resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-TraceResolver::TraceResolverList
-TraceResolver::DoLookup (std::string id) const
-{
- return TraceResolverList ();
-}
-void
-TraceResolver::DoConnect (CallbackBase const &cb)
-{}
-
-void
-TraceResolver::DoDisconnect (CallbackBase const &cb)
-{}
-
-
-}//namespace ns3
diff --git a/src/common/trace-resolver.h b/src/common/trace-resolver.h
deleted file mode 100644
index 93bf43095..000000000
--- a/src/common/trace-resolver.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef TRACE_RESOLVER_H
-#define TRACE_RESOLVER_H
-
-#include
-#include
-#include "trace-context.h"
-
-namespace ns3 {
-
-class CallbackBase;
-
-/**
- * \brief the base class which is used to incremental perform trace
- * namespace resolution.
- * \ingroup lowleveltracing
- *
- * This class provides a public API to the ns3::TraceRoot object:
- * - ns3::TraceResolver::Connect
- * - ns3::TraceResolver::Disconnect
- *
- * It also provides an API for its subclasses. Each subclass should
- * implement one of:
- * - ns3::TraceResolver::DoLookup
- * - ns3::TraceResolver::DoConnect and ns3::TraceResolver::DoDisconnect
- * Each subclass must also provide an ns3::TraceContext to the TraceResolver
- * constructor. Finally, each subclass can access the ns3::TraceContext
- * associated to this ns3::TraceResolver through the
- * ns3::TraceResolver::GetContext method.
- */
-class TraceResolver
-{
-public:
- virtual ~TraceResolver ();
- /**
- * \param path the namespace path to resolver
- * \param cb the callback to connect to the matching namespace
- *
- * This method is typically invoked by ns3::TraceRoot but advanced
- * users could also conceivably call it directly if they want to
- * skip the ns3::TraceRoot.
- */
- void Connect (std::string path, CallbackBase const &cb);
- /**
- * \param path the namespace path to resolver
- * \param cb the callback to disconnect in the matching namespace
- *
- * This method is typically invoked by ns3::TraceRoot but advanced
- * users could also conceivably call it directly if they want to
- * skip the ns3::TraceRoot.
- */
- void Disconnect (std::string path, CallbackBase const &cb);
-protected:
- /**
- * \param context the context used to initialize this TraceResolver.
- *
- * Every subclass must call this constructor
- */
- TraceResolver (TraceContext const &context);
- /**
- * \returns the ns3::TraceContext stored in this ns3::TraceResolver.
- *
- * Subclasses usually invoke this method to get access to the
- * TraceContext stored here to pass it down to the TraceResolver
- * constructors invoked from within the DoLookup method.
- */
- TraceContext const &GetContext (void) const;
- typedef std::list TraceResolverList;
-private:
- TraceResolver ();
- /**
- * \param id the id to resolve. This is supposed to be
- * one element of the global tracing namespace.
- * \returns a list of reslvers which match the input namespace element
- *
- * A subclass which overrides this method should return a potentially
- * empty list of pointers to ns3::TraceResolver instances which match
- * the input namespace element. Each of these TraceResolver should be
- * instanciated with a TraceContext which holds enough context
- * information to identify the type of the TraceResolver.
- */
- virtual TraceResolverList DoLookup (std::string id) const;
- /**
- * \param cb callback to connect
- *
- * This method is invoked on leaf trace resolvers.
- */
- virtual void DoConnect (CallbackBase const &cb);
- /**
- * \param cb callback to disconnect
- *
- * This method is invoked on leaf trace resolvers.
- */
- virtual void DoDisconnect (CallbackBase const &cb);
- TraceContext m_context;
-};
-
-}//namespace ns3
-
-#endif /* TRACE_RESOLVER_H */
diff --git a/src/common/trace-root.cc b/src/common/trace-root.cc
deleted file mode 100644
index 5bb270b8c..000000000
--- a/src/common/trace-root.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#include "trace-root.h"
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/trace-context.h"
-
-namespace ns3 {
-
-void
-TraceRoot::Connect (std::string path, CallbackBase const &cb)
-{
- TraceResolver *resolver = GetComposite ();
- resolver->Connect (path, cb);
-}
-void
-TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
-{
- TraceResolver *resolver = GetComposite ();
- resolver->Disconnect (path, cb);
-}
-void
-TraceRoot::Register (std::string name,
- Callback createResolver)
-{
- CompositeTraceResolver *resolver = GetComposite ();
- resolver->Add (name, createResolver);
-}
-
-CompositeTraceResolver *
-TraceRoot::GetComposite (void)
-{
- static CompositeTraceResolver resolver = CompositeTraceResolver (TraceContext ());
- return &resolver;
-}
-
-} // namespace ns3
diff --git a/src/common/trace-root.h b/src/common/trace-root.h
deleted file mode 100644
index a07f923cd..000000000
--- a/src/common/trace-root.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage
- */
-#ifndef TRACE_ROOT_H
-#define TRACE_ROOT_H
-
-#include
-#include "ns3/callback.h"
-
-/**
- * \defgroup lowleveltracing Low-level tracing
- *
- * This low-level API is built around a few concepts:
- * - There can be any number of trace source objects. Each trace source
- * object can generate any number of trace events. The current
- * trace source objects are: ns3::CallbackTraceSourceSource, ns3::UVTraceSource,
- * ns3::SVTraceSource, and, ns3::FVTraceSource.
- * - Each trace source can be connected to any number of trace sinks.
- * A trace sink is a ns3::Callback with a very special signature. Its
- * first argument is always a ns3::TraceContext.
- * - Every trace source is uniquely identified by a ns3::TraceContext. Every
- * trace sink can query a ns3::TraceContext for information. This allows
- * a trace sink which is connected to multiple trace sources to identify
- * from which source each event is coming from.
- *
- * To define new trace sources, a model author needs to instante one trace source
- * object for each kind of tracing event he wants to export. The trace source objects
- * currently defined are:
- * - ns3::CallbackTraceSourceSource: this trace source can be used to convey any kind of
- * trace event to the user. It is a functor, that is, it is a variable
- * which behaves like a function which will forward every event to every
- * connected trace sink (i.e., ns3::Callback). This trace source takes
- * up to four arguments and forwards these 4 arguments together with the
- * ns3::TraceContext which identifies this trace source to the connected
- * trace sinks.
- * - ns3::UVTraceSource: this trace source is used to convey key state variable
- * changes to the user. It behaves like a normal integer unsigned variable:
- * you can apply every normal arithmetic operator to it. It will forward
- * every change in the value of the variable back to every connected trace
- * sink by providing a TraceContext, the old value and the new value.
- * - ns3::SVTraceSource: this is the signed integer equivalent of
- * ns3::UVTraceSource.
- * - ns3::FVTraceSource: this is the floating point equivalent of
- * ns3::UVTraceSource and ns3::SVTraceSource.
- *
- * For example, to define a trace source which notifies you of a new packet
- * being transmitted, you would have to:
- * \code
- * class MyModel
- * {
- * public:
- * void Tx (Packet const &p);
- * private:
- * CallbackTraceSource m_txTrace;
- * };
- *
- * void
- * MyModel::Tx (Packet const &p)
- * {
- * // trace packet tx event.
- * m_txTrace (p);
- * // ... send the packet for real.
- * }
- * \endcode
- *
- * Once the model author has instantiated these objects and has wired them
- * in his simulation code (that is, he calls them wherever he wants to trigger
- * a trace event), he needs to make these trace sources available to users
- * to allow them to connect any number of trace sources to any number
- * of user trace sinks. While it would be possible to make each model
- * export directly each of his trace source instances and request users to
- * invoke a source->Connect (callback) method to perform the connection
- * explicitely, it was felt that this was a bit cumbersome to do.
- *
- * As such, the ``connection'' between a set of sources and a sink is
- * performed through a third-party class, the TraceResolver, which
- * can be used to automate the connection of multiple matching trace sources
- * to a single sink. This TraceResolver works by defining a hierarchical
- * tracing namespace: the root of this namespace is accessed through the
- * ns3::TraceRoot class. The namespace is represented as a string made of
- * multiple elements, each of which is separated from the other elements
- * by the '/' character. A namespace string always starts with a '/'.
- *
- * By default, the current simulation models provide a '/nodes' tracing root.
- * This '/nodes' namespace is structured as follows:
- * \code
- * /nodes/n/arp
- * /nodes/n/udp
- * /nodes/n/ipv4
- * /tx
- * /rx
- * /drop
- * /interfaces/n/netdevice
- * /queue/
- * /enque
- * /deque
- * /drop
- * \endcode
- *
- * The 'n' element which follows the /nodes and /interfaces namespace elements
- * identify a specific node and interface through their index within the
- * ns3::NodeList and ns3::Ipv4 objects respectively.
- *
- * To connect a trace sink to a trace source identified by a namespace string,
- * a user can call the ns3::TraceRoot::Connect method (the ns3::TraceRoot::Disconnect
- * method does the symmetric operation). This connection method can accept
- * fully-detailed namespace strings but it can also perform pattern matching
- * on the user-provided namespace strings to connect multiple trace sources
- * to a single trace sink in a single connection operation.
- *
- * The syntax of the pattern matching rules are loosely based on regular
- * expressions:
- * - the '*' character matches every element
- * - the (a|b) construct matches element 'a' or 'b'
- * - the [ss-ee] construct matches all numerical values which belong
- * to the interval which includes ss and ee
- *
- * For example, the user could use the following to connect a single sink
- * to the ipv4 tx, rx, and drop trace events:
- *
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet);
- * TraceRoot::Connect ("/nodes/ * /ipv4/ *", MakeCallback (&MyTraceSink));
- * \endcode
- *
- * Of course, this code would work only if the signature of the trace sink
- * is exactly equal to the signature of all the trace sources which match
- * the namespace string (if one of the matching trace source does not match
- * exactly, a fatal error will be triggered at runtime during the connection
- * process). The ns3::TraceContext extra argument contains
- * information on where the trace source is located in the namespace tree.
- * In that example, if there are multiple nodes in this scenario, each
- * call to the MyTraceSink function would receive a different TraceContext,
- * each of which would contain a different NodeList::NodeIndex object.
- *
- * It is important to understand exactly what an ns3::TraceContext
- * is. It is a container for a number of type instances. Each instance of
- * a ns3::TraceContext contains one and only one instance of a given type.
- * ns3::TraceContext::Add can be called to add a type instance into a
- * TraceContext instance and ns3::TraceContext::Get can be called to get
- * a copy of a type instance stored into the ns3::TraceContext. If ::Get
- * cannot retrieve the requested type, a fatal error is triggered at
- * runtime. The values stored into an ns3::TraceContext attached to a
- * trace source are automatically determined during the namespace
- * resolution process. To retrieve a value from a ns3::TraceContext, the
- * code can be as simple as this:
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet)
- * {
- * NodeList::NodeIndex index;
- * context.Get (index);
- * std::cout << "node id=" << NodeList::GetNode (index)->GetId () << std::endl;
- * }
- * \endcode
- *
- * The hierarchical global namespace described here is not implemented
- * in a single central location: it was felt that doing this would make
- * it too hard to introduce user-specific models which could hook
- * automatically into the overal tracing system. If the tracing
- * namespace was implemented in a single central location, every model
- * author would have had to modify this central component to make
- * his own model available to trace users.
- *
- * Instead, the handling of the namespace is distributed across every relevant
- * model: every model implements only the part of the namespace it is
- * really responsible for. To do this, every model is expected
- * to provide an instance of a TraceResolver whose
- * responsability is to recursively provide access to the trace sources
- * defined in its model. Each TraceResolver instance should be a subclass
- * of the TraceResolver base class which implements either the DoLookup
- * or the DoConnect and DoDisconnect methods. Because implementing these
- * methods can be a bit tedious, our tracing framework provides a number
- * of helper template classes which should save the model author from
- * having to implement his own in most cases:
- * - ns3::CompositeTraceResolver: this subclass of ns3::TraceResolver can
- * be used to aggregate together multiple trace sources and multiple other
- * ns3::TraceResolver instances.
- * - ns3::ArrayTraceResolver: this subclass of ns3::TraceResolver can be
- * used to match any number of elements within an array where every element
- * is identified by its index.
- *
- * Once you can instantiate your own ns3::TraceResolver object instance, you
- * have to hook it up into the global namespace. There are two ways to do this:
- * - you can hook your ns3::TraceResolver creation method as a new trace
- * root by using the ns3::TraceRoot::Register method
- * - you can hook your new ns3::TraceResolver creation method into the
- * container of your model. This step will obvsiouly depend on which model
- * contains your own model but, if you wrote a new l3 protocol, all you
- * would have to do to hook into your container L3Demux class is to implement
- * the pure virtual method inherited from the L3Protocol class whose name is
- * ns3::L3protocol::CreateTraceResolver.
- *
- * So, in most cases, exporting a model's trace sources is a matter of
- * implementing a method CreateTraceResolver as shown below:
- * \code
- * class MyModel
- * {
- * public:
- * enum TraceType {
- * TX,
- * RX,
- * ...
- * };
- * TraceResolver *CreateTraceResolver (TraceContext const &context);
- * void Tx (Packet const &p);
- * private:
- * CallbackTraceSource m_txTrace;
- * };
- *
- * TraceResolver *
- * MyModel::CreateTraceResolver (TraceContext const &context)
- * {
- * CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- * resolver->Add ("tx", m_txTrace, MyModel::TX);
- * return resolver;
- * }
- * void
- * MyModel::Tx (Packet const &p)
- * {
- * m_txTrace (p);
- * }
- * \endcode
- *
- * If you really want to have fun and implement your own ns3::TraceResolver
- * subclass, you need to understand the basic Connection and Disconnection
- * algorithm. The code of that algorithm is wholy contained in the
- * ns3::TraceResolver::Connect and ns3::TraceResolver::Disconnect methods.
- * The idea is that we recursively parse the input namespace string by removing
- * the first namespace element. This element is 'resolved' is calling
- * the ns3::TraceResolver::DoLookup method which returns a list of
- * TraceResolver instances. Each of the returned TraceResolver instance is
- * then given what is left of the namespace by calling ns3::TraceResolver::Connect
- * until the last namespace element is processed. At this point, we invoke
- * the ns3::TraceResolver::DoConnect or ns3::TraceResolver::DoDisconnect
- * methods to break the recursion. A good way to understand this algorithm
- * is to trace its behavior. Let's say that you want to connect to
- * '/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *'. It would generate
- * the following call traces:
- *
- * \code
- * TraceRoot::Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- * traceContext = TraceContext ();
- * rootResolver = CompositeTraceResolver (traceContext);
- * rootResolver->Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- * resolver = CompositeTraceResolver::DoLookup ("nodes");
- * return NodeList::CreateTraceResolver (GetContext ());
- * return ArrayTraceResolver (context);
- * resolver->Connect ("/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- * ArrayTraceResolver::DoLookup ("*");
- * for (i = 0; i < n_nodes; i++)
- * resolver = nodes[i]->CreateTraceResolver (GetContext ());
- * return CompositeTraceResolver (context);
- * resolvers.add (resolver);
- * return resolvers;
- * for resolver in (resolvers)
- * resolver->Connect ("/ipv4/interfaces/ * /netdevice/queue/ *", callback);
- * CompositeTraceResolver::DoLookup ("ipv4");
- * resolver = ipv4->CreateTraceResolver (GetContext ());
- * return CompositeTraceResolver (context);
- * return resolver;
- * resolver->Connect ("/interfaces/ * /netdevice/queue/ *", callback);
- * CompositeTraceResolver::DoLookup ("interfaces");
- * resolver = ArrayTraceResolver (GetContext ());
- * resolver->Connect ("/ * /netdevice/queue/ *", callback);
- * ArrayTraceResolver::DoLookup ("*");
- * for (i = 0; i < n_interfaces; i++)
- * resolver = interfaces[i]->CreateTraceResolver (GetContext ());
- * return CompositeTraceResolver ()
- * resolvers.add (resolver);
- * return resolvers;
- * resolver->Connect ("/netdevice/queue/ *", callback);
- * CompositeTraceResolver::DoLookup ("netdevice");
- * resolver = NetDevice::CreateTraceResolver (GetContext ());
- * return CompositeTraceResolver ();
- * return resolver;
- * resolver->Connect ("/queue/ *", callback);
- * CompositeTraceResolver::DoLookup ("queue");
- * resolver = Queue::CreateTraceResolver (GetContext ());
- * return CompositeTraceResolver ();
- * return resolver
- * resolver->Connect ("*", callback);
- * CompositeTraceResolver::DoLookup ("*");
- * for match in (matches)
- * resolver = TerminalTraceResolver ("match");
- * resolvers.add (resolver)
- * return resolvers;
- * for resolver in (resolvers)
- * TerminalTraceResolver->DoConnect (callback);
- * \endcode
- */
-
-namespace ns3 {
-
-class CompositeTraceResolver;
-class TraceResolver;
-class TraceContext;
-class CallbackBase;
-
-/**
- * \brief The main class used to access tracing functionality for
- * a user.
- *
- * \ingroup lowleveltracing
- */
-class TraceRoot
-{
-public:
- static void Connect (std::string path, CallbackBase const &cb);
- static void Disconnect (std::string path, CallbackBase const &cb);
- static void Register (std::string name,
- Callback createResolver);
-private:
- static CompositeTraceResolver *GetComposite (void);
-};
-
-}// namespace ns3
-
-#endif /* TRACE_ROOT_H */
diff --git a/src/common/wscript b/src/common/wscript
index c6e9cb45d..2472ecd1e 100644
--- a/src/common/wscript
+++ b/src/common/wscript
@@ -12,14 +12,6 @@ def build(bld):
'tags.cc',
'tag-registry.cc',
'pcap-writer.cc',
- 'variable-tracer-test.cc',
- 'trace-context.cc',
- 'trace-context-element.cc',
- 'trace-resolver.cc',
- 'callback-trace-source.cc',
- 'empty-trace-resolver.cc',
- 'composite-trace-resolver.cc',
- 'trace-root.cc',
'data-rate.cc',
]
@@ -35,18 +27,6 @@ def build(bld):
'packet.h',
'packet-printer.h',
'packet-metadata.h',
- 'uv-trace-source.h',
- 'sv-trace-source.h',
- 'fv-trace-source.h',
'pcap-writer.h',
- 'callback-trace-source.h',
- 'trace-context.h',
- 'trace-context-element.h',
- 'trace-resolver.h',
- 'empty-trace-resolver.h',
- 'composite-trace-resolver.h',
- 'array-trace-resolver.h',
- 'trace-root.h',
- 'terminal-trace-resolver.h',
'data-rate.h',
]
diff --git a/src/core/array-trace-resolver.h b/src/core/array-trace-resolver.h
new file mode 100644
index 000000000..ecbc63d5d
--- /dev/null
+++ b/src/core/array-trace-resolver.h
@@ -0,0 +1,205 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage
+ */
+#ifndef ARRAY_TRACE_RESOLVER_H
+#define ARRAY_TRACE_RESOLVER_H
+
+#include
+#include
+#include "callback.h"
+#include "trace-resolver.h"
+#include "object.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to offer trace resolution for an array of objects.
+ * \ingroup tracing
+ *
+ * \class ArrayTraceResolver
+ *
+ * An ArrayTraceResolver is a resolver which can match any input integer
+ * against an element in an array. The array is accessed using a
+ * pair iterators. Each element of the array is expected
+ * to be a subclass of the Object base class.
+ *
+ * When the Connect method is called, this trace resolver will
+ * automatically store in the TraceContext of each resolved object
+ * its index through an object of type INDEX specified during the
+ * instanciation of the ArrayTraceResolver template.
+ */
+template
+class ArrayTraceResolver : public TraceResolver
+{
+public:
+ ArrayTraceResolver ();
+ ~ArrayTraceResolver ();
+
+ /**
+ * \param begin an iterator which points to the start of the array.
+ * \param end an iterator which points to the end of the array.
+ */
+ template
+ void SetIterators (T begin, T end);
+
+ // inherited from TraceResolver
+ virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+ virtual void Disconnect (std::string path, CallbackBase const &cb);
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection);
+ virtual void TraceAll (std::ostream &os, const TraceContext &context);
+
+private:
+ class IteratorBase
+ {
+ public:
+ virtual ~IteratorBase () {}
+ virtual void Next (void) = 0;
+ virtual bool HasNext (void) = 0;
+ virtual Ptr