From 8e59241aa815131b3d2d550175bbbcabf01a1108 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sat, 12 Oct 2024 19:13:42 -0700 Subject: [PATCH] Use Ruby C API directly --- .github/workflows/build.yml | 11 ++++--- ext/field_test/ext.cpp | 64 +++++++++++++++++++++++++++++++++---- ext/field_test/extconf.rb | 2 +- field_test.gemspec | 1 - 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 642c5c3..febb798 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,19 +2,20 @@ name: build on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - - ruby: 3.3 - gemfile: gemfiles/rails80.gemfile - ruby: 3.3 gemfile: Gemfile + os: ubuntu-latest - ruby: 3.2 - gemfile: gemfiles/rails71.gemfile + gemfile: Gemfile + os: macos-latest - ruby: 3.1 - gemfile: gemfiles/rails70.gemfile + gemfile: Gemfile + os: windows-latest env: BUNDLE_GEMFILE: ${{ matrix.gemfile }} steps: diff --git a/ext/field_test/ext.cpp b/ext/field_test/ext.cpp index 408c9db..fb3d6f2 100644 --- a/ext/field_test/ext.cpp +++ b/ext/field_test/ext.cpp @@ -1,16 +1,66 @@ -#include -#include +#include #include "bayestest.hpp" using bayestest::BinaryTest; +void binary_test_free(void* data) +{ + free(data); +} + +size_t binary_test_size(const void* data) +{ + // does not currently include size of variants + return sizeof(BinaryTest); +} + +static const rb_data_type_t binary_test_type = { + .wrap_struct_name = "binary_test", + .function = { + .dmark = NULL, + .dfree = binary_test_free, + .dsize = binary_test_size, + }, + .data = NULL, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +VALUE binary_test_alloc(VALUE self) +{ + BinaryTest* data = new BinaryTest(); + + return TypedData_Wrap_Struct(self, &binary_test_type, data); +} + +VALUE binary_test_add(VALUE self, VALUE participants, VALUE conversions) +{ + BinaryTest* data; + TypedData_Get_Struct(self, BinaryTest, &binary_test_type, data); + + data->add(NUM2INT(participants), NUM2INT(conversions)); + + return Qnil; +} + +VALUE binary_test_probabilities(VALUE self) +{ + BinaryTest* data; + TypedData_Get_Struct(self, BinaryTest, &binary_test_type, data); + + VALUE arr = rb_ary_new(); + for (auto &v : data->probabilities()) { + rb_ary_push(arr, DBL2NUM(v)); + } + return arr; +} + extern "C" void Init_ext() { - auto rb_mFieldTest = Rice::define_module("FieldTest"); + auto mFieldTest = rb_define_module("FieldTest"); - Rice::define_class_under(rb_mFieldTest, "BinaryTest") - .define_constructor(Rice::Constructor()) - .define_method("add", &BinaryTest::add) - .define_method("probabilities", &BinaryTest::probabilities); + auto cBinaryTest = rb_define_class_under(mFieldTest, "BinaryTest", rb_cObject); + rb_define_alloc_func(cBinaryTest, binary_test_alloc); + rb_define_method(cBinaryTest, "add", binary_test_add, 2); + rb_define_method(cBinaryTest, "probabilities", binary_test_probabilities, 0); } diff --git a/ext/field_test/extconf.rb b/ext/field_test/extconf.rb index 43cbc28..1bcb145 100644 --- a/ext/field_test/extconf.rb +++ b/ext/field_test/extconf.rb @@ -1,4 +1,4 @@ -require "mkmf-rice" +require "mkmf" $CXXFLAGS << " -std=c++17 $(optflags)" diff --git a/field_test.gemspec b/field_test.gemspec index 4ec83df..6c7078a 100644 --- a/field_test.gemspec +++ b/field_test.gemspec @@ -19,5 +19,4 @@ Gem::Specification.new do |spec| spec.add_dependency "railties", ">= 7" spec.add_dependency "activerecord", ">= 7" spec.add_dependency "browser", ">= 2" - spec.add_dependency "rice", ">= 4.0.2" end