Joe Van Dyk
12/13/2005 5:15:00 AM
On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 12/12/05, Eero Saynatkari <ruby-forum-reg@mailinator.com> wrote:
> > Joe Van Dyk wrote:
> > > (I've already looked at Swig, btw. I'd like to do this one by hand.)
> > >
> > > I have the following:
> > >
> > > typedef struct {
> > > double x;
> > > double y;
> > > double z;
> > > } VelocityRecord;
> > >
> > > typedef struct {
> > > double x;
> > > double y;
> > > double z;
> > > } PositionRecord;
> > >
> > > typedef struct {
> > > int id;
> > > int type;
> > > PositionRecord position;
> > > VelocityRecord velocity;
> > > } Player;
> > >
> > > Player Players[10];
> > >
> > >
> > > The number of Players is fixed ahead of time. I want to be able to
> > > access that data from Ruby. Ideally, something like:
> > >
> > > module Simulation
> > > attr_accessor :players # Other stuff will be here
> > > class Player
> > > class VelocityRecord
> > > attr_accessor :x, :y :z
> > > end
> > > class PositionRecord
> > > attr_accessor :x, :y, :z
> > > end
> > > end
> > > end
> >
> > My typical recommendation is to just wrap a pointer to
> > the struct and pass that around. Then, for each method
> > just extract the pointer, access the correct field and
> > generate a VALUE out of that (inside the function that
> > corresponds to the method).
>
> Can you share more details? Is that essentially what I've done in my
> later posts on this?
Here's what I have so far. Seems to work well:
#include "ruby.h"
#include "simulation.h"
VALUE get_frame_count(VALUE self) { return INT2NUM(HIFEN2_Count); }
VALUE get_mission_time(VALUE self) { return INT2NUM(HIFEN2_Mission); }
VALUE get_max_players(VALUE self) { return INT2NUM(MAX_PLAYERS); }
VALUE player_new(VALUE self, VALUE rb_i)
{
int i = NUM2INT(rb_i);
return Data_Wrap_Struct(self, NULL, NULL, &Players[i]);
}
Player* get_player(VALUE self)
{
Player *p;
Data_Get_Struct(self, Player, p);
return p;
}
VALUE get_player_id(VALUE self) { return INT2NUM(get_player(self)->id); }
VALUE get_player_x_pos(VALUE self) { return
rb_float_new(get_player(self)->position.x); }
VALUE get_player_y_pos(VALUE self) { return
rb_float_new(get_player(self)->position.y); }
VALUE get_player_z_pos(VALUE self) { return
rb_float_new(get_player(self)->position.z); }
VALUE get_player_x_vel(VALUE self) { return
rb_float_new(get_player(self)->velocity.x); }
VALUE get_player_y_vel(VALUE self) { return
rb_float_new(get_player(self)->velocity.y); }
VALUE get_player_z_vel(VALUE self) { return
rb_float_new(get_player(self)->velocity.z); }
VALUE cSimulation;
VALUE cPlayer;
void Init_Sim()
{
cSimulation = rb_define_class("Simulation", rb_cObject);
rb_define_method(cSimulation, "frame_count", get_frame_count, 0);
rb_define_method(cSimulation, "mission_time", get_mission_time, 0);
rb_define_method(cSimulation, "max_players", get_max_players, 0);
cPlayer = rb_define_class("Player", rb_cObject);
rb_define_singleton_method(cPlayer, "new", player_new, 1);
rb_define_method(cPlayer, "player_id", get_player_id, 0);
rb_define_method(cPlayer, "x_position", get_player_x_pos, 0);
rb_define_method(cPlayer, "y_position", get_player_y_pos, 0);
rb_define_method(cPlayer, "z_position", get_player_z_pos, 0);
rb_define_method(cPlayer, "x_velocity", get_player_x_vel, 0);
rb_define_method(cPlayer, "y_velocity", get_player_y_vel, 0);
rb_define_method(cPlayer, "z_velocity", get_player_z_vel, 0);
}