ruby: set everything up

develop
jj 2012-04-12 19:12:46 +02:00
parent ac0d878b69
commit f503bf36f4
2 changed files with 360 additions and 225 deletions

@ -77,36 +77,65 @@ class Number < MemStruct
@_bits = bits
@_signed = signed
end
def _get
v = case @_bits
when 32; DFHack.memory_read_int32(@_memaddr)
when 16; DFHack.memory_read_int16(@_memaddr)
when 8; DFHack.memory_read_int8( @_memaddr)
when 64;(DFHack.memory_read_int32(@_memaddr) & 0xffffffff) + (DFHack.memory_read_int32(@_memaddr+4) << 32)
end
v &= (1 << @_bits) - 1 if not @_signed
v
end
def _set(v)
case @_bits
when 32; DFHack.memory_write_int32(@_memaddr, v)
when 16; DFHack.memory_write_int16(@_memaddr, v)
when 8; DFHack.memory_write_int8( @_memaddr, v)
when 64; DFHack.memory_write_int32(@_memaddr, v & 0xffffffff) ; DFHack.memory_write_int32(@memaddr+4, v>>32)
end
end
end
class Float < MemStruct
# _get/_set defined in ruby.cpp
def _get
DFHack.memory_read_float(@_memaddr)
end
class BitField < Number
def _set(v)
DFHack.memory_write_float(@_memaddr, v)
end
end
class BitField < MemStruct
attr_accessor :_shift, :_len
def initialize(shift, len)
@_shift = shift
@_len = len
super(32, false)
end
def _mask
(1 << @_len) - 1
end
def _get(whole=false)
v = super()
return v if whole
v = (v >> @_shift) % (1 << @_len)
def _get
v = DFHack.memory_read_int32(@_memaddr) >> @_shift
if @_len == 1
v == 0 ? false : true
((v & 1) == 0) ? false : true
else
v
v & _mask
end
end
def _set(v)
if @_len == 1
# allow 'bit = 0'
v = (v && v != 0 ? 1 : 0)
end
v = ((v % (1 << @_len)) << @_shift)
v = (v & _mask) << @_shift
ori = _get(true)
super(ori - (ori & (-1 % (1 << @_len)) << @_shift) + v)
ori = DFHack.memory_read_int32(@_memaddr) & 0xffffffff
DFHack.memory_write_int32(@_memaddr, ori - (ori & ((-1 & _mask) << @_shift)) + v)
end
end
@ -116,6 +145,30 @@ class Pointer < MemStruct
@_tglen = tglen
@_tg = tg
end
def _getp
DFHack.memory_read_int32(@_memaddr) & 0xffffffff
end
def _setp(v)
DFHack.memory_write_int32(@_memaddr, v)
end
# _getp/_setp defined in ruby.cpp, access the pointer value
def _get
addr = _getp
return if addr == 0 # XXX are there pointers with -1 as 'empty' value ?
@_tg._at(addr)._get
end
def _set(v)
addr = _getp
raise 'null pointer' if addr == 0 # TODO malloc ?
@_tg._at(addr)._set(v)
end
# the pointer is invisible, forward all methods to the pointed object
def method_missing(*a)
_get.send(*a)
end
end
class StaticArray < MemStruct
attr_accessor :_tglen, :_length, :_tg
@ -124,21 +177,21 @@ class StaticArray < MemStruct
@_length = length
@_tg = tg
end
def _set(a) ; a.each_with_index { |v, i| self[i] = v } ; end
def _set(a)
a.each_with_index { |v, i| self[i] = v }
end
alias length _length
alias size _length
def _tgat(i)
tg._at(@_memaddr + i*@_tglen)
@_tg._at(@_memaddr + i*@_tglen) if i >= 0 and i < @_length
end
def [](i)
if (i > 0) or (@_length and i < @_length)
i += @_length if i < 0
tgat(i)._get
end
end
def []=(i, v)
if (i > 0) or (@_length and i < @_length)
tgat(i)._set
end
i += @_length if i < 0
tgat(i)._set(v)
end
end
class StaticString < MemStruct
@ -146,6 +199,12 @@ class StaticString < MemStruct
def initialize(length)
@_length = length
end
def _get
DFHack.memory_read(@_memaddr, @_length)
end
def _set(v)
DFHack.memory_write(@_memaddr, v[0, @_length])
end
end
class StlVector < MemStruct
@ -154,10 +213,87 @@ class StlVector < MemStruct
@_tglen = tglen
@_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
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
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
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
end
def _set(v)
delete_at(length-1) while length > v.length # match lengthes
v.each_with_index { |e, i| self[i] = e } # patch entries
end
def clear
delete_at(length-1) while length > 0
end
def [](idx)
idx += length if idx < 0
@_tg._at(value_at(idx)) if idx >= 0 and idx < length
end
def []=(idx, v)
idx += length if idx < 0
if idx >= length
insert_at(idx, v)
elsif idx < 0
raise 'invalid idx'
else
set_value_at(idx, v)
end
end
def <<(v)
insert_at(length, v)
self
end
def pop
l = length
if l > 0
v = self[l-1]
delete_at(l-1)
end
v
end
def to_a
(0...length).map { |i| self[i] }
end
end
class StlString < MemStruct
def _get
DFHack.memory_read_stlstring(@_memaddr)
end
def _set(v)
DFHack.memory_write_stlstring(@_memaddr, v)
end
end
class StlBitVector < MemStruct
# TODO
end
class StlDeque < MemStruct
attr_accessor :_tglen, :_tg
@ -168,6 +304,7 @@ class StlDeque < MemStruct
end
class DfFlagarray < MemStruct
# TODO
end
class DfArray < MemStruct
attr_accessor :_tglen, :_tg
@ -175,6 +312,8 @@ class DfArray < MemStruct
@_tglen = tglen
@_tg = tg
end
# TODO
end
class DfLinkedList < MemStruct
attr_accessor :_tg

@ -12,14 +12,16 @@
#include <ruby.h>
using std::string;
using std::vector;
using namespace DFHack;
// DFHack stuff
static void df_rubythread(void*);
static command_result df_rubyload(color_ostream &out, vector <string> & parameters);
static command_result df_rubyeval(color_ostream &out, vector <string> & parameters);
static command_result df_rubyload(color_ostream &out, std::vector <std::string> & parameters);
static command_result df_rubyeval(color_ostream &out, std::vector <std::string> & parameters);
static void ruby_bind_dfhack(void);
// inter-thread communication stuff
@ -39,7 +41,6 @@ static command_result r_result;
static tthread::thread *r_thread;
static int onupdate_active;
// dfhack interface
DFHACK_PLUGIN("ruby")
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
@ -122,7 +123,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
return ret;
}
static command_result df_rubyload(color_ostream &out, vector <string> & parameters)
static command_result df_rubyload(color_ostream &out, std::vector <std::string> & parameters)
{
command_result ret;
@ -154,7 +155,7 @@ static command_result df_rubyload(color_ostream &out, vector <string> & paramete
return ret;
}
static command_result df_rubyeval(color_ostream &out, vector <string> & parameters)
static command_result df_rubyeval(color_ostream &out, std::vector <std::string> & parameters)
{
command_result ret;
@ -195,6 +196,8 @@ static command_result df_rubyeval(color_ostream &out, vector <string> & paramete
// ruby stuff
// ruby thread code
static void dump_rb_error(void)
{
@ -275,12 +278,12 @@ static void df_rubythread(void *p)
// ruby classes
// main DFHack ruby module
static VALUE rb_cDFHack;
static VALUE rb_c_WrapData;
// DFHack methods
// DFHack module ruby methods, binds specific dfhack methods
// enable/disable calls to DFHack.onupdate()
static VALUE rb_dfonupdateactive(VALUE self)
{
@ -308,16 +311,33 @@ static VALUE rb_dfsuspend(VALUE self)
return Qtrue;
}
/*
static VALUE rb_dfgetversion(VALUE self)
// returns the delta to apply to dfhack xml addrs wrt actual memory addresses
// usage: real_addr = addr_from_xml + this_delta;
static VALUE rb_dfrebase_delta(void)
{
return rb_str_new2(getcore().vinfo->getVersion().c_str());
uint32_t expected_base_address;
uint32_t actual_base_address = 0;
#ifdef WIN32
expected_base_address = 0x00400000;
actual_base_address = (uint32_t)GetModuleHandle(0);
#else
expected_base_address = 0x08048000;
FILE *f = fopen("/proc/self/maps", "r");
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strstr(line, "libs/Dwarf_Fortress")) {
actual_base_address = strtoul(line, 0, 16);
break;
}
}
#endif
return rb_int2inum(actual_base_address - expected_base_address);
}
*/
// TODO color_ostream proxy yadda yadda
static VALUE rb_dfprint_str(VALUE self, VALUE s)
{
// TODO color_ostream proxy yadda yadda
//getcore().con.print("%s", rb_string_value_ptr(&s));
Core::printerr("%s", rb_string_value_ptr(&s));
return Qnil;
@ -329,22 +349,30 @@ static VALUE rb_dfprint_err(VALUE self, VALUE s)
return Qnil;
}
// raw memory access
// WARNING: may cause game crash ! double-check your addresses !
static VALUE rb_dfmemread(VALUE self, VALUE addr, VALUE len)
/* TODO needs main dfhack support
this needs a custom DFHack::Plugin subclass to pass the cmdname to invoke(), to match the ruby callback
// register a ruby method as dfhack console command
// usage: DFHack.register("moo", "this commands prints moo on the console") { DFHack.puts "moo !" }
static VALUE rb_dfregister(VALUE self, VALUE name, VALUE descr)
{
return rb_str_new((char*)rb_num2ulong(addr), rb_num2ulong(len));
}
commands.push_back(PluginCommand(rb_string_value_ptr(&name),
rb_string_value_ptr(&descr),
df_rubycustom));
static VALUE rb_dfmemwrite(VALUE self, VALUE addr, VALUE raw)
return Qtrue;
}
*/
static VALUE rb_dfregister(VALUE self, VALUE name, VALUE descr)
{
// no stable api for raw.length between rb1.8/rb1.9 ...
int strlen = FIX2INT(rb_funcall(raw, rb_intern("length"), 0));
rb_raise(rb_eRuntimeError, "not implemented");
}
memcpy((void*)rb_num2ulong(addr), rb_string_value_ptr(&raw), strlen);
return Qtrue;
}
// raw memory access
// used by the ruby class definitions
// WARNING: may cause game crash ! double-check your addresses !
static VALUE rb_dfmalloc(VALUE self, VALUE len)
{
@ -357,214 +385,170 @@ static VALUE rb_dffree(VALUE self, VALUE ptr)
return Qtrue;
}
// raw c++ wrappers
// return the nth element of a vector
static VALUE rb_dfvectorat(VALUE self, VALUE vect_addr, VALUE idx)
// memory reading (buffer)
static VALUE rb_dfmemory_read(VALUE self, VALUE addr, VALUE len)
{
vector<uint32_t> *v = (vector<uint32_t>*)rb_num2ulong(vect_addr);
return rb_uint2inum(v->at(FIX2INT(idx)));
return rb_str_new((char*)rb_num2ulong(addr), rb_num2ulong(len));
}
// return a c++ string as a ruby string (nul-terminated)
static VALUE rb_dfreadstring(VALUE self, VALUE str_addr)
static VALUE rb_dfmemory_read_stlstring(VALUE self, VALUE addr)
{
string *s = (string*)rb_num2ulong(str_addr);
return rb_str_new2(s->c_str());
std::string *s = (std::string*)rb_num2ulong(addr);
return rb_str_new(s->c_str(), s->length());
}
/* XXX this needs a custom DFHack::Plugin subclass to pass the cmdname to invoke(), to match the ruby callback
// register a ruby method as dfhack console command
// usage: DFHack.register("moo", "this commands prints moo on the console") { DFHack.puts "moo !" }
static VALUE rb_dfregister(VALUE self, VALUE name, VALUE descr)
// memory reading (integers/floats)
static VALUE rb_dfmemory_read_int8(VALUE self, VALUE addr)
{
commands.push_back(PluginCommand(rb_string_value_ptr(&name),
rb_string_value_ptr(&descr),
df_rubycustom));
return Qtrue;
return rb_int2inum(*(char*)rb_num2ulong(addr));
}
*/
static VALUE rb_dfregister(VALUE self, VALUE name, VALUE descr)
static VALUE rb_dfmemory_read_int16(VALUE self, VALUE addr)
{
rb_raise(rb_eRuntimeError, "not implemented");
return rb_int2inum(*(short*)rb_num2ulong(addr));
}
// return the address of the struct in DF memory (for raw memread/write)
static VALUE rb_memaddr(VALUE self)
static VALUE rb_dfmemory_read_int32(VALUE self, VALUE addr)
{
void *data;
Data_Get_Struct(self, void, data);
return rb_uint2inum((uint32_t)data);
return rb_int2inum(*(int*)rb_num2ulong(addr));
}
static VALUE rb_dfmemory_read_float(VALUE self, VALUE addr)
{
return rb_float_new(*(float*)rb_num2ulong(addr));
}
// memory writing (buffer)
static VALUE rb_dfmemory_write(VALUE self, VALUE addr, VALUE raw)
{
// no stable api for raw.length between rb1.8/rb1.9 ...
int strlen = FIX2INT(rb_funcall(raw, rb_intern("length"), 0));
// BEGIN GENERATED SECTION
// begin generated T_cursor binding
static VALUE rb_c_T_cursor;
memcpy((void*)rb_num2ulong(addr), rb_string_value_ptr(&raw), strlen);
static VALUE rb_m_T_cursor_x(VALUE self) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
return rb_uint2inum(var->x);
return Qtrue;
}
static VALUE rb_m_T_cursor_x_set(VALUE self, VALUE val) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
var->x = rb_num2ulong(val);
static VALUE rb_dfmemory_write_stlstring(VALUE self, VALUE addr, VALUE val)
{
std::string *s = (std::string*)rb_num2ulong(addr);
int strlen = FIX2INT(rb_funcall(val, rb_intern("length"), 0));
s->assign(rb_string_value_ptr(&val), strlen);
return Qtrue;
}
static VALUE rb_m_T_cursor_y(VALUE self) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
return rb_uint2inum(var->y);
}
static VALUE rb_m_T_cursor_y_set(VALUE self, VALUE val) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
var->y = rb_num2ulong(val);
// memory writing (integers/floats)
static VALUE rb_dfmemory_write_int8(VALUE self, VALUE addr, VALUE val)
{
*(char*)rb_num2ulong(addr) = rb_num2ulong(val);
return Qtrue;
}
static VALUE rb_m_T_cursor_z(VALUE self) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
return rb_uint2inum(var->z);
static VALUE rb_dfmemory_write_int16(VALUE self, VALUE addr, VALUE val)
{
*(short*)rb_num2ulong(addr) = rb_num2ulong(val);
return Qtrue;
}
static VALUE rb_m_T_cursor_z_set(VALUE self, VALUE val) {
struct df::global::T_cursor *var;
Data_Get_Struct(self, struct df::global::T_cursor, var);
var->z = rb_num2ulong(val);
static VALUE rb_dfmemory_write_int32(VALUE self, VALUE addr, VALUE val)
{
*(int*)rb_num2ulong(addr) = rb_num2ulong(val);
return Qtrue;
}
// link methods to the class
static void ruby_bind_T_cursor(void) {
// create a class, child of WrapData, in module DFHack
rb_c_T_cursor = rb_define_class_under(rb_cDFHack, "T_cursor", rb_c_WrapData);
// reader for 'x' (0 = no arg)
rb_define_method(rb_c_T_cursor, "x", RUBY_METHOD_FUNC(rb_m_T_cursor_x), 0);
// writer for 'x' (1 arg)
rb_define_method(rb_c_T_cursor, "x=", RUBY_METHOD_FUNC(rb_m_T_cursor_x_set), 1);
rb_define_method(rb_c_T_cursor, "y", RUBY_METHOD_FUNC(rb_m_T_cursor_y), 0);
rb_define_method(rb_c_T_cursor, "y=", RUBY_METHOD_FUNC(rb_m_T_cursor_y_set), 1);
rb_define_method(rb_c_T_cursor, "z", RUBY_METHOD_FUNC(rb_m_T_cursor_z), 0);
rb_define_method(rb_c_T_cursor, "z=", RUBY_METHOD_FUNC(rb_m_T_cursor_z_set), 1);
static VALUE rb_dfmemory_write_float(VALUE self, VALUE addr, VALUE val)
{
*(float*)rb_num2ulong(addr) = rb_num2dbl(val);
return Qtrue;
}
// create an instance of T_cursor from global::cursor
// this method is linked to DFHack.cursor in ruby_bind_dfhack()
static VALUE rb_global_cursor(VALUE self) {
return Data_Wrap_Struct(rb_c_T_cursor, 0, 0, df::global::cursor);
// vector access
// vector<uint8>
static VALUE rb_dfmemory_vec8_length(VALUE self, VALUE addr)
{
std::vector<uint8_t> *v = (std::vector<uint8_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->size());
}
// begin generated unit binding
static VALUE rb_c_unit;
static VALUE rb_m_unit_id(VALUE self) {
struct df::unit *var;
Data_Get_Struct(self, struct df::unit, var);
return rb_uint2inum(var->id);
static VALUE rb_dfmemory_vec8_at(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint8_t> *v = (std::vector<uint8_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->at(FIX2INT(idx)));
}
static VALUE rb_m_unit_id_set(VALUE self, VALUE val) {
struct df::unit *var;
Data_Get_Struct(self, struct df::unit, var);
var->id = rb_num2ulong(val);
static VALUE rb_dfmemory_vec8_set(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint8_t> *v = (std::vector<uint8_t>*)rb_num2ulong(addr);
v->at(FIX2INT(idx)) = rb_num2ulong(val);
return Qtrue;
}
static void ruby_bind_unit(void) {
// ruby class name must begin with uppercase
rb_c_unit = rb_define_class_under(rb_cDFHack, "Unit", rb_c_WrapData);
rb_define_method(rb_c_unit, "id", RUBY_METHOD_FUNC(rb_m_unit_id), 0);
rb_define_method(rb_c_unit, "id=", RUBY_METHOD_FUNC(rb_m_unit_id_set), 1);
static VALUE rb_dfmemory_vec8_insert(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint8_t> *v = (std::vector<uint8_t>*)rb_num2ulong(addr);
v->insert(v->begin()+FIX2INT(idx), rb_num2ulong(val));
return Qtrue;
}
// begin generated world binding
static VALUE rb_c_world;
static VALUE rb_c_world_T_units;
static VALUE rb_m_world_T_units_all(VALUE self) {
struct df::world::T_units *var;
Data_Get_Struct(self, struct df::world::T_units, var);
// read a vector
VALUE ret = rb_ary_new();
for (unsigned i=0 ; i<var->all.size() ; ++i)
rb_ary_push(ret, Data_Wrap_Struct(rb_c_unit, 0, 0, var->all[i]));
return ret;
static VALUE rb_dfmemory_vec8_delete(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint8_t> *v = (std::vector<uint8_t>*)rb_num2ulong(addr);
v->erase(v->begin()+FIX2INT(idx));
return Qtrue;
}
static VALUE rb_m_world_units(VALUE self) {
struct df::world *var;
Data_Get_Struct(self, struct df::world, var);
return Data_Wrap_Struct(rb_c_world_T_units, 0, 0, &var->units);
// vector<uint16>
static VALUE rb_dfmemory_vec16_length(VALUE self, VALUE addr)
{
std::vector<uint16_t> *v = (std::vector<uint16_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->size());
}
static void ruby_bind_world(void) {
rb_c_world = rb_define_class_under(rb_cDFHack, "World", rb_c_WrapData);
rb_c_world_T_units = rb_define_class_under(rb_c_world, "T_units", rb_c_WrapData);
rb_define_method(rb_c_world, "units", RUBY_METHOD_FUNC(rb_m_world_units), 0);
rb_define_method(rb_c_world_T_units, "all", RUBY_METHOD_FUNC(rb_m_world_T_units_all), 0);
static VALUE rb_dfmemory_vec16_at(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint16_t> *v = (std::vector<uint16_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->at(FIX2INT(idx)));
}
static VALUE rb_global_world(VALUE self) {
return Data_Wrap_Struct(rb_c_world, 0, 0, df::global::world);
static VALUE rb_dfmemory_vec16_set(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint16_t> *v = (std::vector<uint16_t>*)rb_num2ulong(addr);
v->at(FIX2INT(idx)) = rb_num2ulong(val);
return Qtrue;
}
/*
static VALUE rb_dfcreatures(VALUE self)
static VALUE rb_dfmemory_vec16_insert(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
OffsetGroup *ogc = getcore().vinfo->getGroup("Creatures");
vector <df_creature*> *v = (vector<df_creature*>*)ogc->getAddress("vector");
VALUE ret = rb_ary_new();
for (unsigned i=0 ; i<v->size() ; ++i)
rb_ary_push(ret, Data_Wrap_Struct(rb_cCreature, 0, 0, v->at(i)));
return ret;
std::vector<uint16_t> *v = (std::vector<uint16_t>*)rb_num2ulong(addr);
v->insert(v->begin()+FIX2INT(idx), rb_num2ulong(val));
return Qtrue;
}
static VALUE rb_getlaborname(VALUE self, VALUE idx)
static VALUE rb_dfmemory_vec16_delete(VALUE self, VALUE addr, VALUE idx)
{
return rb_str_new2(getcore().vinfo->getLabor(FIX2INT(idx)).c_str());
std::vector<uint16_t> *v = (std::vector<uint16_t>*)rb_num2ulong(addr);
v->erase(v->begin()+FIX2INT(idx));
return Qtrue;
}
static VALUE rb_getskillname(VALUE self, VALUE idx)
// vector<uint32>
static VALUE rb_dfmemory_vec32_length(VALUE self, VALUE addr)
{
return rb_str_new2(getcore().vinfo->getSkill(FIX2INT(idx)).c_str());
std::vector<uint32_t> *v = (std::vector<uint32_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->size());
}
static VALUE rb_mapblock(VALUE self, VALUE x, VALUE y, VALUE z)
static VALUE rb_dfmemory_vec32_at(VALUE self, VALUE addr, VALUE idx)
{
Maps *map;
Data_Get_Struct(self, Maps, map);
df_block *block;
block = map->getBlock(FIX2INT(x)/16, FIX2INT(y)/16, FIX2INT(z));
if (!block)
return Qnil;
return Data_Wrap_Struct(rb_cMapBlock, 0, 0, block);
std::vector<uint32_t> *v = (std::vector<uint32_t>*)rb_num2ulong(addr);
return rb_uint2inum(v->at(FIX2INT(idx)));
}
static VALUE rb_dfmemory_vec32_set(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint32_t> *v = (std::vector<uint32_t>*)rb_num2ulong(addr);
v->at(FIX2INT(idx)) = rb_num2ulong(val);
return Qtrue;
}
static VALUE rb_dfmemory_vec32_insert(VALUE self, VALUE addr, VALUE idx, VALUE val)
{
std::vector<uint32_t> *v = (std::vector<uint32_t>*)rb_num2ulong(addr);
v->insert(v->begin()+FIX2INT(idx), rb_num2ulong(val));
return Qtrue;
}
static VALUE rb_dfmemory_vec32_delete(VALUE self, VALUE addr, VALUE idx)
{
std::vector<uint32_t> *v = (std::vector<uint32_t>*)rb_num2ulong(addr);
v->erase(v->begin()+FIX2INT(idx));
return Qtrue;
}
*/
@ -577,30 +561,42 @@ 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, "resume", RUBY_METHOD_FUNC(rb_dfresume), 0);
//rb_define_singleton_method(rb_cDFHack, "version", RUBY_METHOD_FUNC(rb_dfgetversion), 0);
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);
rb_define_singleton_method(rb_cDFHack, "memread", RUBY_METHOD_FUNC(rb_dfmemread), 2);
rb_define_singleton_method(rb_cDFHack, "memwrite", RUBY_METHOD_FUNC(rb_dfmemwrite), 2);
rb_define_singleton_method(rb_cDFHack, "malloc", RUBY_METHOD_FUNC(rb_dfmalloc), 1);
rb_define_singleton_method(rb_cDFHack, "free", RUBY_METHOD_FUNC(rb_dffree), 1);
rb_define_singleton_method(rb_cDFHack, "vectorat", RUBY_METHOD_FUNC(rb_dfvectorat), 2);
rb_define_singleton_method(rb_cDFHack, "readstring", RUBY_METHOD_FUNC(rb_dfreadstring), 1);
rb_define_singleton_method(rb_cDFHack, "register_dfcommand", RUBY_METHOD_FUNC(rb_dfregister), 2);
// accessors for dfhack globals
rb_define_singleton_method(rb_cDFHack, "cursor", RUBY_METHOD_FUNC(rb_global_cursor), 0);
rb_define_singleton_method(rb_cDFHack, "world", RUBY_METHOD_FUNC(rb_global_world), 0);
// parent class for all wrapped objects
rb_c_WrapData = rb_define_class_under(rb_cDFHack, "WrapData", rb_cObject);
rb_define_method(rb_c_WrapData, "memaddr", RUBY_METHOD_FUNC(rb_memaddr), 0);
// call generated bindings
ruby_bind_T_cursor();
ruby_bind_unit();
ruby_bind_world();
rb_define_const(rb_cDFHack, "REBASE_DELTA", rb_dfrebase_delta());
rb_define_singleton_method(rb_cDFHack, "memory_read", RUBY_METHOD_FUNC(rb_dfmemory_read), 2);
rb_define_singleton_method(rb_cDFHack, "memory_read_stlstring", RUBY_METHOD_FUNC(rb_dfmemory_read_stlstring), 1);
rb_define_singleton_method(rb_cDFHack, "memory_read_int8", RUBY_METHOD_FUNC(rb_dfmemory_read_int8), 1);
rb_define_singleton_method(rb_cDFHack, "memory_read_int16", RUBY_METHOD_FUNC(rb_dfmemory_read_int16), 1);
rb_define_singleton_method(rb_cDFHack, "memory_read_int32", RUBY_METHOD_FUNC(rb_dfmemory_read_int32), 1);
rb_define_singleton_method(rb_cDFHack, "memory_read_float", RUBY_METHOD_FUNC(rb_dfmemory_read_float), 1);
rb_define_singleton_method(rb_cDFHack, "memory_write", RUBY_METHOD_FUNC(rb_dfmemory_write), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_stlstring", RUBY_METHOD_FUNC(rb_dfmemory_write_stlstring), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_int8", RUBY_METHOD_FUNC(rb_dfmemory_write_int8), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_int16", RUBY_METHOD_FUNC(rb_dfmemory_write_int16), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_int32", RUBY_METHOD_FUNC(rb_dfmemory_write_int32), 2);
rb_define_singleton_method(rb_cDFHack, "memory_write_float", RUBY_METHOD_FUNC(rb_dfmemory_write_float), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector8_length", RUBY_METHOD_FUNC(rb_dfmemory_vec8_length), 1);
rb_define_singleton_method(rb_cDFHack, "memory_vector8_at", RUBY_METHOD_FUNC(rb_dfmemory_vec8_at), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector8_set", RUBY_METHOD_FUNC(rb_dfmemory_vec8_set), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector8_insert", RUBY_METHOD_FUNC(rb_dfmemory_vec8_insert), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector8_delete", RUBY_METHOD_FUNC(rb_dfmemory_vec8_delete), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector16_length", RUBY_METHOD_FUNC(rb_dfmemory_vec16_length), 1);
rb_define_singleton_method(rb_cDFHack, "memory_vector16_at", RUBY_METHOD_FUNC(rb_dfmemory_vec16_at), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector16_set", RUBY_METHOD_FUNC(rb_dfmemory_vec16_set), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector16_insert", RUBY_METHOD_FUNC(rb_dfmemory_vec16_insert), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector16_delete", RUBY_METHOD_FUNC(rb_dfmemory_vec16_delete), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_length", RUBY_METHOD_FUNC(rb_dfmemory_vec32_length), 1);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_at", RUBY_METHOD_FUNC(rb_dfmemory_vec32_at), 2);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_set", RUBY_METHOD_FUNC(rb_dfmemory_vec32_set), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_insert", RUBY_METHOD_FUNC(rb_dfmemory_vec32_insert), 3);
rb_define_singleton_method(rb_cDFHack, "memory_vector32_delete", RUBY_METHOD_FUNC(rb_dfmemory_vec32_delete), 2);
// load the default ruby-level definitions
int state=0;