doc/manual/attributes.texi
changeset 5431 01a657b8d1ef
parent 4755 04a9a7e9a624
--- a/doc/manual/attributes.texi	Sat Oct 17 16:02:25 2009 -0700
+++ b/doc/manual/attributes.texi	Sun Oct 18 22:11:29 2009 -0700
@@ -125,7 +125,8 @@
 
 This is defined in the node.cc file as follows:
 
-@verbatim
+@smallformat
+@example
 TypeId 
 Node::GetTypeId (void)
 {
@@ -148,15 +149,16 @@
     ;
   return tid;
 }
-@end verbatim
+@end example
+@end smallformat
 
-Look at the TypeId of an ns-3 @code{Object} class as an extended form of run 
-time type information (RTTI).  The C++ language includes simple kind of RTTI
+Consider the TypeId of an ns-3 @code{Object} class as an extended form of run 
+time type information (RTTI).  The C++ language includes a simple kind of RTTI
 in order to support @code{dynamic_cast} and @code{typeid} operators.
 
 The ``@code{.SetParent<Object> ()}'' call in the declaration above is used in 
 conjunction with our object aggregation mechanisms to allow safe up- and
-down-casing in inheritance trees during @code{GetObject}.
+down-casting in inheritance trees during @code{GetObject}.
 
 The ``@code{.AddConstructor<Node> ()}'' call is used in conjunction with our
 abstract object factory mechanisms to allow us to construct C++ objects without
@@ -183,7 +185,7 @@
 @verbatim
   ObjectFactory factory;
   const std::string typeId = "ns3::Node'';
-  factory.SetTypeId(typeId);
+  factory.SetTypeId (typeId);
   Ptr<Object> node = factory.Create <Object> ();
 @end verbatim
 
@@ -259,7 +261,8 @@
 In the ns-3 attribute system, these value definitions and accessor
 functions are moved into the TypeId class; e.g.:  
 
-@verbatim
+@smallformat
+@example
 NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
 
 TypeId DropTailQueue::GetTypeId (void) 
@@ -276,7 +279,8 @@
   
   return tid;
 }
-@end verbatim
+@end example
+@end smallformat
 
 The AddAttribute() method is performing a number of things with this
 value:
@@ -295,11 +299,19 @@
 may manipulate these values.
 
 Note that initialization of the attribute relies on the macro
-NS_OBJECT_ENSURE_REGISTERED (DropTailQueue) being called; if you leave
+@code{NS_OBJECT_ENSURE_REGISTERED} (DropTailQueue) being called; if you leave
 this out of your new class implementation, your attributes will not be 
 initialized correctly.
 
-@subsection Basic usage
+While we have described how to create attributes, we still haven't
+described how to access and manage these values.  For instance, there is no 
+@code{globals.h} header file where these are stored; attributes are
+stored with their classes.  Questions that naturally arise are how
+do users easily learn about all of the attributes of their models, and
+how does a user access these attributes, or document their values 
+as part of the record of their simulation?
+
+@subsection Default values and command-line arguments
 
 Let's look at how a user script might access these values.  
 This is based on the script found at @code{samples/main-attribute-value.cc},
@@ -341,7 +353,8 @@
 our newly created queues will not have a m_maxPackets initialized to
 100 packets but to 80 packets, because of what we did above with
 default values.
-@verbatim
+@smallformat
+@example
   Ptr<Node> n0 = CreateObject<Node> ();
 
   Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
@@ -349,7 +362,8 @@
 
   Ptr<Queue> q = CreateObject<DropTailQueue> ();
   net0->AddQueue(q);
-@end verbatim
+@end example
+@end smallformat
 
 At this point, we have created a single node (Node 0) and a 
 single PointToPointNetDevice (NetDevice 0) and added a 
@@ -358,10 +372,10 @@
 Now, we can manipulate the MaxPackets value of the already 
 instantiated DropTailQueue.  Here are various ways to do that.
 
-@subsubsection Pointer-based access
+@subsection Pointer-based access
 
 We assume that a smart pointer (Ptr) to a relevant network device is 
-in hand; here, it is the net0 pointer. 
+in hand; in the current example, it is the @code{net0} pointer. 
 
 One way to change the value is to access a pointer to the
 underlying queue and modify its attribute.
@@ -369,11 +383,11 @@
 First, we observe that we can get a pointer to the (base class)
 queue via the PointToPointNetDevice attributes, where it is called
 TxQueue 
-@verbatim
+@example
   PointerValue tmp;
   net0->GetAttribute ("TxQueue", tmp);
   Ptr<Object> txQueue = tmp.GetObject ();
-@end verbatim
+@end example
 
 Using the GetObject function, we can perform a safe downcast
 to a DropTailQueue, where MaxPackets is a member
@@ -409,44 +423,52 @@
   NS_LOG_INFO ("3.  txQueue limit changed: " << limit.Get () << " packets");
 @end verbatim
 
-@subsubsection Namespace-based access
+@subsection Namespace-based access
 
 An alternative way to get at the attribute is to use the configuration namespace.
 Here, this attribute resides on a known path in this namespace; this approach
 is useful if one doesn't have access to the underlying pointers and would like
 to configure a specific attribute with a single statement.  
 
-@verbatim
+@smallformat
+@example
   Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
   txQueue->GetAttribute ("MaxPackets", limit); 
   NS_LOG_INFO ("4.  txQueue limit changed through namespace: " << 
     limit.Get () << " packets");
-@end verbatim
+@end example
+@end smallformat
 
 We could have also used wildcards to set this value for all nodes and all net 
 devices (which in this simple example has the same effect as the previous Set())
-@verbatim
+@smallformat
+@example
   Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
   txQueue->GetAttribute ("MaxPackets", limit); 
   NS_LOG_INFO ("5.  txQueue limit changed through wildcarded namespace: " << 
     limit.Get () << " packets");
-@end verbatim
+@end example
+@end smallformat
 
-@subsubsection Object Name Service-based access
+@subsection Object Name Service-based access
 
 Another way to get at the attribute is to use the object name service facility.
 Here, this attribute is found using a name string.  This approach is useful if 
 one doesn't have access to the underlying pointers and it is difficult to 
 determine the required concrete configuration namespaced path.
 
-@verbatim
+@smallformat
+@example
   Names::Add ("server", serverNode);
   Names::Add ("server/eth0", serverDevice);
 
   ...
 
   Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
-@end verbatim
+@end example
+@end smallformat
+
+@xref{Object names} for a fuller treatment of the ns-3 configuration namespace.
 
 @subsection Setting through constructors helper classes
 
@@ -466,7 +488,8 @@
                                  "LayoutType", StringValue ("RowFirst"));
 @end verbatim
 
-@subsection Value classes
+@subsection Implementation details
+@subsubsection Value classes
 Readers will note the new FooValue classes which are subclasses of the
 AttributeValue base class.  These can be thought of as
 an intermediate class that can be used to convert from raw types to the
@@ -489,14 +512,14 @@
 @item ATTRIBUTE_HELPER_CPP
 @end itemize
 
-@subsection Initialization order
+@subsubsection Initialization order
 
 In general, the attribute code to assign values to the underlying
 class member variables is executed after an object is constructed.
 But what if you need the values assigned before the constructor
 body executes, because you need them in the logic of the constructor?
 There is a way to do this, used for example in the class 
-@code{ns3::ConfigStore}:  call @code{ObjectBase::ConstructSelf()}
+@code{ns3::ConfigStore}:  call @code{ObjectBase::ConstructSelf ()}
 as follows:
 
 @verbatim
@@ -546,7 +569,8 @@
 ns-3; what additional things must be done to hook it into this system.
 
 We've already introduced what a TypeId definition looks like:
-@verbatim
+@smallformat
+@example
 TypeId
 RandomWalk2dMobilityModel::GetTypeId (void)
 {
@@ -568,7 +592,8 @@
     ;
   return tid;
 }
-@end verbatim
+@end example
+@end smallformat
 
 The declaration for this in the class declaration is one-line public
 member method:
@@ -599,7 +624,9 @@
 copy/pasted with macro-ized code.  For instance, consider class
 declaration for Rectangle in the @code{src/mobility/} directory:
 
-@verbatim
+@subsection Header file
+@smallformat
+@example
 /**
  * \brief a 2d rectangle
  */
@@ -612,35 +639,42 @@
   double yMin;
   double yMax;
 };
-@end verbatim
+@end example
+@end smallformat
  
 One macro call and two operators, must be added below the class declaration
 in order to turn a Rectangle into a value usable by the @code{Attribute}
 system:
 
-@verbatim
+@smallformat
+@example
 std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
 std::istream &operator >> (std::istream &is, Rectangle &rectangle);
 
 ATTRIBUTE_HELPER_HEADER (Rectangle);
-@end verbatim
+@end example
+@end smallformat
 
+@subsection Implementation file
 In the class definition (@code{.cc} file), the code looks like this:
 
-@verbatim
+@smallformat
+@example
 ATTRIBUTE_HELPER_CPP (Rectangle);
 
 std::ostream &
 operator << (std::ostream &os, const Rectangle &rectangle)
 {
-  os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
+  os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|"
+     << rectangle.yMax;
   return os;
 }
 std::istream &
 operator >> (std::istream &is, Rectangle &rectangle)
  {
   char c1, c2, c3;
-  is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
+  is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 
+     >> rectangle.yMax;
   if (c1 != '|' ||
       c2 != '|' ||
       c3 != '|')
@@ -649,7 +683,8 @@
     }
   return is;
 }
-@end verbatim
+@end example
+@end smallformat
 
 These stream operators simply convert from a string representation of the
 Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
@@ -679,7 +714,8 @@
 Let's edit it to add the ConfigStore feature.  First, add an include statement 
 to include the contrib module, and then add these lines:
 
-@verbatim
+@smallformat
+@example
 #include "contrib-module.h"
 ...
 int main (...)
@@ -693,7 +729,8 @@
 
   Simulator::Run ();
 }
-@end verbatim
+@end example
+@end smallformat
 
 There are three attributes that govern the behavior of the ConfigStore:
 "Mode", "Filename", and "FileFormat".  The Mode (default "None") configures
@@ -705,12 +742,16 @@
 
 So, using the above modified program, try executing the following
 waf command and 
-@verbatim
-./waf --command-template="%s --ns3::ConfigStore::Filename=csma-bridge-config.xml --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=Xml" --run scratch/csma-bridge
-@end verbatim
+@smallformat
+@example
+./waf --command-template="%s --ns3::ConfigStore::Filename=csma-bridge-config.xml
+--ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=Xml" --run scratch/csma-bridge
+@end example
+@end smallformat
 After running, you can open the csma-bridge-config.xml file and it will
 display the configuration that was applied to your simulation; e.g.
-@verbatim
+@smallformat
+@example
 <?xml version="1.0" encoding="UTF-8"?>
 <ns3>
  <default name="ns3::V4Ping::Remote" value="102.102.102.102"/>
@@ -723,7 +764,9 @@
  <default name="ns3::QstaWifiMac::MaxMissedBeacons" value="10"/>
  <default name="ns3::QstaWifiMac::ActiveProbing" value="false"/>
 ...
-@end verbatim
+@end example
+@end smallformat
+
 This file can be archived with your simulation script and output data.
 
 While it is possible to generate a sample config file and lightly
@@ -749,7 +792,8 @@
 input xml file to begin with, it is sometimes helpful to run the
 program to generate an output xml file first, then hand-edit that
 file and re-input it for the next simulation run).
-@verbatim
+@smallformat
+@example
 #include "contrib-module.h"
 ...
 int main (...)
@@ -778,7 +822,8 @@
   outputConfig.ConfigureAttributes ();
   Simulator::Run ();
 }
-@end verbatim
+@end example
+@end smallformat
 
 @subsection GTK-based ConfigStore
 
@@ -794,24 +839,28 @@
 @end verbatim
 To check whether it is configured or not, check the output of the
 ./waf configure step:
-@verbatim
+@smallformat
+@example
 ---- Summary of optional NS-3 features:
 Threading Primitives          : enabled
 Real Time Simulator           : enabled
 GtkConfigStore                : not enabled (library 'gtk+-2.0 >= 2.12' not found)
-@end verbatim
+@end example
+@end smallformat
 
 In the above example, it was not enabled, so it cannot be used until a
 suitable version is installed and ./waf configure; ./waf is rerun.
 
 Usage is almost the same as the non-GTK-based version, but there
 are no ConfigStore attributes involved:
-@verbatim
+@smallformat
+@example
   // Invoke just before entering Simulator::Run ()
   GtkConfigStore config;
   config.ConfigureDefaults ();
   config.ConfigureAttributes ();
-@end verbatim
+@end example
+@end smallformat
 
 Now, when you run the script, a GUI should pop up, allowing you to open
 menus of attributes on different nodes/objects, and then launch the