src/core/config.cc
changeset 2531 b451b5fc8b57
parent 2504 da3ec9cc3ba3
child 2532 86a40c7cbfe9
     1.1 --- a/src/core/config.cc	Thu Feb 28 04:28:34 2008 +0100
     1.2 +++ b/src/core/config.cc	Sun Mar 02 21:00:37 2008 +0100
     1.3 @@ -109,7 +109,7 @@
     1.4    void DoArrayResolve (std::string path, const ObjectVector &vector);
     1.5    void DoResolveOne (Ptr<Object> object, std::string name);
     1.6    std::string GetResolvedPath (std::string name) const;
     1.7 -  virtual void DoOne (Ptr<Object> object, std::string name) = 0;
     1.8 +  virtual void DoOne (Ptr<Object> object, std::string path, std::string name) = 0;
     1.9    std::vector<std::string> m_workStack;
    1.10    std::string m_path;
    1.11  };
    1.12 @@ -142,7 +142,7 @@
    1.13  Resolver::DoResolveOne (Ptr<Object> object, std::string name)
    1.14  {
    1.15    NS_LOG_DEBUG ("resolved="<<GetResolvedPath (name));
    1.16 -  DoOne (object, name);
    1.17 +  DoOne (object, GetResolvedPath (name), name);
    1.18  }
    1.19  
    1.20  void
    1.21 @@ -160,7 +160,7 @@
    1.22      {
    1.23        std::string attributeName = path.substr (1, path.size ()-1);
    1.24        NS_LOG_DEBUG ("handle attr="<<attributeName);
    1.25 -      DoOne (root, attributeName);
    1.26 +      DoOne (root, GetResolvedPath (attributeName), attributeName);
    1.27        return;
    1.28      }
    1.29    std::string item = path.substr (1, next-1);
    1.30 @@ -267,6 +267,7 @@
    1.31  public:
    1.32    void Set (std::string path, Attribute value);
    1.33    void Connect (std::string path, const CallbackBase &cb);
    1.34 +  void ConnectWithContext (std::string path, const CallbackBase &cb);
    1.35    void Disconnect (std::string path, const CallbackBase &cb);
    1.36  
    1.37    void RegisterRootNamespaceObject (Ptr<Object> obj);
    1.38 @@ -287,7 +288,7 @@
    1.39        : Resolver (path),
    1.40  	m_value (value) {}
    1.41    private:
    1.42 -    virtual void DoOne (Ptr<Object> object, std::string name) {
    1.43 +    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
    1.44        object->SetAttribute (name, m_value);
    1.45      }
    1.46      Attribute m_value;
    1.47 @@ -307,7 +308,7 @@
    1.48        : Resolver (path),
    1.49  	m_cb (cb) {}
    1.50    private:
    1.51 -    virtual void DoOne (Ptr<Object> object, std::string name) {
    1.52 +    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
    1.53        object->TraceSourceConnect (name, m_cb);
    1.54      }
    1.55      CallbackBase m_cb;
    1.56 @@ -327,7 +328,7 @@
    1.57        : Resolver (path),
    1.58  	m_cb (cb) {}
    1.59    private:
    1.60 -    virtual void DoOne (Ptr<Object> object, std::string name) {
    1.61 +    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
    1.62        object->TraceSourceDisconnect (name, m_cb);
    1.63      }
    1.64      CallbackBase m_cb;
    1.65 @@ -338,6 +339,26 @@
    1.66      }
    1.67  }
    1.68  void 
    1.69 +ConfigImpl::ConnectWithContext (std::string path, const CallbackBase &cb)
    1.70 +{
    1.71 +  class ConnectWithContextResolver : public Resolver 
    1.72 +  {
    1.73 +  public:
    1.74 +    ConnectWithContextResolver (std::string path, const CallbackBase &cb)
    1.75 +      : Resolver (path),
    1.76 +	m_cb (cb) {}
    1.77 +  private:
    1.78 +    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
    1.79 +      object->TraceSourceConnectWithContext (name, path, m_cb);
    1.80 +    }
    1.81 +    CallbackBase m_cb;
    1.82 +  } resolver = ConnectWithContextResolver (path, cb);
    1.83 +  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
    1.84 +    {
    1.85 +      resolver.Resolve (*i);
    1.86 +    }
    1.87 +}
    1.88 +void 
    1.89  ConfigImpl::RegisterRootNamespaceObject (Ptr<Object> obj)
    1.90  {
    1.91    m_roots.push_back (obj);
    1.92 @@ -379,6 +400,11 @@
    1.93  {
    1.94    Singleton<ConfigImpl>::Get ()->Disconnect (path, cb);
    1.95  }
    1.96 +void 
    1.97 +ConnectWithContext (std::string path, const CallbackBase &cb)
    1.98 +{
    1.99 +  Singleton<ConfigImpl>::Get ()->ConnectWithContext (path, cb);
   1.100 +}
   1.101  
   1.102  void RegisterRootNamespaceObject (Ptr<Object> obj)
   1.103  {
   1.104 @@ -505,7 +531,9 @@
   1.105    virtual bool RunTests (void);
   1.106  private:
   1.107    void ChangeNotification (int16_t old, int16_t newValue);
   1.108 +  void ChangeNotificationWithPath (std::string path, int16_t old, int16_t newValue);
   1.109    int16_t m_traceNotification;
   1.110 +  std::string m_tracePath;
   1.111  };
   1.112  
   1.113  static ConfigTest g_configTestUnique;
   1.114 @@ -520,6 +548,13 @@
   1.115    m_traceNotification = newValue;
   1.116  }
   1.117  
   1.118 +void 
   1.119 +ConfigTest::ChangeNotificationWithPath (std::string path, int16_t old, int16_t newValue)
   1.120 +{
   1.121 +  m_traceNotification = newValue;
   1.122 +  m_tracePath = path;
   1.123 +}
   1.124 +
   1.125  bool
   1.126  ConfigTest::RunTests (void)
   1.127  {
   1.128 @@ -639,6 +674,34 @@
   1.129    d1->SetAttribute ("Source", Integer (-4));
   1.130    NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
   1.131  
   1.132 +  
   1.133 +  Config::ConnectWithContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
   1.134 +			      MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
   1.135 +  m_traceNotification = 0;
   1.136 +  // this should trigger no notification
   1.137 +  d2->SetAttribute ("Source", Integer (-2));
   1.138 +  NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
   1.139 +  m_traceNotification = 0;
   1.140 +  m_tracePath = "";
   1.141 +  // this should trigger a notification
   1.142 +  d1->SetAttribute ("Source", Integer (-3));
   1.143 +  NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   1.144 +  NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/1/Source")
   1.145 +  m_traceNotification = 0;
   1.146 +  m_tracePath = "";
   1.147 +  // this should trigger a notification
   1.148 +  d3->SetAttribute ("Source", Integer (-3));
   1.149 +  NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   1.150 +  NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/3/Source");
   1.151 +  // Yes, disconnection _cannot_ work with 'context-based connection.
   1.152 +  // XXX: what do we do about this ?
   1.153 +  Config::Disconnect ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
   1.154 +		      MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
   1.155 +  m_traceNotification = 0;
   1.156 +  // this should _not_ trigger a notification
   1.157 +  d1->SetAttribute ("Source", Integer (-4));
   1.158 +  NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
   1.159 +
   1.160  
   1.161  
   1.162    return result;