--- a/examples/visualizer.py Wed Aug 06 17:53:20 2008 +0100
+++ b/examples/visualizer.py Wed Aug 06 17:55:01 2008 +0100
@@ -1,8 +1,9 @@
# -*- python; coding: utf-8 -*-
LAYOUT_ALGORITHM = 'neato' # ['neato'|'dot'|'twopi'|'circo'|'fdp'|'nop']
-NS3_POSITION_SCALE = 100
-
+REPRESENT_CHANNELS_AS_NODES = 1
+NS3_POSITION_SCALE = 1
+SAMPLE_PERIOD = 0.1
import ns3
@@ -11,6 +12,8 @@
import gtk
import goocanvas
import gobject
+ import threading
+ gobject.threads_init()
except ImportError:
pygraphviz = None
goocanvas = None
@@ -85,6 +88,30 @@
self.canvas_item.set_property("data", "M %r %r L %r %r" % (pos1_x, pos1_y, pos2_x, pos2_y))
+
+class SimulationThread(threading.Thread):
+ def __init__(self, viz):
+ super(SimulationThread, self).__init__()
+ assert isinstance(viz, Visualizer)
+ self.viz = viz # Visualizer object
+ self.lock = threading.Lock()
+ self.target_time = 0 # in seconds
+ self.quit = False
+
+ def run(self):
+ while not ns3.Simulator.IsFinished() and not self.quit:
+ #print "sim: Wait for lock"
+ self.lock.acquire()
+ try:
+ #print "sim: Run until: ", self.target_time
+ ns3.pyviz.SimulatorRunUntil(ns3.Seconds(self.target_time))
+ #print "sim: Run until: ", self.target_time, ": finished."
+ finally:
+ self.lock.release()
+ #print "sim: Release lock, Wait for view event."
+ self.viz.view_updated.wait() # wait until the main (view) thread finishes updating the view
+ #print "sim: View updated, loop iteration done."
+
class Visualizer(object):
def __init__(self):
@@ -93,6 +120,9 @@
self.window = None
self.canvas = None
+ self.view_updated = threading.Event()
+ self.simulation = SimulationThread(self)
+
def create_gui(self):
self.window = gtk.Window()
vbox = gtk.VBox(); vbox.show()
@@ -142,10 +172,10 @@
for devI in range(node.GetNDevices()):
device = node.GetDevice(devI)
channel = device.GetChannel()
- if isinstance(channel, ns3.BridgeChannel):
+ if isinstance(channel, (ns3.BridgeChannel, ns3.WifiChannel)):
continue
if channel.GetNDevices() > 2:
- if 1:
+ if REPRESENT_CHANNELS_AS_NODES:
# represent channels as white nodes
if mobility is None:
channel_name = "Channel %s" % hash(channel)
@@ -209,21 +239,46 @@
link.canvas_item.set_property("parent", self.canvas.get_root_item())
def update_view(self):
- pass
+ #print "update_view"
+ for node in self.nodes.itervalues():
+ if node.has_mobility:
+ ns3_node = ns3.NodeList.GetNode(node.node_index)
+ mobility = ns3_node.GetObject(ns3.MobilityModel.GetTypeId())
+ if mobility is not None:
+ pos = mobility.GetPosition()
+ node.set_position(pos.x*NS3_POSITION_SCALE, pos.y*NS3_POSITION_SCALE)
+
+
- def sample_timeout(self):
-
-
+ def update_view_timeout(self):
+ #print "view: update_view_timeout"
+ self.simulation.lock.acquire()
+ try:
+ self.update_view()
+ #print "view: target time increased from %f to %f" % \
+ # (self.simulation.target_time, self.simulation.target_time + SAMPLE_PERIOD)
+ self.simulation.target_time += SAMPLE_PERIOD
+ finally:
+ self.simulation.lock.release()
+ #print "view: self.view_updated.set()"
+ self.view_updated.set()
+ self.view_updated.clear()
+ #print "view: done."
+ return True
- return True
def start(self):
self.create_gui()
self.scan_topology()
self.window.connect("delete-event", lambda window, event: gtk.main_quit())
- gobject.timeout_add(100, sample_timeout)
+ gobject.timeout_add(int(SAMPLE_PERIOD*1e3), self.update_view_timeout)
+ self.simulation.start()
gtk.main()
+ self.simulation.quit = True
+ self.view_updated.set()
+ self.simulation.join()
+
def start():
if goocanvas is None: