Ruby/C++ Interfaces
DescriptionThe C++ classes have to be interfaced to Ruby. I have already created an interface for the Color class. Here is some important information.
1. In the header of the file there is a definition for Ruby's Class instance. The naming convention (taken from the documentation) is rb_cCLASSNAME and rb_mMODULENAME. Like in the Color class, add an "extern VALUE NAME;" in the header and a "VALUE NAME;" in the source file. You will notice the rb_cColor variable.
2. Each class and module needs to have a "static void createRubyInterface()" method declared in the header and implemented. I have added this method for every RGSS class, you have to implement it.
3. You can find out all necessary calls here: http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html#S8
4. Don't bother too much with methods that have default arguments or have overloaded definitions (meaning there are several functions with the same number, but different arguments). Just put the normal number of arguments there. I will take care of rewriting the code so it works with any number of arguments. Of course, if you want to learn a bit more, you can do that yourself anyway. I have already implemented Color::initialize and Color::set in that way.
5. Don't forget to use the conversion marcos like INT2NUM or rb_float_new if you define interfaces constants and class variables.
6. Every method HAS TO return a VALUE. If not actual value is returned in C++, then the return value is Qnil. Again. Refer to the Color class. The first Argument is "VALUE self" and that one is never counter when using interface definitions like rb_define_method. Just compare the actual methods and the interface definitions in Color.
7. You don't have to implement the methods. You just have to add the interface calls and edit the method declarations so they can work with Ruby.
8. All methods are static.
9. Be careful with getters and setters. For attr_reader, attr_writer and attr_accessor you can simply use something like "rb_define_attr(rb_cColor, "red", 1, 0);" where the 3rd argument sets read access (0 for no, 1 for yes) and the 4th argument sets write access (0 for no, 1 for yes). Basically using 1, 0 is attr_reader; 0, 1 is attr_writer and 1, 1 is attr_accessor.
PriorityCritical. Before this task is completed, not further development can be done.
PrerequisitesNone.
AssignedForeverZer0
game_guy
Ryex
Everything elseI have also interfaced Graphics and Input so you can get more examples there.
There are many classes, make sure you do them one by one and post here which are done so the others don't do your work as well.
Always refer to Graphics, Input and Color if you get stuck. If you still can't figure out how to do things, post. Since you all know Ruby, most things should be clear or you should at least be able to figure it out easily.
Don't expect anything from me right away. Still trying to get the hang of this. I'm not gonna stop trying though :3
That's why I made this task for you guys. That way you can learn something and be useful. :)
Take your time. I probably won't have time to work on this anymore till the weekend.
Well, I'm gonna tackle the "Window" class. My take me little bit...
* crosses fingers *
I'm gonna try viewport. By the way I have no idea on how to test this O_O
I consider a being able to Build a success. :P
Seriously, though, after a few minutes studying Blizz's examples and reading the link he gave, its actually not too difficult. I'm just gonna take my time and try not to screw it up.
EDIT:
Okay, I have finished Window class as far as I know how. I am still unsure as to how to implement the "update", "dispose", and "disposed?" methods on the C++ side, but all all other variables/methods are interfaced. I think I even did it right!
Until Blizz is around to explain them couple methods I was unsure of, I'm going to move on to the "Sprite" class.
EDIT 2:
Sprite class is done. Going for the Audio module next.
EDIT 3:
Audio module is interfaced. Actual implementation is still missing, but I imagine we will be expanding on this module a lot before were done.
Yeah, you don't have to add the implementation.
F0, you can test it easily. Just open test.rb, add some Ruby regarding that class and see how it works. Obviously you won't be able to test Sprite or something like that, but you can test Tone if you implement it similar to Color.
I'm gonna take on tone and viewport. No one else do those >:U I'll kill you!
Zer0 something you did in your implementation of the window class has made the project impossible to build and then run, it causes an access violation. I would go through it and fix it but I don't really have time...
Not sure exactly how. It doesn't actually implement anything yet. I'll check it out soon as I get off work and see what I can figure out.
EDIT:
I looked at it real quick, and I did find one obvious error that I made (fixed). I had copy-pasted a line of code from the Color class to use as a template and save two seconds of typing. It turns out that I had forgot to set the initialize method to call the from the Window class. It was still calling from the color class. Oops.
I did this on my work computer, which I have the project on, but not VS, so I really can't re-compile and test it out. If someone tests it out before I get a chance to, let me know if that fixed it.
I have changed the implementation of Color to some degree. The previous implementation was actually creating Ruby objects and thus should be slower. The current implementation is pure C++ and is only interfaced by Ruby. Also, Ruby takes care of the garbage collection.
Quote from: game_guy on March 16, 2011, 08:04:39 am
I'm gonna take on tone and viewport. No one else do those >:U I'll kill you!
I just wanna make sure this is left for me so I don't feel utterly useless when I come back....
I haven't touched it. Was tempted to, but didn't. I've been busy with some other stuff the past day or so, so take what time you need.
F0, I noticed that you already implemented some methods. I suggest that you don't do that before all classes have been interfaced. Also, I was getting a crash during one of the createRubyInterface methods. I'll go check why.
EDIT: Found it, fixed it. BTW, there is no need for argument errors. It seems that rb_scan_args does that automatically. :) And it's even better than RGSS's default because it tells you something like ArgumentError (2 for 3..4).
EDIT: Alright, I have additionally implemented Tone and Rect so you have even more examples for the interfaces.
EDIT: I haven't seen much SVN activity from you guys in the past few days. Are you having troubles with the code? I realize that there has been a lot of new code and stuff that you probably don't understand. I am asking because this task is critical after all.
sorry. I was drowning in work. I'm on spring break now so expect a lot of activity from me over the next week.
I've been playing around on new PC and getting it all set up. Will get busy. ;)
EDIT: I'm gonna start interfacing the Bitmap class.
Leave viewport for me. Slowly getting it done with the time I do have.
I committed Bitmap and now I'm in dire need of some sleep. Will start something else in the morning.
Everything compiles okay, and I'm pretty sure its right, but if I am making any mistakes can someone (looks at Blizzard) let me know.
Otherwise I'm just keep doing how I did the Bitmap class.
I'll see if I can take a look at the Bitmap class later today and let you know. Though, in the meantime you could check if you are following the coding convention.
with the Table class we are storing the table in an dynamic array on the c++ side. how do we make sure it gets destroyed when the ruby object is destroyed?
Table should be done.
Could we simply add a "gc_mark" method to it as well. This can check when it is no longer referenced on the Ruby side, then it can be deleted accordingly by the garbage collector.
ah, I see. Data_Wrap_Struct has two arguments 'mark' and 'free' that point to functions called during garbage collection. I'de rather wait till Blizz dose an example of it though.
Yeah, I thought of attempting to do it, but I have a feeling I would screw it up somehow. I figured he will explain it when we get to that part. :P
Yes, gc_mark is the thing that should be used for that and gc_free (the parameter after gc_mark in Data_Make_Struct). I'll handle that for the first class. When I have figured it out completely, you guys can do the rest. But you figured that already out. xD
I'm gonna begin to interface the Tilemap class now.
I'm going to work on plane. after that we should have at the interfaces done at least
Alright. Once you are done, move this topic. I was busy today so I couldn't work on the Bitmap implementation. I'll see if I can do it tomorrow.
Quote from: Ryex on March 21, 2011, 06:16:13 pm
I'm going to work on plane. after that we should have at the interfaces done at least
We actually still have Font, RGSSError, and Viewport.
G_G is working on Viewport as far as I know, so I will do Font tonight. If I have time and are up to it, I may try to do RGSSError as well. I think it only has like three methods anyway.
I have it like half done. Will do rest after homework. .-. completely spaced my mind today, had plenty of time to work on it. Sorry.
- interfaced the Plane class
I did a check and I was wrong it seems
so far the classes left to be interfaces are Font, RGSSError, and Viewport
G_G wanted to work on Viewport if I remember right but I think he is having trouble getting on the the computer so if he doesn't finish it soon lets just do it for him and move on. (Sorry G_G)
EDIT: lol right as I went to post this you posted Zer0
EDIT: while I did my edit G_G posted LOL!
I interfaced RGSSError and Font, and committed both.
Now all we need is Viewport.... * looks at G_G *
Just joking G_G, take your time, we got no other tasks at the moment.
Yeah, I can make Bitmap and Sprite work without needing Viewport. I'll see how much I can get done today. I should at least be able to make them work enough to be able to load a actual image and draw it properly.
Man it sure looks cool with that ARC logo moving about. we really have progress here
Quote from: ForeverZer0 on March 22, 2011, 10:37:44 pm
Now all we need is Viewport.... * looks at G_G *
This.
Quote from: ForeverZer0 on March 22, 2011, 10:37:44 pm
Just joking G_G, take your time, we got no other tasks at the moment.
D:
I know you can find some time. C'mon, G_G. ._.
This task is almost done and I'd like to mark it as finished.
BTW, not only the Viewport class needs to be finished! I have noticed that a portion of the Sprite class is also missing. Somebody of your guys take care of that, it's not much work.
Also, I have fully implemented Font yesterday. There is only one thing that bothers me and that is defaultColor. Since it's an object, it might be wiped by the garbage collector. But because it is a static variable, we have no real means to make sure it gets marked via gc_mark. ._. Does anybody have a suggestion for this? I thought that a possible solution could be that we try to make it a class variable and manually set it to the color. But I had some problems with that and no time to work on it.
I've almost got it done -_- Procrastination is my greatest skill and weakness.
EDIT: I'm working on it now. Won't stop til its done. Sorry. :((((((
Lol, there is no need to apologize.
Alright so I looked at this line right here in color.
color->alpha = (NIL_P(a) ? 255.0f : hclamp((float)NUM2DBL(a), 0.0f, 255.0f));
Basically I'm understating once a user creates a new color object, then sets alpha to say 120 then calls the set method and does not define alpha, it automatically sets it to 255.
Yes. There's quite a bit going on in that line. If the alpha is omitted, then a will be Qnil (is NIL_P a fast check for Qnil). If there is an alpha, it is converted to the C type double, cast to float (since all values are float and the compiler gives warning when you don't cast stuff like this) and it will be clamped between 0 and 255.
If you have more questions, feel free to ask.
I'm looking through the docs but I'm wondering how we return a class? I'm doing the rb_getColor method for Viewport and I'm wondering how we revert the color back to a ruby class. Do we simply just return "viewport->color" or do we have to convert it back to ruby?
That's what the wrap method is for. If you want to return the viewport's color as Ruby class, you use "viewport->color->wrap()".
Also, take a look how I implemented Font::color and Font::rb_color if you want to implement the initializer as well. There are a few things that have to be taken into account because of Ruby/C++.
I also implemented a static create method that creates an instance of a Ruby class within C++ code. Any other way wouldn't properly invoke the GC as far as I know. If you want, you can implement the create method in all classes (actually you should, we will need them). It's basically copy-paste and changing the names of the classes/variables. I have implemented that method in Color and Font.
Just about a done. Have a few more methods then i can commit it tomorrow. Been away from my computer all day. I am not proud of myself.
I am disappoint, son. :V:
BTW, you don't have to complete something before you commit. It's just important that you can build it and that other people don't get errors because of half-done work.
Sorry, I haven't been very active with ARC the past few days. It's been a hectic week and I just haven't found myself in the mood to think too hard on programming. I'll be back in full swing by the weekend. ;)
I was busy this week as well. And I'll probably be busy the next one, too. That's actually why I put together those new tasks; so you guys can keep working and don't have to wait for me to finish some stuff. xD
I'm seriously just not cut out for C++ yet. @___@ I'll keep trying obviously.
I'm still confused on how we return Color. I looked in font and plane classes and the rb_getColor methods all they do is return VALUE self. I'm so confused right now. >.<
Do I feel stupid. Haven't updated for awhile....
I am marking this task as finished now. Even though not all interfaces have been added, the only classes that don't have a full interface yet are the Renderable classes and I am working on those myself so I will add the interfaces myself as well.
@F0: Remember that the Window class in C++ will be quite different than the one in Ruby. e.g. The CursorX class won't exist. It will be controlled over the Window class and it will be just a Sprite instance.