[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Accessing C structures in Ruby

Joe Van Dyk

12/13/2005 3:20:00 AM

(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


15 Answers

Joe Van Dyk

12/13/2005 3:55:00 AM

0

On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> 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

Hm, on second thought, it's probably a lot easier to do:

class Player
attr_reader :x_position, :y_position, :z_position, :x_velocity,
:y_velocity, :z_velocity
end

So, maybe something like this?

void Init_Simulation()
{
rb_define_module(mSimulation, "Simulation");
rb_define_class_under(cPlayer, "Player");

rb_define_method(cPlayer, "x_position", get_x_position, 0);
rb_define_method(cPlayer, "y_position", get_y_position, 0);
rb_define_method(cPlayer, "z_position", get_z_position, 0);
rb_define_method(cPlayer, "x_velocity", get_x_velocity, 0);
rb_define_method(cPlayer, "y_velocity", get_y_velocity, 0);
rb_define_method(cPlayer, "z_velocity", get_z_velocity, 0);
}


Joe Van Dyk

12/13/2005 3:55:00 AM

0

On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> 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

Hm, on second thought, it's probably a lot easier to do:

class Player
attr_reader :x_position, :y_position, :z_position, :x_velocity,
:y_velocity, :z_velocity
end

So, maybe something like this?

void Init_Simulation()
{
rb_define_module(mSimulation, "Simulation");
rb_define_class_under(cPlayer, "Player");

rb_define_method(cPlayer, "x_position", get_x_position, 0);
rb_define_method(cPlayer, "y_position", get_y_position, 0);
rb_define_method(cPlayer, "z_position", get_z_position, 0);
rb_define_method(cPlayer, "x_velocity", get_x_velocity, 0);
rb_define_method(cPlayer, "y_velocity", get_y_velocity, 0);
rb_define_method(cPlayer, "z_velocity", get_z_velocity, 0);
}


Eero Saynatkari

12/13/2005 4:07:00 AM

0

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).


E

--
Posted via http://www.ruby-....


Eero Saynatkari

12/13/2005 4:07:00 AM

0

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).


E

--
Posted via http://www.ruby-....


Joe Van Dyk

12/13/2005 4:32:00 AM

0

On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> 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
>
> Hm, on second thought, it's probably a lot easier to do:
>
> class Player
> attr_reader :x_position, :y_position, :z_position, :x_velocity,
> :y_velocity, :z_velocity
> end
>
> So, maybe something like this?
>
> void Init_Simulation()
> {
> rb_define_module(mSimulation, "Simulation");
> rb_define_class_under(cPlayer, "Player");
>
> rb_define_method(cPlayer, "x_position", get_x_position, 0);
> rb_define_method(cPlayer, "y_position", get_y_position, 0);
> rb_define_method(cPlayer, "z_position", get_z_position, 0);
> rb_define_method(cPlayer, "x_velocity", get_x_velocity, 0);
> rb_define_method(cPlayer, "y_velocity", get_y_velocity, 0);
> rb_define_method(cPlayer, "z_velocity", get_z_velocity, 0);
> }

So, I have a bunch of functions that look like this now:

VALUE get_player_x_pos(VALUE self)
{
Player* p;
Data_Get_Struct(self, Player, p);
rb_float_new(p->position.x);
}

That the way to go?


Joe Van Dyk

12/13/2005 4:32:00 AM

0

On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 12/12/05, Joe Van Dyk <joevandyk@gmail.com> 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
>
> Hm, on second thought, it's probably a lot easier to do:
>
> class Player
> attr_reader :x_position, :y_position, :z_position, :x_velocity,
> :y_velocity, :z_velocity
> end
>
> So, maybe something like this?
>
> void Init_Simulation()
> {
> rb_define_module(mSimulation, "Simulation");
> rb_define_class_under(cPlayer, "Player");
>
> rb_define_method(cPlayer, "x_position", get_x_position, 0);
> rb_define_method(cPlayer, "y_position", get_y_position, 0);
> rb_define_method(cPlayer, "z_position", get_z_position, 0);
> rb_define_method(cPlayer, "x_velocity", get_x_velocity, 0);
> rb_define_method(cPlayer, "y_velocity", get_y_velocity, 0);
> rb_define_method(cPlayer, "z_velocity", get_z_velocity, 0);
> }

So, I have a bunch of functions that look like this now:

VALUE get_player_x_pos(VALUE self)
{
Player* p;
Data_Get_Struct(self, Player, p);
rb_float_new(p->position.x);
}

That the way to go?


Joe Van Dyk

12/13/2005 4:57:00 AM

0

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?


Joe Van Dyk

12/13/2005 4:57:00 AM

0

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?


Joe Van Dyk

12/13/2005 5:15:00 AM

0

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


Joe Van Dyk

12/13/2005 5:15:00 AM

0

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