merge
This commit is contained in:
61
samples/main-random-walk.cc
Normal file
61
samples/main-random-walk.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/mobility-model-notifier.h"
|
||||
#include "ns3/random-topology.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/node-list.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static void
|
||||
CourseChange (ns3::TraceContext const&, Ptr<const MobilityModel> mobility)
|
||||
{
|
||||
Position pos = mobility->Get ();
|
||||
Speed vel = mobility->GetSpeed ();
|
||||
std::cout << Simulator::Now () << ", model=" << mobility << ", POS: x=" << pos.x << ", y=" << pos.y
|
||||
<< ", z=" << pos.z << "; VEL:" << vel.dx << ", y=" << vel.dy
|
||||
<< ", z=" << vel.dz << std::endl;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
DefaultValue::Bind ("RandomWalk2dMode", "Time");
|
||||
DefaultValue::Bind ("RandomWalk2dTime", "2s");
|
||||
DefaultValue::Bind ("RandomWalk2dSpeed", "Constant:1.0");
|
||||
DefaultValue::Bind ("RandomWalk2dBounds", "0:200:0:100");
|
||||
|
||||
DefaultValue::Bind ("RandomDiscPositionX", "100");
|
||||
DefaultValue::Bind ("RandomDiscPositionY", "50");
|
||||
DefaultValue::Bind ("RandomDiscPositionRho", "Uniform:0:30");
|
||||
|
||||
DefaultValue::Bind ("RandomTopologyPositionType", "RandomDiscPosition");
|
||||
DefaultValue::Bind ("RandomTopologyMobilityType", "RandomWalk2dMobilityModel");
|
||||
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
RandomTopology topology;
|
||||
|
||||
for (uint32_t i = 0; i < 100; i++)
|
||||
{
|
||||
Ptr<Node> node = Create<Node> ();
|
||||
node->AddInterface (Create<MobilityModelNotifier> ());
|
||||
}
|
||||
|
||||
topology.Layout (NodeList::Begin (), NodeList::End ());
|
||||
NodeList::Connect ("/nodes/*/$MobilityModelNotifier/course-change",
|
||||
MakeCallback (&CourseChange));
|
||||
|
||||
Simulator::StopAt (Seconds (100.0));
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -41,3 +41,6 @@ def build(bld):
|
||||
['core', 'simulator', 'mobility'])
|
||||
obj.source = 'main-random-topology.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-random-walk',
|
||||
['core', 'simulator', 'mobility'])
|
||||
obj.source = 'main-random-walk.cc'
|
||||
|
||||
19
src/core/int-to-type.h
Normal file
19
src/core/int-to-type.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef INT_TO_TYPE_H
|
||||
#define INT_TO_TYPE_H
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* This trivial template is extremely useful, as explained in
|
||||
* "Modern C++ Design", p29, section 2.4,
|
||||
* "Mapping Integral Constants to Types"
|
||||
*/
|
||||
template <int v>
|
||||
struct IntToType
|
||||
{
|
||||
enum {value = v};
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* INT_TO_TYPE_H */
|
||||
40
src/core/type-traits-test.cc
Normal file
40
src/core/type-traits-test.cc
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "type-traits.h"
|
||||
#include "test.h"
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TypeTraitsTest : public Test
|
||||
{
|
||||
public:
|
||||
TypeTraitsTest ();
|
||||
virtual bool RunTests (void);
|
||||
};
|
||||
|
||||
TypeTraitsTest::TypeTraitsTest ()
|
||||
: Test ("TypeTraits")
|
||||
{}
|
||||
bool
|
||||
TypeTraitsTest::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
//TypeTraits<int &>::ReferencedType ir;
|
||||
//TypeTraits<const int>::NonConstType uci;
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (void)>::IsPointerToMember, 1);
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (void) const>::IsPointerToMember, 1);
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (int)>::IsPointerToMember, 1);
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (int) const>::IsPointerToMember, 1);
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (void) const>::PointerToMemberTraits::nArgs, 0);
|
||||
NS_TEST_ASSERT_EQUAL (TypeTraits<void (TypeTraitsTest::*) (int) const>::PointerToMemberTraits::nArgs, 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static TypeTraitsTest g_typeTraitsTest;
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
|
||||
@@ -1,25 +1,294 @@
|
||||
#ifndef TYPE_TRAITS_H
|
||||
#define TYPE_TRAITS_H
|
||||
|
||||
template <typename T>
|
||||
struct TypeTraits;
|
||||
|
||||
template <typename T>
|
||||
struct TypeTraits
|
||||
{
|
||||
typedef T ReferencedType;
|
||||
};
|
||||
private:
|
||||
struct NullType {};
|
||||
template <typename U> struct UnConst
|
||||
{
|
||||
typedef U Result;
|
||||
};
|
||||
template <typename U> struct UnConst<const U>
|
||||
{
|
||||
typedef U Result;
|
||||
};
|
||||
template <typename U> struct ReferenceTraits
|
||||
{
|
||||
enum {IsReference = 0};
|
||||
typedef U ReferencedType;
|
||||
};
|
||||
template <typename U> struct ReferenceTraits<U&>
|
||||
{
|
||||
enum {IsReference = 1};
|
||||
typedef U ReferencedType;
|
||||
};
|
||||
template <typename U> struct PointerTraits
|
||||
{
|
||||
enum {IsPointer = 0};
|
||||
typedef U PointeeType;
|
||||
};
|
||||
template <typename U> struct PointerTraits<U *>
|
||||
{
|
||||
enum {IsPointer = 1};
|
||||
typedef U PointeeType;
|
||||
};
|
||||
template <typename U> struct FunctionPtrTraits
|
||||
{
|
||||
enum {IsFunctionPointer = 0};
|
||||
};
|
||||
template <typename U>
|
||||
struct FunctionPtrTraits <U (*) (void)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 0};
|
||||
typedef U ReturnType;
|
||||
};
|
||||
template <typename U, typename V1>
|
||||
struct FunctionPtrTraits <U (*) (V1)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 1};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
};
|
||||
template <typename U, typename V1, typename V2>
|
||||
struct FunctionPtrTraits <U (*) (V1,V2)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 2};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
typedef V2 Arg2Type;
|
||||
};
|
||||
template <typename U, typename V1, typename V2,
|
||||
typename V3>
|
||||
struct FunctionPtrTraits <U (*) (V1,V2,V3)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 3};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
typedef V2 Arg2Type;
|
||||
typedef V3 Arg3Type;
|
||||
};
|
||||
template <typename U, typename V1, typename V2,
|
||||
typename V3, typename V4>
|
||||
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 4};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
typedef V2 Arg2Type;
|
||||
typedef V3 Arg3Type;
|
||||
typedef V4 Arg4Type;
|
||||
};
|
||||
template <typename U, typename V1, typename V2,
|
||||
typename V3, typename V4,
|
||||
typename V5>
|
||||
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 5};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
typedef V2 Arg2Type;
|
||||
typedef V3 Arg3Type;
|
||||
typedef V4 Arg4Type;
|
||||
typedef V5 Arg5Type;
|
||||
};
|
||||
template <typename U, typename V1, typename V2,
|
||||
typename V3, typename V4,
|
||||
typename V5, typename V6>
|
||||
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5,V6)>
|
||||
{
|
||||
enum {IsFunctionPointer = 1};
|
||||
enum {nArgs = 6};
|
||||
typedef U ReturnType;
|
||||
typedef V1 Arg1Type;
|
||||
typedef V2 Arg2Type;
|
||||
typedef V3 Arg3Type;
|
||||
typedef V4 Arg4Type;
|
||||
typedef V5 Arg5Type;
|
||||
typedef V6 Arg6Type;
|
||||
};
|
||||
template <typename U> struct PtrToMemberTraits
|
||||
{
|
||||
enum {IsPointerToMember = 0};
|
||||
};
|
||||
template <typename U, typename V>
|
||||
struct PtrToMemberTraits <U (V::*) (void)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 0};
|
||||
typedef U ReturnType;
|
||||
};
|
||||
template <typename U, typename V>
|
||||
struct PtrToMemberTraits <U (V::*) (void) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 0};
|
||||
typedef U ReturnType;
|
||||
};
|
||||
template <typename U, typename V,typename W1>
|
||||
struct PtrToMemberTraits <U (V::*) (W1)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 1};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
};
|
||||
template <typename U, typename V,typename W1>
|
||||
struct PtrToMemberTraits <U (V::*) (W1) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 1};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
};
|
||||
template <typename U, typename V,typename W1, typename W2>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 2};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
};
|
||||
template <typename U, typename V,typename W1, typename W2>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 2};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 3};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 3};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 4};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 4};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4,
|
||||
typename W5>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 5};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
typedef W5 Arg5Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4,
|
||||
typename W5>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 5};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
typedef W5 Arg5Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4,
|
||||
typename W5, typename W6>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6)>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 6};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
typedef W5 Arg5Type;
|
||||
typedef W6 Arg6Type;
|
||||
};
|
||||
template <typename U, typename V,
|
||||
typename W1, typename W2,
|
||||
typename W3, typename W4,
|
||||
typename W5, typename W6>
|
||||
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6) const>
|
||||
{
|
||||
enum {IsPointerToMember = 1};
|
||||
enum {nArgs = 6};
|
||||
typedef U ReturnType;
|
||||
typedef W1 Arg1Type;
|
||||
typedef W2 Arg2Type;
|
||||
typedef W3 Arg3Type;
|
||||
typedef W4 Arg4Type;
|
||||
typedef W5 Arg5Type;
|
||||
typedef W6 Arg6Type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypeTraits<const T &>
|
||||
{
|
||||
typedef T ReferencedType;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypeTraits<T &>
|
||||
{
|
||||
typedef T ReferencedType;
|
||||
public:
|
||||
typedef typename UnConst<T>::Result NonConstType;
|
||||
typedef typename ReferenceTraits<T>::ReferencedType ReferencedType;
|
||||
typedef typename PointerTraits<T>::PointeeType PointeeType;
|
||||
enum {IsPointerToMember = PtrToMemberTraits<T>::IsPointerToMember};
|
||||
enum {IsPointer = PointerTraits<T>::IsPointer};
|
||||
enum {IsReference = ReferenceTraits<T>::IsReference};
|
||||
enum {IsFunctionPointer = FunctionPtrTraits<T>::IsFunctionPointer};
|
||||
typedef PtrToMemberTraits<T> PointerToMemberTraits;
|
||||
typedef FunctionPtrTraits<T> FunctionPointerTraits;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ def build(bld):
|
||||
'composite-trace-resolver.cc',
|
||||
'trace-doc.cc',
|
||||
'trace-source.cc',
|
||||
'type-traits-test.cc',
|
||||
]
|
||||
|
||||
if sys.platform == 'win32':
|
||||
@@ -94,5 +95,6 @@ def build(bld):
|
||||
'composite-trace-resolver.h',
|
||||
'array-trace-resolver.h',
|
||||
'trace-doc.h',
|
||||
'int-to-type.h',
|
||||
]
|
||||
|
||||
|
||||
145
src/mobility/ns2-mobility-file-topology.cc
Normal file
145
src/mobility/ns2-mobility-file-topology.cc
Normal file
@@ -0,0 +1,145 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node-list.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns2-mobility-file-topology.h"
|
||||
#include "static-speed-mobility-model.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("Ns2MobilityFileTopology");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
Ns2MobilityFileTopology::Ns2MobilityFileTopology (std::string filename)
|
||||
: m_filename (filename)
|
||||
{}
|
||||
|
||||
|
||||
Ptr<StaticSpeedMobilityModel>
|
||||
Ns2MobilityFileTopology::GetMobilityModel (std::string idString, const ObjectStore &store) const
|
||||
{
|
||||
std::istringstream iss;
|
||||
iss.str (idString);
|
||||
uint32_t id;
|
||||
iss >> id;
|
||||
Ptr<Object> object = store.Get (id);
|
||||
if (object == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Ptr<StaticSpeedMobilityModel> model =
|
||||
object->QueryInterface<StaticSpeedMobilityModel> (StaticSpeedMobilityModel::iid);
|
||||
if (model == 0)
|
||||
{
|
||||
model = Create<StaticSpeedMobilityModel> ();
|
||||
object->AddInterface (model);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
double
|
||||
Ns2MobilityFileTopology::ReadDouble (std::string valueString) const
|
||||
{
|
||||
std::istringstream iss;
|
||||
iss.str (valueString);
|
||||
double value;
|
||||
iss >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
Ns2MobilityFileTopology::LayoutObjectStore (const ObjectStore &store) const
|
||||
{
|
||||
std::ifstream file (m_filename.c_str (), std::ios::in);
|
||||
if (file.is_open())
|
||||
{
|
||||
while (!file.eof() )
|
||||
{
|
||||
std::string line;
|
||||
getline (file, line);
|
||||
std::string::size_type startNodeId = line.find_first_of ("(");
|
||||
std::string::size_type endNodeId = line.find_first_of (")");
|
||||
if (startNodeId == std::string::npos ||
|
||||
endNodeId == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Ptr<StaticSpeedMobilityModel> model = GetMobilityModel (line.substr (startNodeId + 1,
|
||||
endNodeId - startNodeId),
|
||||
store);
|
||||
if (model == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (startNodeId == 6)
|
||||
{
|
||||
double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos));
|
||||
std::string coordinate = line.substr (endNodeId + 6, 1);
|
||||
Position position = model->Get ();
|
||||
if (coordinate == "X")
|
||||
{
|
||||
position.x = value;
|
||||
NS_DEBUG ("X=" << value);
|
||||
}
|
||||
else if (coordinate == "Y")
|
||||
{
|
||||
position.y = value;
|
||||
NS_DEBUG ("Y=" << value);
|
||||
}
|
||||
else if (coordinate == "Z")
|
||||
{
|
||||
position.z = value;
|
||||
NS_DEBUG ("Z=" << value);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
model->Set (position);
|
||||
}
|
||||
else
|
||||
{
|
||||
double at = ReadDouble (line.substr (8, startNodeId - 17));
|
||||
std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10);
|
||||
std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1);
|
||||
double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10));
|
||||
double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1));
|
||||
double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos));
|
||||
NS_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed);
|
||||
Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetSpeed, model,
|
||||
Speed (xSpeed, ySpeed, zSpeed));
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ns2MobilityFileTopology::Layout (void) const
|
||||
{
|
||||
Layout (NodeList::Begin (), NodeList::End ());
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
113
src/mobility/ns2-mobility-file-topology.h
Normal file
113
src/mobility/ns2-mobility-file-topology.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef NS2_MOBILITY_FILE_TOPOLOGY_H
|
||||
#define NS2_MOBILITY_FILE_TOPOLOGY_H
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/object.h"
|
||||
#include "static-speed-mobility-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief a topology object which can read ns2's movement files
|
||||
* generated by the CMU setdest tool.
|
||||
*/
|
||||
class Ns2MobilityFileTopology
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \param filename filename of file which contains the
|
||||
* ns2 movement trace.
|
||||
*/
|
||||
Ns2MobilityFileTopology (std::string filename);
|
||||
|
||||
/**
|
||||
* Read the ns2 trace file and configure the movement
|
||||
* patterns of all nodes contained in the global ns3::NodeList
|
||||
* whose nodeId is matches the nodeId of the nodes in the trace
|
||||
* file.
|
||||
*/
|
||||
void Layout (void) const;
|
||||
|
||||
/**
|
||||
* \param begin an iterator which points to the start of the input
|
||||
* object array.
|
||||
* \param end an iterator which points to the end of the input
|
||||
* object array.
|
||||
*
|
||||
* Read the ns2 trace file and configure the movement
|
||||
* patterns of all input objects. Each input object
|
||||
* is identified by a unique node id which reflects
|
||||
* the index of the object in the input array.
|
||||
*/
|
||||
template <typename T>
|
||||
void Layout (T begin, T end) const;
|
||||
private:
|
||||
class ObjectStore
|
||||
{
|
||||
public:
|
||||
virtual ~ObjectStore () {}
|
||||
virtual Ptr<Object> Get (uint32_t i) const = 0;
|
||||
};
|
||||
void LayoutObjectStore (const ObjectStore &store) const;
|
||||
Ptr<StaticSpeedMobilityModel> GetMobilityModel (std::string idString, const ObjectStore &store) const;
|
||||
double ReadDouble (std::string valueString) const;
|
||||
std::string m_filename;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
Ns2MobilityFileTopology::Layout (T begin, T end) const
|
||||
{
|
||||
class MyObjectStore : public ObjectStore
|
||||
{
|
||||
public:
|
||||
MyObjectStore (T begin, T end)
|
||||
: m_begin (begin),
|
||||
m_end (end)
|
||||
{}
|
||||
virtual Ptr<Object> Get (uint32_t i) const {
|
||||
T iterator = m_begin;
|
||||
iterator += i;
|
||||
if (iterator >= m_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return *iterator;
|
||||
}
|
||||
private:
|
||||
T m_begin;
|
||||
T m_end;
|
||||
};
|
||||
LayoutObjectStore (MyObjectStore (begin, end));
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* NS2_MOBILITY_FILE_TOPOLOGY_H */
|
||||
210
src/mobility/random-direction-2d-mobility-model.cc
Normal file
210
src/mobility/random-direction-2d-mobility-model.cc
Normal file
@@ -0,0 +1,210 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "ns3/random-variable-default-value.h"
|
||||
#include "ns3/rectangle-default-value.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "random-direction-2d-mobility-model.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RandomDirection2dMobilityModel");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
const double RandomDirection2dMobilityModel::PI = 3.14159265358979323846;
|
||||
const ClassId RandomDirection2dMobilityModel::cid =
|
||||
MakeClassId<RandomDirection2dMobilityModel> ("RandomDirection2dMobilityModel",
|
||||
MobilityModel::iid);
|
||||
|
||||
|
||||
static RandomVariableDefaultValue
|
||||
g_speedVariable ("RandomDirection2dSpeed",
|
||||
"A random variable to control the speed of a RandomDirection2d mobility model.",
|
||||
"Uniform:1:2");
|
||||
|
||||
static RandomVariableDefaultValue
|
||||
g_pauseVariable ("RandomDirection2dPause",
|
||||
"A random variable to control the duration "
|
||||
"of the pause of a RandomDiretion mobility model.",
|
||||
"Constant:2");
|
||||
|
||||
static RectangleDefaultValue
|
||||
g_bounds ("RandomDirection2dArea",
|
||||
"The bounding area for the RandomDirection2d model.",
|
||||
-100, 100, -100, 100);
|
||||
|
||||
|
||||
RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters ()
|
||||
: m_bounds (g_bounds.GetValue ()),
|
||||
m_speedVariable (g_speedVariable.GetCopy ()),
|
||||
m_pauseVariable (g_pauseVariable.GetCopy ())
|
||||
|
||||
{}
|
||||
RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters
|
||||
(const Rectangle &bounds,
|
||||
const RandomVariable &speedVariable,
|
||||
const RandomVariable &pauseVariable)
|
||||
: m_bounds (bounds),
|
||||
m_speedVariable (speedVariable.Copy ()),
|
||||
m_pauseVariable (pauseVariable.Copy ())
|
||||
{}
|
||||
|
||||
RandomDirection2dMobilityModelParameters::~RandomDirection2dMobilityModelParameters ()
|
||||
{
|
||||
delete m_speedVariable;
|
||||
delete m_pauseVariable;
|
||||
m_speedVariable = 0;
|
||||
m_pauseVariable = 0;
|
||||
}
|
||||
|
||||
void
|
||||
RandomDirection2dMobilityModelParameters::SetSpeed (const RandomVariable &speedVariable)
|
||||
{
|
||||
delete m_speedVariable;
|
||||
m_speedVariable = speedVariable.Copy ();
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModelParameters::SetPause (const RandomVariable &pauseVariable)
|
||||
{
|
||||
delete m_pauseVariable;
|
||||
m_pauseVariable = pauseVariable.Copy ();
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModelParameters::SetBounds (const Rectangle &bounds)
|
||||
{
|
||||
m_bounds = bounds;
|
||||
}
|
||||
|
||||
Ptr<RandomDirection2dMobilityModelParameters>
|
||||
RandomDirection2dMobilityModelParameters::GetCurrent (void)
|
||||
{
|
||||
static Ptr<RandomDirection2dMobilityModelParameters> parameters = 0;
|
||||
if (parameters == 0 ||
|
||||
g_bounds.IsDirty () ||
|
||||
g_speedVariable.IsDirty () ||
|
||||
g_pauseVariable.IsDirty ())
|
||||
{
|
||||
parameters = Create<RandomDirection2dMobilityModelParameters> ();
|
||||
g_bounds.ClearDirtyFlag ();
|
||||
g_speedVariable.ClearDirtyFlag ();
|
||||
g_pauseVariable.ClearDirtyFlag ();
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
RandomDirection2dMobilityModel::RandomDirection2dMobilityModel ()
|
||||
: m_parameters (RandomDirection2dMobilityModelParameters::GetCurrent ())
|
||||
{
|
||||
SetInterfaceId (RandomDirection2dMobilityModel::iid);
|
||||
m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
|
||||
}
|
||||
RandomDirection2dMobilityModel::RandomDirection2dMobilityModel
|
||||
(Ptr<RandomDirection2dMobilityModelParameters> parameters)
|
||||
: m_parameters (parameters)
|
||||
{
|
||||
SetInterfaceId (RandomDirection2dMobilityModel::iid);
|
||||
m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModel::DoDispose (void)
|
||||
{
|
||||
m_parameters = 0;
|
||||
// chain up.
|
||||
MobilityModel::DoDispose ();
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModel::Start (void)
|
||||
{
|
||||
double direction = UniformVariable::GetSingleValue (0, 2 * PI);
|
||||
SetDirectionAndSpeed (direction);
|
||||
}
|
||||
|
||||
void
|
||||
RandomDirection2dMobilityModel::BeginPause (void)
|
||||
{
|
||||
Time pause = Seconds (m_parameters->m_pauseVariable->GetValue ());
|
||||
m_helper.Pause ();
|
||||
m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this);
|
||||
NotifyCourseChange ();
|
||||
}
|
||||
|
||||
void
|
||||
RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
double speed = m_parameters->m_speedVariable->GetValue ();
|
||||
const Speed vector (std::cos (direction) * speed,
|
||||
std::sin (direction) * speed,
|
||||
0.0);
|
||||
Position position = m_helper.GetCurrentPosition (m_parameters->m_bounds);
|
||||
m_helper.Reset (vector);
|
||||
Position next = m_parameters->m_bounds.CalculateIntersection (position, vector);
|
||||
Time delay = Seconds (CalculateDistance (position, next) / speed);
|
||||
m_event = Simulator::Schedule (delay,
|
||||
&RandomDirection2dMobilityModel::BeginPause, this);
|
||||
NotifyCourseChange ();
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModel::ResetDirectionAndSpeed (void)
|
||||
{
|
||||
double direction = UniformVariable::GetSingleValue (0, PI);
|
||||
|
||||
Position position = m_helper.GetCurrentPosition (m_parameters->m_bounds);
|
||||
switch (m_parameters->m_bounds.GetClosestSide (position))
|
||||
{
|
||||
case Rectangle::RIGHT:
|
||||
direction += PI / 2;
|
||||
break;
|
||||
case Rectangle::LEFT:
|
||||
direction += - PI / 2;
|
||||
break;
|
||||
case Rectangle::TOP:
|
||||
direction += PI;
|
||||
break;
|
||||
case Rectangle::BOTTOM:
|
||||
direction += 0.0;
|
||||
break;
|
||||
}
|
||||
SetDirectionAndSpeed (direction);
|
||||
}
|
||||
Position
|
||||
RandomDirection2dMobilityModel::DoGet (void) const
|
||||
{
|
||||
return m_helper.GetCurrentPosition (m_parameters->m_bounds);
|
||||
}
|
||||
void
|
||||
RandomDirection2dMobilityModel::DoSet (const Position &position)
|
||||
{
|
||||
m_helper.InitializePosition (position);
|
||||
Simulator::Remove (m_event);
|
||||
m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
|
||||
}
|
||||
Speed
|
||||
RandomDirection2dMobilityModel::DoGetSpeed (void) const
|
||||
{
|
||||
return m_helper.GetSpeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
121
src/mobility/random-direction-2d-mobility-model.h
Normal file
121
src/mobility/random-direction-2d-mobility-model.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef RANDOM_DIRECTION_MOBILITY_MODEL_H
|
||||
#define RANDOM_DIRECTION_MOBILITY_MODEL_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/component-manager.h"
|
||||
#include "ns3/rectangle.h"
|
||||
#include "mobility-model.h"
|
||||
#include "static-speed-helper.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class RandomVariable;
|
||||
|
||||
/**
|
||||
* \brief the parameters to control a RandomDirection mobility model.
|
||||
*/
|
||||
class RandomDirection2dMobilityModelParameters : public Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a default parameter object from Bind default values.
|
||||
*/
|
||||
RandomDirection2dMobilityModelParameters ();
|
||||
/**
|
||||
* \param bounds the 2d bounds of the mobility model
|
||||
* \param speedVariable the random variable used to pick a random speed
|
||||
* \param pauseVariable the random variable used to pick a random pause delay
|
||||
*/
|
||||
RandomDirection2dMobilityModelParameters (const Rectangle &bounds,
|
||||
const RandomVariable &speedVariable,
|
||||
const RandomVariable &pauseVariable);
|
||||
virtual ~RandomDirection2dMobilityModelParameters ();
|
||||
|
||||
/**
|
||||
* \param speedVariable the random variable used to pick a random speed.
|
||||
*/
|
||||
void SetSpeed (const RandomVariable &speedVariable);
|
||||
/**
|
||||
* \param pauseVariable the random variable used to pick a random pause delay.
|
||||
*/
|
||||
void SetPause (const RandomVariable &pauseVariable);
|
||||
/**
|
||||
* \param bounds the 2d bounds of the mobility model.
|
||||
*/
|
||||
void SetBounds (const Rectangle &bounds);
|
||||
private:
|
||||
friend class RandomDirection2dMobilityModel;
|
||||
|
||||
static Ptr<RandomDirection2dMobilityModelParameters> GetCurrent (void);
|
||||
|
||||
Rectangle m_bounds;
|
||||
RandomVariable *m_speedVariable;
|
||||
RandomVariable *m_pauseVariable;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief a RandomDirection mobility model
|
||||
*
|
||||
* The movement of objects is based on random directions: each object
|
||||
* pauses for a specific delay, chooses a random direction and speed and
|
||||
* then travels in the specific direction until it reaches one of
|
||||
* the boundaries of the model. When it reaches the boundary, it pauses,
|
||||
* selects a new direction and speed, aso.
|
||||
*/
|
||||
class RandomDirection2dMobilityModel : public MobilityModel
|
||||
{
|
||||
public:
|
||||
static const ClassId cid;
|
||||
|
||||
/**
|
||||
* Create a RandomDirection model from the default Bind values.
|
||||
*/
|
||||
RandomDirection2dMobilityModel ();
|
||||
/**
|
||||
* \param parameters the parameters which control the behavior of the model.
|
||||
* Create a RandomDirection model using the parameters specified.
|
||||
*/
|
||||
RandomDirection2dMobilityModel (Ptr<RandomDirection2dMobilityModelParameters> parameters);
|
||||
private:
|
||||
void Start (void);
|
||||
void ResetDirectionAndSpeed (void);
|
||||
void BeginPause (void);
|
||||
void SetDirectionAndSpeed (double direction);
|
||||
void InitializeDirectionAndSpeed (void);
|
||||
virtual void DoDispose (void);
|
||||
virtual Position DoGet (void) const;
|
||||
virtual void DoSet (const Position &position);
|
||||
virtual Speed DoGetSpeed (void) const;
|
||||
|
||||
static const double PI;
|
||||
Ptr<RandomDirection2dMobilityModelParameters> m_parameters;
|
||||
EventId m_event;
|
||||
StaticSpeedHelper m_helper;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RANDOM_DIRECTION_MOBILITY_MODEL_H */
|
||||
233
src/mobility/random-walk-2d-mobility-model.cc
Normal file
233
src/mobility/random-walk-2d-mobility-model.cc
Normal file
@@ -0,0 +1,233 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "random-walk-2d-mobility-model.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/time-default-value.h"
|
||||
#include "ns3/rectangle-default-value.h"
|
||||
#include "ns3/random-variable-default-value.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/debug.h"
|
||||
#include <cmath>
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("RandomWalk2d");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
const ClassId RandomWalk2dMobilityModel::cid =
|
||||
MakeClassId<RandomWalk2dMobilityModel> ("RandomWalk2dMobilityModel", RandomWalk2dMobilityModel::iid);
|
||||
|
||||
|
||||
static EnumDefaultValue<RandomWalk2dMobilityModelParameters::Mode>
|
||||
g_mode ("RandomWalk2dMode",
|
||||
"The mode indicates the condition used to "
|
||||
"change the current speed and direction",
|
||||
RandomWalk2dMobilityModelParameters::MODE_DISTANCE, "Distance",
|
||||
RandomWalk2dMobilityModelParameters::MODE_TIME, "Time",
|
||||
0, (void*)0);
|
||||
|
||||
static NumericDefaultValue<double>
|
||||
g_modeDistance ("RandomWalk2dDistance",
|
||||
"Change current direction and speed after moving this distance.",
|
||||
2.0);
|
||||
|
||||
static TimeDefaultValue
|
||||
g_modeTime ("RandomWalk2dTime",
|
||||
"Change current direction and speed after moving for this delay.",
|
||||
Seconds (1.0));
|
||||
|
||||
static RandomVariableDefaultValue
|
||||
g_speed ("RandomWalk2dSpeed",
|
||||
"A random variable used to pick the speed.",
|
||||
"Uniform:2:4");
|
||||
static RandomVariableDefaultValue
|
||||
g_direction ("RandomWalk2dDirection",
|
||||
"A random variable used to pick the direction (gradients).",
|
||||
"Uniform:0.0:6.283184");
|
||||
|
||||
static RectangleDefaultValue
|
||||
g_rectangle ("RandomWalk2dBounds",
|
||||
"Bounds of the area to cruise.",
|
||||
0.0, 0.0, 100.0, 100.0);
|
||||
|
||||
RandomWalk2dMobilityModelParameters::RandomWalk2dMobilityModelParameters ()
|
||||
: m_mode (g_mode.GetValue ()),
|
||||
m_modeDistance (g_modeDistance.GetValue ()),
|
||||
m_modeTime (g_modeTime.GetValue ()),
|
||||
m_speed (g_speed.GetCopy ()),
|
||||
m_direction (g_direction.GetCopy ()),
|
||||
m_bounds (g_rectangle.GetValue ())
|
||||
{}
|
||||
|
||||
RandomWalk2dMobilityModelParameters::~RandomWalk2dMobilityModelParameters ()
|
||||
{
|
||||
delete m_speed;
|
||||
delete m_direction;
|
||||
m_speed = 0;
|
||||
m_direction = 0;
|
||||
}
|
||||
|
||||
void
|
||||
RandomWalk2dMobilityModelParameters::SetSpeed (const RandomVariable &speed)
|
||||
{
|
||||
delete m_speed;
|
||||
m_speed = speed.Copy ();
|
||||
}
|
||||
void
|
||||
RandomWalk2dMobilityModelParameters::SetDirection (const RandomVariable &direction)
|
||||
{
|
||||
delete m_direction;
|
||||
m_direction = direction.Copy ();
|
||||
}
|
||||
void
|
||||
RandomWalk2dMobilityModelParameters::SetModeDistance (double distance)
|
||||
{
|
||||
m_mode = RandomWalk2dMobilityModelParameters::MODE_DISTANCE;
|
||||
m_modeDistance = distance;
|
||||
}
|
||||
void
|
||||
RandomWalk2dMobilityModelParameters::SetModeTime (Time time)
|
||||
{
|
||||
m_mode = RandomWalk2dMobilityModelParameters::MODE_TIME;
|
||||
m_modeTime = time;
|
||||
}
|
||||
void
|
||||
RandomWalk2dMobilityModelParameters::SetBounds (const Rectangle &bounds)
|
||||
{
|
||||
m_bounds = bounds;
|
||||
}
|
||||
|
||||
Ptr<RandomWalk2dMobilityModelParameters>
|
||||
RandomWalk2dMobilityModelParameters::GetCurrent (void)
|
||||
{
|
||||
static Ptr<RandomWalk2dMobilityModelParameters> parameters = 0;
|
||||
if (parameters == 0 ||
|
||||
g_speed.IsDirty () ||
|
||||
g_direction.IsDirty () ||
|
||||
g_mode.IsDirty () ||
|
||||
g_modeDistance.IsDirty () ||
|
||||
g_modeTime.IsDirty () ||
|
||||
g_rectangle.IsDirty ())
|
||||
{
|
||||
parameters = Create<RandomWalk2dMobilityModelParameters> ();
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
RandomWalk2dMobilityModel::RandomWalk2dMobilityModel ()
|
||||
: m_parameters (RandomWalk2dMobilityModelParameters::GetCurrent ())
|
||||
{
|
||||
SetInterfaceId (RandomWalk2dMobilityModel::iid);
|
||||
m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
|
||||
}
|
||||
|
||||
void
|
||||
RandomWalk2dMobilityModel::Start (void)
|
||||
{
|
||||
double speed = m_parameters->m_speed->GetValue ();
|
||||
double direction = m_parameters->m_direction->GetValue ();
|
||||
Speed vector (std::cos (direction) * speed,
|
||||
std::sin (direction) * speed,
|
||||
0.0);
|
||||
m_helper.Reset (vector);
|
||||
|
||||
Time delayLeft;
|
||||
if (m_parameters->m_mode == RandomWalk2dMobilityModelParameters::MODE_TIME)
|
||||
{
|
||||
delayLeft = m_parameters->m_modeTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
delayLeft = Seconds (m_parameters->m_modeDistance / speed);
|
||||
}
|
||||
DoWalk (delayLeft);
|
||||
}
|
||||
|
||||
void
|
||||
RandomWalk2dMobilityModel::DoWalk (Time delayLeft)
|
||||
{
|
||||
Position position = m_helper.GetCurrentPosition ();
|
||||
Speed speed = m_helper.GetSpeed ();
|
||||
Position nextPosition = position;
|
||||
nextPosition.x += speed.dx * delayLeft.GetSeconds ();
|
||||
nextPosition.y += speed.dy * delayLeft.GetSeconds ();
|
||||
if (m_parameters->m_bounds.IsInside (nextPosition))
|
||||
{
|
||||
m_event = Simulator::Schedule (delayLeft, &RandomWalk2dMobilityModel::Start, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPosition = m_parameters->m_bounds.CalculateIntersection (position, speed);
|
||||
Time delay = Seconds ((nextPosition.x - position.x) / speed.dx);
|
||||
m_event = Simulator::Schedule (delay, &RandomWalk2dMobilityModel::Rebound, this,
|
||||
delayLeft - delay);
|
||||
}
|
||||
NotifyCourseChange ();
|
||||
}
|
||||
|
||||
void
|
||||
RandomWalk2dMobilityModel::Rebound (Time delayLeft)
|
||||
{
|
||||
Position position = m_helper.GetCurrentPosition (m_parameters->m_bounds);
|
||||
Speed speed = m_helper.GetSpeed ();
|
||||
switch (m_parameters->m_bounds.GetClosestSide (position))
|
||||
{
|
||||
case Rectangle::RIGHT:
|
||||
case Rectangle::LEFT:
|
||||
speed.dx = - speed.dx;
|
||||
break;
|
||||
case Rectangle::TOP:
|
||||
case Rectangle::BOTTOM:
|
||||
speed.dy = - speed.dy;
|
||||
break;
|
||||
}
|
||||
m_helper.Reset (speed);
|
||||
DoWalk (delayLeft);
|
||||
}
|
||||
|
||||
void
|
||||
RandomWalk2dMobilityModel::DoDispose (void)
|
||||
{
|
||||
m_parameters = 0;
|
||||
// chain up
|
||||
MobilityModel::DoDispose ();
|
||||
}
|
||||
Position
|
||||
RandomWalk2dMobilityModel::DoGet (void) const
|
||||
{
|
||||
return m_helper.GetCurrentPosition (m_parameters->m_bounds);
|
||||
}
|
||||
void
|
||||
RandomWalk2dMobilityModel::DoSet (const Position &position)
|
||||
{
|
||||
NS_ASSERT (m_parameters->m_bounds.IsInside (position));
|
||||
m_helper.InitializePosition (position);
|
||||
Simulator::Remove (m_event);
|
||||
m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
|
||||
}
|
||||
Speed
|
||||
RandomWalk2dMobilityModel::DoGetSpeed (void) const
|
||||
{
|
||||
return m_helper.GetSpeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
147
src/mobility/random-walk-2d-mobility-model.h
Normal file
147
src/mobility/random-walk-2d-mobility-model.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef RANDOM_WALK_2D_MOBILITY_MODEL_H
|
||||
#define RANDOM_WALK_2D_MOBILITY_MODEL_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/component-manager.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/rectangle.h"
|
||||
#include "mobility-model.h"
|
||||
#include "static-speed-helper.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class RandomVariable;
|
||||
|
||||
/**
|
||||
* \brief parameters to control a random walk 2d model
|
||||
*
|
||||
* A single parameter object can be shared by multiple random
|
||||
* walk models.
|
||||
*/
|
||||
class RandomWalk2dMobilityModelParameters : public Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Instantiate a set of RandomWalk parameters initialized
|
||||
* with the Bind default values.
|
||||
*/
|
||||
RandomWalk2dMobilityModelParameters ();
|
||||
virtual ~RandomWalk2dMobilityModelParameters ();
|
||||
/**
|
||||
* \param speed the random variable used to pick a new
|
||||
* speed when the direction is changed.
|
||||
*
|
||||
*/
|
||||
void SetSpeed (const RandomVariable &speed);
|
||||
/**
|
||||
* \param direction the random variable used to pick a new
|
||||
* direction.
|
||||
*/
|
||||
void SetDirection (const RandomVariable &direction);
|
||||
/**
|
||||
* \param distance the distance before a direction change
|
||||
*
|
||||
* Unit is meters.
|
||||
* "time" mode is incompatible with "distance" mode.
|
||||
*/
|
||||
void SetModeDistance (double distance);
|
||||
/**
|
||||
* \param time the delay before a direction change.
|
||||
*
|
||||
* "time" mode is incompatible with "distance" mode.
|
||||
*/
|
||||
void SetModeTime (Time time);
|
||||
|
||||
/**
|
||||
* \param bounds the bounds of the random walk
|
||||
*/
|
||||
void SetBounds (const Rectangle &bounds);
|
||||
|
||||
|
||||
// needed public for internal default value code.
|
||||
enum Mode {
|
||||
MODE_DISTANCE,
|
||||
MODE_TIME
|
||||
};
|
||||
private:
|
||||
friend class RandomWalk2dMobilityModel;
|
||||
static Ptr<RandomWalk2dMobilityModelParameters> GetCurrent (void);
|
||||
|
||||
enum Mode m_mode;
|
||||
double m_modeDistance;
|
||||
Time m_modeTime;
|
||||
RandomVariable *m_speed;
|
||||
RandomVariable *m_direction;
|
||||
Rectangle m_bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief a 2D random walk position model
|
||||
*
|
||||
* Each instance moves with a speed and direction choosen at random
|
||||
* with the user-provided random variables until
|
||||
* either a fixed distance has been walked or until a fixed amount
|
||||
* of time.
|
||||
*
|
||||
* The parameters of the model can be specified either with the ns3::Bind
|
||||
* function and the variables "RandomWalk2dSpeed", "RandomWalk2dMode",
|
||||
* "RandomWalk2dDistance", "RandomWalk2dTime", and, "RandomWalk2dBounds" or
|
||||
* with an instance of the RandomWalk2dMobilityModelParameters class which
|
||||
* must be fed to the RandomWalk2dMobilityModel constructors.
|
||||
*/
|
||||
class RandomWalk2dMobilityModel : public MobilityModel
|
||||
{
|
||||
public:
|
||||
static const ClassId cid;
|
||||
/**
|
||||
* Create a new position object located at position (0,0,0)
|
||||
*/
|
||||
RandomWalk2dMobilityModel ();
|
||||
/**
|
||||
* \param parameters the parameters to use to control
|
||||
* the movement of this mobile object.
|
||||
*
|
||||
* Create a new position object located at position (0,0,0) with
|
||||
* the specified parameters.
|
||||
*/
|
||||
RandomWalk2dMobilityModel (Ptr<RandomWalk2dMobilityModelParameters> parameters);
|
||||
|
||||
private:
|
||||
void Start (void);
|
||||
void Rebound (Time timeLeft);
|
||||
void DoWalk (Time timeLeft);
|
||||
virtual void DoDispose (void);
|
||||
virtual Position DoGet (void) const;
|
||||
virtual void DoSet (const Position &position);
|
||||
virtual Speed DoGetSpeed (void) const;
|
||||
|
||||
StaticSpeedHelper m_helper;
|
||||
EventId m_event;
|
||||
Ptr<RandomWalk2dMobilityModelParameters> m_parameters;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RANDOM_WALK_2D_MOBILITY_MODEL_H */
|
||||
163
src/mobility/random-waypoint-mobility-model.cc
Normal file
163
src/mobility/random-waypoint-mobility-model.cc
Normal file
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include <cmath>
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/random-variable-default-value.h"
|
||||
#include "ns3/component-manager.h"
|
||||
#include "random-waypoint-mobility-model.h"
|
||||
#include "random-position.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
static RandomVariableDefaultValue
|
||||
g_speed ("RandomWaypointSpeed",
|
||||
"A random variable used to pick the speed of a random waypoint model.",
|
||||
"Uniform:0.3:0.7");
|
||||
|
||||
static RandomVariableDefaultValue
|
||||
g_pause ("RandomWaypointPause",
|
||||
"A random variable used to pick the pause of a random waypoint model.",
|
||||
"Constant:2");
|
||||
|
||||
static ClassIdDefaultValue
|
||||
g_position ("RandomWaypointPosition",
|
||||
"A random position model used to pick the next waypoint position.",
|
||||
RandomPosition::iid,
|
||||
"RandomRectanglePosition");
|
||||
|
||||
const ClassId RandomWaypointMobilityModel::cid =
|
||||
MakeClassId<RandomWaypointMobilityModel> ("RandomWaypointMobilityModel", MobilityModel::iid);
|
||||
|
||||
RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters ()
|
||||
: m_speed (g_speed.GetCopy ()),
|
||||
m_pause (g_pause.GetCopy ())
|
||||
{
|
||||
m_position = ComponentManager::Create<RandomPosition> (g_position.GetValue (),
|
||||
RandomPosition::iid);
|
||||
}
|
||||
RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters (Ptr<RandomPosition> randomPosition,
|
||||
const RandomVariable &speed,
|
||||
const RandomVariable &pause)
|
||||
: m_speed (speed.Copy ()),
|
||||
m_pause (pause.Copy ()),
|
||||
m_position (randomPosition)
|
||||
{}
|
||||
void
|
||||
RandomWaypointMobilityModelParameters::SetWaypointPositionModel (Ptr<RandomPosition> randomPosition)
|
||||
{
|
||||
m_position = randomPosition;
|
||||
}
|
||||
void
|
||||
RandomWaypointMobilityModelParameters::SetSpeed (const RandomVariable &speed)
|
||||
{
|
||||
delete m_speed;
|
||||
m_speed = speed.Copy ();
|
||||
}
|
||||
void
|
||||
RandomWaypointMobilityModelParameters::SetPause (const RandomVariable &pause)
|
||||
{
|
||||
delete m_pause;
|
||||
m_pause = pause.Copy ();
|
||||
}
|
||||
void
|
||||
RandomWaypointMobilityModelParameters::DoDispose (void)
|
||||
{
|
||||
m_position = 0;
|
||||
delete m_pause;
|
||||
delete m_speed;
|
||||
m_pause = 0;
|
||||
m_speed = 0;
|
||||
}
|
||||
|
||||
Ptr<RandomWaypointMobilityModelParameters>
|
||||
RandomWaypointMobilityModelParameters::GetCurrent (void)
|
||||
{
|
||||
static Ptr<RandomWaypointMobilityModelParameters> parameters = 0;
|
||||
if (parameters == 0 ||
|
||||
g_position.IsDirty () ||
|
||||
g_pause.IsDirty () ||
|
||||
g_speed.IsDirty ())
|
||||
{
|
||||
parameters = Create<RandomWaypointMobilityModelParameters> ();
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
RandomWaypointMobilityModel::RandomWaypointMobilityModel ()
|
||||
: m_parameters (RandomWaypointMobilityModelParameters::GetCurrent ())
|
||||
{
|
||||
Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
|
||||
}
|
||||
|
||||
RandomWaypointMobilityModel::RandomWaypointMobilityModel (Ptr<RandomWaypointMobilityModelParameters> parameters)
|
||||
: m_parameters (parameters)
|
||||
{
|
||||
Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
|
||||
NotifyCourseChange ();
|
||||
}
|
||||
|
||||
void
|
||||
RandomWaypointMobilityModel::BeginWalk (void)
|
||||
{
|
||||
Position m_current = m_helper.GetCurrentPosition ();
|
||||
Position destination = m_parameters->m_position->Get ();
|
||||
double speed = m_parameters->m_speed->GetValue ();
|
||||
double dx = (destination.x - m_current.x);
|
||||
double dy = (destination.y - m_current.y);
|
||||
double dz = (destination.z - m_current.z);
|
||||
double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
|
||||
|
||||
m_helper.Reset (Speed (k*dx, k*dy, k*dz));
|
||||
Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
|
||||
m_event = Simulator::Schedule (travelDelay,
|
||||
&RandomWaypointMobilityModel::Start, this);
|
||||
NotifyCourseChange ();
|
||||
}
|
||||
|
||||
void
|
||||
RandomWaypointMobilityModel::Start (void)
|
||||
{
|
||||
Time pause = Seconds (m_parameters->m_pause->GetValue ());
|
||||
m_helper.Pause ();
|
||||
NotifyCourseChange ();
|
||||
m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this);
|
||||
}
|
||||
|
||||
Position
|
||||
RandomWaypointMobilityModel::DoGet (void) const
|
||||
{
|
||||
return m_helper.GetCurrentPosition ();
|
||||
}
|
||||
void
|
||||
RandomWaypointMobilityModel::DoSet (const Position &position)
|
||||
{
|
||||
m_helper.InitializePosition (position);
|
||||
Simulator::Remove (m_event);
|
||||
Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
|
||||
}
|
||||
Speed
|
||||
RandomWaypointMobilityModel::DoGetSpeed (void) const
|
||||
{
|
||||
return m_helper.GetSpeed ();
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
112
src/mobility/random-waypoint-mobility-model.h
Normal file
112
src/mobility/random-waypoint-mobility-model.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef RANDOM_WAYPOINT_MOBILITY_MODEL_H
|
||||
#define RANDOM_WAYPOINT_MOBILITY_MODEL_H
|
||||
|
||||
#include "static-speed-helper.h"
|
||||
#include "mobility-model.h"
|
||||
#include "random-position.h"
|
||||
#include "ns3/ptr.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class RandomVariable;
|
||||
|
||||
/**
|
||||
* \brief the parameters which control the behavior of a random waypoint
|
||||
* mobility model.
|
||||
*/
|
||||
class RandomWaypointMobilityModelParameters : public Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Defaults parameters based on the Bind values.
|
||||
*/
|
||||
RandomWaypointMobilityModelParameters ();
|
||||
/**
|
||||
* \param randomPosition a random position model to choose the position of waypoints.
|
||||
* \param speed a random variable to choose the speed
|
||||
* \param pause a random variable to choose the pause delay
|
||||
*/
|
||||
RandomWaypointMobilityModelParameters (Ptr<RandomPosition> randomPosition,
|
||||
const RandomVariable &speed,
|
||||
const RandomVariable &pause);
|
||||
/**
|
||||
* \param randomPosition a random position model to choose the position of waypoints.
|
||||
*/
|
||||
void SetWaypointPositionModel (Ptr<RandomPosition> randomPosition);
|
||||
/**
|
||||
* \param speed a random variable to choose the speed
|
||||
*/
|
||||
void SetSpeed (const RandomVariable &speed);
|
||||
/**
|
||||
* \param pause a random variable to choose the pause delay
|
||||
*/
|
||||
void SetPause (const RandomVariable &pause);
|
||||
private:
|
||||
friend class RandomWaypointMobilityModel;
|
||||
static Ptr<RandomWaypointMobilityModelParameters> GetCurrent (void);
|
||||
virtual void DoDispose (void);
|
||||
RandomVariable *m_speed;
|
||||
RandomVariable *m_pause;
|
||||
Ptr<RandomPosition> m_position;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief a random waypoint mobility model
|
||||
*
|
||||
* Each object chooses a random destination "waypoint", a random speed,
|
||||
* and a random pause time: it then pauses for the specified pause time,
|
||||
* and starts moving towards the specified destination with the specified
|
||||
* speed. Once the destination is reached the process starts again.
|
||||
*
|
||||
* The implementation of this model is not 2d-specific. i.e. if you provide
|
||||
* a 3d random waypoint position model to this mobility model, the model
|
||||
* will still work.
|
||||
*/
|
||||
class RandomWaypointMobilityModel : public MobilityModel
|
||||
{
|
||||
public:
|
||||
static const ClassId cid;
|
||||
|
||||
/**
|
||||
* Create a waypoint mobility model from the Bind default values.
|
||||
*/
|
||||
RandomWaypointMobilityModel ();
|
||||
/**
|
||||
* \param parameters the parameters which control the behavior of this model.
|
||||
*/
|
||||
RandomWaypointMobilityModel (Ptr<RandomWaypointMobilityModelParameters> parameters);
|
||||
private:
|
||||
void Start (void);
|
||||
void BeginWalk (void);
|
||||
virtual Position DoGet (void) const;
|
||||
virtual void DoSet (const Position &position);
|
||||
virtual Speed DoGetSpeed (void) const;
|
||||
|
||||
StaticSpeedHelper m_helper;
|
||||
Ptr<RandomWaypointMobilityModelParameters> m_parameters;
|
||||
EventId m_event;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RANDOM_WAYPOINT_MOBILITY_MODEL_H */
|
||||
@@ -45,17 +45,17 @@ bool
|
||||
Rectangle::IsInside (const Position &position) const
|
||||
{
|
||||
return
|
||||
position.x <= xMax && position.x >= xMin &&
|
||||
position.y <= yMax && position.y >= yMin;
|
||||
position.x <= this->xMax && position.x >= this->xMin &&
|
||||
position.y <= this->yMax && position.y >= this->yMin;
|
||||
}
|
||||
|
||||
Rectangle::Side
|
||||
Rectangle::GetClosestSide (const Position &position) const
|
||||
{
|
||||
double xMinDist = std::abs (position.x - xMin);
|
||||
double xMaxDist = std::abs (xMax - position.x);
|
||||
double yMinDist = std::abs (position.y - yMin);
|
||||
double yMaxDist = std::abs (yMax - position.y);
|
||||
double xMinDist = std::abs (position.x - this->xMin);
|
||||
double xMaxDist = std::abs (this->xMax - position.x);
|
||||
double yMinDist = std::abs (position.y - this->yMin);
|
||||
double yMaxDist = std::abs (this->yMax - position.y);
|
||||
double minX = std::min (xMinDist, xMaxDist);
|
||||
double minY = std::min (yMinDist, yMaxDist);
|
||||
if (minX < minY)
|
||||
@@ -85,29 +85,29 @@ Rectangle::GetClosestSide (const Position &position) const
|
||||
Position
|
||||
Rectangle::CalculateIntersection (const Position ¤t, const Speed &speed) const
|
||||
{
|
||||
double xMaxY = current.y + (xMax - current.x) / speed.dx * speed.dy;
|
||||
double xMinY = current.y + (xMin - current.x) / speed.dx * speed.dy;
|
||||
double yMaxX = current.x + (yMax - current.y) / speed.dy * speed.dx;
|
||||
double yMinX = current.x + (yMin - current.y) / speed.dy * speed.dx;
|
||||
bool xMaxOk = xMaxY <= yMax && xMaxY >= yMin;
|
||||
bool xMinOk = xMinY <= yMax && xMinY >= yMin;
|
||||
bool yMaxOk = yMaxX <= xMax && yMaxX >= xMin;
|
||||
bool yMinOk = yMinX <= xMax && yMinX >= xMin;
|
||||
if (xMaxOk && speed.dx >= 0)
|
||||
double xMaxY = current.y + (this->xMax - current.x) / speed.dx * speed.dy;
|
||||
double xMinY = current.y + (this->xMin - current.x) / speed.dx * speed.dy;
|
||||
double yMaxX = current.x + (this->yMax - current.y) / speed.dy * speed.dx;
|
||||
double yMinX = current.x + (this->yMin - current.y) / speed.dy * speed.dx;
|
||||
bool xMaxYOk = (xMaxY <= this->yMax && xMaxY >= this->yMin);
|
||||
bool xMinYOk = (xMinY <= this->yMax && xMinY >= this->yMin);
|
||||
bool yMaxXOk = (yMaxX <= this->xMax && yMaxX >= this->xMin);
|
||||
bool yMinXOk = (yMinX <= this->xMax && yMinX >= this->xMin);
|
||||
if (xMaxYOk && speed.dx >= 0)
|
||||
{
|
||||
return Position (xMax, xMaxY, 0.0);
|
||||
return Position (this->xMax, xMaxY, 0.0);
|
||||
}
|
||||
else if (xMinOk && speed.dx <= 0)
|
||||
else if (xMinYOk && speed.dx <= 0)
|
||||
{
|
||||
return Position (xMin, xMinY, 0.0);
|
||||
return Position (this->xMin, xMinY, 0.0);
|
||||
}
|
||||
else if (yMaxOk && speed.dy >= 0)
|
||||
else if (yMaxXOk && speed.dy >= 0)
|
||||
{
|
||||
return Position (yMaxX, yMax, 0.0);
|
||||
return Position (yMaxX, this->yMax, 0.0);
|
||||
}
|
||||
else if (yMinOk && speed.dy <= 0)
|
||||
else if (yMinXOk && speed.dy <= 0)
|
||||
{
|
||||
return Position (yMinX, yMin, 0.0);
|
||||
return Position (yMinX, this->yMin, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -31,7 +31,8 @@ StaticSpeedHelper::StaticSpeedHelper (const Position &position)
|
||||
StaticSpeedHelper::StaticSpeedHelper (const Position &position,
|
||||
const Speed &speed)
|
||||
: m_position (position),
|
||||
m_speed (speed)
|
||||
m_speed (speed),
|
||||
m_paused (true)
|
||||
{}
|
||||
void
|
||||
StaticSpeedHelper::InitializePosition (const Position &position)
|
||||
@@ -41,14 +42,7 @@ StaticSpeedHelper::InitializePosition (const Position &position)
|
||||
m_speed.dy = 0.0;
|
||||
m_speed.dz = 0.0;
|
||||
m_lastUpdate = Simulator::Now ();
|
||||
m_pauseEnd = Simulator::Now ();
|
||||
}
|
||||
|
||||
void
|
||||
StaticSpeedHelper::Reset (const Speed &speed, const Time &pauseDelay)
|
||||
{
|
||||
Reset (speed);
|
||||
m_pauseEnd = Simulator::Now () + pauseDelay;
|
||||
m_paused = true;
|
||||
}
|
||||
|
||||
Position
|
||||
@@ -61,7 +55,7 @@ StaticSpeedHelper::GetCurrentPosition (void) const
|
||||
Speed
|
||||
StaticSpeedHelper::GetSpeed (void) const
|
||||
{
|
||||
return m_speed;
|
||||
return m_paused? Speed (0, 0, 0) : m_speed;
|
||||
}
|
||||
void
|
||||
StaticSpeedHelper::SetSpeed (const Speed &speed)
|
||||
@@ -73,17 +67,13 @@ StaticSpeedHelper::SetSpeed (const Speed &speed)
|
||||
void
|
||||
StaticSpeedHelper::Update (void) const
|
||||
{
|
||||
if (m_paused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Time now = Simulator::Now ();
|
||||
if (m_pauseEnd > now)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Time last = std::max (now, m_pauseEnd);
|
||||
if (m_lastUpdate >= last)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Time deltaTime = now - last;
|
||||
NS_ASSERT (m_lastUpdate <= now);
|
||||
Time deltaTime = now - m_lastUpdate;
|
||||
m_lastUpdate = now;
|
||||
double deltaS = deltaTime.GetSeconds ();
|
||||
m_position.x += m_speed.dx * deltaS;
|
||||
@@ -96,7 +86,7 @@ StaticSpeedHelper::Reset (const Speed &speed)
|
||||
{
|
||||
Update ();
|
||||
m_speed = speed;
|
||||
m_pauseEnd = Simulator::Now ();
|
||||
Unpause ();
|
||||
}
|
||||
void
|
||||
StaticSpeedHelper::UpdateFull (const Rectangle &bounds) const
|
||||
@@ -115,5 +105,21 @@ StaticSpeedHelper::GetCurrentPosition (const Rectangle &bounds) const
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void
|
||||
StaticSpeedHelper::Pause (void)
|
||||
{
|
||||
Update ();
|
||||
m_paused = true;
|
||||
}
|
||||
|
||||
void
|
||||
StaticSpeedHelper::Unpause (void)
|
||||
{
|
||||
if (m_paused)
|
||||
{
|
||||
m_lastUpdate = Simulator::Now ();
|
||||
m_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -37,12 +37,13 @@ class StaticSpeedHelper
|
||||
const Speed &speed);
|
||||
void InitializePosition (const Position &position);
|
||||
|
||||
void Reset (const Speed &speed, const Time &pauseDelay);
|
||||
void Reset (const Speed &speed);
|
||||
Position GetCurrentPosition (const Rectangle &bounds) const;
|
||||
Position GetCurrentPosition (void) const;
|
||||
Speed GetSpeed (void) const;
|
||||
void SetSpeed (const Speed &speed);
|
||||
void Pause (void);
|
||||
void Unpause (void);
|
||||
|
||||
private:
|
||||
void Update (void) const;
|
||||
@@ -50,7 +51,7 @@ class StaticSpeedHelper
|
||||
mutable Time m_lastUpdate;
|
||||
mutable Position m_position;
|
||||
Speed m_speed;
|
||||
Time m_pauseEnd;
|
||||
bool m_paused;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -16,6 +16,10 @@ def build(bld):
|
||||
'static-mobility-model.cc',
|
||||
'static-speed-helper.cc',
|
||||
'static-speed-mobility-model.cc',
|
||||
'random-waypoint-mobility-model.cc',
|
||||
'random-walk-2d-mobility-model.cc',
|
||||
'random-direction-2d-mobility-model.cc',
|
||||
'ns2-mobility-file-topology.cc',
|
||||
]
|
||||
|
||||
headers = bld.create_obj('ns3header')
|
||||
@@ -33,4 +37,8 @@ def build(bld):
|
||||
'static-mobility-model.h',
|
||||
'static-speed-helper.h',
|
||||
'static-speed-mobility-model.h',
|
||||
'random-waypoint-mobility-model.h',
|
||||
'random-walk-2d-mobility-model.h',
|
||||
'random-direction-2d-mobility-model.h',
|
||||
'ns2-mobility-file-topology.h',
|
||||
]
|
||||
|
||||
152
src/simulator/event-garbage-collector.cc
Normal file
152
src/simulator/event-garbage-collector.cc
Normal file
@@ -0,0 +1,152 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
* 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: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
#include "event-garbage-collector.h"
|
||||
|
||||
#define CLEANUP_CHUNK_MIN_SIZE 8
|
||||
#define CLEANUP_CHUNK_MAX_SIZE 128
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
EventGarbageCollector::EventGarbageCollector () :
|
||||
m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE)
|
||||
{}
|
||||
|
||||
void
|
||||
EventGarbageCollector::Track (EventId event)
|
||||
{
|
||||
m_events.push_back (event);
|
||||
if (m_events.size () >= m_nextCleanupSize)
|
||||
Cleanup ();
|
||||
}
|
||||
|
||||
inline bool
|
||||
EventExpiredPredicate (const EventId &event)
|
||||
{
|
||||
return event.IsExpired ();
|
||||
}
|
||||
|
||||
void
|
||||
EventGarbageCollector::Grow ()
|
||||
{
|
||||
m_nextCleanupSize += (m_nextCleanupSize < CLEANUP_CHUNK_MAX_SIZE?
|
||||
m_nextCleanupSize : CLEANUP_CHUNK_MAX_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
EventGarbageCollector::Shrink ()
|
||||
{
|
||||
while (m_nextCleanupSize > m_events.size ())
|
||||
m_nextCleanupSize >>= 1;
|
||||
Grow ();
|
||||
}
|
||||
|
||||
// Called when a new event was added and the cleanup limit was exceeded in consequence.
|
||||
void
|
||||
EventGarbageCollector::Cleanup ()
|
||||
{
|
||||
m_events.remove_if (EventExpiredPredicate);
|
||||
|
||||
// If after cleanup we are still over the limit, increase the limit.
|
||||
if (m_events.size () >= m_nextCleanupSize)
|
||||
Grow ();
|
||||
else
|
||||
Shrink ();
|
||||
}
|
||||
|
||||
|
||||
EventGarbageCollector::~EventGarbageCollector ()
|
||||
{
|
||||
for (std::list<EventId>::iterator event = m_events.begin ();
|
||||
event != m_events.end (); event++)
|
||||
{
|
||||
Simulator::Cancel (*event);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#include "ns3/test.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class EventGarbageCollectorTests : public Test
|
||||
{
|
||||
int m_counter;
|
||||
EventGarbageCollector *m_events;
|
||||
|
||||
void EventGarbageCollectorCallback ();
|
||||
|
||||
public:
|
||||
|
||||
EventGarbageCollectorTests ();
|
||||
virtual ~EventGarbageCollectorTests ();
|
||||
virtual bool RunTests (void);
|
||||
};
|
||||
|
||||
EventGarbageCollectorTests::EventGarbageCollectorTests ()
|
||||
: Test ("EventGarbageCollector"), m_counter (0), m_events (0)
|
||||
{}
|
||||
|
||||
EventGarbageCollectorTests::~EventGarbageCollectorTests ()
|
||||
{}
|
||||
|
||||
void
|
||||
EventGarbageCollectorTests::EventGarbageCollectorCallback ()
|
||||
{
|
||||
m_counter++;
|
||||
if (m_counter == 50)
|
||||
{
|
||||
// this should cause the remaining (50) events to be cancelled
|
||||
delete m_events;
|
||||
m_events = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool EventGarbageCollectorTests::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
m_events = new EventGarbageCollector ();
|
||||
|
||||
for (int n = 0; n < 100; n++)
|
||||
{
|
||||
m_events->Track (Simulator::Schedule
|
||||
(Simulator::Now (),
|
||||
&EventGarbageCollectorTests::EventGarbageCollectorCallback,
|
||||
this));
|
||||
}
|
||||
Simulator::Run ();
|
||||
NS_TEST_ASSERT_EQUAL (m_events, 0);
|
||||
NS_TEST_ASSERT_EQUAL (m_counter, 50);
|
||||
return result;
|
||||
}
|
||||
|
||||
static EventGarbageCollectorTests g_eventCollectorTests;
|
||||
|
||||
};
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
62
src/simulator/event-garbage-collector.h
Normal file
62
src/simulator/event-garbage-collector.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
* 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: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
#ifndef EVENT_GARBAGE_COLLECTOR_H
|
||||
#define EVENT_GARBAGE_COLLECTOR_H
|
||||
|
||||
#include <list>
|
||||
#include "event-id.h"
|
||||
#include "simulator.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief An object that tracks scheduled events and automatically
|
||||
* cancels them when it is destroyed. It is useful in situations
|
||||
* where multiple instances of the same type of event can
|
||||
* simultaneously be scheduled, and when the events should be limited
|
||||
* to the lifetime of a container object.
|
||||
*/
|
||||
class EventGarbageCollector
|
||||
{
|
||||
public:
|
||||
|
||||
EventGarbageCollector ();
|
||||
|
||||
/**
|
||||
* \brief Tracks a new event
|
||||
*/
|
||||
void Track (EventId event);
|
||||
|
||||
~EventGarbageCollector ();
|
||||
|
||||
private:
|
||||
|
||||
std::list<EventId>::size_type m_nextCleanupSize;
|
||||
std::list<EventId> m_events;
|
||||
|
||||
void Cleanup ();
|
||||
void Grow ();
|
||||
void Shrink ();
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* EVENT_GARBAGE_COLLECTOR_H */
|
||||
@@ -67,9 +67,10 @@ public:
|
||||
EventId ScheduleDestroy (const Ptr<EventImpl> &event);
|
||||
void Remove (const EventId &ev);
|
||||
void Cancel (const EventId &ev);
|
||||
bool IsExpired (const EventId &ev);
|
||||
bool IsExpired (const EventId &ev) const;
|
||||
void Run (void);
|
||||
Time Now (void) const;
|
||||
Time GetDelayLeft (const EventId &id) const;
|
||||
|
||||
private:
|
||||
void ProcessOneEvent (void);
|
||||
@@ -251,6 +252,18 @@ SimulatorPrivate::Now (void) const
|
||||
{
|
||||
return TimeStep (m_currentTs);
|
||||
}
|
||||
Time
|
||||
SimulatorPrivate::GetDelayLeft (const EventId &id) const
|
||||
{
|
||||
if (IsExpired (id))
|
||||
{
|
||||
return TimeStep (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TimeStep (id.GetTs () - m_currentTs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimulatorPrivate::Remove (const EventId &ev)
|
||||
@@ -293,12 +306,12 @@ SimulatorPrivate::Cancel (const EventId &id)
|
||||
}
|
||||
|
||||
bool
|
||||
SimulatorPrivate::IsExpired (const EventId &ev)
|
||||
SimulatorPrivate::IsExpired (const EventId &ev) const
|
||||
{
|
||||
if (ev.GetUid () == 2)
|
||||
{
|
||||
// destroy events.
|
||||
for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
|
||||
for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
|
||||
{
|
||||
if (*i == ev)
|
||||
{
|
||||
@@ -411,6 +424,11 @@ Simulator::Now (void)
|
||||
{
|
||||
return GetPriv ()->Now ();
|
||||
}
|
||||
Time
|
||||
Simulator::GetDelayLeft (const EventId &id)
|
||||
{
|
||||
return GetPriv ()->GetDelayLeft (id);
|
||||
}
|
||||
|
||||
Ptr<EventImpl>
|
||||
Simulator::MakeEvent (void (*f) (void))
|
||||
|
||||
@@ -552,6 +552,13 @@ public:
|
||||
* Return the "current simulation time".
|
||||
*/
|
||||
static Time Now (void);
|
||||
/**
|
||||
* \param id the event id to analyse
|
||||
* \returns the delay left until the input event id expires.
|
||||
* if the event is not running, this method returns
|
||||
* zero.
|
||||
*/
|
||||
static Time GetDelayLeft (const EventId &id);
|
||||
private:
|
||||
Simulator ();
|
||||
~Simulator ();
|
||||
|
||||
325
src/simulator/timer.cc
Normal file
325
src/simulator/timer.cc
Normal file
@@ -0,0 +1,325 @@
|
||||
#include "timer.h"
|
||||
#include "simulator.h"
|
||||
#include "simulation-singleton.h"
|
||||
#include "event-garbage-collector.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Timer::Timer ()
|
||||
: m_flags (0),
|
||||
m_delay (FemtoSeconds (0)),
|
||||
m_event (),
|
||||
m_impl (0)
|
||||
{}
|
||||
|
||||
Timer::Timer (enum SchedulePolicy schedulePolicy,
|
||||
enum DestroyPolicy destroyPolicy)
|
||||
: m_flags (schedulePolicy | destroyPolicy),
|
||||
m_delay (FemtoSeconds (0)),
|
||||
m_event (),
|
||||
m_impl (0)
|
||||
{}
|
||||
|
||||
Timer::Timer (enum GarbageCollectPolicy policy)
|
||||
: m_flags (GARBAGE_COLLECT),
|
||||
m_delay (FemtoSeconds (0)),
|
||||
m_event (),
|
||||
m_impl (0)
|
||||
{}
|
||||
|
||||
Timer::~Timer ()
|
||||
{
|
||||
if (m_flags & CHECK_ON_DESTROY)
|
||||
{
|
||||
if (m_event.IsRunning ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Event is still running while destroying.");
|
||||
}
|
||||
}
|
||||
else if (m_flags & CANCEL_ON_DESTROY)
|
||||
{
|
||||
m_event.Cancel ();
|
||||
}
|
||||
else if (m_flags & REMOVE_ON_DESTROY)
|
||||
{
|
||||
Simulator::Remove (m_event);
|
||||
}
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
void
|
||||
Timer::SetDelay (const Time &time)
|
||||
{
|
||||
m_delay = time;
|
||||
}
|
||||
Time
|
||||
Timer::GetDelay (void) const
|
||||
{
|
||||
return m_delay;
|
||||
}
|
||||
Time
|
||||
Timer::GetDelayLeft (void) const
|
||||
{
|
||||
switch (GetState ()) {
|
||||
case Timer::RUNNING:
|
||||
return Simulator::GetDelayLeft (m_event);
|
||||
break;
|
||||
case Timer::EXPIRED:
|
||||
return TimeStep (0);
|
||||
break;
|
||||
case Timer::SUSPENDED:
|
||||
return m_delayLeft;
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT (false);
|
||||
return TimeStep (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Timer::Cancel (void)
|
||||
{
|
||||
Simulator::Cancel (m_event);
|
||||
}
|
||||
void
|
||||
Timer::Remove (void)
|
||||
{
|
||||
Simulator::Remove (m_event);
|
||||
}
|
||||
bool
|
||||
Timer::IsExpired (void) const
|
||||
{
|
||||
return !IsSuspended () && m_event.IsExpired ();
|
||||
}
|
||||
bool
|
||||
Timer::IsRunning (void) const
|
||||
{
|
||||
return !IsSuspended () && m_event.IsRunning ();
|
||||
}
|
||||
bool
|
||||
Timer::IsSuspended (void) const
|
||||
{
|
||||
return (m_flags & TIMER_SUSPENDED) == TIMER_SUSPENDED;
|
||||
}
|
||||
enum Timer::State
|
||||
Timer::GetState (void) const
|
||||
{
|
||||
if (IsRunning ())
|
||||
{
|
||||
return Timer::RUNNING;
|
||||
}
|
||||
else if (IsExpired ())
|
||||
{
|
||||
return Timer::EXPIRED;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (IsSuspended ());
|
||||
return Timer::SUSPENDED;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Timer::Schedule (void)
|
||||
{
|
||||
Schedule (m_delay);
|
||||
}
|
||||
|
||||
void
|
||||
Timer::Schedule (Time delay)
|
||||
{
|
||||
NS_ASSERT (m_impl != 0);
|
||||
if (m_flags & CHECK_ON_SCHEDULE)
|
||||
{
|
||||
if (m_event.IsRunning ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Event is still running while re-scheduling.");
|
||||
}
|
||||
}
|
||||
else if (m_flags & CANCEL_ON_SCHEDULE)
|
||||
{
|
||||
m_event.Cancel ();
|
||||
}
|
||||
else if (m_flags & REMOVE_ON_SCHEDULE)
|
||||
{
|
||||
Simulator::Remove (m_event);
|
||||
}
|
||||
m_event = m_impl->Schedule (delay);
|
||||
if (m_flags & GARBAGE_COLLECT)
|
||||
{
|
||||
SimulationSingleton<EventGarbageCollector>::Get ()->Track (m_event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Timer::Suspend (void)
|
||||
{
|
||||
NS_ASSERT (IsRunning ());
|
||||
m_delayLeft = Simulator::GetDelayLeft (m_event);
|
||||
Simulator::Remove (m_event);
|
||||
m_flags |= TIMER_SUSPENDED;
|
||||
}
|
||||
|
||||
void
|
||||
Timer::Resume (void)
|
||||
{
|
||||
NS_ASSERT (m_flags & TIMER_SUSPENDED);
|
||||
m_event = m_impl->Schedule (m_delayLeft);
|
||||
m_flags &= ~TIMER_SUSPENDED;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
#include "ns3/test.h"
|
||||
|
||||
namespace {
|
||||
void bari (int)
|
||||
{}
|
||||
void bar2i (int, int)
|
||||
{}
|
||||
void bar3i (int, int, int)
|
||||
{}
|
||||
void bar4i (int, int, int, int)
|
||||
{}
|
||||
void bar5i (int, int, int, int, int)
|
||||
{}
|
||||
void bar6i (int, int, int, int, int, int)
|
||||
{}
|
||||
void barcir (const int &)
|
||||
{}
|
||||
void barir (int &)
|
||||
{}
|
||||
void barip (int *)
|
||||
{}
|
||||
void barcip (const int *)
|
||||
{}
|
||||
}
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TimerTests : public Test
|
||||
{
|
||||
public:
|
||||
TimerTests ();
|
||||
virtual bool RunTests (void);
|
||||
void bazi (int) {}
|
||||
void baz2i (int, int) {}
|
||||
void baz3i (int, int, int) {}
|
||||
void baz4i (int, int, int, int) {}
|
||||
void baz5i (int, int, int, int, int) {}
|
||||
void baz6i (int, int, int, int, int, int) {}
|
||||
void bazcir (const int&) {}
|
||||
void bazir (int&) {}
|
||||
void bazip (int *) {}
|
||||
void bazcip (const int *) {}
|
||||
};
|
||||
|
||||
TimerTests::TimerTests ()
|
||||
: Test ("Timer")
|
||||
{}
|
||||
|
||||
bool
|
||||
TimerTests::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
Timer timer;
|
||||
|
||||
timer.SetFunction (&bari);
|
||||
timer.SetArguments (1);
|
||||
timer.SetDelay (Seconds (10.0));
|
||||
NS_TEST_ASSERT (!timer.IsRunning ());
|
||||
NS_TEST_ASSERT (timer.IsExpired ());
|
||||
NS_TEST_ASSERT (!timer.IsSuspended ());
|
||||
NS_TEST_ASSERT_EQUAL (timer.GetState (), Timer::EXPIRED);
|
||||
timer.Schedule ();
|
||||
NS_TEST_ASSERT (timer.IsRunning ());
|
||||
NS_TEST_ASSERT (!timer.IsExpired ());
|
||||
NS_TEST_ASSERT (!timer.IsSuspended ());
|
||||
NS_TEST_ASSERT_EQUAL (timer.GetState (), Timer::RUNNING);
|
||||
timer.Suspend ();
|
||||
NS_TEST_ASSERT (!timer.IsRunning ());
|
||||
NS_TEST_ASSERT (!timer.IsExpired ());
|
||||
NS_TEST_ASSERT (timer.IsSuspended ());
|
||||
NS_TEST_ASSERT_EQUAL (timer.GetState (), Timer::SUSPENDED);
|
||||
timer.Resume ();
|
||||
NS_TEST_ASSERT (timer.IsRunning ());
|
||||
NS_TEST_ASSERT (!timer.IsExpired ());
|
||||
NS_TEST_ASSERT (!timer.IsSuspended ());
|
||||
NS_TEST_ASSERT_EQUAL (timer.GetState (), Timer::RUNNING);
|
||||
timer.Cancel ();
|
||||
NS_TEST_ASSERT (!timer.IsRunning ());
|
||||
NS_TEST_ASSERT (timer.IsExpired ());
|
||||
NS_TEST_ASSERT (!timer.IsSuspended ());
|
||||
NS_TEST_ASSERT_EQUAL (timer.GetState (), Timer::EXPIRED);
|
||||
|
||||
int a = 0;
|
||||
int &b = a;
|
||||
const int &c = a;
|
||||
|
||||
timer.SetFunction (&bari);
|
||||
timer.SetArguments (2);
|
||||
timer.SetArguments (a);
|
||||
timer.SetArguments (b);
|
||||
timer.SetArguments (c);
|
||||
timer.SetFunction (&barir);
|
||||
timer.SetArguments (2);
|
||||
timer.SetArguments (a);
|
||||
timer.SetArguments (b);
|
||||
timer.SetArguments (c);
|
||||
timer.SetFunction (&barcir);
|
||||
timer.SetArguments (2);
|
||||
timer.SetArguments (a);
|
||||
timer.SetArguments (b);
|
||||
timer.SetArguments (c);
|
||||
// the following call cannot possibly work and is flagged by
|
||||
// a runtime error.
|
||||
//timer.SetArguments (0.0);
|
||||
timer.SetDelay (Seconds (1.0));
|
||||
timer.Schedule ();
|
||||
|
||||
timer.SetFunction (&TimerTests::bazi, this);
|
||||
timer.SetArguments (3);
|
||||
timer.SetFunction (&TimerTests::bazir, this);
|
||||
timer.SetArguments (3);
|
||||
timer.SetFunction (&TimerTests::bazcir, this);
|
||||
timer.SetArguments (3);
|
||||
|
||||
timer.SetFunction (&bar2i);
|
||||
timer.SetArguments (1, 1);
|
||||
timer.SetFunction (&bar3i);
|
||||
timer.SetArguments (1, 1, 1);
|
||||
timer.SetFunction (&bar4i);
|
||||
timer.SetArguments (1, 1, 1, 1);
|
||||
timer.SetFunction (&bar5i);
|
||||
timer.SetArguments (1, 1, 1, 1, 1);
|
||||
//timer.SetFunction (&bar6i);
|
||||
//timer.SetArguments (1, 1, 1, 1, 1, 1);
|
||||
|
||||
timer.SetFunction (&TimerTests::baz2i, this);
|
||||
timer.SetArguments (1, 1);
|
||||
timer.SetFunction (&TimerTests::baz3i, this);
|
||||
timer.SetArguments (1, 1, 1);
|
||||
timer.SetFunction (&TimerTests::baz4i, this);
|
||||
timer.SetArguments (1, 1, 1, 1);
|
||||
timer.SetFunction (&TimerTests::baz5i, this);
|
||||
timer.SetArguments (1, 1, 1, 1, 1);
|
||||
//timer.SetFunction (&TimerTests::baz6i, this);
|
||||
//timer.SetArguments (1, 1, 1, 1, 1, 1);
|
||||
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TimerTests g_tests;
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
991
src/simulator/timer.h
Normal file
991
src/simulator/timer.h
Normal file
@@ -0,0 +1,991 @@
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include "ns3/fatal-error.h"
|
||||
#include "nstime.h"
|
||||
#include "event-id.h"
|
||||
#include "ns3/int-to-type.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TimerImpl;
|
||||
|
||||
/**
|
||||
* \brief a simple Timer class
|
||||
*
|
||||
* A timer is used to hold together a delay, a function to invoke
|
||||
* when the delay expires, and a set of arguments to pass to the function
|
||||
* when the delay expires.
|
||||
*
|
||||
* A timer can also be used to enforce a set of predefined event lifetime
|
||||
* management policies. These policies are specified at construction time
|
||||
* and cannot be changed after.
|
||||
*/
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
enum SchedulePolicy {
|
||||
/**
|
||||
* This policy cancels the event before scheduling a new event
|
||||
* for each call to Timer::Schedule.
|
||||
*/
|
||||
CANCEL_ON_SCHEDULE = (1<<0),
|
||||
/**
|
||||
* This policy removes the event from the simulation event list
|
||||
* before scheduling a new event for each call to Timer::Schedule.
|
||||
*/
|
||||
REMOVE_ON_SCHEDULE = (1<<1),
|
||||
/**
|
||||
* This policy enforces a check before each call to Timer::Schedule
|
||||
* to verify that the timer has already expired.
|
||||
*/
|
||||
CHECK_ON_SCHEDULE = (1<<2),
|
||||
};
|
||||
enum DestroyPolicy {
|
||||
/**
|
||||
* This policy cancels the event from the destructor of the Timer
|
||||
* to verify that the event has already expired.
|
||||
*/
|
||||
CANCEL_ON_DESTROY = (1<<3),
|
||||
/**
|
||||
* This policy removes the event from the simulation event list
|
||||
* when the destructor of the Timer is invoked.
|
||||
*/
|
||||
REMOVE_ON_DESTROY = (1<<4),
|
||||
/**
|
||||
* This policy enforces a check from the destructor of the Timer
|
||||
* to verify that the timer has already expired.
|
||||
*/
|
||||
CHECK_ON_DESTROY = (1<<5)
|
||||
};
|
||||
enum GarbageCollectPolicy {
|
||||
/**
|
||||
* Every event scheduled with this policy is kept track of by an
|
||||
* event garbage collector which makes sure that all events
|
||||
* of timers with a GARBAGE_COLLECT policy are cancelled at the
|
||||
* end of the simulation.
|
||||
*/
|
||||
GARBAGE_COLLECT = (1<<6)
|
||||
};
|
||||
enum State {
|
||||
RUNNING,
|
||||
EXPIRED,
|
||||
SUSPENDED,
|
||||
};
|
||||
/**
|
||||
* create a timer with a default event lifetime management policy:
|
||||
* - CHECK_ON_SCHEDULE
|
||||
* - CHECK_ON_DESTROY
|
||||
*/
|
||||
Timer ();
|
||||
/**
|
||||
* \param scheduleFlags the event lifetime management policies to use for schedule events
|
||||
* \param destroyFlags the event lifetime management policies to use for destroy events
|
||||
*/
|
||||
Timer (enum SchedulePolicy schedulePolicy,
|
||||
enum DestroyPolicy destroyPolicy);
|
||||
/**
|
||||
* \param policy the garbage collect policy. Only one
|
||||
* value is possible.
|
||||
*/
|
||||
Timer (enum GarbageCollectPolicy policy);
|
||||
~Timer ();
|
||||
|
||||
/**
|
||||
* \param fn the function
|
||||
*
|
||||
* Store this function in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename FN>
|
||||
void SetFunction (FN fn);
|
||||
|
||||
/**
|
||||
* \param memPtr the member function pointer
|
||||
* \param objPtr the pointer to object
|
||||
*
|
||||
* Store this function and object in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void SetFunction (MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
|
||||
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
*
|
||||
* Store this argument in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1>
|
||||
void SetArguments (T1 a1);
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
* \param a2 the second argument
|
||||
*
|
||||
* Store these arguments in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1, typename T2>
|
||||
void SetArguments (T1 a1, T2 a2);
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
* \param a2 the second argument
|
||||
* \param a3 the third argument
|
||||
*
|
||||
* Store these arguments in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void SetArguments (T1 a1, T2 a2, T3 a3);
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
* \param a2 the second argument
|
||||
* \param a3 the third argument
|
||||
* \param a4 the fourth argument
|
||||
*
|
||||
* Store these arguments in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void SetArguments (T1 a1, T2 a2, T3 a3, T4 a4);
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
* \param a2 the second argument
|
||||
* \param a3 the third argument
|
||||
* \param a4 the fourth argument
|
||||
* \param a5 the fifth argument
|
||||
*
|
||||
* Store these arguments in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
|
||||
/**
|
||||
* \param a1 the first argument
|
||||
* \param a2 the second argument
|
||||
* \param a3 the third argument
|
||||
* \param a4 the fourth argument
|
||||
* \param a5 the fifth argument
|
||||
* \param a6 the sixth argument
|
||||
*
|
||||
* Store these arguments in this Timer for later use by Timer::Schedule.
|
||||
*/
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
void SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
|
||||
|
||||
/**
|
||||
* \param delay the delay
|
||||
*
|
||||
* The next call to Schedule will schedule the timer with this delay.
|
||||
*/
|
||||
void SetDelay (const Time &delay);
|
||||
/**
|
||||
* \returns the currently-configured delay for the next Schedule.
|
||||
*/
|
||||
Time GetDelay (void) const;
|
||||
/**
|
||||
* \returns the amount of time left until this timer expires.
|
||||
*
|
||||
* This method returns zero if the timer is in EXPIRED state.
|
||||
*/
|
||||
Time GetDelayLeft (void) const;
|
||||
/**
|
||||
* Cancel the currently-running event if there is one. Do nothing
|
||||
* otherwise.
|
||||
*/
|
||||
void Cancel (void);
|
||||
/**
|
||||
* Remove from the simulation event-list the currently-running event
|
||||
* if there is one. Do nothing otherwise.
|
||||
*/
|
||||
void Remove (void);
|
||||
/**
|
||||
* \return true if there is no currently-running event, false otherwise.
|
||||
*/
|
||||
bool IsExpired (void) const;
|
||||
/**
|
||||
* \return true if there is a currently-running event, false otherwise.
|
||||
*/
|
||||
bool IsRunning (void) const;
|
||||
/**
|
||||
* \returns true if this timer was suspended and not yet resumed, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool IsSuspended (void) const;
|
||||
/**
|
||||
* \returns the current state of the timer.
|
||||
*/
|
||||
enum Timer::State GetState (void) const;
|
||||
/**
|
||||
* Schedule a new event using the currently-configured delay, function,
|
||||
* and arguments.
|
||||
*/
|
||||
void Schedule (void);
|
||||
/**
|
||||
* \param delay the delay to use
|
||||
*
|
||||
* Schedule a new event using the specified delay (ignore the delay set by
|
||||
* Timer::SetDelay), function, and arguments.
|
||||
*/
|
||||
void Schedule (Time delay);
|
||||
|
||||
/**
|
||||
* Cancel the timer and save the amount of time left until it was
|
||||
* set to expire.
|
||||
* Calling Suspend on a non-running timer is an error.
|
||||
*/
|
||||
void Suspend (void);
|
||||
/**
|
||||
* Restart the timer to expire within the amount of time left saved
|
||||
* during Suspend.
|
||||
* Calling Resume without a prior call to Suspend is an error.
|
||||
*/
|
||||
void Resume (void);
|
||||
|
||||
private:
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<0>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<1>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<2>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<3>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<4>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<5>, FN fn);
|
||||
template <typename FN>
|
||||
void DoSetFunction (IntToType<6>, FN fn);
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<0>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<1>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<2>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<3>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<4>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<5>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void DoSetFunction (IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr);
|
||||
|
||||
enum {
|
||||
TIMER_SUSPENDED = (1<<7)
|
||||
};
|
||||
|
||||
int m_flags;
|
||||
Time m_delay;
|
||||
EventId m_event;
|
||||
TimerImpl *m_impl;
|
||||
Time m_delayLeft;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
// The actual implementation.
|
||||
#include "simulator.h"
|
||||
#include "ns3/type-traits.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct TimerTraits
|
||||
{
|
||||
typedef typename TypeTraits<typename TypeTraits<T>::ReferencedType>::NonConstType StoredType;
|
||||
typedef const StoredType &ParameterType;
|
||||
};
|
||||
|
||||
class TimerImpl
|
||||
{
|
||||
public:
|
||||
virtual ~TimerImpl () {}
|
||||
virtual EventId Schedule (const Time &delay) = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename T1>
|
||||
struct TimerImplOne : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1) = 0;
|
||||
};
|
||||
template <typename T1, typename T2>
|
||||
struct TimerImplTwo : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1,T2 a2) = 0;
|
||||
};
|
||||
template <typename T1, typename T2, typename T3>
|
||||
struct TimerImplThree : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1,T2 a2,T3 a3) = 0;
|
||||
};
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
struct TimerImplFour : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1,T2 a2,T3 a3, T4 a4) = 0;
|
||||
};
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
struct TimerImplFive : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1,T2 a2,T3 a3, T4 a4, T5 a5) = 0;
|
||||
};
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
struct TimerImplSix : public TimerImpl
|
||||
{
|
||||
virtual void SetArguments (T1 a1,T2 a2,T3 a3, T4 a4, T5 a5, T6 a6) = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::SetFunction (FN fn)
|
||||
{
|
||||
NS_ASSERT (TypeTraits<FN>::IsFunctionPointer);
|
||||
DoSetFunction (IntToType<TypeTraits<FN>::FunctionPointerTraits::nArgs> (), fn);
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<0>, FN fn)
|
||||
{
|
||||
struct FnTimerImplZero : public TimerImpl
|
||||
{
|
||||
FnTimerImplZero (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn);
|
||||
}
|
||||
FN m_fn;
|
||||
} *function = new FnTimerImplZero (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<1>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
|
||||
struct FnTimerImplOne : public TimerImplOne<T1Parameter>
|
||||
{
|
||||
FnTimerImplOne (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1) {
|
||||
m_a1 = a1;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
} *function = new FnTimerImplOne (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<2>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
|
||||
struct FnTimerImplTwo : public TimerImplTwo<T1Parameter,T2Parameter>
|
||||
{
|
||||
FnTimerImplTwo (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1, m_a2);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
} *function = new FnTimerImplTwo (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<3>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
|
||||
struct FnTimerImplThree : public TimerImplThree<T1Parameter,T2Parameter,T3Parameter>
|
||||
{
|
||||
FnTimerImplThree (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
} *function = new FnTimerImplThree (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<4>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
|
||||
struct FnTimerImplFour : public TimerImplFour<T1Parameter,T2Parameter,T3Parameter,T4Parameter>
|
||||
{
|
||||
FnTimerImplFour (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
} *function = new FnTimerImplFour (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<5>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg5Type T5;
|
||||
typedef typename TimerTraits<T5>::ParameterType T5Parameter;
|
||||
typedef typename TimerTraits<T5>::StoredType T5Stored;
|
||||
|
||||
struct FnTimerImplFive : public TimerImplFive<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter>
|
||||
{
|
||||
FnTimerImplFive (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
m_a5 = a5;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
T5Stored m_a5;
|
||||
} *function = new FnTimerImplFive (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<6>, FN fn)
|
||||
{
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg5Type T5;
|
||||
typedef typename TimerTraits<T5>::ParameterType T5Parameter;
|
||||
typedef typename TimerTraits<T5>::StoredType T5Stored;
|
||||
typedef typename TypeTraits<FN>::FunctionPointerTraits::Arg6Type T6;
|
||||
typedef typename TimerTraits<T6>::ParameterType T6Parameter;
|
||||
typedef typename TimerTraits<T6>::StoredType T6Stored;
|
||||
|
||||
struct FnTimerImplSix : public TimerImplSix<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter,T6Parameter>
|
||||
{
|
||||
FnTimerImplSix (FN fn)
|
||||
: m_fn (fn) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5, T6Parameter a6) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
m_a5 = a5;
|
||||
m_a6 = a6;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
|
||||
}
|
||||
FN m_fn;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
T5Stored m_a5;
|
||||
T6Stored m_a6;
|
||||
} *function = new FnTimerImplSix (fn);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::SetFunction (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
NS_ASSERT (TypeTraits<MEM_PTR>::IsPointerToMember);
|
||||
DoSetFunction (IntToType<TypeTraits<MEM_PTR>::PointerToMemberTraits::nArgs> () , memPtr, objPtr);
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<0>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
struct MemFnTimerImplZero : public TimerImpl
|
||||
{
|
||||
MemFnTimerImplZero (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
} *function = new MemFnTimerImplZero (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<1>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
|
||||
struct MemFnTimerImplOne : public TimerImplOne<T1Parameter>
|
||||
{
|
||||
MemFnTimerImplOne (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1) {
|
||||
m_a1 = a1;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
} *function = new MemFnTimerImplOne (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<2>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
|
||||
struct MemFnTimerImplTwo : public TimerImplTwo<T1Parameter,T2Parameter>
|
||||
{
|
||||
MemFnTimerImplTwo (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
} *function = new MemFnTimerImplTwo (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<3>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
|
||||
struct MemFnTimerImplThree : public TimerImplThree<T1Parameter,T2Parameter,T3Parameter>
|
||||
{
|
||||
MemFnTimerImplThree (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
} *function = new MemFnTimerImplThree (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<4>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
|
||||
struct MemFnTimerImplFour : public TimerImplFour<T1Parameter,T2Parameter,T3Parameter,T4Parameter>
|
||||
{
|
||||
MemFnTimerImplFour (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
} *function = new MemFnTimerImplFour (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<5>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg5Type T5;
|
||||
typedef typename TimerTraits<T5>::ParameterType T5Parameter;
|
||||
typedef typename TimerTraits<T5>::StoredType T5Stored;
|
||||
|
||||
struct MemFnTimerImplFive : public TimerImplFive<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter>
|
||||
{
|
||||
MemFnTimerImplFive (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
m_a5 = a5;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4, m_a5);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
T5Stored m_a5;
|
||||
} *function = new MemFnTimerImplFive (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
template <typename MEM_PTR, typename OBJ_PTR>
|
||||
void
|
||||
Timer::DoSetFunction (IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
{
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
|
||||
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
|
||||
typedef typename TimerTraits<T1>::StoredType T1Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
|
||||
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
|
||||
typedef typename TimerTraits<T2>::StoredType T2Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg3Type T3;
|
||||
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
|
||||
typedef typename TimerTraits<T3>::StoredType T3Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg4Type T4;
|
||||
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
|
||||
typedef typename TimerTraits<T4>::StoredType T4Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg5Type T5;
|
||||
typedef typename TimerTraits<T5>::ParameterType T5Parameter;
|
||||
typedef typename TimerTraits<T5>::StoredType T5Stored;
|
||||
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg6Type T6;
|
||||
typedef typename TimerTraits<T6>::ParameterType T6Parameter;
|
||||
typedef typename TimerTraits<T6>::StoredType T6Stored;
|
||||
|
||||
struct MemFnTimerImplSix : public TimerImplSix<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter,T6Parameter>
|
||||
{
|
||||
MemFnTimerImplSix (MEM_PTR memPtr, OBJ_PTR objPtr)
|
||||
: m_memPtr (memPtr), m_objPtr (objPtr) {}
|
||||
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5,T6Parameter a6) {
|
||||
m_a1 = a1;
|
||||
m_a2 = a2;
|
||||
m_a3 = a3;
|
||||
m_a4 = a4;
|
||||
m_a5 = a5;
|
||||
m_a6 = a6;
|
||||
}
|
||||
virtual EventId Schedule (const Time &delay) {
|
||||
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
|
||||
}
|
||||
MEM_PTR m_memPtr;
|
||||
OBJ_PTR m_objPtr;
|
||||
T1Stored m_a1;
|
||||
T2Stored m_a2;
|
||||
T3Stored m_a3;
|
||||
T4Stored m_a4;
|
||||
T5Stored m_a5;
|
||||
T6Stored m_a6;
|
||||
} *function = new MemFnTimerImplSix (memPtr, objPtr);
|
||||
delete m_impl;
|
||||
m_impl = function;
|
||||
}
|
||||
|
||||
|
||||
template <typename T1>
|
||||
void
|
||||
Timer::SetArguments (T1 a1)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplOne<
|
||||
typename TimerTraits<T1>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void
|
||||
Timer::SetArguments (T1 a1, T2 a2)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplTwo<
|
||||
typename TimerTraits<T1>::ParameterType,
|
||||
typename TimerTraits<T2>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1, a2);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void
|
||||
Timer::SetArguments (T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplThree<
|
||||
typename TimerTraits<T1>::ParameterType,
|
||||
typename TimerTraits<T2>::ParameterType,
|
||||
typename TimerTraits<T3>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1, a2, a3);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void
|
||||
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplFour<
|
||||
typename TimerTraits<T1>::ParameterType,
|
||||
typename TimerTraits<T2>::ParameterType,
|
||||
typename TimerTraits<T3>::ParameterType,
|
||||
typename TimerTraits<T4>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void
|
||||
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplFive<
|
||||
typename TimerTraits<T1>::ParameterType,
|
||||
typename TimerTraits<T2>::ParameterType,
|
||||
typename TimerTraits<T3>::ParameterType,
|
||||
typename TimerTraits<T4>::ParameterType,
|
||||
typename TimerTraits<T5>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
void
|
||||
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
|
||||
{
|
||||
if (m_impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You cannot set the arguments of a Timer before setting its function.");
|
||||
return;
|
||||
}
|
||||
typedef struct TimerImplSix<
|
||||
typename TimerTraits<T1>::ParameterType,
|
||||
typename TimerTraits<T2>::ParameterType,
|
||||
typename TimerTraits<T3>::ParameterType,
|
||||
typename TimerTraits<T4>::ParameterType,
|
||||
typename TimerTraits<T5>::ParameterType,
|
||||
typename TimerTraits<T6>::ParameterType
|
||||
> TimerImplBase;
|
||||
TimerImplBase *impl = dynamic_cast<TimerImplBase *> (m_impl);
|
||||
if (impl == 0)
|
||||
{
|
||||
NS_FATAL_ERROR ("You tried to set Timer arguments incompatible with its function.");
|
||||
return;
|
||||
}
|
||||
impl->SetArguments (a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* TIMER_H */
|
||||
@@ -60,6 +60,8 @@ def build(bld):
|
||||
'event-impl.cc',
|
||||
'simulator.cc',
|
||||
'time-default-value.cc',
|
||||
'timer.cc',
|
||||
'event-garbage-collector.cc',
|
||||
]
|
||||
|
||||
headers = bld.create_obj('ns3header')
|
||||
@@ -73,6 +75,7 @@ def build(bld):
|
||||
'scheduler-factory.h',
|
||||
'simulation-singleton.h',
|
||||
'time-default-value.h',
|
||||
'timer.h'
|
||||
]
|
||||
|
||||
env = bld.env_of_name('default')
|
||||
|
||||
67
utils/mobility-generator.cc
Normal file
67
utils/mobility-generator.cc
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "ns3/ns2-mobility-file-topology.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/mobility-model-notifier.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static void
|
||||
CourseChange (Ptr<const MobilityModel> position)
|
||||
{
|
||||
Position pos = position->Get ();
|
||||
std::cout << Simulator::Now () << ", pos=" << position << ", x=" << pos.x << ", y=" << pos.y
|
||||
<< ", z=" << pos.z << std::endl;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
std::vector<Ptr<Object> > objects;
|
||||
while (argc > 0)
|
||||
{
|
||||
if (strncmp (*argv, "--n=", strlen ("--n=")) == 0)
|
||||
{
|
||||
uint32_t n = atoi (*argv + strlen ("--n="));
|
||||
for (uint32_t i = 0; i < n; i++)
|
||||
{
|
||||
Ptr<MobilityModelNotifier> notifier = Create<MobilityModelNotifier> ();
|
||||
notifier->RegisterListener (MakeCallback (&CourseChange));
|
||||
objects.push_back (notifier);
|
||||
}
|
||||
}
|
||||
else if (strncmp (*argv, "--ns2-topology=",
|
||||
strlen ("--ns2-topology=")) == 0)
|
||||
{
|
||||
const char *filename = *argv + strlen ("--ns2-topology=");
|
||||
Ns2MobilityFileTopology topology (filename);
|
||||
topology.Layout (objects.begin (), objects.end ());
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
137
utils/mobility-visualizer-model.cc
Normal file
137
utils/mobility-visualizer-model.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/mobility-model-notifier.h"
|
||||
#include "ns3/random-topology.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/node-list.h"
|
||||
#include "ns3/rectangle-default-value.h"
|
||||
|
||||
#include "mobility-visualizer.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static Time g_sampleInterval = Seconds (SAMPLE_INTERVAL);
|
||||
static uint32_t g_numNodes = 10;
|
||||
|
||||
template <typename T>
|
||||
static const T* DefaultValueListGet (const std::string &name)
|
||||
{
|
||||
for (DefaultValueList::Iterator iter = DefaultValueList::Begin ();
|
||||
iter != DefaultValueList::End (); iter++)
|
||||
{
|
||||
const DefaultValueBase *value = *iter;
|
||||
if (value->GetName () == name)
|
||||
{
|
||||
return dynamic_cast<const T*> (value);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
Sample ()
|
||||
{
|
||||
|
||||
ViewUpdateData *data = new ViewUpdateData;
|
||||
for (NodeList::Iterator nodeIter = NodeList::Begin (); nodeIter != NodeList::End (); nodeIter++)
|
||||
{
|
||||
Ptr<Node> node = *nodeIter;
|
||||
Ptr<MobilityModel> mobility = node->QueryInterface<MobilityModel> (MobilityModel::iid);
|
||||
Position pos = mobility->Get ();
|
||||
Speed vel = mobility->GetSpeed ();
|
||||
|
||||
NodeUpdate update;
|
||||
update.node = PeekPointer<Node> (node);
|
||||
update.x = pos.x;
|
||||
update.y = pos.y;
|
||||
update.vx = vel.dx;
|
||||
update.vy = vel.dy;
|
||||
data->updateList.push_back (update);
|
||||
}
|
||||
data->time = Simulator::Now ().GetSeconds ();
|
||||
view_update (data);
|
||||
Simulator::Schedule (g_sampleInterval, Sample);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int model_init (int argc, char *argv[], double *x1, double *y1, double *x2, double *y2)
|
||||
{
|
||||
DefaultValue::Bind ("RandomWalk2dMode", "Time");
|
||||
DefaultValue::Bind ("RandomWalk2dTime", "5s");
|
||||
DefaultValue::Bind ("RandomWalk2dSpeed", "Constant:20.0");
|
||||
DefaultValue::Bind ("RandomDirection2dSpeed", "Uniform:10.0:20.0");
|
||||
DefaultValue::Bind ("RandomWalk2dBounds", "0:400:0:300");
|
||||
DefaultValue::Bind ("RandomDirection2dArea", "0:400:0:300");
|
||||
DefaultValue::Bind ("RandomWaypointSpeed", "Uniform:10:30");
|
||||
|
||||
// DefaultValue::Bind ("RandomDiscPositionX", "100");
|
||||
// DefaultValue::Bind ("RandomDiscPositionY", "50");
|
||||
// DefaultValue::Bind ("RandomDiscPositionRho", "Uniform:0:30");
|
||||
|
||||
DefaultValue::Bind ("RandomTopologyPositionType", "RandomRectanglePosition");
|
||||
DefaultValue::Bind ("RandomTopologyMobilityType", "RandomWalk2dMobilityModel");
|
||||
|
||||
// CommandLine::AddArgValue ("sample-interval","sample interval", g_sampleInterval);
|
||||
// CommandLine::AddArgValue ("num-nodes","number of nodes", g_numNodes);
|
||||
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
RandomTopology topology;
|
||||
|
||||
for (uint32_t i = 0; i < g_numNodes; i++)
|
||||
{
|
||||
Ptr<Node> node = Create<Node> ();
|
||||
node->AddInterface (Create<MobilityModelNotifier> ());
|
||||
}
|
||||
|
||||
topology.Layout (NodeList::Begin (), NodeList::End ());
|
||||
|
||||
Simulator::Schedule (g_sampleInterval, Sample);
|
||||
|
||||
ClassId mobType = DefaultValueListGet<ClassIdDefaultValue> ("RandomTopologyMobilityType")->GetValue ();
|
||||
if (mobType.GetName () == "RandomWalk2dMobilityModel")
|
||||
{
|
||||
Rectangle bounds = DefaultValueListGet<RectangleDefaultValue> ("RandomWalk2dBounds")->GetValue ();
|
||||
*x1 = bounds.xMin;
|
||||
*y1 = bounds.yMin;
|
||||
*x2 = bounds.xMax;
|
||||
*y2 = bounds.yMax;
|
||||
std::cout << "RECT " << bounds.xMin << " " << bounds.xMax << " "
|
||||
<< bounds.yMin << " " << bounds.yMax << std::endl;
|
||||
}
|
||||
else if (mobType.GetName () == "RandomDirection2dMobilityModel")
|
||||
{
|
||||
Rectangle bounds = DefaultValueListGet<RectangleDefaultValue> ("RandomDirection2dArea")->GetValue ();
|
||||
*x1 = bounds.xMin;
|
||||
*y1 = bounds.yMin;
|
||||
*x2 = bounds.xMax;
|
||||
*y2 = bounds.yMax;
|
||||
std::cout << "RECT " << bounds.xMin << " " << bounds.xMax << " "
|
||||
<< bounds.yMin << " " << bounds.yMax << std::endl;
|
||||
}
|
||||
else if (mobType.GetName () == "RandomWaypointMobilityModel")
|
||||
{
|
||||
std::cerr << "bounds for RandomWaypointMobilityModel not implemented" << std::endl;
|
||||
//ClassId posType = DefaultValueList::Get<ClassIdDefaultValue> ("RandomWaypointPosition")->GetValue ();
|
||||
std::cout << "?" << std::endl; // too hard to represent an abstract/probabilistic model graphically
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_FATAL_ERROR ("mobility type " << mobType.GetName () << " not supported");
|
||||
}
|
||||
|
||||
std::cerr << g_sampleInterval << std::endl;
|
||||
return 0;
|
||||
}
|
||||
218
utils/mobility-visualizer-view.cc
Normal file
218
utils/mobility-visualizer-view.cc
Normal file
@@ -0,0 +1,218 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <goocanvas.h>
|
||||
#include <glib/gthread.h>
|
||||
|
||||
#include "mobility-visualizer.h"
|
||||
#include <map>
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
#define MAX_QUEUE_LENGTH 100
|
||||
#define MAX_EVENTS 20
|
||||
#define LOOKAHEAD_SECONDS 10
|
||||
|
||||
GtkWidget *g_canvas;
|
||||
|
||||
int model_init (int argc, char *argv[]);
|
||||
|
||||
struct Node
|
||||
{
|
||||
GooCanvasItem *m_item;
|
||||
GooCanvasItem *m_vector;
|
||||
void create ()
|
||||
{
|
||||
GooCanvasItem *root = goo_canvas_get_root_item (GOO_CANVAS (g_canvas));
|
||||
m_item = goo_canvas_ellipse_new (root, 0, 0, 2.0, 2.0,
|
||||
"line_width", 0.5,
|
||||
"stroke_color", "black",
|
||||
"fill_color", "red",
|
||||
NULL);
|
||||
|
||||
m_vector = goo_canvas_polyline_new (root, FALSE, 0,
|
||||
"line_width", 0.3,
|
||||
"stroke_color", "black",
|
||||
"end-arrow", TRUE,
|
||||
"arrow-length", 10.0,
|
||||
"arrow-width", 10.0,
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void update (double x, double y, double vx, double vy)
|
||||
{
|
||||
g_object_set (m_item, "center_x", x, "center_y", y, NULL);
|
||||
|
||||
if (vx == 0 && vy == 0)
|
||||
{
|
||||
GooCanvasPoints *points = goo_canvas_points_new (0);
|
||||
g_object_set (m_vector, "points", points, NULL);
|
||||
goo_canvas_points_unref (points);
|
||||
}
|
||||
else
|
||||
{
|
||||
GooCanvasPoints *points = goo_canvas_points_new (2);
|
||||
|
||||
points->coords[0] = x;
|
||||
points->coords[1] = y;
|
||||
points->coords[2] = x + vx;
|
||||
points->coords[3] = y + vy;
|
||||
|
||||
g_object_set (m_vector, "points", points, NULL);
|
||||
goo_canvas_points_unref (points);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::map<void*, Node> g_nodes;
|
||||
|
||||
GTimeVal initialTime = {-1, -1};
|
||||
gboolean firstTime = TRUE;
|
||||
double g_lookaheadTime = 0;
|
||||
GStaticMutex g_lookaheadTimeMux = G_STATIC_MUTEX_INIT;
|
||||
ViewUpdateData *g_nextData = NULL;
|
||||
|
||||
|
||||
GAsyncQueue *queue;
|
||||
|
||||
#define TIME_SCALE 1
|
||||
|
||||
double get_current_time ()
|
||||
{
|
||||
GTimeVal currTime;
|
||||
g_get_current_time (&currTime);
|
||||
GTimeVal relativeTime;
|
||||
relativeTime.tv_sec = currTime.tv_sec - initialTime.tv_sec + LOOKAHEAD_SECONDS;
|
||||
relativeTime.tv_usec = currTime.tv_usec;
|
||||
g_time_val_add (&relativeTime, -initialTime.tv_usec);
|
||||
return (relativeTime.tv_sec + 1.0e-6*relativeTime.tv_usec)*TIME_SCALE;
|
||||
}
|
||||
|
||||
// called from the simulation thread
|
||||
void view_update (ViewUpdateData *updateData)
|
||||
{
|
||||
while ((g_static_mutex_lock (&g_lookaheadTimeMux), g_lookaheadTime) != 0 and updateData->time >= g_lookaheadTime)
|
||||
{
|
||||
g_static_mutex_unlock (&g_lookaheadTimeMux);
|
||||
g_usleep ((gulong) 10e3);
|
||||
}
|
||||
g_static_mutex_unlock (&g_lookaheadTimeMux);
|
||||
g_async_queue_push (queue, updateData);
|
||||
}
|
||||
|
||||
void view_update_process (ViewUpdateData *updateData)
|
||||
{
|
||||
for (std::vector<NodeUpdate>::const_iterator update
|
||||
= updateData->updateList.begin ();
|
||||
update != updateData->updateList.end ();
|
||||
update++)
|
||||
{
|
||||
if (g_nodes.find (update->node) == g_nodes.end ())
|
||||
{
|
||||
g_nodes[update->node].create ();
|
||||
}
|
||||
g_nodes[update->node].update (update->x, update->y, update->vx, update->vy);
|
||||
}
|
||||
delete updateData;
|
||||
}
|
||||
|
||||
gboolean view_update_consumer ()
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = FALSE;
|
||||
g_get_current_time (&initialTime);
|
||||
}
|
||||
|
||||
double now = get_current_time ();
|
||||
g_static_mutex_lock (&g_lookaheadTimeMux);
|
||||
g_lookaheadTime = now + LOOKAHEAD_SECONDS;
|
||||
g_static_mutex_unlock (&g_lookaheadTimeMux);
|
||||
|
||||
if (!g_nextData)
|
||||
g_nextData = (ViewUpdateData *) g_async_queue_try_pop (queue);
|
||||
|
||||
if (!g_nextData)
|
||||
return TRUE;
|
||||
|
||||
if (g_nextData->time > now)
|
||||
return TRUE;
|
||||
|
||||
do
|
||||
{
|
||||
view_update_process (g_nextData);
|
||||
g_nextData = (ViewUpdateData *) g_async_queue_try_pop (queue);
|
||||
}
|
||||
while (g_nextData && g_nextData->time <= now);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void zoom_changed (GtkAdjustment *adj)
|
||||
{
|
||||
goo_canvas_set_scale (GOO_CANVAS (g_canvas), gtk_adjustment_get_value (adj));
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
g_thread_init (NULL);
|
||||
gtk_init (&argc, &argv);
|
||||
double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
|
||||
model_init (argc, argv, &x1, &y1, &x2, &y2);
|
||||
|
||||
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
|
||||
gtk_widget_show (window);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
GtkWidget *scrolled_win = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
|
||||
gtk_widget_show (scrolled_win);
|
||||
|
||||
GtkWidget *vbox = gtk_vbox_new (FALSE, 4);
|
||||
gtk_widget_show (vbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, 1, 1, 4);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
GtkWidget *hbox = gtk_hbox_new (FALSE, 4);
|
||||
gtk_widget_show (hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, false, false, 4);
|
||||
|
||||
GtkObject *zoom = gtk_adjustment_new (3.0, 0.1, 10.0, 0.2, 1.0, 1.0);
|
||||
gtk_box_pack_start(GTK_BOX (hbox),
|
||||
GTK_WIDGET (g_object_new (GTK_TYPE_SPIN_BUTTON, "adjustment", zoom,
|
||||
"visible", true, "digits", 2, NULL)),
|
||||
false, false, 4);
|
||||
|
||||
g_canvas = goo_canvas_new ();
|
||||
gtk_widget_set_size_request (GTK_WIDGET (g_canvas), 600, 450);
|
||||
goo_canvas_set_bounds (GOO_CANVAS (g_canvas), -500, -500, 500, 500);
|
||||
g_signal_connect (zoom, "value-changed", G_CALLBACK (zoom_changed), NULL);
|
||||
gtk_adjustment_value_changed (GTK_ADJUSTMENT (zoom));
|
||||
gtk_widget_show (g_canvas);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled_win), g_canvas);
|
||||
|
||||
goo_canvas_scroll_to (GOO_CANVAS (g_canvas), 0, 0);
|
||||
|
||||
// create the bounds rectangle
|
||||
if (x1 != x2)
|
||||
{
|
||||
GooCanvasItem *item =
|
||||
goo_canvas_rect_new (goo_canvas_get_root_item (GOO_CANVAS (g_canvas)),
|
||||
x1, y1, x2-x1, y2-y1, NULL);
|
||||
g_object_set (item, "line-width", 1.0, "stroke-color", "grey", NULL);
|
||||
}
|
||||
|
||||
queue = g_async_queue_new ();
|
||||
|
||||
g_timeout_add ((guint) (SAMPLE_INTERVAL*1000), (GSourceFunc) view_update_consumer, NULL);
|
||||
|
||||
g_thread_create (GThreadFunc (ns3::Simulator::Run), NULL, FALSE, NULL);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
23
utils/mobility-visualizer.h
Normal file
23
utils/mobility-visualizer.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#include <vector>
|
||||
|
||||
int model_init (int argc, char *argv[], double *x1, double *y1, double *x2, double *y2);
|
||||
|
||||
struct NodeUpdate
|
||||
{
|
||||
void *node;
|
||||
double x;
|
||||
double y;
|
||||
double vx;
|
||||
double vy;
|
||||
};
|
||||
|
||||
struct ViewUpdateData
|
||||
{
|
||||
std::vector<NodeUpdate> updateList;
|
||||
double time;
|
||||
};
|
||||
|
||||
void view_update (ViewUpdateData *updateData);
|
||||
|
||||
#define SAMPLE_INTERVAL (1.0/30)
|
||||
@@ -1,5 +1,13 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
import os.path
|
||||
|
||||
def configure(conf):
|
||||
check = conf.create_pkgconfig_configurator()
|
||||
check.name = 'goocanvas gthread-2.0'
|
||||
check.uselib = 'MOBILITY_VISUALIZER'
|
||||
check.mandatory = False
|
||||
conf.env['ENABLE_MOBILITY_VISUALIZER'] = check.run()
|
||||
|
||||
|
||||
def build(bld):
|
||||
env = bld.env_of_name('default')
|
||||
@@ -23,3 +31,12 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('print-trace-sources',
|
||||
['internet-node', 'csma-cd', 'point-to-point'])
|
||||
obj.source = 'print-trace-sources.cc'
|
||||
|
||||
if env['ENABLE_MOBILITY_VISUALIZER']:
|
||||
obj = bld.create_ns3_program('mobility-visualizer',
|
||||
['internet-node', 'mobility'])
|
||||
obj.source = ['mobility-visualizer-model.cc', 'mobility-visualizer-view.cc']
|
||||
obj.uselib = 'MOBILITY_VISUALIZER'
|
||||
if os.path.basename(obj.env['CXX']).startswith("g++"):
|
||||
obj.env.append_value('CXXFLAGS', '-fno-strict-aliasing')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user