From 66891fd23ce64e76c2bcb9aff487cb0a9c30e4a0 Mon Sep 17 00:00:00 2001 From: jj Date: Fri, 20 Apr 2012 17:33:48 +0200 Subject: [PATCH] ruby: tweak onupdate, fix some inspects, add inverse ENUM --- plugins/ruby/codegen.pl | 6 +- plugins/ruby/ruby-memstruct.rb | 7 ++ plugins/ruby/ruby.cpp | 2 +- plugins/ruby/ruby.rb | 120 +++++++++++++++++++++++++++------ 4 files changed, 114 insertions(+), 21 deletions(-) diff --git a/plugins/ruby/codegen.pl b/plugins/ruby/codegen.pl index 1baa15365..72ef06156 100755 --- a/plugins/ruby/codegen.pl +++ b/plugins/ruby/codegen.pl @@ -62,6 +62,10 @@ sub render_enum_fields { my ($type) = @_; my $value = -1; + my $idxname = 'ENUM'; + $idxname .= '_' while ($seen_enum_name{$idxname}); + $seen_enum_name{$idxname}++; + push @lines_rb, "$idxname = {}"; for my $item ($type->findnodes('child::enum-item')) { $value = $item->getAttribute('value') || ($value+1); my $elemname = $item->getAttribute('name'); # || "unk_$value"; @@ -70,7 +74,7 @@ sub render_enum_fields { my $rbelemname = rb_ucase($elemname); $rbelemname .= '_' while ($seen_enum_name{$rbelemname}); $seen_enum_name{$rbelemname}++; - push @lines_rb, "$rbelemname = $value"; + push @lines_rb, "$rbelemname = $value ; ${idxname}[$value] = :$rbelemname"; } } } diff --git a/plugins/ruby/ruby-memstruct.rb b/plugins/ruby/ruby-memstruct.rb index d20c22c9d..c18a52bed 100644 --- a/plugins/ruby/ruby-memstruct.rb +++ b/plugins/ruby/ruby-memstruct.rb @@ -204,6 +204,9 @@ class Pointer < MemStruct def method_missing(*a) _getv.send(*a) end + def respond_to?(q) + _getv.respond_to?(q) + end def inspect cn = (@_tg ? @_tg.class.name.sub(/^DFHack::/, '') : '') @@ -412,10 +415,12 @@ class StlDeque < MemStruct @_tg = tg end # TODO + def inspect ; "#" ; end end class DfFlagarray < MemStruct # TODO + def inspect ; "#" ; end end class DfArray < Compound attr_accessor :_tglen, :_tg @@ -453,6 +458,8 @@ class DfLinkedList < MemStruct def initialize(tg) @_tg = tg end + # TODO + def inspect ; "#" ; end end class Global < MemStruct diff --git a/plugins/ruby/ruby.cpp b/plugins/ruby/ruby.cpp index 0b0df486f..b60b5007b 100644 --- a/plugins/ruby/ruby.cpp +++ b/plugins/ruby/ruby.cpp @@ -296,7 +296,7 @@ static VALUE rb_dfonupdateactive(VALUE self) static VALUE rb_dfonupdateactiveset(VALUE self, VALUE val) { - onupdate_active = (val == Qtrue || val == INT2FIX(1)) ? 1 : 0; + onupdate_active = (val == Qfalse || val == Qnil || val == INT2FIX(0)) ? 0 : 1; return Qtrue; } diff --git a/plugins/ruby/ruby.rb b/plugins/ruby/ruby.rb index 976b3e1ac..bb402404b 100644 --- a/plugins/ruby/ruby.rb +++ b/plugins/ruby/ruby.rb @@ -2,6 +2,7 @@ require 'hack/ruby-autogen' module DFHack class << self + # update the ruby.cpp version to accept a block def suspend if block_given? begin @@ -15,26 +16,48 @@ module DFHack end end - def puts(*a) - a.flatten.each { |l| - print_str(l.to_s.chomp + "\n") - } - nil + module ::Kernel + def puts(*a) + a.flatten.each { |l| + DFHack.print_str(l.to_s.chomp + "\n") + } + nil + end + + def puts_err(*a) + a.flatten.each { |l| + DFHack.print_err(l.to_s.chomp + "\n") + } + nil + end end - def puts_err(*a) - a.flatten.each { |l| - print_err(l.to_s.chomp + "\n") - } - nil + # register a callback to be called every gframe or more + # ex: DFHack.onupdate_register { DFHack.world.units[0].counters.job_counter = 0 } + def onupdate_register(&b) + @onupdate_list ||= [] + @onupdate_list << b + DFHack.onupdate_active = true + @onupdate_list.last + end + + # delete the callback for onupdate ; use the value returned by onupdate_register + def onupdate_unregister(b) + @onupdate_list.delete b + DFHack.onupdate_active = false if @onupdate_list.empty? + end + + # this method is called by dfhack every 'onupdate' if onupdate_active is true + def onupdate + @onupdate_list.each { |cb| cb.call } end # return an Unit - # with no arg, return currently selected unit in df UI (v or k menu) + # with no arg, return currently selected unit in df UI ('v' or 'k' menu) # with numeric arg, search unit by unit.id # with an argument that respond to x/y/z (eg cursor), find first unit at this position - def find_unit(what=nil) - if what == nil + def find_unit(what=:selected) + if what == :selected case ui.main.mode when UiSidebarMode::ViewUnits # nobody selected => idx == 0 @@ -56,9 +79,9 @@ module DFHack end # return an Item - # arg similar to find_unit - def find_item(what=nil) - if what == nil + # arg similar to find_unit; no arg = 'k' menu + def find_item(what=:selected) + if what == :selected case ui.main.mode when UiSidebarMode::LookAround k = ui_look_list.items[ui_look_cursor] @@ -75,8 +98,8 @@ module DFHack end end - # return a map block - # can use find_map_block(cursor) or anything that respond to x/y/z + # return a map block by tile coordinates + # you can also use find_map_block(cursor) or anything that respond to x/y/z def find_map_block(x=cursor, y=nil, z=nil) x = x.pos if x.respond_to?(:pos) x, y, z = x.x, x.y, x.z if x.respond_to?(:x) @@ -85,6 +108,65 @@ module DFHack end end + def center_viewscreen(x, y=nil, z=nil) + x = x.pos if x.respond_to?(:pos) + x, y, z = x.x, x.y, x.z if x.respond_to?(:x) + + # compute screen 'map' size (tiles) + menuwidth = ui_menu_width + # ui_menu_width shows only the 'tab' status + menuwidth = 1 if menuwidth == 2 and ui_area_map_width == 2 and cursor.x != -30000 + menuwidth = 2 if menuwidth == 3 and cursor.x != -30000 + w_w = gps.dimx - 2 + w_h = gps.dimy - 2 + case menuwidth + when 1; w_w -= 55 + when 2; w_w -= (ui_area_map_width == 2 ? 24 : 31) + end + + # center view + w_x = x - w_w/2 + w_y = y - w_h/2 + w_z = z + # round view coordinates (optional) + #w_x -= w_x % 10 + #w_y -= w_y % 10 + # crop to map limits + w_x = [[w_x, world.map.x_count - w_w].min, 0].max + w_y = [[w_y, world.map.y_count - w_h].min, 0].max + + self.window_x = w_x + self.window_y = w_y + self.window_z = w_z + + if cursor.x != -30000 + cursor.x, cursor.y, cursor.z = x, y, z + end + end + + # add an announcement + # color = integer, bright = bool + def add_announcement(str, color=0, bright=false) + cont = false + while str.length > 0 + rep = Report.cpp_alloc + rep.color = color + rep.bright = ((bright && bright != 0) ? 1 : 0) + rep.year = cur_year + rep.time = cur_year_tick + rep.flags.continuation = cont + cont = true + rep.flags.announcement = true + rep.text = str[0, 73] + str = str[73..-1].to_s + rep.id = world.status.next_report_id + world.status.next_report_id += 1 + world.status.reports << rep + world.status.announcements << rep + world.status.display_timer = 2000 + end + end + def test puts "starting" @@ -107,7 +189,7 @@ module DFHack end end -# alias, so we can write 'df.world.units.all[0]' +# global alias so we can write 'df.world.units.all[0]' def df DFHack end