Permalink
Browse files

Checkpoint for merge

  • Loading branch information...
1 parent 7c59829 commit 600bac68e47e51e8e3134cd38bb9ece701899518 Cyrus Hall committed Mar 14, 2007
Showing with 227 additions and 43 deletions.
  1. +10 −1 goviz
  2. +4 −1 lib/gosim.rb
  3. +151 −29 lib/gosim/data.rb
  4. +26 −0 lib/gosim/event_reader.rb
  5. +36 −12 lib/gosim/view.rb
View
11 goviz
@@ -4,11 +4,20 @@ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
require 'rational'
require 'gosim/view'
+require 'rdoc/usage'
if ARGV[0] and File.exists?(ARGV[0])
- $LOAD_PATH.unshift(File.expand_path(File.dirname(ARGV[0])))
+# $LOAD_PATH.unshift(File.expand_path(File.dirname(ARGV[0])))
puts "Loading simulation file: #{File.basename(ARGV[0])}"
+
+ # Tell the view that we are in live sim mode
+ GoSim::View::instance.live = true
+
+ # Since there will be events published to the DataSet classes, we need to
+ # make sure to correctly flush the Zlib stream
+ at_exit { GoSim::Data::DataSetWriter.instance.close() }
+
load ARGV[0]
end
View
@@ -1,12 +1,14 @@
require 'logger'
require 'singleton'
require 'observer'
+require 'yaml'
+require 'zlib'
require 'pqueue'
require 'gsl'
module GoSim
- MAX_INT = 2**30
+ MAX_INT = 2**31
module Base
# TODO: Figure out what we want to do for a logging framework.
@@ -35,6 +37,7 @@ def verbose
require 'gosim/simulation'
require 'gosim/network'
+require 'gosim/event_reader'
require 'gosim/data'
# Make the logger report simulation time instead of real-time.
View
@@ -1,44 +1,166 @@
module GoSim
- class DataSet
- @@sets = {}
- @@handlers = {}
+ module Data
- class << self
- def flush_all
- @@sets.values.each {|s| s.flush }
+ VIEW_MOD = :view_module
+ TIME_MOD = :time
+
+ class DataSetReader < GoSim::Entity
+ def initialize(trace)
+ super()
+ @tracefile = trace
+ reopen()
+ @sim = Simulation::instance
+ @sim.add_observer(self)
+ @requires_done = false
end
- def add_handler(key, &block)
- @@handlers[key] ||= []
- @@handlers[key] << block
+ def update
+ reset
+ reopen
end
- def [](set)
- @@sets[set]
+ def reopen
+ @trace = EventReader.new(@tracefile)
+ e = @trace.next
+ while e[0] == VIEW_MOD
+ if !@requires_done
+ begin
+ require "#{e[1]}"
+ rescue LoadError => e
+ view = GoSim::View.instance
+ view.show_error("Could not find view module - please select a " +
+ "view\nmodule that is compatable with the data set.")
+ file = view.get_file_dialog
+ load file
+ end
+ end
+ e = @trace.next
+ end
+
+ @requires_done = true
+
+ if e[0] == TIME_MOD
+ @time = e[1]
+ else
+ raise Exception.new("InvalidTrace")
+ end
end
- end
- def initialize(name, location='./')
- @sim = Simulation.instance
- @name = name.to_sym
- @@sets[@name] = self
+ def queue_to(time)
+ while time > @time
+ event = @trace.next
+ break if event.nil?
- @location = location
- @data_file = File.open(File.join(location, name.to_s), "w")
- end
+ puts "Event read #{event.inspect}"
+
+ if event[0] == TIME_MOD
+ @time = event[1]
+ puts "Set time to #{@time}"
+ else
+ @sim.schedule_event(:data_set_add, @sid, @time - @sim.time, event)
+ end
+ end
- # TODO: Maybe we want to log while also visualizing?
- def log(*args)
- if @@handlers[@name]
- @@handlers[@name].each {|h| h.call(*args) }
- elsif @data_file
- @data_file.write(@sim.time.to_s + ': ' + args.join(', ') + "\n")
+ return @time
end
- end
- def flush
- @data_file.flush
+ def handle_data_set_add(event)
+ if !DataSet[event[0]].nil?
+ puts "#{event.inspect}"
+ DataSet[event[0]].log(event[1]) #.each { | h | h.call(*event[1]) }
+ end
+ end
+ end #DataSetReader
+
+ class DataSetWriter
+ include Singleton
+
+ def initialize
+ @running = false
+ @last_time = -1
+ @file = nil
+ @sim = Simulation::instance
+ @sim.add_observer(self)
+ end
+
+ def update
+ @file.close
+ rewind
+ end
+
+ def rewind
+ @file = Zlib::GzipWriter.open(@output_file)
+ end
+
+ def set_output_file(file = './output/trace.gz')
+ if !@running
+ @output_file = file
+ rewind
+ end
+ end
+
+ def add_view_mod(name)
+ @file.write([VIEW_MOD, name].to_yaml) if @file && @sim.time == 0
+ end
+
+ def flush_all
+ @file.flush if !@file.nil?
+ end
+
+ def log(sym, args)
+ if(!@file.nil?)
+ if(@sim.time > @last_time)
+ @last_time = @sim.time
+ @file.write([TIME_MOD, @sim.time].to_yaml)
+ end
+
+ @file.write([sym, args].to_yaml)
+ end
+ end #DataSetWriter
+
+ def close
+ flush_all
+ @file.close if !@file.nil?
+ end
end
- end
+
+ class DataSet
+ @@sets = {}
+ @@handlers = {}
+
+ class << self
+
+ def add_handler(key, &block)
+ if !@@handlers.has_key?(key)
+ DataSet.new(key)
+ end
+
+ @@handlers[key] ||= []
+ @@handlers[key] << block
+ end
+
+ def [](set)
+ @@sets[set]
+ end
+ end
+
+ def initialize(name)
+ @name = name.to_sym
+ @@sets[@name] = self
+ end
+
+ # TODO: Maybe we want to log while also visualizing?
+ # DataSet::flush_all
+ def log(*args)
+ if @@handlers[@name]
+ @@handlers[@name].each {|h| h.call(*args) }
+ end
+
+ # Always log for now.
+ DataSetWriter::instance.log(@name, args)
+ end
+ end #DataSet
+
+ end #Data
end
View
@@ -0,0 +1,26 @@
+module GoSim
+ class EventReader
+ def initialize(filename)
+ @trace = Zlib::GzipReader.open(filename)
+ @trace.readline
+ end
+
+ def next
+ return nil if @trace.eof?
+
+ yaml_str = "---\n"
+
+ while(true && !@trace.eof?)
+ line = @trace.readline
+ break if line =~ /---/
+ yaml_str += line
+ end
+
+ return YAML::load(yaml_str)
+ end
+
+ def eof?
+ return @trace.eof?
+ end
+ end
+end
View
@@ -29,6 +29,8 @@ def initialize
@glade['map_scroller'].add(@space_map)
@sim = Simulation.instance
+ @virt_time = 0
+ @live = false # ie, from a trace file
@reset_handlers = []
@@ -48,11 +50,16 @@ def initialize
@play_stop_lbl = @glade["play_stop"]
end
+ def live=(arg)
+ @live = arg if @sim.time == 0
+ end
+
def run
Gtk.main
end
def on_quit
+ GoSim::Data::DataSetWriter::instance.flush_all
Gtk.main_quit
end
@@ -70,23 +77,33 @@ def on_delete(widget)
def on_open_trace
file = get_file_dialog("Open trace...")
if(!file.nil?)
-
-
+ puts "opening #{file}"
+ @trace_events = GoSim::Data::DataSetReader.new(file)
end
end
-
def on_open_live_sim
show_error("Opening of simulations not currently supported from GUI.\nUse the command line.")
end
def on_time_forward
@forwarding = true
- Thread.new {
- @sim.run(@sim.time + @ticks_per_sec)
- }
- @cur_time.text = @sim.time.to_s
+ if !@live
+ if @trace_events.nil?
+ show_error("No trace has been opened.")
+ return
+ else
+ @trace_events.queue_to(@virt_time + @ticks_per_sec)
+ end
+ end
+
+ Thread.new do
+ @sim.run(@virt_time + @ticks_per_sec)
+ end
+
+ @virt_time += @ticks_per_sec
+ @cur_time.text = @virt_time.to_s
Gtk.main_iteration while Gtk.events_pending?
@forwarding = false
@@ -97,7 +114,7 @@ def on_time_back
end
def on_time_play
- print "play button\n"
+# print "play button\n"
@playing = !@playing
if @playing
@@ -124,7 +141,8 @@ def on_time_reset
on_time_play if @playing
@sim.reset
- @cur_time.text = @sim.time.to_s
+ @virt_time = 0
+ @cur_time.text = @virt_time.to_s
@reset_handlers.each {|h| h.call }
end
@@ -133,9 +151,7 @@ def add_reset_handler(&block)
@reset_handlers << block
end
- private
-
- def show_error(mesg, title = "Error")
+ def show_message(mesg, title = "Message")
# Create the dialog
dialog = Gtk::Dialog.new(title, @main_window,
Gtk::Dialog::DESTROY_WITH_PARENT,
@@ -147,9 +163,14 @@ def show_error(mesg, title = "Error")
# Add the message in a label, and show everything we've added to the dialog.
dialog.vbox.add(Gtk::Label.new(("\n" + mesg + "\n").gsub("\n", " \n ")))
+ #dialog.run
dialog.show_all
end
+ def show_error(mesg, title = "Error")
+ show_message(mesg, title)
+ end
+
def get_file_dialog(dialog_name = "Open...")
file = nil
fs = Gtk::FileChooserDialog.new(dialog_name, @main_window,
@@ -160,6 +181,8 @@ def get_file_dialog(dialog_name = "Open...")
file = fs.filename
end
fs.destroy
+
+ return file
end
end
@@ -228,4 +251,5 @@ def log(text)
end
=end
+
end

0 comments on commit 600bac6

Please sign in to comment.