diff --git a/example/main/Cargo.toml b/example/main/Cargo.toml
index 4967cc6..7b590c7 100644
--- a/example/main/Cargo.toml
+++ b/example/main/Cargo.toml
@@ -25,7 +25,7 @@ edition = "2021"
default-run = "main"
[dependencies]
-libloading = "0.8.1"
+libloading = "0.8.3"
trixy = { path = "../../." }
[build-dependencies]
diff --git a/example/main/Makefile b/example/main/Makefile
index cea6907..e673702 100644
--- a/example/main/Makefile
+++ b/example/main/Makefile
@@ -22,7 +22,8 @@ BIN_NAME := ./target/plugin.so
BUILD_DIR := ./target/c_build/
-SRC := $(wildcard c/*.c)
+# SRC := $(wildcard c/*.c)
+SRC := c/main.c
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)
diff --git a/example/main/build.rs b/example/main/build.rs
index 8ef17a9..5d53eea 100644
--- a/example/main/build.rs
+++ b/example/main/build.rs
@@ -20,15 +20,15 @@
* If not, see .
*/
-use trixy::macros::config::TrixyConfig;
+use trixy::macros::config::trixy::TrixyConfig;
fn main() {
println!("cargo:rerun-if-changed=./dist/*");
println!("cargo:rerun-if-changed=./src/bin/main/api.tri");
println!("cargo:rerun-if-changed=./src/bin/main/trinitrix_api.tri");
- TrixyConfig::new("handle_cmd")
- .trixy_path("./src/bin/main/trinitrix_api.tri")
+ let file_tree = TrixyConfig::new("handle_cmd")
+ .trixy_path("./src/bin/main/api.tri")
.dist_dir_path("./dist")
- .generate_debug(true)
.generate();
+ file_tree.materialize().unwrap();
}
diff --git a/example/main/c/main.c b/example/main/c/main.c
index 922ce3d..5de1453 100644
--- a/example/main/c/main.c
+++ b/example/main/c/main.c
@@ -47,6 +47,21 @@ handle_error ()
free (error);
}
+struct Dog
+guess (const char *pers_name, uint32_t age)
+{
+ println ("Rust wants to name the dog %s, but that's not good!", pers_name);
+
+ // The callback must free all its owned arguments, as rust just moved these
+ // here and is not going to free them.
+ string_free (pers_name);
+
+ struct Dog dog = {
+ .name = "James",
+ };
+ return dog;
+}
+
int
plugin_main ()
{
@@ -64,7 +79,7 @@ plugin_main ()
println ("Saying hi!");
const char *hi;
- if (!one.hi (&hi, "Adam"))
+ if (!dogs.hi (&hi, "Adam"))
handle_error ();
println ("Rust returned: %s", hi);
@@ -74,7 +89,7 @@ plugin_main ()
// types are defined in the `api.tri` file)
struct Dog dog = { .name = "Bruce" };
struct TrainedDog tDog;
- if (!one.train_dog (&tDog, dog))
+ if (!dogs.train_dog (&tDog, dog))
handle_error ();
println ("Dog %s is now trained with specialization %i", tDog.name,
@@ -82,5 +97,11 @@ plugin_main ()
// Beware that you need to free them with the appropriate free functions
string_free (tDog.name);
+ // Trixy also supports functions (i.e. callbacks):
+ enum DogType output_dog;
+ if (!dogs.guess_my_favourite_dog (&output_dog, guess))
+ handle_error ();
+ println ("Rust guessed %d", output_dog);
+
return 0;
}
diff --git a/example/main/c/trinitrix.c b/example/main/c/trinitrix.c
new file mode 100644
index 0000000..a50866d
--- /dev/null
+++ b/example/main/c/trinitrix.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 - 2024:
+ * The Trinitrix Project
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ *
+ * This file is part of the Trixy crate for Trinitrix.
+ *
+ * Trixy is free software: you can redistribute it and/or modify
+ * it under the terms of the Lesser GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the Lesser GNU General Public License along with this program.
+ * If not, see .
+ */
+
+#include "../dist/interface.h"
+#include
+#include
+#include
+#include
+
+#define println(args...) \
+ printf ("\33[32;1m(plugin):\33[0m \33[34;1m"); \
+ printf (args); \
+ printf ("\n\33[0m"); \
+ fflush (stdout);
+#define eprintln(args...) \
+ printf ("\33[32;1m(plugin):\33[0m\33[31;1m "); \
+ printf (args); \
+ printf ("\n\33[0m"); \
+ fflush (stdout);
+
+void
+handle_error ()
+{
+ int error_length = last_error_length ();
+ char *error = malloc (error_length);
+ last_error_message (error, error_length);
+ eprintln ("Encountered error: %s", error);
+ free (error);
+}
+
+int
+plugin_main ()
+{
+ if (!trinitrix.api.room_message_send ("Hi!"))
+ handle_error ();
+ return EXIT_SUCCESS;
+}
diff --git a/example/main/src/bin/main/api.tri b/example/main/src/bin/main/api.tri
index 26d6bd0..8b77d96 100644
--- a/example/main/src/bin/main/api.tri
+++ b/example/main/src/bin/main/api.tri
@@ -37,7 +37,21 @@ enum TrainingMistake {
Died,
}
-mod one {
+struct Dog {
+ name: String,
+}
+
+mod dogs {
+ /// The possible types a dog can have
+ ///
+ /// Beware that [`DogType::Cat`] and [`DogType::Lion`] are not really recognized as
+ /// dogs.
+ enum DogType {
+ Akita,
+ Cat,
+ Lion,
+ }
+
/// A Dog after extensive training
struct TrainedDog {
name: String,
@@ -46,15 +60,10 @@ mod one {
/// Say hi to a name
fn hi(name: String) -> String;
- /// Train a dog without using any resources
- // fn cheaply_train_dog(dog: Dog) -> Result;
-
/// Train a dog
fn train_dog(dog: Dog) -> TrainedDog;
-}
-struct Dog {
- name: String,
+ fn guess_my_favourite_dog(callback: fn(name: String, age: u32) -> Dog) -> DogType;
}
// Trixy is a subset of Rust
diff --git a/example/main/src/bin/main/main.rs b/example/main/src/bin/main/main.rs
index 126f1b2..9f6e296 100644
--- a/example/main/src/bin/main/main.rs
+++ b/example/main/src/bin/main/main.rs
@@ -22,8 +22,11 @@
use std::{env, ffi::c_int, mem};
+use dogs::TrainedDog;
use libloading::{Library, Symbol};
+use crate::dogs::DogType;
+
include!(concat!(env!("OUT_DIR"), "/api.rs"));
// run `cargo r --bin api > ./src/bin/main/api.rs` to output the generated api
@@ -32,13 +35,37 @@ include!(concat!(env!("OUT_DIR"), "/api.rs"));
fn handle_cmd(cmd: Commands) {
match cmd {
- Commands::One(one) => match one {
- one::One::hi { trixy_output, name } => {
+ Commands::Dogs(one) => match one {
+ dogs::Dogs::hi { trixy_output, name } => {
let output = format!("Hi {}!", name);
println!("(rust): {}", output);
trixy_output.send(output.into()).expect("Will work");
mem::forget(name);
}
+ dogs::Dogs::train_dog { trixy_output, dog } => {
+ trixy_output
+ .send(
+ TrainedDog {
+ name: "Willis".into(),
+ training: DogTraining::Wolf,
+ }
+ .try_into()
+ .unwrap(),
+ )
+ .unwrap();
+ mem::forget(dog);
+ }
+ dogs::Dogs::guess_my_favourite_dog {
+ trixy_output,
+ callback,
+ } => {
+ let fav_dog = callback("Frank".into(), 30);
+ let dog_name: String = fav_dog.name.clone().try_into().unwrap();
+ println!("(rust): They want a dog named: {}", dog_name);
+ trixy_output.send(DogType::Cat.into()).unwrap();
+
+ mem::forget(dog_name);
+ }
},
Commands::outstanding { name } => {
println!("(rust): {} is outstanding!", name);
diff --git a/example/main/src/bin/main/trinitrix_api.tri b/example/main/src/bin/main/trinitrix_api.tri
new file mode 120000
index 0000000..83efdf9
--- /dev/null
+++ b/example/main/src/bin/main/trinitrix_api.tri
@@ -0,0 +1 @@
+../../../../../tests/trinitrix_api/input.tri
\ No newline at end of file