Skip to content

Commit

Permalink
WIP: Add cxx
Browse files Browse the repository at this point in the history
  • Loading branch information
Ondraceq committed Dec 1, 2022
1 parent 3987173 commit 0b35d67
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 1 deletion.
15 changes: 14 additions & 1 deletion softwareComponents/rust-rofi_voxel/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
cmake_minimum_required(VERSION 3.15)

add_rust_library(rofi_voxel)
add_rust_library(rofi_voxel FEATURES cpp_json_bindings CXX_LIB_NAME rofi_voxel_cpp_json_bindings)
add_rust_tests(test-rofi_voxel ALL_FEATURES)


set(BINDING_SRCS
binding_src/voxel_reconfig_binding.cpp
)
add_library(voxel_reconfig ${BINDING_SRCS})
target_link_libraries(voxel_reconfig PRIVATE rofi_voxel configurationWithJson)
target_link_libraries(voxel_reconfig PUBLIC atoms voxel)
target_include_directories(voxel_reconfig PUBLIC binding_include)

file(GLOB BINDING_TEST_SRC binding_test/*.cpp)
add_executable(test-binding_voxel_reconfig ${BINDING_TEST_SRC})
target_link_libraries(test-binding_voxel_reconfig PRIVATE Catch2WithMain voxel_reconfig)
14 changes: 14 additions & 0 deletions softwareComponents/rust-rofi_voxel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
[package]
name = "rofi_voxel"
version = "0.1.0"
authors = [ "Ondřej Svoboda <[email protected]>" ]
edition = "2021"
publish = false
repository = "https://github.com/paradise-fi/RoFI"

[lib]
crate-type = [ "lib", "cdylib", "staticlib" ]

[features]
default = [ "cpp_json_bindings" ]
cpp_json_bindings = [ "dep:serde_json", "dep:failure", "dep:cxx", "dep:cxx-build" ]

[dependencies]
amplify = "3.13.0"
bimap = "0.6.2"
Expand All @@ -17,3 +24,10 @@ rs-graph = "0.20.1"
serde = { version = "1.0", features = ["derive"] }
smallvec = "1.8.1"
static_assertions = "1.1.0"

cxx = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true }
failure = { version = "0.1.8", optional = true }

[build-dependencies]
cxx-build = { version = "1.0", optional = true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <vector>

#include "atoms/result.hpp"
#include "voxel.hpp"

namespace rofi::voxel
{
auto voxel_reconfig( const rofi::voxel::VoxelWorld & init, const rofi::voxel::VoxelWorld & goal )
-> atoms::Result< std::vector< rofi::voxel::VoxelWorld > >;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "voxel_reconfig.hpp"

#include <cstdint>
#include <ranges>

#include "configuration/serialization.hpp"
#include "cpp_json_bindings.rs.h"


namespace rofi::voxel
{
auto voxel_reconfig( const rofi::voxel::VoxelWorld & init, const rofi::voxel::VoxelWorld & goal )
-> atoms::Result< std::vector< rofi::voxel::VoxelWorld > >
{
using namespace std::string_literals;
namespace serialization = rofi::configuration::serialization;

auto initJson = nlohmann::json( init ).dump();
auto goalJson = nlohmann::json( goal ).dump();

auto result = std::vector< rofi::voxel::VoxelWorld >();

try {
auto rustResult = voxel_reconfiguration( initJson, goalJson );
std::ranges::copy( rustResult, std::back_insert_iterator( rustResult ) );
} catch ( const nlohmann::json::exception & e ) {
return atoms::result_error( "Error while parsing json from Rust voxel reconfiguration ("s
+ e.what() + ")" );
}

// auto resultJson = nlohmann::json();
// try {
// resultJson = nlohmann::json::parse( resultPtr );
// } catch ( const nlohmann::json::exception & e ) {
// rust_free_cstring( resultPtr );
// return atoms::result_error( "Error while parsing json from Rust voxel reconfiguration ("s
// + e.what() + ")" );
// }
// rust_free_cstring( resultPtr );

// try {
// return atoms::result_value( resultJson.get< std::vector< VoxelWorld > >() );
// } catch ( const nlohmann::json::exception & e ) {
// return atoms::result_error( "Error while getting VoxelWorlds from json ("s + e.what()
// + ")" );
// }

// return atoms::result_error( "Not implemented"s );
return atoms::result_value( result );
}

} // namespace rofi::voxel
66 changes: 66 additions & 0 deletions softwareComponents/rust-rofi_voxel/binding_test/voxel_reconfig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "voxel_reconfig.hpp"

#include <catch2/catch.hpp>

#include "configuration/rofiworld.hpp"
#include "configuration/universalModule.hpp"
#include "voxel.hpp"


using namespace rofi::configuration;

TEST_CASE( "No error" )
{
SECTION( "Single module - default" )
{
auto world = RofiWorld();

auto & um = world.insert( UniversalModule( 1, 0_deg, 0_deg, 0_deg ) );
connect< RigidJoint >( um.connectors()[ 0 ], Vector{ 0, 0, 0 }, matrices::identity );
REQUIRE( world.validate() );

auto voxelWorld = rofi::voxel::VoxelWorld::fromRofiWorld( world );
REQUIRE( voxelWorld );

auto result = rofi::voxel::voxel_reconfig( *voxelWorld, *voxelWorld );
REQUIRE( result );

CHECK( result->size() == 0 );
}

SECTION( "Single module - one move" )
{
auto initWorld = RofiWorld();
auto & initUm = initWorld.insert( UniversalModule( 1, 0_deg, 0_deg, 0_deg ) );
connect< RigidJoint >( initUm.connectors()[ 0 ], Vector{ 0, 0, 0 }, matrices::identity );
REQUIRE( initWorld.validate() );
auto initVoxelWorld = rofi::voxel::VoxelWorld::fromRofiWorld( initWorld );
REQUIRE( initVoxelWorld );

auto goalWorld = RofiWorld();
auto & goalUm = goalWorld.insert( UniversalModule( 1, 0_deg, 0_deg, 0_deg ) );
connect< RigidJoint >( goalUm.connectors()[ 0 ], Vector{ 0, 0, 0 }, matrices::identity );
SECTION( "Move alpha" )
{
goalUm.setAlpha( GENERATE( 90_deg, -90_deg ) );
}
SECTION( "Move beta" )
{
goalUm.setBeta( GENERATE( 90_deg, -90_deg ) );
}
SECTION( "Move gamma" )
{
goalUm.setGamma( GENERATE( 90_deg, -90_deg ) );
}

REQUIRE( goalWorld.validate() );
auto goalVoxelWorld = rofi::voxel::VoxelWorld::fromRofiWorld( goalWorld );
REQUIRE( goalVoxelWorld );


auto result = rofi::voxel::voxel_reconfig( *initVoxelWorld, *goalVoxelWorld );
REQUIRE( result );

CHECK( result->size() == 1 );
}
}
12 changes: 12 additions & 0 deletions softwareComponents/rust-rofi_voxel/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fn build_cpp_json_bindings() {
cxx_build::bridge("src/cpp_json_bindings.rs")
.shared_flag(true)
.out_dir(std::env::var_os("CXX_OUT_DIR").expect("CXX_OUT_DIR is not set"))
.compile("rofi_voxel_cpp_json_bindings");

println!("cargo:rerun-if-changed=src/cpp_json_bindings.rs");
}

fn main() {
build_cpp_json_bindings();
}
23 changes: 23 additions & 0 deletions softwareComponents/rust-rofi_voxel/src/cpp_json_bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::*;

#[cxx::bridge(namespace = "rofi::voxel")]
mod ffi {
extern "Rust" {
fn voxel_reconfiguration(init_json: &str, goal_json: &str) -> Result<Vec<String>>;
}
}

fn voxel_reconfiguration(init_json: &str, goal_json: &str) -> Result<Vec<String>, failure::Error> {
let init = serde_json::from_str::<serde::VoxelWorld>(init_json)?;
let goal = serde_json::from_str::<serde::VoxelWorld>(goal_json)?;

let (init, _min_pos) = init.to_world_and_min_pos()?;
let (goal, _min_pos) = goal.to_world_and_min_pos()?;

let reconfig_sequence = reconfiguration::compute_reconfiguration_moves(&init, goal)?;

Ok(reconfig_sequence
.iter()
.map(|world| serde_json::to_string(&serde::VoxelWorld::from_world(world)))
.collect::<Result<Vec<_>, _>>()?)
}
3 changes: 3 additions & 0 deletions softwareComponents/rust-rofi_voxel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ pub mod connectivity;
pub mod module_move;
pub mod module_repr;
pub mod reconfiguration;

#[cfg(feature = "cpp_json_bindings")]
mod cpp_json_bindings;

0 comments on commit 0b35d67

Please sign in to comment.