ruby: fix anon unions, add some find_* helpers in ruby.rb

develop
jj 2012-04-17 22:42:23 +02:00
parent d901dd28cf
commit 3339fdfea8
3 changed files with 80 additions and 4 deletions

@ -149,6 +149,9 @@ sub render_struct_fields {
for my $field ($type->findnodes('child::ld:field')) { for my $field ($type->findnodes('child::ld:field')) {
my $name = $field->getAttribute('name'); my $name = $field->getAttribute('name');
$name = $field->getAttribute('ld:anon-name') if (!$name); $name = $field->getAttribute('ld:anon-name') if (!$name);
if (!$name and $field->getAttribute('ld:anon-compound')) {
render_struct_fields($field, $cppvar);
}
next if (!$name); next if (!$name);
my $offset = get_offset($cppvar, $name); my $offset = get_offset($cppvar, $name);

@ -374,6 +374,18 @@ static VALUE rb_dfget_global_address(VALUE self, VALUE name)
return rb_uint2inum(addr); return rb_uint2inum(addr);
} }
static VALUE rb_dfget_vtable(VALUE self, VALUE name)
{
uint32_t addr = (uint32_t)Core::getInstance().vinfo->getVTable(rb_string_value_ptr(&name));
return rb_uint2inum(addr);
}
static VALUE rb_dfget_rtti_classname(VALUE self, VALUE objptr)
{
void **ptr = (void**)rb_num2ulong(objptr);
return rb_str_new2(typeid(*ptr).name());
}
@ -569,6 +581,8 @@ static void ruby_bind_dfhack(void) {
rb_define_singleton_method(rb_cDFHack, "resume", RUBY_METHOD_FUNC(rb_dfresume), 0); rb_define_singleton_method(rb_cDFHack, "resume", RUBY_METHOD_FUNC(rb_dfresume), 0);
rb_define_singleton_method(rb_cDFHack, "do_suspend", RUBY_METHOD_FUNC(rb_dfsuspend), 0); rb_define_singleton_method(rb_cDFHack, "do_suspend", RUBY_METHOD_FUNC(rb_dfsuspend), 0);
rb_define_singleton_method(rb_cDFHack, "get_global_address", RUBY_METHOD_FUNC(rb_dfget_global_address), 1); rb_define_singleton_method(rb_cDFHack, "get_global_address", RUBY_METHOD_FUNC(rb_dfget_global_address), 1);
rb_define_singleton_method(rb_cDFHack, "get_vtable", RUBY_METHOD_FUNC(rb_dfget_vtable), 1);
rb_define_singleton_method(rb_cDFHack, "get_rtti_classname", RUBY_METHOD_FUNC(rb_dfget_rtti_classname), 1);
rb_define_singleton_method(rb_cDFHack, "register_dfcommand", RUBY_METHOD_FUNC(rb_dfregister), 2); rb_define_singleton_method(rb_cDFHack, "register_dfcommand", RUBY_METHOD_FUNC(rb_dfregister), 2);
rb_define_singleton_method(rb_cDFHack, "print_str", RUBY_METHOD_FUNC(rb_dfprint_str), 1); rb_define_singleton_method(rb_cDFHack, "print_str", RUBY_METHOD_FUNC(rb_dfprint_str), 1);
rb_define_singleton_method(rb_cDFHack, "print_err", RUBY_METHOD_FUNC(rb_dfprint_err), 1); rb_define_singleton_method(rb_cDFHack, "print_err", RUBY_METHOD_FUNC(rb_dfprint_err), 1);

@ -29,16 +29,75 @@ module DFHack
nil nil
end end
# return an Unit
# 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
case ui.main.mode
when UiSidebarMode::ViewUnits
# nobody selected => idx == 0
v = world.units.other[0][ui_selected_unit]
v if v and v.z == cursor.z
when UiSidebarMode::LookAround
k = ui_look_list.items[ui_look_cursor]
k.unit if k.type == MemHack::UiLookList::Unit
end
elsif what.kind_of?(Integer)
world.units.all.find { |u| u.id == what }
elsif what.respond_to?(:x) or what.respond_to?(:pos)
what = what.pos if what.respond_to?(:pos)
x, y, z = what.x, what.y, what.z
world.units.all.find { |u| u.pos.x == x and u.pos.y == y and u.pos.z == z }
else
raise "what what?"
end
end
# return an Item
# arg similar to find_unit
def find_item(what=nil)
if what == nil
case ui.main.mode
when UiSidebarMode::LookAround
k = ui_look_list.items[ui_look_cursor]
k.item if k.type == MemHack::UiLookList::Item
end
elsif what.kind_of?(Integer)
world.items.all.find { |i| i.id == what }
elsif what.respond_to?(:x) or what.respond_to?(:pos)
what = what.pos if what.respond_to?(:pos)
x, y, z = what.x, what.y, what.z
world.items.all.find { |i| i.pos.x == x and i.pos.y == y and i.pos.z == z }
else
raise "what what?"
end
end
# return a map block
# can 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)
if x >= 0 and x < world.map.x_count and y >= 0 and y < world.map.y_count and z >= 0 and z < world.map.z_count
world.map.block_index[x/16][y/16][z]
end
end
def test def test
puts "starting" puts "starting"
suspend { suspend {
puts "cursor pos: #{cursor.x} #{cursor.y} #{cursor.z}" puts "cursor pos: #{cursor.x} #{cursor.y} #{cursor.z}"
puts "unit[0] id: #{world.units.all[0].id}" if u = find_unit
puts "selected unit id: #{u.id}"
end
if cursor.x >= 0 if b = find_map_block
world.map.block_index[cursor.x/16][cursor.y/16][cursor.z].designation[cursor.x%16][cursor.y%16].dig = TileDigDesignation::Default b.designation[cursor.x%16][cursor.y%16].dig = TileDigDesignation::Default
b.flags.designated = true
puts "dug cursor tile" puts "dug cursor tile"
end end
} }