ruby: add global-objects, add bitfield._whole, make StlVector enumerable

develop
jj 2012-04-13 16:17:56 +02:00
parent f503bf36f4
commit 3044da5887
4 changed files with 116 additions and 41 deletions

@ -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";

@ -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

@ -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);

@ -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}"
}