summaryrefslogtreecommitdiffhomepage
path: root/mrb_gems/basic_struct_example/src/basic_struct_example.c
diff options
context:
space:
mode:
authorrealtradam <[email protected]>2023-02-15 19:14:56 -0500
committerrealtradam <[email protected]>2023-02-15 19:14:56 -0500
commit0e689b72d7fc7afa64508a99948527009712d189 (patch)
tree113a5c52a0ada6dff15a027edb33abf877cf5b96 /mrb_gems/basic_struct_example/src/basic_struct_example.c
parent90950ee613c32c248108406a176598d6216e3140 (diff)
downloadmruby-playground-0e689b72d7fc7afa64508a99948527009712d189.tar.gz
mruby-playground-0e689b72d7fc7afa64508a99948527009712d189.zip
struct exampleHEADmaster
Diffstat (limited to 'mrb_gems/basic_struct_example/src/basic_struct_example.c')
-rw-r--r--mrb_gems/basic_struct_example/src/basic_struct_example.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/mrb_gems/basic_struct_example/src/basic_struct_example.c b/mrb_gems/basic_struct_example/src/basic_struct_example.c
new file mode 100644
index 0000000..ec304a1
--- /dev/null
+++ b/mrb_gems/basic_struct_example/src/basic_struct_example.c
@@ -0,0 +1,129 @@
+#include <mruby.h>
+#include <mruby/data.h>
+#include <mruby/class.h>
+#include <mruby/compile.h>
+#include <stdio.h>
+
+// a regular C struct
+typedef struct Color
+{
+ char r;
+ char g;
+ char b;
+} Color;
+// we will later be building an interface for it
+
+// A struct that informs the Ruby VM what function to call
+// when garbage collecting our struct wrapper. Here nothing
+// special needs to be done so the default "mrb_free" function
+// is used.
+// Ending the struct name with 'mrb_struct' is a
+// convention I like to use for these mruby 'internal'
+// structs
+static const struct mrb_data_type Color_mrb_struct = {
+ "Color", // name of the class in ruby
+ mrb_free // the function we want it to call when garbage collected
+ // ^ you can customize this, but remember to always call mrb_free
+ // ^ within whatever customization you make
+};
+
+static mrb_value
+Color_initialize(mrb_state* mrb, mrb_value self) {
+ //Rectangle *wrapped_value = (Rectangle *) mrb_malloc(mrb, sizeof(Rectangle));
+ //MyCustomStruct *wrapped_value = (MyCustomStruct *)mrb_malloc(mrb, sizeof(MyCustomStruct));
+
+ Color *wrapped_value = (Color *)DATA_PTR(self);
+ if(wrapped_value) { mrb_free(mrb, wrapped_value); }
+ mrb_data_init(self, NULL, &Color_mrb_struct);
+ wrapped_value = (Color *)mrb_malloc(mrb, sizeof(Color));
+
+ mrb_int parameter_r; // the value that will be recieved from the function call parameter
+ mrb_int parameter_g; // the value that will be recieved from the function call parameter
+ mrb_int parameter_b; // the value that will be recieved from the function call parameter
+
+ mrb_get_args(mrb, "iii", &parameter_r, &parameter_g, &parameter_b); // getting the value of the param and storing it.
+ wrapped_value->r = (char)parameter_r;
+ wrapped_value->g = (char)parameter_g;
+ wrapped_value->b = (char)parameter_b;
+ //mrb_data_init(self, wrapped_value, &mrb_Rectangle_struct);
+ mrb_data_init(self, wrapped_value, &Color_mrb_struct);
+ return self;
+}
+
+// defining the function to be later bound to a ruby method
+static mrb_value
+Color_r_getter(mrb_state *mrb, mrb_value self)
+{
+ // Unwrap the Ruby object into a C pointer
+ struct Color *my_struct = DATA_GET_PTR(
+ mrb, // The Ruby VM
+ self, // The Ruby object holding the struct
+ &Color_mrb_struct, // Address to the custom struct tag we declared above
+ Color // The struct tag we declared at the top
+ );
+
+ // Get the x value from the struct and convert it into a Ruby object. Return it
+ return mrb_fixnum_value(my_struct->r);
+}
+
+static mrb_value
+Color_r_setter(mrb_state* mrb, mrb_value self) {
+ mrb_int parameter_r; // the value that will be recieved from the function call parameter
+
+ mrb_get_args(mrb, "i", &parameter_r); // getting the value of the param and storing it.
+
+ // Unwrap the Ruby object into a C pointer
+ // same as the function defined above does
+ Color *my_struct = DATA_GET_PTR(mrb, self, &Color_mrb_struct, Color);
+
+ // Set the value in the struct to the new one
+ // note: we do not need to rerwap the struct or anything as we
+ // are using a pointer to change the values inside the wrapped
+ // struct.
+ my_struct->r = (char)parameter_r;
+
+ // Ruby convention is to return the value we set so we do that
+ return mrb_fixnum_value((char)parameter_r);
+}
+
+// gem initializer
+void
+mrb_basic_struct_example_gem_init(mrb_state* mrb) {
+ struct RClass *basic_struct_example_class = mrb_define_module(mrb, "BasicStructExample");
+ struct RClass *color_class = mrb_define_class_under(
+ mrb,
+ basic_struct_example_class,
+ "Color",
+ mrb->object_class
+ );
+ // This macro MUST be called and it must be after the class is defined
+ MRB_SET_INSTANCE_TT(color_class, MRB_TT_DATA);
+
+ mrb_define_method(
+ mrb, // Mruby VM state
+ color_class, // Class we bind method to
+ "initialize", // Name of method
+ Color_initialize, // Function we are binding as a method
+ MRB_ARGS_ANY() // How many arguments are optional/required
+ );
+ mrb_define_method(
+ mrb, // Mruby VM state
+ color_class, // Class we bind method to
+ "r", // Name of method
+ Color_r_getter, // Function we are binding as a method
+ MRB_ARGS_NONE() // How many arguments are optional/required
+ );
+ mrb_define_method(
+ mrb, // Mruby VM state
+ color_class, // Class we bind method to
+ "r=", // Name of method
+ Color_r_setter, // Function we are binding as a method
+ MRB_ARGS_ANY() // How many arguments are optional/required
+ );
+}
+
+// gem finalizer
+void
+mrb_basic_struct_example_gem_final(mrb_state* mrb) {
+
+}