Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'gosu'
- FONT_HEIGHT = 24
- def hack_in_new_class_or_module_lol(new)
- if new.end_with?("::")
- eval "module #{new.chomp("::")}; end"
- else
- eval "class #{new}; end"
- end
- end
- class Container
- attr_reader :x,:y,:child
- def initialize(x,y,kind,type,name,child)
- @x,@y,@kind,@type,@name,@child=x,y,kind,type,name,child
- end
- def draw(scx)
- return if @x-scx>$main.width or @x+w-scx<0
- h=FONT_HEIGHT
- Gosu::draw_quad(@x,@y,c=(@selected ? 0xffc09000 : contains? ? 0xff208020 : 0xff404040),@x+w,@y,c,@x+w,@y+h,c,@x,@y+h,c,0)
- $font.draw(text,@x+2,@y+2,1)
- end
- def w
- @w ||= $font.text_width(text)+4
- end
- def text
- @text ||=
- case @kind
- when :hash
- @name.to_s + " => " + _child
- when :array
- @name.to_s + ": " + _child
- when :var
- @name.to_s + " = " + _child
- when :root
- "FILE ROOT"
- else
- @name
- end
- end
- def _child
- @_child ||= (@child.class==Hash ? "{}" : @child.class==Array ? "[]" : @child.to_s)
- end
- def click(x,y)
- if x.between?(@x,@x+w) and y.between?(@y,@y+FONT_HEIGHT)
- $main.add_level(self)
- end
- end
- def contains?
- @contains ||= (@child.class==Hash && !@child.empty? or @child.class==Array && !@child.empty? or !@child.instance_variables.empty?)
- end
- def select
- @selected=true
- end
- def unselect
- @selected=nil
- end
- end
- class PlaceholderClass
- def initialize(name)
- @name=name
- end
- def to_s
- "/#{@name}/"
- end
- def instance_variables
- []
- end
- end
- class String
- def to_s
- return "\"#{self}\""
- end
- end
- class Symbol
- def to_s
- return ":#{self.id2name}"
- end
- end
- class GameWindow < Gosu::Window
- def initialize
- super(800, 600, false)
- self.caption = "Marshal Explorer"
- $font=Gosu::Font.new(self,"Courier New",FONT_HEIGHT)
- reset
- end
- def update
- if @drag
- @scx=@drag[0]-(mouse_x-@drag[2])*(button_down?(Gosu::KbLeftShift) ? 10 : 1)
- @scy=@drag[1]-(mouse_y-@drag[3])
- end
- end
- def draw
- translate(-@scx,-@scy) do
- @hierarchy.flatten.each do |c|
- c.draw(@scx)
- end
- end
- $font.draw("Drop file into window to inspect", 16, 16, 100, 1, 1, Gosu::Color::RED) if @hierarchy.flatten.length == 1
- end
- def button_down(id)
- if id==Gosu::MsLeft
- @hierarchy.flatten.each do |c|
- c.click(mouse_x+@scx,mouse_y+@scy)
- end
- end
- if id==Gosu::MsRight
- @drag=[@scx,@scy,mouse_x,mouse_y]
- end
- if id==Gosu::KbHome
- @scx=@scy=-64
- end
- end
- def button_up(id)
- if id==Gosu::MsRight
- @drag=nil
- end
- end
- def container?(item)
- item.class==Array or item.class==Hash or item.class==HashKey && container?(item.v)
- end
- def raze(base)
- base_level=@hierarchy.index(@hierarchy.find{|h| h.include?(base)})
- if base_level
- @hierarchy.delete_if{|ar| @hierarchy.index(ar)>base_level}
- @hierarchy.last.each{|h| h.unselect}
- end
- base.select if base
- @hierarchy << []
- end
- def add_level(base)
- return if base and !base.contains?
- if !base
- raze(base)
- @hierarchy.last << Container.new(0,0,:root,$data.class,"ROOT",$data)
- elsif base.child.class==Hash
- raze(base)
- x=base.x
- base.child.each_pair do |k,v|
- @hierarchy.last << Container.new(x,base.y+FONT_HEIGHT+8,:hash,v.class,k,v)
- x+=@hierarchy.last.last.w+8
- end
- elsif base.child.class==Array
- raze(base)
- x=base.x
- i=0
- base.child.each do |v|
- @hierarchy.last << Container.new(x,base.y+FONT_HEIGHT+8,:array,v.class,i,v)
- x+=@hierarchy.last.last.w+8
- i+=1
- end
- else
- raze(base)
- x=base.x
- base.child.instance_variables.each do |k|
- v=base.child.instance_variable_get(k)
- @hierarchy.last << Container.new(x,base.y+FONT_HEIGHT+8,:var,v.class,k,v)
- x+=@hierarchy.last.last.w+8
- end
- end
- end
- def needs_cursor?
- true
- end
- def reset
- @hierarchy=[]
- add_level(nil)
- @scx=@scy=-64
- end
- def drop(file)
- $data = []
- $file = nil
- while true
- begin
- $file ||= File.new(file, "r")
- $data << Marshal.load($file)
- rescue ArgumentError => ae #undefined class/module
- next if !ae.to_s.start_with?("undefined")
- break if ae.to_s.include?("dump format error")
- $file=nil
- $data.clear
- new=ae.to_s.split.last
- hack_in_new_class_or_module_lol(new)
- rescue TypeError => te #class needs to have method _load
- next if !te.to_s.start_with?("class")
- new=te.to_s.split[1]
- $file=nil
- $data.clear
- eval "class #{new}; def self._load(data); return PlaceholderClass.new('#{new}') end end"
- rescue EOFError
- break
- end
- end
- reset
- end
- end
- begin
- require_relative "ClassSupply.rb"
- rescue LoadError
- end
- ($main=GameWindow.new).show
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement