From 3044da58871c753783657266ad6580ec2739303a Mon Sep 17 00:00:00 2001 From: jj Date: Fri, 13 Apr 2012 16:17:56 +0200 Subject: [PATCH] ruby: add global-objects, add bitfield._whole, make StlVector enumerable --- plugins/ruby/codegen.pl | 65 ++++++++++++++++++++++++---- plugins/ruby/ruby-memstruct.rb | 79 +++++++++++++++++++++------------- plugins/ruby/ruby.cpp | 8 ++++ plugins/ruby/ruby.rb | 5 ++- 4 files changed, 116 insertions(+), 41 deletions(-) diff --git a/plugins/ruby/codegen.pl b/plugins/ruby/codegen.pl index 7afc63da7..1894e883d 100755 --- a/plugins/ruby/codegen.pl +++ b/plugins/ruby/codegen.pl @@ -56,7 +56,7 @@ sub render_global_enum { indent_rb { render_enum_fields($type); }; - push @lines_rb, "end"; + push @lines_rb, "end\n"; } sub render_enum_fields { my ($type) = @_; @@ -84,11 +84,17 @@ sub render_global_bitfield { indent_rb { render_bitfield_fields($type); }; - push @lines_rb, "end"; + push @lines_rb, "end\n"; } sub render_bitfield_fields { my ($type) = @_; + push @lines_rb, "field(:_whole, 0) {"; + indent_rb { + render_item_number($type, ''); + }; + push @lines_rb, "}"; + my $shift = 0; for my $field ($type->findnodes('child::ld:field')) { my $count = $field->getAttribute('count') || 1; @@ -134,7 +140,7 @@ sub render_global_class { indent_rb { render_struct_fields($type, "(*$cppvar)"); }; - push @lines_rb, "end"; + push @lines_rb, "end\n"; } sub render_struct_fields { my ($type, $cppvar) = @_; @@ -153,6 +159,48 @@ sub render_struct_fields { } } +sub render_global_objects { + my (@objects) = @_; + my @global_objects; + + my $sname = 'global_objects'; + my $rbname = rb_ucase($sname); + + %seen_enum_name = (); + + push @lines_cpp, "}" if @include_cpp; + push @lines_cpp, "void cpp_$sname(FILE *fout) {"; + push @include_cpp, $sname; + + push @lines_rb, "class $rbname < Compound"; + indent_rb { + for my $obj (@objects) { + my $oname = $obj->getAttribute('name'); + my $addr = "DFHack.get_global_address('$oname')"; + push @lines_rb, "field(:$oname, $addr) {"; + my $item = $obj->findnodes('child::ld:item')->[0]; + indent_rb { + render_item($item, "(*df::global::$oname)"); + }; + push @lines_rb, "}"; + + push @global_objects, $oname; + } + }; + push @lines_rb, "end"; + + push @lines_rb, "module ::DFHack"; + indent_rb { + push @lines_rb, "Global = GlobalObjects.new._at(0)"; + for my $obj (@global_objects) { + push @lines_rb, "def self.$obj ; Global.$obj ; end"; + push @lines_rb, "def self.$obj=(v) ; Global.$obj = v ; end"; + } + }; + push @lines_rb, "end"; +} + + sub render_item { my ($item, $cppvar) = @_; return if (!$item); @@ -180,7 +228,7 @@ sub render_item_number { my ($item, $cppvar) = @_; my $subtype = $item->getAttribute('ld:subtype'); - $subtype = $item->getAttribute('base-type') if ($subtype eq 'enum'); + $subtype = $item->getAttribute('base-type') if (!$subtype or $subtype eq 'enum' or $subtype eq 'bitfield'); $subtype = 'int32_t' if (!$subtype); if ($subtype eq 'int64_t') { @@ -298,7 +346,6 @@ sub render_item_bytes { } } - sub get_offset { my ($cppvar, $fname) = @_; @@ -373,10 +420,9 @@ for my $name (sort { $a cmp $b } keys %global_types) { } } -for my $obj ($doc->findnodes('/ld:data-definition/ld:global-object')) { - my $name = $obj->getAttribute('name'); - # TODO -} + +render_global_objects($doc->findnodes('/ld:data-definition/ld:global-object')); + open FH, ">$output"; if ($output =~ /\.cpp$/) { @@ -396,6 +442,7 @@ if ($output =~ /\.cpp$/) { print FH " fclose(fout);\n"; print FH " return 0;\n"; print FH "}\n"; + } else { print FH "module DFHack\n"; print FH "module MemHack\n"; diff --git a/plugins/ruby/ruby-memstruct.rb b/plugins/ruby/ruby-memstruct.rb index 6ef3873cf..6f5702832 100644 --- a/plugins/ruby/ruby-memstruct.rb +++ b/plugins/ruby/ruby-memstruct.rb @@ -38,7 +38,12 @@ class Compound < MemStruct end def stl_vector(tglen=nil) - StlVector.new(tglen, (yield if tglen)) + tg = yield if tglen + case tglen + when 1; StlVector8.new(tg) + when 2; StlVector16.new(tg) + else StlVector32.new(tg) + end end def stl_string StlString.new @@ -66,7 +71,7 @@ class Compound < MemStruct def compound(&b) m = Class.new(Compound) m.instance_eval(&b) - m + m.new end end def _set(h) ; h.each { |k, v| send("_#{k}=", v) } ; end @@ -193,6 +198,9 @@ class StaticArray < MemStruct i += @_length if i < 0 tgat(i)._set(v) end + + include Enumerable + def each; (0...length).each { |i| yield self[i] }; end end class StaticString < MemStruct attr_accessor :_length @@ -207,42 +215,24 @@ class StaticString < MemStruct end end -class StlVector < MemStruct - attr_accessor :_tglen, :_tg - def initialize(tglen, tg) - @_tglen = tglen +class StlVector32 < MemStruct + attr_accessor :_tg + def initialize(tg) @_tg = tg end def length - case @_tglen - when 1; DFHack.memory_vector8_length(@_memaddr) - when 2; DFHack.memory_vector16_length(@_memaddr) - else DFHack.memory_vector32_length(@_memaddr) - end + DFHack.memory_vector32_length(@_memaddr) end alias size length - def value_at(idx) - case @_tglen - when 1; DFHack.memory_vector8_at(@_memaddr, idx) - when 2; DFHack.memory_vector16_at(@_memaddr, idx) - else DFHack.memory_vector32_at(@_memaddr, idx) - end + DFHack.memory_vector32_at(@_memaddr, idx) end def insert_at(idx, val) - case @_tglen - when 1; DFHack.memory_vector8_insert(@_memaddr, idx, val) - when 2; DFHack.memory_vector16_insert(@_memaddr, idx, val) - else DFHack.memory_vector32_insert(@_memaddr, idx, val) - end + DFHack.memory_vector32_insert(@_memaddr, idx, val) end def delete_at(idx) - case @_tglen - when 1; DFHack.memory_vector8_delete(@_memaddr, idx) - when 2; DFHack.memory_vector16_delete(@_memaddr, idx) - else DFHack.memory_vector32_delete(@_memaddr, idx) - end + DFHack.memory_vector32_delete(@_memaddr, idx) end def _set(v) @@ -279,8 +269,37 @@ class StlVector < MemStruct end v end - def to_a - (0...length).map { |i| self[i] } + include Enumerable + def each; (0...length).each { |i| yield self[i] }; end +end +class StlVector16 < StlVector32 + def length + DFHack.memory_vector16_length(@_memaddr) + end + alias size length + def value_at(idx) + DFHack.memory_vector16_at(@_memaddr, idx) + end + def insert_at(idx, val) + DFHack.memory_vector16_insert(@_memaddr, idx, val) + end + def delete_at(idx) + DFHack.memory_vector16_delete(@_memaddr, idx) + end +end +class StlVector8 < StlVector32 + def length + DFHack.memory_vector8_length(@_memaddr) + end + alias size length + def value_at(idx) + DFHack.memory_vector8_at(@_memaddr, idx) + end + def insert_at(idx, val) + DFHack.memory_vector8_insert(@_memaddr, idx, val) + end + def delete_at(idx) + DFHack.memory_vector8_delete(@_memaddr, idx) end end class StlString < MemStruct @@ -327,7 +346,7 @@ class Global < MemStruct def initialize(glob) @_glob = glob end - def _at(addr) ; g = const_get(@_glob) ; g._at(addr) ; end + def _at(addr) ; g = DFHack::MemHack.const_get(@_glob) ; g.new._at(addr) ; end end diff --git a/plugins/ruby/ruby.cpp b/plugins/ruby/ruby.cpp index 7230b0d91..8bf42be04 100644 --- a/plugins/ruby/ruby.cpp +++ b/plugins/ruby/ruby.cpp @@ -3,6 +3,7 @@ #include "Console.h" #include "Export.h" #include "PluginManager.h" +#include "VersionInfo.h" #include "DataDefs.h" #include "df/world.h" @@ -367,6 +368,12 @@ static VALUE rb_dfregister(VALUE self, VALUE name, VALUE descr) rb_raise(rb_eRuntimeError, "not implemented"); } +static VALUE rb_dfget_global_address(VALUE self, VALUE name) +{ + uint32_t addr = Core::getInstance().vinfo->getAddress(rb_string_value_ptr(&name)); + return rb_uint2inum(addr); +} + @@ -561,6 +568,7 @@ static void ruby_bind_dfhack(void) { rb_define_singleton_method(rb_cDFHack, "onupdate_active=", RUBY_METHOD_FUNC(rb_dfonupdateactiveset), 1); 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, "get_global_address", RUBY_METHOD_FUNC(rb_dfget_global_address), 1); 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_err", RUBY_METHOD_FUNC(rb_dfprint_err), 1); diff --git a/plugins/ruby/ruby.rb b/plugins/ruby/ruby.rb index dcd6ff8b6..3decef958 100644 --- a/plugins/ruby/ruby.rb +++ b/plugins/ruby/ruby.rb @@ -1,3 +1,5 @@ +require 'hack/ruby-autogen' + module DFHack class << self def suspend @@ -29,8 +31,7 @@ module DFHack puts "starting" suspend { - c = cursor - puts "cursor pos: #{c.x} #{c.y} #{c.z}" + puts "cursor pos: #{cursor.x} #{cursor.y} #{cursor.z}" puts "unit[0] id: #{world.units.all[0].id}" }